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

558 lines (545 loc) 41.4 kB
import { r as registerInstance, c as createEvent, h, H as Host, g as getElement } from './index-D_4hbGjA.js'; import { i as inheritAriaAttributes, c as generateElementId, b as inheritAttributes } from './utils-DQvnWXRl.js'; import { C as CloseSolidIcon } from './close-solid.icon-BS5SkFPB.js'; import { S as SearchSolidIcon } from './search-solid.icon-BSvIXSEa.js'; import { c as createPopper } from './popper-BfP9ezJQ.js'; const convertPropsToClasses$2 = ({ 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;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 = class { constructor(hostRef) { registerInstance(this, hostRef); this.menuFocusout = createEvent(this, "menuFocusout"); this.inheritedAttributes = {}; /** Custom CSS class to apply to the ul element. */ this.customClass = ''; /** The orientation of the menu. */ this.orientation = 'vertical'; /** The size of the menu. */ this.size = 'md'; this.handleFocusout = (e) => { // Check if the new focus target is still within this menu if (!this.el.contains(e.relatedTarget)) { // Focus has left the menu entirely this.menuFocusout.emit(e); // Stop propagation for submenus to prevent double emission if (this.isSubMenu) { e.stopPropagation(); } } }; this.getMenuRole = () => this.orientation === 'horizontal' ? 'menubar' : 'menu'; } componentWillLoad() { 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$2({ 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(' '); } render() { return (h(Host, { key: '6c84e9bf11325a2f679a9e9c84bbee201f483ec7', class: this.isSubMenu ? 'modus-wc-menu-submenu' : undefined }, h("ul", Object.assign({ key: '095e756b51978dae6468097431cd6f78006a2058', "aria-orientation": this.orientation, class: this.getClasses(), onFocusout: this.handleFocusout, role: this.getMenuRole() }, this.inheritedAttributes), h("slot", { key: 'd8c279b7bdf157f06fde0f1f6a98aba402fb33f5' })))); } get el() { return getElement(this); } }; ModusWcMenu.style = modusWcMenuCss; const convertPropsToClasses$1 = ({ 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 = class { constructor(hostRef) { registerInstance(this, hostRef); 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$1({ 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 getElement(this); } }; ModusWcMenuItem.style = modusWcMenuItemCss; const convertPropsToClasses = ({ bordered, disabled, feedback, readOnly, size, }) => { let classes = ''; if (bordered) { classes = `${classes} modus-wc-input-bordered`; } if (disabled) { classes = `${classes} modus-wc-input-disabled`; } if (feedback) { classes = `${classes} modus-wc-input--${feedback.level}`; } if (readOnly) { classes = `${classes} modus-wc-text-input--readonly`; } if (size) { classes = `${classes} modus-wc-input-${size}`; } return classes.trim(); }; const modusWcTextInputCss = "modus-wc-text-input .modus-wc-input{border-bottom-width:var(--input-bottom-border-width)}modus-wc-text-input .modus-wc-input--error{border-color:var(--modus-wc-color-error) !important}modus-wc-text-input .modus-wc-input--info{border-color:var(--modus-wc-color-info) !important}modus-wc-text-input .modus-wc-input--success{border-color:var(--modus-wc-color-success) !important}modus-wc-text-input .modus-wc-input--warning{border-color:var(--modus-wc-color-warning) !important}modus-wc-text-input .modus-wc-input-xs{height:var(--modus-wc-size-xs);min-height:var(--modus-wc-size-xs)}modus-wc-text-input .modus-wc-input-sm{height:var(--modus-wc-size-sm);min-height:var(--modus-wc-size-sm)}modus-wc-text-input .modus-wc-input-md{height:var(--modus-wc-size-md);min-height:var(--modus-wc-size-md)}modus-wc-text-input .modus-wc-input-lg{height:var(--modus-wc-size-lg);min-height:var(--modus-wc-size-lg)}modus-wc-text-input .modus-wc-input-xl{height:var(--modus-wc-size-xl);min-height:var(--modus-wc-size-xl)}modus-wc-text-input .modus-wc-input-label{padding-bottom:var(--modus-wc-spacing-sm)}modus-wc-text-input .modus-wc-text-input.modus-wc-input{padding:0 var(--modus-wc-spacing-sm)}modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-input-sm .modus-wc-text-input-icon:not(.modus-wc-text-input-icon-custom){height:var(--modus-wc-line-height-sm);width:var(--modus-wc-line-height-sm)}modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-input-md .modus-wc-text-input-icon:not(.modus-wc-text-input-icon-custom){height:var(--modus-wc-line-height-md);width:var(--modus-wc-line-height-md)}modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-input-lg .modus-wc-text-input-icon:not(.modus-wc-text-input-icon-custom){height:var(--modus-wc-line-height-lg);width:var(--modus-wc-line-height-lg)}modus-wc-text-input .modus-wc-text-input.modus-wc-input .modus-wc-text-input-icon.modus-wc-text-input-icon-clear{cursor:pointer}modus-wc-text-input .modus-wc-text-input.modus-wc-input .modus-wc-text-input-icon.modus-wc-text-input-icon-custom{align-items:center;display:flex;flex-shrink:0;justify-content:center}modus-wc-text-input .modus-wc-text-input.modus-wc-input .modus-wc-clear-icon-container{align-items:center;display:flex;justify-content:center;min-width:var(--modus-wc-line-height-md)}modus-wc-text-input .modus-wc-text-input.modus-wc-input .modus-wc-clear-icon-container.modus-wc-clear-icon-hidden{pointer-events:none;visibility:hidden}modus-wc-text-input .modus-wc-text-input.modus-wc-input .modus-wc-clear-icon-container.modus-wc-clear-icon-visible{visibility:visible}modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-input-sm .modus-wc-clear-icon-container{min-width:var(--modus-wc-line-height-sm)}modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-input-lg .modus-wc-clear-icon-container{min-width:var(--modus-wc-line-height-lg)}[data-theme=modus-classic-light] modus-wc-text-input .modus-wc-text-input.modus-wc-input,[data-theme=modus-classic-dark] modus-wc-text-input .modus-wc-text-input.modus-wc-input{border-radius:var(--modus-wc-border-radius-md)}[data-theme=modus-classic-light] modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-input-sm,[data-theme=modus-classic-dark] modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-input-sm{font-size:var(--modus-wc-font-size-sm);height:var(--modus-wc-input-height-sm);line-height:var(--modus-wc-line-height-sm);padding:var(--modus-wc-spacing-sm) var(--modus-wc-spacing-xs)}[data-theme=modus-classic-light] modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-input-md,[data-theme=modus-classic-dark] modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-input-md{font-size:var(--modus-wc-font-size-md);height:var(--modus-wc-input-height-md);line-height:var(--modus-wc-line-height-md);padding:var(--modus-wc-spacing-sm)}[data-theme=modus-classic-light] modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-input-lg,[data-theme=modus-classic-dark] modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-input-lg{font-size:var(--modus-wc-font-size-lg);height:var(--modus-wc-input-height-lg);line-height:var(--modus-wc-line-height-xl);padding:var(--modus-wc-spacing-md) var(--modus-wc-spacing-sm)}[data-theme=modus-classic-light] modus-wc-text-input .modus-wc-text-input.modus-wc-input:focus-within,[data-theme=modus-classic-dark] modus-wc-text-input .modus-wc-text-input.modus-wc-input:focus-within{border-width:var(--modus-wc-border-width-sm);box-shadow:none;outline:none}[data-theme=modus-classic-light] modus-wc-text-input .modus-wc-text-input.modus-wc-input .modus-wc-text-input-icon.modus-wc-text-input-icon-clear:focus:not(:focus-visible),[data-theme=modus-classic-dark] modus-wc-text-input .modus-wc-text-input.modus-wc-input .modus-wc-text-input-icon.modus-wc-text-input-icon-clear:focus:not(:focus-visible){outline:none}[data-theme=modus-classic-light] modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-text-input--readonly,[data-theme=modus-classic-dark] modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-text-input--readonly{background-color:var(--modus-wc-color-base-100)}[data-theme=modus-classic-light] modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-input-bordered:not(:disabled){border-color:var(--modus-wc-color-accent)}[data-theme=modus-classic-light] modus-wc-text-input .modus-wc-text-input.modus-wc-input.modus-wc-input-bordered:not(:disabled):focus-within{border-color:var(--modus-wc-color-blue-light)}[data-theme=modus-classic-light] modus-wc-text-input .modus-wc-text-input.modus-wc-input .modus-wc-text-input-icon{color:var(--modus-wc-color-gray-8)}[data-theme=modus-classic-dark] modus-wc-text-input .modus-wc-text-input.modus-wc-input .modus-wc-text-input-icon{color:var(--modus-wc-color-gray-2)}[data-theme=modus-classic-dark] modus-wc-text-input .modus-wc-text-input.modus-wc-input:focus-within{border-color:var(--modus-wc-color-highlight-blue)}[data-theme=connect-light] modus-wc-text-input .modus-wc-text-input,[data-theme=connect-dark] modus-wc-text-input .modus-wc-text-input{border-bottom-width:var(--input-bottom-border-width);outline-width:0 !important}[data-theme=connect-light] modus-wc-text-input .modus-wc-text-input:not(.modus-wc-select,.modus-wc-number-input),[data-theme=connect-dark] modus-wc-text-input .modus-wc-text-input:not(.modus-wc-select,.modus-wc-number-input){padding:0 var(--modus-wc-spacing-sm)}[data-theme=connect-light] modus-wc-text-input .modus-wc-text-input:hover,[data-theme=connect-dark] modus-wc-text-input .modus-wc-text-input:hover{border-bottom-color:var(--modus-wc-color-primary)}[data-theme=connect-light] modus-wc-text-input .modus-wc-text-input:active,[data-theme=connect-dark] modus-wc-text-input .modus-wc-text-input:active{border-bottom-color:var(--modus-wc-color-primary)}[data-theme=connect-light] modus-wc-text-input .modus-wc-text-input:focus,[data-theme=connect-dark] modus-wc-text-input .modus-wc-text-input:focus{border-bottom-color:var(--modus-wc-color-primary);outline:none}[data-theme=connect-light] modus-wc-text-input .modus-wc-text-input:focus-within,[data-theme=connect-dark] modus-wc-text-input .modus-wc-text-input:focus-within{border-bottom-color:var(--modus-wc-color-primary);outline:none}"; const ModusWcTextInput = class { constructor(hostRef) { registerInstance(this, hostRef); this.clearClick = createEvent(this, "clearClick"); this.inputBlur = createEvent(this, "inputBlur"); this.inputChange = createEvent(this, "inputChange"); this.inputFocus = createEvent(this, "inputFocus"); this.inheritedAttributes = {}; this.generatedId = generateElementId(); /** Indicates that the input should have a border. */ this.bordered = true; /** Aria label for the clear icon button. */ this.clearAriaLabel = 'Clear text'; /** Custom CSS class to apply to the input. */ this.customClass = ''; /** Whether the form control is disabled. */ this.disabled = false; /** Show the clear button within the input field. */ this.includeClear = false; /** Show the search icon within the input field. */ this.includeSearch = false; /** Text that appears in the form control when it has no value set. */ this.placeholder = ''; /** Whether the value is editable. */ this.readOnly = false; /** A value is required for the form to be submittable. */ this.required = false; /** The size of the input. */ this.size = 'md'; /** Type of form control. */ this.type = 'text'; /** The value of the control. */ this.value = ''; this.handleBlur = (event) => { this.inputBlur.emit(event); }; this.handleClearText = (event) => { this.value = ''; this.inputChange.emit(event); this.clearClick.emit(); }; this.handleFocus = (event) => { this.inputFocus.emit(event); }; this.handleInput = (event) => { this.value = event.target.value; this.inputChange.emit(event); }; } componentWillLoad() { if (!this.el.ariaLabel) { this.el.ariaLabel = this.placeholder || 'Text input'; } this.inheritedAttributes = Object.assign(Object.assign({}, inheritAriaAttributes(this.el)), inheritAttributes(this.el, ['spellcheck', 'inputmode'])); if (!this.el.hasAttribute('inputmode') && !this.inheritedAttributes.inputmode) { this.el.setAttribute('inputmode', 'text'); } } getClasses() { const classList = [ 'modus-wc-text-input', 'modus-wc-input', 'modus-wc-w-full', 'modus-wc-flex', 'modus-wc-items-center', 'modus-wc-gap-1', ]; const propClasses = convertPropsToClasses({ bordered: this.bordered, disabled: this.disabled, feedback: this.feedback, readOnly: this.readOnly, 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(' '); } shouldIncludeClear() { return (!!this.includeClear && !this.disabled && !this.readOnly && !!this.value); } render() { const showClear = this.shouldIncludeClear(); const effectiveId = this.inputId || this.generatedId; const hasCustomIcon = !!this.el.querySelector('[slot="custom-icon"]'); return (h(Host, { key: '0e7bdce5e281ea9630c19cb0b8e7c791b9b84a9b' }, this.label && (h("modus-wc-input-label", { key: 'eddf5e49410f94cc182bc51b97e4ef91c3918322', forId: effectiveId, labelText: this.label, required: this.required, size: this.size })), h("label", { key: 'e9f5f5e880bb6610316c9cec6875608a13f59fc3', class: this.getClasses() }, hasCustomIcon ? (h("div", { class: "modus-wc-text-input-icon modus-wc-text-input-icon-custom" }, h("slot", { name: "custom-icon" }))) : (this.includeSearch && (h(SearchSolidIcon, { className: "modus-wc-text-input-icon modus-wc-text-input-icon-search" }))), h("input", Object.assign({ key: 'dc972a389b04a6d73afb93799431a52e5e163c96', "aria-required": this.required, autocapitalize: this.autoCapitalize, autocomplete: this.autoComplete, autocorrect: this.autoCorrect, class: "modus-wc-grow", disabled: this.disabled, enterkeyhint: this.enterkeyhint, id: effectiveId, maxlength: this.maxLength, minlength: this.minLength, name: this.name, onBlur: this.handleBlur, onFocus: this.handleFocus, onInput: this.handleInput, pattern: this.pattern, placeholder: this.placeholder, readonly: this.readOnly, required: this.required, tabIndex: this.inputTabIndex, type: this.type, value: this.value }, this.inheritedAttributes)), this.includeClear && (h("div", { key: '9ba4799eb5b808a7f5d01cf66738e10c3c6d8957', class: `modus-wc-clear-icon-container ${showClear ? 'modus-wc-clear-icon-visible' : 'modus-wc-clear-icon-hidden'}` }, h(CloseSolidIcon, { key: '3edd47bd185a5de2b2023f3472b8900cedb4b683', ariaLabel: this.clearAriaLabel, className: "modus-wc-text-input-icon modus-wc-text-input-icon-clear", decorative: false, onClear: this.handleClearText })))), this.feedback && (h("modus-wc-input-feedback", { key: 'f1fc2d8df7fe7973e9b669dead0abf9d74a41dd6', level: this.feedback.level, message: this.feedback.message, size: this.size })))); } get el() { return getElement(this); } }; ModusWcTextInput.style = modusWcTextInputCss; const modusWcTooltipCss = ".modus-wc-tooltip-content{background-color:var(--modus-wc-color-neutral-content);border-radius:0.25rem;color:var(--modus-wc-color-neutral);font-size:0.875rem;font-weight:var(--modus-wc-font-weight-regular);max-width:20rem;overflow-wrap:break-word;padding:0.25rem 0.5rem;pointer-events:none;position:relative;text-align:center;white-space:normal;width:max-content;word-break:break-word;z-index:1000}.modus-wc-tooltip-arrow,.modus-wc-tooltip-arrow::before{background:inherit;height:8px;position:absolute;width:8px}.modus-wc-tooltip-arrow{text-align:initial;visibility:hidden}.modus-wc-tooltip-arrow::before{background-color:var(--modus-wc-color-neutral-content);content:\"\";transform:rotate(45deg);visibility:visible}.modus-wc-tooltip-content[data-popper-placement^=top] .modus-wc-tooltip-arrow{bottom:-4px}.modus-wc-tooltip-content[data-popper-placement^=bottom] .modus-wc-tooltip-arrow{top:-4px}.modus-wc-tooltip-content[data-popper-placement^=left] .modus-wc-tooltip-arrow{right:-4px}.modus-wc-tooltip-content[data-popper-placement^=right] .modus-wc-tooltip-arrow{left:-4px}[data-theme=modus-classic-light] .modus-wc-tooltip-content{background-color:var(--modus-wc-color-gray-7);color:var(--modus-wc-color-white)}[data-theme=modus-classic-light] .modus-wc-tooltip-arrow::before{background-color:var(--modus-wc-color-gray-7)}[data-theme=modus-classic-dark] .modus-wc-tooltip-content{background-color:var(--modus-wc-color-gray-0);color:var(--modus-wc-color-trimble-gray)}[data-theme=modus-classic-dark] .modus-wc-tooltip-arrow::before{background-color:var(--modus-wc-color-gray-0)}[data-theme=connect-light] .modus-wc-tooltip-content,[data-theme=connect-dark] .modus-wc-tooltip-content{background-color:var(--modus-wc-color-base-content);color:var(--modus-wc-color-base-page)}[data-theme=connect-light] .modus-wc-tooltip-arrow::before,[data-theme=connect-dark] .modus-wc-tooltip-arrow::before{background-color:var(--modus-wc-color-base-content)}"; const ModusWcTooltip = class { constructor(hostRef) { registerInstance(this, hostRef); this.dismissEscape = createEvent(this, "dismissEscape"); this.inheritedAttributes = {}; this.popperInstance = null; this.tooltipElement = null; this.triggerElement = null; /** The text content of the tooltip. */ this.content = ''; /** Custom CSS class to apply to the inner div. */ this.customClass = ''; /** Disables displaying the tooltip on hover */ this.disabled = false; /** The position that the tooltip will render in relation to the element. */ this.position = 'auto'; /** Track if tooltip was dismissed with Escape key */ this.escapeDismissed = false; /** Track if tooltip is currently visible */ this.isVisible = false; this.handleWindowResize = () => { if (this.popperInstance && this.isVisible) { void this.popperInstance.update(); } }; this.handleWindowScroll = () => { if (this.popperInstance && this.isVisible) { void this.popperInstance.update(); } }; } componentWillLoad() { this.inheritedAttributes = inheritAriaAttributes(this.el); } elementKeyupHandler(event) { switch (event.code) { case 'Escape': { // Allow Escape to dismiss tooltip when it's visible // When forceOpen is true, Escape should NOT dismiss it if (this.isVisible && !this.forceOpen) { this.escapeDismissed = true; this.dismissEscape.emit(); this.hideTooltip(); } break; } } } componentDidLoad() { this.triggerElement = this.el.querySelector('div > :first-child'); this.tooltipElement = document.createElement('div'); this.tooltipElement.className = `modus-wc-tooltip-content ${this.customClass || ''}`; this.tooltipElement.textContent = this.content; this.tooltipElement.setAttribute('role', 'tooltip'); if (this.tooltipId) { this.tooltipElement.id = this.tooltipId; } const arrow = document.createElement('div'); arrow.className = 'modus-wc-tooltip-arrow'; this.tooltipElement.appendChild(arrow); document.body.appendChild(this.tooltipElement); this.tooltipElement.style.display = 'none'; if (this.triggerElement && this.tooltipElement) { this.initializePopper(); } if (this.forceOpen && !this.disabled && !this.escapeDismissed) { this.showTooltip(); } } disconnectedCallback() { if (this.popperInstance) { this.popperInstance.destroy(); this.popperInstance = null; } if (this.tooltipElement && document.body.contains(this.tooltipElement)) { document.body.removeChild(this.tooltipElement); } window.removeEventListener('resize', this.handleWindowResize); window.removeEventListener('scroll', this.handleWindowScroll, true); } initializePopper() { if (!this.triggerElement || !this.tooltipElement) return; const placement = this.position === 'auto' ? 'top' : this.position; const arrowElement = this.tooltipElement.querySelector('.modus-wc-tooltip-arrow'); this.popperInstance = createPopper(this.triggerElement, this.tooltipElement, { placement, strategy: 'absolute', modifiers: [ { name: 'offset', options: { offset: [0, 8], }, }, { name: 'preventOverflow', options: { padding: 8, boundary: 'viewport', }, }, { name: 'flip', options: { fallbackPlacements: ['top', 'right', 'bottom', 'left'], padding: 8, boundary: 'viewport', }, }, { name: 'arrow', options: { element: arrowElement, padding: 5, }, }, { name: 'computeStyles', options: { adaptive: true, gpuAcceleration: true, }, }, { name: 'eventListeners', options: { scroll: true, resize: true, }, }, ], }); window.addEventListener('resize', this.handleWindowResize); window.addEventListener('scroll', this.handleWindowScroll, true); } showTooltip() { if (this.disabled || this.escapeDismissed || !this.tooltipElement) return; this.tooltipElement.style.display = 'block'; this.isVisible = true; if (this.popperInstance) { void this.popperInstance.update(); // Force a second update after a short delay to ensure arrow positioning setTimeout(() => { if (this.popperInstance) { void this.popperInstance.update(); } }, 10); } } hideTooltip() { if (!this.tooltipElement) return; if (!this.forceOpen || this.escapeDismissed) { this.tooltipElement.style.display = 'none'; this.isVisible = false; } } handlePositionChange() { if (this.popperInstance) { void this.popperInstance.setOptions({ placement: this.position === 'auto' ? 'top' : this.position, }); void this.popperInstance.update(); } } handleContentChange(newContent) { if (this.tooltipElement) { const arrow = this.tooltipElement.querySelector('.modus-wc-tooltip-arrow'); this.tooltipElement.textContent = newContent; if (arrow) { this.tooltipElement.appendChild(arrow); } } } handleForceOpenChange(forceOpen) { if (forceOpen && !this.disabled) { this.showTooltip(); } else { this.hideTooltip(); } } handleMouseEnter() { this.escapeDismissed = false; this.showTooltip(); } handleMouseLeave() { if (!this.forceOpen) { this.hideTooltip(); } } render() { return (h(Host, { key: '028f22dad1fdd4537bd012847d785b8d518d55b2' }, h("div", Object.assign({ key: '9638d7b4536e70c3a38ee3c7b81d27a69effd148', "aria-describedby": this.tooltipId, id: this.tooltipId }, this.inheritedAttributes), h("slot", { key: '326d59ea026f46496671e1eb4238ae59d6ec320d' })))); } get el() { return getElement(this); } static get watchers() { return { "position": ["handlePositionChange"], "content": ["handleContentChange"], "forceOpen": ["handleForceOpenChange"] }; } }; ModusWcTooltip.style = modusWcTooltipCss; export { ModusWcMenu as modus_wc_menu, ModusWcMenuItem as modus_wc_menu_item, ModusWcTextInput as modus_wc_text_input, ModusWcTooltip as modus_wc_tooltip };