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

205 lines (200 loc) 16.1 kB
import { p as proxyCustomElement, H, d as createEvent, h, c as Host } from './p-X1tirp06.js'; import { i as inheritAriaAttributes } from './p-VPqXjOQn.js'; import { d as defineCustomElement$3 } from './p-v6-_mwzz.js'; import { d as defineCustomElement$2 } from './p-DtlnhsZ5.js'; import { d as defineCustomElement$1 } from './p-CYbL8-QO.js'; const convertPropsToClasses = ({ bordered, disabled, selected, focused, size, }) => { let classes = ''; if (bordered) { classes = `${classes} modus-wc-menu-item-bordered`; } if (disabled) { classes = `${classes} modus-wc-menu-item-disabled`; } if (selected) { classes = `${classes} modus-wc-menu-item-selected`; } if (focused) { classes = `${classes} modus-wc-menu-item-focused`; } if (size) { classes = `${classes} modus-wc-menu-item-${size}`; } return classes.trim(); }; const modusWcMenuItemCss = "modus-wc-menu-item .modus-wc-menu-item button{align-items:center;border-radius:0;display:flex;width:100%}modus-wc-menu-item .modus-wc-menu-item button:hover{background-color:transparent}modus-wc-menu-item .modus-wc-menu-item button:focus{background-color:transparent}modus-wc-menu-item .modus-wc-menu-item button.modus-wc-menu-dropdown-toggle::after{color:var(--modus-wc-color-gray-6)}modus-wc-menu-item .modus-wc-menu-item button .modus-wc-menu-item-content{align-items:center;display:flex;width:100%}modus-wc-menu-item .modus-wc-menu-item button .modus-wc-menu-item-content [slot=start-icon]{padding-inline-end:var(--modus-wc-spacing-lg)}modus-wc-menu-item .modus-wc-menu-item button .modus-wc-menu-item-content modus-wc-checkbox{padding-inline-end:var(--modus-wc-spacing-lg)}modus-wc-menu-item .modus-wc-menu-item button .modus-wc-menu-item-content .modus-wc-menu-item-labels{padding-inline-end:var(--modus-wc-spacing-xs);padding-inline-start:var(--modus-wc-spacing-xs)}modus-wc-menu-item .modus-wc-menu-item button .modus-wc-menu-item-content .modus-wc-menu-item-sublabel{font-size:var(--modus-wc-font-size-sm)}modus-wc-menu-item .modus-wc-menu-item button .modus-wc-menu-item-content .modus-wc-menu-item-selected-icon{margin-left:auto}modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-sm button{font-size:var(--modus-wc-font-size-sm)}modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-sm button .modus-wc-menu-item-sublabel{font-size:var(--modus-wc-font-size-xs)}modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-md button{font-size:var(--modus-wc-font-size-md)}modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-md button .modus-wc-menu-item-sublabel{font-size:var(--modus-wc-font-size-sm)}modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-lg button{font-size:var(--modus-wc-font-size-lg)}modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-lg button .modus-wc-menu-item-sublabel{font-size:var(--modus-wc-font-size-md)}modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-bordered{border-bottom:var(--modus-wc-border-width-xs) solid var(--modus-wc-color-base-100);border-radius:0;border-top:var(--modus-wc-border-width-xs) solid var(--modus-wc-color-base-100)}modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-selected){color:var(--modus-wc-color-gray-10)}modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-selected{background-color:var(--modus-wc-color-blue-pale);border-radius:inherit;color:var(--modus-wc-color-primary)}modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-selected:focus{background-color:var(--modus-wc-color-blue-pale)}modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-selected button:hover,modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-selected button:focus{background-color:transparent;box-shadow:none;color:inherit}modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-disabled{opacity:0.4}modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-disabled button{pointer-events:none}modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-disabled):not(:has(.modus-wc-menu-dropdown)):hover{background-color:var(--modus-wc-color-gray-0);color:inherit;outline:none}modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-selected):not(.modus-wc-menu-item-disabled):not(:has(.modus-wc-menu-dropdown)):focus:not(:focus-visible),modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-selected):not(.modus-wc-menu-item-disabled):not(:has(.modus-wc-menu-dropdown)).modus-wc-arrow-focused{background-color:var(--modus-wc-color-gray-0);color:inherit;outline:none}modus-wc-menu-item .modus-wc-menu-item:focus-visible{background-color:transparent;outline:2px solid var(--modus-wc-color-trimble-blue);outline-offset:-2px}[data-theme=modus-classic-dark] modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-selected),[data-theme=modus-modern-dark] modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-selected),[data-theme=connect-dark] modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-selected){color:var(--modus-wc-color-gray-light)}[data-theme=modus-classic-dark] modus-wc-menu-item .modus-wc-menu-item button.modus-wc-menu-dropdown-toggle::after,[data-theme=modus-modern-dark] modus-wc-menu-item .modus-wc-menu-item button.modus-wc-menu-dropdown-toggle::after,[data-theme=connect-dark] modus-wc-menu-item .modus-wc-menu-item button.modus-wc-menu-dropdown-toggle::after{color:var(--modus-wc-color-gray-3)}[data-theme=modus-classic-dark] modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-disabled):not(:has(.modus-wc-menu-dropdown)):hover,[data-theme=modus-modern-dark] modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-disabled):not(:has(.modus-wc-menu-dropdown)):hover,[data-theme=connect-dark] modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-disabled):not(:has(.modus-wc-menu-dropdown)):hover{background-color:var(--modus-wc-color-gray-9);color:inherit;outline:none}[data-theme=modus-classic-dark] modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-selected,[data-theme=modus-modern-dark] modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-selected,[data-theme=connect-dark] modus-wc-menu-item .modus-wc-menu-item.modus-wc-menu-item-selected{background-color:color-mix(in sRGB, var(--modus-wc-color-primary) 30%, transparent)}[data-theme=modus-classic-dark] modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-selected):not(.modus-wc-menu-item-disabled):not(:has(.modus-wc-menu-dropdown)):focus:not(:focus-visible),[data-theme=modus-classic-dark] modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-selected):not(.modus-wc-menu-item-disabled):not(:has(.modus-wc-menu-dropdown)).modus-wc-arrow-focused,[data-theme=modus-modern-dark] modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-selected):not(.modus-wc-menu-item-disabled):not(:has(.modus-wc-menu-dropdown)):focus:not(:focus-visible),[data-theme=modus-modern-dark] modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-selected):not(.modus-wc-menu-item-disabled):not(:has(.modus-wc-menu-dropdown)).modus-wc-arrow-focused,[data-theme=connect-dark] modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-selected):not(.modus-wc-menu-item-disabled):not(:has(.modus-wc-menu-dropdown)):focus:not(:focus-visible),[data-theme=connect-dark] modus-wc-menu-item .modus-wc-menu-item:not(.modus-wc-menu-item-selected):not(.modus-wc-menu-item-disabled):not(:has(.modus-wc-menu-dropdown)).modus-wc-arrow-focused{background-color:var(--modus-wc-color-gray-9)}.modus-wc-menu-item-tooltip{display:inline-block;width:auto}"; const ModusWcMenuItem = /*@__PURE__*/ proxyCustomElement(class ModusWcMenuItem extends H { constructor() { super(); this.__registerHost(); this.itemSelect = createEvent(this, "itemSelect"); this.inheritedAttributes = {}; /** Custom CSS class to apply to the li element. */ this.customClass = ''; /** The text rendered in the menu item. */ this.label = ''; /** The size of the menu item. */ this.size = 'md'; /** The position of the tooltip relative to the menu item. */ this.tooltipPosition = 'auto'; /** The unique identifying value of the menu item. */ this.value = ''; /** Internal state to track if submenu is expanded */ this.isExpanded = false; this.handleKeyDown = (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); this.handleItemSelect(); } }; this.handleItemSelect = () => { // For submenu items, handle the toggle if (this.hasSubmenu) { // Check if side nav is expanded (if this menu is inside a side nav) const sideNav = this.el.closest('modus-wc-side-navigation'); if (sideNav && !sideNav.expanded) { // Don't allow submenu expansion when side nav is collapsed // Still emit the event for consistency this.itemSelect.emit({ value: this.value }); return; } // The submenu should be inside this menu-item element (slotted content) const submenu = this.el.querySelector('.modus-wc-menu-dropdown'); const liElement = this.el.querySelector('li'); if (submenu && liElement) { submenu.classList.toggle('modus-wc-menu-dropdown-show'); const buttonElement = liElement.querySelector('button'); // Update internal expanded state and add/remove class this.isExpanded = submenu.classList.contains('modus-wc-menu-dropdown-show'); if (this.isExpanded) { liElement.classList.add('modus-wc-menu-item-expanded'); if (buttonElement) { buttonElement.classList.add('modus-wc-menu-dropdown-show'); } } else { liElement.classList.remove('modus-wc-menu-item-expanded'); if (buttonElement) { buttonElement.classList.remove('modus-wc-menu-dropdown-show'); } } } } // For checkbox items, provide immediate visual feedback else if (this.checkbox) { const liElement = this.el.querySelector('li'); const checkboxElement = this.el.querySelector('modus-wc-checkbox'); if (liElement) { // Toggle based on current state const isSelected = liElement.classList.contains('modus-wc-menu-item-selected'); if (isSelected) { liElement.classList.remove('modus-wc-menu-item-selected'); } else { liElement.classList.add('modus-wc-menu-item-selected'); } // Update checkbox visual state if (checkboxElement) { checkboxElement.setAttribute('value', (!isSelected).toString()); } this.selected = true; } } // For regular menu items, set selected to true else { this.selected = true; } // Always emit the event with current selection state this.itemSelect.emit({ value: this.value, selected: this.selected }); }; } componentWillLoad() { this.inheritedAttributes = inheritAriaAttributes(this.el); } /** * Public method to collapse the submenu if it's expanded */ async collapseSubmenu() { if (this.hasSubmenu && this.isExpanded) { const submenu = this.el.querySelector('.modus-wc-menu-dropdown'); const liElement = this.el.querySelector('li'); if (submenu && liElement) { submenu.classList.remove('modus-wc-menu-dropdown-show'); liElement.classList.remove('modus-wc-menu-item-expanded'); this.isExpanded = false; } } return Promise.resolve(); } getClasses() { const classList = ['modus-wc-menu-item']; const propClasses = convertPropsToClasses({ bordered: this.bordered, disabled: this.disabled, selected: this.hasSubmenu ? false : this.selected, focused: this.focused, 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(' '); } getButtonClasses() { return this.hasSubmenu ? 'modus-wc-menu-dropdown-toggle' : ''; } render() { return (h(Host, { key: '7d8f11c2661bb48fea599296919753a9afcc6b8b' }, h("li", Object.assign({ key: 'ff0f32cce009f017d91450639ad518bbbd75eec2', "aria-current": this.selected, "aria-disabled": this.disabled, class: this.getClasses(), onKeyDown: this.handleKeyDown, role: "menuitem", tabIndex: this.disabled ? -1 : 0 }, this.inheritedAttributes), h("button", { key: '549d1b8758345179772632fa671dafe0208e8f20', class: this.getButtonClasses(), disabled: this.disabled, onClick: this.handleItemSelect, tabIndex: -1, type: "button" }, h("div", { key: '7aa8b7bd9677b5061e3c5b5878a4dc78579dc131', class: "modus-wc-menu-item-content" }, this.checkbox && (h("modus-wc-checkbox", { key: 'ef1f3f365b85665839fd2a7e46b09457a6ae077c', "aria-label": "Checkbox", disabled: this.disabled, size: this.size, value: !!this.selected })), h("slot", { key: '077efb3c770fc31ab16e29bdcbeac5c15db86b3b', name: "start-icon" }), h("div", { key: '22ae0acc390dddcfa9927a69ee695aadce4ffde9', class: "modus-wc-menu-item-labels" }, this.tooltipContent ? (h("modus-wc-tooltip", { content: this.tooltipContent, position: this.tooltipPosition, customClass: "modus-wc-menu-item-tooltip" }, h("div", null, this.label))) : (h("div", null, this.label)), this.subLabel && (h("div", { key: '683e67e731296b116d92944ef0d109748bf3fcf5', class: "modus-wc-menu-item-sublabel" }, this.subLabel))))), h("slot", { key: '10dfea85bd31f8da1f43ad8e72bf83b4f6293514' })))); } get el() { return this; } static get style() { return modusWcMenuItemCss; } }, [4, "modus-wc-menu-item", { "bordered": [4], "checkbox": [4], "customClass": [1, "custom-class"], "disabled": [4], "label": [1], "startIcon": [1, "start-icon"], "selected": [4], "focused": [4], "size": [1], "subLabel": [1, "sub-label"], "tooltipContent": [1, "tooltip-content"], "tooltipPosition": [1, "tooltip-position"], "value": [1], "hasSubmenu": [4, "has-submenu"], "isExpanded": [32], "collapseSubmenu": [64] }]); function defineCustomElement() { if (typeof customElements === "undefined") { return; } const components = ["modus-wc-menu-item", "modus-wc-checkbox", "modus-wc-input-label", "modus-wc-tooltip"]; components.forEach(tagName => { switch (tagName) { case "modus-wc-menu-item": if (!customElements.get(tagName)) { customElements.define(tagName, ModusWcMenuItem); } break; case "modus-wc-checkbox": if (!customElements.get(tagName)) { defineCustomElement$3(); } break; case "modus-wc-input-label": if (!customElements.get(tagName)) { defineCustomElement$2(); } break; case "modus-wc-tooltip": if (!customElements.get(tagName)) { defineCustomElement$1(); } break; } }); } export { ModusWcMenuItem as M, defineCustomElement as d };