Skip to content

Commit

Permalink
refactor!: move vaadin-message elements to light DOM (#4710)
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan committed Oct 14, 2022
1 parent afd776e commit 4b1c09b
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 179 deletions.
8 changes: 7 additions & 1 deletion packages/message-list/src/vaadin-message-list.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@ export interface MessageListItem {
* `<vaadin-message-list>` is a Web Component for showing an ordered list of messages. The messages are rendered as <vaadin-message>
*
* ### Example
*
* To create a new message list, add the component to the page:
*
* ```html
* <vaadin-message-list></vaadin-message-list>
* ```
*
* Provide the messages to the message list with the `items` property.
* Provide the messages to the message list with the [`items`](#/elements/vaadin-message-list#property-items) property.
*
* ```js
* document.querySelector('vaadin-message-list').items = [
* { text: 'Hello list', time: 'yesterday', userName: 'Matt Mambo', userAbbr: 'MM', userColorIndex: 1 },
Expand All @@ -42,6 +45,9 @@ export interface MessageListItem {
* ----------|----------------
* `list` | The container wrapping messages.
*
* See the [`<vaadin-message>`](#/elements/vaadin-message) documentation for the available
* state attributes and stylable shadow parts of message elements.
*
* See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
*/
declare class MessageList extends KeyboardDirectionMixin(ThemableMixin(ElementMixin(HTMLElement))) {
Expand Down
97 changes: 73 additions & 24 deletions packages/message-list/src/vaadin-message-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
* Copyright (c) 2021 - 2022 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import '@polymer/polymer/lib/elements/dom-repeat.js';
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
import { microTask } from '@vaadin/component-base/src/async.js';
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
import { KeyboardDirectionMixin } from '@vaadin/component-base/src/keyboard-direction-mixin.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
Expand All @@ -15,12 +13,15 @@ import { Message } from './vaadin-message.js';
* `<vaadin-message-list>` is a Web Component for showing an ordered list of messages. The messages are rendered as <vaadin-message>
*
* ### Example
*
* To create a new message list, add the component to the page:
*
* ```html
* <vaadin-message-list></vaadin-message-list>
* ```
*
* Provide the messages to the message list with the `items` property.
* Provide the messages to the message list with the [`items`](#/elements/vaadin-message-list#property-items) property.
*
* ```js
* document.querySelector('vaadin-message-list').items = [
* { text: 'Hello list', time: 'yesterday', userName: 'Matt Mambo', userAbbr: 'MM', userColorIndex: 1 },
Expand All @@ -36,6 +37,9 @@ import { Message } from './vaadin-message.js';
* ----------|----------------
* `list` | The container wrapping messages.
*
* See the [`<vaadin-message>`](#/elements/vaadin-message) documentation for the available
* state attributes and stylable shadow parts of message elements.
*
* See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
*
* @extends HTMLElement
Expand Down Expand Up @@ -86,19 +90,7 @@ class MessageList extends KeyboardDirectionMixin(ElementMixin(ThemableMixin(Poly
}
</style>
<div part="list" role="list">
<template is="dom-repeat" items="[[items]]">
<vaadin-message
time="[[item.time]]"
user-name="[[item.userName]]"
user-abbr="[[item.userAbbr]]"
user-img="[[item.userImg]]"
user-color-index="[[item.userColorIndex]]"
theme$="[[item.theme]]"
role="listitem"
on-focusin="_handleFocusEvent"
>[[item.text]]</vaadin-message
>
</template>
<slot></slot>
</div>
`;
}
Expand Down Expand Up @@ -126,24 +118,81 @@ class MessageList extends KeyboardDirectionMixin(ElementMixin(ThemableMixin(Poly

/** @protected */
get _messages() {
return Array.from(this.shadowRoot.querySelectorAll('vaadin-message'));
return [...this.querySelectorAll('vaadin-message')];
}

/** @private */
_itemsChanged(newVal, oldVal) {
const focusedIndex = this._getIndexOfFocusableElement();
if (newVal && newVal.length) {
const moreItems = !oldVal || newVal.length > oldVal.length;
const items = newVal || [];
const oldItems = oldVal || [];

if (items.length || oldItems.length) {
const focusedIndex = this._getIndexOfFocusableElement();
const closeToBottom = this.scrollHeight < this.clientHeight + this.scrollTop + 50;
microTask.run(() => {
this._setTabIndexesByIndex(focusedIndex);
if (moreItems && closeToBottom) {

const removed = oldItems.filter((item) => !items.includes(item));
const added = [...items];

this._messages.forEach((message) => {
const item = message._item;
if (removed.includes(item)) {
message.remove();
} else if (added.includes(item)) {
added.splice(added.indexOf(item), 1);
}
});

this.__addMessages(added, items);

this._setTabIndexesByIndex(focusedIndex);

requestAnimationFrame(() => {
if (items.length > oldItems.length && closeToBottom) {
this._scrollToLastMessage();
}
});
}
}

/** @private */
__addMessages(itemsToAdd, allItems) {
itemsToAdd.forEach((item) => {
const message = this.__createMessage(item);
const nextItem = allItems[allItems.indexOf(item) + 1];
const nextMessage = this._messages.find((msg) => msg._item === nextItem);
if (nextMessage) {
this.insertBefore(message, nextMessage);
} else {
this.appendChild(message);
}
});
}

/** @private */
__createMessage(item) {
const message = document.createElement('vaadin-message');
message.setAttribute('role', 'listitem');

message.textContent = item.text;
message.time = item.time;
message.userName = item.userName;
message.userAbbr = item.userAbbr;
message.userImg = item.userImg;
message.userColorIndex = item.userColorIndex;

message._item = item;

if (item.theme) {
message.setAttribute('theme', item.theme);
}

message.addEventListener('focusin', (e) => {
this._onMessageFocusIn(e);
});

return message;
}

/** @private */
_scrollToLastMessage() {
if (this.items.length > 0) {
Expand All @@ -152,7 +201,7 @@ class MessageList extends KeyboardDirectionMixin(ElementMixin(ThemableMixin(Poly
}

/** @private */
_handleFocusEvent(e) {
_onMessageFocusIn(e) {
const target = e.composedPath().find((node) => node instanceof Message);
this._setTabIndexesByMessage(target);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,18 @@
export const snapshots = {};

snapshots["vaadin-message-list default"] =
`<div
part="list"
role="list"
`<vaadin-message-list
aria-relevant="additions"
role="log"
>
<dom-repeat style="display: none;">
<template is="dom-repeat">
</template>
</dom-repeat>
</div>
</vaadin-message-list>
`;
/* end snapshot vaadin-message-list default */

snapshots["vaadin-message-list items"] =
`<div
part="list"
role="list"
`<vaadin-message-list
aria-relevant="additions"
role="log"
>
<vaadin-message
role="listitem"
Expand Down Expand Up @@ -49,18 +45,14 @@ snapshots["vaadin-message-list items"] =
>
</vaadin-avatar>
</vaadin-message>
<dom-repeat style="display: none;">
<template is="dom-repeat">
</template>
</dom-repeat>
</div>
</vaadin-message-list>
`;
/* end snapshot vaadin-message-list items */

snapshots["vaadin-message-list theme"] =
`<div
part="list"
role="list"
`<vaadin-message-list
aria-relevant="additions"
role="log"
>
<vaadin-message
role="listitem"
Expand All @@ -78,11 +70,7 @@ snapshots["vaadin-message-list theme"] =
>
</vaadin-avatar>
</vaadin-message>
<dom-repeat style="display: none;">
<template is="dom-repeat">
</template>
</dom-repeat>
</div>
</vaadin-message-list>
`;
/* end snapshot vaadin-message-list theme */

6 changes: 3 additions & 3 deletions packages/message-list/test/dom/message-list.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('vaadin-message-list', () => {
});

it('default', async () => {
await expect(list).shadowDom.to.equalSnapshot();
await expect(list).dom.to.equalSnapshot();
});

it('items', async () => {
Expand All @@ -19,12 +19,12 @@ describe('vaadin-message-list', () => {
{ text: 'Good morning!', userName: 'Lina Roy' },
];
await nextFrame();
await expect(list).shadowDom.to.equalSnapshot();
await expect(list).dom.to.equalSnapshot();
});

it('theme', async () => {
list.items = [{ text: 'Partial service outage.', userName: 'Admin', theme: 'danger' }];
await nextFrame();
await expect(list).shadowDom.to.equalSnapshot();
await expect(list).dom.to.equalSnapshot();
});
});
Loading

0 comments on commit 4b1c09b

Please sign in to comment.