UNPKG

@trimble-oss/moduswebcomponents

Version:

Modus Web Components is a modern, accessible UI library built with Stencil JS that provides reusable web components following Trimble's Modus design system. This updated version focuses on improved flexibility, enhanced theming options, comprehensive cust

153 lines (148 loc) 6.73 kB
import { p as proxyCustomElement, H, d as createEvent, h, c as Host } from './p-Blhe_h6i.js'; import { h as handleShadowDOMStyles } from './p-tWS3Egrk.js'; import { i as inheritAriaAttributes } from './p-DUWn6PrQ.js'; const convertPropsToClasses = ({ bordered, orientation, size, }) => { let classes = ''; if (bordered) { classes = `${classes} modus-wc-menu--bordered`; } if (orientation === 'horizontal') { classes = `${classes} modus-wc-menu-horizontal`; } if (size) { classes = `${classes} modus-wc-menu-${size}`; } return classes.trim(); }; const modusWcMenuCss = "modus-wc-menu.modus-wc-menu-submenu{display:contents}modus-wc-menu .modus-wc-menu{background-color:var(--modus-wc-color-base-page);border-radius:var(--modus-wc-border-radius-md);list-style:none;margin:0;overflow:hidden;padding:0;padding-inline-start:0}modus-wc-menu .modus-wc-menu.modus-wc-menu--bordered{border:var(--modus-wc-border-width-xs) solid var(--modus-wc-color-base-200)}modus-wc-menu .modus-wc-menu-dropdown{display:none;list-style:none}modus-wc-menu .modus-wc-menu-dropdown-show{display:block}[data-theme=modus-classic-light] modus-wc-menu .modus-wc-menu{background-color:var(--modus-wc-color-white);border-color:var(--modus-wc-color-gray-0)}[data-theme=modus-classic-dark] modus-wc-menu .modus-wc-menu{background-color:var(--modus-wc-color-black);border-color:var(--modus-wc-color-gray-8)}"; const ModusWcMenu = /*@__PURE__*/ proxyCustomElement(class ModusWcMenu extends H { constructor() { super(); this.__registerHost(); this.menuFocusout = createEvent(this, "menuFocusout", 7); this.menuSelectionChange = createEvent(this, "menuSelectionChange", 7); this.inheritedAttributes = {}; this.selectedItems = []; /** Custom CSS class to apply to the ul element. */ this.customClass = ''; /** The orientation of the menu. */ this.orientation = 'vertical'; /** The selection mode of the menu. */ this.selectionMode = 'single'; /** The size of the menu. */ this.size = 'md'; this.getMenuRole = () => this.orientation === 'horizontal' ? 'menubar' : 'menu'; } onSelectionModeChange() { this.selectedItems = []; } componentWillLoad() { handleShadowDOMStyles(this.el); if (!this.el.ariaLabel) { this.el.ariaLabel = 'Menu'; } this.inheritedAttributes = inheritAriaAttributes(this.el); } getClasses() { // For submenus, only add the dropdown class if (this.isSubMenu) { const classList = ['modus-wc-menu-dropdown']; if (this.customClass) classList.push(this.customClass); return classList.join(' '); } // For regular menus, add all the standard classes const classList = ['modus-wc-menu modus-wc-w-full']; const propClasses = convertPropsToClasses({ bordered: this.bordered, orientation: this.orientation, size: this.size, }); // The order CSS classes are added matters to CSS specificity if (propClasses) classList.push(propClasses); if (this.customClass) classList.push(this.customClass); return classList.join(' '); } getMenuItems() { return Array.from(this.el.querySelectorAll('modus-wc-menu-item')).filter((item) => item.closest('modus-wc-menu') === this.el); } handleItemSelect(e) { if (this.selectionMode !== 'multiple') return; const item = e.target; const isCurrentlySelected = this.selectedItems.includes(item); if (e.detail.selected && !isCurrentlySelected) { this.selectedItems = [...this.selectedItems, item]; } else if (!e.detail.selected && isCurrentlySelected) { this.selectedItems = this.selectedItems.filter((i) => i !== item); } this.menuSelectionChange.emit({ selectedItems: this.selectedItems }); } handleKeyDown(e) { if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return; e.preventDefault(); const items = this.getMenuItems(); const focusableItems = items.filter((item) => !item.disabled); if (focusableItems.length === 0) return; const activeEl = document.activeElement; const currentMenuItem = activeEl === null || activeEl === void 0 ? void 0 : activeEl.closest('modus-wc-menu-item'); const currentIndex = focusableItems.indexOf(currentMenuItem); let nextIndex; if (e.key === 'ArrowDown') { nextIndex = currentIndex < focusableItems.length - 1 ? currentIndex + 1 : 0; } else { nextIndex = currentIndex > 0 ? currentIndex - 1 : focusableItems.length - 1; } const nextLi = focusableItems[nextIndex].querySelector('li'); if (nextLi) { nextLi.focus(); } } handleFocusout(e) { if (!this.el.contains(e.relatedTarget)) { this.menuFocusout.emit(e); if (this.isSubMenu) { e.stopPropagation(); } } } render() { return (h(Host, { key: '19854fb1e7960407db704bb954ff66bb355ab042', class: this.isSubMenu ? 'modus-wc-menu-submenu' : undefined }, h("ul", Object.assign({ key: '0752b609c2ed4a897c8a6e8ecc73718cff4c8d09', "aria-orientation": this.orientation, class: this.getClasses(), role: this.getMenuRole() }, this.inheritedAttributes), h("slot", { key: '4957e81fa8566c990a5f06464d2d26dee3af5ba7' })))); } get el() { return this; } static get watchers() { return { "selectionMode": ["onSelectionModeChange"] }; } static get style() { return modusWcMenuCss; } }, [4, "modus-wc-menu", { "bordered": [4], "customClass": [1, "custom-class"], "orientation": [1], "selectionMode": [513, "selection-mode"], "size": [1], "isSubMenu": [4, "is-sub-menu"] }, [[0, "itemSelect", "handleItemSelect"], [0, "keydown", "handleKeyDown"], [0, "focusout", "handleFocusout"]], { "selectionMode": ["onSelectionModeChange"] }]); function defineCustomElement() { if (typeof customElements === "undefined") { return; } const components = ["modus-wc-menu"]; components.forEach(tagName => { switch (tagName) { case "modus-wc-menu": if (!customElements.get(tagName)) { customElements.define(tagName, ModusWcMenu); } break; } }); } export { ModusWcMenu as M, defineCustomElement as d };