luxen-ui 0.18.1 → 0.18.2
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 +185 -175
- package/cdn/elements/dropdown/dropdown.d.ts +16 -1
- package/cdn/elements/dropdown/dropdown.d.ts.map +1 -1
- package/cdn/elements/dropdown/dropdown.js +1 -1
- package/cdn/elements/dropdown/dropdown.js.map +1 -1
- package/cdn/elements/tabs/tabs.d.ts +2 -0
- package/cdn/elements/tabs/tabs.d.ts.map +1 -1
- package/cdn/elements/tabs/tabs.js.map +1 -1
- package/cdn/standalone.css +35 -0
- package/cdn/styles/elements/tabs/line.css +35 -0
- package/dist/css/elements/tabs/line.css +35 -0
- package/dist/custom-elements.json +185 -175
- package/dist/elements/dropdown/dropdown.d.ts +16 -1
- package/dist/elements/dropdown/dropdown.d.ts.map +1 -1
- package/dist/elements/dropdown/dropdown.js +46 -4
- package/dist/elements/tabs/tabs.d.ts +2 -0
- package/dist/elements/tabs/tabs.d.ts.map +1 -1
- package/dist/elements/tabs/tabs.js +2 -0
- package/dist/metadata/index.json +11 -1
- package/dist/metadata/tabs.json +10 -0
- package/dist/templates/elements/tabs.md +4 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabs.js","names":[],"sources":["../../../src/html/elements/tabs/tabs.ts"],"sourcesContent":["import { property } from 'lit/decorators.js';\nimport { LuxenElement } from '../../shared/luxen-element.js';\nimport { uniqueId } from '../../registry.js';\n\nexport type TabsVariant = 'enclosed' | 'line';\nexport type TabsOrientation = 'horizontal' | 'vertical';\n\n/** Fired when the active tab changes. Bubbles; not composed. */\nexport class TabsChangeEvent extends Event {\n readonly index: number;\n readonly name: string | null;\n constructor(index: number, name: string | null) {\n super('change', { bubbles: true, composed: false, cancelable: false });\n this.index = index;\n this.name = name;\n }\n}\n\ninterface TabsEventMap {\n change: TabsChangeEvent;\n}\n\n/**\n * @summary A tabs component that progressively enhances light DOM markup\n * with ARIA roles, keyboard navigation, and animated indicators.\n *\n * @example\n * Mark the initially-active tab with `aria-selected=\"true\"` so it is styled as\n * selected before the script upgrades the element (progressive enhancement).\n * ```html\n * <l-tabs variant=\"enclosed\">\n * <div>\n * <button aria-selected=\"true\">Tab 1</button>\n * <button>Tab 2</button>\n * </div>\n * <div>Content 1</div>\n * <div>Content 2</div>\n * </l-tabs>\n * ```\n *\n * @event change - Fired when the active tab changes. Bubbles. Properties: `index: number`, `name: string | null`.\n *\n * @cssproperty [--indicator-color=var(--l-color-text-primary)] - `line` variant: color of the active underline that slides under the selected tab.\n * @cssproperty [--indicator-thickness=2px] - `line` variant: thickness of the active underline.\n * @cssproperty [--track-color=var(--l-color-border)] - `line` variant: color of the static bottom border the tabs sit on.\n * @cssproperty [--track-thickness=1px] - `line` variant: thickness of the static bottom border.\n *\n * @customElement l-tabs\n */\n// oxlint-disable-next-line typescript/no-unsafe-declaration-merging -- typed addEventListener overloads merged below; no uninitialized properties.\nexport class Tabs extends LuxenElement {\n override createRenderRoot() {\n return this;\n }\n\n private _initialized = false;\n private _setupTimer = 0;\n private _instanceId = uniqueId('tabs');\n private _tablistEl: HTMLElement | null = null;\n private _tabs: HTMLButtonElement[] = [];\n private _panels: HTMLElement[] = [];\n private _resizeObserver: ResizeObserver | null = null;\n\n /** Visual variant. */\n @property({ reflect: true })\n variant: TabsVariant = 'line';\n\n /** Index of the active tab (0-based). */\n @property({ reflect: true })\n value = '0';\n\n /** Stretch tabs to fill container width. */\n @property({ type: Boolean, reflect: true, attribute: 'full-width' })\n fullWidth = false;\n\n /** Tab orientation. */\n @property({ reflect: true })\n orientation: TabsOrientation = 'horizontal';\n\n // --- Lifecycle ---\n\n override connectedCallback() {\n super.connectedCallback();\n // Children may not be parsed yet when the element upgrades mid-parse: try\n // synchronously, then retry once on a macrotask. setTimeout, not rAF — rAF\n // is suspended in hidden documents, so the element would stay inert there.\n if (!this._trySetup()) {\n this._setupTimer = window.setTimeout(() => this._trySetup(), 0);\n }\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n clearTimeout(this._setupTimer);\n this._teardown();\n }\n\n /** @returns true when setup ran or was already done; false to schedule a retry. */\n private _trySetup(): boolean {\n if (this._initialized || !this.isConnected) return true;\n if (this.children.length < 2) return false;\n this._setup();\n return true;\n }\n\n override updated(changed: Map<string, unknown>) {\n if (changed.has('value') && this._tabs.length) {\n this._selectTab(Number(this.value), false);\n }\n if (changed.has('orientation') && this._tablistEl) {\n this._tablistEl.setAttribute('aria-orientation', this.orientation);\n }\n }\n\n // --- Setup / Teardown ---\n\n private _setup() {\n const children = Array.from(this.children) as HTMLElement[];\n if (children.length < 2) return;\n this._initialized = true;\n\n // First child is the tablist container\n this._tablistEl = children[0];\n this._tablistEl.setAttribute('role', 'tablist');\n this._tablistEl.setAttribute('aria-orientation', this.orientation);\n\n // Buttons inside tablist become tabs\n this._tabs = Array.from(this._tablistEl.querySelectorAll('button'));\n\n // Remaining children become panels\n this._panels = children.slice(1);\n\n const activeIndex = Number(this.value) || 0;\n\n // Enhance tabs\n for (let i = 0; i < this._tabs.length; i++) {\n const tab = this._tabs[i];\n const panel = this._panels[i];\n const name = tab.getAttribute('name') ?? String(i);\n const tabId = `${this._instanceId}-tab-${name}`;\n const panelId = `${this._instanceId}-panel-${name}`;\n\n tab.setAttribute('role', 'tab');\n tab.setAttribute('id', tabId);\n tab.setAttribute('aria-selected', String(i === activeIndex));\n tab.setAttribute('tabindex', i === activeIndex ? '0' : '-1');\n\n if (panel) {\n tab.setAttribute('aria-controls', panelId);\n panel.setAttribute('role', 'tabpanel');\n panel.setAttribute('id', panelId);\n panel.setAttribute('aria-labelledby', tabId);\n panel.setAttribute('tabindex', '0');\n if (i !== activeIndex) {\n panel.hidden = true;\n } else {\n panel.hidden = false;\n }\n }\n }\n\n // Attach listeners\n this._tablistEl.addEventListener('click', this._onClick);\n this._tablistEl.addEventListener('keydown', this._onKeyDown);\n\n // Initial indicator position. Synchronous first (offset reads force\n // layout), then a ResizeObserver keeps it correct across hidden→visible\n // transitions and size changes — rAF is suspended in hidden documents,\n // so it must not be the only scheduling mechanism here.\n this._updateIndicator();\n this._resizeObserver = new ResizeObserver(() => this._updateIndicator());\n this._resizeObserver.observe(this._tablistEl);\n }\n\n private _teardown() {\n this._tablistEl?.removeEventListener('click', this._onClick);\n this._tablistEl?.removeEventListener('keydown', this._onKeyDown);\n this._resizeObserver?.disconnect();\n this._resizeObserver = null;\n this._initialized = false;\n }\n\n // --- Tab selection ---\n\n private _selectTab(index: number, emitEvent = true) {\n if (index < 0 || index >= this._tabs.length) return;\n\n for (let i = 0; i < this._tabs.length; i++) {\n const tab = this._tabs[i];\n const panel = this._panels[i];\n const isActive = i === index;\n\n tab.setAttribute('aria-selected', String(isActive));\n tab.setAttribute('tabindex', isActive ? '0' : '-1');\n\n if (panel) {\n panel.hidden = !isActive;\n }\n }\n\n this.value = String(index);\n this._updateIndicator();\n\n if (emitEvent) {\n const name = this._tabs[index]?.getAttribute('name') ?? null;\n this.dispatchEvent(new TabsChangeEvent(index, name));\n }\n }\n\n // --- Indicator ---\n\n private _updateIndicator() {\n if (!this._tablistEl) return;\n const activeTab = this._tabs[Number(this.value)];\n if (!activeTab) return;\n\n const isVertical = this.orientation === 'vertical';\n\n if (isVertical) {\n this._tablistEl.style.setProperty('--_indicator-top', `${activeTab.offsetTop}px`);\n this._tablistEl.style.setProperty('--_indicator-height', `${activeTab.offsetHeight}px`);\n } else {\n this._tablistEl.style.setProperty('--_indicator-left', `${activeTab.offsetLeft}px`);\n this._tablistEl.style.setProperty('--_indicator-width', `${activeTab.offsetWidth}px`);\n }\n }\n\n // --- Event handlers ---\n\n private _onClick = (e: Event) => {\n const tab = (e.target as HTMLElement).closest<HTMLButtonElement>('[role=\"tab\"]');\n if (!tab) return;\n const index = this._tabs.indexOf(tab);\n if (index >= 0) {\n this._selectTab(index);\n tab.focus();\n }\n };\n\n private _onKeyDown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement;\n if (target.getAttribute('role') !== 'tab') return;\n\n const isHorizontal = this.orientation === 'horizontal';\n const prevKey = isHorizontal ? 'ArrowLeft' : 'ArrowUp';\n const nextKey = isHorizontal ? 'ArrowRight' : 'ArrowDown';\n\n let index = this._tabs.indexOf(target as HTMLButtonElement);\n\n switch (e.key) {\n case nextKey:\n e.preventDefault();\n index = (index + 1) % this._tabs.length;\n this._selectTab(index);\n this._tabs[index].focus();\n break;\n case prevKey:\n e.preventDefault();\n index = (index - 1 + this._tabs.length) % this._tabs.length;\n this._selectTab(index);\n this._tabs[index].focus();\n break;\n case 'Home':\n e.preventDefault();\n this._selectTab(0);\n this._tabs[0].focus();\n break;\n case 'End':\n e.preventDefault();\n this._selectTab(this._tabs.length - 1);\n this._tabs[this._tabs.length - 1].focus();\n break;\n }\n };\n}\n\n// Type `addEventListener('change', …)` on this element so the listener receives\n// a `TabsChangeEvent` (with `.index`/`.name`) instead of a bare `Event`, with no\n// cast. This is the canonical reference for the pattern used across the library.\n//\n// Why a same-named interface and not a global augmentation: `change` already\n// exists in lib.dom's `GlobalEventHandlersEventMap` (typed `Event`), and TS\n// forbids re-declaring an existing key with a different type — so colliding\n// names (`change`, `select`, `input`, `toggle`) can't be typed globally. Merging\n// a same-named `interface Tabs` into the `class Tabs` adds these overloads to\n// the element's own type only. (Non-colliding names like `show`/`story-change`\n// ARE augmented globally in their event-class module — no per-element block.)\n//\n// In `(type: K, listener: (ev: TabsEventMap[K]) => void)`, K is pinned to the\n// string literal you pass, and `TabsEventMap[K]` indexes the event type from it\n// (`'change'` → `TabsChangeEvent`). `this: Tabs` is a fake parameter that types\n// `this` inside a non-arrow listener; it emits no runtime code.\n//\n// Three load-bearing details:\n// 1. The `(type: string, …)` fallback overloads are REQUIRED: declaring our\n// own `addEventListener` hides ALL inherited `HTMLElement` overloads, so\n// without them `addEventListener('click', …)` would stop compiling. The\n// typed overload comes first so `'change'` resolves before the fallback.\n// 2. This interface sits AFTER the class: the CEM analyzer dedups on the first\n// declaration of the name, so an interface before the class would shadow it\n// and the manifest would extract nothing for this element.\n// 3. The merge is flagged by `no-unsafe-declaration-merging` (disabled on the\n// class above) — safe here because we merge only method overloads, never\n// uninitialized properties.\nexport interface Tabs {\n addEventListener<K extends keyof TabsEventMap>(\n type: K,\n listener: (this: Tabs, ev: TabsEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void;\n removeEventListener<K extends keyof TabsEventMap>(\n type: K,\n listener: (this: Tabs, ev: TabsEventMap[K]) => void,\n options?: boolean | EventListenerOptions,\n ): void;\n removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ): void;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tabs.js","names":[],"sources":["../../../src/html/elements/tabs/tabs.ts"],"sourcesContent":["import { property } from 'lit/decorators.js';\nimport { LuxenElement } from '../../shared/luxen-element.js';\nimport { uniqueId } from '../../registry.js';\n\nexport type TabsVariant = 'enclosed' | 'line';\nexport type TabsOrientation = 'horizontal' | 'vertical';\n\n/** Fired when the active tab changes. Bubbles; not composed. */\nexport class TabsChangeEvent extends Event {\n readonly index: number;\n readonly name: string | null;\n constructor(index: number, name: string | null) {\n super('change', { bubbles: true, composed: false, cancelable: false });\n this.index = index;\n this.name = name;\n }\n}\n\ninterface TabsEventMap {\n change: TabsChangeEvent;\n}\n\n/**\n * @summary A tabs component that progressively enhances light DOM markup\n * with ARIA roles, keyboard navigation, and animated indicators.\n *\n * @example\n * Mark the initially-active tab with `aria-selected=\"true\"` so it is styled as\n * selected before the script upgrades the element (progressive enhancement).\n * ```html\n * <l-tabs variant=\"enclosed\">\n * <div>\n * <button aria-selected=\"true\">Tab 1</button>\n * <button>Tab 2</button>\n * </div>\n * <div>Content 1</div>\n * <div>Content 2</div>\n * </l-tabs>\n * ```\n *\n * @event change - Fired when the active tab changes. Bubbles. Properties: `index: number`, `name: string | null`.\n *\n * @cssproperty [--indicator-color=var(--l-color-text-primary)] - `line` variant: color of the active underline that slides under the selected tab.\n * @cssproperty [--indicator-thickness=2px] - `line` variant: thickness of the active underline.\n * @cssproperty [--track-color=var(--l-color-border)] - `line` variant: color of the static bottom border the tabs sit on.\n * @cssproperty [--track-thickness=1px] - `line` variant: thickness of the static bottom border.\n * @cssproperty [--hover-color=var(--l-color-bg-state-hover)] - `line` variant: fill of the pill that appears behind a hovered tab label.\n * @cssproperty [--hover-inset=4px] - `line` variant: block-axis gap between the hover pill and the tab edges, keeping it detached from the bottom border.\n *\n * @customElement l-tabs\n */\n// oxlint-disable-next-line typescript/no-unsafe-declaration-merging -- typed addEventListener overloads merged below; no uninitialized properties.\nexport class Tabs extends LuxenElement {\n override createRenderRoot() {\n return this;\n }\n\n private _initialized = false;\n private _setupTimer = 0;\n private _instanceId = uniqueId('tabs');\n private _tablistEl: HTMLElement | null = null;\n private _tabs: HTMLButtonElement[] = [];\n private _panels: HTMLElement[] = [];\n private _resizeObserver: ResizeObserver | null = null;\n\n /** Visual variant. */\n @property({ reflect: true })\n variant: TabsVariant = 'line';\n\n /** Index of the active tab (0-based). */\n @property({ reflect: true })\n value = '0';\n\n /** Stretch tabs to fill container width. */\n @property({ type: Boolean, reflect: true, attribute: 'full-width' })\n fullWidth = false;\n\n /** Tab orientation. */\n @property({ reflect: true })\n orientation: TabsOrientation = 'horizontal';\n\n // --- Lifecycle ---\n\n override connectedCallback() {\n super.connectedCallback();\n // Children may not be parsed yet when the element upgrades mid-parse: try\n // synchronously, then retry once on a macrotask. setTimeout, not rAF — rAF\n // is suspended in hidden documents, so the element would stay inert there.\n if (!this._trySetup()) {\n this._setupTimer = window.setTimeout(() => this._trySetup(), 0);\n }\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n clearTimeout(this._setupTimer);\n this._teardown();\n }\n\n /** @returns true when setup ran or was already done; false to schedule a retry. */\n private _trySetup(): boolean {\n if (this._initialized || !this.isConnected) return true;\n if (this.children.length < 2) return false;\n this._setup();\n return true;\n }\n\n override updated(changed: Map<string, unknown>) {\n if (changed.has('value') && this._tabs.length) {\n this._selectTab(Number(this.value), false);\n }\n if (changed.has('orientation') && this._tablistEl) {\n this._tablistEl.setAttribute('aria-orientation', this.orientation);\n }\n }\n\n // --- Setup / Teardown ---\n\n private _setup() {\n const children = Array.from(this.children) as HTMLElement[];\n if (children.length < 2) return;\n this._initialized = true;\n\n // First child is the tablist container\n this._tablistEl = children[0];\n this._tablistEl.setAttribute('role', 'tablist');\n this._tablistEl.setAttribute('aria-orientation', this.orientation);\n\n // Buttons inside tablist become tabs\n this._tabs = Array.from(this._tablistEl.querySelectorAll('button'));\n\n // Remaining children become panels\n this._panels = children.slice(1);\n\n const activeIndex = Number(this.value) || 0;\n\n // Enhance tabs\n for (let i = 0; i < this._tabs.length; i++) {\n const tab = this._tabs[i];\n const panel = this._panels[i];\n const name = tab.getAttribute('name') ?? String(i);\n const tabId = `${this._instanceId}-tab-${name}`;\n const panelId = `${this._instanceId}-panel-${name}`;\n\n tab.setAttribute('role', 'tab');\n tab.setAttribute('id', tabId);\n tab.setAttribute('aria-selected', String(i === activeIndex));\n tab.setAttribute('tabindex', i === activeIndex ? '0' : '-1');\n\n if (panel) {\n tab.setAttribute('aria-controls', panelId);\n panel.setAttribute('role', 'tabpanel');\n panel.setAttribute('id', panelId);\n panel.setAttribute('aria-labelledby', tabId);\n panel.setAttribute('tabindex', '0');\n if (i !== activeIndex) {\n panel.hidden = true;\n } else {\n panel.hidden = false;\n }\n }\n }\n\n // Attach listeners\n this._tablistEl.addEventListener('click', this._onClick);\n this._tablistEl.addEventListener('keydown', this._onKeyDown);\n\n // Initial indicator position. Synchronous first (offset reads force\n // layout), then a ResizeObserver keeps it correct across hidden→visible\n // transitions and size changes — rAF is suspended in hidden documents,\n // so it must not be the only scheduling mechanism here.\n this._updateIndicator();\n this._resizeObserver = new ResizeObserver(() => this._updateIndicator());\n this._resizeObserver.observe(this._tablistEl);\n }\n\n private _teardown() {\n this._tablistEl?.removeEventListener('click', this._onClick);\n this._tablistEl?.removeEventListener('keydown', this._onKeyDown);\n this._resizeObserver?.disconnect();\n this._resizeObserver = null;\n this._initialized = false;\n }\n\n // --- Tab selection ---\n\n private _selectTab(index: number, emitEvent = true) {\n if (index < 0 || index >= this._tabs.length) return;\n\n for (let i = 0; i < this._tabs.length; i++) {\n const tab = this._tabs[i];\n const panel = this._panels[i];\n const isActive = i === index;\n\n tab.setAttribute('aria-selected', String(isActive));\n tab.setAttribute('tabindex', isActive ? '0' : '-1');\n\n if (panel) {\n panel.hidden = !isActive;\n }\n }\n\n this.value = String(index);\n this._updateIndicator();\n\n if (emitEvent) {\n const name = this._tabs[index]?.getAttribute('name') ?? null;\n this.dispatchEvent(new TabsChangeEvent(index, name));\n }\n }\n\n // --- Indicator ---\n\n private _updateIndicator() {\n if (!this._tablistEl) return;\n const activeTab = this._tabs[Number(this.value)];\n if (!activeTab) return;\n\n const isVertical = this.orientation === 'vertical';\n\n if (isVertical) {\n this._tablistEl.style.setProperty('--_indicator-top', `${activeTab.offsetTop}px`);\n this._tablistEl.style.setProperty('--_indicator-height', `${activeTab.offsetHeight}px`);\n } else {\n this._tablistEl.style.setProperty('--_indicator-left', `${activeTab.offsetLeft}px`);\n this._tablistEl.style.setProperty('--_indicator-width', `${activeTab.offsetWidth}px`);\n }\n }\n\n // --- Event handlers ---\n\n private _onClick = (e: Event) => {\n const tab = (e.target as HTMLElement).closest<HTMLButtonElement>('[role=\"tab\"]');\n if (!tab) return;\n const index = this._tabs.indexOf(tab);\n if (index >= 0) {\n this._selectTab(index);\n tab.focus();\n }\n };\n\n private _onKeyDown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement;\n if (target.getAttribute('role') !== 'tab') return;\n\n const isHorizontal = this.orientation === 'horizontal';\n const prevKey = isHorizontal ? 'ArrowLeft' : 'ArrowUp';\n const nextKey = isHorizontal ? 'ArrowRight' : 'ArrowDown';\n\n let index = this._tabs.indexOf(target as HTMLButtonElement);\n\n switch (e.key) {\n case nextKey:\n e.preventDefault();\n index = (index + 1) % this._tabs.length;\n this._selectTab(index);\n this._tabs[index].focus();\n break;\n case prevKey:\n e.preventDefault();\n index = (index - 1 + this._tabs.length) % this._tabs.length;\n this._selectTab(index);\n this._tabs[index].focus();\n break;\n case 'Home':\n e.preventDefault();\n this._selectTab(0);\n this._tabs[0].focus();\n break;\n case 'End':\n e.preventDefault();\n this._selectTab(this._tabs.length - 1);\n this._tabs[this._tabs.length - 1].focus();\n break;\n }\n };\n}\n\n// Type `addEventListener('change', …)` on this element so the listener receives\n// a `TabsChangeEvent` (with `.index`/`.name`) instead of a bare `Event`, with no\n// cast. This is the canonical reference for the pattern used across the library.\n//\n// Why a same-named interface and not a global augmentation: `change` already\n// exists in lib.dom's `GlobalEventHandlersEventMap` (typed `Event`), and TS\n// forbids re-declaring an existing key with a different type — so colliding\n// names (`change`, `select`, `input`, `toggle`) can't be typed globally. Merging\n// a same-named `interface Tabs` into the `class Tabs` adds these overloads to\n// the element's own type only. (Non-colliding names like `show`/`story-change`\n// ARE augmented globally in their event-class module — no per-element block.)\n//\n// In `(type: K, listener: (ev: TabsEventMap[K]) => void)`, K is pinned to the\n// string literal you pass, and `TabsEventMap[K]` indexes the event type from it\n// (`'change'` → `TabsChangeEvent`). `this: Tabs` is a fake parameter that types\n// `this` inside a non-arrow listener; it emits no runtime code.\n//\n// Three load-bearing details:\n// 1. The `(type: string, …)` fallback overloads are REQUIRED: declaring our\n// own `addEventListener` hides ALL inherited `HTMLElement` overloads, so\n// without them `addEventListener('click', …)` would stop compiling. The\n// typed overload comes first so `'change'` resolves before the fallback.\n// 2. This interface sits AFTER the class: the CEM analyzer dedups on the first\n// declaration of the name, so an interface before the class would shadow it\n// and the manifest would extract nothing for this element.\n// 3. The merge is flagged by `no-unsafe-declaration-merging` (disabled on the\n// class above) — safe here because we merge only method overloads, never\n// uninitialized properties.\nexport interface Tabs {\n addEventListener<K extends keyof TabsEventMap>(\n type: K,\n listener: (this: Tabs, ev: TabsEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ): void;\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void;\n removeEventListener<K extends keyof TabsEventMap>(\n type: K,\n listener: (this: Tabs, ev: TabsEventMap[K]) => void,\n options?: boolean | EventListenerOptions,\n ): void;\n removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ): void;\n}\n"],"mappings":"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"}
|
package/cdn/standalone.css
CHANGED
|
@@ -5626,6 +5626,41 @@ In dark mode, mixes the base color with black (default 15% black).
|
|
|
5626
5626
|
|
|
5627
5627
|
& > :first-child button {
|
|
5628
5628
|
padding: calc(var(--spacing) * 2) calc(var(--spacing) * 3);
|
|
5629
|
+
|
|
5630
|
+
/* `isolation` keeps the pill's negative z-index inside the button: it
|
|
5631
|
+
paints above the button background but under the label, and can never
|
|
5632
|
+
slip behind an ancestor's background (a card wrapping the tabs). */
|
|
5633
|
+
position: relative;
|
|
5634
|
+
isolation: isolate;
|
|
5635
|
+
|
|
5636
|
+
/* Hover pill, detached from the track: inset on the block axis so it
|
|
5637
|
+
never touches the bottom border or the sliding indicator. A 4px inset
|
|
5638
|
+
on a 44px tab leaves a 36px pill — same height as a medium control. */
|
|
5639
|
+
&::after {
|
|
5640
|
+
content: '';
|
|
5641
|
+
position: absolute;
|
|
5642
|
+
z-index: -1;
|
|
5643
|
+
inset-block: var(--hover-inset, calc(var(--spacing) * 1));
|
|
5644
|
+
inset-inline: 0;
|
|
5645
|
+
border-radius: var(--l-radius-md);
|
|
5646
|
+
background: transparent;
|
|
5647
|
+
transition: background-color var(--_duration) var(--_easing);
|
|
5648
|
+
}
|
|
5649
|
+
|
|
5650
|
+
/* Applies to the selected tab too — the fill is click feedback, not a
|
|
5651
|
+
selection cue (the underline carries that), so it would read as dead
|
|
5652
|
+
if the active tab were the one place it stopped responding. */
|
|
5653
|
+
@media (hover: hover) {
|
|
5654
|
+
&:hover::after {
|
|
5655
|
+
background: var(--hover-color, var(--l-color-bg-state-hover));
|
|
5656
|
+
}
|
|
5657
|
+
}
|
|
5658
|
+
}
|
|
5659
|
+
}
|
|
5660
|
+
|
|
5661
|
+
@media (prefers-reduced-motion: reduce) {
|
|
5662
|
+
l-tabs[variant='line'] > :first-child button::after {
|
|
5663
|
+
transition-duration: 0ms;
|
|
5629
5664
|
}
|
|
5630
5665
|
}
|
|
5631
5666
|
}
|
|
@@ -138,6 +138,41 @@
|
|
|
138
138
|
|
|
139
139
|
& > :first-child button {
|
|
140
140
|
padding: calc(var(--spacing) * 2) calc(var(--spacing) * 3);
|
|
141
|
+
|
|
142
|
+
/* `isolation` keeps the pill's negative z-index inside the button: it
|
|
143
|
+
paints above the button background but under the label, and can never
|
|
144
|
+
slip behind an ancestor's background (a card wrapping the tabs). */
|
|
145
|
+
position: relative;
|
|
146
|
+
isolation: isolate;
|
|
147
|
+
|
|
148
|
+
/* Hover pill, detached from the track: inset on the block axis so it
|
|
149
|
+
never touches the bottom border or the sliding indicator. A 4px inset
|
|
150
|
+
on a 44px tab leaves a 36px pill — same height as a medium control. */
|
|
151
|
+
&::after {
|
|
152
|
+
content: '';
|
|
153
|
+
position: absolute;
|
|
154
|
+
z-index: -1;
|
|
155
|
+
inset-block: var(--hover-inset, calc(var(--spacing) * 1));
|
|
156
|
+
inset-inline: 0;
|
|
157
|
+
border-radius: var(--l-radius-md);
|
|
158
|
+
background: transparent;
|
|
159
|
+
transition: background-color var(--_duration) var(--_easing);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* Applies to the selected tab too — the fill is click feedback, not a
|
|
163
|
+
selection cue (the underline carries that), so it would read as dead
|
|
164
|
+
if the active tab were the one place it stopped responding. */
|
|
165
|
+
@media (hover: hover) {
|
|
166
|
+
&:hover::after {
|
|
167
|
+
background: var(--hover-color, var(--l-color-bg-state-hover));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@media (prefers-reduced-motion: reduce) {
|
|
174
|
+
l-tabs[variant='line'] > :first-child button::after {
|
|
175
|
+
transition-duration: 0ms;
|
|
141
176
|
}
|
|
142
177
|
}
|
|
143
178
|
}
|
|
@@ -138,6 +138,41 @@
|
|
|
138
138
|
|
|
139
139
|
& > :first-child button {
|
|
140
140
|
padding: calc(var(--spacing) * 2) calc(var(--spacing) * 3);
|
|
141
|
+
|
|
142
|
+
/* `isolation` keeps the pill's negative z-index inside the button: it
|
|
143
|
+
paints above the button background but under the label, and can never
|
|
144
|
+
slip behind an ancestor's background (a card wrapping the tabs). */
|
|
145
|
+
position: relative;
|
|
146
|
+
isolation: isolate;
|
|
147
|
+
|
|
148
|
+
/* Hover pill, detached from the track: inset on the block axis so it
|
|
149
|
+
never touches the bottom border or the sliding indicator. A 4px inset
|
|
150
|
+
on a 44px tab leaves a 36px pill — same height as a medium control. */
|
|
151
|
+
&::after {
|
|
152
|
+
content: '';
|
|
153
|
+
position: absolute;
|
|
154
|
+
z-index: -1;
|
|
155
|
+
inset-block: var(--hover-inset, calc(var(--spacing) * 1));
|
|
156
|
+
inset-inline: 0;
|
|
157
|
+
border-radius: var(--l-radius-md);
|
|
158
|
+
background: transparent;
|
|
159
|
+
transition: background-color var(--_duration) var(--_easing);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* Applies to the selected tab too — the fill is click feedback, not a
|
|
163
|
+
selection cue (the underline carries that), so it would read as dead
|
|
164
|
+
if the active tab were the one place it stopped responding. */
|
|
165
|
+
@media (hover: hover) {
|
|
166
|
+
&:hover::after {
|
|
167
|
+
background: var(--hover-color, var(--l-color-bg-state-hover));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@media (prefers-reduced-motion: reduce) {
|
|
174
|
+
l-tabs[variant='line'] > :first-child button::after {
|
|
175
|
+
transition-duration: 0ms;
|
|
141
176
|
}
|
|
142
177
|
}
|
|
143
178
|
}
|
|
@@ -172,181 +172,6 @@
|
|
|
172
172
|
}
|
|
173
173
|
]
|
|
174
174
|
},
|
|
175
|
-
{
|
|
176
|
-
"kind": "javascript-module",
|
|
177
|
-
"path": "src/html/elements/avatar/avatar.ts",
|
|
178
|
-
"declarations": [
|
|
179
|
-
{
|
|
180
|
-
"kind": "class",
|
|
181
|
-
"description": "",
|
|
182
|
-
"name": "Avatar",
|
|
183
|
-
"cssProperties": [
|
|
184
|
-
{
|
|
185
|
-
"description": "Box size (any length). Set it inline (e.g. `style=\"--size: 20px\"`) for an arbitrary size beyond the `size` token scale; the font then follows proportionally. The `size` attribute sets it to the matching token.",
|
|
186
|
-
"name": "--size",
|
|
187
|
-
"default": "40px"
|
|
188
|
-
},
|
|
189
|
-
{
|
|
190
|
-
"description": "Background fill color for initials and the default icon.",
|
|
191
|
-
"name": "--color"
|
|
192
|
-
},
|
|
193
|
-
{
|
|
194
|
-
"description": "Initials/icon color over `--color`. Defaults to an auto-derived readable color; set it to enforce a specific brand color (overrides the automatic choice).",
|
|
195
|
-
"name": "--text-color"
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
"description": "Set to `circle` for a fully circular avatar (default is a rounded square).",
|
|
199
|
-
"name": "--appearance"
|
|
200
|
-
}
|
|
201
|
-
],
|
|
202
|
-
"cssParts": [
|
|
203
|
-
{
|
|
204
|
-
"description": "The avatar container that paints `--color`; style it (e.g. `color`) to override the auto-derived text color.",
|
|
205
|
-
"name": "base"
|
|
206
|
-
}
|
|
207
|
-
],
|
|
208
|
-
"members": [
|
|
209
|
-
{
|
|
210
|
-
"kind": "field",
|
|
211
|
-
"name": "src",
|
|
212
|
-
"type": {
|
|
213
|
-
"text": "string"
|
|
214
|
-
},
|
|
215
|
-
"default": "''",
|
|
216
|
-
"description": "Image URL. Falls back to initials (then the default icon) if it fails to load.",
|
|
217
|
-
"attribute": "src"
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
"kind": "field",
|
|
221
|
-
"name": "name",
|
|
222
|
-
"type": {
|
|
223
|
-
"text": "string"
|
|
224
|
-
},
|
|
225
|
-
"default": "''",
|
|
226
|
-
"description": "Name used as the accessible label and to derive the initials fallback.",
|
|
227
|
-
"attribute": "name"
|
|
228
|
-
},
|
|
229
|
-
{
|
|
230
|
-
"kind": "field",
|
|
231
|
-
"name": "size",
|
|
232
|
-
"type": {
|
|
233
|
-
"text": "string"
|
|
234
|
-
},
|
|
235
|
-
"default": "'md'",
|
|
236
|
-
"description": "Avatar size: `xs`, `sm`, `md` (default), `lg`, or `xl`.",
|
|
237
|
-
"attribute": "size",
|
|
238
|
-
"reflects": true
|
|
239
|
-
},
|
|
240
|
-
{
|
|
241
|
-
"kind": "field",
|
|
242
|
-
"name": "badge",
|
|
243
|
-
"type": {
|
|
244
|
-
"text": "number"
|
|
245
|
-
},
|
|
246
|
-
"default": "0",
|
|
247
|
-
"description": "Count shown in the corner badge. `0` hides the badge.",
|
|
248
|
-
"attribute": "badge"
|
|
249
|
-
},
|
|
250
|
-
{
|
|
251
|
-
"kind": "field",
|
|
252
|
-
"name": "interactive",
|
|
253
|
-
"type": {
|
|
254
|
-
"text": "boolean"
|
|
255
|
-
},
|
|
256
|
-
"default": "false",
|
|
257
|
-
"description": "Render as a `<button>` with focus ring and hover states.",
|
|
258
|
-
"attribute": "interactive",
|
|
259
|
-
"reflects": true
|
|
260
|
-
}
|
|
261
|
-
],
|
|
262
|
-
"attributes": [
|
|
263
|
-
{
|
|
264
|
-
"name": "src",
|
|
265
|
-
"type": {
|
|
266
|
-
"text": "string"
|
|
267
|
-
},
|
|
268
|
-
"default": "''",
|
|
269
|
-
"description": "Image URL. Falls back to initials (then the default icon) if it fails to load.",
|
|
270
|
-
"fieldName": "src"
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
"name": "name",
|
|
274
|
-
"type": {
|
|
275
|
-
"text": "string"
|
|
276
|
-
},
|
|
277
|
-
"default": "''",
|
|
278
|
-
"description": "Name used as the accessible label and to derive the initials fallback.",
|
|
279
|
-
"fieldName": "name"
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
"name": "size",
|
|
283
|
-
"type": {
|
|
284
|
-
"text": "string"
|
|
285
|
-
},
|
|
286
|
-
"default": "'md'",
|
|
287
|
-
"description": "Avatar size: `xs`, `sm`, `md` (default), `lg`, or `xl`.",
|
|
288
|
-
"fieldName": "size"
|
|
289
|
-
},
|
|
290
|
-
{
|
|
291
|
-
"name": "badge",
|
|
292
|
-
"type": {
|
|
293
|
-
"text": "number"
|
|
294
|
-
},
|
|
295
|
-
"default": "0",
|
|
296
|
-
"description": "Count shown in the corner badge. `0` hides the badge.",
|
|
297
|
-
"fieldName": "badge"
|
|
298
|
-
},
|
|
299
|
-
{
|
|
300
|
-
"name": "interactive",
|
|
301
|
-
"type": {
|
|
302
|
-
"text": "boolean"
|
|
303
|
-
},
|
|
304
|
-
"default": "false",
|
|
305
|
-
"description": "Render as a `<button>` with focus ring and hover states.",
|
|
306
|
-
"fieldName": "interactive"
|
|
307
|
-
}
|
|
308
|
-
],
|
|
309
|
-
"superclass": {
|
|
310
|
-
"name": "LuxenElement",
|
|
311
|
-
"module": "/src/html/shared/luxen-element.js"
|
|
312
|
-
},
|
|
313
|
-
"tagName": "l-avatar",
|
|
314
|
-
"customElement": true,
|
|
315
|
-
"summary": "An avatar component for displaying user images, initials, or a default icon.",
|
|
316
|
-
"_cssClasses": [
|
|
317
|
-
{
|
|
318
|
-
"name": ".l-avatar-group",
|
|
319
|
-
"description": "Flex wrapper that overlaps a row of stacked avatars."
|
|
320
|
-
}
|
|
321
|
-
]
|
|
322
|
-
}
|
|
323
|
-
],
|
|
324
|
-
"exports": [
|
|
325
|
-
{
|
|
326
|
-
"kind": "js",
|
|
327
|
-
"name": "Avatar",
|
|
328
|
-
"declaration": {
|
|
329
|
-
"name": "Avatar",
|
|
330
|
-
"module": "src/html/elements/avatar/avatar.ts"
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
]
|
|
334
|
-
},
|
|
335
|
-
{
|
|
336
|
-
"kind": "javascript-module",
|
|
337
|
-
"path": "src/html/elements/avatar/index.ts",
|
|
338
|
-
"declarations": [],
|
|
339
|
-
"exports": [
|
|
340
|
-
{
|
|
341
|
-
"kind": "js",
|
|
342
|
-
"name": "*",
|
|
343
|
-
"declaration": {
|
|
344
|
-
"name": "*",
|
|
345
|
-
"module": "src/html/elements/avatar/avatar.js"
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
]
|
|
349
|
-
},
|
|
350
175
|
{
|
|
351
176
|
"kind": "javascript-module",
|
|
352
177
|
"path": "src/html/elements/alert-dialog/alert-dialog.ts",
|
|
@@ -827,6 +652,181 @@
|
|
|
827
652
|
}
|
|
828
653
|
]
|
|
829
654
|
},
|
|
655
|
+
{
|
|
656
|
+
"kind": "javascript-module",
|
|
657
|
+
"path": "src/html/elements/avatar/avatar.ts",
|
|
658
|
+
"declarations": [
|
|
659
|
+
{
|
|
660
|
+
"kind": "class",
|
|
661
|
+
"description": "",
|
|
662
|
+
"name": "Avatar",
|
|
663
|
+
"cssProperties": [
|
|
664
|
+
{
|
|
665
|
+
"description": "Box size (any length). Set it inline (e.g. `style=\"--size: 20px\"`) for an arbitrary size beyond the `size` token scale; the font then follows proportionally. The `size` attribute sets it to the matching token.",
|
|
666
|
+
"name": "--size",
|
|
667
|
+
"default": "40px"
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
"description": "Background fill color for initials and the default icon.",
|
|
671
|
+
"name": "--color"
|
|
672
|
+
},
|
|
673
|
+
{
|
|
674
|
+
"description": "Initials/icon color over `--color`. Defaults to an auto-derived readable color; set it to enforce a specific brand color (overrides the automatic choice).",
|
|
675
|
+
"name": "--text-color"
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
"description": "Set to `circle` for a fully circular avatar (default is a rounded square).",
|
|
679
|
+
"name": "--appearance"
|
|
680
|
+
}
|
|
681
|
+
],
|
|
682
|
+
"cssParts": [
|
|
683
|
+
{
|
|
684
|
+
"description": "The avatar container that paints `--color`; style it (e.g. `color`) to override the auto-derived text color.",
|
|
685
|
+
"name": "base"
|
|
686
|
+
}
|
|
687
|
+
],
|
|
688
|
+
"members": [
|
|
689
|
+
{
|
|
690
|
+
"kind": "field",
|
|
691
|
+
"name": "src",
|
|
692
|
+
"type": {
|
|
693
|
+
"text": "string"
|
|
694
|
+
},
|
|
695
|
+
"default": "''",
|
|
696
|
+
"description": "Image URL. Falls back to initials (then the default icon) if it fails to load.",
|
|
697
|
+
"attribute": "src"
|
|
698
|
+
},
|
|
699
|
+
{
|
|
700
|
+
"kind": "field",
|
|
701
|
+
"name": "name",
|
|
702
|
+
"type": {
|
|
703
|
+
"text": "string"
|
|
704
|
+
},
|
|
705
|
+
"default": "''",
|
|
706
|
+
"description": "Name used as the accessible label and to derive the initials fallback.",
|
|
707
|
+
"attribute": "name"
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
"kind": "field",
|
|
711
|
+
"name": "size",
|
|
712
|
+
"type": {
|
|
713
|
+
"text": "string"
|
|
714
|
+
},
|
|
715
|
+
"default": "'md'",
|
|
716
|
+
"description": "Avatar size: `xs`, `sm`, `md` (default), `lg`, or `xl`.",
|
|
717
|
+
"attribute": "size",
|
|
718
|
+
"reflects": true
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
"kind": "field",
|
|
722
|
+
"name": "badge",
|
|
723
|
+
"type": {
|
|
724
|
+
"text": "number"
|
|
725
|
+
},
|
|
726
|
+
"default": "0",
|
|
727
|
+
"description": "Count shown in the corner badge. `0` hides the badge.",
|
|
728
|
+
"attribute": "badge"
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
"kind": "field",
|
|
732
|
+
"name": "interactive",
|
|
733
|
+
"type": {
|
|
734
|
+
"text": "boolean"
|
|
735
|
+
},
|
|
736
|
+
"default": "false",
|
|
737
|
+
"description": "Render as a `<button>` with focus ring and hover states.",
|
|
738
|
+
"attribute": "interactive",
|
|
739
|
+
"reflects": true
|
|
740
|
+
}
|
|
741
|
+
],
|
|
742
|
+
"attributes": [
|
|
743
|
+
{
|
|
744
|
+
"name": "src",
|
|
745
|
+
"type": {
|
|
746
|
+
"text": "string"
|
|
747
|
+
},
|
|
748
|
+
"default": "''",
|
|
749
|
+
"description": "Image URL. Falls back to initials (then the default icon) if it fails to load.",
|
|
750
|
+
"fieldName": "src"
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
"name": "name",
|
|
754
|
+
"type": {
|
|
755
|
+
"text": "string"
|
|
756
|
+
},
|
|
757
|
+
"default": "''",
|
|
758
|
+
"description": "Name used as the accessible label and to derive the initials fallback.",
|
|
759
|
+
"fieldName": "name"
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
"name": "size",
|
|
763
|
+
"type": {
|
|
764
|
+
"text": "string"
|
|
765
|
+
},
|
|
766
|
+
"default": "'md'",
|
|
767
|
+
"description": "Avatar size: `xs`, `sm`, `md` (default), `lg`, or `xl`.",
|
|
768
|
+
"fieldName": "size"
|
|
769
|
+
},
|
|
770
|
+
{
|
|
771
|
+
"name": "badge",
|
|
772
|
+
"type": {
|
|
773
|
+
"text": "number"
|
|
774
|
+
},
|
|
775
|
+
"default": "0",
|
|
776
|
+
"description": "Count shown in the corner badge. `0` hides the badge.",
|
|
777
|
+
"fieldName": "badge"
|
|
778
|
+
},
|
|
779
|
+
{
|
|
780
|
+
"name": "interactive",
|
|
781
|
+
"type": {
|
|
782
|
+
"text": "boolean"
|
|
783
|
+
},
|
|
784
|
+
"default": "false",
|
|
785
|
+
"description": "Render as a `<button>` with focus ring and hover states.",
|
|
786
|
+
"fieldName": "interactive"
|
|
787
|
+
}
|
|
788
|
+
],
|
|
789
|
+
"superclass": {
|
|
790
|
+
"name": "LuxenElement",
|
|
791
|
+
"module": "/src/html/shared/luxen-element.js"
|
|
792
|
+
},
|
|
793
|
+
"tagName": "l-avatar",
|
|
794
|
+
"customElement": true,
|
|
795
|
+
"summary": "An avatar component for displaying user images, initials, or a default icon.",
|
|
796
|
+
"_cssClasses": [
|
|
797
|
+
{
|
|
798
|
+
"name": ".l-avatar-group",
|
|
799
|
+
"description": "Flex wrapper that overlaps a row of stacked avatars."
|
|
800
|
+
}
|
|
801
|
+
]
|
|
802
|
+
}
|
|
803
|
+
],
|
|
804
|
+
"exports": [
|
|
805
|
+
{
|
|
806
|
+
"kind": "js",
|
|
807
|
+
"name": "Avatar",
|
|
808
|
+
"declaration": {
|
|
809
|
+
"name": "Avatar",
|
|
810
|
+
"module": "src/html/elements/avatar/avatar.ts"
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
]
|
|
814
|
+
},
|
|
815
|
+
{
|
|
816
|
+
"kind": "javascript-module",
|
|
817
|
+
"path": "src/html/elements/avatar/index.ts",
|
|
818
|
+
"declarations": [],
|
|
819
|
+
"exports": [
|
|
820
|
+
{
|
|
821
|
+
"kind": "js",
|
|
822
|
+
"name": "*",
|
|
823
|
+
"declaration": {
|
|
824
|
+
"name": "*",
|
|
825
|
+
"module": "src/html/elements/avatar/avatar.js"
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
]
|
|
829
|
+
},
|
|
830
830
|
{
|
|
831
831
|
"kind": "javascript-module",
|
|
832
832
|
"path": "src/html/elements/badge/badge.ts",
|
|
@@ -8573,6 +8573,16 @@
|
|
|
8573
8573
|
"description": "`line` variant: thickness of the static bottom border.",
|
|
8574
8574
|
"name": "--track-thickness",
|
|
8575
8575
|
"default": "1px"
|
|
8576
|
+
},
|
|
8577
|
+
{
|
|
8578
|
+
"description": "`line` variant: fill of the pill that appears behind a hovered tab label.",
|
|
8579
|
+
"name": "--hover-color",
|
|
8580
|
+
"default": "var(--l-color-bg-state-hover)"
|
|
8581
|
+
},
|
|
8582
|
+
{
|
|
8583
|
+
"description": "`line` variant: block-axis gap between the hover pill and the tab edges, keeping it detached from the bottom border.",
|
|
8584
|
+
"name": "--hover-inset",
|
|
8585
|
+
"default": "4px"
|
|
8576
8586
|
}
|
|
8577
8587
|
],
|
|
8578
8588
|
"members": [
|
|
@@ -107,7 +107,22 @@ export declare class Dropdown extends LuxenElement {
|
|
|
107
107
|
private _onPanelPointerOut;
|
|
108
108
|
private _selectCurrentItem;
|
|
109
109
|
private _selectItem;
|
|
110
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* Route `popover="auto"` light-dismiss through the same close path as every
|
|
112
|
+
* other user-driven close (trigger click, Escape, item selection), so the
|
|
113
|
+
* cancelable `hide` event fires for it too. Assigning `open` here directly
|
|
114
|
+
* would skip it and desync anything a consumer syncs on `hide`.
|
|
115
|
+
*
|
|
116
|
+
* Driving `open` as a property or attribute still closes the menu with only
|
|
117
|
+
* `after-hide` — `l-dialog` mediates that path from `updated()`, this element
|
|
118
|
+
* does not. A gap worth closing on its own.
|
|
119
|
+
*
|
|
120
|
+
* The platform makes a popover's close non-cancelable (`beforetoggle` is only
|
|
121
|
+
* cancelable when opening), so a vetoed `hide` is honored by putting the panel
|
|
122
|
+
* back. `toggle` is the right hook for that: it is queued after the hide has
|
|
123
|
+
* actually been applied, whereas during `beforetoggle` the panel is still
|
|
124
|
+
* `:popover-open` and `showPopover()` would be a no-op the pending hide undoes.
|
|
125
|
+
*/
|
|
111
126
|
private _onToggle;
|
|
112
127
|
render(): import("lit").TemplateResult<1>;
|
|
113
128
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown.d.ts","sourceRoot":"","sources":["../../../src/html/elements/dropdown/dropdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAOtE,qEAAqE;AACrE,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;gBAChB,IAAI,EAAE,YAAY;CAI/B;AAED,UAAU,gBAAgB;IACxB,MAAM,EAAE,mBAAmB,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,qBAAa,QAAS,SAAQ,YAAY;IACxC,OAAgB,MAAM,4BAAwB;IAE9C,OAAO,CAAC,SAAS,CAId;IAEH,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,iBAAiB,CAAK;IAE9B,oCAAoC;IAEpC,QAAQ,CAAC,IAAI,UAAS;IAEtB,wCAAwC;IAExC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAkB;IAE/C,2CAA2C;IAE3C,QAAQ,CAAC,QAAQ,SAAK;IAEtB,qCAAqC;IAErC,QAAQ,CAAC,QAAQ,UAAS;IAE1B;;;;;;OAMG;IAEH,QAAQ,CAAC,QAAQ,EAAE,SAAS,GAAG,SAAS,CAAC;IAEzC,OAAO,KAAK,UAAU,GAGrB;IAED,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,YAAY;IAQpB,mFAAmF;IACnF,OAAO,CAAC,gBAAgB;IAIxB,6FAA6F;IAC7F,OAAO,CAAC,aAAa;IAQrB,gFAAgF;IAChF,OAAO,CAAC,aAAa;IAQrB,0FAA0F;IAC1F,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,YAAY;IAOpB,IAAI;IAKJ,IAAI;IAKJ,MAAM;IAOG,oBAAoB;IAMpB,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC;YAQhC,iBAAiB;IA8B/B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,UAAU,CAA6B;YAEjC,YAAY;IAsB1B,OAAO,CAAC,iBAAiB;IAMzB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IA4BtB,OAAO,CAAC,cAAc;IAqBtB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,gBAAgB;IAgBxB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB,CAW1B;IAEF,OAAO,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"dropdown.d.ts","sourceRoot":"","sources":["../../../src/html/elements/dropdown/dropdown.ts"],"names":[],"mappings":"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"}
|