UNPKG

@universal-material/web

Version:
158 lines (157 loc) 5.6 kB
import { __decorate } from "tslib"; import { html, LitElement, render } from 'lit'; import { customElement, property, query, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { map } from 'lit/directives/map.js'; import { when } from 'lit/directives/when.js'; import { styles } from './overflow-menu.styles.js'; let OverflowMenu = class OverflowMenu extends LitElement { static { this.styles = styles; } #resizeObserver; #items; #collapsedItems; #anchor; set anchor(value) { this.#anchor = value; this.#invalidate(); this.#resizeObserver.disconnect(); this.#resizeObserver.observe(this.anchor); } get anchor() { return this.#anchor ?? this; } #menuItemsContainer; #updateMenusTimeout; constructor() { super(); this.#resizeObserver = new ResizeObserver(() => this.#invalidate()); this.#items = []; this.#collapsedItems = []; this._renderMenu = false; this.#anchor = null; this.#menuItemsContainer = document.createElement('div'); this.#updateMenusTimeout = 0; this.#menuItemsContainer.slot = 'menu-items'; setTimeout(() => this.appendChild(this.#menuItemsContainer)); } connectedCallback() { super.connectedCallback(); this.anchor = this.anchor; } disconnectedCallback() { super.disconnectedCallback(); this.#resizeObserver.disconnect(); } #invalidate() { this.#updateMenuToggleVisibility(); this.#updateMenuItems(); } #updateMenuToggleVisibility() { let collapsedCount = 0; let hasAlwaysCollapsedItems = false; for (const item of this.#items) { hasAlwaysCollapsedItems = hasAlwaysCollapsedItems || item.collapse === 'always'; if (this.#isNotCollapsedMenuItem(item)) { continue; } collapsedCount++; } const firstItem = this.#items[0]; const renderMenu = hasAlwaysCollapsedItems || !!firstItem && (this._renderMenu ? collapsedCount > 1 : collapsedCount > 0); if (this._renderMenu !== renderMenu) { this._renderMenu = renderMenu; } } #updateMenuItems() { if (!this._renderMenu) { this.#collapsedItems.length = 0; return; } clearTimeout(this.#updateMenusTimeout); this.#updateMenusTimeout = setTimeout(() => { const previousCollapsedLength = this.#collapsedItems.length; this.#collapsedItems.length = 0; for (const item of this.#items) { if (this.#isNotCollapsedMenuItem(item)) { continue; } this.#collapsedItems.push(item); } if (previousCollapsedLength !== this.#collapsedItems.length) { this.requestUpdate(); } }, 100); } #isNotCollapsedMenuItem(item) { return item.offsetTop === this.offsetTop && item.collapse !== 'always'; } #handleSlotChange(e) { const slot = e.target; this.#items = slot .assignedElements() .filter(el => el.tagName === 'U-OVERFLOW-MENU-ITEM') .reverse(); this.#invalidate(); } render() { this._renderMenuItems(); const classes = { 'show-menu': this._renderMenu }; return html ` <div class="container ${classMap(classes)}"> <div class="items-set"> <div class="empty-space"></div> <slot @slotchange="${this.#handleSlotChange}"></slot> </div> ${when(this._renderMenu, () => html ` <div class="inner-menu"> <u-icon-button @click=${{ handleEvent: () => this.menu?.toggle() }}> <slot name="icon"> <svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 -960 960 960" width="1em" fill="currentColor"> <path d="M480-160q-33 0-56.5-23.5T400-240q0-33 23.5-56.5T480-320q33 0 56.5 23.5T560-240q0 33-23.5 56.5T480-160Zm0-240q-33 0-56.5-23.5T400-480q0-33 23.5-56.5T480-560q33 0 56.5 23.5T560-480q0 33-23.5 56.5T480-400Zm0-240q-33 0-56.5-23.5T400-720q0-33 23.5-56.5T480-800q33 0 56.5 23.5T560-720q0 33-23.5 56.5T480-640Z"/> </svg> </slot> </u-icon-button> <u-menu anchor-corner="end-end"> <slot name="menu-items"></slot> </u-menu> </div> `)} </div> `; } _renderMenuItems() { const menuItems = html ` ${map(this.#collapsedItems, item => { const nodes = item.childNodes.values(); return html ` <u-menu-item @click=${{ handleEvent: () => item.click() }}> <div slot="leading-icon"> ${map(nodes, node => node.cloneNode(true))} </div> ${item.label} </u-menu-item> `; })}`; render(menuItems, this.#menuItemsContainer); } }; __decorate([ state() ], OverflowMenu.prototype, "_renderMenu", void 0); __decorate([ query('u-menu') ], OverflowMenu.prototype, "menu", void 0); __decorate([ property() ], OverflowMenu.prototype, "anchor", null); OverflowMenu = __decorate([ customElement('u-overflow-menu') ], OverflowMenu); export { OverflowMenu }; //# sourceMappingURL=overflow-menu.js.map