@felleslosninger/minid-elements 0.0.117 → 0.0.119
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/combobox.component.d.ts +1 -1
- package/dist/components/combobox.component.d.ts.map +1 -1
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/dropdown.component.d.ts +6 -0
- package/dist/components/dropdown.component.d.ts.map +1 -1
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/menu.component.d.ts.map +1 -1
- package/dist/components/menu.js +0 -7
- package/dist/components/menu.js.map +1 -1
- package/dist/mixins/tailwind.mixin.d.ts.map +1 -1
- package/dist/mixins/tailwind.mixin.js.map +1 -1
- package/package.json +1 -1
|
@@ -46,7 +46,7 @@ export declare class MinidCombobox extends MinidCombobox_base {
|
|
|
46
46
|
* The combobox will close when the user interacts outside of this element (e.g. clicking). Useful for composing other
|
|
47
47
|
* components that use a combobox internally.
|
|
48
48
|
*/
|
|
49
|
-
containingElement
|
|
49
|
+
private containingElement?;
|
|
50
50
|
connectedCallback(): void;
|
|
51
51
|
firstUpdated(): void;
|
|
52
52
|
disconnectedCallback(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combobox.component.d.ts","sourceRoot":"","sources":["../../src/components/combobox.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAE,MAAM,KAAK,CAAC;AAO5C,OAAO,mBAAmB,CAAC;AAY3B,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAKzD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,aAAa,CAAC;KAC/B;CACF;;AAUD;;;;GAIG;AACH,qBACa,aAAc,SAAQ,kBAA0B;IAC3D,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,cAAc,CAAwD;IAG9E,OAAO,CAAC,KAAK,CAAc;IAG3B,OAAO,CAAC,OAAO,CAAmB;IAGlC,OAAO,CAAC,KAAK,CAAmB;IAGhC,OAAO,CAAC,eAAe,CAInB;IAEJ;;;OAGG;IAEH,gBAAgB,UAAS;IAEzB;;OAEG;IAEH,IAAI,UAAS;IAGb,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAEhC;;OAEG;IAEH,QAAQ,SAAK;IAEb;;OAEG;IAEH,QAAQ,SAAK;IAEb;;;OAGG;IAEH,KAAK,UAAS;IAGd,QAAQ,UAAS;IAEjB;;;OAGG;IAEH,
|
|
1
|
+
{"version":3,"file":"combobox.component.d.ts","sourceRoot":"","sources":["../../src/components/combobox.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAE,MAAM,KAAK,CAAC;AAO5C,OAAO,mBAAmB,CAAC;AAY3B,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAKzD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,aAAa,CAAC;KAC/B;CACF;;AAUD;;;;GAIG;AACH,qBACa,aAAc,SAAQ,kBAA0B;IAC3D,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,cAAc,CAAwD;IAG9E,OAAO,CAAC,KAAK,CAAc;IAG3B,OAAO,CAAC,OAAO,CAAmB;IAGlC,OAAO,CAAC,KAAK,CAAmB;IAGhC,OAAO,CAAC,eAAe,CAInB;IAEJ;;;OAGG;IAEH,gBAAgB,UAAS;IAEzB;;OAEG;IAEH,IAAI,UAAS;IAGb,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAEhC;;OAEG;IAEH,QAAQ,SAAK;IAEb;;OAEG;IAEH,QAAQ,SAAK;IAEb;;;OAGG;IAEH,KAAK,UAAS;IAGd,QAAQ,UAAS;IAEjB;;;OAGG;IAEH,OAAO,CAAC,iBAAiB,CAAC,CAAc;IAExC,iBAAiB;IAQjB,YAAY;IAsBZ,oBAAoB;IAMpB,cAAc;IAUd,OAAO,IAID,SAAS,GACT,SAAS;IAGf,OAAO,CAAC,kBAAkB,CAWxB;IAEF,OAAO,CAAC,aAAa,CAQnB;IAEF,OAAO,CAAC,qBAAqB,CAmC3B;IAEF,OAAO,CAAC,uBAAuB,CAM7B;IAEF,OAAO,CAAC,iBAAiB,CAiBvB;IAEF,kBAAkB;IAaZ,oBAAoB,CAAC,KAAK,EAAE,aAAa;IA4D/C,kBAAkB,CAAC,KAAK,EAAE,aAAa;IAOvC,uBAAuB;IAcvB,uBAAuB;IAyBvB;;OAEG;IACG,IAAI;IASV;;OAEG;IACG,IAAI;IASV;;;OAGG;IACH,UAAU;IAIV,gBAAgB;IAchB,mBAAmB;IAOb,gBAAgB;IA0Cb,MAAM;CAwChB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combobox.js","sources":["../../src/components/combobox.component.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport {\n customElement,\n property,\n query,\n queryAssignedElements,\n} from 'lit/decorators.js';\nimport './popup.component';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport { MinidPopup } from './popup.component';\nimport { waitForEvent } from '../internal/event';\nimport { watch } from '../internal/watch';\nimport {\n getAnimation,\n setDefaultAnimation,\n} from '../utilities/animation-registry';\nimport { animateTo, stopAnimations } from '../internal/animate';\nimport { getTabbableBoundary } from '../internal/tabbable';\nimport { MinidButton } from './button.component';\nimport { MinidMenu } from '../components/menu.component';\nimport { MinidPhoneInput } from '../components/phone-input.component';\nimport { MinidTextfield } from '../components/textfield.component';\nimport { MinidMenuItem } from '../components/menu-item.component.ts';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-combobox': MinidCombobox;\n }\n}\n\nconst styles = [\n css`\n :host {\n display: flex;\n }\n `,\n];\n\n/**\n * @slot -- Default slot for content of the dropdown panel\n * @slot trigger - Used for the button element that will be used to open the dropdown menu\n * @part panel - Select the dropdown panel host element\n */\n@customElement('mid-combobox')\nexport class MinidCombobox extends styled(LitElement, styles) {\n private closeWatcher?: CloseWatcher;\n private triggerElement: 'mid-textfield' | 'mid-phone-input' = 'mid-textfield';\n\n @query('#combobox')\n private popup!: MinidPopup;\n\n @query('.combobox__trigger')\n private trigger!: HTMLSlotElement;\n\n @query('.combobox__panel')\n private panel!: HTMLSlotElement;\n\n @queryAssignedElements({ slot: 'trigger' })\n private triggerElements!: (\n | MinidTextfield\n | MinidPhoneInput\n | HTMLInputElement\n )[];\n\n /**\n * By default, the combobox is closed when an item is selected. This attribute will keep it open instead. Useful for\n * comboboxs that allow for multiple interactions.\n */\n @property({ type: Boolean, reflect: true })\n stayopenonselect = false;\n\n /**\n * Indicates wether the combobox panel is open. You can use this or the show/hide methods.\n */\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @property()\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Distance between trigger and combobox panel\n */\n @property({ type: Number })\n distance = 4;\n\n /**\n * Nudge the combobox panel position. Accepts a negative or positive number.\n */\n @property({ type: Number })\n skidding = 0;\n\n /**\n * Choose if position is `fixed` or `absolute`. `absolute` is more performant,\n * but `fixed` can solve issues with overflow clipping\n */\n @property({ type: Boolean })\n hoist = false;\n\n @property({ type: Boolean })\n disabled = false;\n\n /**\n * The combobox will close when the user interacts outside of this element (e.g. clicking). Useful for composing other\n * components that use a combobox internally.\n */\n @property({ attribute: false })\n containingElement?: HTMLElement;\n\n connectedCallback() {\n super.connectedCallback();\n\n if (!this.containingElement) {\n this.containingElement = this;\n }\n }\n\n firstUpdated() {\n const input = this.triggerElements[0];\n if (input.tagName.toLowerCase() === 'mid-phone-input') {\n this.triggerElement = 'mid-phone-input';\n } else if (input.tagName.toLowerCase() === 'mid-textfield') {\n this.triggerElement = 'mid-textfield';\n }\n\n this.panel.hidden = !this.open;\n\n const menu = this.getMenu();\n if (menu) {\n menu.variant = 'combobox';\n }\n\n // If the combobox panel is visible on init, update its position\n if (this.open) {\n this.addOpenListeners();\n this.popup.active = true;\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeOpenListeners();\n this.hide();\n }\n\n focusOnTrigger() {\n const trigger = this.trigger.assignedElements({ flatten: true })[0] as\n | HTMLElement\n | undefined;\n\n if (typeof trigger?.focus === 'function') {\n trigger.focus();\n }\n }\n\n getMenu() {\n return this.panel\n .assignedElements({ flatten: true })\n .find((el) => el.tagName.toLowerCase() === 'mid-menu') as\n | MinidMenu\n | undefined;\n }\n\n private handleCountryClick = () => {\n const menu = this.getMenu();\n\n this.open ? this.hide() : this.show();\n if (this.open && menu && menu.searchable) {\n // Delay focus slightly to win the focus battle\n setTimeout(() => {\n menu.clearFilter();\n menu.focusSearchField();\n }, 1);\n }\n };\n\n private handleKeyDown = (event: KeyboardEvent) => {\n // Close when escape is pressed inside an open combobox. We need to listen on the panel itself and stop propagation\n // in case any ancestors are also listening for this key.\n if (this.open && event.key === 'Escape') {\n event.stopPropagation();\n this.hide();\n this.focusOnTrigger();\n }\n };\n\n private handleDocumentKeyDown = (event: KeyboardEvent) => {\n // Close when escape or tab is pressed\n if (event.key === 'Escape' && this.open && !this.closeWatcher) {\n event.stopPropagation();\n this.focusOnTrigger();\n this.hide();\n return;\n }\n\n // Handle tabbing\n if (event.key === 'Tab') {\n const composedPath = event.composedPath();\n const tabbedIsMenuItem = composedPath.some(\n (e): e is MinidMenuItem =>\n (e as HTMLElement).tagName?.toLowerCase() === 'mid-menu-item'\n );\n\n // Tabbing within an open menu should close the combobox and refocus the trigger\n if (this.open && tabbedIsMenuItem) {\n event.preventDefault();\n this.hide();\n this.focusOnTrigger();\n return;\n }\n\n // Tabbing outside of the containing element closes the panel\n //\n // If the combobox is used within a shadow DOM, we need to obtain the activeElement within that shadowRoot,\n // otherwise `document.activeElement` will only return the name of the parent shadow DOM element.\n setTimeout(() => {\n if (composedPath.every((target) => target !== this.containingElement)) {\n this.hide();\n }\n });\n }\n };\n\n private handleDocumentMouseDown = (event: MouseEvent) => {\n // Close when clicking outside of the containing element\n const path = event.composedPath();\n if (this.containingElement && !path.includes(this.containingElement)) {\n this.hide();\n }\n };\n\n private handlePanelSelect = (event: CustomEvent) => {\n if (this.triggerElement !== 'mid-phone-input') {\n return;\n }\n\n // Transfer selected country from panel to input field\n const input = this.triggerElements[0] as MinidPhoneInput;\n const country = event.detail.item.value;\n input.country = country;\n\n const target = event.target as HTMLElement;\n\n // Hide the combobox when a menu item is selected\n if (!this.stayopenonselect && target.tagName.toLowerCase() === 'mid-menu') {\n this.hide();\n this.focusOnTrigger();\n }\n };\n\n handleTriggerClick() {\n if (this.triggerElement === 'mid-phone-input') {\n return;\n }\n\n if (this.open) {\n this.hide();\n } else {\n this.show();\n this.focusOnTrigger();\n }\n }\n\n async handleTriggerKeyDown(event: KeyboardEvent) {\n // When spacebar/enter is pressed, show the panel but don't focus on the menu. This let's the user press the same\n // key again to hide the menu in case they don't want to make a selection.\n if ([' ', 'Enter'].includes(event.key)) {\n event.preventDefault();\n if (this.triggerElement === 'mid-textfield') {\n this.handleTriggerClick();\n }\n return;\n }\n\n const menu = this.getMenu();\n\n if (menu) {\n const menuItems = menu.getAllSelectableItems();\n const firstMenuItem = menuItems[0];\n const lastMenuItem = menuItems[menuItems.length - 1];\n\n // When up/down is pressed, we make the assumption that the user is familiar with the menu and plans to make a\n // selection. Rather than toggle the panel, we focus on the menu (if one exists) and activate the first item for\n // faster navigation.\n if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {\n event.preventDefault();\n\n // Show the menu if it's not already open\n if (!this.open) {\n this.show();\n\n // Wait for the combobox to open before focusing, but not the animation\n await this.updateComplete;\n }\n\n if (menuItems.length > 0) {\n // Focus on the first/last menu item after showing\n this.updateComplete.then(() => {\n if (event.key === 'ArrowDown' || event.key === 'Home') {\n menu.setCurrentItem(firstMenuItem);\n if (this.triggerElement === 'mid-textfield') {\n firstMenuItem.focus();\n } else {\n menu.clearFilter();\n menu.focusSearchField();\n }\n }\n\n if (event.key === 'ArrowUp' || event.key === 'End') {\n menu.setCurrentItem(lastMenuItem);\n if (this.triggerElement === 'mid-textfield') {\n lastMenuItem.focus();\n } else {\n menu.clearFilter();\n menu.focusSearchField();\n }\n }\n });\n }\n }\n }\n }\n\n handleTriggerKeyUp(event: KeyboardEvent) {\n // Prevent space from triggering a click event in Firefox\n if (event.key === ' ') {\n event.preventDefault();\n }\n }\n\n handleTriggerSlotChange() {\n this.updateAccessibleTrigger();\n }\n\n //\n // Slotted triggers can be arbitrary content, but we need to link them to the combobox panel with `aria-haspopup` and\n // `aria-expanded`. These must be applied to the \"accessible trigger\" (the tabbable portion of the trigger element\n // that gets slotted in) so screen readers will understand them. The accessible trigger could be the slotted element,\n // a child of the slotted element, or an element in the slotted element's shadow root.\n //\n // For example, the accessible trigger of an <sl-button> is a <button> located inside its shadow root.\n //\n // To determine this, we assume the first tabbable element in the trigger slot is the \"accessible trigger.\"\n //\n updateAccessibleTrigger() {\n const assignedElements = this.trigger.assignedElements({\n flatten: true,\n }) as HTMLElement[];\n const accessibleTrigger = assignedElements.find(\n (el) => getTabbableBoundary(el).start\n );\n let target: HTMLElement;\n\n if (accessibleTrigger) {\n switch (accessibleTrigger.tagName.toLowerCase()) {\n // buttons have to update the internal button so it's announced correctly by screen readers\n case 'mid-button':\n target = (accessibleTrigger as MinidButton).button;\n break;\n\n default:\n target = accessibleTrigger;\n }\n\n target.setAttribute('aria-haspopup', 'true');\n target.setAttribute('aria-expanded', this.open ? 'true' : 'false');\n }\n }\n\n /**\n * Shows the combobox panel.\n */\n async show() {\n if (this.open) {\n return undefined;\n }\n\n this.open = true;\n return waitForEvent(this, 'mid-after-show');\n }\n\n /**\n * Hides the combobox panel\n */\n async hide() {\n if (!this.open) {\n return undefined;\n }\n\n this.open = false;\n return waitForEvent(this, 'mid-after-hide');\n }\n\n /**\n * Instructs the combobox menu to reposition. Useful when the position or size of the trigger changes when the menu\n * is activated.\n */\n reposition() {\n this.popup.reposition();\n }\n\n addOpenListeners() {\n if ('CloseWatcher' in window) {\n this.closeWatcher?.destroy();\n this.closeWatcher = new CloseWatcher();\n this.closeWatcher.onclose = () => {\n this.hide();\n this.focusOnTrigger();\n };\n }\n\n document.addEventListener('keydown', this.handleDocumentKeyDown);\n document.addEventListener('mousedown', this.handleDocumentMouseDown);\n }\n\n removeOpenListeners() {\n document.removeEventListener('keydown', this.handleDocumentKeyDown);\n document.removeEventListener('mousedown', this.handleDocumentMouseDown);\n this.closeWatcher?.destroy();\n }\n\n @watch('open', { waitUntilFirstUpdate: true })\n async handleOpenChange() {\n if (this.disabled) {\n this.open = false;\n return;\n }\n\n this.updateAccessibleTrigger();\n\n if (this.open) {\n // Show\n this.dispatchEvent(\n new Event('mid-show', { bubbles: true, composed: true })\n );\n this.addOpenListeners();\n\n await stopAnimations(this);\n this.panel.hidden = false;\n this.popup.active = true;\n const { keyframes, options } = getAnimation(this, 'combobox.show');\n await animateTo(this.popup.popup, keyframes, options);\n\n this.dispatchEvent(\n new Event('mid-after-show', { bubbles: true, composed: true })\n );\n } else {\n // Hide\n this.dispatchEvent(\n new Event('mid-hide', { bubbles: true, composed: true })\n );\n this.removeOpenListeners();\n await stopAnimations(this);\n const { keyframes, options } = getAnimation(this, 'combobox.hide');\n await animateTo(this.popup.popup, keyframes, options);\n this.panel.hidden = true;\n this.popup.active = false;\n\n this.dispatchEvent(\n new Event('mid-after-hide', { bubbles: true, composed: true })\n );\n }\n }\n\n override render() {\n return html`\n <mid-popup\n id=\"combobox\"\n distance=${this.distance}\n placement=\"bottom-end\"\n skidding=${this.skidding}\n strategy=${this.hoist ? 'fixed' : 'absolute'}\n flip\n shift\n auto-size=\"vertical\"\n auto-size-padding=\"10\"\n sync=\"width\"\n ?active=${this.open}\n >\n <slot\n class=\"combobox__trigger\"\n slot=\"anchor\"\n name=\"trigger\"\n @click=${this.handleTriggerClick}\n @keydown=${this.handleTriggerKeyDown}\n @keyup=${this.handleTriggerKeyUp}\n @slotchange=${this.handleTriggerSlotChange}\n @mid-country-click=${this.handleCountryClick}\n ></slot>\n <div\n class=\"bg-accent\"\n aria-hidden=${this.open ? 'false' : 'true'}\n aria-labelledby=\"combobox\"\n >\n <slot\n class=\"combobox__panel\"\n part=\"panel\"\n @keydown=${this.handleKeyDown}\n @mid-select=${this.handlePanelSelect}\n ></slot>\n </div>\n </mid-popup>\n `;\n }\n}\n\nsetDefaultAnimation('combobox.show', {\n keyframes: [\n { opacity: 0, scale: 0.9 },\n { opacity: 1, scale: 1 },\n ],\n options: { duration: 100, easing: 'ease' },\n});\n\nsetDefaultAnimation('combobox.hide', {\n keyframes: [\n { opacity: 1, scale: 1 },\n { opacity: 0, scale: 0.9 },\n ],\n options: { duration: 100, easing: 'ease' },\n});\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"combobox.js","sources":["../../src/components/combobox.component.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport {\n customElement,\n property,\n query,\n queryAssignedElements,\n} from 'lit/decorators.js';\nimport './popup.component';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport { MinidPopup } from './popup.component';\nimport { waitForEvent } from '../internal/event';\nimport { watch } from '../internal/watch';\nimport {\n getAnimation,\n setDefaultAnimation,\n} from '../utilities/animation-registry';\nimport { animateTo, stopAnimations } from '../internal/animate';\nimport { getTabbableBoundary } from '../internal/tabbable';\nimport { MinidButton } from './button.component';\nimport { MinidMenu } from '../components/menu.component';\nimport { MinidPhoneInput } from '../components/phone-input.component';\nimport { MinidTextfield } from '../components/textfield.component';\nimport { MinidMenuItem } from '../components/menu-item.component.ts';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-combobox': MinidCombobox;\n }\n}\n\nconst styles = [\n css`\n :host {\n display: flex;\n }\n `,\n];\n\n/**\n * @slot -- Default slot for content of the dropdown panel\n * @slot trigger - Used for the button element that will be used to open the dropdown menu\n * @part panel - Select the dropdown panel host element\n */\n@customElement('mid-combobox')\nexport class MinidCombobox extends styled(LitElement, styles) {\n private closeWatcher?: CloseWatcher;\n private triggerElement: 'mid-textfield' | 'mid-phone-input' = 'mid-textfield';\n\n @query('#combobox')\n private popup!: MinidPopup;\n\n @query('.combobox__trigger')\n private trigger!: HTMLSlotElement;\n\n @query('.combobox__panel')\n private panel!: HTMLSlotElement;\n\n @queryAssignedElements({ slot: 'trigger' })\n private triggerElements!: (\n | MinidTextfield\n | MinidPhoneInput\n | HTMLInputElement\n )[];\n\n /**\n * By default, the combobox is closed when an item is selected. This attribute will keep it open instead. Useful for\n * comboboxs that allow for multiple interactions.\n */\n @property({ type: Boolean, reflect: true })\n stayopenonselect = false;\n\n /**\n * Indicates wether the combobox panel is open. You can use this or the show/hide methods.\n */\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @property()\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Distance between trigger and combobox panel\n */\n @property({ type: Number })\n distance = 4;\n\n /**\n * Nudge the combobox panel position. Accepts a negative or positive number.\n */\n @property({ type: Number })\n skidding = 0;\n\n /**\n * Choose if position is `fixed` or `absolute`. `absolute` is more performant,\n * but `fixed` can solve issues with overflow clipping\n */\n @property({ type: Boolean })\n hoist = false;\n\n @property({ type: Boolean })\n disabled = false;\n\n /**\n * The combobox will close when the user interacts outside of this element (e.g. clicking). Useful for composing other\n * components that use a combobox internally.\n */\n @property({ attribute: false })\n private containingElement?: HTMLElement;\n\n connectedCallback() {\n super.connectedCallback();\n\n if (!this.containingElement) {\n this.containingElement = this;\n }\n }\n\n firstUpdated() {\n const input = this.triggerElements[0];\n if (input.tagName.toLowerCase() === 'mid-phone-input') {\n this.triggerElement = 'mid-phone-input';\n } else if (input.tagName.toLowerCase() === 'mid-textfield') {\n this.triggerElement = 'mid-textfield';\n }\n\n this.panel.hidden = !this.open;\n\n const menu = this.getMenu();\n if (menu) {\n menu.variant = 'combobox';\n }\n\n // If the combobox panel is visible on init, update its position\n if (this.open) {\n this.addOpenListeners();\n this.popup.active = true;\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeOpenListeners();\n this.hide();\n }\n\n focusOnTrigger() {\n const trigger = this.trigger.assignedElements({ flatten: true })[0] as\n | HTMLElement\n | undefined;\n\n if (typeof trigger?.focus === 'function') {\n trigger.focus();\n }\n }\n\n getMenu() {\n return this.panel\n .assignedElements({ flatten: true })\n .find((el) => el.tagName.toLowerCase() === 'mid-menu') as\n | MinidMenu\n | undefined;\n }\n\n private handleCountryClick = () => {\n const menu = this.getMenu();\n\n this.open ? this.hide() : this.show();\n if (this.open && menu && menu.searchable) {\n // Delay focus slightly to win the focus battle\n setTimeout(() => {\n menu.clearFilter();\n menu.focusSearchField();\n }, 1);\n }\n };\n\n private handleKeyDown = (event: KeyboardEvent) => {\n // Close when escape is pressed inside an open combobox. We need to listen on the panel itself and stop propagation\n // in case any ancestors are also listening for this key.\n if (this.open && event.key === 'Escape') {\n event.stopPropagation();\n this.hide();\n this.focusOnTrigger();\n }\n };\n\n private handleDocumentKeyDown = (event: KeyboardEvent) => {\n // Close when escape or tab is pressed\n if (event.key === 'Escape' && this.open && !this.closeWatcher) {\n event.stopPropagation();\n this.focusOnTrigger();\n this.hide();\n return;\n }\n\n // Handle tabbing\n if (event.key === 'Tab') {\n const composedPath = event.composedPath();\n const tabbedIsMenuItem = composedPath.some(\n (e): e is MinidMenuItem =>\n (e as HTMLElement).tagName?.toLowerCase() === 'mid-menu-item'\n );\n\n // Tabbing within an open menu should close the combobox and refocus the trigger\n if (this.open && tabbedIsMenuItem) {\n event.preventDefault();\n this.hide();\n this.focusOnTrigger();\n return;\n }\n\n // Tabbing outside of the containing element closes the panel\n //\n // If the combobox is used within a shadow DOM, we need to obtain the activeElement within that shadowRoot,\n // otherwise `document.activeElement` will only return the name of the parent shadow DOM element.\n setTimeout(() => {\n if (composedPath.every((target) => target !== this.containingElement)) {\n this.hide();\n }\n });\n }\n };\n\n private handleDocumentMouseDown = (event: MouseEvent) => {\n // Close when clicking outside of the containing element\n const path = event.composedPath();\n if (this.containingElement && !path.includes(this.containingElement)) {\n this.hide();\n }\n };\n\n private handlePanelSelect = (event: CustomEvent) => {\n if (this.triggerElement !== 'mid-phone-input') {\n return;\n }\n\n // Transfer selected country from panel to input field\n const input = this.triggerElements[0] as MinidPhoneInput;\n const country = event.detail.item.value;\n input.country = country;\n\n const target = event.target as HTMLElement;\n\n // Hide the combobox when a menu item is selected\n if (!this.stayopenonselect && target.tagName.toLowerCase() === 'mid-menu') {\n this.hide();\n this.focusOnTrigger();\n }\n };\n\n handleTriggerClick() {\n if (this.triggerElement === 'mid-phone-input') {\n return;\n }\n\n if (this.open) {\n this.hide();\n } else {\n this.show();\n this.focusOnTrigger();\n }\n }\n\n async handleTriggerKeyDown(event: KeyboardEvent) {\n // When spacebar/enter is pressed, show the panel but don't focus on the menu. This let's the user press the same\n // key again to hide the menu in case they don't want to make a selection.\n if ([' ', 'Enter'].includes(event.key)) {\n event.preventDefault();\n if (this.triggerElement === 'mid-textfield') {\n this.handleTriggerClick();\n }\n return;\n }\n\n const menu = this.getMenu();\n\n if (menu) {\n const menuItems = menu.getAllSelectableItems();\n const firstMenuItem = menuItems[0];\n const lastMenuItem = menuItems[menuItems.length - 1];\n\n // When up/down is pressed, we make the assumption that the user is familiar with the menu and plans to make a\n // selection. Rather than toggle the panel, we focus on the menu (if one exists) and activate the first item for\n // faster navigation.\n if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {\n event.preventDefault();\n\n // Show the menu if it's not already open\n if (!this.open) {\n this.show();\n\n // Wait for the combobox to open before focusing, but not the animation\n await this.updateComplete;\n }\n\n if (menuItems.length > 0) {\n // Focus on the first/last menu item after showing\n this.updateComplete.then(() => {\n if (event.key === 'ArrowDown' || event.key === 'Home') {\n menu.setCurrentItem(firstMenuItem);\n if (this.triggerElement === 'mid-textfield') {\n firstMenuItem.focus();\n } else {\n menu.clearFilter();\n menu.focusSearchField();\n }\n }\n\n if (event.key === 'ArrowUp' || event.key === 'End') {\n menu.setCurrentItem(lastMenuItem);\n if (this.triggerElement === 'mid-textfield') {\n lastMenuItem.focus();\n } else {\n menu.clearFilter();\n menu.focusSearchField();\n }\n }\n });\n }\n }\n }\n }\n\n handleTriggerKeyUp(event: KeyboardEvent) {\n // Prevent space from triggering a click event in Firefox\n if (event.key === ' ') {\n event.preventDefault();\n }\n }\n\n handleTriggerSlotChange() {\n this.updateAccessibleTrigger();\n }\n\n //\n // Slotted triggers can be arbitrary content, but we need to link them to the combobox panel with `aria-haspopup` and\n // `aria-expanded`. These must be applied to the \"accessible trigger\" (the tabbable portion of the trigger element\n // that gets slotted in) so screen readers will understand them. The accessible trigger could be the slotted element,\n // a child of the slotted element, or an element in the slotted element's shadow root.\n //\n // For example, the accessible trigger of an <sl-button> is a <button> located inside its shadow root.\n //\n // To determine this, we assume the first tabbable element in the trigger slot is the \"accessible trigger.\"\n //\n updateAccessibleTrigger() {\n const assignedElements = this.trigger.assignedElements({\n flatten: true,\n }) as HTMLElement[];\n const accessibleTrigger = assignedElements.find(\n (el) => getTabbableBoundary(el).start\n );\n let target: HTMLElement;\n\n if (accessibleTrigger) {\n switch (accessibleTrigger.tagName.toLowerCase()) {\n // buttons have to update the internal button so it's announced correctly by screen readers\n case 'mid-button':\n target = (accessibleTrigger as MinidButton).button;\n break;\n\n default:\n target = accessibleTrigger;\n }\n\n target.setAttribute('aria-haspopup', 'true');\n target.setAttribute('aria-expanded', this.open ? 'true' : 'false');\n }\n }\n\n /**\n * Shows the combobox panel.\n */\n async show() {\n if (this.open) {\n return undefined;\n }\n\n this.open = true;\n return waitForEvent(this, 'mid-after-show');\n }\n\n /**\n * Hides the combobox panel\n */\n async hide() {\n if (!this.open) {\n return undefined;\n }\n\n this.open = false;\n return waitForEvent(this, 'mid-after-hide');\n }\n\n /**\n * Instructs the combobox menu to reposition. Useful when the position or size of the trigger changes when the menu\n * is activated.\n */\n reposition() {\n this.popup.reposition();\n }\n\n addOpenListeners() {\n if ('CloseWatcher' in window) {\n this.closeWatcher?.destroy();\n this.closeWatcher = new CloseWatcher();\n this.closeWatcher.onclose = () => {\n this.hide();\n this.focusOnTrigger();\n };\n }\n\n document.addEventListener('keydown', this.handleDocumentKeyDown);\n document.addEventListener('mousedown', this.handleDocumentMouseDown);\n }\n\n removeOpenListeners() {\n document.removeEventListener('keydown', this.handleDocumentKeyDown);\n document.removeEventListener('mousedown', this.handleDocumentMouseDown);\n this.closeWatcher?.destroy();\n }\n\n @watch('open', { waitUntilFirstUpdate: true })\n async handleOpenChange() {\n if (this.disabled) {\n this.open = false;\n return;\n }\n\n this.updateAccessibleTrigger();\n\n if (this.open) {\n // Show\n this.dispatchEvent(\n new Event('mid-show', { bubbles: true, composed: true })\n );\n this.addOpenListeners();\n\n await stopAnimations(this);\n this.panel.hidden = false;\n this.popup.active = true;\n const { keyframes, options } = getAnimation(this, 'combobox.show');\n await animateTo(this.popup.popup, keyframes, options);\n\n this.dispatchEvent(\n new Event('mid-after-show', { bubbles: true, composed: true })\n );\n } else {\n // Hide\n this.dispatchEvent(\n new Event('mid-hide', { bubbles: true, composed: true })\n );\n this.removeOpenListeners();\n await stopAnimations(this);\n const { keyframes, options } = getAnimation(this, 'combobox.hide');\n await animateTo(this.popup.popup, keyframes, options);\n this.panel.hidden = true;\n this.popup.active = false;\n\n this.dispatchEvent(\n new Event('mid-after-hide', { bubbles: true, composed: true })\n );\n }\n }\n\n override render() {\n return html`\n <mid-popup\n id=\"combobox\"\n distance=${this.distance}\n placement=\"bottom-end\"\n skidding=${this.skidding}\n strategy=${this.hoist ? 'fixed' : 'absolute'}\n flip\n shift\n auto-size=\"vertical\"\n auto-size-padding=\"10\"\n sync=\"width\"\n ?active=${this.open}\n >\n <slot\n class=\"combobox__trigger\"\n slot=\"anchor\"\n name=\"trigger\"\n @click=${this.handleTriggerClick}\n @keydown=${this.handleTriggerKeyDown}\n @keyup=${this.handleTriggerKeyUp}\n @slotchange=${this.handleTriggerSlotChange}\n @mid-country-click=${this.handleCountryClick}\n ></slot>\n <div\n class=\"bg-accent\"\n aria-hidden=${this.open ? 'false' : 'true'}\n aria-labelledby=\"combobox\"\n >\n <slot\n class=\"combobox__panel\"\n part=\"panel\"\n @keydown=${this.handleKeyDown}\n @mid-select=${this.handlePanelSelect}\n ></slot>\n </div>\n </mid-popup>\n `;\n }\n}\n\nsetDefaultAnimation('combobox.show', {\n keyframes: [\n { opacity: 0, scale: 0.9 },\n { opacity: 1, scale: 1 },\n ],\n options: { duration: 100, easing: 'ease' },\n});\n\nsetDefaultAnimation('combobox.hide', {\n keyframes: [\n { opacity: 1, scale: 1 },\n { opacity: 0, scale: 0.9 },\n ],\n options: { duration: 100, easing: 'ease' },\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,13 @@ declare const MinidDropdown_base: typeof LitElement;
|
|
|
10
10
|
/**
|
|
11
11
|
* @slot -- Default slot for content of the dropdown panel
|
|
12
12
|
* @slot trigger - Used for the button element that will be used to open the dropdown menu
|
|
13
|
+
*
|
|
13
14
|
* @part panel - Select the dropdown panel host element
|
|
15
|
+
*
|
|
16
|
+
* @event mid-show - Emitted when panel opening is initiated
|
|
17
|
+
* @event mid-hide - Emitted when panel closing is iniitated
|
|
18
|
+
* @event mid-after-show - Emitted after the panel opening animation is finished
|
|
19
|
+
* @event mid-after-hide - Emitted after the panel closing animation is finished
|
|
14
20
|
*/
|
|
15
21
|
export declare class MinidDropdown extends MinidDropdown_base {
|
|
16
22
|
private readonly popupId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown.component.d.ts","sourceRoot":"","sources":["../../src/components/dropdown.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAE,MAAM,KAAK,CAAC;AAK5C,OAAO,mBAAmB,CAAC;AAM3B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAM/C,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAG5D,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,aAAa,CAAC;KAC/B;CACF;;AAYD
|
|
1
|
+
{"version":3,"file":"dropdown.component.d.ts","sourceRoot":"","sources":["../../src/components/dropdown.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAE,MAAM,KAAK,CAAC;AAK5C,OAAO,mBAAmB,CAAC;AAM3B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAM/C,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAG5D,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,aAAa,CAAC;KAC/B;CACF;;AAYD;;;;;;;;;;GAUG;AACH,qBACa,aAAc,SAAQ,kBAA0B;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAC5D,OAAO,CAAC,YAAY,CAAC,CAAsB;IAG3C,KAAK,EAAG,UAAU,CAAC;IAGnB,OAAO,EAAG,eAAe,CAAC;IAG1B,KAAK,EAAG,eAAe,CAAC;IAGxB,IAAI,UAAS;IAGb,QAAQ,UAAS;IAEjB;;;OAGG;IAEH,gBAAgB,UAAS;IAGzB,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAGhC,SAAS,EACL,KAAK,GACL,WAAW,GACX,SAAS,GACT,QAAQ,GACR,cAAc,GACd,YAAY,GACZ,OAAO,GACP,aAAa,GACb,WAAW,GACX,MAAM,GACN,YAAY,GACZ,UAAU,CAAgB;IAE9B;;OAEG;IAEH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IAEnC;;OAEG;IAEH,QAAQ,SAAK;IAEb;;OAEG;IAEH,QAAQ,SAAK;IAGb,KAAK,UAAS;IAEd;;;OAGG;IAEH,KAAK,UAAS;IAEd;;;OAGG;IAEH,iBAAiB,CAAC,EAAE,WAAW,CAAC;IAEhC,iBAAiB;IAQjB,YAAY;IAUZ,oBAAoB;IAMpB,cAAc;IASd,OAAO,IAID,SAAS,GACT,SAAS;IAGf,OAAO,CAAC,aAAa,CAQnB;IAEF,OAAO,CAAC,qBAAqB,CAmC3B;IAEF,OAAO,CAAC,uBAAuB,CAO7B;IAEF,OAAO,CAAC,iBAAiB,CAQvB;IAEF,kBAAkB;IASZ,oBAAoB,CAAC,KAAK,EAAE,aAAa;IAgD/C,kBAAkB,CAAC,KAAK,EAAE,aAAa;IAOvC,uBAAuB;IAIvB,uBAAuB;IAoBvB;;OAEG;IACG,IAAI;IASV;;OAEG;IACG,IAAI;IASV;;;OAGG;IACH,UAAU;IAIV,gBAAgB;IAgBhB,mBAAmB;IAWb,gBAAgB;IA2Cb,MAAM;CAwChB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown.js","sources":["../../src/components/dropdown.component.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport './popup.component';\nimport {\n getAnimation,\n setDefaultAnimation,\n} from '../utilities/animation-registry.ts';\nimport { waitForEvent } from '../internal/event.ts';\nimport { MinidPopup } from './popup.component';\nimport { watch } from '../internal/watch.ts';\nimport { animateTo, stopAnimations } from '../internal/animate.ts';\nimport { getTabbableBoundary } from '../internal/tabbable.ts';\nimport { MinidButton } from '../components/button.component.ts';\nimport type { MidSelectEvent } from '../events/mid-select.ts';\nimport { MinidMenu } from '../components/menu.component.ts';\nimport { MinidMenuItem } from '../components/menu-item.component.ts';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-dropdown': MinidDropdown;\n }\n}\n\nlet nextUniqueId = 0;\n\nconst styles = [\n css`\n :host {\n display: inline-flex;\n }\n `,\n];\n\n/**\n * @slot -- Default slot for content of the dropdown panel\n * @slot trigger - Used for the button element that will be used to open the dropdown menu\n * @part panel - Select the dropdown panel host element\n */\n@customElement('mid-dropdown')\nexport class MinidDropdown extends styled(LitElement, styles) {\n private readonly popupId = `mid-dropdown-${nextUniqueId++}`;\n private closeWatcher?: CloseWatcher | null;\n\n @query('.popup')\n popup!: MinidPopup;\n\n @query('.trigger')\n trigger!: HTMLSlotElement;\n\n @query('.panel')\n panel!: HTMLSlotElement;\n\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * By default, the dropdown is closed when an item is selected. This attribute will keep it open instead. Useful for\n * dropdowns that allow for multiple interactions.\n */\n @property({ type: Boolean, reflect: true })\n stayopenonselect = false;\n\n @property()\n size: 'sm' | 'md' | 'lg' = 'md';\n\n @property({ reflect: true })\n placement:\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n | 'left'\n | 'left-start'\n | 'left-end' = 'bottom-end';\n\n /**\n * Sync the dropdown panel size with the trigger element\n */\n @property({ reflect: true })\n sync?: 'width' | 'height' | 'both';\n\n /**\n * Distance between trigger and dropdown panel\n */\n @property({ type: Number })\n distance = 4;\n\n /**\n * Nudge the dropdown panel position. Accepts a negative or positive number.\n */\n @property({ type: Number })\n skidding = 0;\n\n @property({ type: Boolean })\n arrow = false;\n\n /**\n * Choose if position is `fixed` or `absolute`. `absolute` is more performant,\n * but `fixed` can solve issues with overflow clipping\n */\n @property({ type: Boolean })\n hoist = false;\n\n /**\n * The dropdown will close when the user interacts outside of this element (e.g. clicking). Useful for composing other\n * components that use a dropdown internally.\n */\n @property({ attribute: false })\n containingElement?: HTMLElement;\n\n connectedCallback() {\n super.connectedCallback();\n\n if (!this.containingElement) {\n this.containingElement = this;\n }\n }\n\n firstUpdated() {\n this.panel.hidden = !this.open;\n\n // If the dropdown is visible on init, update its position\n if (this.open) {\n this.addOpenListeners();\n this.popup.active = true;\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeOpenListeners();\n this.hide();\n }\n\n focusOnTrigger() {\n const trigger = this.trigger.assignedElements({ flatten: true })[0] as\n | HTMLElement\n | undefined;\n if (typeof trigger?.focus === 'function') {\n trigger.focus();\n }\n }\n\n getMenu() {\n return this.panel\n .assignedElements({ flatten: true })\n .find((el) => el.tagName.toLowerCase() === 'mid-menu') as\n | MinidMenu\n | undefined;\n }\n\n private handleKeyDown = (event: KeyboardEvent) => {\n // Close when escape is pressed inside an open dropdown. We need to listen on the panel itself and stop propagation\n // in case any ancestors are also listening for this key.\n if (this.open && event.key === 'Escape') {\n event.stopPropagation();\n this.hide();\n this.focusOnTrigger();\n }\n };\n\n private handleDocumentKeyDown = (event: KeyboardEvent) => {\n // Close when escape or tab is pressed\n if (event.key === 'Escape' && this.open && !this.closeWatcher) {\n event.stopPropagation();\n this.focusOnTrigger();\n this.hide();\n return;\n }\n\n // Handle tabbing\n if (event.key === 'Tab') {\n const composedPath = event.composedPath();\n const tabbedIsMenuItem = composedPath.some(\n (e): e is MinidMenuItem =>\n (e as HTMLElement).tagName?.toLowerCase() === 'mid-menu-item'\n );\n\n // Tabbing within an open menu should close the dropdown and refocus the trigger\n if (this.open && tabbedIsMenuItem) {\n event.preventDefault();\n this.hide();\n this.focusOnTrigger();\n return;\n }\n\n // Tabbing outside of the containing element closes the panel\n //\n // If the dropdown is used within a shadow DOM, we need to obtain the activeElement within that shadowRoot,\n // otherwise `document.activeElement` will only return the name of the parent shadow DOM element.\n setTimeout(() => {\n if (composedPath.every((target) => target !== this.containingElement)) {\n this.hide();\n }\n });\n }\n };\n\n private handleDocumentMouseDown = (event: MouseEvent) => {\n // Close when clicking outside of the containing element\n const path = event.composedPath();\n\n if (this.containingElement && !path.includes(this.containingElement)) {\n this.hide();\n }\n };\n\n private handlePanelSelect = (event: MidSelectEvent) => {\n const target = event.target as HTMLElement;\n\n // Hide the dropdown when a menu item is selected\n if (!this.stayopenonselect && target.tagName.toLowerCase() === 'mid-menu') {\n this.hide();\n this.focusOnTrigger();\n }\n };\n\n handleTriggerClick() {\n if (this.open) {\n this.hide();\n } else {\n this.show();\n this.focusOnTrigger();\n }\n }\n\n async handleTriggerKeyDown(event: KeyboardEvent) {\n // When spacebar/enter is pressed, show the panel but don't focus on the menu. This let's the user press the same\n // key again to hide the menu in case they don't want to make a selection.\n if ([' ', 'Enter'].includes(event.key)) {\n event.preventDefault();\n this.handleTriggerClick();\n return;\n }\n\n const menu = this.getMenu();\n\n if (menu) {\n const menuItems = menu.getAllSelectableItems();\n const firstMenuItem = menuItems[0];\n const lastMenuItem = menuItems[menuItems.length - 1];\n\n // When up/down is pressed, we make the assumption that the user is familiar with the menu and plans to make a\n // selection. Rather than toggle the panel, we focus on the menu (if one exists) and activate the first item for\n // faster navigation.\n if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {\n event.preventDefault();\n\n // Show the menu if it's not already open\n if (!this.open) {\n this.show();\n\n // Wait for the dropdown to open before focusing, but not the animation\n await this.updateComplete;\n }\n\n if (menuItems.length > 0) {\n // Focus on the first/last menu item after showing\n this.updateComplete.then(() => {\n if (event.key === 'ArrowDown' || event.key === 'Home') {\n menu.setCurrentItem(firstMenuItem);\n firstMenuItem.focus();\n }\n\n if (event.key === 'ArrowUp' || event.key === 'End') {\n menu.setCurrentItem(lastMenuItem);\n lastMenuItem.focus();\n }\n });\n }\n }\n }\n }\n\n handleTriggerKeyUp(event: KeyboardEvent) {\n // Prevent space from triggering a click event in Firefox\n if (event.key === ' ') {\n event.preventDefault();\n }\n }\n\n handleTriggerSlotChange() {\n this.updateAccessibleTrigger();\n }\n\n updateAccessibleTrigger() {\n const assignedElements = this.trigger.assignedElements({\n flatten: true,\n }) as HTMLElement[];\n const accessibleTrigger = assignedElements.find(\n (el) => getTabbableBoundary(el).start\n );\n let target: HTMLElement;\n if (accessibleTrigger) {\n if (accessibleTrigger.tagName.toLowerCase() === 'mid-button') {\n target = (accessibleTrigger as MinidButton).button;\n } else {\n target = accessibleTrigger;\n }\n\n target.setAttribute('aria-haspopup', 'true');\n target.setAttribute('aria-expanded', this.open ? 'true' : 'false');\n }\n }\n\n /**\n * Shows the dropdown panel.\n */\n async show() {\n if (this.open) {\n return undefined;\n }\n\n this.open = true;\n return waitForEvent(this, 'mid-after-show');\n }\n\n /**\n * Hides the dropdown panel\n */\n async hide() {\n if (!this.open) {\n return undefined;\n }\n\n this.open = false;\n return waitForEvent(this, 'mid-after-hide');\n }\n\n /**\n * Instructs the dropdown menu to reposition. Useful when the position or size of the trigger changes when the menu\n * is activated.\n */\n reposition() {\n this.popup.reposition();\n }\n\n addOpenListeners() {\n this.panel.addEventListener('mid-select', this.handlePanelSelect);\n if ('CloseWatcher' in window) {\n this.closeWatcher?.destroy();\n this.closeWatcher = new CloseWatcher();\n this.closeWatcher.onclose = () => {\n this.hide();\n this.focusOnTrigger();\n };\n } else {\n this.panel.addEventListener('keydown', this.handleKeyDown);\n }\n document.addEventListener('keydown', this.handleDocumentKeyDown);\n document.addEventListener('mousedown', this.handleDocumentMouseDown);\n }\n\n removeOpenListeners() {\n if (this.panel) {\n this.panel.removeEventListener('mid-select', this.handlePanelSelect);\n this.panel.removeEventListener('keydown', this.handleKeyDown);\n }\n document.removeEventListener('keydown', this.handleDocumentKeyDown);\n document.removeEventListener('mousedown', this.handleDocumentMouseDown);\n this.closeWatcher?.destroy();\n }\n\n @watch('open', { waitUntilFirstUpdate: true })\n async handleOpenChange() {\n if (this.disabled) {\n this.open = false;\n return;\n }\n\n this.updateAccessibleTrigger();\n\n if (this.open) {\n // Show\n this.dispatchEvent(\n new Event('mid-show', { bubbles: true, composed: true })\n );\n this.addOpenListeners();\n\n await stopAnimations(this);\n this.panel.hidden = false;\n this.popup.active = true;\n const { keyframes, options } = getAnimation(this, 'dropdown.show');\n await animateTo(this.popup.popup, keyframes, options);\n\n this.dispatchEvent(\n new Event('mid-after-show', { bubbles: true, composed: true })\n );\n } else {\n // Hide\n this.dispatchEvent(\n new Event('mid-hide', { bubbles: true, composed: true })\n );\n this.removeOpenListeners();\n\n await stopAnimations(this);\n const { keyframes, options } = getAnimation(this, 'dropdown.hide');\n await animateTo(this.popup.popup, keyframes, options);\n this.panel.hidden = true;\n this.popup.active = false;\n\n this.dispatchEvent(\n new Event('mid-after-hide', { bubbles: true, composed: true })\n );\n }\n }\n\n override render() {\n return html`\n <mid-popup\n id=\"${this.popupId}\"\n class=\"${classMap({\n 'text-body-sm': this.size === 'sm',\n 'text-body-md': this.size === 'md',\n 'text-body-lg': this.size === 'lg',\n })} popup [--arrow-border-color:var(--border-color-neutral-subtle)] [--arrow-size:8px]\"\n distance=${this.distance}\n placement=\"${this.placement}\"\n skidding=${this.skidding}\n strategy=${this.hoist ? 'fixed' : 'absolute'}\n flip\n shift\n auto-size=\"vertical\"\n auto-size-padding=\"10\"\n sync=${ifDefined(this.sync)}\n ?arrow=${this.arrow}\n >\n <slot\n class=\"trigger\"\n slot=\"anchor\"\n name=\"trigger\"\n @click=${this.handleTriggerClick}\n @keydown=${this.handleTriggerKeyDown}\n @keyup=${this.handleTriggerKeyUp}\n @slotchange=${this.handleTriggerSlotChange}\n >\n </slot>\n <div\n class=\"bg-accent\"\n aria-hidden=${this.open ? 'false' : 'true'}\n aria-labelledby=\"${this.popupId}\"\n >\n <slot part=\"panel\" class=\"panel\"></slot>\n </div>\n </mid-popup>\n `;\n }\n}\n\nsetDefaultAnimation('dropdown.show', {\n keyframes: [\n { opacity: 0, scale: 0.9 },\n { opacity: 1, scale: 1 },\n ],\n options: { duration: 100, easing: 'ease' },\n});\n\nsetDefaultAnimation('dropdown.hide', {\n keyframes: [\n { opacity: 1, scale: 1 },\n { opacity: 0, scale: 0.9 },\n ],\n options: { duration: 100, easing: 'ease' },\n});\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dropdown.js","sources":["../../src/components/dropdown.component.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport './popup.component';\nimport {\n getAnimation,\n setDefaultAnimation,\n} from '../utilities/animation-registry.ts';\nimport { waitForEvent } from '../internal/event.ts';\nimport { MinidPopup } from './popup.component';\nimport { watch } from '../internal/watch.ts';\nimport { animateTo, stopAnimations } from '../internal/animate.ts';\nimport { getTabbableBoundary } from '../internal/tabbable.ts';\nimport { MinidButton } from '../components/button.component.ts';\nimport type { MidSelectEvent } from '../events/mid-select.ts';\nimport { MinidMenu } from '../components/menu.component.ts';\nimport { MinidMenuItem } from '../components/menu-item.component.ts';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-dropdown': MinidDropdown;\n }\n}\n\nlet nextUniqueId = 0;\n\nconst styles = [\n css`\n :host {\n display: inline-flex;\n }\n `,\n];\n\n/**\n * @slot -- Default slot for content of the dropdown panel\n * @slot trigger - Used for the button element that will be used to open the dropdown menu\n *\n * @part panel - Select the dropdown panel host element\n *\n * @event mid-show - Emitted when panel opening is initiated\n * @event mid-hide - Emitted when panel closing is iniitated\n * @event mid-after-show - Emitted after the panel opening animation is finished\n * @event mid-after-hide - Emitted after the panel closing animation is finished\n */\n@customElement('mid-dropdown')\nexport class MinidDropdown extends styled(LitElement, styles) {\n private readonly popupId = `mid-dropdown-${nextUniqueId++}`;\n private closeWatcher?: CloseWatcher | null;\n\n @query('.popup')\n popup!: MinidPopup;\n\n @query('.trigger')\n trigger!: HTMLSlotElement;\n\n @query('.panel')\n panel!: HTMLSlotElement;\n\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * By default, the dropdown is closed when an item is selected. This attribute will keep it open instead. Useful for\n * dropdowns that allow for multiple interactions.\n */\n @property({ type: Boolean, reflect: true })\n stayopenonselect = false;\n\n @property()\n size: 'sm' | 'md' | 'lg' = 'md';\n\n @property({ reflect: true })\n placement:\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n | 'left'\n | 'left-start'\n | 'left-end' = 'bottom-end';\n\n /**\n * Sync the dropdown panel size with the trigger element\n */\n @property({ reflect: true })\n sync?: 'width' | 'height' | 'both';\n\n /**\n * Distance between trigger and dropdown panel\n */\n @property({ type: Number })\n distance = 4;\n\n /**\n * Nudge the dropdown panel position. Accepts a negative or positive number.\n */\n @property({ type: Number })\n skidding = 0;\n\n @property({ type: Boolean })\n arrow = false;\n\n /**\n * Choose if position is `fixed` or `absolute`. `absolute` is more performant,\n * but `fixed` can solve issues with overflow clipping\n */\n @property({ type: Boolean })\n hoist = false;\n\n /**\n * The dropdown will close when the user interacts outside of this element (e.g. clicking). Useful for composing other\n * components that use a dropdown internally.\n */\n @property({ attribute: false })\n containingElement?: HTMLElement;\n\n connectedCallback() {\n super.connectedCallback();\n\n if (!this.containingElement) {\n this.containingElement = this;\n }\n }\n\n firstUpdated() {\n this.panel.hidden = !this.open;\n\n // If the dropdown is visible on init, update its position\n if (this.open) {\n this.addOpenListeners();\n this.popup.active = true;\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeOpenListeners();\n this.hide();\n }\n\n focusOnTrigger() {\n const trigger = this.trigger.assignedElements({ flatten: true })[0] as\n | HTMLElement\n | undefined;\n if (typeof trigger?.focus === 'function') {\n trigger.focus();\n }\n }\n\n getMenu() {\n return this.panel\n .assignedElements({ flatten: true })\n .find((el) => el.tagName.toLowerCase() === 'mid-menu') as\n | MinidMenu\n | undefined;\n }\n\n private handleKeyDown = (event: KeyboardEvent) => {\n // Close when escape is pressed inside an open dropdown. We need to listen on the panel itself and stop propagation\n // in case any ancestors are also listening for this key.\n if (this.open && event.key === 'Escape') {\n event.stopPropagation();\n this.hide();\n this.focusOnTrigger();\n }\n };\n\n private handleDocumentKeyDown = (event: KeyboardEvent) => {\n // Close when escape or tab is pressed\n if (event.key === 'Escape' && this.open && !this.closeWatcher) {\n event.stopPropagation();\n this.focusOnTrigger();\n this.hide();\n return;\n }\n\n // Handle tabbing\n if (event.key === 'Tab') {\n const composedPath = event.composedPath();\n const tabbedIsMenuItem = composedPath.some(\n (e): e is MinidMenuItem =>\n (e as HTMLElement).tagName?.toLowerCase() === 'mid-menu-item'\n );\n\n // Tabbing within an open menu should close the dropdown and refocus the trigger\n if (this.open && tabbedIsMenuItem) {\n event.preventDefault();\n this.hide();\n this.focusOnTrigger();\n return;\n }\n\n // Tabbing outside of the containing element closes the panel\n //\n // If the dropdown is used within a shadow DOM, we need to obtain the activeElement within that shadowRoot,\n // otherwise `document.activeElement` will only return the name of the parent shadow DOM element.\n setTimeout(() => {\n if (composedPath.every((target) => target !== this.containingElement)) {\n this.hide();\n }\n });\n }\n };\n\n private handleDocumentMouseDown = (event: MouseEvent) => {\n // Close when clicking outside of the containing element\n const path = event.composedPath();\n\n if (this.containingElement && !path.includes(this.containingElement)) {\n this.hide();\n }\n };\n\n private handlePanelSelect = (event: MidSelectEvent) => {\n const target = event.target as HTMLElement;\n\n // Hide the dropdown when a menu item is selected\n if (!this.stayopenonselect && target.tagName.toLowerCase() === 'mid-menu') {\n this.hide();\n this.focusOnTrigger();\n }\n };\n\n handleTriggerClick() {\n if (this.open) {\n this.hide();\n } else {\n this.show();\n this.focusOnTrigger();\n }\n }\n\n async handleTriggerKeyDown(event: KeyboardEvent) {\n // When spacebar/enter is pressed, show the panel but don't focus on the menu. This let's the user press the same\n // key again to hide the menu in case they don't want to make a selection.\n if ([' ', 'Enter'].includes(event.key)) {\n event.preventDefault();\n this.handleTriggerClick();\n return;\n }\n\n const menu = this.getMenu();\n\n if (menu) {\n const menuItems = menu.getAllSelectableItems();\n const firstMenuItem = menuItems[0];\n const lastMenuItem = menuItems[menuItems.length - 1];\n\n // When up/down is pressed, we make the assumption that the user is familiar with the menu and plans to make a\n // selection. Rather than toggle the panel, we focus on the menu (if one exists) and activate the first item for\n // faster navigation.\n if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {\n event.preventDefault();\n\n // Show the menu if it's not already open\n if (!this.open) {\n this.show();\n\n // Wait for the dropdown to open before focusing, but not the animation\n await this.updateComplete;\n }\n\n if (menuItems.length > 0) {\n // Focus on the first/last menu item after showing\n this.updateComplete.then(() => {\n if (event.key === 'ArrowDown' || event.key === 'Home') {\n menu.setCurrentItem(firstMenuItem);\n firstMenuItem.focus();\n }\n\n if (event.key === 'ArrowUp' || event.key === 'End') {\n menu.setCurrentItem(lastMenuItem);\n lastMenuItem.focus();\n }\n });\n }\n }\n }\n }\n\n handleTriggerKeyUp(event: KeyboardEvent) {\n // Prevent space from triggering a click event in Firefox\n if (event.key === ' ') {\n event.preventDefault();\n }\n }\n\n handleTriggerSlotChange() {\n this.updateAccessibleTrigger();\n }\n\n updateAccessibleTrigger() {\n const assignedElements = this.trigger.assignedElements({\n flatten: true,\n }) as HTMLElement[];\n const accessibleTrigger = assignedElements.find(\n (el) => getTabbableBoundary(el).start\n );\n let target: HTMLElement;\n if (accessibleTrigger) {\n if (accessibleTrigger.tagName.toLowerCase() === 'mid-button') {\n target = (accessibleTrigger as MinidButton).button;\n } else {\n target = accessibleTrigger;\n }\n\n target.setAttribute('aria-haspopup', 'true');\n target.setAttribute('aria-expanded', this.open ? 'true' : 'false');\n }\n }\n\n /**\n * Shows the dropdown panel.\n */\n async show() {\n if (this.open) {\n return undefined;\n }\n\n this.open = true;\n return waitForEvent(this, 'mid-after-show');\n }\n\n /**\n * Hides the dropdown panel\n */\n async hide() {\n if (!this.open) {\n return undefined;\n }\n\n this.open = false;\n return waitForEvent(this, 'mid-after-hide');\n }\n\n /**\n * Instructs the dropdown menu to reposition. Useful when the position or size of the trigger changes when the menu\n * is activated.\n */\n reposition() {\n this.popup.reposition();\n }\n\n addOpenListeners() {\n this.panel.addEventListener('mid-select', this.handlePanelSelect);\n if ('CloseWatcher' in window) {\n this.closeWatcher?.destroy();\n this.closeWatcher = new CloseWatcher();\n this.closeWatcher.onclose = () => {\n this.hide();\n this.focusOnTrigger();\n };\n } else {\n this.panel.addEventListener('keydown', this.handleKeyDown);\n }\n document.addEventListener('keydown', this.handleDocumentKeyDown);\n document.addEventListener('mousedown', this.handleDocumentMouseDown);\n }\n\n removeOpenListeners() {\n if (this.panel) {\n this.panel.removeEventListener('mid-select', this.handlePanelSelect);\n this.panel.removeEventListener('keydown', this.handleKeyDown);\n }\n document.removeEventListener('keydown', this.handleDocumentKeyDown);\n document.removeEventListener('mousedown', this.handleDocumentMouseDown);\n this.closeWatcher?.destroy();\n }\n\n @watch('open', { waitUntilFirstUpdate: true })\n async handleOpenChange() {\n if (this.disabled) {\n this.open = false;\n return;\n }\n\n this.updateAccessibleTrigger();\n\n if (this.open) {\n // Show\n this.dispatchEvent(\n new Event('mid-show', { bubbles: true, composed: true })\n );\n this.addOpenListeners();\n\n await stopAnimations(this);\n this.panel.hidden = false;\n this.popup.active = true;\n const { keyframes, options } = getAnimation(this, 'dropdown.show');\n await animateTo(this.popup.popup, keyframes, options);\n\n this.dispatchEvent(\n new Event('mid-after-show', { bubbles: true, composed: true })\n );\n } else {\n // Hide\n this.dispatchEvent(\n new Event('mid-hide', { bubbles: true, composed: true })\n );\n this.removeOpenListeners();\n\n await stopAnimations(this);\n const { keyframes, options } = getAnimation(this, 'dropdown.hide');\n await animateTo(this.popup.popup, keyframes, options);\n this.panel.hidden = true;\n this.popup.active = false;\n\n this.dispatchEvent(\n new Event('mid-after-hide', { bubbles: true, composed: true })\n );\n }\n }\n\n override render() {\n return html`\n <mid-popup\n id=\"${this.popupId}\"\n class=\"${classMap({\n 'text-body-sm': this.size === 'sm',\n 'text-body-md': this.size === 'md',\n 'text-body-lg': this.size === 'lg',\n })} popup [--arrow-border-color:var(--border-color-neutral-subtle)] [--arrow-size:8px]\"\n distance=${this.distance}\n placement=\"${this.placement}\"\n skidding=${this.skidding}\n strategy=${this.hoist ? 'fixed' : 'absolute'}\n flip\n shift\n auto-size=\"vertical\"\n auto-size-padding=\"10\"\n sync=${ifDefined(this.sync)}\n ?arrow=${this.arrow}\n >\n <slot\n class=\"trigger\"\n slot=\"anchor\"\n name=\"trigger\"\n @click=${this.handleTriggerClick}\n @keydown=${this.handleTriggerKeyDown}\n @keyup=${this.handleTriggerKeyUp}\n @slotchange=${this.handleTriggerSlotChange}\n >\n </slot>\n <div\n class=\"bg-accent\"\n aria-hidden=${this.open ? 'false' : 'true'}\n aria-labelledby=\"${this.popupId}\"\n >\n <slot part=\"panel\" class=\"panel\"></slot>\n </div>\n </mid-popup>\n `;\n }\n}\n\nsetDefaultAnimation('dropdown.show', {\n keyframes: [\n { opacity: 0, scale: 0.9 },\n { opacity: 1, scale: 1 },\n ],\n options: { duration: 100, easing: 'ease' },\n});\n\nsetDefaultAnimation('dropdown.hide', {\n keyframes: [\n { opacity: 1, scale: 1 },\n { opacity: 0, scale: 0.9 },\n ],\n options: { duration: 100, easing: 'ease' },\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.component.d.ts","sourceRoot":"","sources":["../../src/components/menu.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAW,MAAM,KAAK,CAAC;AAGrD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,SAAS,CAAC;KACvB;CACF;;AAWD;;GAEG;AACH,qBACa,SAAU,SAAQ,cAA0B;IAEvD,WAAW,EAAG,eAAe,CAAC;IAG9B,WAAW,EAAG,gBAAgB,CAAC;IAG/B,QAAQ,EAAG,gBAAgB,CAAC;IAE5B;;OAEG;IAEH,UAAU,UAAS;IAEnB;;OAEG;IAEH,OAAO,EAAE,UAAU,GAAG,UAAU,CAAc;IAG9C,eAAe,UAAS;IAExB,SAAS,CAAC,YAAY,IAAI,IAAI;IAS9B,OAAO,CAAC,WAAW;
|
|
1
|
+
{"version":3,"file":"menu.component.d.ts","sourceRoot":"","sources":["../../src/components/menu.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAW,MAAM,KAAK,CAAC;AAGrD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,SAAS,CAAC;KACvB;CACF;;AAWD;;GAEG;AACH,qBACa,SAAU,SAAQ,cAA0B;IAEvD,WAAW,EAAG,eAAe,CAAC;IAG9B,WAAW,EAAG,gBAAgB,CAAC;IAG/B,QAAQ,EAAG,gBAAgB,CAAC;IAE5B;;OAEG;IAEH,UAAU,UAAS;IAEnB;;OAEG;IAEH,OAAO,EAAE,UAAU,GAAG,UAAU,CAAc;IAG9C,eAAe,UAAS;IAExB,SAAS,CAAC,YAAY,IAAI,IAAI;IAS9B,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,aAAa;IAgDrB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,UAAU;IASlB;;;OAGG;IACH,MAAM,GAAI,UAAU,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,UAUlD;IAEF,WAAW;IAMX;;OAEG;IACH,qBAAqB;IAQrB,WAAW;IAQX;;;OAGG;IACH,cAAc;IAMd;;;OAGG;IACH,cAAc,CAAC,IAAI,EAAE,aAAa;IAUlC,gBAAgB;IAMP,MAAM;CAuChB"}
|
package/dist/components/menu.js
CHANGED
|
@@ -53,13 +53,6 @@ let MinidMenu = class extends styled(LitElement, styles) {
|
|
|
53
53
|
(el) => menuItemTypes.includes(el?.getAttribute?.("role") || "")
|
|
54
54
|
);
|
|
55
55
|
if (!target) return;
|
|
56
|
-
const closestMenu = composedPath.find(
|
|
57
|
-
(el) => el?.getAttribute?.("role") === "menu"
|
|
58
|
-
);
|
|
59
|
-
const clickHasSubmenu = closestMenu !== this;
|
|
60
|
-
if (clickHasSubmenu) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
56
|
const item = target;
|
|
64
57
|
this.dispatchEvent(
|
|
65
58
|
new CustomEvent("mid-select", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.js","sources":["../../src/components/menu.component.ts"],"sourcesContent":["import { css, html, LitElement, nothing } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport { MinidMenuItem } from './menu-item.component';\nimport { scrollIntoView } from '../internal/scroll';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-menu': MinidMenu;\n }\n}\n\nconst styles = [\n css`\n :host {\n --max-height: none;\n --max-width: none;\n }\n `,\n];\n\n/**\n * @event {{ detail: { item: MidMenuItem } }} mid-select - Emitted when a menu item is selected.\n */\n@customElement('mid-menu')\nexport class MinidMenu extends styled(LitElement, styles) {\n @query('slot')\n defaultSlot!: HTMLSlotElement;\n\n @query('.filter-input')\n filterInput!: HTMLInputElement;\n\n @query('.item-list')\n itemList!: HTMLUListElement;\n\n /**\n * Adds an input element that filters selectable menu items\n */\n @property({ type: Boolean })\n searchable = false;\n\n /**\n * Wether the menu should be styled as a dropdown or a combobox\n */\n @property()\n variant: 'combobox' | 'dropdown' = 'dropdown';\n\n @state()\n isEmptyItemList = false;\n\n protected firstUpdated(): void {\n this.getAllItems().forEach((item) => {\n item.variant = this.variant;\n item.addEventListener('mouseenter', () => {\n this.setCurrentItem(item);\n });\n });\n }\n\n private handleClick(event: MouseEvent) {\n const menuItemTypes = ['menuitem', 'menuitemcheckbox'];\n\n const composedPath = event.composedPath();\n const target = composedPath.find((el) =>\n menuItemTypes.includes((el as HTMLElement)?.getAttribute?.('role') || '')\n );\n\n if (!target) return;\n\n const closestMenu = composedPath.find(\n (el) => (el as HTMLElement)?.getAttribute?.('role') === 'menu'\n );\n const clickHasSubmenu = closestMenu !== this;\n\n // Make sure we're the menu thats supposed to be handling the click event.\n if (clickHasSubmenu) {\n return;\n }\n\n // This isn't true. But we use it for TypeScript checks below.\n const item = target as MinidMenuItem;\n\n // if (item.type === 'checkbox') {\n // item.checked = !item.checked;\n // }\n\n this.dispatchEvent(\n new CustomEvent('mid-select', {\n bubbles: true,\n composed: true,\n detail: { item },\n })\n );\n }\n\n private handleFilterItems() {\n this.filter((item) =>\n item.innerText\n .toLowerCase()\n .includes(this.filterInput.value.toLowerCase())\n );\n\n const items = this.getAllSelectableItems();\n this.isEmptyItemList = items.length === 0;\n this.setCurrentItem(items[0]);\n }\n\n private scrollOptionIntoView(item: MinidMenuItem): void {\n scrollIntoView(item, this.itemList, 'vertical', 'auto');\n }\n\n private handleKeyDown(event: KeyboardEvent) {\n // Make a selection when pressing enter or space\n if (event.key === 'Enter' || event.key === ' ') {\n const item = this.getCurrentItem();\n event.preventDefault();\n event.stopPropagation();\n\n // Simulate a click to support @click handlers on menu items that also work with the keyboard\n item?.click();\n }\n\n // Move the selection when pressing down or up\n else if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {\n const items = this.getAllSelectableItems();\n const activeItem = this.getCurrentItem();\n let index = activeItem ? items.indexOf(activeItem) : 0;\n\n if (items.length > 0) {\n event.preventDefault();\n event.stopPropagation();\n\n if (event.key === 'ArrowDown') {\n index++;\n } else if (event.key === 'ArrowUp') {\n index--;\n } else if (event.key === 'Home') {\n index = 0;\n } else if (event.key === 'End') {\n index = items.length - 1;\n }\n\n if (index < 0) {\n index = items.length - 1;\n }\n if (index > items.length - 1) {\n index = 0;\n }\n\n this.setCurrentItem(items[index]);\n this.scrollOptionIntoView(items[index]);\n\n if (!this.searchable) {\n items[index].focus();\n }\n }\n }\n }\n\n private handleMouseDown(event: MouseEvent) {\n const target = event.target as HTMLElement;\n\n if (this.isMenuItem(target)) {\n this.setCurrentItem(target as MinidMenuItem);\n }\n }\n\n private handleSlotChange() {\n const items = this.getAllSelectableItems();\n\n // Reset the roving tab index when the slotted items change\n if (items.length > 0) {\n this.setCurrentItem(items[0]);\n }\n }\n\n private isMenuItem(item: HTMLElement) {\n return (\n item.tagName.toLowerCase() === 'mid-menu-item' ||\n ['menuitem', 'menuitemcheckbox', 'menuitemradio'].includes(\n item.getAttribute('role') ?? ''\n )\n );\n }\n\n /**\n * Pass a filter function to enable/disable menu items in the menu\n * @type {(item: MinidMenuItem) => boolean}\n */\n filter = (filterFn: (item: MinidMenuItem) => boolean) => {\n this.getAllItems().forEach((item) => {\n if (filterFn(item)) {\n item.removeAttribute('hidden');\n item.removeAttribute('inert');\n } else {\n item.setAttribute('inert', 'true');\n item.setAttribute('hidden', 'true');\n }\n });\n };\n\n clearFilter() {\n this.filterInput.value = '';\n this.itemList.scrollTop = 0;\n this.filterInput.dispatchEvent(new Event('input'));\n }\n\n /**\n * @internal Gets all slotted menu items, ignoring dividers, headers, and other elements.\n */\n getAllSelectableItems() {\n return [\n ...(this.defaultSlot.assignedElements({\n flatten: true,\n }) as MinidMenuItem[]),\n ].filter((el) => !(el.inert || !this.isMenuItem(el)));\n }\n\n getAllItems() {\n return [\n ...(this.defaultSlot.assignedElements({\n flatten: true,\n }) as MinidMenuItem[]),\n ].filter((el) => this.isMenuItem(el));\n }\n\n /**\n * @internal Gets the current menu item, which is the menu item that has `tabindex=\"0\"` within the roving tab index.\n * The menu item may or may not have focus, but for keyboard interaction purposes it's considered the \"active\" item.\n */\n getCurrentItem() {\n return this.getAllSelectableItems().find(\n (i) => i.getAttribute('tabindex') === '0'\n );\n }\n\n /**\n * @internal Sets the current menu item to the specified element. This sets `tabindex=\"0\"` on the target element and\n * `tabindex=\"-1\"` to all other items. This method must be called prior to setting focus on a menu item.\n */\n setCurrentItem(item: MinidMenuItem) {\n const items = this.getAllSelectableItems();\n\n // Update tab indexes\n items.forEach((i) => {\n i.setActive(i === item);\n i.setAttribute('tabindex', i === item ? '0' : '-1');\n });\n }\n\n focusSearchField() {\n if (this.searchable) {\n this.filterInput.focus();\n }\n }\n\n override render() {\n return html`\n <div class=\"border-neutral-subtle rounded-md border shadow-md\">\n ${!this.searchable\n ? nothing\n : html`<div\n class=\"border-neutral-subtle flex items-center gap-2 border-b p-2\"\n >\n <mid-icon\n class=\"text-6\"\n slot=\"prefix\"\n library=\"system\"\n name=\"magnifying-glass\"\n >\n </mid-icon>\n <input\n @input=${this.handleFilterItems}\n @keydown=${this.handleKeyDown}\n class=\"filter-input border-neutral-subtle focus-visible:outline-focus-outer h-8 w-full rounded border px-2\"\n type=\"search\"\n />\n </div>`}\n <ul\n role=\"menu\"\n class=\"item-list max-h-(--max-height) max-w-(--max-width) overflow-y-auto px-2 py-3\"\n >\n <slot\n @slotchange=${this.handleSlotChange}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n @mousedown=${this.handleMouseDown}\n ></slot>\n ${this.isEmptyItemList\n ? html`<div class=\"p-2\">Fant ingen treff</div>`\n : nothing}\n </ul>\n </div>\n `;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"menu.js","sources":["../../src/components/menu.component.ts"],"sourcesContent":["import { css, html, LitElement, nothing } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport { MinidMenuItem } from './menu-item.component';\nimport { scrollIntoView } from '../internal/scroll';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-menu': MinidMenu;\n }\n}\n\nconst styles = [\n css`\n :host {\n --max-height: none;\n --max-width: none;\n }\n `,\n];\n\n/**\n * @event {{ detail: { item: MidMenuItem } }} mid-select - Emitted when a menu item is selected.\n */\n@customElement('mid-menu')\nexport class MinidMenu extends styled(LitElement, styles) {\n @query('slot')\n defaultSlot!: HTMLSlotElement;\n\n @query('.filter-input')\n filterInput!: HTMLInputElement;\n\n @query('.item-list')\n itemList!: HTMLUListElement;\n\n /**\n * Adds an input element that filters selectable menu items\n */\n @property({ type: Boolean })\n searchable = false;\n\n /**\n * Wether the menu should be styled as a dropdown or a combobox\n */\n @property()\n variant: 'combobox' | 'dropdown' = 'dropdown';\n\n @state()\n isEmptyItemList = false;\n\n protected firstUpdated(): void {\n this.getAllItems().forEach((item) => {\n item.variant = this.variant;\n item.addEventListener('mouseenter', () => {\n this.setCurrentItem(item);\n });\n });\n }\n\n private handleClick(event: MouseEvent) {\n const menuItemTypes = ['menuitem', 'menuitemcheckbox'];\n\n const composedPath = event.composedPath();\n const target = composedPath.find((el) =>\n menuItemTypes.includes((el as HTMLElement)?.getAttribute?.('role') || '')\n );\n\n if (!target) return;\n\n // This isn't true. But we use it for TypeScript checks below.\n const item = target as MinidMenuItem;\n\n // if (item.type === 'checkbox') {\n // item.checked = !item.checked;\n // }\n\n this.dispatchEvent(\n new CustomEvent('mid-select', {\n bubbles: true,\n composed: true,\n detail: { item },\n })\n );\n }\n\n private handleFilterItems() {\n this.filter((item) =>\n item.innerText\n .toLowerCase()\n .includes(this.filterInput.value.toLowerCase())\n );\n\n const items = this.getAllSelectableItems();\n this.isEmptyItemList = items.length === 0;\n this.setCurrentItem(items[0]);\n }\n\n private scrollOptionIntoView(item: MinidMenuItem): void {\n scrollIntoView(item, this.itemList, 'vertical', 'auto');\n }\n\n private handleKeyDown(event: KeyboardEvent) {\n // Make a selection when pressing enter or space\n if (event.key === 'Enter' || event.key === ' ') {\n const item = this.getCurrentItem();\n event.preventDefault();\n event.stopPropagation();\n\n // Simulate a click to support @click handlers on menu items that also work with the keyboard\n item?.click();\n }\n\n // Move the selection when pressing down or up\n else if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {\n const items = this.getAllSelectableItems();\n const activeItem = this.getCurrentItem();\n let index = activeItem ? items.indexOf(activeItem) : 0;\n\n if (items.length > 0) {\n event.preventDefault();\n event.stopPropagation();\n\n if (event.key === 'ArrowDown') {\n index++;\n } else if (event.key === 'ArrowUp') {\n index--;\n } else if (event.key === 'Home') {\n index = 0;\n } else if (event.key === 'End') {\n index = items.length - 1;\n }\n\n if (index < 0) {\n index = items.length - 1;\n }\n if (index > items.length - 1) {\n index = 0;\n }\n\n this.setCurrentItem(items[index]);\n this.scrollOptionIntoView(items[index]);\n\n if (!this.searchable) {\n items[index].focus();\n }\n }\n }\n }\n\n private handleMouseDown(event: MouseEvent) {\n const target = event.target as HTMLElement;\n\n if (this.isMenuItem(target)) {\n this.setCurrentItem(target as MinidMenuItem);\n }\n }\n\n private handleSlotChange() {\n const items = this.getAllSelectableItems();\n\n // Reset the roving tab index when the slotted items change\n if (items.length > 0) {\n this.setCurrentItem(items[0]);\n }\n }\n\n private isMenuItem(item: HTMLElement) {\n return (\n item.tagName.toLowerCase() === 'mid-menu-item' ||\n ['menuitem', 'menuitemcheckbox', 'menuitemradio'].includes(\n item.getAttribute('role') ?? ''\n )\n );\n }\n\n /**\n * Pass a filter function to enable/disable menu items in the menu\n * @type {(item: MinidMenuItem) => boolean}\n */\n filter = (filterFn: (item: MinidMenuItem) => boolean) => {\n this.getAllItems().forEach((item) => {\n if (filterFn(item)) {\n item.removeAttribute('hidden');\n item.removeAttribute('inert');\n } else {\n item.setAttribute('inert', 'true');\n item.setAttribute('hidden', 'true');\n }\n });\n };\n\n clearFilter() {\n this.filterInput.value = '';\n this.itemList.scrollTop = 0;\n this.filterInput.dispatchEvent(new Event('input'));\n }\n\n /**\n * @internal Gets all slotted menu items, ignoring dividers, headers, and other elements.\n */\n getAllSelectableItems() {\n return [\n ...(this.defaultSlot.assignedElements({\n flatten: true,\n }) as MinidMenuItem[]),\n ].filter((el) => !(el.inert || !this.isMenuItem(el)));\n }\n\n getAllItems() {\n return [\n ...(this.defaultSlot.assignedElements({\n flatten: true,\n }) as MinidMenuItem[]),\n ].filter((el) => this.isMenuItem(el));\n }\n\n /**\n * @internal Gets the current menu item, which is the menu item that has `tabindex=\"0\"` within the roving tab index.\n * The menu item may or may not have focus, but for keyboard interaction purposes it's considered the \"active\" item.\n */\n getCurrentItem() {\n return this.getAllSelectableItems().find(\n (i) => i.getAttribute('tabindex') === '0'\n );\n }\n\n /**\n * @internal Sets the current menu item to the specified element. This sets `tabindex=\"0\"` on the target element and\n * `tabindex=\"-1\"` to all other items. This method must be called prior to setting focus on a menu item.\n */\n setCurrentItem(item: MinidMenuItem) {\n const items = this.getAllSelectableItems();\n\n // Update tab indexes\n items.forEach((i) => {\n i.setActive(i === item);\n i.setAttribute('tabindex', i === item ? '0' : '-1');\n });\n }\n\n focusSearchField() {\n if (this.searchable) {\n this.filterInput.focus();\n }\n }\n\n override render() {\n return html`\n <div class=\"border-neutral-subtle rounded-md border shadow-md\">\n ${!this.searchable\n ? nothing\n : html`<div\n class=\"border-neutral-subtle flex items-center gap-2 border-b p-2\"\n >\n <mid-icon\n class=\"text-6\"\n slot=\"prefix\"\n library=\"system\"\n name=\"magnifying-glass\"\n >\n </mid-icon>\n <input\n @input=${this.handleFilterItems}\n @keydown=${this.handleKeyDown}\n class=\"filter-input border-neutral-subtle focus-visible:outline-focus-outer h-8 w-full rounded border px-2\"\n type=\"search\"\n />\n </div>`}\n <ul\n role=\"menu\"\n class=\"item-list max-h-(--max-height) max-w-(--max-width) overflow-y-auto px-2 py-3\"\n >\n <slot\n @slotchange=${this.handleSlotChange}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n @mousedown=${this.handleMouseDown}\n ></slot>\n ${this.isEmptyItemList\n ? html`<div class=\"p-2\">Fant ingen treff</div>`\n : nothing}\n </ul>\n </div>\n `;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tailwind.mixin.d.ts","sourceRoot":"","sources":["../../src/mixins/tailwind.mixin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAI9D,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,WAAW,CAAC,UAAU,CAAC,EACtD,YAAY,CAAC,EACb,aAAY,cAAmB,KAC9B,
|
|
1
|
+
{"version":3,"file":"tailwind.mixin.d.ts","sourceRoot":"","sources":["../../src/mixins/tailwind.mixin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAI9D,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,WAAW,CAAC,UAAU,CAAC,EACtD,YAAY,CAAC,EACb,aAAY,cAAmB,KAC9B,CA2DA,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tailwind.mixin.js","sources":["../../src/mixins/tailwind.mixin.ts"],"sourcesContent":["import { type CSSResultArray, LitElement } from 'lit';\nimport type { Constructor } from '../types/mixin-constructor';\n\nconst tailwindSheet = new CSSStyleSheet();\n\nexport const styled = <T extends Constructor<LitElement>>(\n superClass: T,\n elementCss: CSSResultArray = []\n): T =>\n class extends superClass {\n static styles = [tailwindSheet, elementCss];\n tailwindLinkElement: HTMLStyleElement;\n\n constructor(..._: any[]) {\n super();\n this.tailwindLinkElement = document.querySelector(\n '[data-mid-tailwind]'\n ) as HTMLStyleElement;\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n\n if (tailwindSheet.cssRules.length) {\n return;\n }\n\n if (!this.tailwindLinkElement) {\n return;\n }\n\n this.tailwindLinkElement.addEventListener('load', () => {\n if (tailwindSheet.cssRules.length) {\n return;\n }\n\n this.insertCssRules();\n });\n\n // Handle cases where the stylesheet might already be in the cache\n this.insertCssRules();\n }\n\n private insertCssRules() {\n if (this.tailwindLinkElement.sheet) {\n Array.from(this.tailwindLinkElement.sheet.cssRules).forEach((rule) => {\n try {\n tailwindSheet.insertRule(\n rule.cssText,\n tailwindSheet.cssRules.length\n );\n } catch (error) {\n console.warn('Error inserting rule:', rule.cssText, error);\n }\n });\n } else {\n console.warn(\n 'Error getting css stylesheet from element with id \"tailwind-styles\"'\n );\n }\n }\n };\n"],"names":[],"mappings":"AAGA,MAAM,gBAAgB,IAAI,cAAA;AAEnB,MAAM,SAAS,CACpB,YACA,aAA6B,CAAA,MAAC;AAJhC;AAME,4BAAc,WAAW;AAAA,
|
|
1
|
+
{"version":3,"file":"tailwind.mixin.js","sources":["../../src/mixins/tailwind.mixin.ts"],"sourcesContent":["import { type CSSResultArray, LitElement } from 'lit';\nimport type { Constructor } from '../types/mixin-constructor';\n\nconst tailwindSheet = new CSSStyleSheet();\n\nexport const styled = <T extends Constructor<LitElement>>(\n superClass: T,\n elementCss: CSSResultArray = []\n): T =>\n class extends superClass {\n /**\n * @ignore\n */\n static styles = [tailwindSheet, elementCss];\n /**\n * @ignore\n */\n private tailwindLinkElement: HTMLStyleElement;\n\n constructor(..._: any[]) {\n super();\n this.tailwindLinkElement = document.querySelector(\n '[data-mid-tailwind]'\n ) as HTMLStyleElement;\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n\n if (tailwindSheet.cssRules.length) {\n return;\n }\n\n if (!this.tailwindLinkElement) {\n return;\n }\n\n this.tailwindLinkElement.addEventListener('load', () => {\n if (tailwindSheet.cssRules.length) {\n return;\n }\n\n this.insertCssRules();\n });\n\n // Handle cases where the stylesheet might already be in the cache\n this.insertCssRules();\n }\n\n private insertCssRules() {\n if (this.tailwindLinkElement.sheet) {\n Array.from(this.tailwindLinkElement.sheet.cssRules).forEach((rule) => {\n try {\n tailwindSheet.insertRule(\n rule.cssText,\n tailwindSheet.cssRules.length\n );\n } catch (error) {\n console.warn('Error inserting rule:', rule.cssText, error);\n }\n });\n } else {\n console.warn(\n 'Error getting css stylesheet from element with id \"tailwind-styles\"'\n );\n }\n }\n };\n"],"names":[],"mappings":"AAGA,MAAM,gBAAgB,IAAI,cAAA;AAEnB,MAAM,SAAS,CACpB,YACA,aAA6B,CAAA,MAAC;AAJhC;AAME,4BAAc,WAAW;AAAA,IAUvB,eAAe,GAAU;AACvB,YAAA;AACA,WAAK,sBAAsB,SAAS;AAAA,QAClC;AAAA,MAAA;AAAA,IACF;AAAA,IAGF,oBAA0B;AACxB,YAAM,kBAAA;AAEN,UAAI,cAAc,SAAS,QAAQ;AACjC;AAAA,MAAA;AAGF,UAAI,CAAC,KAAK,qBAAqB;AAC7B;AAAA,MAAA;AAGF,WAAK,oBAAoB,iBAAiB,QAAQ,MAAM;AACtD,YAAI,cAAc,SAAS,QAAQ;AACjC;AAAA,QAAA;AAGF,aAAK,eAAA;AAAA,MAAe,CACrB;AAGD,WAAK,eAAA;AAAA,IAAe;AAAA,IAGd,iBAAiB;AACvB,UAAI,KAAK,oBAAoB,OAAO;AAClC,cAAM,KAAK,KAAK,oBAAoB,MAAM,QAAQ,EAAE,QAAQ,CAAC,SAAS;AACpE,cAAI;AACF,0BAAc;AAAA,cACZ,KAAK;AAAA,cACL,cAAc,SAAS;AAAA,YAAA;AAAA,UACzB,SACO,OAAO;AACd,oBAAQ,KAAK,yBAAyB,KAAK,SAAS,KAAK;AAAA,UAAA;AAAA,QAC3D,CACD;AAAA,MAAA,OACI;AACL,gBAAQ;AAAA,UACN;AAAA,QAAA;AAAA,MACF;AAAA,IACF;AAAA,EAEJ,GAtDE,GAAO,SAAS,CAAC,eAAe,UAAU,GAJ5C;AAAA;"}
|