UNPKG

@limetech/lime-elements

Version:
256 lines (255 loc) • 9.46 kB
import { MDCMenu } from "@material/menu"; import { MDCRipple } from "@material/ripple"; import { strings as menuStrings } from "@material/menu/constants"; import { h, } from "@stencil/core"; import { MenuListRenderer } from "./menu-list-renderer"; const { SELECTED_EVENT } = menuStrings; /** * @private */ export class MenuList { constructor() { /** * Size of the icons in the list */ this.iconSize = 'small'; this.MenuListRenderer = new MenuListRenderer(); this.setup = () => { this.setupMenu(); this.setupListeners(); }; this.setupMenu = () => { if (this.mdcMenu) { this.teardown(); this.mdcMenu = null; } const element = this.element.shadowRoot.querySelector('.mdc-menu'); if (!element) { return; } this.mdcMenu = new MDCMenu(element); this.mdcMenu.hasTypeahead = true; this.mdcMenu.wrapFocus = true; // eslint-disable-next-line sonarjs/constructor-for-side-effects for (const item of this.mdcMenu.items) new MDCRipple(item); }; this.setupListeners = () => { if (!this.mdcMenu) { return; } this.mdcMenu.unlisten(SELECTED_EVENT, this.handleMenuSelect); this.mdcMenu.listen(SELECTED_EVENT, this.handleMenuSelect); }; this.teardown = () => { var _a, _b; (_a = this.mdcMenu) === null || _a === void 0 ? void 0 : _a.unlisten(SELECTED_EVENT, this.handleMenuSelect); (_b = this.mdcMenu) === null || _b === void 0 ? void 0 : _b.destroy(); }; this.handleMenuSelect = (event) => { this.handleSingleSelect(event.detail.index); }; this.handleSingleSelect = (index) => { const MenuItems = this.items.filter(this.isMenuItem); if (MenuItems[index].disabled) { return; } const selectedItem = MenuItems.find((item) => { return !!item.selected; }); let interactedItem; if (selectedItem) { interactedItem = Object.assign(Object.assign({}, selectedItem), { selected: false }); this.select.emit(interactedItem); } if (MenuItems[index] !== selectedItem) { interactedItem = Object.assign(Object.assign({}, MenuItems[index]), { selected: false }); this.select.emit(interactedItem); } this.interact.emit(interactedItem); }; this.isMenuItem = (item) => { return !('separator' in item); }; } connectedCallback() { this.setup(); } disconnectedCallback() { this.teardown(); } componentDidLoad() { this.setup(); this.triggerIconColorWarning(); } render() { this.config = { badgeIcons: this.badgeIcons, iconSize: this.iconSize, }; const html = this.MenuListRenderer.render(this.items, this.config); return h("div", { key: '1c044c711555d155c5559f8b787a3bbad09b7526', class: "mdc-menu mdc-menu-surface" }, html); } itemsChanged() { setTimeout(() => { this.setup(); }, 0); } triggerIconColorWarning() { var _a; if ((_a = this.items) === null || _a === void 0 ? void 0 : _a.some((item) => 'iconColor' in item)) { console.warn("The `iconColor` prop is deprecated, has no visual effect anymore, and will soon be removed! Use the new `Icon` interface, and instead of `iconColor: 'color-name'` write `icon: { name: 'icon-name', color: 'color-name' }`."); } } static get is() { return "limel-menu-list"; } static get encapsulation() { return "shadow"; } static get delegatesFocus() { return true; } static get originalStyleUrls() { return { "$": ["menu-list.scss"] }; } static get styleUrls() { return { "$": ["menu-list.css"] }; } static get properties() { return { "items": { "type": "unknown", "mutable": false, "complexType": { "original": "Array<MenuItem | ListSeparator>", "resolved": "(ListSeparator | MenuItem<any>)[]", "references": { "Array": { "location": "global", "id": "global::Array" }, "MenuItem": { "location": "import", "path": "../menu/menu.types", "id": "src/components/menu/menu.types.ts::MenuItem", "referenceLocation": "MenuItem" }, "ListSeparator": { "location": "import", "path": "../list-item/list-item.types", "id": "src/components/list-item/list-item.types.ts::ListSeparator", "referenceLocation": "ListSeparator" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "List of items to display" }, "getter": false, "setter": false }, "badgeIcons": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Set to `true` if the list should display larger icons with a background" }, "getter": false, "setter": false, "reflect": false, "attribute": "badge-icons" }, "iconSize": { "type": "string", "mutable": false, "complexType": { "original": "IconSize", "resolved": "\"large\" | \"medium\" | \"small\" | \"x-small\"", "references": { "IconSize": { "location": "import", "path": "../icon/icon.types", "id": "src/components/icon/icon.types.ts::IconSize", "referenceLocation": "IconSize" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "Size of the icons in the list" }, "getter": false, "setter": false, "reflect": false, "attribute": "icon-size", "defaultValue": "'small'" } }; } static get events() { return [{ "method": "select", "name": "select", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Fired when a new value has been selected from the list." }, "complexType": { "original": "MenuItem", "resolved": "MenuItem<any>", "references": { "MenuItem": { "location": "import", "path": "../menu/menu.types", "id": "src/components/menu/menu.types.ts::MenuItem", "referenceLocation": "MenuItem" } } } }, { "method": "interact", "name": "interact", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Fires when a user interacts with an item in the list (e.g., click,\nkeyboard select)." }, "complexType": { "original": "MenuItem", "resolved": "MenuItem<any>", "references": { "MenuItem": { "location": "import", "path": "../menu/menu.types", "id": "src/components/menu/menu.types.ts::MenuItem", "referenceLocation": "MenuItem" } } } }]; } static get elementRef() { return "element"; } static get watchers() { return [{ "propName": "items", "methodName": "itemsChanged" }]; } }