luxen-ui 0.1.2 → 0.2.1
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/cdn/custom-elements.json +183 -5
- package/cdn/elements/dialog/dialog.d.ts +4 -0
- package/cdn/elements/dialog/dialog.d.ts.map +1 -1
- package/cdn/elements/dialog/dialog.js +10 -6
- package/cdn/elements/dialog/dialog.js.map +1 -1
- package/cdn/elements/dialog/dialog.styles.js +1 -1
- package/cdn/elements/dialog/dialog.styles.js.map +1 -1
- package/cdn/elements/dropdown/dropdown.js +1 -1
- package/cdn/elements/dropdown/dropdown.js.map +1 -1
- package/cdn/elements/dropdown-item/dropdown-item.js +1 -1
- package/cdn/elements/dropdown-item/dropdown-item.js.map +1 -1
- package/cdn/elements/input-stepper/input-stepper.d.ts +3 -0
- package/cdn/elements/input-stepper/input-stepper.d.ts.map +1 -1
- package/cdn/elements/input-stepper/input-stepper.js.map +1 -1
- package/cdn/elements/popover/popover.d.ts +3 -1
- package/cdn/elements/popover/popover.d.ts.map +1 -1
- package/cdn/elements/popover/popover.js +2 -2
- package/cdn/elements/popover/popover.js.map +1 -1
- package/cdn/shared/controllers/popover.d.ts +1 -0
- package/cdn/shared/controllers/popover.d.ts.map +1 -1
- package/cdn/shared/controllers/popover.js +1 -1
- package/cdn/shared/controllers/popover.js.map +1 -1
- package/cdn/styles/elements/button.css +1 -1
- package/cdn/styles/elements/input-stepper/default.css +19 -16
- package/cdn/styles/elements/input-stepper/rounded.css +14 -11
- package/cdn/styles/index.css +5 -2
- package/dist/css/elements/button.css +1 -1
- package/dist/css/elements/input-stepper/default.css +19 -16
- package/dist/css/elements/input-stepper/rounded.css +14 -11
- package/dist/css/index.css +5 -2
- package/dist/custom-elements.json +183 -5
- package/dist/elements/dialog/dialog.css +4 -3
- package/dist/elements/dialog/dialog.d.ts +4 -0
- package/dist/elements/dialog/dialog.d.ts.map +1 -1
- package/dist/elements/dialog/dialog.js +17 -4
- package/dist/elements/dropdown/dropdown.css +4 -4
- package/dist/elements/dropdown-item/dropdown-item.css +2 -1
- package/dist/elements/input-stepper/input-stepper.d.ts +3 -0
- package/dist/elements/input-stepper/input-stepper.d.ts.map +1 -1
- package/dist/elements/input-stepper/input-stepper.js +3 -0
- package/dist/elements/popover/popover.css +9 -5
- package/dist/elements/popover/popover.d.ts +3 -1
- package/dist/elements/popover/popover.d.ts.map +1 -1
- package/dist/elements/popover/popover.js +15 -4
- package/dist/shared/controllers/popover.d.ts +1 -0
- package/dist/shared/controllers/popover.d.ts.map +1 -1
- package/dist/shared/controllers/popover.js +2 -1
- package/dist/skills/luxen-ui/references/dialog.md +3 -1
- package/package.json +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown.js","names":[],"sources":["../../../src/html/elements/dropdown/dropdown.css?inline","../../../src/html/elements/dropdown/dropdown.ts"],"sourcesContent":[":host {\n --background: var(--l-color-bg-surface, Canvas);\n --radius: 8px;\n --shadow: 0 4px 16px rgb(0 0 0 / 12%);\n --show-duration: 150;\n --hide-duration: 150;\n\n display: inline-block;\n position: relative;\n}\n\n.trigger {\n display: contents;\n}\n\n[popover] {\n inset: unset;\n overflow: visible;\n box-sizing: border-box;\n width: max-content;\n min-width: anchor-size(width);\n padding: 4px 0;\n margin: 0;\n border: 1px solid var(--l-color-border, light-dark(#e5e7eb, #374151));\n border-radius: var(--radius);\n background: var(--background);\n color: var(--l-color-text-primary, CanvasText);\n box-shadow: var(--shadow);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n","import { html, unsafeCSS, type PropertyValues } from 'lit';\nimport { LuxenElement } from '../../shared/luxen-element';\nimport { property } from 'lit/decorators.js';\nimport type { Placement } from '@floating-ui/dom';\nimport { PopoverController } from '../../shared/controllers/popover';\nimport { tagName } from '../../registry';\nimport type { LuxenDropdownItem } from '../dropdown-item/dropdown-item';\nimport hostStyles from '../../shared/styles/host.styles';\nimport rawStyles from './dropdown.css?inline';\n\nconst styles = unsafeCSS(rawStyles);\n\n/**\n * A dropdown menu anchored to a trigger element.\n *\n * @slot trigger - The element that triggers the dropdown.\n * @slot - Menu content (`l-dropdown-item` elements).\n *\n * @csspart panel - The floating menu container.\n *\n * @cssproperty --background - Panel background color.\n * @cssproperty --radius - Panel border radius. Default `8px`.\n * @cssproperty --shadow - Panel box shadow.\n * @cssproperty --show-duration - Show animation duration in ms. Default `150`.\n * @cssproperty --hide-duration - Hide animation duration in ms. Default `150`.\n *\n * @event show - Fired before the dropdown opens. Cancelable.\n * @event after-show - Fired after the open animation completes.\n * @event hide - Fired before the dropdown closes. Cancelable.\n * @event after-hide - Fired after the close animation completes.\n * @event select - Fired when an item is selected. Detail: `{ item: LuxenDropdownItem }`.\n */\nexport class LuxenDropdown extends LuxenElement {\n static override styles = [hostStyles, styles];\n\n private _floating = new PopoverController(this, {\n getTriggerElement: () => this._triggerEl,\n getFloatingElement: () => this._panelEl,\n getArrowElement: () => null,\n });\n\n private _typeaheadBuffer = '';\n private _typeaheadTimeout = 0;\n\n /** Whether the dropdown is open. */\n @property({ type: Boolean, reflect: true })\n accessor open = false;\n\n /** Preferred placement of the panel. */\n @property()\n accessor placement: Placement = 'bottom-start';\n\n /** Distance in pixels from the trigger. */\n @property({ type: Number })\n accessor distance = 4;\n\n /** Disables the dropdown trigger. */\n @property({ type: Boolean, reflect: true })\n accessor disabled = false;\n\n private get _triggerEl(): HTMLElement | null {\n const slot = this.shadowRoot!.querySelector<HTMLSlotElement>('.trigger slot');\n return (slot?.assignedElements()[0] as HTMLElement) ?? null;\n }\n\n private get _panelEl(): HTMLElement | null {\n return this.shadowRoot!.querySelector<HTMLElement>('[popover]');\n }\n\n private _getItems(): LuxenDropdownItem[] {\n const menuSlot = this.shadowRoot!.querySelector<HTMLSlotElement>('slot:not([name])');\n if (!menuSlot) return [];\n return (menuSlot.assignedElements() as LuxenDropdownItem[]).filter(\n (el) => el.tagName === tagName('dropdown-item').toUpperCase() && !el.disabled,\n );\n }\n\n private _getAllItems(): LuxenDropdownItem[] {\n const menuSlot = this.shadowRoot!.querySelector<HTMLSlotElement>('slot:not([name])');\n if (!menuSlot) return [];\n return (menuSlot.assignedElements() as LuxenDropdownItem[]).filter(\n (el) => el.tagName === tagName('dropdown-item').toUpperCase(),\n );\n }\n\n private _getDuration(prop: '--show-duration' | '--hide-duration'): number {\n const parsed = parseFloat(getComputedStyle(this).getPropertyValue(prop));\n return Number.isNaN(parsed) ? 150 : parsed;\n }\n\n // --- Public API ---\n\n show() {\n if (this.open || this.disabled) return;\n if (this.emit('show', { cancelable: true })) this.open = true;\n }\n\n hide() {\n if (!this.open) return;\n if (this.emit('hide', { cancelable: true })) this.open = false;\n }\n\n toggle() {\n if (this.open) this.hide();\n else this.show();\n }\n\n // --- Lifecycle ---\n\n override updated(changed: PropertyValues<this>) {\n if (changed.has('open')) {\n this._handleOpenChange();\n }\n }\n\n // --- Open/Close ---\n\n private async _handleOpenChange() {\n const panel = this._panelEl;\n if (!panel) return;\n\n const posOpts = { placement: this.placement, distance: this.distance };\n\n if (this.open) {\n panel.showPopover();\n await this._floating.updatePosition(posOpts);\n if (!this.open) return;\n await this._floating.animateShow(panel, this._getDuration('--show-duration'));\n this._floating.startPositioning(posOpts);\n this._triggerEl?.setAttribute('aria-expanded', 'true');\n this.emit('after-show');\n } else {\n this._floating.stopPositioning();\n this._triggerEl?.setAttribute('aria-expanded', 'false');\n await this._floating.animateHide(panel, this._getDuration('--hide-duration'));\n if (panel.matches(':popover-open')) panel.hidePopover();\n this.emit('after-hide');\n }\n }\n\n // --- Focus management ---\n\n private _setActiveItem(item: LuxenDropdownItem) {\n const itemEl = item.shadowRoot!.querySelector<HTMLElement>('.item');\n if (!itemEl) return;\n\n // Reset all items\n for (const i of this._getAllItems()) {\n const el = i.shadowRoot!.querySelector<HTMLElement>('.item');\n el?.setAttribute('tabindex', '-1');\n }\n\n itemEl.setAttribute('tabindex', '0');\n itemEl.focus();\n }\n\n private _focusFirstItem() {\n const items = this._getItems();\n if (items.length) this._setActiveItem(items[0]);\n }\n\n private _focusLastItem() {\n const items = this._getItems();\n if (items.length) this._setActiveItem(items[items.length - 1]);\n }\n\n private _getCurrentItem(): LuxenDropdownItem | null {\n const items = this._getItems();\n return (\n items.find((item) => {\n const el = item.shadowRoot!.querySelector<HTMLElement>('.item');\n return el?.getAttribute('tabindex') === '0' && item.shadowRoot!.activeElement === el;\n }) ?? null\n );\n }\n\n private _focusNextItem() {\n const items = this._getItems();\n const current = this._getCurrentItem();\n const index = current ? items.indexOf(current) : -1;\n const next = items[(index + 1) % items.length];\n if (next) this._setActiveItem(next);\n }\n\n private _focusPreviousItem() {\n const items = this._getItems();\n const current = this._getCurrentItem();\n const index = current ? items.indexOf(current) : 0;\n const prev = items[(index - 1 + items.length) % items.length];\n if (prev) this._setActiveItem(prev);\n }\n\n // --- Typeahead ---\n\n private _handleTypeahead(key: string) {\n clearTimeout(this._typeaheadTimeout);\n this._typeaheadBuffer += key.toLowerCase();\n this._typeaheadTimeout = window.setTimeout(() => {\n this._typeaheadBuffer = '';\n }, 500);\n\n const items = this._getItems();\n const match = items.find((item) =>\n item.getTextLabel().toLowerCase().startsWith(this._typeaheadBuffer),\n );\n if (match) this._setActiveItem(match);\n }\n\n // --- Event handlers ---\n\n private _onTriggerClick = () => {\n if (!this.disabled) this.toggle();\n };\n\n private _onTriggerKeyDown = (e: KeyboardEvent) => {\n if (this.disabled) return;\n\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n this.show();\n requestAnimationFrame(() => this._focusFirstItem());\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n this.show();\n requestAnimationFrame(() => this._focusLastItem());\n }\n };\n\n private _onPanelKeyDown = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n this._focusNextItem();\n break;\n case 'ArrowUp':\n e.preventDefault();\n this._focusPreviousItem();\n break;\n case 'Home':\n e.preventDefault();\n this._focusFirstItem();\n break;\n case 'End':\n e.preventDefault();\n this._focusLastItem();\n break;\n case 'Escape':\n e.preventDefault();\n this.hide();\n this._triggerEl?.focus();\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n this._selectCurrentItem();\n break;\n default:\n if (e.key.length === 1 && !e.ctrlKey && !e.metaKey) {\n this._handleTypeahead(e.key);\n }\n }\n };\n\n private _onItemClick = (e: Event) => {\n const item = (e.target as HTMLElement).closest<LuxenDropdownItem>(tagName('dropdown-item'));\n if (item && !item.disabled) {\n this._selectItem(item);\n }\n };\n\n private _selectCurrentItem() {\n const current = this._getCurrentItem();\n if (current) this._selectItem(current);\n }\n\n private _selectItem(item: LuxenDropdownItem) {\n if (item.type === 'checkbox') {\n item.checked = !item.checked;\n }\n this.emit('select', { detail: { item } });\n if (item.type !== 'checkbox') {\n this.hide();\n this._triggerEl?.focus();\n }\n }\n\n /** Sync `open` when popover=\"auto\" light-dismiss fires. */\n private _onToggle = (e: Event) => {\n const toggleEvent = e as ToggleEvent;\n if (toggleEvent.newState === 'closed' && this.open) {\n this.open = false;\n this._triggerEl?.setAttribute('aria-expanded', 'false');\n }\n };\n\n override render() {\n return html`\n <div\n class=\"trigger\"\n @click=${this._onTriggerClick}\n @keydown=${this._onTriggerKeyDown}\n >\n <slot name=\"trigger\"></slot>\n </div>\n <div\n popover=\"auto\"\n part=\"panel\"\n role=\"menu\"\n @keydown=${this._onPanelKeyDown}\n @click=${this._onItemClick}\n @toggle=${this._onToggle}\n >\n <slot></slot>\n </div>\n `;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dropdown.js","names":[],"sources":["../../../src/html/elements/dropdown/dropdown.css?inline","../../../src/html/elements/dropdown/dropdown.ts"],"sourcesContent":[":host {\n --background: var(--l-color-bg-surface, Canvas);\n --radius: 6px;\n --shadow: 0 4px 6px -1px rgb(0 0 0 / 8%), 0 2px 4px -2px rgb(0 0 0 / 6%);\n --show-duration: 150;\n --hide-duration: 150;\n\n display: inline-block;\n position: relative;\n}\n\n.trigger {\n display: contents;\n}\n\n[popover] {\n inset: unset;\n overflow: visible;\n box-sizing: border-box;\n width: max-content;\n min-width: anchor-size(width);\n padding: 0.25rem;\n margin: 0;\n border: 1px solid var(--l-color-border-overlay, light-dark(#e5e7eb, #374151));\n border-radius: var(--radius);\n background: var(--background);\n color: var(--l-color-text-primary, CanvasText);\n box-shadow: var(--shadow);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n","import { html, unsafeCSS, type PropertyValues } from 'lit';\nimport { LuxenElement } from '../../shared/luxen-element';\nimport { property } from 'lit/decorators.js';\nimport type { Placement } from '@floating-ui/dom';\nimport { PopoverController } from '../../shared/controllers/popover';\nimport { tagName } from '../../registry';\nimport type { LuxenDropdownItem } from '../dropdown-item/dropdown-item';\nimport hostStyles from '../../shared/styles/host.styles';\nimport rawStyles from './dropdown.css?inline';\n\nconst styles = unsafeCSS(rawStyles);\n\n/**\n * A dropdown menu anchored to a trigger element.\n *\n * @slot trigger - The element that triggers the dropdown.\n * @slot - Menu content (`l-dropdown-item` elements).\n *\n * @csspart panel - The floating menu container.\n *\n * @cssproperty --background - Panel background color.\n * @cssproperty --radius - Panel border radius. Default `8px`.\n * @cssproperty --shadow - Panel box shadow.\n * @cssproperty --show-duration - Show animation duration in ms. Default `150`.\n * @cssproperty --hide-duration - Hide animation duration in ms. Default `150`.\n *\n * @event show - Fired before the dropdown opens. Cancelable.\n * @event after-show - Fired after the open animation completes.\n * @event hide - Fired before the dropdown closes. Cancelable.\n * @event after-hide - Fired after the close animation completes.\n * @event select - Fired when an item is selected. Detail: `{ item: LuxenDropdownItem }`.\n */\nexport class LuxenDropdown extends LuxenElement {\n static override styles = [hostStyles, styles];\n\n private _floating = new PopoverController(this, {\n getTriggerElement: () => this._triggerEl,\n getFloatingElement: () => this._panelEl,\n getArrowElement: () => null,\n });\n\n private _typeaheadBuffer = '';\n private _typeaheadTimeout = 0;\n\n /** Whether the dropdown is open. */\n @property({ type: Boolean, reflect: true })\n accessor open = false;\n\n /** Preferred placement of the panel. */\n @property()\n accessor placement: Placement = 'bottom-start';\n\n /** Distance in pixels from the trigger. */\n @property({ type: Number })\n accessor distance = 4;\n\n /** Disables the dropdown trigger. */\n @property({ type: Boolean, reflect: true })\n accessor disabled = false;\n\n private get _triggerEl(): HTMLElement | null {\n const slot = this.shadowRoot!.querySelector<HTMLSlotElement>('.trigger slot');\n return (slot?.assignedElements()[0] as HTMLElement) ?? null;\n }\n\n private get _panelEl(): HTMLElement | null {\n return this.shadowRoot!.querySelector<HTMLElement>('[popover]');\n }\n\n private _getItems(): LuxenDropdownItem[] {\n const menuSlot = this.shadowRoot!.querySelector<HTMLSlotElement>('slot:not([name])');\n if (!menuSlot) return [];\n return (menuSlot.assignedElements() as LuxenDropdownItem[]).filter(\n (el) => el.tagName === tagName('dropdown-item').toUpperCase() && !el.disabled,\n );\n }\n\n private _getAllItems(): LuxenDropdownItem[] {\n const menuSlot = this.shadowRoot!.querySelector<HTMLSlotElement>('slot:not([name])');\n if (!menuSlot) return [];\n return (menuSlot.assignedElements() as LuxenDropdownItem[]).filter(\n (el) => el.tagName === tagName('dropdown-item').toUpperCase(),\n );\n }\n\n private _getDuration(prop: '--show-duration' | '--hide-duration'): number {\n const parsed = parseFloat(getComputedStyle(this).getPropertyValue(prop));\n return Number.isNaN(parsed) ? 150 : parsed;\n }\n\n // --- Public API ---\n\n show() {\n if (this.open || this.disabled) return;\n if (this.emit('show', { cancelable: true })) this.open = true;\n }\n\n hide() {\n if (!this.open) return;\n if (this.emit('hide', { cancelable: true })) this.open = false;\n }\n\n toggle() {\n if (this.open) this.hide();\n else this.show();\n }\n\n // --- Lifecycle ---\n\n override updated(changed: PropertyValues<this>) {\n if (changed.has('open')) {\n this._handleOpenChange();\n }\n }\n\n // --- Open/Close ---\n\n private async _handleOpenChange() {\n const panel = this._panelEl;\n if (!panel) return;\n\n const posOpts = { placement: this.placement, distance: this.distance };\n\n if (this.open) {\n panel.showPopover();\n await this._floating.updatePosition(posOpts);\n if (!this.open) return;\n await this._floating.animateShow(panel, this._getDuration('--show-duration'));\n this._floating.startPositioning(posOpts);\n this._triggerEl?.setAttribute('aria-expanded', 'true');\n this.emit('after-show');\n } else {\n this._floating.stopPositioning();\n this._triggerEl?.setAttribute('aria-expanded', 'false');\n await this._floating.animateHide(panel, this._getDuration('--hide-duration'));\n if (panel.matches(':popover-open')) panel.hidePopover();\n this.emit('after-hide');\n }\n }\n\n // --- Focus management ---\n\n private _setActiveItem(item: LuxenDropdownItem) {\n const itemEl = item.shadowRoot!.querySelector<HTMLElement>('.item');\n if (!itemEl) return;\n\n // Reset all items\n for (const i of this._getAllItems()) {\n const el = i.shadowRoot!.querySelector<HTMLElement>('.item');\n el?.setAttribute('tabindex', '-1');\n }\n\n itemEl.setAttribute('tabindex', '0');\n itemEl.focus();\n }\n\n private _focusFirstItem() {\n const items = this._getItems();\n if (items.length) this._setActiveItem(items[0]);\n }\n\n private _focusLastItem() {\n const items = this._getItems();\n if (items.length) this._setActiveItem(items[items.length - 1]);\n }\n\n private _getCurrentItem(): LuxenDropdownItem | null {\n const items = this._getItems();\n return (\n items.find((item) => {\n const el = item.shadowRoot!.querySelector<HTMLElement>('.item');\n return el?.getAttribute('tabindex') === '0' && item.shadowRoot!.activeElement === el;\n }) ?? null\n );\n }\n\n private _focusNextItem() {\n const items = this._getItems();\n const current = this._getCurrentItem();\n const index = current ? items.indexOf(current) : -1;\n const next = items[(index + 1) % items.length];\n if (next) this._setActiveItem(next);\n }\n\n private _focusPreviousItem() {\n const items = this._getItems();\n const current = this._getCurrentItem();\n const index = current ? items.indexOf(current) : 0;\n const prev = items[(index - 1 + items.length) % items.length];\n if (prev) this._setActiveItem(prev);\n }\n\n // --- Typeahead ---\n\n private _handleTypeahead(key: string) {\n clearTimeout(this._typeaheadTimeout);\n this._typeaheadBuffer += key.toLowerCase();\n this._typeaheadTimeout = window.setTimeout(() => {\n this._typeaheadBuffer = '';\n }, 500);\n\n const items = this._getItems();\n const match = items.find((item) =>\n item.getTextLabel().toLowerCase().startsWith(this._typeaheadBuffer),\n );\n if (match) this._setActiveItem(match);\n }\n\n // --- Event handlers ---\n\n private _onTriggerClick = () => {\n if (!this.disabled) this.toggle();\n };\n\n private _onTriggerKeyDown = (e: KeyboardEvent) => {\n if (this.disabled) return;\n\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n this.show();\n requestAnimationFrame(() => this._focusFirstItem());\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n this.show();\n requestAnimationFrame(() => this._focusLastItem());\n }\n };\n\n private _onPanelKeyDown = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n this._focusNextItem();\n break;\n case 'ArrowUp':\n e.preventDefault();\n this._focusPreviousItem();\n break;\n case 'Home':\n e.preventDefault();\n this._focusFirstItem();\n break;\n case 'End':\n e.preventDefault();\n this._focusLastItem();\n break;\n case 'Escape':\n e.preventDefault();\n this.hide();\n this._triggerEl?.focus();\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n this._selectCurrentItem();\n break;\n default:\n if (e.key.length === 1 && !e.ctrlKey && !e.metaKey) {\n this._handleTypeahead(e.key);\n }\n }\n };\n\n private _onItemClick = (e: Event) => {\n const item = (e.target as HTMLElement).closest<LuxenDropdownItem>(tagName('dropdown-item'));\n if (item && !item.disabled) {\n this._selectItem(item);\n }\n };\n\n private _selectCurrentItem() {\n const current = this._getCurrentItem();\n if (current) this._selectItem(current);\n }\n\n private _selectItem(item: LuxenDropdownItem) {\n if (item.type === 'checkbox') {\n item.checked = !item.checked;\n }\n this.emit('select', { detail: { item } });\n if (item.type !== 'checkbox') {\n this.hide();\n this._triggerEl?.focus();\n }\n }\n\n /** Sync `open` when popover=\"auto\" light-dismiss fires. */\n private _onToggle = (e: Event) => {\n const toggleEvent = e as ToggleEvent;\n if (toggleEvent.newState === 'closed' && this.open) {\n this.open = false;\n this._triggerEl?.setAttribute('aria-expanded', 'false');\n }\n };\n\n override render() {\n return html`\n <div\n class=\"trigger\"\n @click=${this._onTriggerClick}\n @keydown=${this._onTriggerKeyDown}\n >\n <slot name=\"trigger\"></slot>\n </div>\n <div\n popover=\"auto\"\n part=\"panel\"\n role=\"menu\"\n @keydown=${this._onPanelKeyDown}\n @click=${this._onItemClick}\n @toggle=${this._onToggle}\n >\n <slot></slot>\n </div>\n `;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as e,i as t,n}from"../../chunks/lit.js";import{LuxenElement as r}from"../../shared/luxen-element.js";import{a as i,t as a}from"../../chunks/decorate.js";import o from"../../shared/styles/host.styles.js";var s=e(`:host{display:block}:host([disabled]){pointer-events:none;opacity:.5}.item{cursor:pointer;color:var(--l-color-text-primary,CanvasText);white-space:nowrap;outline:none;align-items:center;gap:8px;padding
|
|
1
|
+
import{c as e,i as t,n}from"../../chunks/lit.js";import{LuxenElement as r}from"../../shared/luxen-element.js";import{a as i,t as a}from"../../chunks/decorate.js";import o from"../../shared/styles/host.styles.js";var s=e(`:host{display:block}:host([disabled]){pointer-events:none;opacity:.5}.item{cursor:pointer;color:var(--l-color-text-primary,CanvasText);white-space:nowrap;border-radius:4px;outline:none;align-items:center;gap:8px;padding:.375rem .5rem;font-size:.875rem;line-height:1.5;display:flex}.item:focus-visible{background:var(--l-color-bg-state-hover)}@media (hover:hover){.item:hover{background:var(--l-color-bg-state-hover)}}.check{flex-shrink:0;width:16px;display:flex}:host(:not([checked])) .check svg{visibility:hidden}::slotted([slot=prefix]),::slotted([slot=suffix]){flex-shrink:0;display:flex}.label{flex:1}`),c=class extends r{static{this.styles=[o,s]}#e=``;get value(){return this.#e}set value(e){this.#e=e}#t=!1;get disabled(){return this.#t}set disabled(e){this.#t=e}#n=`normal`;get type(){return this.#n}set type(e){this.#n=e}#r=!1;get checked(){return this.#r}set checked(e){this.#r=e}getTextLabel(){return(this.textContent??``).trim()}render(){let e=this.type===`checkbox`;return t`
|
|
2
2
|
<div
|
|
3
3
|
class="item"
|
|
4
4
|
role=${e?`menuitemcheckbox`:`menuitem`}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown-item.js","names":[],"sources":["../../../src/html/elements/dropdown-item/dropdown-item.css?inline","../../../src/html/elements/dropdown-item/dropdown-item.ts"],"sourcesContent":[":host {\n display: block;\n}\n\n:host([disabled]) {\n pointer-events: none;\n opacity: 0.5;\n}\n\n.item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding:
|
|
1
|
+
{"version":3,"file":"dropdown-item.js","names":[],"sources":["../../../src/html/elements/dropdown-item/dropdown-item.css?inline","../../../src/html/elements/dropdown-item/dropdown-item.ts"],"sourcesContent":[":host {\n display: block;\n}\n\n:host([disabled]) {\n pointer-events: none;\n opacity: 0.5;\n}\n\n.item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 0.375rem 0.5rem;\n cursor: pointer;\n outline: none;\n border-radius: 4px;\n font-size: 0.875rem;\n line-height: 1.5;\n color: var(--l-color-text-primary, CanvasText);\n white-space: nowrap;\n}\n\n.item:focus-visible {\n background: var(--l-color-bg-state-hover);\n}\n\n@media (hover: hover) {\n .item:hover {\n background: var(--l-color-bg-state-hover);\n }\n}\n\n.check {\n display: flex;\n width: 16px;\n flex-shrink: 0;\n}\n\n:host(:not([checked])) .check svg {\n visibility: hidden;\n}\n\n::slotted([slot='prefix']),\n::slotted([slot='suffix']) {\n display: flex;\n flex-shrink: 0;\n}\n\n.label {\n flex: 1;\n}\n","import { html, nothing, unsafeCSS } from 'lit';\nimport { LuxenElement } from '../../shared/luxen-element';\nimport { property } from 'lit/decorators.js';\nimport hostStyles from '../../shared/styles/host.styles';\nimport rawStyles from './dropdown-item.css?inline';\n\nconst styles = unsafeCSS(rawStyles);\n\n/**\n * A menu item for use inside `<l-dropdown>`.\n *\n * @slot - Label text.\n * @slot prefix - Leading content (e.g. icon).\n * @slot suffix - Trailing content.\n *\n * @cssproperty --color - Text color.\n */\nexport class LuxenDropdownItem extends LuxenElement {\n static override styles = [hostStyles, styles];\n\n /** The value associated with this item. */\n @property()\n accessor value = '';\n\n /** Disables the item. */\n @property({ type: Boolean, reflect: true })\n accessor disabled = false;\n\n /** The type of item: `normal` or `checkbox`. */\n @property()\n accessor type: 'normal' | 'checkbox' = 'normal';\n\n /** Whether the checkbox item is checked. */\n @property({ type: Boolean, reflect: true })\n accessor checked = false;\n\n /** Returns the text label of this item. */\n getTextLabel(): string {\n return (this.textContent ?? '').trim();\n }\n\n override render() {\n const isCheckbox = this.type === 'checkbox';\n\n return html`\n <div\n class=\"item\"\n role=${isCheckbox ? 'menuitemcheckbox' : 'menuitem'}\n aria-checked=${isCheckbox ? String(this.checked) : nothing}\n aria-disabled=${this.disabled ? 'true' : nothing}\n tabindex=\"-1\"\n >\n ${isCheckbox\n ? html`\n <span\n class=\"check\"\n aria-hidden=\"true\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M3.5 8.5L6.5 11.5L12.5 4.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n `\n : html` <slot name=\"prefix\"></slot> `}\n <span class=\"label\"><slot></slot></span>\n <slot name=\"suffix\"></slot>\n </div>\n `;\n }\n}\n"],"mappings":"oNCMA,IAAM,EAAS,kmBAAoB,CAWtB,EAAb,cAAuC,CAAa,oBACzB,CAAC,EAAY,EAAO,IAI5B,OAAR,OAAA,0CAIW,OAAX,UAAA,6CAI8B,aAA9B,MAAA,yCAIU,OAAV,SAAA,yCAGT,cAAuB,CACrB,OAAQ,KAAK,aAAe,IAAI,MAAM,CAGxC,QAAkB,CAChB,IAAM,EAAa,KAAK,OAAS,WAEjC,MAAO,EAAI;;;eAGA,EAAa,mBAAqB,WAAW;uBACrC,EAAa,OAAO,KAAK,QAAQ,CAAG,EAAQ;wBAC3C,KAAK,SAAW,OAAS,EAAQ;;;UAG/C,EACE,CAAI;;;;;;;;;;;;;;;;;;;;cAqBJ,CAAI,gCAAgC;;;;WArD7C,GAAU,CAAA,CAAA,EAAA,UAAA,QAAA,KAAA,IAIV,EAAS,CAAE,KAAM,QAAS,QAAS,GAAM,CAAC,CAAA,CAAA,EAAA,UAAA,WAAA,KAAA,IAI1C,GAAU,CAAA,CAAA,EAAA,UAAA,OAAA,KAAA,IAIV,EAAS,CAAE,KAAM,QAAS,QAAS,GAAM,CAAC,CAAA,CAAA,EAAA,UAAA,UAAA,KAAA"}
|
|
@@ -14,6 +14,9 @@ export type InputStepperSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
|
14
14
|
* ```
|
|
15
15
|
*
|
|
16
16
|
* @event change - Fired when the value changes. Detail: `{ value: number }`.
|
|
17
|
+
*
|
|
18
|
+
* @cssproperty --border-color - Border color of the stepper container (default appearance) and of each button (rounded appearance). Defaults to `--l-color-border`.
|
|
19
|
+
* @cssproperty --border-radius - Border radius of the stepper container (default appearance). Defaults to `--radius-md`.
|
|
17
20
|
*/
|
|
18
21
|
export declare class LuxenInputStepper extends LuxenElement {
|
|
19
22
|
createRenderRoot(): this;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-stepper.d.ts","sourceRoot":"","sources":["../../../src/html/elements/input-stepper/input-stepper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEhE
|
|
1
|
+
{"version":3,"file":"input-stepper.d.ts","sourceRoot":"","sources":["../../../src/html/elements/input-stepper/input-stepper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEhE;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IACxC,gBAAgB;IAIzB,wEAAwE;IAExE,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,wEAAwE;IAExE,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,kEAAkE;IAElE,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,oBAAoB;IAEpB,IAAI,EAAE,gBAAgB,CAAQ;IAE9B,iDAAiD;IAEjD,UAAU,UAAS;IAEnB,0CAA0C;IAE1C,aAAa,SAAkB;IAE/B,0CAA0C;IAE1C,aAAa,SAAiB;IAE9B,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,eAAe,CAAS;IAEvB,iBAAiB;IAKjB,oBAAoB;IAKpB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAS9C,sCAAsC;IACtC,SAAS;IAOT,sCAAsC;IACtC,SAAS;IAST,OAAO,CAAC,MAAM;IAsCd,OAAO,CAAC,SAAS;IAwBjB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,oBAAoB;IAgB5B,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,YAAY,CAA0B;IAE9C,OAAO,CAAC,cAAc,CAWpB;CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-stepper.js","names":[],"sources":["../../../src/html/elements/input-stepper/input-stepper.ts"],"sourcesContent":["import { property } from 'lit/decorators.js';\nimport { LuxenElement } from '../../shared/luxen-element';\n\nexport type InputStepperSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\n/**\n * A stepper control that enhances a native `<input type=\"number\">` with\n * decrement/increment buttons and an optional animated number track.\n *\n * @link https://www.nngroup.com/articles/input-steppers/\n *\n * @example\n * ```html\n * <l-input-stepper>\n * <input type=\"number\" min=\"0\" max=\"10\" value=\"5\" />\n * </l-input-stepper>\n * ```\n *\n * @event change - Fired when the value changes. Detail: `{ value: number }`.\n */\nexport class LuxenInputStepper extends LuxenElement {\n override createRenderRoot() {\n return this;\n }\n\n /** Minimum allowed value. Falls back to the input's `min` attribute. */\n @property({ type: Number })\n min?: number;\n\n /** Maximum allowed value. Falls back to the input's `max` attribute. */\n @property({ type: Number })\n max?: number;\n\n /** Step increment. Falls back to the input's `step` attribute. */\n @property({ type: Number })\n step?: number;\n\n /** Control size. */\n @property({ reflect: true })\n size: InputStepperSize = 'md';\n\n /** Enable the animated number roller overlay. */\n @property({ type: Boolean, reflect: true, attribute: 'with-roller' })\n withRoller = false;\n\n /** Icon name for the decrement button. */\n @property({ attribute: 'decrement-icon' })\n decrementIcon = 'lucide:minus';\n\n /** Icon name for the increment button. */\n @property({ attribute: 'increment-icon' })\n incrementIcon = 'lucide:plus';\n\n private _input: HTMLInputElement | null = null;\n private _decrementBtn: HTMLButtonElement | null = null;\n private _incrementBtn: HTMLButtonElement | null = null;\n private _valueWrapper: HTMLDivElement | null = null;\n private _trackDisplay: HTMLDivElement | null = null;\n private _track: HTMLDivElement | null = null;\n private _observer: MutationObserver | null = null;\n private _skipTransition = false;\n\n override connectedCallback() {\n super.connectedCallback();\n requestAnimationFrame(() => this._setup());\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this._teardown();\n }\n\n override updated(changed: Map<string, unknown>) {\n if (!this._input) return;\n\n if (changed.has('min') || changed.has('max') || changed.has('step')) {\n this._syncConstraints();\n this._updateButtonStates();\n }\n }\n\n /** Decrease the value by one step. */\n decrement() {\n if (!this._input) return;\n const { min, step } = this._getConstraints();\n const newVal = Math.max(this._input.valueAsNumber - step, min);\n this._applyValue(newVal);\n }\n\n /** Increase the value by one step. */\n increment() {\n if (!this._input) return;\n const { max, step } = this._getConstraints();\n const newVal = Math.min(this._input.valueAsNumber + step, max);\n this._applyValue(newVal);\n }\n\n // --- Setup / Teardown ---\n\n private _setup() {\n this._input = this.querySelector('input[type=\"number\"]');\n if (!this._input) return;\n\n this._input.inputMode = 'numeric';\n\n // Wrap input in value container\n this._valueWrapper = document.createElement('div');\n this._valueWrapper.className = 'l-input-stepper-value';\n this._input.replaceWith(this._valueWrapper);\n this._valueWrapper.appendChild(this._input);\n\n // Inject track overlay\n if (this.withRoller) {\n this._buildTrack();\n }\n\n // Create buttons\n this._decrementBtn = this._createButton(this.decrementIcon, 'Decrease value');\n this._incrementBtn = this._createButton(this.incrementIcon, 'Increase value');\n\n this._valueWrapper.before(this._decrementBtn);\n this._valueWrapper.after(this._incrementBtn);\n\n // Events\n this._decrementBtn.addEventListener('click', this._onDecrement);\n this._incrementBtn.addEventListener('click', this._onIncrement);\n this._input.addEventListener('change', this._onInputChange);\n\n // Observe disabled attribute on input\n this._observer = new MutationObserver(() => this._updateButtonStates());\n this._observer.observe(this._input, { attributes: true, attributeFilter: ['disabled'] });\n\n this._syncConstraints();\n this._updateButtonStates();\n this._updateTrack();\n }\n\n private _teardown() {\n this._decrementBtn?.removeEventListener('click', this._onDecrement);\n this._incrementBtn?.removeEventListener('click', this._onIncrement);\n this._input?.removeEventListener('change', this._onInputChange);\n this._observer?.disconnect();\n\n // Restore input to direct child\n if (this._input && this._valueWrapper) {\n this._valueWrapper.replaceWith(this._input);\n }\n this._decrementBtn?.remove();\n this._incrementBtn?.remove();\n\n this._input = null;\n this._decrementBtn = null;\n this._incrementBtn = null;\n this._valueWrapper = null;\n this._trackDisplay = null;\n this._track = null;\n this._observer = null;\n }\n\n // --- DOM helpers ---\n\n private _createButton(icon: string, label: string): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.setAttribute('aria-label', label);\n btn.innerHTML = `<l-icon name=\"${icon}\"></l-icon>`;\n return btn;\n }\n\n private _buildTrack() {\n if (!this._valueWrapper) return;\n\n this._trackDisplay = document.createElement('div');\n this._trackDisplay.className = 'l-input-stepper-track-display';\n\n this._track = document.createElement('div');\n this._track.className = 'l-input-stepper-track';\n this._track.setAttribute('aria-hidden', 'true');\n\n this._rebuildTrackNumbers();\n this._trackDisplay.appendChild(this._track);\n this._valueWrapper.appendChild(this._trackDisplay);\n }\n\n private _rebuildTrackNumbers() {\n if (!this._track) return;\n\n const { min, max, step } = this._getConstraints();\n const effectiveMax = Number.isFinite(max) ? max : (this._input?.valueAsNumber ?? 0) + 100;\n\n this._track.innerHTML = '';\n for (let i = min; i <= effectiveMax; i += step) {\n const div = document.createElement('div');\n div.textContent = String(i);\n this._track.appendChild(div);\n }\n }\n\n // --- Constraints ---\n\n private _getConstraints() {\n const min = this.min ?? (Number(this._input?.getAttribute('min')) || 0);\n const max =\n this.max ??\n (this._input?.hasAttribute('max') ? Number(this._input.getAttribute('max')) : Infinity);\n const step = this.step ?? (Number(this._input?.getAttribute('step')) || 1);\n return { min, max, step };\n }\n\n private _syncConstraints() {\n if (!this._input) return;\n const { min, max, step } = this._getConstraints();\n\n this._input.min = String(min);\n if (Number.isFinite(max)) this._input.max = String(max);\n this._input.step = String(step);\n\n this._rebuildTrackNumbers();\n this._updateTrack();\n }\n\n // --- Value ---\n\n private _applyValue(val: number) {\n if (!this._input) return;\n this._input.value = String(val);\n this._updateButtonStates();\n this._updateTrack();\n this.emit('change', { detail: { value: val } });\n }\n\n // --- Track ---\n\n private _updateTrack() {\n if (!this._track) return;\n\n const { min, step } = this._getConstraints();\n const value = this._input?.valueAsNumber ?? min;\n const offset = (min - value) / step;\n\n this._track.style.translate = `0 calc(${offset} * var(--_button-size))`;\n\n if (this._skipTransition) {\n this._track.style.transition = 'none';\n void this._track.offsetHeight;\n this._track.style.transition = '';\n this._skipTransition = false;\n }\n }\n\n // --- Button states ---\n\n private _updateButtonStates() {\n if (!this._input || !this._decrementBtn || !this._incrementBtn) return;\n\n const { min, max } = this._getConstraints();\n const value = this._input.valueAsNumber;\n const disabled = this._input.disabled;\n\n this._decrementBtn.disabled = disabled || value <= min;\n this._incrementBtn.disabled = disabled || value >= max;\n }\n\n // --- Event handlers ---\n\n private _onDecrement = () => this.decrement();\n private _onIncrement = () => this.increment();\n\n private _onInputChange = () => {\n if (!this._input) return;\n\n const { min, max } = this._getConstraints();\n const clamped = Math.min(Math.max(this._input.valueAsNumber, min), max);\n this._input.value = String(clamped);\n\n this._skipTransition = true;\n this._updateButtonStates();\n this._updateTrack();\n this.emit('change', { detail: { value: clamped } });\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"input-stepper.js","names":[],"sources":["../../../src/html/elements/input-stepper/input-stepper.ts"],"sourcesContent":["import { property } from 'lit/decorators.js';\nimport { LuxenElement } from '../../shared/luxen-element';\n\nexport type InputStepperSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\n/**\n * A stepper control that enhances a native `<input type=\"number\">` with\n * decrement/increment buttons and an optional animated number track.\n *\n * @link https://www.nngroup.com/articles/input-steppers/\n *\n * @example\n * ```html\n * <l-input-stepper>\n * <input type=\"number\" min=\"0\" max=\"10\" value=\"5\" />\n * </l-input-stepper>\n * ```\n *\n * @event change - Fired when the value changes. Detail: `{ value: number }`.\n *\n * @cssproperty --border-color - Border color of the stepper container (default appearance) and of each button (rounded appearance). Defaults to `--l-color-border`.\n * @cssproperty --border-radius - Border radius of the stepper container (default appearance). Defaults to `--radius-md`.\n */\nexport class LuxenInputStepper extends LuxenElement {\n override createRenderRoot() {\n return this;\n }\n\n /** Minimum allowed value. Falls back to the input's `min` attribute. */\n @property({ type: Number })\n min?: number;\n\n /** Maximum allowed value. Falls back to the input's `max` attribute. */\n @property({ type: Number })\n max?: number;\n\n /** Step increment. Falls back to the input's `step` attribute. */\n @property({ type: Number })\n step?: number;\n\n /** Control size. */\n @property({ reflect: true })\n size: InputStepperSize = 'md';\n\n /** Enable the animated number roller overlay. */\n @property({ type: Boolean, reflect: true, attribute: 'with-roller' })\n withRoller = false;\n\n /** Icon name for the decrement button. */\n @property({ attribute: 'decrement-icon' })\n decrementIcon = 'lucide:minus';\n\n /** Icon name for the increment button. */\n @property({ attribute: 'increment-icon' })\n incrementIcon = 'lucide:plus';\n\n private _input: HTMLInputElement | null = null;\n private _decrementBtn: HTMLButtonElement | null = null;\n private _incrementBtn: HTMLButtonElement | null = null;\n private _valueWrapper: HTMLDivElement | null = null;\n private _trackDisplay: HTMLDivElement | null = null;\n private _track: HTMLDivElement | null = null;\n private _observer: MutationObserver | null = null;\n private _skipTransition = false;\n\n override connectedCallback() {\n super.connectedCallback();\n requestAnimationFrame(() => this._setup());\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this._teardown();\n }\n\n override updated(changed: Map<string, unknown>) {\n if (!this._input) return;\n\n if (changed.has('min') || changed.has('max') || changed.has('step')) {\n this._syncConstraints();\n this._updateButtonStates();\n }\n }\n\n /** Decrease the value by one step. */\n decrement() {\n if (!this._input) return;\n const { min, step } = this._getConstraints();\n const newVal = Math.max(this._input.valueAsNumber - step, min);\n this._applyValue(newVal);\n }\n\n /** Increase the value by one step. */\n increment() {\n if (!this._input) return;\n const { max, step } = this._getConstraints();\n const newVal = Math.min(this._input.valueAsNumber + step, max);\n this._applyValue(newVal);\n }\n\n // --- Setup / Teardown ---\n\n private _setup() {\n this._input = this.querySelector('input[type=\"number\"]');\n if (!this._input) return;\n\n this._input.inputMode = 'numeric';\n\n // Wrap input in value container\n this._valueWrapper = document.createElement('div');\n this._valueWrapper.className = 'l-input-stepper-value';\n this._input.replaceWith(this._valueWrapper);\n this._valueWrapper.appendChild(this._input);\n\n // Inject track overlay\n if (this.withRoller) {\n this._buildTrack();\n }\n\n // Create buttons\n this._decrementBtn = this._createButton(this.decrementIcon, 'Decrease value');\n this._incrementBtn = this._createButton(this.incrementIcon, 'Increase value');\n\n this._valueWrapper.before(this._decrementBtn);\n this._valueWrapper.after(this._incrementBtn);\n\n // Events\n this._decrementBtn.addEventListener('click', this._onDecrement);\n this._incrementBtn.addEventListener('click', this._onIncrement);\n this._input.addEventListener('change', this._onInputChange);\n\n // Observe disabled attribute on input\n this._observer = new MutationObserver(() => this._updateButtonStates());\n this._observer.observe(this._input, { attributes: true, attributeFilter: ['disabled'] });\n\n this._syncConstraints();\n this._updateButtonStates();\n this._updateTrack();\n }\n\n private _teardown() {\n this._decrementBtn?.removeEventListener('click', this._onDecrement);\n this._incrementBtn?.removeEventListener('click', this._onIncrement);\n this._input?.removeEventListener('change', this._onInputChange);\n this._observer?.disconnect();\n\n // Restore input to direct child\n if (this._input && this._valueWrapper) {\n this._valueWrapper.replaceWith(this._input);\n }\n this._decrementBtn?.remove();\n this._incrementBtn?.remove();\n\n this._input = null;\n this._decrementBtn = null;\n this._incrementBtn = null;\n this._valueWrapper = null;\n this._trackDisplay = null;\n this._track = null;\n this._observer = null;\n }\n\n // --- DOM helpers ---\n\n private _createButton(icon: string, label: string): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.setAttribute('aria-label', label);\n btn.innerHTML = `<l-icon name=\"${icon}\"></l-icon>`;\n return btn;\n }\n\n private _buildTrack() {\n if (!this._valueWrapper) return;\n\n this._trackDisplay = document.createElement('div');\n this._trackDisplay.className = 'l-input-stepper-track-display';\n\n this._track = document.createElement('div');\n this._track.className = 'l-input-stepper-track';\n this._track.setAttribute('aria-hidden', 'true');\n\n this._rebuildTrackNumbers();\n this._trackDisplay.appendChild(this._track);\n this._valueWrapper.appendChild(this._trackDisplay);\n }\n\n private _rebuildTrackNumbers() {\n if (!this._track) return;\n\n const { min, max, step } = this._getConstraints();\n const effectiveMax = Number.isFinite(max) ? max : (this._input?.valueAsNumber ?? 0) + 100;\n\n this._track.innerHTML = '';\n for (let i = min; i <= effectiveMax; i += step) {\n const div = document.createElement('div');\n div.textContent = String(i);\n this._track.appendChild(div);\n }\n }\n\n // --- Constraints ---\n\n private _getConstraints() {\n const min = this.min ?? (Number(this._input?.getAttribute('min')) || 0);\n const max =\n this.max ??\n (this._input?.hasAttribute('max') ? Number(this._input.getAttribute('max')) : Infinity);\n const step = this.step ?? (Number(this._input?.getAttribute('step')) || 1);\n return { min, max, step };\n }\n\n private _syncConstraints() {\n if (!this._input) return;\n const { min, max, step } = this._getConstraints();\n\n this._input.min = String(min);\n if (Number.isFinite(max)) this._input.max = String(max);\n this._input.step = String(step);\n\n this._rebuildTrackNumbers();\n this._updateTrack();\n }\n\n // --- Value ---\n\n private _applyValue(val: number) {\n if (!this._input) return;\n this._input.value = String(val);\n this._updateButtonStates();\n this._updateTrack();\n this.emit('change', { detail: { value: val } });\n }\n\n // --- Track ---\n\n private _updateTrack() {\n if (!this._track) return;\n\n const { min, step } = this._getConstraints();\n const value = this._input?.valueAsNumber ?? min;\n const offset = (min - value) / step;\n\n this._track.style.translate = `0 calc(${offset} * var(--_button-size))`;\n\n if (this._skipTransition) {\n this._track.style.transition = 'none';\n void this._track.offsetHeight;\n this._track.style.transition = '';\n this._skipTransition = false;\n }\n }\n\n // --- Button states ---\n\n private _updateButtonStates() {\n if (!this._input || !this._decrementBtn || !this._incrementBtn) return;\n\n const { min, max } = this._getConstraints();\n const value = this._input.valueAsNumber;\n const disabled = this._input.disabled;\n\n this._decrementBtn.disabled = disabled || value <= min;\n this._incrementBtn.disabled = disabled || value >= max;\n }\n\n // --- Event handlers ---\n\n private _onDecrement = () => this.decrement();\n private _onIncrement = () => this.increment();\n\n private _onInputChange = () => {\n if (!this._input) return;\n\n const { min, max } = this._getConstraints();\n const clamped = Math.min(Math.max(this._input.valueAsNumber, min), max);\n this._input.value = String(clamped);\n\n this._skipTransition = true;\n this._updateButtonStates();\n this._updateTrack();\n this.emit('change', { detail: { value: clamped } });\n };\n}\n"],"mappings":"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"}
|
|
@@ -12,7 +12,7 @@ import { Placement } from '@floating-ui/dom';
|
|
|
12
12
|
*
|
|
13
13
|
* @cssproperty --background - Background color. Default: `Canvas`.
|
|
14
14
|
* @cssproperty --color - Text color. Default: inherited.
|
|
15
|
-
* @cssproperty --radius - Border radius. Default `8px`.
|
|
15
|
+
* @cssproperty --border-radius - Border radius. Default `8px`.
|
|
16
16
|
* @cssproperty --max-width - Maximum width. Default `320px`.
|
|
17
17
|
* @cssproperty --shadow - Box shadow.
|
|
18
18
|
* @cssproperty --arrow-size - Arrow size. Default `8px`.
|
|
@@ -33,6 +33,8 @@ export declare class LuxenPopover extends LuxenElement {
|
|
|
33
33
|
accessor open: boolean;
|
|
34
34
|
/** Hide the directional arrow. */
|
|
35
35
|
accessor withoutArrow: boolean;
|
|
36
|
+
/** Stretch the popover to the viewport width. Useful for mega menus. */
|
|
37
|
+
accessor fullWidth: boolean;
|
|
36
38
|
/** Space-separated list of trigger modes: `click`, `hover`, `focus`, `manual`. */
|
|
37
39
|
accessor trigger: string;
|
|
38
40
|
private _hasTrigger;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../../src/html/elements/popover/popover.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAQlD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,YAAa,SAAQ,YAAY;IAC5C,OAAgB,MAAM,4BAAwB;IAE9C,OAAO,CAAC,UAAU,CAAuB;IAEzC,OAAO,CAAC,SAAS,CAOd;IAEH,yDAAyD;IAEzD,QAAQ,CAAC,GAAG,SAAM;IAElB,8CAA8C;IAE9C,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAY;IAEzC,sDAAsD;IAEtD,QAAQ,CAAC,QAAQ,SAAK;IAEtB,6CAA6C;IAE7C,QAAQ,CAAC,IAAI,UAAS;IAEtB,kCAAkC;IAElC,QAAQ,CAAC,YAAY,UAAS;IAE9B,kFAAkF;IAElF,QAAQ,CAAC,OAAO,SAAW;IAE3B,OAAO,CAAC,WAAW;IAInB,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,KAAK,UAAU,GAErB;IAED,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,CAAC,YAAY;IAKX,iBAAiB;IAKjB,oBAAoB;IAKpB,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC;IAU9C,IAAI;IAIJ,IAAI;IAIJ,MAAM;YAIQ,iBAAiB;
|
|
1
|
+
{"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../../src/html/elements/popover/popover.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAQlD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,YAAa,SAAQ,YAAY;IAC5C,OAAgB,MAAM,4BAAwB;IAE9C,OAAO,CAAC,UAAU,CAAuB;IAEzC,OAAO,CAAC,SAAS,CAOd;IAEH,yDAAyD;IAEzD,QAAQ,CAAC,GAAG,SAAM;IAElB,8CAA8C;IAE9C,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAY;IAEzC,sDAAsD;IAEtD,QAAQ,CAAC,QAAQ,SAAK;IAEtB,6CAA6C;IAE7C,QAAQ,CAAC,IAAI,UAAS;IAEtB,kCAAkC;IAElC,QAAQ,CAAC,YAAY,UAAS;IAE9B,wEAAwE;IAExE,QAAQ,CAAC,SAAS,UAAS;IAE3B,kFAAkF;IAElF,QAAQ,CAAC,OAAO,SAAW;IAE3B,OAAO,CAAC,WAAW;IAInB,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,KAAK,UAAU,GAErB;IAED,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,CAAC,YAAY;IAKX,iBAAiB;IAKjB,oBAAoB;IAKpB,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC;IAU9C,IAAI;IAIJ,IAAI;IAIJ,MAAM;YAIQ,iBAAiB;IA8B/B,OAAO,CAAC,eAAe,CAIrB;IAEF,OAAO,CAAC,eAAe,CAGrB;IAEF,OAAO,CAAC,UAAU,CAEhB;IACF,OAAO,CAAC,WAAW,CAEjB;IACF,OAAO,CAAC,QAAQ,CAEd;IAEF,OAAO,CAAC,UAAU,CAKhB;IAEF,2DAA2D;IAC3D,OAAO,CAAC,SAAS,CAKf;IAEF,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,uBAAuB;IAOtB,MAAM;CAoBhB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{uniqueId as e}from"../../registry.js";import{c as t,i as n,n as r}from"../../chunks/lit.js";import{LuxenElement as i}from"../../shared/luxen-element.js";import{a,t as o}from"../../chunks/decorate.js";import s from"../../shared/styles/host.styles.js";import{PopoverController as c}from"../../shared/controllers/popover.js";var l=t(`:host{--background:var(--l-color-bg-surface,Canvas);--color:inherit;--radius:
|
|
1
|
+
import{uniqueId as e}from"../../registry.js";import{c as t,i as n,n as r}from"../../chunks/lit.js";import{LuxenElement as i}from"../../shared/luxen-element.js";import{a,t as o}from"../../chunks/decorate.js";import s from"../../shared/styles/host.styles.js";import{PopoverController as c}from"../../shared/controllers/popover.js";var l=t(`:host{--background:var(--l-color-bg-surface,Canvas);--color:inherit;--border-radius:6px;--max-width:320px;--shadow:0 4px 6px -1px #00000014, 0 2px 4px -2px #0000000f;--arrow-size:8px;--show-duration:.15s;--hide-duration:.15s;--_border-color:var(--l-color-border-overlay,var(--lightningcss-light,#e5e7eb)var(--lightningcss-dark,#374151));display:contents}[popover]{inset:unset;isolation:isolate;box-sizing:border-box;width:max-content;max-width:var(--max-width);border:1px solid var(--_border-color);border-radius:var(--border-radius);background:var(--background);color:var(--color);box-shadow:var(--shadow);font-size:.875rem;line-height:1.5;overflow:visible}:host([full-width]) [popover]{width:100vw;max-width:none}i{width:var(--arrow-size);height:var(--arrow-size);background:var(--background);z-index:-1;display:block;position:absolute;transform:rotate(45deg)}:host([data-placement^=top]) i{border-right:1px solid var(--_border-color);border-bottom:1px solid var(--_border-color)}:host([data-placement^=bottom]) i{border-top:1px solid var(--_border-color);border-left:1px solid var(--_border-color)}:host([data-placement^=left]) i{border-right:1px solid var(--_border-color);border-top:1px solid var(--_border-color)}:host([data-placement^=right]) i{border-left:1px solid var(--_border-color);border-bottom:1px solid var(--_border-color)}`),u=class extends i{constructor(...t){super(...t),this._popoverId=e(`popover`),this._floating=new c(this,{getTriggerElement:()=>this._trigger,getFloatingElement:()=>this._popoverEl,getArrowElement:()=>this._arrowEl,onPlacementChange:e=>{this.dataset.placement=e}}),this.#e=``,this.#t=`bottom`,this.#n=8,this.#r=!1,this.#i=!1,this.#a=!1,this.#o=`click`,this._onPointerEnter=()=>{this._hasTrigger(`hover`)&&(this._floating.cleanupSafePolygon(),this.show())},this._onPointerLeave=e=>{!this._hasTrigger(`hover`)||!this.open||this._floating.handlePointerLeave(e,()=>this.hide())},this._onFocusIn=()=>{this._hasTrigger(`focus`)&&this.show()},this._onFocusOut=()=>{this._hasTrigger(`focus`)&&this.hide()},this._onClick=()=>{this._hasTrigger(`click`)&&this.toggle()},this._onKeyDown=e=>{this.open&&e.key===`Escape`&&(e.stopPropagation(),this.hide())},this._onToggle=e=>{e.newState===`closed`&&this.open&&(this.open=!1)}}static{this.styles=[s,l]}#e;get for(){return this.#e}set for(e){this.#e=e}#t;get placement(){return this.#t}set placement(e){this.#t=e}#n;get distance(){return this.#n}set distance(e){this.#n=e}#r;get open(){return this.#r}set open(e){this.#r=e}#i;get withoutArrow(){return this.#i}set withoutArrow(e){this.#i=e}#a;get fullWidth(){return this.#a}set fullWidth(e){this.#a=e}#o;get trigger(){return this.#o}set trigger(e){this.#o=e}_hasTrigger(e){return this.trigger.split(` `).includes(e)}get _trigger(){return this.for?this.getRootNode().getElementById(this.for):null}get _popoverEl(){return this.shadowRoot.querySelector(`[popover]`)}get _arrowEl(){return this.withoutArrow?null:this.shadowRoot.querySelector(`i`)}_getDuration(e){let t=parseFloat(getComputedStyle(this).getPropertyValue(e));return Number.isNaN(t)?150:t}connectedCallback(){super.connectedCallback(),requestAnimationFrame(()=>this._addTriggerListeners())}disconnectedCallback(){super.disconnectedCallback(),this._removeTriggerListeners()}updated(e){e.has(`open`)&&this._handleOpenChange(),e.has(`for`)&&(this._removeTriggerListeners(e.get(`for`)),this._addTriggerListeners())}show(){this.open||=!0}hide(){this.open&&=!1}toggle(){this.open=!this.open}async _handleOpenChange(){let e=this._popoverEl;if(!e)return;let t={placement:this.placement,distance:this.distance,fullWidth:this.fullWidth};if(this.open){if(e.showPopover(),await this._floating.updatePosition(t),!this.open)return;await this._floating.animateShow(e,this._getDuration(`--show-duration`)),this._floating.startPositioning(t),this._trigger?.setAttribute(`aria-expanded`,`true`),this._trigger?.setAttribute(`aria-controls`,this._popoverId)}else this._floating.stopPositioning(),this._floating.cleanupSafePolygon(),this._trigger?.setAttribute(`aria-expanded`,`false`),this._trigger?.removeAttribute(`aria-controls`),await this._floating.animateHide(e,this._getDuration(`--hide-duration`)),e.matches(`:popover-open`)&&e.hidePopover()}_addTriggerListeners(){this._floating.addTriggerListeners({onPointerEnter:this._onPointerEnter,onPointerLeave:this._onPointerLeave,onFocusIn:this._onFocusIn,onFocusOut:this._onFocusOut,onClick:this._onClick,onKeyDown:this._onKeyDown})}_removeTriggerListeners(e){let t=e?this.getRootNode().getElementById(e):void 0;this._floating.removeTriggerListeners(t)}render(){return n`
|
|
2
2
|
<div
|
|
3
3
|
id=${this._popoverId}
|
|
4
4
|
popover="auto"
|
|
@@ -13,5 +13,5 @@ import{uniqueId as e}from"../../registry.js";import{c as t,i as n,n as r}from"..
|
|
|
13
13
|
`}
|
|
14
14
|
<slot></slot>
|
|
15
15
|
</div>
|
|
16
|
-
`}};o([a()],u.prototype,`for`,null),o([a()],u.prototype,`placement`,null),o([a({type:Number})],u.prototype,`distance`,null),o([a({type:Boolean,reflect:!0})],u.prototype,`open`,null),o([a({type:Boolean,reflect:!0,attribute:`without-arrow`})],u.prototype,`withoutArrow`,null),o([a()],u.prototype,`trigger`,null);export{u as LuxenPopover};
|
|
16
|
+
`}};o([a()],u.prototype,`for`,null),o([a()],u.prototype,`placement`,null),o([a({type:Number})],u.prototype,`distance`,null),o([a({type:Boolean,reflect:!0})],u.prototype,`open`,null),o([a({type:Boolean,reflect:!0,attribute:`without-arrow`})],u.prototype,`withoutArrow`,null),o([a({type:Boolean,reflect:!0,attribute:`full-width`})],u.prototype,`fullWidth`,null),o([a()],u.prototype,`trigger`,null);export{u as LuxenPopover};
|
|
17
17
|
//# sourceMappingURL=popover.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"popover.js","names":[],"sources":["../../../src/html/elements/popover/popover.css?inline","../../../src/html/elements/popover/popover.ts"],"sourcesContent":[":host {\n --background: var(--l-color-bg-surface, Canvas);\n --color: inherit;\n --radius: 8px;\n --max-width: 320px;\n --shadow: 0 4px 16px rgb(0 0 0 / 12%);\n --arrow-size: 8px;\n --show-duration: 150ms;\n --hide-duration: 150ms;\n\n --_border-color: var(--l-color-border, light-dark(#e5e7eb, #374151));\n\n display: contents;\n}\n\n[popover] {\n inset: unset;\n overflow: visible;\n isolation: isolate;\n box-sizing: border-box;\n width: max-content;\n max-width: var(--max-width);\n padding: 12px 16px;\n border: 1px solid var(--_border-color);\n border-radius: var(--radius);\n background: var(--background);\n color: var(--color);\n font-size: 0.875rem;\n line-height: 1.5;\n box-shadow: var(--shadow);\n}\n\ni {\n position: absolute;\n display: block;\n width: var(--arrow-size);\n height: var(--arrow-size);\n background: var(--background);\n transform: rotate(45deg);\n z-index: -1;\n}\n\n:host([data-placement^='top']) i {\n border-right: 1px solid var(--_border-color);\n border-bottom: 1px solid var(--_border-color);\n}\n\n:host([data-placement^='bottom']) i {\n border-top: 1px solid var(--_border-color);\n border-left: 1px solid var(--_border-color);\n}\n\n:host([data-placement^='left']) i {\n border-right: 1px solid var(--_border-color);\n border-top: 1px solid var(--_border-color);\n}\n\n:host([data-placement^='right']) i {\n border-left: 1px solid var(--_border-color);\n border-bottom: 1px solid var(--_border-color);\n}\n","import { html, nothing, unsafeCSS, type PropertyValues } from 'lit';\nimport { LuxenElement } from '../../shared/luxen-element';\nimport { property } from 'lit/decorators.js';\nimport type { Placement } from '@floating-ui/dom';\nimport { PopoverController } from '../../shared/controllers/popover';\nimport { uniqueId } from '../../registry';\nimport hostStyles from '../../shared/styles/host.styles';\nimport rawStyles from './popover.css?inline';\n\nconst styles = unsafeCSS(rawStyles);\n\n/**\n * @summary A popover that displays interactive content anchored to a trigger.\n * @customElement l-popover\n *\n * @slot - Popover content.\n *\n * @csspart body - The popover container.\n * @csspart arrow - The directional arrow element.\n *\n * @cssproperty --background - Background color. Default: `Canvas`.\n * @cssproperty --color - Text color. Default: inherited.\n * @cssproperty --radius - Border radius. Default `8px`.\n * @cssproperty --max-width - Maximum width. Default `320px`.\n * @cssproperty --shadow - Box shadow.\n * @cssproperty --arrow-size - Arrow size. Default `8px`.\n * @cssproperty --show-duration - Show animation duration. Default `150ms`.\n * @cssproperty --hide-duration - Hide animation duration. Default `150ms`.\n */\nexport class LuxenPopover extends LuxenElement {\n static override styles = [hostStyles, styles];\n\n private _popoverId = uniqueId('popover');\n\n private _floating = new PopoverController(this, {\n getTriggerElement: () => this._trigger,\n getFloatingElement: () => this._popoverEl,\n getArrowElement: () => this._arrowEl,\n onPlacementChange: (p) => {\n this.dataset.placement = p;\n },\n });\n\n /** The HTML id of the element triggering the popover. */\n @property()\n accessor for = '';\n\n /** The preferred placement of the popover. */\n @property()\n accessor placement: Placement = 'bottom';\n\n /** The distance in pixels from the target element. */\n @property({ type: Number })\n accessor distance = 8;\n\n /** Whether or not the popover is visible. */\n @property({ type: Boolean, reflect: true })\n accessor open = false;\n\n /** Hide the directional arrow. */\n @property({ type: Boolean, reflect: true, attribute: 'without-arrow' })\n accessor withoutArrow = false;\n\n /** Space-separated list of trigger modes: `click`, `hover`, `focus`, `manual`. */\n @property()\n accessor trigger = 'click';\n\n private _hasTrigger(type: string) {\n return this.trigger.split(' ').includes(type);\n }\n\n private get _trigger(): HTMLElement | null {\n return this.for ? (this.getRootNode() as Document | ShadowRoot).getElementById(this.for) : null;\n }\n\n private get _popoverEl(): HTMLElement {\n return this.shadowRoot!.querySelector('[popover]')!;\n }\n\n private get _arrowEl(): HTMLElement | null {\n return this.withoutArrow ? null : this.shadowRoot!.querySelector('i');\n }\n\n private _getDuration(prop: '--show-duration' | '--hide-duration'): number {\n const parsed = parseFloat(getComputedStyle(this).getPropertyValue(prop));\n return Number.isNaN(parsed) ? 150 : parsed;\n }\n\n override connectedCallback() {\n super.connectedCallback();\n requestAnimationFrame(() => this._addTriggerListeners());\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this._removeTriggerListeners();\n }\n\n override updated(changed: PropertyValues<this>) {\n if (changed.has('open')) {\n this._handleOpenChange();\n }\n if (changed.has('for')) {\n this._removeTriggerListeners(changed.get('for') as string);\n this._addTriggerListeners();\n }\n }\n\n show() {\n if (!this.open) this.open = true;\n }\n\n hide() {\n if (this.open) this.open = false;\n }\n\n toggle() {\n this.open = !this.open;\n }\n\n private async _handleOpenChange() {\n const popover = this._popoverEl;\n if (!popover) return;\n\n const posOpts = { placement: this.placement, distance: this.distance };\n\n if (this.open) {\n popover.showPopover();\n await this._floating.updatePosition(posOpts);\n if (!this.open) return;\n await this._floating.animateShow(popover, this._getDuration('--show-duration'));\n this._floating.startPositioning(posOpts);\n this._trigger?.setAttribute('aria-expanded', 'true');\n this._trigger?.setAttribute('aria-controls', this._popoverId);\n } else {\n this._floating.stopPositioning();\n this._floating.cleanupSafePolygon();\n this._trigger?.setAttribute('aria-expanded', 'false');\n this._trigger?.removeAttribute('aria-controls');\n await this._floating.animateHide(popover, this._getDuration('--hide-duration'));\n if (popover.matches(':popover-open')) popover.hidePopover();\n }\n }\n\n // --- Trigger event handlers ---\n\n private _onPointerEnter = () => {\n if (!this._hasTrigger('hover')) return;\n this._floating.cleanupSafePolygon();\n this.show();\n };\n\n private _onPointerLeave = (e: PointerEvent) => {\n if (!this._hasTrigger('hover') || !this.open) return;\n this._floating.handlePointerLeave(e, () => this.hide());\n };\n\n private _onFocusIn = () => {\n if (this._hasTrigger('focus')) this.show();\n };\n private _onFocusOut = () => {\n if (this._hasTrigger('focus')) this.hide();\n };\n private _onClick = () => {\n if (this._hasTrigger('click')) this.toggle();\n };\n\n private _onKeyDown = (e: KeyboardEvent) => {\n if (this.open && e.key === 'Escape') {\n e.stopPropagation();\n this.hide();\n }\n };\n\n /** Sync `open` when popover=\"auto\" light-dismiss fires. */\n private _onToggle = (e: Event) => {\n const toggleEvent = e as ToggleEvent;\n if (toggleEvent.newState === 'closed' && this.open) {\n this.open = false;\n }\n };\n\n private _addTriggerListeners() {\n this._floating.addTriggerListeners({\n onPointerEnter: this._onPointerEnter,\n onPointerLeave: this._onPointerLeave,\n onFocusIn: this._onFocusIn,\n onFocusOut: this._onFocusOut,\n onClick: this._onClick,\n onKeyDown: this._onKeyDown,\n });\n }\n\n private _removeTriggerListeners(forId?: string) {\n const trigger = forId\n ? (this.getRootNode() as Document | ShadowRoot).getElementById(forId)\n : undefined;\n this._floating.removeTriggerListeners(trigger);\n }\n\n override render() {\n return html`\n <div\n id=${this._popoverId}\n popover=\"auto\"\n part=\"body\"\n @toggle=${this._onToggle}\n >\n ${this.withoutArrow\n ? nothing\n : html`\n <i\n part=\"arrow\"\n role=\"presentation\"\n ></i>\n `}\n <slot></slot>\n </div>\n `;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"popover.js","names":[],"sources":["../../../src/html/elements/popover/popover.css?inline","../../../src/html/elements/popover/popover.ts"],"sourcesContent":[":host {\n --background: var(--l-color-bg-surface, Canvas);\n --color: inherit;\n --border-radius: 6px;\n --max-width: 320px;\n --shadow: 0 4px 6px -1px rgb(0 0 0 / 8%), 0 2px 4px -2px rgb(0 0 0 / 6%);\n --arrow-size: 8px;\n --show-duration: 150ms;\n --hide-duration: 150ms;\n\n --_border-color: var(--l-color-border-overlay, light-dark(#e5e7eb, #374151));\n\n display: contents;\n}\n\n[popover] {\n inset: unset;\n overflow: visible;\n isolation: isolate;\n box-sizing: border-box;\n width: max-content;\n max-width: var(--max-width);\n border: 1px solid var(--_border-color);\n border-radius: var(--border-radius);\n background: var(--background);\n color: var(--color);\n font-size: 0.875rem;\n line-height: 1.5;\n box-shadow: var(--shadow);\n}\n\n:host([full-width]) [popover] {\n width: 100vw;\n max-width: none;\n}\n\ni {\n position: absolute;\n display: block;\n width: var(--arrow-size);\n height: var(--arrow-size);\n background: var(--background);\n transform: rotate(45deg);\n z-index: -1;\n}\n\n:host([data-placement^='top']) i {\n border-right: 1px solid var(--_border-color);\n border-bottom: 1px solid var(--_border-color);\n}\n\n:host([data-placement^='bottom']) i {\n border-top: 1px solid var(--_border-color);\n border-left: 1px solid var(--_border-color);\n}\n\n:host([data-placement^='left']) i {\n border-right: 1px solid var(--_border-color);\n border-top: 1px solid var(--_border-color);\n}\n\n:host([data-placement^='right']) i {\n border-left: 1px solid var(--_border-color);\n border-bottom: 1px solid var(--_border-color);\n}\n","import { html, nothing, unsafeCSS, type PropertyValues } from 'lit';\nimport { LuxenElement } from '../../shared/luxen-element';\nimport { property } from 'lit/decorators.js';\nimport type { Placement } from '@floating-ui/dom';\nimport { PopoverController } from '../../shared/controllers/popover';\nimport { uniqueId } from '../../registry';\nimport hostStyles from '../../shared/styles/host.styles';\nimport rawStyles from './popover.css?inline';\n\nconst styles = unsafeCSS(rawStyles);\n\n/**\n * @summary A popover that displays interactive content anchored to a trigger.\n * @customElement l-popover\n *\n * @slot - Popover content.\n *\n * @csspart body - The popover container.\n * @csspart arrow - The directional arrow element.\n *\n * @cssproperty --background - Background color. Default: `Canvas`.\n * @cssproperty --color - Text color. Default: inherited.\n * @cssproperty --border-radius - Border radius. Default `8px`.\n * @cssproperty --max-width - Maximum width. Default `320px`.\n * @cssproperty --shadow - Box shadow.\n * @cssproperty --arrow-size - Arrow size. Default `8px`.\n * @cssproperty --show-duration - Show animation duration. Default `150ms`.\n * @cssproperty --hide-duration - Hide animation duration. Default `150ms`.\n */\nexport class LuxenPopover extends LuxenElement {\n static override styles = [hostStyles, styles];\n\n private _popoverId = uniqueId('popover');\n\n private _floating = new PopoverController(this, {\n getTriggerElement: () => this._trigger,\n getFloatingElement: () => this._popoverEl,\n getArrowElement: () => this._arrowEl,\n onPlacementChange: (p) => {\n this.dataset.placement = p;\n },\n });\n\n /** The HTML id of the element triggering the popover. */\n @property()\n accessor for = '';\n\n /** The preferred placement of the popover. */\n @property()\n accessor placement: Placement = 'bottom';\n\n /** The distance in pixels from the target element. */\n @property({ type: Number })\n accessor distance = 8;\n\n /** Whether or not the popover is visible. */\n @property({ type: Boolean, reflect: true })\n accessor open = false;\n\n /** Hide the directional arrow. */\n @property({ type: Boolean, reflect: true, attribute: 'without-arrow' })\n accessor withoutArrow = false;\n\n /** Stretch the popover to the viewport width. Useful for mega menus. */\n @property({ type: Boolean, reflect: true, attribute: 'full-width' })\n accessor fullWidth = false;\n\n /** Space-separated list of trigger modes: `click`, `hover`, `focus`, `manual`. */\n @property()\n accessor trigger = 'click';\n\n private _hasTrigger(type: string) {\n return this.trigger.split(' ').includes(type);\n }\n\n private get _trigger(): HTMLElement | null {\n return this.for ? (this.getRootNode() as Document | ShadowRoot).getElementById(this.for) : null;\n }\n\n private get _popoverEl(): HTMLElement {\n return this.shadowRoot!.querySelector('[popover]')!;\n }\n\n private get _arrowEl(): HTMLElement | null {\n return this.withoutArrow ? null : this.shadowRoot!.querySelector('i');\n }\n\n private _getDuration(prop: '--show-duration' | '--hide-duration'): number {\n const parsed = parseFloat(getComputedStyle(this).getPropertyValue(prop));\n return Number.isNaN(parsed) ? 150 : parsed;\n }\n\n override connectedCallback() {\n super.connectedCallback();\n requestAnimationFrame(() => this._addTriggerListeners());\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this._removeTriggerListeners();\n }\n\n override updated(changed: PropertyValues<this>) {\n if (changed.has('open')) {\n this._handleOpenChange();\n }\n if (changed.has('for')) {\n this._removeTriggerListeners(changed.get('for') as string);\n this._addTriggerListeners();\n }\n }\n\n show() {\n if (!this.open) this.open = true;\n }\n\n hide() {\n if (this.open) this.open = false;\n }\n\n toggle() {\n this.open = !this.open;\n }\n\n private async _handleOpenChange() {\n const popover = this._popoverEl;\n if (!popover) return;\n\n const posOpts = {\n placement: this.placement,\n distance: this.distance,\n fullWidth: this.fullWidth,\n };\n\n if (this.open) {\n popover.showPopover();\n await this._floating.updatePosition(posOpts);\n if (!this.open) return;\n await this._floating.animateShow(popover, this._getDuration('--show-duration'));\n this._floating.startPositioning(posOpts);\n this._trigger?.setAttribute('aria-expanded', 'true');\n this._trigger?.setAttribute('aria-controls', this._popoverId);\n } else {\n this._floating.stopPositioning();\n this._floating.cleanupSafePolygon();\n this._trigger?.setAttribute('aria-expanded', 'false');\n this._trigger?.removeAttribute('aria-controls');\n await this._floating.animateHide(popover, this._getDuration('--hide-duration'));\n if (popover.matches(':popover-open')) popover.hidePopover();\n }\n }\n\n // --- Trigger event handlers ---\n\n private _onPointerEnter = () => {\n if (!this._hasTrigger('hover')) return;\n this._floating.cleanupSafePolygon();\n this.show();\n };\n\n private _onPointerLeave = (e: PointerEvent) => {\n if (!this._hasTrigger('hover') || !this.open) return;\n this._floating.handlePointerLeave(e, () => this.hide());\n };\n\n private _onFocusIn = () => {\n if (this._hasTrigger('focus')) this.show();\n };\n private _onFocusOut = () => {\n if (this._hasTrigger('focus')) this.hide();\n };\n private _onClick = () => {\n if (this._hasTrigger('click')) this.toggle();\n };\n\n private _onKeyDown = (e: KeyboardEvent) => {\n if (this.open && e.key === 'Escape') {\n e.stopPropagation();\n this.hide();\n }\n };\n\n /** Sync `open` when popover=\"auto\" light-dismiss fires. */\n private _onToggle = (e: Event) => {\n const toggleEvent = e as ToggleEvent;\n if (toggleEvent.newState === 'closed' && this.open) {\n this.open = false;\n }\n };\n\n private _addTriggerListeners() {\n this._floating.addTriggerListeners({\n onPointerEnter: this._onPointerEnter,\n onPointerLeave: this._onPointerLeave,\n onFocusIn: this._onFocusIn,\n onFocusOut: this._onFocusOut,\n onClick: this._onClick,\n onKeyDown: this._onKeyDown,\n });\n }\n\n private _removeTriggerListeners(forId?: string) {\n const trigger = forId\n ? (this.getRootNode() as Document | ShadowRoot).getElementById(forId)\n : undefined;\n this._floating.removeTriggerListeners(trigger);\n }\n\n override render() {\n return html`\n <div\n id=${this._popoverId}\n popover=\"auto\"\n part=\"body\"\n @toggle=${this._onToggle}\n >\n ${this.withoutArrow\n ? nothing\n : html`\n <i\n part=\"arrow\"\n role=\"presentation\"\n ></i>\n `}\n <slot></slot>\n </div>\n `;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../../src/html/shared/controllers/popover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,KAAK,CAAC;AACtE,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,kBAAkB,CAAC;AAoN1B,MAAM,WAAW,uBAAuB;IACtC,iBAAiB,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;IAC5C,kBAAkB,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;IAC7C,eAAe,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../../src/html/shared/controllers/popover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,KAAK,CAAC;AACtE,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,kBAAkB,CAAC;AAoN1B,MAAM,WAAW,uBAAuB;IACtC,iBAAiB,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;IAC5C,kBAAkB,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;IAC7C,eAAe,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,KAAK,eAAe,GAAG;IACrB,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;IAC3C,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;IAC3C,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACpC,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACrC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;CACxC,CAAC;AAEF,qBAAa,iBAAkB,YAAW,kBAAkB;IAC1D,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,kBAAkB,CAAC,CAAa;IACxC,OAAO,CAAC,mBAAmB,CAAC,CAAa;IACzC,OAAO,CAAC,SAAS,CAAC,CAAkB;IACpC,OAAO,CAAC,eAAe,CAAC,CAAqB;IAC7C,OAAO,CAAC,iBAAiB,CAAM;gBAEnB,IAAI,EAAE,sBAAsB,GAAG,WAAW,EAAE,MAAM,EAAE,uBAAuB;IAMvF,aAAa;IAEb,gBAAgB;IAMhB,IAAI,gBAAgB,WAEnB;IAIK,cAAc,CAAC,OAAO,EAAE,eAAe;IA0C7C,gBAAgB,CAAC,OAAO,EAAE,eAAe;IASzC,eAAe;IAOf,kBAAkB,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,IAAI;IAiDtD,kBAAkB;IAOlB,mBAAmB,CAAC,QAAQ,EAAE,eAAe;IAoB7C,sBAAsB,CAAC,eAAe,CAAC,EAAE,WAAW,GAAG,IAAI;IAyBrD,WAAW,CAAC,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,QAAQ,EAAE;IAYrE,WAAW,CAAC,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,QAAQ,EAAE;CAW5E"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=Math.min,t=Math.max,n=Math.round,r=Math.floor,i=e=>({x:e,y:e}),a={left:`right`,right:`left`,bottom:`top`,top:`bottom`};function o(n,r,i){return t(n,e(r,i))}function s(e,t){return typeof e==`function`?e(t):e}function c(e){return e.split(`-`)[0]}function l(e){return e.split(`-`)[1]}function u(e){return e===`x`?`y`:`x`}function d(e){return e===`y`?`height`:`width`}function f(e){let t=e[0];return t===`t`||t===`b`?`y`:`x`}function p(e){return u(f(e))}function m(e,t,n){n===void 0&&(n=!1);let r=l(e),i=p(e),a=d(i),o=i===`x`?r===(n?`end`:`start`)?`right`:`left`:r===`start`?`bottom`:`top`;return t.reference[a]>t.floating[a]&&(o=C(o)),[o,C(o)]}function h(e){let t=C(e);return[g(e),t,g(t)]}function g(e){return e.includes(`start`)?e.replace(`start`,`end`):e.replace(`end`,`start`)}var _=[`left`,`right`],v=[`right`,`left`],y=[`top`,`bottom`],b=[`bottom`,`top`];function x(e,t,n){switch(e){case`top`:case`bottom`:return n?t?v:_:t?_:v;case`left`:case`right`:return t?y:b;default:return[]}}function S(e,t,n,r){let i=l(e),a=x(c(e),n===`start`,r);return i&&(a=a.map(e=>e+`-`+i),t&&(a=a.concat(a.map(g)))),a}function C(e){let t=c(e);return a[t]+e.slice(t.length)}function w(e){return{top:0,right:0,bottom:0,left:0,...e}}function ee(e){return typeof e==`number`?{top:e,right:e,bottom:e,left:e}:w(e)}function T(e){let{x:t,y:n,width:r,height:i}=e;return{width:r,height:i,top:n,left:t,right:t+r,bottom:n+i,x:t,y:n}}function E(e,t,n){let{reference:r,floating:i}=e,a=f(t),o=p(t),s=d(o),u=c(t),m=a===`y`,h=r.x+r.width/2-i.width/2,g=r.y+r.height/2-i.height/2,_=r[s]/2-i[s]/2,v;switch(u){case`top`:v={x:h,y:r.y-i.height};break;case`bottom`:v={x:h,y:r.y+r.height};break;case`right`:v={x:r.x+r.width,y:g};break;case`left`:v={x:r.x-i.width,y:g};break;default:v={x:r.x,y:r.y}}switch(l(t)){case`start`:v[o]-=_*(n&&m?-1:1);break;case`end`:v[o]+=_*(n&&m?-1:1);break}return v}async function D(e,t){t===void 0&&(t={});let{x:n,y:r,platform:i,rects:a,elements:o,strategy:c}=e,{boundary:l=`clippingAncestors`,rootBoundary:u=`viewport`,elementContext:d=`floating`,altBoundary:f=!1,padding:p=0}=s(t,e),m=ee(p),h=o[f?d===`floating`?`reference`:`floating`:d],g=T(await i.getClippingRect({element:await(i.isElement==null?void 0:i.isElement(h))??!0?h:h.contextElement||await(i.getDocumentElement==null?void 0:i.getDocumentElement(o.floating)),boundary:l,rootBoundary:u,strategy:c})),_=d===`floating`?{x:n,y:r,width:a.floating.width,height:a.floating.height}:a.reference,v=await(i.getOffsetParent==null?void 0:i.getOffsetParent(o.floating)),y=await(i.isElement==null?void 0:i.isElement(v))&&await(i.getScale==null?void 0:i.getScale(v))||{x:1,y:1},b=T(i.convertOffsetParentRelativeRectToViewportRelativeRect?await i.convertOffsetParentRelativeRectToViewportRelativeRect({elements:o,rect:_,offsetParent:v,strategy:c}):_);return{top:(g.top-b.top+m.top)/y.y,bottom:(b.bottom-g.bottom+m.bottom)/y.y,left:(g.left-b.left+m.left)/y.x,right:(b.right-g.right+m.right)/y.x}}var O=50,k=async(e,t,n)=>{let{placement:r=`bottom`,strategy:i=`absolute`,middleware:a=[],platform:o}=n,s=o.detectOverflow?o:{...o,detectOverflow:D},c=await(o.isRTL==null?void 0:o.isRTL(t)),l=await o.getElementRects({reference:e,floating:t,strategy:i}),{x:u,y:d}=E(l,r,c),f=r,p=0,m={};for(let n=0;n<a.length;n++){let h=a[n];if(!h)continue;let{name:g,fn:_}=h,{x:v,y,data:b,reset:x}=await _({x:u,y:d,initialPlacement:r,placement:f,strategy:i,middlewareData:m,rects:l,platform:s,elements:{reference:e,floating:t}});u=v??u,d=y??d,m[g]={...m[g],...b},x&&p<O&&(p++,typeof x==`object`&&(x.placement&&(f=x.placement),x.rects&&(l=x.rects===!0?await o.getElementRects({reference:e,floating:t,strategy:i}):x.rects),{x:u,y:d}=E(l,f,c)),n=-1)}return{x:u,y:d,placement:f,strategy:i,middlewareData:m}},A=t=>({name:`arrow`,options:t,async fn(n){let{x:r,y:i,placement:a,rects:c,platform:u,elements:f,middlewareData:m}=n,{element:h,padding:g=0}=s(t,n)||{};if(h==null)return{};let _=ee(g),v={x:r,y:i},y=p(a),b=d(y),x=await u.getDimensions(h),S=y===`y`,C=S?`top`:`left`,w=S?`bottom`:`right`,T=S?`clientHeight`:`clientWidth`,E=c.reference[b]+c.reference[y]-v[y]-c.floating[b],D=v[y]-c.reference[y],O=await(u.getOffsetParent==null?void 0:u.getOffsetParent(h)),k=O?O[T]:0;(!k||!await(u.isElement==null?void 0:u.isElement(O)))&&(k=f.floating[T]||c.floating[b]);let A=E/2-D/2,j=k/2-x[b]/2-1,M=e(_[C],j),N=e(_[w],j),P=M,te=k-x[b]-N,F=k/2-x[b]/2+A,I=o(P,F,te),L=!m.arrow&&l(a)!=null&&F!==I&&c.reference[b]/2-(F<P?M:N)-x[b]/2<0,R=L?F<P?F-P:F-te:0;return{[y]:v[y]+R,data:{[y]:I,centerOffset:F-I-R,...L&&{alignmentOffset:R}},reset:L}}}),j=function(e){return e===void 0&&(e={}),{name:`flip`,options:e,async fn(t){var n;let{placement:r,middlewareData:i,rects:a,initialPlacement:o,platform:l,elements:u}=t,{mainAxis:d=!0,crossAxis:p=!0,fallbackPlacements:g,fallbackStrategy:_=`bestFit`,fallbackAxisSideDirection:v=`none`,flipAlignment:y=!0,...b}=s(e,t);if((n=i.arrow)!=null&&n.alignmentOffset)return{};let x=c(r),w=f(o),ee=c(o)===o,T=await(l.isRTL==null?void 0:l.isRTL(u.floating)),E=g||(ee||!y?[C(o)]:h(o)),D=v!==`none`;!g&&D&&E.push(...S(o,y,v,T));let O=[o,...E],k=await l.detectOverflow(t,b),A=[],j=i.flip?.overflows||[];if(d&&A.push(k[x]),p){let e=m(r,a,T);A.push(k[e[0]],k[e[1]])}if(j=[...j,{placement:r,overflows:A}],!A.every(e=>e<=0)){let e=(i.flip?.index||0)+1,t=O[e];if(t&&(!(p===`alignment`&&w!==f(t))||j.every(e=>f(e.placement)===w?e.overflows[0]>0:!0)))return{data:{index:e,overflows:j},reset:{placement:t}};let n=j.filter(e=>e.overflows[0]<=0).sort((e,t)=>e.overflows[1]-t.overflows[1])[0]?.placement;if(!n)switch(_){case`bestFit`:{let e=j.filter(e=>{if(D){let t=f(e.placement);return t===w||t===`y`}return!0}).map(e=>[e.placement,e.overflows.filter(e=>e>0).reduce((e,t)=>e+t,0)]).sort((e,t)=>e[1]-t[1])[0]?.[0];e&&(n=e);break}case`initialPlacement`:n=o;break}if(r!==n)return{reset:{placement:n}}}return{}}}},M=new Set([`left`,`top`]);async function N(e,t){let{placement:n,platform:r,elements:i}=e,a=await(r.isRTL==null?void 0:r.isRTL(i.floating)),o=c(n),u=l(n),d=f(n)===`y`,p=M.has(o)?-1:1,m=a&&d?-1:1,h=s(t,e),{mainAxis:g,crossAxis:_,alignmentAxis:v}=typeof h==`number`?{mainAxis:h,crossAxis:0,alignmentAxis:null}:{mainAxis:h.mainAxis||0,crossAxis:h.crossAxis||0,alignmentAxis:h.alignmentAxis};return u&&typeof v==`number`&&(_=u===`end`?v*-1:v),d?{x:_*m,y:g*p}:{x:g*p,y:_*m}}var P=function(e){return e===void 0&&(e=0),{name:`offset`,options:e,async fn(t){var n;let{x:r,y:i,placement:a,middlewareData:o}=t,s=await N(t,e);return a===o.offset?.placement&&(n=o.arrow)!=null&&n.alignmentOffset?{}:{x:r+s.x,y:i+s.y,data:{...s,placement:a}}}}},te=function(e){return e===void 0&&(e={}),{name:`shift`,options:e,async fn(t){let{x:n,y:r,placement:i,platform:a}=t,{mainAxis:l=!0,crossAxis:d=!1,limiter:p={fn:e=>{let{x:t,y:n}=e;return{x:t,y:n}}},...m}=s(e,t),h={x:n,y:r},g=await a.detectOverflow(t,m),_=f(c(i)),v=u(_),y=h[v],b=h[_];if(l){let e=v===`y`?`top`:`left`,t=v===`y`?`bottom`:`right`,n=y+g[e],r=y-g[t];y=o(n,y,r)}if(d){let e=_===`y`?`top`:`left`,t=_===`y`?`bottom`:`right`,n=b+g[e],r=b-g[t];b=o(n,b,r)}let x=p.fn({...t,[v]:y,[_]:b});return{...x,data:{x:x.x-n,y:x.y-r,enabled:{[v]:l,[_]:d}}}}}};function F(){return typeof window<`u`}function I(e){return ne(e)?(e.nodeName||``).toLowerCase():`#document`}function L(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function R(e){return((ne(e)?e.ownerDocument:e.document)||window.document)?.documentElement}function ne(e){return F()?e instanceof Node||e instanceof L(e).Node:!1}function z(e){return F()?e instanceof Element||e instanceof L(e).Element:!1}function B(e){return F()?e instanceof HTMLElement||e instanceof L(e).HTMLElement:!1}function re(e){return!F()||typeof ShadowRoot>`u`?!1:e instanceof ShadowRoot||e instanceof L(e).ShadowRoot}function V(e){let{overflow:t,overflowX:n,overflowY:r,display:i}=q(e);return/auto|scroll|overlay|hidden|clip/.test(t+r+n)&&i!==`inline`&&i!==`contents`}function ie(e){return/^(table|td|th)$/.test(I(e))}function H(e){try{if(e.matches(`:popover-open`))return!0}catch{}try{return e.matches(`:modal`)}catch{return!1}}var ae=/transform|translate|scale|rotate|perspective|filter/,oe=/paint|layout|strict|content/,U=e=>!!e&&e!==`none`,se;function W(e){let t=z(e)?q(e):e;return U(t.transform)||U(t.translate)||U(t.scale)||U(t.rotate)||U(t.perspective)||!G()&&(U(t.backdropFilter)||U(t.filter))||ae.test(t.willChange||``)||oe.test(t.contain||``)}function ce(e){let t=Y(e);for(;B(t)&&!K(t);){if(W(t))return t;if(H(t))return null;t=Y(t)}return null}function G(){return se??=typeof CSS<`u`&&CSS.supports&&CSS.supports(`-webkit-backdrop-filter`,`none`),se}function K(e){return/^(html|body|#document)$/.test(I(e))}function q(e){return L(e).getComputedStyle(e)}function J(e){return z(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function Y(e){if(I(e)===`html`)return e;let t=e.assignedSlot||e.parentNode||re(e)&&e.host||R(e);return re(t)?t.host:t}function le(e){let t=Y(e);return K(t)?e.ownerDocument?e.ownerDocument.body:e.body:B(t)&&V(t)?t:le(t)}function X(e,t,n){t===void 0&&(t=[]),n===void 0&&(n=!0);let r=le(e),i=r===e.ownerDocument?.body,a=L(r);if(i){let e=ue(a);return t.concat(a,a.visualViewport||[],V(r)?r:[],e&&n?X(e):[])}else return t.concat(r,X(r,[],n))}function ue(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function de(e){let t=q(e),r=parseFloat(t.width)||0,i=parseFloat(t.height)||0,a=B(e),o=a?e.offsetWidth:r,s=a?e.offsetHeight:i,c=n(r)!==o||n(i)!==s;return c&&(r=o,i=s),{width:r,height:i,$:c}}function fe(e){return z(e)?e:e.contextElement}function Z(e){let t=fe(e);if(!B(t))return i(1);let r=t.getBoundingClientRect(),{width:a,height:o,$:s}=de(t),c=(s?n(r.width):r.width)/a,l=(s?n(r.height):r.height)/o;return(!c||!Number.isFinite(c))&&(c=1),(!l||!Number.isFinite(l))&&(l=1),{x:c,y:l}}var pe=i(0);function me(e){let t=L(e);return!G()||!t.visualViewport?pe:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function he(e,t,n){return t===void 0&&(t=!1),!n||t&&n!==L(e)?!1:t}function Q(e,t,n,r){t===void 0&&(t=!1),n===void 0&&(n=!1);let a=e.getBoundingClientRect(),o=fe(e),s=i(1);t&&(r?z(r)&&(s=Z(r)):s=Z(e));let c=he(o,n,r)?me(o):i(0),l=(a.left+c.x)/s.x,u=(a.top+c.y)/s.y,d=a.width/s.x,f=a.height/s.y;if(o){let e=L(o),t=r&&z(r)?L(r):r,n=e,i=ue(n);for(;i&&r&&t!==n;){let e=Z(i),t=i.getBoundingClientRect(),r=q(i),a=t.left+(i.clientLeft+parseFloat(r.paddingLeft))*e.x,o=t.top+(i.clientTop+parseFloat(r.paddingTop))*e.y;l*=e.x,u*=e.y,d*=e.x,f*=e.y,l+=a,u+=o,n=L(i),i=ue(n)}}return T({width:d,height:f,x:l,y:u})}function $(e,t){let n=J(e).scrollLeft;return t?t.left+n:Q(R(e)).left+n}function ge(e,t){let n=e.getBoundingClientRect();return{x:n.left+t.scrollLeft-$(e,n),y:n.top+t.scrollTop}}function _e(e){let{elements:t,rect:n,offsetParent:r,strategy:a}=e,o=a===`fixed`,s=R(r),c=t?H(t.floating):!1;if(r===s||c&&o)return n;let l={scrollLeft:0,scrollTop:0},u=i(1),d=i(0),f=B(r);if((f||!f&&!o)&&((I(r)!==`body`||V(s))&&(l=J(r)),f)){let e=Q(r);u=Z(r),d.x=e.x+r.clientLeft,d.y=e.y+r.clientTop}let p=s&&!f&&!o?ge(s,l):i(0);return{width:n.width*u.x,height:n.height*u.y,x:n.x*u.x-l.scrollLeft*u.x+d.x+p.x,y:n.y*u.y-l.scrollTop*u.y+d.y+p.y}}function ve(e){return Array.from(e.getClientRects())}function ye(e){let n=R(e),r=J(e),i=e.ownerDocument.body,a=t(n.scrollWidth,n.clientWidth,i.scrollWidth,i.clientWidth),o=t(n.scrollHeight,n.clientHeight,i.scrollHeight,i.clientHeight),s=-r.scrollLeft+$(e),c=-r.scrollTop;return q(i).direction===`rtl`&&(s+=t(n.clientWidth,i.clientWidth)-a),{width:a,height:o,x:s,y:c}}var be=25;function xe(e,t){let n=L(e),r=R(e),i=n.visualViewport,a=r.clientWidth,o=r.clientHeight,s=0,c=0;if(i){a=i.width,o=i.height;let e=G();(!e||e&&t===`fixed`)&&(s=i.offsetLeft,c=i.offsetTop)}let l=$(r);if(l<=0){let e=r.ownerDocument,t=e.body,n=getComputedStyle(t),i=e.compatMode===`CSS1Compat`&&parseFloat(n.marginLeft)+parseFloat(n.marginRight)||0,o=Math.abs(r.clientWidth-t.clientWidth-i);o<=be&&(a-=o)}else l<=be&&(a+=l);return{width:a,height:o,x:s,y:c}}function Se(e,t){let n=Q(e,!0,t===`fixed`),r=n.top+e.clientTop,a=n.left+e.clientLeft,o=B(e)?Z(e):i(1);return{width:e.clientWidth*o.x,height:e.clientHeight*o.y,x:a*o.x,y:r*o.y}}function Ce(e,t,n){let r;if(t===`viewport`)r=xe(e,n);else if(t===`document`)r=ye(R(e));else if(z(t))r=Se(t,n);else{let n=me(e);r={x:t.x-n.x,y:t.y-n.y,width:t.width,height:t.height}}return T(r)}function we(e,t){let n=Y(e);return n===t||!z(n)||K(n)?!1:q(n).position===`fixed`||we(n,t)}function Te(e,t){let n=t.get(e);if(n)return n;let r=X(e,[],!1).filter(e=>z(e)&&I(e)!==`body`),i=null,a=q(e).position===`fixed`,o=a?Y(e):e;for(;z(o)&&!K(o);){let t=q(o),n=W(o);!n&&t.position===`fixed`&&(i=null),(a?!n&&!i:!n&&t.position===`static`&&i&&(i.position===`absolute`||i.position===`fixed`)||V(o)&&!n&&we(e,o))?r=r.filter(e=>e!==o):i=t,o=Y(o)}return t.set(e,r),r}function Ee(n){let{element:r,boundary:i,rootBoundary:a,strategy:o}=n,s=[...i===`clippingAncestors`?H(r)?[]:Te(r,this._c):[].concat(i),a],c=Ce(r,s[0],o),l=c.top,u=c.right,d=c.bottom,f=c.left;for(let n=1;n<s.length;n++){let i=Ce(r,s[n],o);l=t(i.top,l),u=e(i.right,u),d=e(i.bottom,d),f=t(i.left,f)}return{width:u-f,height:d-l,x:f,y:l}}function De(e){let{width:t,height:n}=de(e);return{width:t,height:n}}function Oe(e,t,n){let r=B(t),a=R(t),o=n===`fixed`,s=Q(e,!0,o,t),c={scrollLeft:0,scrollTop:0},l=i(0);function u(){l.x=$(a)}if(r||!r&&!o)if((I(t)!==`body`||V(a))&&(c=J(t)),r){let e=Q(t,!0,o,t);l.x=e.x+t.clientLeft,l.y=e.y+t.clientTop}else a&&u();o&&!r&&a&&u();let d=a&&!r&&!o?ge(a,c):i(0);return{x:s.left+c.scrollLeft-l.x-d.x,y:s.top+c.scrollTop-l.y-d.y,width:s.width,height:s.height}}function ke(e){return q(e).position===`static`}function Ae(e,t){if(!B(e)||q(e).position===`fixed`)return null;if(t)return t(e);let n=e.offsetParent;return R(e)===n&&(n=n.ownerDocument.body),n}function je(e,t){let n=L(e);if(H(e))return n;if(!B(e)){let t=Y(e);for(;t&&!K(t);){if(z(t)&&!ke(t))return t;t=Y(t)}return n}let r=Ae(e,t);for(;r&&ie(r)&&ke(r);)r=Ae(r,t);return r&&K(r)&&ke(r)&&!W(r)?n:r||ce(e)||n}var Me=async function(e){let t=this.getOffsetParent||je,n=this.getDimensions,r=await n(e.floating);return{reference:Oe(e.reference,await t(e.floating),e.strategy),floating:{x:0,y:0,width:r.width,height:r.height}}};function Ne(e){return q(e).direction===`rtl`}var Pe={convertOffsetParentRelativeRectToViewportRelativeRect:_e,getDocumentElement:R,getClippingRect:Ee,getOffsetParent:je,getElementRects:Me,getClientRects:ve,getDimensions:De,getScale:Z,isElement:z,isRTL:Ne};function Fe(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function Ie(n,i){let a=null,o,s=R(n);function c(){var e;clearTimeout(o),(e=a)==null||e.disconnect(),a=null}function l(u,d){u===void 0&&(u=!1),d===void 0&&(d=1),c();let f=n.getBoundingClientRect(),{left:p,top:m,width:h,height:g}=f;if(u||i(),!h||!g)return;let _=r(m),v=r(s.clientWidth-(p+h)),y=r(s.clientHeight-(m+g)),b=r(p),x={rootMargin:-_+`px `+-v+`px `+-y+`px `+-b+`px`,threshold:t(0,e(1,d))||1},S=!0;function C(e){let t=e[0].intersectionRatio;if(t!==d){if(!S)return l();t?l(!1,t):o=setTimeout(()=>{l(!1,1e-7)},1e3)}t===1&&!Fe(f,n.getBoundingClientRect())&&l(),S=!1}try{a=new IntersectionObserver(C,{...x,root:s.ownerDocument})}catch{a=new IntersectionObserver(C,x)}a.observe(n)}return l(!0),c}function Le(e,t,n,r){r===void 0&&(r={});let{ancestorScroll:i=!0,ancestorResize:a=!0,elementResize:o=typeof ResizeObserver==`function`,layoutShift:s=typeof IntersectionObserver==`function`,animationFrame:c=!1}=r,l=fe(e),u=i||a?[...l?X(l):[],...t?X(t):[]]:[];u.forEach(e=>{i&&e.addEventListener(`scroll`,n,{passive:!0}),a&&e.addEventListener(`resize`,n)});let d=l&&s?Ie(l,n):null,f=-1,p=null;o&&(p=new ResizeObserver(e=>{let[r]=e;r&&r.target===l&&p&&t&&(p.unobserve(t),cancelAnimationFrame(f),f=requestAnimationFrame(()=>{var e;(e=p)==null||e.observe(t)})),n()}),l&&!c&&p.observe(l),t&&p.observe(t));let m,h=c?Q(e):null;c&&g();function g(){let t=Q(e);h&&!Fe(h,t)&&n(),h=t,m=requestAnimationFrame(g)}return n(),()=>{var e;u.forEach(e=>{i&&e.removeEventListener(`scroll`,n),a&&e.removeEventListener(`resize`,n)}),d?.(),(e=p)==null||e.disconnect(),p=null,c&&cancelAnimationFrame(m)}}var Re=P,ze=te,Be=j,Ve=A,He=(e,t,n)=>{let r=new Map,i={platform:Pe,...n},a={...i.platform,_c:r};return k(e,t,{...i,platform:a})};function Ue([e,t],n){let r=!1;for(let i=0,a=n.length-1;i<n.length;a=i++){let[o,s]=n[i],[c,l]=n[a];s>=t!=l>=t&&e<=(c-o)*(t-s)/(l-s)+o&&(r=!r)}return r}function We([e,t],n){return e>=n.left&&e<=n.right&&t>=n.top&&t<=n.bottom}function Ge(e,t,n,r,i){let a=i.split(`-`)[0],o=n.width>r.width,s=n.height>r.height,c=e>n.right-n.width/2,l=t>n.bottom-n.height/2;switch(a){case`top`:return[[o?e+2/2:c?e+8:e-8,t+2+1],[o?e-2/2:c?e+8:e-8,t+2+1],[n.left,c||o?n.bottom-2:n.top],[n.right,c?o?n.bottom-2:n.top:n.bottom-2]];case`bottom`:return[[o?e+2/2:c?e+8:e-8,t-2],[o?e-2/2:c?e+8:e-8,t-2],[n.left,c||o?n.top+2:n.bottom],[n.right,c?o?n.top+2:n.bottom:n.top+2]];case`left`:{let r=[e+2+1,s?t+2/2:l?t+8:t-8],i=[e+2+1,s?t-2/2:l?t+8:t-8];return[[l||s?n.right-2:n.left,n.top],[l?s?n.right-2:n.left:n.right-2,n.bottom],r,i]}case`right`:{let r=[e-2,s?t+2/2:l?t+8:t-8],i=[e-2,s?t-2/2:l?t+8:t-8];return[[l||s?n.left+2:n.right,n.top],[l?s?n.left+2:n.right:n.left+2,n.bottom],r,i]}default:return[]}}var Ke={top:`bottom`,right:`left`,bottom:`top`,left:`right`},qe=typeof window<`u`?window.matchMedia(`(prefers-reduced-motion: reduce)`):void 0,Je=class{constructor(e,t){this._currentPlacement=``,this._host=e,this._config=t,e.addController(this)}hostConnected(){}hostDisconnected(){this.stopPositioning(),this.cleanupSafePolygon(),this.removeTriggerListeners()}get currentPlacement(){return this._currentPlacement}async updatePosition(e){let t=this._config.getTriggerElement(),n=this._config.getFloatingElement(),r=this._config.getArrowElement();if(!t||!n)return;let i=[Re(e.distance),Be(),ze(),...r?[Ve({element:r,padding:8})]:[]],{x:a,y:o,placement:s,middlewareData:c}=await He(t,n,{placement:e.placement,strategy:`fixed`,middleware:i});if(Object.assign(n.style,{position:`fixed`,left:`${a}px`,top:`${o}px`}),s!==this._currentPlacement&&(this._currentPlacement=s,this._config.onPlacementChange?.(s)),c.arrow&&r){let{x:e,y:t}=c.arrow,n=Ke[s.split(`-`)[0]];Object.assign(r.style,{left:e==null?``:`${e}px`,top:t==null?``:`${t}px`,[n]:`${-r.offsetWidth/2}px`})}}startPositioning(e){let t=this._config.getTriggerElement(),n=this._config.getFloatingElement();!t||!n||(this._cleanupAutoUpdate?.(),this._cleanupAutoUpdate=Le(t,n,()=>this.updatePosition(e)))}stopPositioning(){this._cleanupAutoUpdate?.(),this._cleanupAutoUpdate=void 0}handlePointerLeave(e,t){let n=this._config.getFloatingElement(),r=this._config.getTriggerElement();if(!n||!r){t();return}let i=e.clientX,a=e.clientY,o=e=>{let{clientX:o,clientY:c}=e,l=[o,c],u=n.getBoundingClientRect(),d=r.getBoundingClientRect(),f=this._currentPlacement.split(`-`)[0];if(!We(l,u)&&!We(l,d)){if(f===`top`&&a>=d.bottom-1||f===`bottom`&&a<=d.top+1||f===`left`&&i>=d.right-1||f===`right`&&i<=d.left+1){s(),t();return}Ue(l,Ge(i,a,u,d,this._currentPlacement))||(s(),t())}},s=()=>{document.removeEventListener(`pointermove`,o)};document.addEventListener(`pointermove`,o),this._cleanupSafePolygon?.(),this._cleanupSafePolygon=s}cleanupSafePolygon(){this._cleanupSafePolygon?.(),this._cleanupSafePolygon=void 0}addTriggerListeners(e){let t=this._config.getTriggerElement();t&&(this._handlers=e,this._triggerElement=t,e.onPointerEnter&&t.addEventListener(`pointerenter`,e.onPointerEnter),e.onPointerLeave&&t.addEventListener(`pointerleave`,e.onPointerLeave),e.onFocusIn&&t.addEventListener(`focusin`,e.onFocusIn),e.onFocusOut&&t.addEventListener(`focusout`,e.onFocusOut),e.onClick&&t.addEventListener(`click`,e.onClick),e.onKeyDown&&t.addEventListener(`keydown`,e.onKeyDown))}removeTriggerListeners(e){let t=e??this._triggerElement,n=this._handlers;!t||!n||(n.onPointerEnter&&t.removeEventListener(`pointerenter`,n.onPointerEnter),n.onPointerLeave&&t.removeEventListener(`pointerleave`,n.onPointerLeave),n.onFocusIn&&t.removeEventListener(`focusin`,n.onFocusIn),n.onFocusOut&&t.removeEventListener(`focusout`,n.onFocusOut),n.onClick&&t.removeEventListener(`click`,n.onClick),n.onKeyDown&&t.removeEventListener(`keydown`,n.onKeyDown),e||(this._handlers=void 0,this._triggerElement=void 0))}async animateShow(e,t,n){let r=qe?.matches?0:t;e.getAnimations().forEach(e=>e.cancel()),e.animate(n??[{opacity:0,scale:.96},{opacity:1,scale:1}],{duration:r,fill:`forwards`})}async animateHide(e,t,n){let r=qe?.matches?0:t;await e.animate(n??[{opacity:1,scale:1},{opacity:0,scale:.96}],{duration:r,fill:`forwards`}).finished}};export{Je as PopoverController};
|
|
1
|
+
var e=Math.min,t=Math.max,n=Math.round,r=Math.floor,i=e=>({x:e,y:e}),a={left:`right`,right:`left`,bottom:`top`,top:`bottom`};function o(n,r,i){return t(n,e(r,i))}function s(e,t){return typeof e==`function`?e(t):e}function c(e){return e.split(`-`)[0]}function l(e){return e.split(`-`)[1]}function u(e){return e===`x`?`y`:`x`}function d(e){return e===`y`?`height`:`width`}function f(e){let t=e[0];return t===`t`||t===`b`?`y`:`x`}function p(e){return u(f(e))}function m(e,t,n){n===void 0&&(n=!1);let r=l(e),i=p(e),a=d(i),o=i===`x`?r===(n?`end`:`start`)?`right`:`left`:r===`start`?`bottom`:`top`;return t.reference[a]>t.floating[a]&&(o=C(o)),[o,C(o)]}function h(e){let t=C(e);return[g(e),t,g(t)]}function g(e){return e.includes(`start`)?e.replace(`start`,`end`):e.replace(`end`,`start`)}var _=[`left`,`right`],v=[`right`,`left`],y=[`top`,`bottom`],b=[`bottom`,`top`];function x(e,t,n){switch(e){case`top`:case`bottom`:return n?t?v:_:t?_:v;case`left`:case`right`:return t?y:b;default:return[]}}function S(e,t,n,r){let i=l(e),a=x(c(e),n===`start`,r);return i&&(a=a.map(e=>e+`-`+i),t&&(a=a.concat(a.map(g)))),a}function C(e){let t=c(e);return a[t]+e.slice(t.length)}function w(e){return{top:0,right:0,bottom:0,left:0,...e}}function ee(e){return typeof e==`number`?{top:e,right:e,bottom:e,left:e}:w(e)}function T(e){let{x:t,y:n,width:r,height:i}=e;return{width:r,height:i,top:n,left:t,right:t+r,bottom:n+i,x:t,y:n}}function E(e,t,n){let{reference:r,floating:i}=e,a=f(t),o=p(t),s=d(o),u=c(t),m=a===`y`,h=r.x+r.width/2-i.width/2,g=r.y+r.height/2-i.height/2,_=r[s]/2-i[s]/2,v;switch(u){case`top`:v={x:h,y:r.y-i.height};break;case`bottom`:v={x:h,y:r.y+r.height};break;case`right`:v={x:r.x+r.width,y:g};break;case`left`:v={x:r.x-i.width,y:g};break;default:v={x:r.x,y:r.y}}switch(l(t)){case`start`:v[o]-=_*(n&&m?-1:1);break;case`end`:v[o]+=_*(n&&m?-1:1);break}return v}async function D(e,t){t===void 0&&(t={});let{x:n,y:r,platform:i,rects:a,elements:o,strategy:c}=e,{boundary:l=`clippingAncestors`,rootBoundary:u=`viewport`,elementContext:d=`floating`,altBoundary:f=!1,padding:p=0}=s(t,e),m=ee(p),h=o[f?d===`floating`?`reference`:`floating`:d],g=T(await i.getClippingRect({element:await(i.isElement==null?void 0:i.isElement(h))??!0?h:h.contextElement||await(i.getDocumentElement==null?void 0:i.getDocumentElement(o.floating)),boundary:l,rootBoundary:u,strategy:c})),_=d===`floating`?{x:n,y:r,width:a.floating.width,height:a.floating.height}:a.reference,v=await(i.getOffsetParent==null?void 0:i.getOffsetParent(o.floating)),y=await(i.isElement==null?void 0:i.isElement(v))&&await(i.getScale==null?void 0:i.getScale(v))||{x:1,y:1},b=T(i.convertOffsetParentRelativeRectToViewportRelativeRect?await i.convertOffsetParentRelativeRectToViewportRelativeRect({elements:o,rect:_,offsetParent:v,strategy:c}):_);return{top:(g.top-b.top+m.top)/y.y,bottom:(b.bottom-g.bottom+m.bottom)/y.y,left:(g.left-b.left+m.left)/y.x,right:(b.right-g.right+m.right)/y.x}}var O=50,k=async(e,t,n)=>{let{placement:r=`bottom`,strategy:i=`absolute`,middleware:a=[],platform:o}=n,s=o.detectOverflow?o:{...o,detectOverflow:D},c=await(o.isRTL==null?void 0:o.isRTL(t)),l=await o.getElementRects({reference:e,floating:t,strategy:i}),{x:u,y:d}=E(l,r,c),f=r,p=0,m={};for(let n=0;n<a.length;n++){let h=a[n];if(!h)continue;let{name:g,fn:_}=h,{x:v,y,data:b,reset:x}=await _({x:u,y:d,initialPlacement:r,placement:f,strategy:i,middlewareData:m,rects:l,platform:s,elements:{reference:e,floating:t}});u=v??u,d=y??d,m[g]={...m[g],...b},x&&p<O&&(p++,typeof x==`object`&&(x.placement&&(f=x.placement),x.rects&&(l=x.rects===!0?await o.getElementRects({reference:e,floating:t,strategy:i}):x.rects),{x:u,y:d}=E(l,f,c)),n=-1)}return{x:u,y:d,placement:f,strategy:i,middlewareData:m}},A=t=>({name:`arrow`,options:t,async fn(n){let{x:r,y:i,placement:a,rects:c,platform:u,elements:f,middlewareData:m}=n,{element:h,padding:g=0}=s(t,n)||{};if(h==null)return{};let _=ee(g),v={x:r,y:i},y=p(a),b=d(y),x=await u.getDimensions(h),S=y===`y`,C=S?`top`:`left`,w=S?`bottom`:`right`,T=S?`clientHeight`:`clientWidth`,E=c.reference[b]+c.reference[y]-v[y]-c.floating[b],D=v[y]-c.reference[y],O=await(u.getOffsetParent==null?void 0:u.getOffsetParent(h)),k=O?O[T]:0;(!k||!await(u.isElement==null?void 0:u.isElement(O)))&&(k=f.floating[T]||c.floating[b]);let A=E/2-D/2,j=k/2-x[b]/2-1,M=e(_[C],j),N=e(_[w],j),P=M,te=k-x[b]-N,F=k/2-x[b]/2+A,I=o(P,F,te),L=!m.arrow&&l(a)!=null&&F!==I&&c.reference[b]/2-(F<P?M:N)-x[b]/2<0,R=L?F<P?F-P:F-te:0;return{[y]:v[y]+R,data:{[y]:I,centerOffset:F-I-R,...L&&{alignmentOffset:R}},reset:L}}}),j=function(e){return e===void 0&&(e={}),{name:`flip`,options:e,async fn(t){var n;let{placement:r,middlewareData:i,rects:a,initialPlacement:o,platform:l,elements:u}=t,{mainAxis:d=!0,crossAxis:p=!0,fallbackPlacements:g,fallbackStrategy:_=`bestFit`,fallbackAxisSideDirection:v=`none`,flipAlignment:y=!0,...b}=s(e,t);if((n=i.arrow)!=null&&n.alignmentOffset)return{};let x=c(r),w=f(o),ee=c(o)===o,T=await(l.isRTL==null?void 0:l.isRTL(u.floating)),E=g||(ee||!y?[C(o)]:h(o)),D=v!==`none`;!g&&D&&E.push(...S(o,y,v,T));let O=[o,...E],k=await l.detectOverflow(t,b),A=[],j=i.flip?.overflows||[];if(d&&A.push(k[x]),p){let e=m(r,a,T);A.push(k[e[0]],k[e[1]])}if(j=[...j,{placement:r,overflows:A}],!A.every(e=>e<=0)){let e=(i.flip?.index||0)+1,t=O[e];if(t&&(!(p===`alignment`&&w!==f(t))||j.every(e=>f(e.placement)===w?e.overflows[0]>0:!0)))return{data:{index:e,overflows:j},reset:{placement:t}};let n=j.filter(e=>e.overflows[0]<=0).sort((e,t)=>e.overflows[1]-t.overflows[1])[0]?.placement;if(!n)switch(_){case`bestFit`:{let e=j.filter(e=>{if(D){let t=f(e.placement);return t===w||t===`y`}return!0}).map(e=>[e.placement,e.overflows.filter(e=>e>0).reduce((e,t)=>e+t,0)]).sort((e,t)=>e[1]-t[1])[0]?.[0];e&&(n=e);break}case`initialPlacement`:n=o;break}if(r!==n)return{reset:{placement:n}}}return{}}}},M=new Set([`left`,`top`]);async function N(e,t){let{placement:n,platform:r,elements:i}=e,a=await(r.isRTL==null?void 0:r.isRTL(i.floating)),o=c(n),u=l(n),d=f(n)===`y`,p=M.has(o)?-1:1,m=a&&d?-1:1,h=s(t,e),{mainAxis:g,crossAxis:_,alignmentAxis:v}=typeof h==`number`?{mainAxis:h,crossAxis:0,alignmentAxis:null}:{mainAxis:h.mainAxis||0,crossAxis:h.crossAxis||0,alignmentAxis:h.alignmentAxis};return u&&typeof v==`number`&&(_=u===`end`?v*-1:v),d?{x:_*m,y:g*p}:{x:g*p,y:_*m}}var P=function(e){return e===void 0&&(e=0),{name:`offset`,options:e,async fn(t){var n;let{x:r,y:i,placement:a,middlewareData:o}=t,s=await N(t,e);return a===o.offset?.placement&&(n=o.arrow)!=null&&n.alignmentOffset?{}:{x:r+s.x,y:i+s.y,data:{...s,placement:a}}}}},te=function(e){return e===void 0&&(e={}),{name:`shift`,options:e,async fn(t){let{x:n,y:r,placement:i,platform:a}=t,{mainAxis:l=!0,crossAxis:d=!1,limiter:p={fn:e=>{let{x:t,y:n}=e;return{x:t,y:n}}},...m}=s(e,t),h={x:n,y:r},g=await a.detectOverflow(t,m),_=f(c(i)),v=u(_),y=h[v],b=h[_];if(l){let e=v===`y`?`top`:`left`,t=v===`y`?`bottom`:`right`,n=y+g[e],r=y-g[t];y=o(n,y,r)}if(d){let e=_===`y`?`top`:`left`,t=_===`y`?`bottom`:`right`,n=b+g[e],r=b-g[t];b=o(n,b,r)}let x=p.fn({...t,[v]:y,[_]:b});return{...x,data:{x:x.x-n,y:x.y-r,enabled:{[v]:l,[_]:d}}}}}};function F(){return typeof window<`u`}function I(e){return ne(e)?(e.nodeName||``).toLowerCase():`#document`}function L(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function R(e){return((ne(e)?e.ownerDocument:e.document)||window.document)?.documentElement}function ne(e){return F()?e instanceof Node||e instanceof L(e).Node:!1}function z(e){return F()?e instanceof Element||e instanceof L(e).Element:!1}function B(e){return F()?e instanceof HTMLElement||e instanceof L(e).HTMLElement:!1}function re(e){return!F()||typeof ShadowRoot>`u`?!1:e instanceof ShadowRoot||e instanceof L(e).ShadowRoot}function V(e){let{overflow:t,overflowX:n,overflowY:r,display:i}=q(e);return/auto|scroll|overlay|hidden|clip/.test(t+r+n)&&i!==`inline`&&i!==`contents`}function ie(e){return/^(table|td|th)$/.test(I(e))}function H(e){try{if(e.matches(`:popover-open`))return!0}catch{}try{return e.matches(`:modal`)}catch{return!1}}var ae=/transform|translate|scale|rotate|perspective|filter/,oe=/paint|layout|strict|content/,U=e=>!!e&&e!==`none`,se;function W(e){let t=z(e)?q(e):e;return U(t.transform)||U(t.translate)||U(t.scale)||U(t.rotate)||U(t.perspective)||!G()&&(U(t.backdropFilter)||U(t.filter))||ae.test(t.willChange||``)||oe.test(t.contain||``)}function ce(e){let t=Y(e);for(;B(t)&&!K(t);){if(W(t))return t;if(H(t))return null;t=Y(t)}return null}function G(){return se??=typeof CSS<`u`&&CSS.supports&&CSS.supports(`-webkit-backdrop-filter`,`none`),se}function K(e){return/^(html|body|#document)$/.test(I(e))}function q(e){return L(e).getComputedStyle(e)}function J(e){return z(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function Y(e){if(I(e)===`html`)return e;let t=e.assignedSlot||e.parentNode||re(e)&&e.host||R(e);return re(t)?t.host:t}function le(e){let t=Y(e);return K(t)?e.ownerDocument?e.ownerDocument.body:e.body:B(t)&&V(t)?t:le(t)}function X(e,t,n){t===void 0&&(t=[]),n===void 0&&(n=!0);let r=le(e),i=r===e.ownerDocument?.body,a=L(r);if(i){let e=ue(a);return t.concat(a,a.visualViewport||[],V(r)?r:[],e&&n?X(e):[])}else return t.concat(r,X(r,[],n))}function ue(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function de(e){let t=q(e),r=parseFloat(t.width)||0,i=parseFloat(t.height)||0,a=B(e),o=a?e.offsetWidth:r,s=a?e.offsetHeight:i,c=n(r)!==o||n(i)!==s;return c&&(r=o,i=s),{width:r,height:i,$:c}}function fe(e){return z(e)?e:e.contextElement}function Z(e){let t=fe(e);if(!B(t))return i(1);let r=t.getBoundingClientRect(),{width:a,height:o,$:s}=de(t),c=(s?n(r.width):r.width)/a,l=(s?n(r.height):r.height)/o;return(!c||!Number.isFinite(c))&&(c=1),(!l||!Number.isFinite(l))&&(l=1),{x:c,y:l}}var pe=i(0);function me(e){let t=L(e);return!G()||!t.visualViewport?pe:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function he(e,t,n){return t===void 0&&(t=!1),!n||t&&n!==L(e)?!1:t}function Q(e,t,n,r){t===void 0&&(t=!1),n===void 0&&(n=!1);let a=e.getBoundingClientRect(),o=fe(e),s=i(1);t&&(r?z(r)&&(s=Z(r)):s=Z(e));let c=he(o,n,r)?me(o):i(0),l=(a.left+c.x)/s.x,u=(a.top+c.y)/s.y,d=a.width/s.x,f=a.height/s.y;if(o){let e=L(o),t=r&&z(r)?L(r):r,n=e,i=ue(n);for(;i&&r&&t!==n;){let e=Z(i),t=i.getBoundingClientRect(),r=q(i),a=t.left+(i.clientLeft+parseFloat(r.paddingLeft))*e.x,o=t.top+(i.clientTop+parseFloat(r.paddingTop))*e.y;l*=e.x,u*=e.y,d*=e.x,f*=e.y,l+=a,u+=o,n=L(i),i=ue(n)}}return T({width:d,height:f,x:l,y:u})}function $(e,t){let n=J(e).scrollLeft;return t?t.left+n:Q(R(e)).left+n}function ge(e,t){let n=e.getBoundingClientRect();return{x:n.left+t.scrollLeft-$(e,n),y:n.top+t.scrollTop}}function _e(e){let{elements:t,rect:n,offsetParent:r,strategy:a}=e,o=a===`fixed`,s=R(r),c=t?H(t.floating):!1;if(r===s||c&&o)return n;let l={scrollLeft:0,scrollTop:0},u=i(1),d=i(0),f=B(r);if((f||!f&&!o)&&((I(r)!==`body`||V(s))&&(l=J(r)),f)){let e=Q(r);u=Z(r),d.x=e.x+r.clientLeft,d.y=e.y+r.clientTop}let p=s&&!f&&!o?ge(s,l):i(0);return{width:n.width*u.x,height:n.height*u.y,x:n.x*u.x-l.scrollLeft*u.x+d.x+p.x,y:n.y*u.y-l.scrollTop*u.y+d.y+p.y}}function ve(e){return Array.from(e.getClientRects())}function ye(e){let n=R(e),r=J(e),i=e.ownerDocument.body,a=t(n.scrollWidth,n.clientWidth,i.scrollWidth,i.clientWidth),o=t(n.scrollHeight,n.clientHeight,i.scrollHeight,i.clientHeight),s=-r.scrollLeft+$(e),c=-r.scrollTop;return q(i).direction===`rtl`&&(s+=t(n.clientWidth,i.clientWidth)-a),{width:a,height:o,x:s,y:c}}var be=25;function xe(e,t){let n=L(e),r=R(e),i=n.visualViewport,a=r.clientWidth,o=r.clientHeight,s=0,c=0;if(i){a=i.width,o=i.height;let e=G();(!e||e&&t===`fixed`)&&(s=i.offsetLeft,c=i.offsetTop)}let l=$(r);if(l<=0){let e=r.ownerDocument,t=e.body,n=getComputedStyle(t),i=e.compatMode===`CSS1Compat`&&parseFloat(n.marginLeft)+parseFloat(n.marginRight)||0,o=Math.abs(r.clientWidth-t.clientWidth-i);o<=be&&(a-=o)}else l<=be&&(a+=l);return{width:a,height:o,x:s,y:c}}function Se(e,t){let n=Q(e,!0,t===`fixed`),r=n.top+e.clientTop,a=n.left+e.clientLeft,o=B(e)?Z(e):i(1);return{width:e.clientWidth*o.x,height:e.clientHeight*o.y,x:a*o.x,y:r*o.y}}function Ce(e,t,n){let r;if(t===`viewport`)r=xe(e,n);else if(t===`document`)r=ye(R(e));else if(z(t))r=Se(t,n);else{let n=me(e);r={x:t.x-n.x,y:t.y-n.y,width:t.width,height:t.height}}return T(r)}function we(e,t){let n=Y(e);return n===t||!z(n)||K(n)?!1:q(n).position===`fixed`||we(n,t)}function Te(e,t){let n=t.get(e);if(n)return n;let r=X(e,[],!1).filter(e=>z(e)&&I(e)!==`body`),i=null,a=q(e).position===`fixed`,o=a?Y(e):e;for(;z(o)&&!K(o);){let t=q(o),n=W(o);!n&&t.position===`fixed`&&(i=null),(a?!n&&!i:!n&&t.position===`static`&&i&&(i.position===`absolute`||i.position===`fixed`)||V(o)&&!n&&we(e,o))?r=r.filter(e=>e!==o):i=t,o=Y(o)}return t.set(e,r),r}function Ee(n){let{element:r,boundary:i,rootBoundary:a,strategy:o}=n,s=[...i===`clippingAncestors`?H(r)?[]:Te(r,this._c):[].concat(i),a],c=Ce(r,s[0],o),l=c.top,u=c.right,d=c.bottom,f=c.left;for(let n=1;n<s.length;n++){let i=Ce(r,s[n],o);l=t(i.top,l),u=e(i.right,u),d=e(i.bottom,d),f=t(i.left,f)}return{width:u-f,height:d-l,x:f,y:l}}function De(e){let{width:t,height:n}=de(e);return{width:t,height:n}}function Oe(e,t,n){let r=B(t),a=R(t),o=n===`fixed`,s=Q(e,!0,o,t),c={scrollLeft:0,scrollTop:0},l=i(0);function u(){l.x=$(a)}if(r||!r&&!o)if((I(t)!==`body`||V(a))&&(c=J(t)),r){let e=Q(t,!0,o,t);l.x=e.x+t.clientLeft,l.y=e.y+t.clientTop}else a&&u();o&&!r&&a&&u();let d=a&&!r&&!o?ge(a,c):i(0);return{x:s.left+c.scrollLeft-l.x-d.x,y:s.top+c.scrollTop-l.y-d.y,width:s.width,height:s.height}}function ke(e){return q(e).position===`static`}function Ae(e,t){if(!B(e)||q(e).position===`fixed`)return null;if(t)return t(e);let n=e.offsetParent;return R(e)===n&&(n=n.ownerDocument.body),n}function je(e,t){let n=L(e);if(H(e))return n;if(!B(e)){let t=Y(e);for(;t&&!K(t);){if(z(t)&&!ke(t))return t;t=Y(t)}return n}let r=Ae(e,t);for(;r&&ie(r)&&ke(r);)r=Ae(r,t);return r&&K(r)&&ke(r)&&!W(r)?n:r||ce(e)||n}var Me=async function(e){let t=this.getOffsetParent||je,n=this.getDimensions,r=await n(e.floating);return{reference:Oe(e.reference,await t(e.floating),e.strategy),floating:{x:0,y:0,width:r.width,height:r.height}}};function Ne(e){return q(e).direction===`rtl`}var Pe={convertOffsetParentRelativeRectToViewportRelativeRect:_e,getDocumentElement:R,getClippingRect:Ee,getOffsetParent:je,getElementRects:Me,getClientRects:ve,getDimensions:De,getScale:Z,isElement:z,isRTL:Ne};function Fe(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function Ie(n,i){let a=null,o,s=R(n);function c(){var e;clearTimeout(o),(e=a)==null||e.disconnect(),a=null}function l(u,d){u===void 0&&(u=!1),d===void 0&&(d=1),c();let f=n.getBoundingClientRect(),{left:p,top:m,width:h,height:g}=f;if(u||i(),!h||!g)return;let _=r(m),v=r(s.clientWidth-(p+h)),y=r(s.clientHeight-(m+g)),b=r(p),x={rootMargin:-_+`px `+-v+`px `+-y+`px `+-b+`px`,threshold:t(0,e(1,d))||1},S=!0;function C(e){let t=e[0].intersectionRatio;if(t!==d){if(!S)return l();t?l(!1,t):o=setTimeout(()=>{l(!1,1e-7)},1e3)}t===1&&!Fe(f,n.getBoundingClientRect())&&l(),S=!1}try{a=new IntersectionObserver(C,{...x,root:s.ownerDocument})}catch{a=new IntersectionObserver(C,x)}a.observe(n)}return l(!0),c}function Le(e,t,n,r){r===void 0&&(r={});let{ancestorScroll:i=!0,ancestorResize:a=!0,elementResize:o=typeof ResizeObserver==`function`,layoutShift:s=typeof IntersectionObserver==`function`,animationFrame:c=!1}=r,l=fe(e),u=i||a?[...l?X(l):[],...t?X(t):[]]:[];u.forEach(e=>{i&&e.addEventListener(`scroll`,n,{passive:!0}),a&&e.addEventListener(`resize`,n)});let d=l&&s?Ie(l,n):null,f=-1,p=null;o&&(p=new ResizeObserver(e=>{let[r]=e;r&&r.target===l&&p&&t&&(p.unobserve(t),cancelAnimationFrame(f),f=requestAnimationFrame(()=>{var e;(e=p)==null||e.observe(t)})),n()}),l&&!c&&p.observe(l),t&&p.observe(t));let m,h=c?Q(e):null;c&&g();function g(){let t=Q(e);h&&!Fe(h,t)&&n(),h=t,m=requestAnimationFrame(g)}return n(),()=>{var e;u.forEach(e=>{i&&e.removeEventListener(`scroll`,n),a&&e.removeEventListener(`resize`,n)}),d?.(),(e=p)==null||e.disconnect(),p=null,c&&cancelAnimationFrame(m)}}var Re=P,ze=te,Be=j,Ve=A,He=(e,t,n)=>{let r=new Map,i={platform:Pe,...n},a={...i.platform,_c:r};return k(e,t,{...i,platform:a})};function Ue([e,t],n){let r=!1;for(let i=0,a=n.length-1;i<n.length;a=i++){let[o,s]=n[i],[c,l]=n[a];s>=t!=l>=t&&e<=(c-o)*(t-s)/(l-s)+o&&(r=!r)}return r}function We([e,t],n){return e>=n.left&&e<=n.right&&t>=n.top&&t<=n.bottom}function Ge(e,t,n,r,i){let a=i.split(`-`)[0],o=n.width>r.width,s=n.height>r.height,c=e>n.right-n.width/2,l=t>n.bottom-n.height/2;switch(a){case`top`:return[[o?e+2/2:c?e+8:e-8,t+2+1],[o?e-2/2:c?e+8:e-8,t+2+1],[n.left,c||o?n.bottom-2:n.top],[n.right,c?o?n.bottom-2:n.top:n.bottom-2]];case`bottom`:return[[o?e+2/2:c?e+8:e-8,t-2],[o?e-2/2:c?e+8:e-8,t-2],[n.left,c||o?n.top+2:n.bottom],[n.right,c?o?n.top+2:n.bottom:n.top+2]];case`left`:{let r=[e+2+1,s?t+2/2:l?t+8:t-8],i=[e+2+1,s?t-2/2:l?t+8:t-8];return[[l||s?n.right-2:n.left,n.top],[l?s?n.right-2:n.left:n.right-2,n.bottom],r,i]}case`right`:{let r=[e-2,s?t+2/2:l?t+8:t-8],i=[e-2,s?t-2/2:l?t+8:t-8];return[[l||s?n.left+2:n.right,n.top],[l?s?n.left+2:n.right:n.left+2,n.bottom],r,i]}default:return[]}}var Ke={top:`bottom`,right:`left`,bottom:`top`,left:`right`},qe=typeof window<`u`?window.matchMedia(`(prefers-reduced-motion: reduce)`):void 0,Je=class{constructor(e,t){this._currentPlacement=``,this._host=e,this._config=t,e.addController(this)}hostConnected(){}hostDisconnected(){this.stopPositioning(),this.cleanupSafePolygon(),this.removeTriggerListeners()}get currentPlacement(){return this._currentPlacement}async updatePosition(e){let t=this._config.getTriggerElement(),n=this._config.getFloatingElement(),r=this._config.getArrowElement();if(!t||!n)return;let i=[Re(e.distance),Be(),ze(),...r?[Ve({element:r,padding:8})]:[]],{x:a,y:o,placement:s,middlewareData:c}=await He(t,n,{placement:e.placement,strategy:`fixed`,middleware:i});if(Object.assign(n.style,{position:`fixed`,left:e.fullWidth?`0px`:`${a}px`,top:`${o}px`,width:e.fullWidth?`100vw`:``}),s!==this._currentPlacement&&(this._currentPlacement=s,this._config.onPlacementChange?.(s)),c.arrow&&r){let{x:e,y:t}=c.arrow,n=Ke[s.split(`-`)[0]];Object.assign(r.style,{left:e==null?``:`${e}px`,top:t==null?``:`${t}px`,[n]:`${-r.offsetWidth/2}px`})}}startPositioning(e){let t=this._config.getTriggerElement(),n=this._config.getFloatingElement();!t||!n||(this._cleanupAutoUpdate?.(),this._cleanupAutoUpdate=Le(t,n,()=>this.updatePosition(e)))}stopPositioning(){this._cleanupAutoUpdate?.(),this._cleanupAutoUpdate=void 0}handlePointerLeave(e,t){let n=this._config.getFloatingElement(),r=this._config.getTriggerElement();if(!n||!r){t();return}let i=e.clientX,a=e.clientY,o=e=>{let{clientX:o,clientY:c}=e,l=[o,c],u=n.getBoundingClientRect(),d=r.getBoundingClientRect(),f=this._currentPlacement.split(`-`)[0];if(!We(l,u)&&!We(l,d)){if(f===`top`&&a>=d.bottom-1||f===`bottom`&&a<=d.top+1||f===`left`&&i>=d.right-1||f===`right`&&i<=d.left+1){s(),t();return}Ue(l,Ge(i,a,u,d,this._currentPlacement))||(s(),t())}},s=()=>{document.removeEventListener(`pointermove`,o)};document.addEventListener(`pointermove`,o),this._cleanupSafePolygon?.(),this._cleanupSafePolygon=s}cleanupSafePolygon(){this._cleanupSafePolygon?.(),this._cleanupSafePolygon=void 0}addTriggerListeners(e){let t=this._config.getTriggerElement();t&&(this._handlers=e,this._triggerElement=t,e.onPointerEnter&&t.addEventListener(`pointerenter`,e.onPointerEnter),e.onPointerLeave&&t.addEventListener(`pointerleave`,e.onPointerLeave),e.onFocusIn&&t.addEventListener(`focusin`,e.onFocusIn),e.onFocusOut&&t.addEventListener(`focusout`,e.onFocusOut),e.onClick&&t.addEventListener(`click`,e.onClick),e.onKeyDown&&t.addEventListener(`keydown`,e.onKeyDown))}removeTriggerListeners(e){let t=e??this._triggerElement,n=this._handlers;!t||!n||(n.onPointerEnter&&t.removeEventListener(`pointerenter`,n.onPointerEnter),n.onPointerLeave&&t.removeEventListener(`pointerleave`,n.onPointerLeave),n.onFocusIn&&t.removeEventListener(`focusin`,n.onFocusIn),n.onFocusOut&&t.removeEventListener(`focusout`,n.onFocusOut),n.onClick&&t.removeEventListener(`click`,n.onClick),n.onKeyDown&&t.removeEventListener(`keydown`,n.onKeyDown),e||(this._handlers=void 0,this._triggerElement=void 0))}async animateShow(e,t,n){let r=qe?.matches?0:t;e.getAnimations().forEach(e=>e.cancel()),e.animate(n??[{opacity:0,scale:.96},{opacity:1,scale:1}],{duration:r,fill:`forwards`})}async animateHide(e,t,n){let r=qe?.matches?0:t;await e.animate(n??[{opacity:1,scale:1},{opacity:0,scale:.96}],{duration:r,fill:`forwards`}).finished}};export{Je as PopoverController};
|
|
2
2
|
//# sourceMappingURL=popover.js.map
|