@ds-mo/ui 2.4.1 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.build-stamp +1 -1
- package/dist/components/ds-app-shell.js +1 -1
- package/dist/components/ds-app-shell.js.map +1 -1
- package/dist/components/ds-bar-nav.js +1 -1
- package/dist/components/ds-bar-nav.js.map +1 -1
- package/dist/components/ds-menu.js +1 -1
- package/dist/components/ds-select.js +1 -1
- package/dist/components/ds-select.js.map +1 -1
- package/dist/components/ds-shell-gradient-picker.d.ts +11 -0
- package/dist/components/ds-shell-gradient-picker.js +2 -0
- package/dist/components/ds-shell-gradient-picker.js.map +1 -0
- package/dist/components/ds-shell-gradient-swatch.d.ts +11 -0
- package/dist/components/ds-shell-gradient-swatch.js +2 -0
- package/dist/components/ds-shell-gradient-swatch.js.map +1 -0
- package/dist/components/ds-slider.js +1 -1
- package/dist/components/ds-toggle.js +1 -1
- package/dist/components/p-BU5fKLdO.js +2 -0
- package/dist/components/p-BU5fKLdO.js.map +1 -0
- package/dist/components/p-BgiK3sHs.js +2 -0
- package/dist/components/p-BgiK3sHs.js.map +1 -0
- package/dist/components/p-CLmK4lRE.js +2 -0
- package/dist/components/p-CLmK4lRE.js.map +1 -0
- package/dist/components/p-DKG6W4pb.js +2 -0
- package/dist/components/p-DKG6W4pb.js.map +1 -0
- package/dist/types/components/AppShell/AppShell.d.ts +6 -0
- package/dist/types/components/Menu/Menu.d.ts +4 -0
- package/dist/types/components/Menu/menu-types.d.ts +10 -1
- package/dist/types/components/ShellGradientPicker/ShellGradientPicker.d.ts +10 -0
- package/dist/types/components/ShellGradientSwatch/ShellGradientSwatch.d.ts +14 -0
- package/dist/types/components/ShellGradientSwatch/shell-gradient-swatch-types.d.ts +4 -0
- package/dist/types/components.d.ts +127 -0
- package/dist/types/nav/index.d.ts +2 -0
- package/dist/types/nav/shell-gradient-presets.d.ts +11 -0
- package/dist/types/nav/shell-gradient.d.ts +7 -4
- package/package.json +2 -2
- package/src/angular/index.ts +2 -0
- package/src/angular/proxies.ts +69 -3
- package/src/react/components.ts +2 -0
- package/src/react/ds-menu.ts +5 -3
- package/src/react/ds-shell-gradient-picker.ts +27 -0
- package/src/react/ds-shell-gradient-swatch.ts +27 -0
- package/src/wc/components/AppShell/AppShell.tsx +13 -1
- package/src/wc/components/BarNav/bar-nav-tabs-menu-utils.ts +2 -2
- package/src/wc/components/Menu/Menu.tsx +27 -4
- package/src/wc/components/Menu/menu-types.ts +19 -1
- package/src/wc/components/ShellGradientPicker/ShellGradientPicker.tsx +49 -0
- package/src/wc/components/ShellGradientSwatch/ShellGradientSwatch.tsx +53 -0
- package/src/wc/components/ShellGradientSwatch/shell-gradient-swatch-types.ts +16 -0
- package/src/wc/components.d.ts +127 -0
- package/src/wc/nav/index.ts +9 -0
- package/src/wc/nav/shell-gradient-presets.ts +35 -0
- package/src/wc/nav/shell-gradient.ts +26 -8
- package/dist/components/p-YzIqPOqL.js +0 -2
- package/dist/components/p-YzIqPOqL.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["queryWithinComponentHost","host","selector","root","shadowRoot","querySelector","getTabListFromTabGroup","tabGroupEl","tabsToMenuSections","tabs","selectedId","sections","batch","item","isTabDivider","length","push","items","label","value","id","isSelected","isInactive","disabled","tabsToOverflowMenuSections","trimLeadingDividers","tabsOverflowContainer","tabListScrollWidth","containerClientWidth","collapsed","hysteresis","diff","visibleTabCountForWidth","itemWidths","availableWidth","overflowTriggerWidth","itemGap","listExtraWidth","fullWidth","widthForItemCount","availableForTabs","Math","max","count","i","width","trimTrailingDividers","end","slice","start","itemsWidth","reduce","sum","barNavCss","BarNav","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","navStyle","tabsJson","basePath","currentUrl","resolvedTabs","urlDerivedValue","hideTabsForDetailRoute","tabsCollapsed","menuOpen","tabLayoutCommitted","visibleTabs","overflowTabs","menuInitialFocusVisible","overflowRovingFocused","headerEl","triggerEl","menuEl","visibleTabGroupEl","probeTabGroupEl","resizeObserver","intrinsicWidthRetryCount","tabLayoutPendingFrames","panelNavTransition","ChromeTransitionDepth","panelToolsTransition","overflowCoalescer","createRafCoalescer","updateTabsCollapsed","chromeTransitionShell","committedSection","pendingSection","onChromeTransitionStart","event","source","readChromeTransitionSource","enter","phase","readChromeTransitionPhase","onChromeTransitionEnd","exit","isActive","scheduleOverflowCheck","handleOverflowFocus","handleOverflowBlur","effectiveValue","hasOverflowTabs","digestTabsConfig","map","t","join","resetTabOverflowLayout","onHostPropsChange","applyHostProps","onSelectionChange","syncMenuSections","onMenuOpenChange","open","onTabsCollapsedChange","prevCollapsed","requestAnimationFrame","undefined","queueMicrotask","focusVisibleSelectedTab","componentWillLoad","componentDidLoad","syncHostPropsIfNeeded","scheduleDeferredHostPropSync","setupOverflowObserver","bindChromeTransitionListeners","componentDidRender","chromeOverflowPaused","syncMenuAnchor","disconnectedCallback","disconnect","cancel","unbindChromeTransitionListeners","shell","el","closest","addEventListener","CHROME_TRANSITION_START","CHROME_TRANSITION_END","removeEventListener","shouldResyncBarNavProps","syncValueFromUrl","remaining","HOST_PROP_SYNC_BUDGET","tick","ResizeObserver","observe","schedule","getLeftZoneAvailableWidth","headerStyle","getComputedStyle","horizontalPadding","parseFloat","paddingLeft","paddingRight","clientWidth","getTabsIntrinsicWidth","tabList","scrollWidth","getHeaderGap","style","columnGap","gap","getOverflowTriggerReserveWidth","getBoundingClientRect","getProbeTabMetrics","children","Array","from","child","some","childrenWidth","gapWidth","setOverflowTabLayout","nextCollapsed","visibleChanged","overflowChanged","scheduleIntrinsicWidthRetry","INTRINSIC_WIDTH_RETRY_MAX","forceTabLayoutCommit","fallbackCollapsed","metrics","intrinsicWidth","TAB_LAYOUT_COMMIT_MAX_FRAMES","shouldCollapse","OVERFLOW_HYSTERESIS_PX","visibleCount","anchor","handleMenuSelect","e","detail","selectTab","String","handleMenuClose","incomingTabs","parseJsonArrayProp","nextBasePath","sectionChanged","startsWith","tabsConfigChanged","hideTabs","deriveBarNavValueFromUrl","dsTabChange","emit","tab","focus","preventScroll","handleTabChange","toggleTabMenu","options","minWidth","focusVisible","handleTabRovingExit","setFocus","handleTriggerKeyDown","key","preventDefault","focusLastTab","render","sectionReady","hasTabs","tabGroupKey","renderedTabs","h","Host","class","ref","inert","next","selectionFollowsFocus","rovingEnabled","onDsChange","onDsRovingExit","onFocusin","heading","icon","activeFill","focusTabIndex","haspopup","expanded","onDsClick","onFocusout","onKeyDown","side","align","sideOffset","alignOffset","initialFocusVisible","onDsSelect","onDsClose"],"sources":["src/wc/components/BarNav/bar-nav-dom-utils.ts","src/wc/components/BarNav/bar-nav-tabs-menu-utils.ts","src/wc/components/BarNav/BarNav.css?tag=ds-bar-nav&encapsulation=scoped","src/wc/components/BarNav/BarNav.tsx"],"sourcesContent":["export type QueryableHost = {\n shadowRoot?: ShadowRoot | null;\n querySelector: (selectors: string) => Element | null;\n};\n\n/**\n * Query within a Stencil custom-element host (light DOM today, shadow DOM–safe).\n * Use for child nodes owned by ds-tab-group and similar components.\n */\nexport function queryWithinComponentHost(\n host: QueryableHost | null | undefined,\n selector: string,\n): HTMLElement | null {\n if (!host) return null;\n const root = host.shadowRoot ?? host;\n return root.querySelector(selector) as HTMLElement | null;\n}\n\nexport function getTabListFromTabGroup(\n tabGroupEl: QueryableHost | null | undefined,\n): HTMLElement | null {\n return queryWithinComponentHost(tabGroupEl, '[role=\"tablist\"]');\n}\n","import type { MenuSection } from '../Menu/menu-types';\nimport {\n getSelectableTabs,\n isTabDivider,\n type TabItem,\n type TabItemTab,\n} from '../TabGroup/tab-item-utils';\n\n/** Map BarNav tabs to menu sections, preserving `{ type: 'divider' }` as section breaks. */\nexport function tabsToMenuSections(tabs: TabItem[], selectedId: string): MenuSection[] {\n const sections: MenuSection[] = [];\n let batch: MenuSection['items'] = [];\n\n for (const item of tabs) {\n if (isTabDivider(item)) {\n if (batch.length > 0) {\n sections.push({ items: batch });\n batch = [];\n }\n continue;\n }\n\n batch.push({\n label: item.label,\n value: item.id,\n isSelected: item.id === selectedId,\n isInactive: item.disabled,\n });\n }\n\n if (batch.length > 0) {\n sections.push({ items: batch });\n }\n\n return sections;\n}\n\nexport function tabsToOverflowMenuSections(tabs: TabItem[], selectedId: string): MenuSection[] {\n return tabsToMenuSections(trimLeadingDividers(tabs), selectedId);\n}\n\nexport function getActiveTab(tabs: TabItem[], selectedId: string): TabItemTab | undefined {\n const selectable = getSelectableTabs(tabs);\n return selectable.find(tab => tab.id === selectedId) ?? selectable[0];\n}\n\nexport function getActiveTabLabel(tabs: TabItem[], selectedId: string): string {\n return getActiveTab(tabs, selectedId)?.label ?? 'Tabs';\n}\n\n/** True when tablist content exceeds the available width (with optional hysteresis). */\nexport function tabsOverflowContainer(\n tabListScrollWidth: number,\n containerClientWidth: number,\n collapsed: boolean,\n hysteresis = 2,\n): boolean {\n const diff = tabListScrollWidth - containerClientWidth;\n if (collapsed) {\n return diff > -hysteresis;\n }\n return diff > hysteresis;\n}\n\nexport function visibleTabCountForWidth(\n itemWidths: number[],\n availableWidth: number,\n overflowTriggerWidth: number,\n itemGap: number,\n listExtraWidth: number,\n): number {\n if (itemWidths.length === 0 || availableWidth <= 0) return 0;\n\n const fullWidth = widthForItemCount(itemWidths, itemWidths.length, itemGap, listExtraWidth);\n if (fullWidth <= availableWidth) return itemWidths.length;\n\n const availableForTabs = Math.max(0, availableWidth - overflowTriggerWidth);\n let count = 0;\n\n for (let i = 1; i <= itemWidths.length; i++) {\n const width = widthForItemCount(itemWidths, i, itemGap, listExtraWidth);\n if (width > availableForTabs) break;\n count = i;\n }\n\n return count;\n}\n\nexport function trimTrailingDividers(tabs: TabItem[]): TabItem[] {\n let end = tabs.length;\n while (end > 0 && isTabDivider(tabs[end - 1])) {\n end -= 1;\n }\n return tabs.slice(0, end);\n}\n\nfunction trimLeadingDividers(tabs: TabItem[]): TabItem[] {\n let start = 0;\n while (start < tabs.length && isTabDivider(tabs[start])) {\n start += 1;\n }\n return tabs.slice(start);\n}\n\nfunction widthForItemCount(\n itemWidths: number[],\n count: number,\n itemGap: number,\n listExtraWidth: number,\n): number {\n if (count <= 0) return 0;\n const itemsWidth = itemWidths.slice(0, count).reduce((sum, width) => sum + width, 0);\n return listExtraWidth + itemsWidth + itemGap * Math.max(0, count - 1);\n}\n","@import '../../utils/focus-ring.css';\n\n:host {\n display: block;\n}\n\n.bar-nav {\n display: flex;\n align-items: center;\n position: relative;\n height: var(--dimension-size-600);\n padding: var(--dimension-space-100);\n gap: var(--dimension-space-100);\n box-sizing: border-box;\n border-bottom: var(--dimension-stroke-width-012) solid var(--_bar-nav-border);\n background-color: var(--_bar-nav-bg);\n color: var(--_bar-nav-fg-primary);\n -webkit-user-select: none;\n user-select: none;\n overflow: hidden;\n transition:\n background-color var(--effect-motion-short-3),\n border-color var(--effect-motion-short-3),\n color var(--effect-motion-short-3);\n isolation: isolate;\n /* Default chrome — app surfaces */\n --_bar-nav-bg: var(--color-background-secondary);\n --_bar-nav-border: var(--color-border-tertiary);\n --_bar-nav-fg-primary: var(--color-foreground-primary);\n --_bar-nav-fg-secondary: var(--color-foreground-secondary);\n --_bar-nav-hover: var(--color-interaction-hover);\n --_bar-nav-pressed: var(--color-interaction-pressed);\n --_bar-nav-focus: var(--color-interaction-focus);\n --_bar-nav-dot: var(--color-foreground-bold-brand);\n --ds-focus-ring-color: var(--_bar-nav-focus);\n}\n\n/* Style slots — same app tokens for now; hook texture/glyph layers later. */\n.bar-nav--dashboard,\n.bar-nav--settings {\n --_bar-nav-bg: var(--color-background-secondary);\n --_bar-nav-border: var(--color-border-tertiary);\n --_bar-nav-fg-primary: var(--color-foreground-primary);\n --_bar-nav-fg-secondary: var(--color-foreground-secondary);\n --_bar-nav-hover: var(--color-interaction-hover);\n --_bar-nav-pressed: var(--color-interaction-pressed);\n --_bar-nav-focus: var(--color-interaction-focus);\n --_bar-nav-dot: var(--color-foreground-bold-brand);\n}\n\n/* Shell-owned chrome (bg + wash + grid) — bar is a transparent frame. */\n:host-context(ds-app-shell[gradient]) .bar-nav,\n:host-context(ds-app-shell[grid]) .bar-nav {\n background-color: transparent;\n}\n\n.bar-nav > :not(.bar-nav__tabs-probe) {\n position: relative;\n z-index: 3;\n}\n\n/* Overflow — keep fitting tabs visible and pin the overflow trigger to the far edge. */\n.bar-nav--tabs-collapsed {\n display: flex;\n gap: var(--dimension-space-100);\n align-items: center;\n}\n\n/* Expanded tabs — consume full header width */\n.bar-nav__left {\n position: relative;\n flex: 1 1 0%;\n min-width: 0;\n width: 0;\n display: flex;\n align-items: center;\n}\n\n.bar-nav__left ds-tab-group-nav {\n flex: 1;\n min-width: 0;\n}\n\n/* Unconstrained width so intrinsic tab row width is measurable while collapsed */\n.bar-nav__tabs-probe {\n position: absolute;\n left: 0;\n top: 0;\n visibility: hidden;\n pointer-events: none;\n overflow: visible;\n width: max-content;\n max-width: none;\n z-index: -1;\n}\n\n.bar-nav__tabs-probe ds-tab-group-nav {\n width: max-content;\n}\n\n.bar-nav__tabs-visible {\n width: 100%;\n min-width: 0;\n}\n\n/* In-flow placeholder while measuring overflow — avoids layout jump; hidden from view/accessibility. */\n.bar-nav__tabs-pending {\n flex: 1;\n min-width: 0;\n height: var(--dimension-size-400);\n visibility: hidden;\n pointer-events: none;\n}\n\n/* Overflow trigger — compact icon button aligned to the right edge. */\n.bar-nav__overflow-trigger {\n margin-left: auto;\n --ds-button-unfilled-icon-fg: var(--_bar-nav-fg-secondary);\n --ds-button-unfilled-icon-fg-active: var(--_bar-nav-fg-primary);\n --ds-button-unfilled-icon-hover-bg: var(--_bar-nav-hover);\n --ds-button-unfilled-icon-pressed-bg: var(--_bar-nav-pressed);\n --ds-focus-ring-color: var(--_bar-nav-focus);\n}\n\n/* Fallback heading when no tabs — matches a single (selected) tab so the area\n name shares the tab label's type token, color, height and horizontal inset.\n Inset = tab button padding (space-075, 6px) + label inset (space-025, 2px). */\n.bar-nav__heading {\n display: inline-flex;\n align-items: center;\n height: var(--dimension-size-400);\n padding-inline: var(--dimension-space-100);\n color: var(--_bar-nav-fg-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n -webkit-user-select: none;\n user-select: none;\n}\n","import {\n Component,\n Prop,\n Event,\n EventEmitter,\n Element,\n Watch,\n State,\n h,\n Host,\n} from '@stencil/core';\nimport type { NavChromeStyle } from '../../nav/nav-chrome';\nimport type { MenuItemData } from '../Menu/menu-types';\nimport { isTabDivider } from '../TabGroup/tab-item-utils';\nimport type { BarNavTab } from './bar-nav-types';\nimport {\n deriveBarNavValueFromUrl,\n parseJsonArrayProp,\n shouldResyncBarNavProps,\n} from './bar-nav-utils';\nimport {\n getTabListFromTabGroup,\n queryWithinComponentHost,\n type QueryableHost,\n} from './bar-nav-dom-utils';\nimport {\n tabsOverflowContainer,\n tabsToOverflowMenuSections,\n trimTrailingDividers,\n visibleTabCountForWidth,\n} from './bar-nav-tabs-menu-utils';\nimport {\n CHROME_TRANSITION_END,\n CHROME_TRANSITION_START,\n ChromeTransitionDepth,\n createRafCoalescer,\n readChromeTransitionSource,\n readChromeTransitionPhase,\n} from '../../nav/chrome-transition';\n\n@Component({\n tag: 'ds-bar-nav',\n styleUrl: 'BarNav.css',\n scoped: true,\n})\nexport class BarNav {\n /** Style slot: `dashboard` or `settings`. Colors match for now. */\n @Prop({ attribute: 'nav-style', reflect: true }) navStyle: NavChromeStyle = 'dashboard';\n\n @Element() el!: HTMLElement;\n\n /**\n * Tab items for the left section.\n * Set via JS property: `el.tabs = [...]`. Replace the array reference to update.\n */\n @Prop() tabs: BarNavTab[] = [];\n\n /** JSON fallback for `tabs` — useful when framework bindings don't propagate arrays. */\n @Prop({ attribute: 'tabs-json' }) tabsJson: string = '';\n\n /** ID of the currently active tab. Overridden when `currentUrl` + `basePath` are set. */\n @Prop({ mutable: true }) value: string = '';\n\n /**\n * Fallback heading shown when no tabs are provided.\n * When tabs are present the heading is hidden.\n */\n @Prop() heading: string | undefined;\n\n /** Section base path (e.g. `/dashboard/safety`). Used with `currentUrl` to derive `value`. */\n @Prop() basePath: string = '';\n\n /** Current route URL. When set with `basePath`, the active tab is derived automatically. */\n @Prop() currentUrl: string = '';\n\n /** Emitted when the active tab changes. Detail = tab id. */\n @Event() dsTabChange!: EventEmitter<string>;\n\n @State() private resolvedTabs: BarNavTab[] = [];\n @State() private urlDerivedValue: string = '';\n @State() private hideTabsForDetailRoute = false;\n @State() private tabsCollapsed = false;\n @State() private menuOpen = false;\n /** When false, defer showing expanded tabs or the collapsed trigger until intrinsic width is measured (avoids a one-frame flash of the full tab row on narrow viewports). */\n @State() private tabLayoutCommitted = false;\n @State() private visibleTabs: BarNavTab[] = [];\n @State() private overflowTabs: BarNavTab[] = [];\n @State() private menuInitialFocusVisible = false;\n @State() private overflowRovingFocused = false;\n\n private static readonly HOST_PROP_SYNC_BUDGET = 8;\n private static readonly INTRINSIC_WIDTH_RETRY_MAX = 3;\n private static readonly TAB_LAYOUT_COMMIT_MAX_FRAMES = 16;\n private static readonly OVERFLOW_HYSTERESIS_PX = 8;\n\n private headerEl: HTMLElement | null = null;\n private triggerEl: (HTMLElement & { setFocus?: () => Promise<void> }) | null = null;\n private menuEl: HTMLDsMenuElement | null = null;\n private visibleTabGroupEl: HTMLDsTabGroupNavElement | null = null;\n private probeTabGroupEl: QueryableHost | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private intrinsicWidthRetryCount = 0;\n private tabLayoutPendingFrames = 0;\n private readonly panelNavTransition = new ChromeTransitionDepth();\n private readonly panelToolsTransition = new ChromeTransitionDepth();\n private readonly overflowCoalescer = createRafCoalescer(() => {\n this.updateTabsCollapsed();\n });\n private chromeTransitionShell: HTMLElement | null = null;\n /** Matches `basePath` once tabs + URL are reconciled for the active section. */\n @State() private committedSection = '';\n /** Section waiting for URL + tabs to catch up after a cross-area navigation. */\n @State() private pendingSection = '';\n\n private get effectiveValue(): string {\n if (this.currentUrl && this.basePath) {\n return this.urlDerivedValue;\n }\n return this.value;\n }\n\n private get hasOverflowTabs(): boolean {\n return this.tabLayoutCommitted && this.tabsCollapsed && this.overflowTabs.length > 0;\n }\n\n private digestTabsConfig(tabs: BarNavTab[]): string {\n return tabs.map(t => (isTabDivider(t) ? '|' : t.id)).join(',');\n }\n\n private resetTabOverflowLayout() {\n this.tabLayoutCommitted = false;\n this.tabsCollapsed = false;\n this.menuOpen = false;\n this.menuInitialFocusVisible = false;\n this.intrinsicWidthRetryCount = 0;\n this.tabLayoutPendingFrames = 0;\n this.visibleTabs = [];\n this.overflowTabs = [];\n }\n\n @Watch('tabs')\n @Watch('tabsJson')\n @Watch('currentUrl')\n @Watch('basePath')\n onHostPropsChange() {\n this.applyHostProps();\n }\n\n @Watch('value')\n @Watch('urlDerivedValue')\n onSelectionChange() {\n this.syncMenuSections();\n this.scheduleOverflowCheck();\n }\n\n @Watch('menuOpen')\n onMenuOpenChange(open: boolean) {\n if (this.menuEl) {\n this.menuEl.open = open;\n }\n }\n\n @Watch('tabsCollapsed')\n onTabsCollapsedChange(collapsed: boolean, prevCollapsed: boolean | undefined) {\n if (!collapsed) {\n this.menuOpen = false;\n this.menuInitialFocusVisible = false;\n this.menuEl = null;\n }\n this.scheduleOverflowCheck();\n if (collapsed) {\n requestAnimationFrame(() => {\n this.scheduleOverflowCheck();\n });\n }\n if (collapsed || prevCollapsed === undefined || prevCollapsed === collapsed) return;\n requestAnimationFrame(() => this.scheduleOverflowCheck());\n queueMicrotask(() => this.focusVisibleSelectedTab());\n }\n\n componentWillLoad() {\n this.applyHostProps();\n }\n\n componentDidLoad() {\n this.syncHostPropsIfNeeded();\n this.scheduleDeferredHostPropSync();\n this.setupOverflowObserver();\n this.bindChromeTransitionListeners();\n this.scheduleOverflowCheck();\n }\n\n componentDidRender() {\n if (this.chromeOverflowPaused()) {\n this.syncMenuAnchor();\n return;\n }\n this.scheduleOverflowCheck();\n this.syncMenuAnchor();\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.overflowCoalescer.cancel();\n this.unbindChromeTransitionListeners();\n }\n\n private bindChromeTransitionListeners() {\n const shell = this.el.closest('ds-app-shell');\n if (!shell) return;\n this.chromeTransitionShell = shell;\n shell.addEventListener(CHROME_TRANSITION_START, this.onChromeTransitionStart);\n shell.addEventListener(CHROME_TRANSITION_END, this.onChromeTransitionEnd);\n }\n\n private unbindChromeTransitionListeners() {\n if (!this.chromeTransitionShell) return;\n this.chromeTransitionShell.removeEventListener(\n CHROME_TRANSITION_START,\n this.onChromeTransitionStart,\n );\n this.chromeTransitionShell.removeEventListener(\n CHROME_TRANSITION_END,\n this.onChromeTransitionEnd,\n );\n this.chromeTransitionShell = null;\n }\n\n private onChromeTransitionStart = (event: Event) => {\n const source = readChromeTransitionSource(event);\n if (source === 'panel-nav') {\n this.panelNavTransition.enter();\n return;\n }\n if (source === 'panel-tools') {\n const phase = readChromeTransitionPhase(event) ?? 'opening';\n if (phase === 'closing') {\n this.panelToolsTransition.enter();\n }\n }\n };\n\n private chromeOverflowPaused(): boolean {\n return this.panelNavTransition.isActive || this.panelToolsTransition.isActive;\n }\n\n private onChromeTransitionEnd = (event: Event) => {\n const source = readChromeTransitionSource(event);\n if (source === 'panel-nav') {\n this.panelNavTransition.exit();\n if (!this.panelNavTransition.isActive) {\n this.scheduleOverflowCheck();\n }\n return;\n }\n if (source === 'panel-tools') {\n this.panelToolsTransition.exit();\n this.scheduleOverflowCheck();\n }\n };\n\n /** Re-resolve props assigned by the host after componentWillLoad (Angular ngAfterViewInit). */\n private syncHostPropsIfNeeded() {\n if (shouldResyncBarNavProps(this.resolvedTabs, this.tabs, this.tabsJson)) {\n this.applyHostProps();\n } else if (this.currentUrl && this.basePath) {\n this.syncValueFromUrl();\n }\n }\n\n /** Poll across animation frames — host props may land without triggering @Watch. */\n private scheduleDeferredHostPropSync() {\n let remaining = BarNav.HOST_PROP_SYNC_BUDGET;\n const tick = () => {\n this.syncHostPropsIfNeeded();\n if (--remaining > 0) {\n requestAnimationFrame(tick);\n }\n };\n queueMicrotask(tick);\n }\n\n private setupOverflowObserver() {\n if (typeof ResizeObserver === 'undefined' || !this.headerEl) return;\n this.resizeObserver?.disconnect();\n this.resizeObserver = new ResizeObserver(() => {\n if (this.chromeOverflowPaused()) return;\n this.scheduleOverflowCheck();\n });\n this.resizeObserver.observe(this.headerEl);\n }\n\n private scheduleOverflowCheck() {\n if (this.chromeOverflowPaused()) return;\n this.overflowCoalescer.schedule();\n }\n\n /** Width available for the tab row or collapsed trigger. */\n private getLeftZoneAvailableWidth(): number {\n if (!this.headerEl) return 0;\n\n const headerStyle = getComputedStyle(this.headerEl);\n const horizontalPadding =\n (parseFloat(headerStyle.paddingLeft) || 0) + (parseFloat(headerStyle.paddingRight) || 0);\n\n return Math.max(0, this.headerEl.clientWidth - horizontalPadding);\n }\n\n private getTabsIntrinsicWidth(): number {\n const tabList = getTabListFromTabGroup(this.probeTabGroupEl);\n return tabList?.scrollWidth ?? 0;\n }\n\n private getHeaderGap(): number {\n if (!this.headerEl) return 0;\n const style = getComputedStyle(this.headerEl);\n return parseFloat(style.columnGap || style.gap) || 0;\n }\n\n private getOverflowTriggerReserveWidth(): number {\n if (!this.triggerEl) {\n return 40;\n }\n return this.triggerEl.getBoundingClientRect().width + this.getHeaderGap();\n }\n\n private getProbeTabMetrics():\n | {\n itemWidths: number[];\n itemGap: number;\n listExtraWidth: number;\n }\n | null {\n const tabList = getTabListFromTabGroup(this.probeTabGroupEl);\n if (!tabList) return null;\n\n const children = Array.from(tabList.children) as HTMLElement[];\n const itemWidths = children.map(child => child.getBoundingClientRect().width);\n if (itemWidths.length === 0 || itemWidths.some(width => width === 0)) return null;\n\n const style = getComputedStyle(tabList);\n const itemGap = parseFloat(style.columnGap || style.gap) || 0;\n const childrenWidth = itemWidths.reduce((sum, width) => sum + width, 0);\n const gapWidth = itemGap * Math.max(0, itemWidths.length - 1);\n const listExtraWidth = Math.max(0, tabList.scrollWidth - childrenWidth - gapWidth);\n\n return { itemWidths, itemGap, listExtraWidth };\n }\n\n private setOverflowTabLayout(visibleTabs: BarNavTab[], overflowTabs: BarNavTab[]) {\n const nextCollapsed = overflowTabs.length > 0;\n const visibleChanged =\n this.digestTabsConfig(visibleTabs) !== this.digestTabsConfig(this.visibleTabs);\n const overflowChanged =\n this.digestTabsConfig(overflowTabs) !== this.digestTabsConfig(this.overflowTabs);\n\n if (visibleChanged) {\n this.visibleTabs = visibleTabs;\n }\n if (overflowChanged) {\n this.overflowTabs = overflowTabs;\n }\n if (nextCollapsed !== this.tabsCollapsed) {\n this.tabsCollapsed = nextCollapsed;\n if (!nextCollapsed) {\n this.menuOpen = false;\n }\n }\n }\n\n private scheduleIntrinsicWidthRetry() {\n if (this.intrinsicWidthRetryCount >= BarNav.INTRINSIC_WIDTH_RETRY_MAX) return;\n this.intrinsicWidthRetryCount++;\n requestAnimationFrame(() => this.scheduleOverflowCheck());\n }\n\n private forceTabLayoutCommit(fallbackCollapsed: boolean) {\n this.intrinsicWidthRetryCount = 0;\n this.tabLayoutPendingFrames = 0;\n this.setOverflowTabLayout(\n fallbackCollapsed ? [] : this.resolvedTabs,\n fallbackCollapsed ? this.resolvedTabs : [],\n );\n this.tabLayoutCommitted = true;\n }\n\n private updateTabsCollapsed() {\n if (!this.headerEl || this.resolvedTabs.length === 0 || this.hideTabsForDetailRoute) {\n if (this.tabsCollapsed) {\n this.setOverflowTabLayout([], []);\n }\n this.intrinsicWidthRetryCount = 0;\n this.tabLayoutPendingFrames = 0;\n this.tabLayoutCommitted = true;\n return;\n }\n\n const metrics = this.getProbeTabMetrics();\n const intrinsicWidth = this.getTabsIntrinsicWidth();\n if (!metrics || intrinsicWidth === 0) {\n this.tabLayoutPendingFrames += 1;\n if (this.intrinsicWidthRetryCount >= BarNav.INTRINSIC_WIDTH_RETRY_MAX) {\n this.forceTabLayoutCommit(false);\n } else if (this.tabLayoutPendingFrames >= BarNav.TAB_LAYOUT_COMMIT_MAX_FRAMES) {\n this.forceTabLayoutCommit(false);\n } else {\n this.scheduleIntrinsicWidthRetry();\n }\n return;\n }\n this.intrinsicWidthRetryCount = 0;\n this.tabLayoutPendingFrames = 0;\n\n const shouldCollapse = tabsOverflowContainer(\n intrinsicWidth,\n this.getLeftZoneAvailableWidth(),\n this.tabsCollapsed,\n BarNav.OVERFLOW_HYSTERESIS_PX,\n );\n\n if (!shouldCollapse) {\n this.setOverflowTabLayout(this.resolvedTabs, []);\n this.tabLayoutCommitted = true;\n return;\n }\n\n const visibleCount = visibleTabCountForWidth(\n metrics.itemWidths,\n this.getLeftZoneAvailableWidth(),\n this.getOverflowTriggerReserveWidth(),\n metrics.itemGap,\n metrics.listExtraWidth,\n );\n const visibleTabs = trimTrailingDividers(this.resolvedTabs.slice(0, visibleCount));\n const overflowTabs = this.resolvedTabs.slice(visibleTabs.length);\n this.setOverflowTabLayout(visibleTabs, overflowTabs);\n this.tabLayoutCommitted = true;\n }\n\n private syncMenuAnchor() {\n if (!this.menuEl || !this.triggerEl || !this.hasOverflowTabs) return;\n this.menuEl.anchor = this.triggerEl;\n this.syncMenuSections();\n }\n\n private handleMenuSelect(e: Event) {\n const detail = (e as CustomEvent<MenuItemData>).detail;\n if (detail?.value !== undefined) {\n this.selectTab(String(detail.value));\n }\n this.menuOpen = false;\n this.menuInitialFocusVisible = false;\n }\n\n private handleMenuClose() {\n this.menuOpen = false;\n this.menuInitialFocusVisible = false;\n }\n\n /** Batch tabs/basePath/currentUrl updates so URL derivation never runs with a mixed section. */\n private incomingTabs(): BarNavTab[] {\n return this.tabsJson\n ? parseJsonArrayProp(this.tabsJson, [])\n : (this.tabs ?? []);\n }\n\n private applyHostProps() {\n const nextBasePath = this.basePath;\n const sectionChanged =\n nextBasePath !== '' &&\n this.committedSection !== '' &&\n nextBasePath !== this.committedSection;\n\n if (sectionChanged) {\n this.urlDerivedValue = '';\n this.committedSection = '';\n this.pendingSection = nextBasePath;\n this.resolvedTabs = [];\n this.resetTabOverflowLayout();\n return;\n }\n\n if (this.pendingSection) {\n if (!nextBasePath || nextBasePath !== this.pendingSection) {\n return;\n }\n if (!this.currentUrl.startsWith(this.pendingSection)) {\n return;\n }\n const tabs = this.incomingTabs();\n if (tabs.length === 0) {\n return;\n }\n this.pendingSection = '';\n }\n\n const tabs = this.incomingTabs();\n const tabsConfigChanged =\n this.digestTabsConfig(tabs) !== this.digestTabsConfig(this.resolvedTabs);\n\n this.resolvedTabs = tabs;\n this.syncValueFromUrl();\n this.committedSection = nextBasePath;\n if (tabsConfigChanged) {\n this.resetTabOverflowLayout();\n }\n this.scheduleOverflowCheck();\n }\n\n private syncMenuSections() {\n if (!this.menuEl) return;\n this.menuEl.sections = tabsToOverflowMenuSections(this.overflowTabs, this.effectiveValue);\n }\n\n private syncValueFromUrl() {\n const tabs = this.incomingTabs();\n\n if (!this.currentUrl || !this.basePath) {\n this.urlDerivedValue = '';\n this.hideTabsForDetailRoute = false;\n return;\n }\n\n if (!this.currentUrl.startsWith(this.basePath)) {\n this.urlDerivedValue = '';\n this.hideTabsForDetailRoute = false;\n return;\n }\n\n const { value, hideTabs } = deriveBarNavValueFromUrl(\n this.currentUrl,\n this.basePath,\n tabs,\n );\n this.urlDerivedValue = value;\n this.hideTabsForDetailRoute = hideTabs;\n }\n\n private selectTab(id: string) {\n this.value = id;\n this.dsTabChange.emit(id);\n }\n\n /** Move focus to the selected tab in the visible tab group (after expand). */\n private focusVisibleSelectedTab() {\n const tab = queryWithinComponentHost(\n this.visibleTabGroupEl,\n `[data-tab-id=\"${this.effectiveValue}\"]`,\n );\n tab?.focus({ preventScroll: true });\n }\n\n private handleTabChange(e: Event) {\n this.selectTab((e as CustomEvent<string>).detail);\n }\n\n private toggleTabMenu(options?: { focusVisible?: boolean }) {\n if (this.menuOpen) {\n this.menuOpen = false;\n this.menuInitialFocusVisible = false;\n return;\n }\n\n if (this.menuEl && this.triggerEl) {\n this.menuEl.anchor = this.triggerEl;\n this.menuEl.minWidth = '';\n this.syncMenuSections();\n }\n\n this.menuInitialFocusVisible = options?.focusVisible ?? false;\n this.menuOpen = true;\n }\n\n private handleTabRovingExit(e: CustomEvent<'start' | 'end'>) {\n if (e.detail !== 'end' || !this.hasOverflowTabs) return;\n this.overflowRovingFocused = true;\n void this.triggerEl?.setFocus?.();\n }\n\n private handleOverflowFocus = () => {\n this.overflowRovingFocused = true;\n };\n\n private handleOverflowBlur = () => {\n this.overflowRovingFocused = false;\n };\n\n private handleTriggerKeyDown(e: KeyboardEvent) {\n if (!this.hasOverflowTabs) return;\n\n if (!this.menuOpen) {\n if (e.key === 'ArrowLeft') {\n e.preventDefault();\n this.overflowRovingFocused = false;\n void this.visibleTabGroupEl?.focusLastTab();\n return;\n }\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.toggleTabMenu({ focusVisible: true });\n }\n return;\n }\n\n if (e.key === 'Escape') {\n e.preventDefault();\n this.menuOpen = false;\n this.menuInitialFocusVisible = false;\n void this.triggerEl?.setFocus?.();\n }\n }\n\n render() {\n const sectionReady =\n this.basePath !== '' && this.committedSection === this.basePath;\n const hasTabs =\n sectionReady && this.resolvedTabs.length > 0 && !this.hideTabsForDetailRoute;\n const tabGroupKey = this.basePath || 'no-section';\n const renderedTabs = this.hasOverflowTabs ? this.visibleTabs : this.resolvedTabs;\n\n return (\n <Host>\n <header\n class={{\n 'bar-nav': true,\n 'bar-nav--dashboard': this.navStyle === 'dashboard',\n 'bar-nav--settings': this.navStyle === 'settings',\n 'bar-nav--tabs-collapsed':\n hasTabs && this.hasOverflowTabs,\n }}\n ref={el => {\n this.headerEl = el as HTMLElement;\n if (el && !this.resizeObserver) {\n this.setupOverflowObserver();\n }\n }}\n >\n {hasTabs && (\n <div class=\"bar-nav__tabs-probe\" aria-hidden=\"true\" inert>\n <ds-tab-group-nav\n key={`probe-${tabGroupKey}`}\n ref={el => {\n const next = el ?? null;\n if (next === this.probeTabGroupEl) return;\n this.probeTabGroupEl = next;\n if (next) {\n this.intrinsicWidthRetryCount = 0;\n this.tabLayoutPendingFrames = 0;\n this.scheduleOverflowCheck();\n }\n }}\n tabs={this.resolvedTabs}\n value={this.effectiveValue}\n />\n </div>\n )}\n\n {hasTabs && this.tabLayoutCommitted && renderedTabs.length > 0 && (\n <div class=\"bar-nav__left\">\n <ds-tab-group-nav\n key={`visible-${tabGroupKey}`}\n class=\"bar-nav__tabs-visible\"\n ref={el => {\n this.visibleTabGroupEl = el ?? null;\n }}\n tabs={renderedTabs}\n value={this.effectiveValue}\n selectionFollowsFocus={false}\n rovingEnabled={!this.overflowRovingFocused}\n onDsChange={(e: Event) => this.handleTabChange(e)}\n onDsRovingExit={(e: CustomEvent<'start' | 'end'>) => this.handleTabRovingExit(e)}\n onFocusin={() => {\n this.overflowRovingFocused = false;\n }}\n />\n </div>\n )}\n\n {hasTabs && !this.tabLayoutCommitted && (\n <div class=\"bar-nav__tabs-pending\" aria-hidden=\"true\" />\n )}\n\n {!hasTabs && this.heading && (\n <span class=\"bar-nav__heading text-body-medium-emphasis\">{this.heading}</span>\n )}\n\n {hasTabs && this.hasOverflowTabs && (\n <ds-button-unfilled-icon\n class={{\n 'bar-nav__overflow-trigger': true,\n }}\n icon=\"Ellipses\"\n isActive={this.menuOpen}\n activeFill={false}\n focusTabIndex={this.overflowRovingFocused ? 0 : -1}\n ref={(el?: HTMLDsButtonUnfilledIconElement) => {\n this.triggerEl = (el as (HTMLElement & { setFocus?: () => Promise<void> })) ?? null;\n }}\n haspopup=\"menu\"\n expanded={this.menuOpen}\n aria-label=\"More tabs\"\n onDsClick={() => this.toggleTabMenu({ focusVisible: false })}\n onFocusin={this.handleOverflowFocus}\n onFocusout={this.handleOverflowBlur}\n onKeyDown={(e: KeyboardEvent) => this.handleTriggerKeyDown(e)}\n />\n )}\n\n </header>\n\n {hasTabs && this.hasOverflowTabs && (\n <ds-menu\n ref={el => {\n this.menuEl = (el as HTMLDsMenuElement) ?? null;\n }}\n open={this.menuOpen}\n sections={tabsToOverflowMenuSections(this.overflowTabs, this.effectiveValue)}\n side=\"bottom\"\n align=\"end\"\n sideOffset=\"calc(var(--dimension-space-100) + var(--dimension-space-050))\"\n alignOffset=\"var(--dimension-space-050)\"\n initialFocusVisible={this.menuInitialFocusVisible}\n onDsSelect={(e: Event) => this.handleMenuSelect(e)}\n onDsClose={() => this.handleMenuClose()}\n />\n )}\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["queryWithinComponentHost","host","selector","root","shadowRoot","querySelector","getTabListFromTabGroup","tabGroupEl","tabsToMenuSections","tabs","selectedId","sections","batch","item","isTabDivider","length","push","items","label","value","id","isSelected","isInactive","disabled","tabsToOverflowMenuSections","trimLeadingDividers","tabsOverflowContainer","tabListScrollWidth","containerClientWidth","collapsed","hysteresis","diff","visibleTabCountForWidth","itemWidths","availableWidth","overflowTriggerWidth","itemGap","listExtraWidth","fullWidth","widthForItemCount","availableForTabs","Math","max","count","i","width","trimTrailingDividers","end","slice","start","itemsWidth","reduce","sum","barNavCss","BarNav","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","navStyle","tabsJson","basePath","currentUrl","resolvedTabs","urlDerivedValue","hideTabsForDetailRoute","tabsCollapsed","menuOpen","tabLayoutCommitted","visibleTabs","overflowTabs","menuInitialFocusVisible","overflowRovingFocused","headerEl","triggerEl","menuEl","visibleTabGroupEl","probeTabGroupEl","resizeObserver","intrinsicWidthRetryCount","tabLayoutPendingFrames","panelNavTransition","ChromeTransitionDepth","panelToolsTransition","overflowCoalescer","createRafCoalescer","updateTabsCollapsed","chromeTransitionShell","committedSection","pendingSection","onChromeTransitionStart","event","source","readChromeTransitionSource","enter","phase","readChromeTransitionPhase","onChromeTransitionEnd","exit","isActive","scheduleOverflowCheck","handleOverflowFocus","handleOverflowBlur","effectiveValue","hasOverflowTabs","digestTabsConfig","map","t","join","resetTabOverflowLayout","onHostPropsChange","applyHostProps","onSelectionChange","syncMenuSections","onMenuOpenChange","open","onTabsCollapsedChange","prevCollapsed","requestAnimationFrame","undefined","queueMicrotask","focusVisibleSelectedTab","componentWillLoad","componentDidLoad","syncHostPropsIfNeeded","scheduleDeferredHostPropSync","setupOverflowObserver","bindChromeTransitionListeners","componentDidRender","chromeOverflowPaused","syncMenuAnchor","disconnectedCallback","disconnect","cancel","unbindChromeTransitionListeners","shell","el","closest","addEventListener","CHROME_TRANSITION_START","CHROME_TRANSITION_END","removeEventListener","shouldResyncBarNavProps","syncValueFromUrl","remaining","HOST_PROP_SYNC_BUDGET","tick","ResizeObserver","observe","schedule","getLeftZoneAvailableWidth","headerStyle","getComputedStyle","horizontalPadding","parseFloat","paddingLeft","paddingRight","clientWidth","getTabsIntrinsicWidth","tabList","scrollWidth","getHeaderGap","style","columnGap","gap","getOverflowTriggerReserveWidth","getBoundingClientRect","getProbeTabMetrics","children","Array","from","child","some","childrenWidth","gapWidth","setOverflowTabLayout","nextCollapsed","visibleChanged","overflowChanged","scheduleIntrinsicWidthRetry","INTRINSIC_WIDTH_RETRY_MAX","forceTabLayoutCommit","fallbackCollapsed","metrics","intrinsicWidth","TAB_LAYOUT_COMMIT_MAX_FRAMES","shouldCollapse","OVERFLOW_HYSTERESIS_PX","visibleCount","anchor","handleMenuSelect","e","detail","selectTab","String","handleMenuClose","incomingTabs","parseJsonArrayProp","nextBasePath","sectionChanged","startsWith","tabsConfigChanged","hideTabs","deriveBarNavValueFromUrl","dsTabChange","emit","tab","focus","preventScroll","handleTabChange","toggleTabMenu","options","minWidth","focusVisible","handleTabRovingExit","setFocus","handleTriggerKeyDown","key","preventDefault","focusLastTab","render","sectionReady","hasTabs","tabGroupKey","renderedTabs","h","Host","class","ref","inert","next","selectionFollowsFocus","rovingEnabled","onDsChange","onDsRovingExit","onFocusin","heading","icon","activeFill","focusTabIndex","haspopup","expanded","onDsClick","onFocusout","onKeyDown","side","align","sideOffset","alignOffset","initialFocusVisible","onDsSelect","onDsClose"],"sources":["src/wc/components/BarNav/bar-nav-dom-utils.ts","src/wc/components/BarNav/bar-nav-tabs-menu-utils.ts","src/wc/components/BarNav/BarNav.css?tag=ds-bar-nav&encapsulation=scoped","src/wc/components/BarNav/BarNav.tsx"],"sourcesContent":["export type QueryableHost = {\n shadowRoot?: ShadowRoot | null;\n querySelector: (selectors: string) => Element | null;\n};\n\n/**\n * Query within a Stencil custom-element host (light DOM today, shadow DOM–safe).\n * Use for child nodes owned by ds-tab-group and similar components.\n */\nexport function queryWithinComponentHost(\n host: QueryableHost | null | undefined,\n selector: string,\n): HTMLElement | null {\n if (!host) return null;\n const root = host.shadowRoot ?? host;\n return root.querySelector(selector) as HTMLElement | null;\n}\n\nexport function getTabListFromTabGroup(\n tabGroupEl: QueryableHost | null | undefined,\n): HTMLElement | null {\n return queryWithinComponentHost(tabGroupEl, '[role=\"tablist\"]');\n}\n","import type { MenuItemData, MenuSection } from '../Menu/menu-types';\nimport {\n getSelectableTabs,\n isTabDivider,\n type TabItem,\n type TabItemTab,\n} from '../TabGroup/tab-item-utils';\n\n/** Map BarNav tabs to menu sections, preserving `{ type: 'divider' }` as section breaks. */\nexport function tabsToMenuSections(tabs: TabItem[], selectedId: string): MenuSection[] {\n const sections: MenuSection[] = [];\n let batch: MenuItemData[] = [];\n\n for (const item of tabs) {\n if (isTabDivider(item)) {\n if (batch.length > 0) {\n sections.push({ items: batch });\n batch = [];\n }\n continue;\n }\n\n batch.push({\n label: item.label,\n value: item.id,\n isSelected: item.id === selectedId,\n isInactive: item.disabled,\n });\n }\n\n if (batch.length > 0) {\n sections.push({ items: batch });\n }\n\n return sections;\n}\n\nexport function tabsToOverflowMenuSections(tabs: TabItem[], selectedId: string): MenuSection[] {\n return tabsToMenuSections(trimLeadingDividers(tabs), selectedId);\n}\n\nexport function getActiveTab(tabs: TabItem[], selectedId: string): TabItemTab | undefined {\n const selectable = getSelectableTabs(tabs);\n return selectable.find(tab => tab.id === selectedId) ?? selectable[0];\n}\n\nexport function getActiveTabLabel(tabs: TabItem[], selectedId: string): string {\n return getActiveTab(tabs, selectedId)?.label ?? 'Tabs';\n}\n\n/** True when tablist content exceeds the available width (with optional hysteresis). */\nexport function tabsOverflowContainer(\n tabListScrollWidth: number,\n containerClientWidth: number,\n collapsed: boolean,\n hysteresis = 2,\n): boolean {\n const diff = tabListScrollWidth - containerClientWidth;\n if (collapsed) {\n return diff > -hysteresis;\n }\n return diff > hysteresis;\n}\n\nexport function visibleTabCountForWidth(\n itemWidths: number[],\n availableWidth: number,\n overflowTriggerWidth: number,\n itemGap: number,\n listExtraWidth: number,\n): number {\n if (itemWidths.length === 0 || availableWidth <= 0) return 0;\n\n const fullWidth = widthForItemCount(itemWidths, itemWidths.length, itemGap, listExtraWidth);\n if (fullWidth <= availableWidth) return itemWidths.length;\n\n const availableForTabs = Math.max(0, availableWidth - overflowTriggerWidth);\n let count = 0;\n\n for (let i = 1; i <= itemWidths.length; i++) {\n const width = widthForItemCount(itemWidths, i, itemGap, listExtraWidth);\n if (width > availableForTabs) break;\n count = i;\n }\n\n return count;\n}\n\nexport function trimTrailingDividers(tabs: TabItem[]): TabItem[] {\n let end = tabs.length;\n while (end > 0 && isTabDivider(tabs[end - 1])) {\n end -= 1;\n }\n return tabs.slice(0, end);\n}\n\nfunction trimLeadingDividers(tabs: TabItem[]): TabItem[] {\n let start = 0;\n while (start < tabs.length && isTabDivider(tabs[start])) {\n start += 1;\n }\n return tabs.slice(start);\n}\n\nfunction widthForItemCount(\n itemWidths: number[],\n count: number,\n itemGap: number,\n listExtraWidth: number,\n): number {\n if (count <= 0) return 0;\n const itemsWidth = itemWidths.slice(0, count).reduce((sum, width) => sum + width, 0);\n return listExtraWidth + itemsWidth + itemGap * Math.max(0, count - 1);\n}\n","@import '../../utils/focus-ring.css';\n\n:host {\n display: block;\n}\n\n.bar-nav {\n display: flex;\n align-items: center;\n position: relative;\n height: var(--dimension-size-600);\n padding: var(--dimension-space-100);\n gap: var(--dimension-space-100);\n box-sizing: border-box;\n border-bottom: var(--dimension-stroke-width-012) solid var(--_bar-nav-border);\n background-color: var(--_bar-nav-bg);\n color: var(--_bar-nav-fg-primary);\n -webkit-user-select: none;\n user-select: none;\n overflow: hidden;\n transition:\n background-color var(--effect-motion-short-3),\n border-color var(--effect-motion-short-3),\n color var(--effect-motion-short-3);\n isolation: isolate;\n /* Default chrome — app surfaces */\n --_bar-nav-bg: var(--color-background-secondary);\n --_bar-nav-border: var(--color-border-tertiary);\n --_bar-nav-fg-primary: var(--color-foreground-primary);\n --_bar-nav-fg-secondary: var(--color-foreground-secondary);\n --_bar-nav-hover: var(--color-interaction-hover);\n --_bar-nav-pressed: var(--color-interaction-pressed);\n --_bar-nav-focus: var(--color-interaction-focus);\n --_bar-nav-dot: var(--color-foreground-bold-brand);\n --ds-focus-ring-color: var(--_bar-nav-focus);\n}\n\n/* Style slots — same app tokens for now; hook texture/glyph layers later. */\n.bar-nav--dashboard,\n.bar-nav--settings {\n --_bar-nav-bg: var(--color-background-secondary);\n --_bar-nav-border: var(--color-border-tertiary);\n --_bar-nav-fg-primary: var(--color-foreground-primary);\n --_bar-nav-fg-secondary: var(--color-foreground-secondary);\n --_bar-nav-hover: var(--color-interaction-hover);\n --_bar-nav-pressed: var(--color-interaction-pressed);\n --_bar-nav-focus: var(--color-interaction-focus);\n --_bar-nav-dot: var(--color-foreground-bold-brand);\n}\n\n/* Shell-owned chrome (bg + wash + grid) — bar is a transparent frame. */\n:host-context(ds-app-shell[gradient]) .bar-nav,\n:host-context(ds-app-shell[grid]) .bar-nav {\n background-color: transparent;\n}\n\n.bar-nav > :not(.bar-nav__tabs-probe) {\n position: relative;\n z-index: 3;\n}\n\n/* Overflow — keep fitting tabs visible and pin the overflow trigger to the far edge. */\n.bar-nav--tabs-collapsed {\n display: flex;\n gap: var(--dimension-space-100);\n align-items: center;\n}\n\n/* Expanded tabs — consume full header width */\n.bar-nav__left {\n position: relative;\n flex: 1 1 0%;\n min-width: 0;\n width: 0;\n display: flex;\n align-items: center;\n}\n\n.bar-nav__left ds-tab-group-nav {\n flex: 1;\n min-width: 0;\n}\n\n/* Unconstrained width so intrinsic tab row width is measurable while collapsed */\n.bar-nav__tabs-probe {\n position: absolute;\n left: 0;\n top: 0;\n visibility: hidden;\n pointer-events: none;\n overflow: visible;\n width: max-content;\n max-width: none;\n z-index: -1;\n}\n\n.bar-nav__tabs-probe ds-tab-group-nav {\n width: max-content;\n}\n\n.bar-nav__tabs-visible {\n width: 100%;\n min-width: 0;\n}\n\n/* In-flow placeholder while measuring overflow — avoids layout jump; hidden from view/accessibility. */\n.bar-nav__tabs-pending {\n flex: 1;\n min-width: 0;\n height: var(--dimension-size-400);\n visibility: hidden;\n pointer-events: none;\n}\n\n/* Overflow trigger — compact icon button aligned to the right edge. */\n.bar-nav__overflow-trigger {\n margin-left: auto;\n --ds-button-unfilled-icon-fg: var(--_bar-nav-fg-secondary);\n --ds-button-unfilled-icon-fg-active: var(--_bar-nav-fg-primary);\n --ds-button-unfilled-icon-hover-bg: var(--_bar-nav-hover);\n --ds-button-unfilled-icon-pressed-bg: var(--_bar-nav-pressed);\n --ds-focus-ring-color: var(--_bar-nav-focus);\n}\n\n/* Fallback heading when no tabs — matches a single (selected) tab so the area\n name shares the tab label's type token, color, height and horizontal inset.\n Inset = tab button padding (space-075, 6px) + label inset (space-025, 2px). */\n.bar-nav__heading {\n display: inline-flex;\n align-items: center;\n height: var(--dimension-size-400);\n padding-inline: var(--dimension-space-100);\n color: var(--_bar-nav-fg-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n -webkit-user-select: none;\n user-select: none;\n}\n","import {\n Component,\n Prop,\n Event,\n EventEmitter,\n Element,\n Watch,\n State,\n h,\n Host,\n} from '@stencil/core';\nimport type { NavChromeStyle } from '../../nav/nav-chrome';\nimport type { MenuItemData } from '../Menu/menu-types';\nimport { isTabDivider } from '../TabGroup/tab-item-utils';\nimport type { BarNavTab } from './bar-nav-types';\nimport {\n deriveBarNavValueFromUrl,\n parseJsonArrayProp,\n shouldResyncBarNavProps,\n} from './bar-nav-utils';\nimport {\n getTabListFromTabGroup,\n queryWithinComponentHost,\n type QueryableHost,\n} from './bar-nav-dom-utils';\nimport {\n tabsOverflowContainer,\n tabsToOverflowMenuSections,\n trimTrailingDividers,\n visibleTabCountForWidth,\n} from './bar-nav-tabs-menu-utils';\nimport {\n CHROME_TRANSITION_END,\n CHROME_TRANSITION_START,\n ChromeTransitionDepth,\n createRafCoalescer,\n readChromeTransitionSource,\n readChromeTransitionPhase,\n} from '../../nav/chrome-transition';\n\n@Component({\n tag: 'ds-bar-nav',\n styleUrl: 'BarNav.css',\n scoped: true,\n})\nexport class BarNav {\n /** Style slot: `dashboard` or `settings`. Colors match for now. */\n @Prop({ attribute: 'nav-style', reflect: true }) navStyle: NavChromeStyle = 'dashboard';\n\n @Element() el!: HTMLElement;\n\n /**\n * Tab items for the left section.\n * Set via JS property: `el.tabs = [...]`. Replace the array reference to update.\n */\n @Prop() tabs: BarNavTab[] = [];\n\n /** JSON fallback for `tabs` — useful when framework bindings don't propagate arrays. */\n @Prop({ attribute: 'tabs-json' }) tabsJson: string = '';\n\n /** ID of the currently active tab. Overridden when `currentUrl` + `basePath` are set. */\n @Prop({ mutable: true }) value: string = '';\n\n /**\n * Fallback heading shown when no tabs are provided.\n * When tabs are present the heading is hidden.\n */\n @Prop() heading: string | undefined;\n\n /** Section base path (e.g. `/dashboard/safety`). Used with `currentUrl` to derive `value`. */\n @Prop() basePath: string = '';\n\n /** Current route URL. When set with `basePath`, the active tab is derived automatically. */\n @Prop() currentUrl: string = '';\n\n /** Emitted when the active tab changes. Detail = tab id. */\n @Event() dsTabChange!: EventEmitter<string>;\n\n @State() private resolvedTabs: BarNavTab[] = [];\n @State() private urlDerivedValue: string = '';\n @State() private hideTabsForDetailRoute = false;\n @State() private tabsCollapsed = false;\n @State() private menuOpen = false;\n /** When false, defer showing expanded tabs or the collapsed trigger until intrinsic width is measured (avoids a one-frame flash of the full tab row on narrow viewports). */\n @State() private tabLayoutCommitted = false;\n @State() private visibleTabs: BarNavTab[] = [];\n @State() private overflowTabs: BarNavTab[] = [];\n @State() private menuInitialFocusVisible = false;\n @State() private overflowRovingFocused = false;\n\n private static readonly HOST_PROP_SYNC_BUDGET = 8;\n private static readonly INTRINSIC_WIDTH_RETRY_MAX = 3;\n private static readonly TAB_LAYOUT_COMMIT_MAX_FRAMES = 16;\n private static readonly OVERFLOW_HYSTERESIS_PX = 8;\n\n private headerEl: HTMLElement | null = null;\n private triggerEl: (HTMLElement & { setFocus?: () => Promise<void> }) | null = null;\n private menuEl: HTMLDsMenuElement | null = null;\n private visibleTabGroupEl: HTMLDsTabGroupNavElement | null = null;\n private probeTabGroupEl: QueryableHost | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private intrinsicWidthRetryCount = 0;\n private tabLayoutPendingFrames = 0;\n private readonly panelNavTransition = new ChromeTransitionDepth();\n private readonly panelToolsTransition = new ChromeTransitionDepth();\n private readonly overflowCoalescer = createRafCoalescer(() => {\n this.updateTabsCollapsed();\n });\n private chromeTransitionShell: HTMLElement | null = null;\n /** Matches `basePath` once tabs + URL are reconciled for the active section. */\n @State() private committedSection = '';\n /** Section waiting for URL + tabs to catch up after a cross-area navigation. */\n @State() private pendingSection = '';\n\n private get effectiveValue(): string {\n if (this.currentUrl && this.basePath) {\n return this.urlDerivedValue;\n }\n return this.value;\n }\n\n private get hasOverflowTabs(): boolean {\n return this.tabLayoutCommitted && this.tabsCollapsed && this.overflowTabs.length > 0;\n }\n\n private digestTabsConfig(tabs: BarNavTab[]): string {\n return tabs.map(t => (isTabDivider(t) ? '|' : t.id)).join(',');\n }\n\n private resetTabOverflowLayout() {\n this.tabLayoutCommitted = false;\n this.tabsCollapsed = false;\n this.menuOpen = false;\n this.menuInitialFocusVisible = false;\n this.intrinsicWidthRetryCount = 0;\n this.tabLayoutPendingFrames = 0;\n this.visibleTabs = [];\n this.overflowTabs = [];\n }\n\n @Watch('tabs')\n @Watch('tabsJson')\n @Watch('currentUrl')\n @Watch('basePath')\n onHostPropsChange() {\n this.applyHostProps();\n }\n\n @Watch('value')\n @Watch('urlDerivedValue')\n onSelectionChange() {\n this.syncMenuSections();\n this.scheduleOverflowCheck();\n }\n\n @Watch('menuOpen')\n onMenuOpenChange(open: boolean) {\n if (this.menuEl) {\n this.menuEl.open = open;\n }\n }\n\n @Watch('tabsCollapsed')\n onTabsCollapsedChange(collapsed: boolean, prevCollapsed: boolean | undefined) {\n if (!collapsed) {\n this.menuOpen = false;\n this.menuInitialFocusVisible = false;\n this.menuEl = null;\n }\n this.scheduleOverflowCheck();\n if (collapsed) {\n requestAnimationFrame(() => {\n this.scheduleOverflowCheck();\n });\n }\n if (collapsed || prevCollapsed === undefined || prevCollapsed === collapsed) return;\n requestAnimationFrame(() => this.scheduleOverflowCheck());\n queueMicrotask(() => this.focusVisibleSelectedTab());\n }\n\n componentWillLoad() {\n this.applyHostProps();\n }\n\n componentDidLoad() {\n this.syncHostPropsIfNeeded();\n this.scheduleDeferredHostPropSync();\n this.setupOverflowObserver();\n this.bindChromeTransitionListeners();\n this.scheduleOverflowCheck();\n }\n\n componentDidRender() {\n if (this.chromeOverflowPaused()) {\n this.syncMenuAnchor();\n return;\n }\n this.scheduleOverflowCheck();\n this.syncMenuAnchor();\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.overflowCoalescer.cancel();\n this.unbindChromeTransitionListeners();\n }\n\n private bindChromeTransitionListeners() {\n const shell = this.el.closest('ds-app-shell');\n if (!shell) return;\n this.chromeTransitionShell = shell;\n shell.addEventListener(CHROME_TRANSITION_START, this.onChromeTransitionStart);\n shell.addEventListener(CHROME_TRANSITION_END, this.onChromeTransitionEnd);\n }\n\n private unbindChromeTransitionListeners() {\n if (!this.chromeTransitionShell) return;\n this.chromeTransitionShell.removeEventListener(\n CHROME_TRANSITION_START,\n this.onChromeTransitionStart,\n );\n this.chromeTransitionShell.removeEventListener(\n CHROME_TRANSITION_END,\n this.onChromeTransitionEnd,\n );\n this.chromeTransitionShell = null;\n }\n\n private onChromeTransitionStart = (event: Event) => {\n const source = readChromeTransitionSource(event);\n if (source === 'panel-nav') {\n this.panelNavTransition.enter();\n return;\n }\n if (source === 'panel-tools') {\n const phase = readChromeTransitionPhase(event) ?? 'opening';\n if (phase === 'closing') {\n this.panelToolsTransition.enter();\n }\n }\n };\n\n private chromeOverflowPaused(): boolean {\n return this.panelNavTransition.isActive || this.panelToolsTransition.isActive;\n }\n\n private onChromeTransitionEnd = (event: Event) => {\n const source = readChromeTransitionSource(event);\n if (source === 'panel-nav') {\n this.panelNavTransition.exit();\n if (!this.panelNavTransition.isActive) {\n this.scheduleOverflowCheck();\n }\n return;\n }\n if (source === 'panel-tools') {\n this.panelToolsTransition.exit();\n this.scheduleOverflowCheck();\n }\n };\n\n /** Re-resolve props assigned by the host after componentWillLoad (Angular ngAfterViewInit). */\n private syncHostPropsIfNeeded() {\n if (shouldResyncBarNavProps(this.resolvedTabs, this.tabs, this.tabsJson)) {\n this.applyHostProps();\n } else if (this.currentUrl && this.basePath) {\n this.syncValueFromUrl();\n }\n }\n\n /** Poll across animation frames — host props may land without triggering @Watch. */\n private scheduleDeferredHostPropSync() {\n let remaining = BarNav.HOST_PROP_SYNC_BUDGET;\n const tick = () => {\n this.syncHostPropsIfNeeded();\n if (--remaining > 0) {\n requestAnimationFrame(tick);\n }\n };\n queueMicrotask(tick);\n }\n\n private setupOverflowObserver() {\n if (typeof ResizeObserver === 'undefined' || !this.headerEl) return;\n this.resizeObserver?.disconnect();\n this.resizeObserver = new ResizeObserver(() => {\n if (this.chromeOverflowPaused()) return;\n this.scheduleOverflowCheck();\n });\n this.resizeObserver.observe(this.headerEl);\n }\n\n private scheduleOverflowCheck() {\n if (this.chromeOverflowPaused()) return;\n this.overflowCoalescer.schedule();\n }\n\n /** Width available for the tab row or collapsed trigger. */\n private getLeftZoneAvailableWidth(): number {\n if (!this.headerEl) return 0;\n\n const headerStyle = getComputedStyle(this.headerEl);\n const horizontalPadding =\n (parseFloat(headerStyle.paddingLeft) || 0) + (parseFloat(headerStyle.paddingRight) || 0);\n\n return Math.max(0, this.headerEl.clientWidth - horizontalPadding);\n }\n\n private getTabsIntrinsicWidth(): number {\n const tabList = getTabListFromTabGroup(this.probeTabGroupEl);\n return tabList?.scrollWidth ?? 0;\n }\n\n private getHeaderGap(): number {\n if (!this.headerEl) return 0;\n const style = getComputedStyle(this.headerEl);\n return parseFloat(style.columnGap || style.gap) || 0;\n }\n\n private getOverflowTriggerReserveWidth(): number {\n if (!this.triggerEl) {\n return 40;\n }\n return this.triggerEl.getBoundingClientRect().width + this.getHeaderGap();\n }\n\n private getProbeTabMetrics():\n | {\n itemWidths: number[];\n itemGap: number;\n listExtraWidth: number;\n }\n | null {\n const tabList = getTabListFromTabGroup(this.probeTabGroupEl);\n if (!tabList) return null;\n\n const children = Array.from(tabList.children) as HTMLElement[];\n const itemWidths = children.map(child => child.getBoundingClientRect().width);\n if (itemWidths.length === 0 || itemWidths.some(width => width === 0)) return null;\n\n const style = getComputedStyle(tabList);\n const itemGap = parseFloat(style.columnGap || style.gap) || 0;\n const childrenWidth = itemWidths.reduce((sum, width) => sum + width, 0);\n const gapWidth = itemGap * Math.max(0, itemWidths.length - 1);\n const listExtraWidth = Math.max(0, tabList.scrollWidth - childrenWidth - gapWidth);\n\n return { itemWidths, itemGap, listExtraWidth };\n }\n\n private setOverflowTabLayout(visibleTabs: BarNavTab[], overflowTabs: BarNavTab[]) {\n const nextCollapsed = overflowTabs.length > 0;\n const visibleChanged =\n this.digestTabsConfig(visibleTabs) !== this.digestTabsConfig(this.visibleTabs);\n const overflowChanged =\n this.digestTabsConfig(overflowTabs) !== this.digestTabsConfig(this.overflowTabs);\n\n if (visibleChanged) {\n this.visibleTabs = visibleTabs;\n }\n if (overflowChanged) {\n this.overflowTabs = overflowTabs;\n }\n if (nextCollapsed !== this.tabsCollapsed) {\n this.tabsCollapsed = nextCollapsed;\n if (!nextCollapsed) {\n this.menuOpen = false;\n }\n }\n }\n\n private scheduleIntrinsicWidthRetry() {\n if (this.intrinsicWidthRetryCount >= BarNav.INTRINSIC_WIDTH_RETRY_MAX) return;\n this.intrinsicWidthRetryCount++;\n requestAnimationFrame(() => this.scheduleOverflowCheck());\n }\n\n private forceTabLayoutCommit(fallbackCollapsed: boolean) {\n this.intrinsicWidthRetryCount = 0;\n this.tabLayoutPendingFrames = 0;\n this.setOverflowTabLayout(\n fallbackCollapsed ? [] : this.resolvedTabs,\n fallbackCollapsed ? this.resolvedTabs : [],\n );\n this.tabLayoutCommitted = true;\n }\n\n private updateTabsCollapsed() {\n if (!this.headerEl || this.resolvedTabs.length === 0 || this.hideTabsForDetailRoute) {\n if (this.tabsCollapsed) {\n this.setOverflowTabLayout([], []);\n }\n this.intrinsicWidthRetryCount = 0;\n this.tabLayoutPendingFrames = 0;\n this.tabLayoutCommitted = true;\n return;\n }\n\n const metrics = this.getProbeTabMetrics();\n const intrinsicWidth = this.getTabsIntrinsicWidth();\n if (!metrics || intrinsicWidth === 0) {\n this.tabLayoutPendingFrames += 1;\n if (this.intrinsicWidthRetryCount >= BarNav.INTRINSIC_WIDTH_RETRY_MAX) {\n this.forceTabLayoutCommit(false);\n } else if (this.tabLayoutPendingFrames >= BarNav.TAB_LAYOUT_COMMIT_MAX_FRAMES) {\n this.forceTabLayoutCommit(false);\n } else {\n this.scheduleIntrinsicWidthRetry();\n }\n return;\n }\n this.intrinsicWidthRetryCount = 0;\n this.tabLayoutPendingFrames = 0;\n\n const shouldCollapse = tabsOverflowContainer(\n intrinsicWidth,\n this.getLeftZoneAvailableWidth(),\n this.tabsCollapsed,\n BarNav.OVERFLOW_HYSTERESIS_PX,\n );\n\n if (!shouldCollapse) {\n this.setOverflowTabLayout(this.resolvedTabs, []);\n this.tabLayoutCommitted = true;\n return;\n }\n\n const visibleCount = visibleTabCountForWidth(\n metrics.itemWidths,\n this.getLeftZoneAvailableWidth(),\n this.getOverflowTriggerReserveWidth(),\n metrics.itemGap,\n metrics.listExtraWidth,\n );\n const visibleTabs = trimTrailingDividers(this.resolvedTabs.slice(0, visibleCount));\n const overflowTabs = this.resolvedTabs.slice(visibleTabs.length);\n this.setOverflowTabLayout(visibleTabs, overflowTabs);\n this.tabLayoutCommitted = true;\n }\n\n private syncMenuAnchor() {\n if (!this.menuEl || !this.triggerEl || !this.hasOverflowTabs) return;\n this.menuEl.anchor = this.triggerEl;\n this.syncMenuSections();\n }\n\n private handleMenuSelect(e: Event) {\n const detail = (e as CustomEvent<MenuItemData>).detail;\n if (detail?.value !== undefined) {\n this.selectTab(String(detail.value));\n }\n this.menuOpen = false;\n this.menuInitialFocusVisible = false;\n }\n\n private handleMenuClose() {\n this.menuOpen = false;\n this.menuInitialFocusVisible = false;\n }\n\n /** Batch tabs/basePath/currentUrl updates so URL derivation never runs with a mixed section. */\n private incomingTabs(): BarNavTab[] {\n return this.tabsJson\n ? parseJsonArrayProp(this.tabsJson, [])\n : (this.tabs ?? []);\n }\n\n private applyHostProps() {\n const nextBasePath = this.basePath;\n const sectionChanged =\n nextBasePath !== '' &&\n this.committedSection !== '' &&\n nextBasePath !== this.committedSection;\n\n if (sectionChanged) {\n this.urlDerivedValue = '';\n this.committedSection = '';\n this.pendingSection = nextBasePath;\n this.resolvedTabs = [];\n this.resetTabOverflowLayout();\n return;\n }\n\n if (this.pendingSection) {\n if (!nextBasePath || nextBasePath !== this.pendingSection) {\n return;\n }\n if (!this.currentUrl.startsWith(this.pendingSection)) {\n return;\n }\n const tabs = this.incomingTabs();\n if (tabs.length === 0) {\n return;\n }\n this.pendingSection = '';\n }\n\n const tabs = this.incomingTabs();\n const tabsConfigChanged =\n this.digestTabsConfig(tabs) !== this.digestTabsConfig(this.resolvedTabs);\n\n this.resolvedTabs = tabs;\n this.syncValueFromUrl();\n this.committedSection = nextBasePath;\n if (tabsConfigChanged) {\n this.resetTabOverflowLayout();\n }\n this.scheduleOverflowCheck();\n }\n\n private syncMenuSections() {\n if (!this.menuEl) return;\n this.menuEl.sections = tabsToOverflowMenuSections(this.overflowTabs, this.effectiveValue);\n }\n\n private syncValueFromUrl() {\n const tabs = this.incomingTabs();\n\n if (!this.currentUrl || !this.basePath) {\n this.urlDerivedValue = '';\n this.hideTabsForDetailRoute = false;\n return;\n }\n\n if (!this.currentUrl.startsWith(this.basePath)) {\n this.urlDerivedValue = '';\n this.hideTabsForDetailRoute = false;\n return;\n }\n\n const { value, hideTabs } = deriveBarNavValueFromUrl(\n this.currentUrl,\n this.basePath,\n tabs,\n );\n this.urlDerivedValue = value;\n this.hideTabsForDetailRoute = hideTabs;\n }\n\n private selectTab(id: string) {\n this.value = id;\n this.dsTabChange.emit(id);\n }\n\n /** Move focus to the selected tab in the visible tab group (after expand). */\n private focusVisibleSelectedTab() {\n const tab = queryWithinComponentHost(\n this.visibleTabGroupEl,\n `[data-tab-id=\"${this.effectiveValue}\"]`,\n );\n tab?.focus({ preventScroll: true });\n }\n\n private handleTabChange(e: Event) {\n this.selectTab((e as CustomEvent<string>).detail);\n }\n\n private toggleTabMenu(options?: { focusVisible?: boolean }) {\n if (this.menuOpen) {\n this.menuOpen = false;\n this.menuInitialFocusVisible = false;\n return;\n }\n\n if (this.menuEl && this.triggerEl) {\n this.menuEl.anchor = this.triggerEl;\n this.menuEl.minWidth = '';\n this.syncMenuSections();\n }\n\n this.menuInitialFocusVisible = options?.focusVisible ?? false;\n this.menuOpen = true;\n }\n\n private handleTabRovingExit(e: CustomEvent<'start' | 'end'>) {\n if (e.detail !== 'end' || !this.hasOverflowTabs) return;\n this.overflowRovingFocused = true;\n void this.triggerEl?.setFocus?.();\n }\n\n private handleOverflowFocus = () => {\n this.overflowRovingFocused = true;\n };\n\n private handleOverflowBlur = () => {\n this.overflowRovingFocused = false;\n };\n\n private handleTriggerKeyDown(e: KeyboardEvent) {\n if (!this.hasOverflowTabs) return;\n\n if (!this.menuOpen) {\n if (e.key === 'ArrowLeft') {\n e.preventDefault();\n this.overflowRovingFocused = false;\n void this.visibleTabGroupEl?.focusLastTab();\n return;\n }\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.toggleTabMenu({ focusVisible: true });\n }\n return;\n }\n\n if (e.key === 'Escape') {\n e.preventDefault();\n this.menuOpen = false;\n this.menuInitialFocusVisible = false;\n void this.triggerEl?.setFocus?.();\n }\n }\n\n render() {\n const sectionReady =\n this.basePath !== '' && this.committedSection === this.basePath;\n const hasTabs =\n sectionReady && this.resolvedTabs.length > 0 && !this.hideTabsForDetailRoute;\n const tabGroupKey = this.basePath || 'no-section';\n const renderedTabs = this.hasOverflowTabs ? this.visibleTabs : this.resolvedTabs;\n\n return (\n <Host>\n <header\n class={{\n 'bar-nav': true,\n 'bar-nav--dashboard': this.navStyle === 'dashboard',\n 'bar-nav--settings': this.navStyle === 'settings',\n 'bar-nav--tabs-collapsed':\n hasTabs && this.hasOverflowTabs,\n }}\n ref={el => {\n this.headerEl = el as HTMLElement;\n if (el && !this.resizeObserver) {\n this.setupOverflowObserver();\n }\n }}\n >\n {hasTabs && (\n <div class=\"bar-nav__tabs-probe\" aria-hidden=\"true\" inert>\n <ds-tab-group-nav\n key={`probe-${tabGroupKey}`}\n ref={el => {\n const next = el ?? null;\n if (next === this.probeTabGroupEl) return;\n this.probeTabGroupEl = next;\n if (next) {\n this.intrinsicWidthRetryCount = 0;\n this.tabLayoutPendingFrames = 0;\n this.scheduleOverflowCheck();\n }\n }}\n tabs={this.resolvedTabs}\n value={this.effectiveValue}\n />\n </div>\n )}\n\n {hasTabs && this.tabLayoutCommitted && renderedTabs.length > 0 && (\n <div class=\"bar-nav__left\">\n <ds-tab-group-nav\n key={`visible-${tabGroupKey}`}\n class=\"bar-nav__tabs-visible\"\n ref={el => {\n this.visibleTabGroupEl = el ?? null;\n }}\n tabs={renderedTabs}\n value={this.effectiveValue}\n selectionFollowsFocus={false}\n rovingEnabled={!this.overflowRovingFocused}\n onDsChange={(e: Event) => this.handleTabChange(e)}\n onDsRovingExit={(e: CustomEvent<'start' | 'end'>) => this.handleTabRovingExit(e)}\n onFocusin={() => {\n this.overflowRovingFocused = false;\n }}\n />\n </div>\n )}\n\n {hasTabs && !this.tabLayoutCommitted && (\n <div class=\"bar-nav__tabs-pending\" aria-hidden=\"true\" />\n )}\n\n {!hasTabs && this.heading && (\n <span class=\"bar-nav__heading text-body-medium-emphasis\">{this.heading}</span>\n )}\n\n {hasTabs && this.hasOverflowTabs && (\n <ds-button-unfilled-icon\n class={{\n 'bar-nav__overflow-trigger': true,\n }}\n icon=\"Ellipses\"\n isActive={this.menuOpen}\n activeFill={false}\n focusTabIndex={this.overflowRovingFocused ? 0 : -1}\n ref={(el?: HTMLDsButtonUnfilledIconElement) => {\n this.triggerEl = (el as (HTMLElement & { setFocus?: () => Promise<void> })) ?? null;\n }}\n haspopup=\"menu\"\n expanded={this.menuOpen}\n aria-label=\"More tabs\"\n onDsClick={() => this.toggleTabMenu({ focusVisible: false })}\n onFocusin={this.handleOverflowFocus}\n onFocusout={this.handleOverflowBlur}\n onKeyDown={(e: KeyboardEvent) => this.handleTriggerKeyDown(e)}\n />\n )}\n\n </header>\n\n {hasTabs && this.hasOverflowTabs && (\n <ds-menu\n ref={el => {\n this.menuEl = (el as HTMLDsMenuElement) ?? null;\n }}\n open={this.menuOpen}\n sections={tabsToOverflowMenuSections(this.overflowTabs, this.effectiveValue)}\n side=\"bottom\"\n align=\"end\"\n sideOffset=\"calc(var(--dimension-space-100) + var(--dimension-space-050))\"\n alignOffset=\"var(--dimension-space-050)\"\n initialFocusVisible={this.menuInitialFocusVisible}\n onDsSelect={(e: Event) => this.handleMenuSelect(e)}\n onDsClose={() => this.handleMenuClose()}\n />\n )}\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{M as o,d as s}from"./p-
|
|
1
|
+
import{M as o,d as s}from"./p-CLmK4lRE.js";const t=o;const m=s;export{t as DsMenu,m as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-menu.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as e,H as s,c as t,h as i,a as r,t as o}from"./index.js";import{d as n}from"./p-
|
|
1
|
+
import{p as e,H as s,c as t,h as i,a as r,t as o}from"./index.js";import{d as n}from"./p-CLmK4lRE.js";import{d as a}from"./p-BgiK3sHs.js";import{d as l}from"./p-DKG6W4pb.js";const c=()=>`.select-host.sc-ds-select-h{display:inline-block;width:100%;position:relative}.inactive.sc-ds-select-h{opacity:0.5;pointer-events:none}.trigger.sc-ds-select{display:inline-flex;align-items:center;justify-content:space-between;width:100%;height:var(--dimension-size-400);padding:0 var(--dimension-space-075) 0 var(--dimension-space-100);border:none;border-radius:var(--dimension-radius-050);background-color:var(--color-background-primary);box-shadow:var(--effect-elevation-elevated-sm);cursor:pointer;box-sizing:border-box;gap:var(--dimension-space-050);font-family:inherit;outline:none;--_hover-bg:color-mix(in oklch, var(--color-background-primary) 90%, var(--color-foreground-primary));--_pressed-bg:color-mix(in oklch, var(--color-background-primary) 85%, var(--color-foreground-primary))}.trigger.sc-ds-select:focus-visible{outline:var(--dimension-stroke-width-025) solid var(--color-interaction-focus);outline-offset:var(--dimension-space-025)}.trigger.sc-ds-select:hover:not(:disabled){background-color:var(--_hover-bg)}.trigger.sc-ds-select:active:not(:disabled){background-color:var(--_pressed-bg)}.trigger--open.sc-ds-select{background-color:var(--_pressed-bg)}.trigger__label.sc-ds-select{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;font-size:var(--typography-fontsize-md);line-height:var(--typography-lineheight-md);font-weight:var(--typography-weight-regular);color:var(--color-foreground-primary)}.trigger__label--placeholder.sc-ds-select{color:var(--color-foreground-secondary)}.trigger__chevron.sc-ds-select{flex-shrink:0;color:var(--color-foreground-secondary);transition:transform var(--effect-motion-short-2)}.trigger--open.sc-ds-select .trigger__chevron.sc-ds-select{transform:rotate(180deg)}`;const d=e(class e extends s{constructor(e){super();if(e!==false){this.__registerHost()}this.dsChange=t(this,"dsChange");this.options=[];this.value="";this.placeholder="Select option";this.inactive=false;this.isOpen=false;this.triggerEl=null;this.menuEl=null}componentDidLoad(){if(this.menuEl&&this.triggerEl){this.menuEl.anchor=this.triggerEl}this.menuEl?.addEventListener("dsSelect",(e=>{const s=e.detail;if(s?.value!==undefined){this.value=String(s.value);this.dsChange.emit(this.value)}this.isOpen=false}));this.menuEl?.addEventListener("dsClose",(()=>{this.isOpen=false}))}onIsOpenChange(e){if(this.menuEl){this.menuEl.open=e}}onOptionsChange(){this.syncMenuItems()}onValueChange(){this.syncMenuItems()}syncMenuItems(){if(!this.menuEl)return;this.menuEl.items=this.options.map((e=>({label:e.label,value:e.value,isSelected:e.value===this.value})))}open(){if(this.inactive||!this.options.length)return;if(this.menuEl&&this.triggerEl){this.menuEl.menuWidth=`${this.triggerEl.offsetWidth}px`;this.menuEl.anchor=this.triggerEl}this.syncMenuItems();this.isOpen=true}close(){this.isOpen=false}toggle(){if(this.isOpen){this.close()}else{this.open()}}handleKeyDown(e){if(document.activeElement!==this.triggerEl)return;if(!this.isOpen){switch(e.key){case"ArrowDown":case"ArrowUp":case"Enter":case" ":e.preventDefault();this.open();break}}else{if(e.key==="Escape"){e.preventDefault();this.close();this.triggerEl?.focus()}}}get selectedLabel(){const e=this.options.find((e=>e.value===this.value));return e?.label??""}get hasSelection(){return!!this.options.find((e=>e.value===this.value))}render(){const e=this.hasSelection?this.selectedLabel:this.placeholder;const s=!this.hasSelection;return i(r,{key:"47854c5a69705adc07ca601f31e262d3d8d74771",class:{"select-host":true,inactive:this.inactive}},i("button",{key:"2fa71b2e7bb4f890a37a130c6af50cb0cb05df81",ref:e=>{this.triggerEl=e??null},type:"button",class:{trigger:true,"trigger--open":this.isOpen},disabled:this.inactive,role:"combobox","aria-haspopup":"listbox","aria-expanded":this.isOpen,"aria-label":this.ariaLabel,"aria-labelledby":this.ariaLabelledby,onClick:()=>this.toggle()},i("span",{key:"4ce5d30c16af2dd2188d19dfc13d96b3d3bfbe6e",class:{trigger__label:true,"trigger__label--placeholder":s}},e),i("svg",{key:"8a942bde794824fb5b79565d4d297c7b3a42bed4",class:"trigger__chevron",width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true"},i("path",{key:"b937494cd4d3bdf9924541d8f77db13fef11b8b6",d:"M4 6L8 10L12 6",stroke:"currentColor","stroke-width":"1.25","stroke-linecap":"round","stroke-linejoin":"round"}))),i("ds-menu",{key:"d8f76d473fea216bac4db040441288b1da9cd87b",ref:e=>{this.menuEl=e??null},side:"bottom",align:"start"}))}get el(){return this}static get watchers(){return{isOpen:[{onIsOpenChange:0}],options:[{onOptionsChange:0}],value:[{onValueChange:0}]}}static get style(){return c()}},[2,"ds-select",{options:[16],value:[1025],placeholder:[1],inactive:[4],ariaLabel:[1,"aria-label"],ariaLabelledby:[1,"aria-labelledby"],isOpen:[32]},[[0,"keydown","handleKeyDown"]],{isOpen:[{onIsOpenChange:0}],options:[{onOptionsChange:0}],value:[{onValueChange:0}]}]);function h(){if(typeof customElements==="undefined"){return}const e=["ds-select","ds-menu","ds-shell-gradient-picker","ds-shell-gradient-swatch"];e.forEach((e=>{switch(e){case"ds-select":if(!customElements.get(o(e))){customElements.define(o(e),d)}break;case"ds-menu":if(!customElements.get(o(e))){n()}break;case"ds-shell-gradient-picker":if(!customElements.get(o(e))){a()}break;case"ds-shell-gradient-swatch":if(!customElements.get(o(e))){l()}break}}))}h();const g=d;const p=h;export{g as DsSelect,p as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-select.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["selectCss","Select","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","options","value","placeholder","inactive","isOpen","triggerEl","menuEl","componentDidLoad","anchor","addEventListener","e","detail","undefined","String","dsChange","emit","onIsOpenChange","open","onOptionsChange","syncMenuItems","onValueChange","items","map","opt","label","isSelected","length","menuWidth","offsetWidth","close","toggle","handleKeyDown","document","activeElement","key","preventDefault","focus","selectedLabel","found","find","o","hasSelection","render","showPlaceholder","h","Host","class","ref","el","type","trigger","disabled","role","ariaLabel","ariaLabelledby","onClick","trigger__label","width","height","viewBox","fill","d","stroke","side","align"],"sources":["src/wc/components/Select/Select.css?tag=ds-select&encapsulation=scoped","src/wc/components/Select/Select.tsx"],"sourcesContent":["/* ==========================================================================\n Select — combobox-pattern select using ds-menu for the dropdown.\n ========================================================================== */\n\n:host(.select-host) {\n display: inline-block;\n width: 100%;\n position: relative;\n}\n\n:host(.inactive) {\n opacity: 0.5;\n pointer-events: none;\n}\n\n/* ── Trigger button ──────────────────────────────────────────────────────── */\n\n.trigger {\n display: inline-flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: var(--dimension-size-400);\n padding: 0 var(--dimension-space-075) 0 var(--dimension-space-100);\n border: none;\n border-radius: var(--dimension-radius-050);\n background-color: var(--color-background-primary);\n box-shadow: var(--effect-elevation-elevated-sm);\n cursor: pointer;\n box-sizing: border-box;\n gap: var(--dimension-space-050);\n font-family: inherit;\n outline: none;\n\n --_hover-bg: color-mix(in oklch, var(--color-background-primary) 90%, var(--color-foreground-primary));\n --_pressed-bg: color-mix(in oklch, var(--color-background-primary) 85%, var(--color-foreground-primary));\n}\n\n.trigger:focus-visible {\n outline: var(--dimension-stroke-width-025) solid var(--color-interaction-focus);\n outline-offset: var(--dimension-space-025);\n}\n\n.trigger:hover:not(:disabled) {\n background-color: var(--_hover-bg);\n}\n\n.trigger:active:not(:disabled) {\n background-color: var(--_pressed-bg);\n}\n\n.trigger--open {\n background-color: var(--_pressed-bg);\n}\n\n/* ── Trigger label ───────────────────────────────────────────────────────── */\n\n.trigger__label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: left;\n font-size: var(--typography-fontsize-md);\n line-height: var(--typography-lineheight-md);\n font-weight: var(--typography-weight-regular);\n color: var(--color-foreground-primary);\n}\n\n.trigger__label--placeholder {\n color: var(--color-foreground-secondary);\n}\n\n/* ── Chevron icon ────────────────────────────────────────────────────────── */\n\n.trigger__chevron {\n flex-shrink: 0;\n color: var(--color-foreground-secondary);\n transition: transform var(--effect-motion-short-2);\n}\n\n.trigger--open .trigger__chevron {\n transform: rotate(180deg);\n}\n","import { Component, Prop, State, Event, EventEmitter, Element, Watch, Listen, h, Host } from '@stencil/core';\nimport type { MenuItemData } from '../Menu/menu-types';\n\nexport interface SelectOption {\n label: string;\n value: string;\n}\n\n@Component({\n tag: 'ds-select',\n styleUrl: 'Select.css',\n scoped: true,\n})\nexport class Select {\n @Element() el!: HTMLElement;\n\n /**\n * Array of options. Set via JS property.\n * @example el.options = [{ label: 'Apple', value: 'apple' }];\n */\n @Prop() options: SelectOption[] = [];\n\n /** Currently selected value. */\n @Prop({ mutable: true }) value: string = '';\n\n /** Placeholder shown when no value is selected. */\n @Prop() placeholder: string = 'Select option';\n\n /** Disables interaction. */\n @Prop() inactive: boolean = false;\n\n @Prop({ attribute: 'aria-label' }) ariaLabel: string | undefined;\n @Prop({ attribute: 'aria-labelledby' }) ariaLabelledby: string | undefined;\n\n /** Emits the selected value string. */\n @Event() dsChange!: EventEmitter<string>;\n\n @State() private isOpen: boolean = false;\n\n private triggerEl: HTMLButtonElement | null = null;\n private menuEl: HTMLDsMenuElement | null = null;\n\n componentDidLoad() {\n // Wire up the menu anchor to the trigger button\n if (this.menuEl && this.triggerEl) {\n this.menuEl.anchor = this.triggerEl;\n }\n // Listen for menu selection events\n this.menuEl?.addEventListener('dsSelect', (e: Event) => {\n const detail = (e as CustomEvent<MenuItemData>).detail;\n if (detail?.value !== undefined) {\n this.value = String(detail.value);\n this.dsChange.emit(this.value);\n }\n this.isOpen = false;\n });\n // Listen for menu close event\n this.menuEl?.addEventListener('dsClose', () => {\n this.isOpen = false;\n });\n }\n\n @Watch('isOpen')\n onIsOpenChange(open: boolean) {\n if (this.menuEl) {\n this.menuEl.open = open;\n }\n }\n\n @Watch('options')\n onOptionsChange() {\n this.syncMenuItems();\n }\n\n @Watch('value')\n onValueChange() {\n this.syncMenuItems();\n }\n\n private syncMenuItems() {\n if (!this.menuEl) return;\n this.menuEl.items = this.options.map(opt => ({\n label: opt.label,\n value: opt.value,\n isSelected: opt.value === this.value,\n }));\n }\n\n private open() {\n if (this.inactive || !this.options.length) return;\n // Sync menu width to trigger width\n if (this.menuEl && this.triggerEl) {\n this.menuEl.menuWidth = `${this.triggerEl.offsetWidth}px`;\n this.menuEl.anchor = this.triggerEl;\n }\n this.syncMenuItems();\n this.isOpen = true;\n }\n\n private close() {\n this.isOpen = false;\n }\n\n private toggle() {\n if (this.isOpen) {\n this.close();\n } else {\n this.open();\n }\n }\n\n @Listen('keydown')\n handleKeyDown(e: KeyboardEvent) {\n // Only handle keydown on the trigger button\n if (document.activeElement !== this.triggerEl) return;\n\n if (!this.isOpen) {\n switch (e.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n case 'Enter':\n case ' ':\n e.preventDefault();\n this.open();\n break;\n }\n } else {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.close();\n this.triggerEl?.focus();\n }\n }\n }\n\n private get selectedLabel(): string {\n const found = this.options.find(o => o.value === this.value);\n return found?.label ?? '';\n }\n\n private get hasSelection(): boolean {\n return !!this.options.find(o => o.value === this.value);\n }\n\n render() {\n const label = this.hasSelection ? this.selectedLabel : this.placeholder;\n const showPlaceholder = !this.hasSelection;\n\n return (\n <Host class={{ 'select-host': true, inactive: this.inactive }}>\n <button\n ref={el => {\n this.triggerEl = (el as HTMLButtonElement) ?? null;\n }}\n type=\"button\"\n class={{ trigger: true, 'trigger--open': this.isOpen }}\n disabled={this.inactive}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={this.isOpen}\n aria-label={this.ariaLabel}\n aria-labelledby={this.ariaLabelledby}\n onClick={() => this.toggle()}\n >\n <span class={{ 'trigger__label': true, 'trigger__label--placeholder': showPlaceholder }}>\n {label}\n </span>\n <svg\n class=\"trigger__chevron\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M4 6L8 10L12 6\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <ds-menu\n ref={el => {\n this.menuEl = (el as HTMLDsMenuElement) ?? null;\n }}\n side=\"bottom\"\n align=\"start\"\n />\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["selectCss","Select","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","options","value","placeholder","inactive","isOpen","triggerEl","menuEl","componentDidLoad","anchor","addEventListener","e","detail","undefined","String","dsChange","emit","onIsOpenChange","open","onOptionsChange","syncMenuItems","onValueChange","items","map","opt","label","isSelected","length","menuWidth","offsetWidth","close","toggle","handleKeyDown","document","activeElement","key","preventDefault","focus","selectedLabel","found","find","o","hasSelection","render","showPlaceholder","h","Host","class","ref","el","type","trigger","disabled","role","ariaLabel","ariaLabelledby","onClick","trigger__label","width","height","viewBox","fill","d","stroke","side","align"],"sources":["src/wc/components/Select/Select.css?tag=ds-select&encapsulation=scoped","src/wc/components/Select/Select.tsx"],"sourcesContent":["/* ==========================================================================\n Select — combobox-pattern select using ds-menu for the dropdown.\n ========================================================================== */\n\n:host(.select-host) {\n display: inline-block;\n width: 100%;\n position: relative;\n}\n\n:host(.inactive) {\n opacity: 0.5;\n pointer-events: none;\n}\n\n/* ── Trigger button ──────────────────────────────────────────────────────── */\n\n.trigger {\n display: inline-flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: var(--dimension-size-400);\n padding: 0 var(--dimension-space-075) 0 var(--dimension-space-100);\n border: none;\n border-radius: var(--dimension-radius-050);\n background-color: var(--color-background-primary);\n box-shadow: var(--effect-elevation-elevated-sm);\n cursor: pointer;\n box-sizing: border-box;\n gap: var(--dimension-space-050);\n font-family: inherit;\n outline: none;\n\n --_hover-bg: color-mix(in oklch, var(--color-background-primary) 90%, var(--color-foreground-primary));\n --_pressed-bg: color-mix(in oklch, var(--color-background-primary) 85%, var(--color-foreground-primary));\n}\n\n.trigger:focus-visible {\n outline: var(--dimension-stroke-width-025) solid var(--color-interaction-focus);\n outline-offset: var(--dimension-space-025);\n}\n\n.trigger:hover:not(:disabled) {\n background-color: var(--_hover-bg);\n}\n\n.trigger:active:not(:disabled) {\n background-color: var(--_pressed-bg);\n}\n\n.trigger--open {\n background-color: var(--_pressed-bg);\n}\n\n/* ── Trigger label ───────────────────────────────────────────────────────── */\n\n.trigger__label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: left;\n font-size: var(--typography-fontsize-md);\n line-height: var(--typography-lineheight-md);\n font-weight: var(--typography-weight-regular);\n color: var(--color-foreground-primary);\n}\n\n.trigger__label--placeholder {\n color: var(--color-foreground-secondary);\n}\n\n/* ── Chevron icon ────────────────────────────────────────────────────────── */\n\n.trigger__chevron {\n flex-shrink: 0;\n color: var(--color-foreground-secondary);\n transition: transform var(--effect-motion-short-2);\n}\n\n.trigger--open .trigger__chevron {\n transform: rotate(180deg);\n}\n","import { Component, Prop, State, Event, EventEmitter, Element, Watch, Listen, h, Host } from '@stencil/core';\nimport type { MenuItemData } from '../Menu/menu-types';\n\nexport interface SelectOption {\n label: string;\n value: string;\n}\n\n@Component({\n tag: 'ds-select',\n styleUrl: 'Select.css',\n scoped: true,\n})\nexport class Select {\n @Element() el!: HTMLElement;\n\n /**\n * Array of options. Set via JS property.\n * @example el.options = [{ label: 'Apple', value: 'apple' }];\n */\n @Prop() options: SelectOption[] = [];\n\n /** Currently selected value. */\n @Prop({ mutable: true }) value: string = '';\n\n /** Placeholder shown when no value is selected. */\n @Prop() placeholder: string = 'Select option';\n\n /** Disables interaction. */\n @Prop() inactive: boolean = false;\n\n @Prop({ attribute: 'aria-label' }) ariaLabel: string | undefined;\n @Prop({ attribute: 'aria-labelledby' }) ariaLabelledby: string | undefined;\n\n /** Emits the selected value string. */\n @Event() dsChange!: EventEmitter<string>;\n\n @State() private isOpen: boolean = false;\n\n private triggerEl: HTMLButtonElement | null = null;\n private menuEl: HTMLDsMenuElement | null = null;\n\n componentDidLoad() {\n // Wire up the menu anchor to the trigger button\n if (this.menuEl && this.triggerEl) {\n this.menuEl.anchor = this.triggerEl;\n }\n // Listen for menu selection events\n this.menuEl?.addEventListener('dsSelect', (e: Event) => {\n const detail = (e as CustomEvent<MenuItemData>).detail;\n if (detail?.value !== undefined) {\n this.value = String(detail.value);\n this.dsChange.emit(this.value);\n }\n this.isOpen = false;\n });\n // Listen for menu close event\n this.menuEl?.addEventListener('dsClose', () => {\n this.isOpen = false;\n });\n }\n\n @Watch('isOpen')\n onIsOpenChange(open: boolean) {\n if (this.menuEl) {\n this.menuEl.open = open;\n }\n }\n\n @Watch('options')\n onOptionsChange() {\n this.syncMenuItems();\n }\n\n @Watch('value')\n onValueChange() {\n this.syncMenuItems();\n }\n\n private syncMenuItems() {\n if (!this.menuEl) return;\n this.menuEl.items = this.options.map(opt => ({\n label: opt.label,\n value: opt.value,\n isSelected: opt.value === this.value,\n }));\n }\n\n private open() {\n if (this.inactive || !this.options.length) return;\n // Sync menu width to trigger width\n if (this.menuEl && this.triggerEl) {\n this.menuEl.menuWidth = `${this.triggerEl.offsetWidth}px`;\n this.menuEl.anchor = this.triggerEl;\n }\n this.syncMenuItems();\n this.isOpen = true;\n }\n\n private close() {\n this.isOpen = false;\n }\n\n private toggle() {\n if (this.isOpen) {\n this.close();\n } else {\n this.open();\n }\n }\n\n @Listen('keydown')\n handleKeyDown(e: KeyboardEvent) {\n // Only handle keydown on the trigger button\n if (document.activeElement !== this.triggerEl) return;\n\n if (!this.isOpen) {\n switch (e.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n case 'Enter':\n case ' ':\n e.preventDefault();\n this.open();\n break;\n }\n } else {\n if (e.key === 'Escape') {\n e.preventDefault();\n this.close();\n this.triggerEl?.focus();\n }\n }\n }\n\n private get selectedLabel(): string {\n const found = this.options.find(o => o.value === this.value);\n return found?.label ?? '';\n }\n\n private get hasSelection(): boolean {\n return !!this.options.find(o => o.value === this.value);\n }\n\n render() {\n const label = this.hasSelection ? this.selectedLabel : this.placeholder;\n const showPlaceholder = !this.hasSelection;\n\n return (\n <Host class={{ 'select-host': true, inactive: this.inactive }}>\n <button\n ref={el => {\n this.triggerEl = (el as HTMLButtonElement) ?? null;\n }}\n type=\"button\"\n class={{ trigger: true, 'trigger--open': this.isOpen }}\n disabled={this.inactive}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={this.isOpen}\n aria-label={this.ariaLabel}\n aria-labelledby={this.ariaLabelledby}\n onClick={() => this.toggle()}\n >\n <span class={{ 'trigger__label': true, 'trigger__label--placeholder': showPlaceholder }}>\n {label}\n </span>\n <svg\n class=\"trigger__chevron\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M4 6L8 10L12 6\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <ds-menu\n ref={el => {\n this.menuEl = (el as HTMLDsMenuElement) ?? null;\n }}\n side=\"bottom\"\n align=\"start\"\n />\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Components, JSX } from "../types/components";
|
|
2
|
+
|
|
3
|
+
interface DsShellGradientPicker extends Components.DsShellGradientPicker, HTMLElement {}
|
|
4
|
+
export const DsShellGradientPicker: {
|
|
5
|
+
prototype: DsShellGradientPicker;
|
|
6
|
+
new (): DsShellGradientPicker;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Used to define this component and all nested components recursively.
|
|
10
|
+
*/
|
|
11
|
+
export const defineCustomElement: () => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":[],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Components, JSX } from "../types/components";
|
|
2
|
+
|
|
3
|
+
interface DsShellGradientSwatch extends Components.DsShellGradientSwatch, HTMLElement {}
|
|
4
|
+
export const DsShellGradientSwatch: {
|
|
5
|
+
prototype: DsShellGradientSwatch;
|
|
6
|
+
new (): DsShellGradientSwatch;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Used to define this component and all nested components recursively.
|
|
10
|
+
*/
|
|
11
|
+
export const defineCustomElement: () => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":[],"mappings":"","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as e,H as s,c as i,h as t,a,t as r}from"./index.js";const
|
|
1
|
+
import{p as e,H as s,c as i,h as t,a,t as r}from"./index.js";const d=()=>`.field.sc-ds-slider{display:flex;flex-direction:column;gap:var(--dimension-space-050);width:100%}.label-row.sc-ds-slider{display:flex;align-items:baseline;justify-content:space-between;gap:var(--dimension-space-050)}.track.sc-ds-slider{position:relative;width:100%;height:var(--dimension-size-400);padding:0 var(--dimension-space-025);border-radius:var(--dimension-radius-075);cursor:pointer;user-select:none;box-sizing:border-box}.track-inner.sc-ds-slider{position:absolute;inset:0;border-radius:inherit;background-color:var(--color-background-primary);box-shadow:var(--effect-elevation-depressed-sm);pointer-events:none;z-index:1}.fill-track.sc-ds-slider{position:absolute;top:var(--dimension-space-025);right:0;bottom:var(--dimension-space-025);left:0;z-index:1;pointer-events:none}.fill.sc-ds-slider{position:absolute;left:var(--dimension-space-025);top:0;bottom:0;width:max(0px, calc((var(--slider-pct, 0) / 100) * (100% - var(--dimension-size-150)) - var(--dimension-space-025)));background-color:var(--color-background-bold-brand);box-shadow:var(--effect-elevation-elevated-sm);border-radius:var(--dimension-radius-050);transition:opacity var(--effect-motion-short-2);pointer-events:none}.track--at-min.sc-ds-slider .fill.sc-ds-slider{opacity:0}.thumb.sc-ds-slider{position:absolute;top:0;bottom:0;left:calc((var(--slider-pct, 0) / 100) * (100% - var(--dimension-size-150)));width:var(--dimension-size-150);padding:var(--dimension-space-025);box-sizing:border-box;pointer-events:none;z-index:2}.thumb.sc-ds-slider::before{content:'';position:absolute;inset:var(--dimension-space-025);background-color:var(--color-background-primary);box-shadow:var(--effect-elevation-elevated-sm);border-radius:var(--dimension-radius-050)}.thumb.sc-ds-slider::after{content:'';position:absolute;inset:var(--dimension-space-025);background-color:transparent;border-radius:var(--dimension-radius-050);transition:background-color 100ms ease}.track.sc-ds-slider:hover:not(.track--inactive) .thumb.sc-ds-slider::after{background-color:var(--color-interaction-hover)}.track.sc-ds-slider:active:not(.track--inactive) .thumb.sc-ds-slider::after{background-color:var(--color-interaction-pressed)}.range-input.sc-ds-slider{position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;opacity:0;cursor:pointer;-webkit-appearance:none;appearance:none;outline:none;z-index:3}.range-input.sc-ds-slider:disabled{cursor:not-allowed}.range-input.sc-ds-slider:hover{cursor:grab}.range-input.sc-ds-slider:active{cursor:grabbing}.track--inactive.sc-ds-slider{cursor:not-allowed;opacity:0.5}.track.sc-ds-slider:focus-within .track-inner.sc-ds-slider{box-shadow:var(--effect-elevation-depressed-sm), inset 0 0 0 1.25px var(--color-interaction-focus)}`;let n=0;const o=e(class e extends s{constructor(e){super();if(e!==false){this.__registerHost()}this.dsChange=i(this,"dsChange");this.generatedId=`ds-slider-${++n}`;this.value=0;this.min=0;this.max=100;this.step=1;this.inactive=false;this.handleInput=e=>{this.dsChange.emit(Number(e.target.value))}}get pct(){const e=this.max-this.min;return e===0?0:Math.round((this.value-this.min)/e*100)}render(){const e=this.inputId??this.generatedId;const s=this.pct;return t(a,{key:"0103ea55297b4027b0d49adf3c83db970ef308be",class:"field"},t("div",{key:"1d4de1ad37f6558c6a59d806507637e2cb6a4140",class:"label-row"},t("label",{key:"3d838e9559d0536b9d08ce0eb8f968ffce92448d",class:"text-body-small-emphasis",htmlFor:e},this.label),t("span",{key:"5162ed48d6007e6d93285f0dd8fc8cccfa8a9c7b",class:"text-body-small-emphasis"},this.value)),t("div",{key:"cabda7cc6c988d6097fe4ca0441d9dfc561289c5",class:{track:true,"track--inactive":this.inactive,"track--at-min":s===0},style:{"--slider-pct":String(s)}},t("div",{key:"b7d1eb8f73d424a2e380b8f2c31ae031ef0371b8",class:"track-inner"},t("div",{key:"222306d54a1fbadedb124973dd642f091478991d",class:"fill-track"},t("div",{key:"062e67848bbfcf0bf0cfec1441aa8c2d012d2d36",class:"fill"})),t("div",{key:"ed1ac5800e99d90c90df071312ff1cdd489cb642",class:"thumb"})),t("input",{key:"a2cb5727b75abd1aa65b4f4ede00a862e073b2b3",type:"range",id:e,min:this.min,max:this.max,step:this.step,value:this.value,disabled:this.inactive,class:"range-input","aria-valuetext":this.valueText,onInput:this.handleInput})))}static get style(){return d()}},[2,"ds-slider",{value:[2],min:[2],max:[2],step:[2],label:[1],inactive:[4],valueText:[1,"value-text"],inputId:[1,"input-id"]}]);function c(){if(typeof customElements==="undefined"){return}const e=["ds-slider"];e.forEach((e=>{switch(e){case"ds-slider":if(!customElements.get(r(e))){customElements.define(r(e),o)}break}}))}c();const l=o;const b=c;export{l as DsSlider,b as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-slider.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as t,H as e,c as o,h as i,a as s,t as n}from"./index.js";const r=()=>`:host{position:relative;display:inline-flex;align-items:center;justify-content:flex-start;width:var(--dimension-size-400);height:var(--dimension-size-250);padding:0 var(--dimension-space-025);border:none;border-radius:var(--dimension-radius-half);cursor:pointer;user-select:none;outline:none;flex-shrink:0;background-color:var(--color-background-medium-neutral);box-shadow:var(--effect-highlight-depressed-sm);transition:background-color var(--effect-motion-short-2);box-sizing:border-box}:host::before{content:'';position:absolute;inset:0;border-radius:inherit;box-shadow:var(--effect-shadow-depressed-sm);pointer-events:none}:host(:focus-visible){outline:var(--dimension-stroke-width-025) solid var(--color-interaction-focus);outline-offset:var(--dimension-space-025)}:host(.checked){background-color:var(--color-foreground-bold-brand)}:host(.inactive){cursor:not-allowed;opacity:0.5}.thumb{position:relative;flex-shrink:0;width:var(--dimension-size-200);height:var(--dimension-size-200);background-color:var(--color-background-primary);border-radius:var(--dimension-radius-half);box-shadow:var(--effect-elevation-elevated-sm);transition:transform var(--effect-motion-short-2);transform:translateX(0);z-index:1}.thumb::after{content:'';position:absolute;inset:0;background-color:transparent;border-radius:inherit;transition:background-color var(--effect-motion-instant, 100ms);pointer-events:none}:host(:hover:not(.inactive)) .thumb::after{background-color:var(--color-interaction-hover)}:host(:active:not(.inactive)) .thumb::after{background-color:var(--color-interaction-pressed)}:host(.checked) .thumb{transform:translateX(var(--dimension-offset-150))}:host(:active:not(.inactive)) .thumb{transform:translateX(0) scale(var(--dimension-scale-subtle)) !important;transition:transform var(--effect-motion-instant)}:host(.checked:active:not(.inactive)) .thumb{transform:translateX(var(--dimension-offset-150)) scale(var(--dimension-scale-subtle)) !important;transition:transform var(--effect-motion-instant)}`;const a=t(class t extends e{constructor(t){super();if(t!==false){this.__registerHost()}this.__attachShadow();this.dsChange=o(this,"dsChange");this.checked=false;this.inactive=false;this.handleClick=()=>{if(this.inactive)return;this.checked=!this.checked;this.dsChange.emit(this.checked)};this.handleKeyDown=t=>{if(this.inactive)return;if(t.key===" "||t.key==="Enter"){t.preventDefault();this.handleClick()}}}render(){return i(s,{key:"
|
|
1
|
+
import{p as t,H as e,c as o,h as i,a as s,t as n}from"./index.js";const r=()=>`:host{position:relative;display:inline-flex;align-items:center;justify-content:flex-start;width:var(--dimension-size-400);height:var(--dimension-size-250);padding:0 var(--dimension-space-025);border:none;border-radius:var(--dimension-radius-half);cursor:pointer;user-select:none;outline:none;flex-shrink:0;background-color:var(--color-background-medium-neutral);box-shadow:var(--effect-highlight-depressed-sm);transition:background-color var(--effect-motion-short-2);box-sizing:border-box}:host::before{content:'';position:absolute;inset:0;border-radius:inherit;box-shadow:var(--effect-shadow-depressed-sm);pointer-events:none}:host(:focus-visible){outline:var(--dimension-stroke-width-025) solid var(--color-interaction-focus);outline-offset:var(--dimension-space-025)}:host(.checked){background-color:var(--color-foreground-bold-brand)}:host(.inactive){cursor:not-allowed;opacity:0.5}.thumb{position:relative;flex-shrink:0;width:var(--dimension-size-200);height:var(--dimension-size-200);background-color:var(--color-background-primary);border-radius:var(--dimension-radius-half);box-shadow:var(--effect-elevation-elevated-sm);transition:transform var(--effect-motion-short-2);transform:translateX(0);z-index:1}.thumb::after{content:'';position:absolute;inset:0;background-color:transparent;border-radius:inherit;transition:background-color var(--effect-motion-instant, 100ms);pointer-events:none}:host(:hover:not(.inactive)) .thumb::after{background-color:var(--color-interaction-hover)}:host(:active:not(.inactive)) .thumb::after{background-color:var(--color-interaction-pressed)}:host(.checked) .thumb{transform:translateX(var(--dimension-offset-150))}:host(:active:not(.inactive)) .thumb{transform:translateX(0) scale(var(--dimension-scale-subtle)) !important;transition:transform var(--effect-motion-instant)}:host(.checked:active:not(.inactive)) .thumb{transform:translateX(var(--dimension-offset-150)) scale(var(--dimension-scale-subtle)) !important;transition:transform var(--effect-motion-instant)}`;const a=t(class t extends e{constructor(t){super();if(t!==false){this.__registerHost()}this.__attachShadow();this.dsChange=o(this,"dsChange");this.checked=false;this.inactive=false;this.handleClick=()=>{if(this.inactive)return;this.checked=!this.checked;this.dsChange.emit(this.checked)};this.handleKeyDown=t=>{if(this.inactive)return;if(t.key===" "||t.key==="Enter"){t.preventDefault();this.handleClick()}}}render(){return i(s,{key:"a8e22d676be8eaaa9d42b67a7d1d77e05f8aede9",role:"switch","aria-checked":String(this.checked),"aria-disabled":this.inactive||undefined,tabIndex:this.inactive?-1:0,class:{toggle:true,checked:this.checked,inactive:this.inactive},onClick:this.handleClick,onKeyDown:this.handleKeyDown},i("span",{key:"f963c1c2e7992c517f06b5368e6b7b553cf04cd2",class:"thumb"}))}static get style(){return r()}},[1,"ds-toggle",{checked:[1028],inactive:[4]}]);function c(){if(typeof customElements==="undefined"){return}const t=["ds-toggle"];t.forEach((t=>{switch(t){case"ds-toggle":if(!customElements.get(n(t))){customElements.define(n(t),a)}break}}))}c();const d=a;const h=c;export{d as DsToggle,h as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-toggle.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const o=["cool","neutral","warm"];const r="neutral";const n={cool:"Cool",neutral:"Neutral",warm:"Warm"};const t={cool:"var(--color-color-intent-blue-strong-background)",neutral:"var(--color-color-intent-grey-strong-background)",warm:"var(--color-color-intent-yellow-strong-background)"};const a="100% 100% at 0% 0%";function c(o){return t[o]}function l(o){const r=c(o);return`radial-gradient(${a}, var(--color-background-transparent) 0%, ${r} 100%)`}export{r as D,o as S,n as a,l as b};
|
|
2
|
+
//# sourceMappingURL=p-BU5fKLdO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["SHELL_GRADIENT_PRESETS","DEFAULT_SHELL_GRADIENT_PRESET","SHELL_GRADIENT_PRESET_LABELS","cool","neutral","warm","SHELL_GRADIENT_PRESET_STOP","GRADIENT_GEOMETRY","shellGradientPresetStopToken","preset","buildShellRadialGradientForPreset","stop"],"sources":["src/wc/nav/shell-gradient-presets.ts"],"sourcesContent":["/** Built-in shell chrome wash presets — cool (blue), neutral (grey), warm (yellow). */\nexport type ShellGradientPreset = 'cool' | 'neutral' | 'warm';\n\nexport const SHELL_GRADIENT_PRESETS: ShellGradientPreset[] = ['cool', 'neutral', 'warm'];\n\n/** Default wash when `gradient-preset` is omitted. */\nexport const DEFAULT_SHELL_GRADIENT_PRESET: ShellGradientPreset = 'neutral';\n\nexport const SHELL_GRADIENT_PRESET_LABELS: Record<ShellGradientPreset, string> = {\n cool: 'Cool',\n neutral: 'Neutral',\n warm: 'Warm',\n};\n\nconst SHELL_GRADIENT_PRESET_STOP: Record<ShellGradientPreset, string> = {\n cool: 'var(--color-color-intent-blue-strong-background)',\n neutral: 'var(--color-color-intent-grey-strong-background)',\n warm: 'var(--color-color-intent-yellow-strong-background)',\n};\n\nconst GRADIENT_GEOMETRY = '100% 100% at 0% 0%';\n\nexport function shellGradientPresetStopToken(preset: ShellGradientPreset): string {\n return SHELL_GRADIENT_PRESET_STOP[preset];\n}\n\nexport function isShellGradientPreset(value: string): value is ShellGradientPreset {\n return (SHELL_GRADIENT_PRESETS as string[]).includes(value);\n}\n\n/** Radial wash for a preset — transparent at top-left into the intent stop. */\nexport function buildShellRadialGradientForPreset(preset: ShellGradientPreset): string {\n const stop = shellGradientPresetStopToken(preset);\n return `radial-gradient(${GRADIENT_GEOMETRY}, var(--color-background-transparent) 0%, ${stop} 100%)`;\n}\n"],"mappings":"AAGO,MAAMA,EAAgD,CAAC,OAAQ,UAAW,QAG1E,MAAMC,EAAqD,UAE3D,MAAMC,EAAoE,CAC/EC,KAAM,OACNC,QAAS,UACTC,KAAM,QAGR,MAAMC,EAAkE,CACtEH,KAAM,mDACNC,QAAS,mDACTC,KAAM,sDAGR,MAAME,EAAoB,qBAEpB,SAAUC,EAA6BC,GAC3C,OAAOH,EAA2BG,EACpC,CAOM,SAAUC,EAAkCD,GAChD,MAAME,EAAOH,EAA6BC,GAC1C,MAAO,mBAAmBF,8CAA8DI,SAC1F,Q","ignoreList":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{p as e,H as s,c as t,h as i,a,t as r}from"./index.js";import{d}from"./p-DKG6W4pb.js";import{D as n,S as c}from"./p-BU5fKLdO.js";const l=()=>`.sc-ds-shell-gradient-picker-h{display:block}.shell-gradient-picker.sc-ds-shell-gradient-picker{display:flex;align-items:center;gap:var(--dimension-space-100);padding:var(--dimension-space-050) var(--dimension-space-075) var(--dimension-space-075)}`;const h=e(class e extends s{constructor(e){super();if(e!==false){this.__registerHost()}this.dsChange=t(this,"dsChange");this.value=n;this.handleSwatchSelect=e=>{if(e===this.value)return;this.value=e;this.dsChange.emit(e)}}render(){return i(a,{key:"decc075b09071f721637d8462dd18c9f4be943e5"},i("div",{key:"9444dfe9b5a2d7d2f0b40cb46a41cb86eb1b8082",class:"shell-gradient-picker",role:"radiogroup","aria-label":"Shell gradient theme"},c.map((e=>i("ds-shell-gradient-swatch",{key:e,preset:e,selected:this.value===e,onDsSelect:e=>{e.stopPropagation();this.handleSwatchSelect(e.detail)}})))))}static get style(){return l()}},[2,"ds-shell-gradient-picker",{value:[1537]}]);function o(){if(typeof customElements==="undefined"){return}const e=["ds-shell-gradient-picker","ds-shell-gradient-swatch"];e.forEach((e=>{switch(e){case"ds-shell-gradient-picker":if(!customElements.get(r(e))){customElements.define(r(e),h)}break;case"ds-shell-gradient-swatch":if(!customElements.get(r(e))){d()}break}}))}o();export{h as S,o as d};
|
|
2
|
+
//# sourceMappingURL=p-BgiK3sHs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["shellGradientPickerCss","ShellGradientPicker","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","value","DEFAULT_SHELL_GRADIENT_PRESET","handleSwatchSelect","preset","dsChange","emit","render","h","Host","key","class","role","SHELL_GRADIENT_PRESETS","map","selected","onDsSelect","e","stopPropagation","detail"],"sources":["src/wc/components/ShellGradientPicker/ShellGradientPicker.css?tag=ds-shell-gradient-picker&encapsulation=scoped","src/wc/components/ShellGradientPicker/ShellGradientPicker.tsx"],"sourcesContent":[":host {\n display: block;\n}\n\n.shell-gradient-picker {\n display: flex;\n align-items: center;\n gap: var(--dimension-space-100);\n padding: var(--dimension-space-050) var(--dimension-space-075) var(--dimension-space-075);\n}\n","import { Component, Prop, Event, EventEmitter, h, Host } from '@stencil/core';\nimport {\n SHELL_GRADIENT_PRESETS,\n DEFAULT_SHELL_GRADIENT_PRESET,\n type ShellGradientPreset,\n} from '../ShellGradientSwatch/shell-gradient-swatch-types';\n\n@Component({\n tag: 'ds-shell-gradient-picker',\n styleUrl: 'ShellGradientPicker.css',\n scoped: true,\n})\nexport class ShellGradientPicker {\n /** Active shell wash preset. */\n @Prop({ mutable: true, reflect: true }) value: ShellGradientPreset =\n DEFAULT_SHELL_GRADIENT_PRESET;\n\n @Event() dsChange!: EventEmitter<ShellGradientPreset>;\n\n private handleSwatchSelect = (preset: ShellGradientPreset) => {\n if (preset === this.value) return;\n this.value = preset;\n this.dsChange.emit(preset);\n };\n\n render() {\n return (\n <Host>\n <div\n class=\"shell-gradient-picker\"\n role=\"radiogroup\"\n aria-label=\"Shell gradient theme\"\n >\n {SHELL_GRADIENT_PRESETS.map(preset => (\n <ds-shell-gradient-swatch\n key={preset}\n preset={preset}\n selected={this.value === preset}\n onDsSelect={(e: CustomEvent<ShellGradientPreset>) => {\n e.stopPropagation();\n this.handleSwatchSelect(e.detail);\n }}\n />\n ))}\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"uIAAA,MAAMA,EAAyB,IAAM,2P,MCYxBC,EAAmBC,EAAA,MAAAD,UAAAE,EALhC,WAAAC,CAAAC,G,6EAO0CC,KAAAC,MACtCC,EAIMF,KAAAG,mBAAsBC,IAC5B,GAAIA,IAAWJ,KAAKC,MAAO,OAC3BD,KAAKC,MAAQG,EACbJ,KAAKK,SAASC,KAAKF,EAAO,CA0B7B,CAvBC,MAAAG,GACE,OACEC,EAACC,EAAI,CAAAC,IAAA,4CACHF,EAAA,OAAAE,IAAA,2CACEC,MAAM,wBACNC,KAAK,aAAY,aACN,wBAEVC,EAAuBC,KAAIV,GAC1BI,EAAA,4BACEE,IAAKN,EACLA,OAAQA,EACRW,SAAUf,KAAKC,QAAUG,EACzBY,WAAaC,IACXA,EAAEC,kBACFlB,KAAKG,mBAAmBc,EAAEE,OAAO,O","ignoreList":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{p as e,H as s,c as i,h as t,a as n,t as o}from"./index.js";import{d as r}from"./p-BgiK3sHs.js";import{d as a}from"./p-DKG6W4pb.js";import{T as d}from"./p-BRju0sEC.js";import{r as c}from"./p-CYJ-de0u.js";import{r as u}from"./p-C1cBr-Ri.js";function h(e){const{anchorRect:s,popupWidth:i,popupHeight:t,side:n,align:o,sideOffsetPx:r,alignOffsetPx:a,viewportPadPx:d,viewportWidth:c,viewportHeight:u}=e;let h=0;let l=0;switch(n){case"top":l=s.top-t-r;h=o==="start"?s.left+a:o==="end"?s.right-i+a:s.left+s.width/2-i/2+a;break;case"bottom":l=s.bottom+r;h=o==="start"?s.left+a:o==="end"?s.right-i+a:s.left+s.width/2-i/2+a;break;case"left":h=s.left-i-r;l=o==="start"?s.top+a:o==="end"?s.bottom-t+a:s.top+s.height/2-t/2+a;break;case"right":h=s.right+r;l=o==="start"?s.top+a:o==="end"?s.bottom-t+a:s.top+s.height/2-t/2+a;break}return{x:Math.min(Math.max(h,d),c-i-d),y:Math.min(Math.max(l,d),u-t-d)}}function l(e){return"variant"in e&&e.variant==="gradient-picker"}const m=()=>`.sc-ds-menu-h{--ds-focus-ring-width:var(--dimension-stroke-width-025, 2px);--ds-focus-ring-offset:var(--dimension-space-025, 2px);--ds-focus-ring-color:var(--color-interaction-focus)}.ds-focus-ring.sc-ds-menu:focus-visible{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:var(--ds-focus-ring-offset)}.ds-focus-ring.ds-focus-ring--visible.sc-ds-menu{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:var(--ds-focus-ring-offset)}.ds-focus-ring-inset.sc-ds-menu:focus-visible{outline:none}.ds-focus-ring-inset.sc-ds-menu:focus-visible::after{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:calc(-1 * var(--ds-focus-ring-width))}.ds-focus-ring-inset.ds-focus-ring--visible.sc-ds-menu{outline:none}.ds-focus-ring-inset.ds-focus-ring--visible.sc-ds-menu::after{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:calc(-1 * var(--ds-focus-ring-width))}.menu-popup.sc-ds-menu{box-sizing:border-box;display:flex;flex-direction:column;min-width:var(--dimension-menu-width-xs);max-width:var(--dimension-panel-width-lg);overflow:hidden;background-color:var(--color-background-primary);border-radius:var(--dimension-radius-075);box-shadow:var(--effect-shadow-elevated-floating);animation:menuFadeIn var(--effect-motion-short-2) forwards;backface-visibility:hidden;will-change:transform}.menu-popup.sc-ds-menu::after{content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;box-shadow:var(--effect-highlight-elevated-floating)}.menu-popup--closing.sc-ds-menu{animation:menuFadeOut var(--effect-motion-short-3) forwards}@keyframes menuFadeIn{from{opacity:0;transform:inherit scale(0.97)}to{opacity:1}}@keyframes menuFadeOut{from{opacity:1}to{opacity:0}}.menu-section.sc-ds-menu{display:flex;flex-direction:column;gap:var(--dimension-space-050);padding:var(--dimension-space-050)}.menu-section--divided.sc-ds-menu{border-bottom:var(--dimension-stroke-width-015) solid var(--color-border-tertiary)}.section-header.sc-ds-menu{display:flex;align-items:center;height:var(--dimension-size-400);padding:var(--dimension-space-050) var(--dimension-space-075);-webkit-user-select:none;user-select:none}.section-label.sc-ds-menu{color:var(--color-foreground-secondary)}.menu-section--gradient-picker.sc-ds-menu{padding-bottom:var(--dimension-space-050)}.menu-item.sc-ds-menu{display:flex;align-items:center;gap:var(--dimension-space-050);position:relative;width:100%;min-height:var(--dimension-size-400);padding:var(--dimension-space-075);box-sizing:border-box;border:none;border-radius:var(--dimension-radius-025);background:transparent;cursor:pointer;-webkit-user-select:none;user-select:none;text-align:left;color:inherit;--_hover-bg:var(--color-interaction-hover);--_pressed-bg:var(--color-interaction-pressed);--_selected-bg:var(--color-interaction-active)}.menu-item.sc-ds-menu:has(.menu-item__subtext){align-items:flex-start}.menu-item.sc-ds-menu::after{content:'';position:absolute;inset:0;border-radius:inherit;background:transparent;pointer-events:none;transition:none}.menu-item--selected.sc-ds-menu::after{background:var(--_selected-bg);transition:none}.menu-item.sc-ds-menu:hover:not(:disabled):not(.menu-item--selected)::after{background:var(--_hover-bg);transition:none}.menu-item.sc-ds-menu:active:not(:disabled)::after{background:var(--_pressed-bg);transition:none}.menu-item--inactive.sc-ds-menu{opacity:0.5;cursor:not-allowed;pointer-events:none}.menu-item--destructive.sc-ds-menu .menu-item__label.sc-ds-menu{color:var(--color-foreground-bold-negative) !important}.menu-item__content.sc-ds-menu{position:relative;z-index:1;display:flex;flex:1;flex-direction:column;gap:var(--dimension-space-025);min-width:0}.menu-item__label.sc-ds-menu{color:var(--color-foreground-secondary)}.menu-item.sc-ds-menu:has(.menu-item__subtext) .menu-item__label.sc-ds-menu,.menu-item--selected.sc-ds-menu .menu-item__label.sc-ds-menu{color:var(--color-foreground-primary)}.menu-item__subtext.sc-ds-menu{color:var(--color-foreground-secondary);line-height:1.4}.menu-item__toggle.sc-ds-menu{position:relative;z-index:1;flex-shrink:0;width:calc(var(--dimension-size-400) + var(--dimension-size-050));height:var(--dimension-size-250);border-radius:var(--dimension-radius-125);background-color:var(--color-background-translucent);transition:background-color var(--effect-motion-short-2)}.menu-item__toggle--on.sc-ds-menu{background-color:var(--color-background-medium-brand)}.menu-item__toggle-thumb.sc-ds-menu{position:absolute;top:var(--dimension-space-025);left:var(--dimension-space-025);width:var(--dimension-size-200);height:var(--dimension-size-200);border-radius:50%;background-color:var(--color-foreground-on-bold-background-primary);transition:transform var(--effect-motion-short-2)}.menu-item__toggle--on.sc-ds-menu .menu-item__toggle-thumb.sc-ds-menu{transform:translateX(var(--dimension-offset-200, 16px))}`;const f=8;const p=e(class e extends s{constructor(e){super();if(e!==false){this.__registerHost()}this.dsClose=i(this,"dsClose");this.dsSelect=i(this,"dsSelect");this.dsGradientSelect=i(this,"dsGradientSelect");this.open=false;this.items=[];this.sections=[];this.side="bottom";this.align="start";this.sideOffset=d.space050;this.alignOffset=0;this.initialFocusVisible=false;this.shouldRender=false;this.closing=false;this.pos={x:0,y:0};this.focusedIndex=0;this.positionReady=false;this.focusRingVisible=false;this.clickOutsideHandler=null;this.scrollResizeHandler=null;this.closeTimer=null;this.itemEls=[];this.positionRetryRaf=null;this.listenersReady=false}componentDidLoad(){if(this.open)this.onOpenChange(true)}disconnectedCallback(){this.cancelPositionRetry();this.teardownListeners()}onOpenChange(e){if(e){this.teardownListeners();this.shouldRender=true;this.closing=false;this.positionReady=false;this.listenersReady=false;this.focusRingVisible=this.initialFocusVisible;this.listenersReady=true;this.setupListeners();this.schedulePositionUpdate((()=>{this.focusInitialItem()}))}else if(this.shouldRender){this.cancelPositionRetry();this.closing=true;this.teardownListeners();this.listenersReady=false;this.closeTimer=setTimeout((()=>{this.shouldRender=false;this.closing=false;this.closeTimer=null}),this.closeAnimationMs)}}onAnchorChange(){if(this.open)this.schedulePositionUpdate()}onPositionPropsChange(){if(this.open)this.schedulePositionUpdate()}get viewportPadPx(){return c(d.space050,d.space050)}get sideOffsetPx(){return c(this.sideOffset,d.space050)}get alignOffsetPx(){return c(this.alignOffset,0)}get popupFallbackWidthPx(){return c(d.menuWidthXs,d.menuWidthXs)}get popupFallbackHeightPx(){return c(d.menuFallbackHeight,d.menuFallbackHeight)}get closeAnimationMs(){return u(d.motionShort3,d.animationDurationShort3)}get resolvedAnchor(){if(this.anchor)return this.anchor;if(this.anchorId)return document.getElementById(this.anchorId);return null}get activeSections(){if(this.sections.length>0)return this.sections;if(this.items.length>0)return[{items:this.items}];return[]}get flatItems(){return this.activeSections.flatMap((e=>l(e)?[]:e.items))}cancelPositionRetry(){if(this.positionRetryRaf!==null){cancelAnimationFrame(this.positionRetryRaf);this.positionRetryRaf=null}}schedulePositionUpdate(e){if(!this.open)return;this.cancelPositionRetry();this.positionReady=false;let s=f;const i=()=>{this.positionRetryRaf=null;if(!this.open)return;if(this.calculatePosition()){this.positionReady=true;e?.();return}if(s>0){s-=1;this.positionRetryRaf=requestAnimationFrame(i)}};this.positionRetryRaf=requestAnimationFrame(i)}calculatePosition(){const e=this.resolvedAnchor;if(!e)return false;const s=this.el.querySelector(".menu-popup");if(!s)return false;this.pos=h({anchorRect:e.getBoundingClientRect(),popupWidth:s.offsetWidth||this.popupFallbackWidthPx,popupHeight:s.offsetHeight||this.popupFallbackHeightPx,side:this.side,align:this.align,sideOffsetPx:this.sideOffsetPx,alignOffsetPx:this.alignOffsetPx,viewportPadPx:this.viewportPadPx,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight});return true}focusInitialItem(){const e=this.flatItems;const s=e.findIndex((e=>e.isSelected&&!e.isInactive));const i=e.findIndex((e=>!e.isInactive));this.focusedIndex=s>=0?s:i>=0?i:0;requestAnimationFrame((()=>{const e=this.el.querySelectorAll(".menu-item");e[this.focusedIndex]?.focus()}))}setupListeners(){this.clickOutsideHandler=e=>{const s=e.target;const i=this.el.querySelector(".menu-popup");const t=this.resolvedAnchor;if(i?.contains(s)||t?.contains(s))return;this.close()};this.scrollResizeHandler=()=>{if(this.shouldRender&&!this.closing)this.calculatePosition()};document.addEventListener("mousedown",this.clickOutsideHandler,true);window.addEventListener("scroll",this.scrollResizeHandler,true);window.addEventListener("resize",this.scrollResizeHandler)}teardownListeners(){if(this.clickOutsideHandler){document.removeEventListener("mousedown",this.clickOutsideHandler,true);this.clickOutsideHandler=null}if(this.scrollResizeHandler){window.removeEventListener("scroll",this.scrollResizeHandler,true);window.removeEventListener("resize",this.scrollResizeHandler);this.scrollResizeHandler=null}if(this.closeTimer){clearTimeout(this.closeTimer);this.closeTimer=null}}close(){this.resolvedAnchor?.focus();this.dsClose.emit();this.open=false;this.onOpenChange(false)}handleKeyDown(e){if(!this.shouldRender||this.closing)return;const s=this.flatItems;const i=s.map(((e,s)=>({it:e,i:s}))).filter((({it:e})=>!e.isInactive)).map((({i:e})=>e));if(!i.length)return;const t=i.indexOf(this.focusedIndex);const n=t<0?0:t;switch(e.key){case"ArrowDown":e.preventDefault();e.stopPropagation();this.focusRingVisible=true;this.focusedIndex=i[(n+1)%i.length];this.focusItem(this.focusedIndex);break;case"ArrowUp":e.preventDefault();e.stopPropagation();this.focusRingVisible=true;this.focusedIndex=i[(n-1+i.length)%i.length];this.focusItem(this.focusedIndex);break;case"Home":e.preventDefault();e.stopPropagation();this.focusRingVisible=true;this.focusedIndex=i[0];this.focusItem(this.focusedIndex);break;case"End":e.preventDefault();e.stopPropagation();this.focusRingVisible=true;this.focusedIndex=i[i.length-1];this.focusItem(this.focusedIndex);break;case"Escape":e.preventDefault();this.close();break;case"Tab":e.preventDefault();this.close();break}}focusItem(e){const s=this.el.querySelectorAll(".menu-item");s[e]?.focus()}handleItemClick(e){if(e.isInactive)return;this.dsSelect.emit(e);this.close()}handleGradientSelect(e){this.dsGradientSelect.emit(e)}render(){if(!this.shouldRender)return t(n,{style:{display:"contents"}});const e=this.activeSections;let s=0;const i={position:"fixed",left:"0",top:"0",transform:`translate(${Math.round(this.pos.x)}px, ${Math.round(this.pos.y)}px)`,zIndex:"9998",visibility:this.positionReady?"visible":"hidden"};if(this.menuWidth)i["width"]=this.menuWidth;if(this.minWidth)i["min-width"]=this.minWidth;return t(n,{style:{display:"contents"}},t("div",{class:{"menu-popup":true,"menu-popup--closing":this.closing},style:i,role:"menu","aria-label":"Menu","aria-orientation":"vertical"},e.map(((i,n)=>t("div",{key:n,class:{"menu-section":true,"menu-section--divided":n<e.length-1,"menu-section--gradient-picker":l(i)},role:i.header?"group":undefined,"aria-label":i.header},i.header&&t("div",{class:"section-header","aria-hidden":"true"},t("span",{class:"text-body-small-emphasis section-label"},i.header)),l(i)?t("ds-shell-gradient-picker",{value:i.value,onDsChange:e=>{e.stopPropagation();this.handleGradientSelect(e.detail)}}):i.items.map((e=>{const i=s++;const n=this.focusedIndex===i;return t("button",{key:i,type:"button",class:{"menu-item":true,"ds-focus-ring-inset":true,"ds-focus-ring--visible":n&&this.focusRingVisible,"menu-item--selected":!!e.isSelected,"menu-item--inactive":!!e.isInactive,"menu-item--destructive":!!e.isDestructive,"menu-item--focused":n},role:"menuitem","aria-current":e.isSelected?"true":undefined,disabled:e.isInactive,tabIndex:n?0:-1,onMouseDown:()=>{this.focusRingVisible=false},onClick:()=>this.handleItemClick(e),onFocus:()=>{this.focusedIndex=i}},t("div",{class:"menu-item__content"},t("span",{class:e.isSelected?"text-body-medium-emphasis menu-item__label":"text-body-medium menu-item__label"},e.label),e.subtext&&t("span",{class:"text-body-small menu-item__subtext"},e.subtext)),e.showToggle&&t("div",{class:{"menu-item__toggle":true,"menu-item__toggle--on":!!e.toggleValue},"aria-hidden":"true"},t("div",{class:"menu-item__toggle-thumb"})))})))))))}get el(){return this}static get watchers(){return{open:[{onOpenChange:0}],anchor:[{onAnchorChange:0}],anchorId:[{onAnchorChange:0}],side:[{onPositionPropsChange:0}],align:[{onPositionPropsChange:0}],sideOffset:[{onPositionPropsChange:0}],alignOffset:[{onPositionPropsChange:0}]}}static get style(){return m()}},[2,"ds-menu",{open:[1028],items:[16],sections:[16],side:[1],align:[1],sideOffset:[8,"side-offset"],alignOffset:[8,"align-offset"],menuWidth:[1,"menu-width"],minWidth:[1,"min-width"],anchor:[16],anchorId:[1,"anchor-id"],initialFocusVisible:[4,"initial-focus-visible"],shouldRender:[32],closing:[32],pos:[32],focusedIndex:[32],positionReady:[32],focusRingVisible:[32]},[[0,"keydown","handleKeyDown"]],{open:[{onOpenChange:0}],anchor:[{onAnchorChange:0}],anchorId:[{onAnchorChange:0}],side:[{onPositionPropsChange:0}],align:[{onPositionPropsChange:0}],sideOffset:[{onPositionPropsChange:0}],alignOffset:[{onPositionPropsChange:0}]}]);function g(){if(typeof customElements==="undefined"){return}const e=["ds-menu","ds-shell-gradient-picker","ds-shell-gradient-swatch"];e.forEach((e=>{switch(e){case"ds-menu":if(!customElements.get(o(e))){customElements.define(o(e),p)}break;case"ds-shell-gradient-picker":if(!customElements.get(o(e))){r()}break;case"ds-shell-gradient-swatch":if(!customElements.get(o(e))){a()}break}}))}g();export{p as M,g as d};
|
|
2
|
+
//# sourceMappingURL=p-CLmK4lRE.js.map
|