@ds-mo/ui 8.1.0 → 8.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/.build-stamp +1 -1
- package/dist/agent.json +501 -47
- package/dist/angular/ds-field.d.ts +1 -1
- package/dist/angular/ds-field.js +3 -3
- package/dist/angular/ds-input.d.ts +1 -1
- package/dist/angular/ds-input.js +3 -3
- package/dist/angular/ds-panel-nav.d.ts +1 -1
- package/dist/angular/ds-panel-nav.js +3 -3
- package/dist/angular/ds-radio.d.ts +18 -0
- package/dist/angular/{ds-radio-group.js → ds-radio.js} +12 -12
- package/dist/angular/ds-slider.d.ts +12 -3
- package/dist/angular/ds-slider.js +8 -4
- package/dist/angular/index.d.ts +1 -1
- package/dist/angular/index.js +1 -1
- package/dist/angular/proxies.d.ts +1 -1
- package/dist/angular/proxies.js +1 -1
- package/dist/angular/radio-value-accessor.d.ts +1 -1
- package/dist/angular/radio-value-accessor.js +2 -2
- package/dist/components/ds-app-shell.js +1 -1
- package/dist/components/ds-badge.js +1 -1
- package/dist/components/ds-banner.js +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-button-filled.js +1 -1
- package/dist/components/ds-button-unfilled.js +1 -1
- package/dist/components/ds-card-data-viz-donut.js +1 -1
- package/dist/components/ds-card-data-viz-donut.js.map +1 -1
- package/dist/components/ds-card-setting.js +1 -1
- package/dist/components/ds-card.js +1 -1
- package/dist/components/ds-chart-bar.js +1 -1
- package/dist/components/ds-chart-bar.js.map +1 -1
- package/dist/components/ds-chart-donut.js +1 -1
- package/dist/components/ds-chart-donut.js.map +1 -1
- package/dist/components/ds-chart-legend.js +1 -1
- package/dist/components/ds-chart-line.js +1 -1
- package/dist/components/ds-chart-line.js.map +1 -1
- package/dist/components/ds-checkbox.js +1 -1
- package/dist/components/ds-chip.js +1 -1
- package/dist/components/ds-divider.js +1 -1
- package/dist/components/ds-empty-state.js +1 -1
- package/dist/components/ds-field.js +1 -1
- package/dist/components/ds-field.js.map +1 -1
- package/dist/components/ds-icon.js +1 -1
- package/dist/components/ds-input.js +1 -1
- package/dist/components/ds-input.js.map +1 -1
- package/dist/components/ds-loader.js +1 -1
- package/dist/components/ds-menu.js +1 -1
- package/dist/components/ds-modal.js +1 -1
- package/dist/components/ds-modal.js.map +1 -1
- package/dist/components/ds-pagination.js +1 -1
- package/dist/components/ds-panel-nav.js +1 -1
- package/dist/components/ds-panel-nav.js.map +1 -1
- package/dist/components/ds-panel-sub-nav.js +1 -1
- package/dist/components/ds-panel-sub-nav.js.map +1 -1
- package/dist/components/ds-panel-tools.js +1 -1
- package/dist/components/{ds-radio-group.d.ts → ds-radio.d.ts} +4 -4
- package/dist/components/ds-radio.js +2 -0
- package/dist/components/ds-radio.js.map +1 -0
- package/dist/components/ds-select-multi.js +1 -1
- package/dist/components/ds-select-multi.js.map +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.js +1 -1
- package/dist/components/ds-shell-gradient-swatch.js +1 -1
- package/dist/components/ds-skeleton.js +1 -1
- package/dist/components/ds-slider.js +1 -1
- package/dist/components/ds-slider.js.map +1 -1
- package/dist/components/ds-switch.js +1 -1
- package/dist/components/ds-tab-group.js +1 -1
- package/dist/components/ds-tab-group.js.map +1 -1
- package/dist/components/ds-table.js +1 -1
- package/dist/components/ds-tag.js +1 -1
- package/dist/components/ds-text.js +1 -1
- package/dist/components/ds-tooltip-data-viz.js +1 -1
- package/dist/components/ds-tooltip.js +1 -1
- package/dist/components/{p-CTmsQjsE.js → p-BU_gxTiw.js} +2 -2
- package/dist/components/p-BU_gxTiw.js.map +1 -0
- package/dist/components/{p-Ckiwpsgw.js → p-BjhTeU17.js} +2 -2
- package/dist/components/{p-Du9UUSJ5.js → p-C91iXoXj.js} +2 -2
- package/dist/components/{p-WdtWRvVr.js → p-CDu_LfhF.js} +2 -2
- package/dist/components/{p-_zP4v-Al.js → p-CSyIAX11.js} +2 -2
- package/dist/components/p-CSyIAX11.js.map +1 -0
- package/dist/components/{p-BMbadvZo.js → p-Cj4vIqqx.js} +2 -2
- package/dist/components/{p-BMbadvZo.js.map → p-Cj4vIqqx.js.map} +1 -1
- package/dist/components/{p-wxw8arTd.js → p-Cpr3K41-.js} +1 -1
- package/dist/components/{p-wxw8arTd.js.map → p-Cpr3K41-.js.map} +1 -1
- package/dist/components/{p-CwaC4wLu.js → p-CqsgiNwB.js} +2 -2
- package/dist/components/p-CqsgiNwB.js.map +1 -0
- package/dist/components/{p-JsVSx7ZR.js → p-DHJZDpNk.js} +2 -2
- package/dist/components/{p-DDBLO7bY.js → p-DKVDYHxb.js} +2 -2
- package/dist/components/p-DRqbwDzo.js +2 -0
- package/dist/components/p-DRqbwDzo.js.map +1 -0
- package/dist/components/{p-B2FhhQba.js → p-KeMecQN9.js} +2 -2
- package/dist/components/p-NwPqPArp.js +2 -0
- package/dist/components/p-NwPqPArp.js.map +1 -0
- package/dist/components/{p-COzps7J4.js → p-PP5602IN.js} +2 -2
- package/dist/components/p-PP5602IN.js.map +1 -0
- package/dist/components/p-VKIsOVza.js +2 -0
- package/dist/components/p-VKIsOVza.js.map +1 -0
- package/dist/components/p-kGSowBA8.js +2 -0
- package/dist/components/{p-auwU64d8.js.map → p-kGSowBA8.js.map} +1 -1
- package/dist/docs/components.json +1391 -166
- package/dist/lib/components/Text/text-types.d.ts +1 -1
- package/dist/react/components.d.ts +1 -1
- package/dist/react/components.js +1 -1
- package/dist/react/ds-radio.d.ts +12 -0
- package/dist/react/ds-radio.js +12 -0
- package/dist/react/ds-slider.d.ts +4 -3
- package/dist/react/ds-slider.js +4 -1
- package/dist/types/components/ButtonUnfilled/ButtonUnfilled.d.ts +2 -1
- package/dist/types/components/Field/Field.d.ts +37 -2
- package/dist/types/components/Icon/Icon.d.ts +6 -1
- package/dist/types/components/Input/Input.d.ts +26 -0
- package/dist/types/components/Loader/Loader.d.ts +6 -1
- package/dist/types/components/Menu/Menu.d.ts +6 -0
- package/dist/types/components/Modal/Modal.d.ts +5 -0
- package/dist/types/components/PanelNav/PanelNav.d.ts +9 -0
- package/dist/types/components/{RadioGroup/RadioGroup.d.ts → Radio/Radio.d.ts} +18 -2
- package/dist/types/components/Radio/index.d.ts +2 -0
- package/dist/types/components/Slider/Slider.d.ts +101 -7
- package/dist/types/components/Switch/Switch.d.ts +4 -0
- package/dist/types/components/TabGroup/TabGroup.d.ts +1 -0
- package/dist/types/components/Text/Text.d.ts +6 -0
- package/dist/types/components/Text/text-types.d.ts +1 -1
- package/dist/types/components.d.ts +431 -46
- package/package.json +9 -4
- package/dist/angular/ds-radio-group.d.ts +0 -15
- package/dist/components/ds-radio-group.js +0 -2
- package/dist/components/ds-radio-group.js.map +0 -1
- package/dist/components/p-BEmVLLnN.js +0 -2
- package/dist/components/p-BEmVLLnN.js.map +0 -1
- package/dist/components/p-BcB-zkOx.js +0 -2
- package/dist/components/p-BcB-zkOx.js.map +0 -1
- package/dist/components/p-COzps7J4.js.map +0 -1
- package/dist/components/p-CTmsQjsE.js.map +0 -1
- package/dist/components/p-CwaC4wLu.js.map +0 -1
- package/dist/components/p-_zP4v-Al.js.map +0 -1
- package/dist/components/p-auwU64d8.js +0 -2
- package/dist/components/p-f0a1l4Uc.js +0 -2
- package/dist/components/p-f0a1l4Uc.js.map +0 -1
- package/dist/react/ds-radio-group.d.ts +0 -12
- package/dist/react/ds-radio-group.js +0 -12
- package/dist/types/components/RadioGroup/index.d.ts +0 -2
- /package/dist/components/{p-Ckiwpsgw.js.map → p-BjhTeU17.js.map} +0 -0
- /package/dist/components/{p-Du9UUSJ5.js.map → p-C91iXoXj.js.map} +0 -0
- /package/dist/components/{p-WdtWRvVr.js.map → p-CDu_LfhF.js.map} +0 -0
- /package/dist/components/{p-JsVSx7ZR.js.map → p-DHJZDpNk.js.map} +0 -0
- /package/dist/components/{p-DDBLO7bY.js.map → p-DKVDYHxb.js.map} +0 -0
- /package/dist/components/{p-B2FhhQba.js.map → p-KeMecQN9.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["tabsToMenuSections","tabs","selectedId","sections","batch","item","isTabDivider","length","push","items","label","value","id","dot","isSelected","isInactive","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","moreTabsLabel","resolvedTabs","urlDerivedValue","hideTabsForDetailRoute","tabsCollapsed","menuOpen","tabLayoutCommitted","visibleTabs","overflowTabs","menuInitialFocusVisible","overflowRovingFocused","focusedTabId","headerEl","triggerEl","menuEl","visibleTabListEl","probeTabListEl","resizeObserver","intrinsicWidthRetryCount","tabLayoutPendingFrames","panelNavTransition","ChromeTransitionGate","panelToolsTransition","overflowCoalescer","createRafCoalescer","updateTabsCollapsed","chromeTransitionShell","committedSection","pendingSection","onChromeTransitionStart","event","source","readChromeTransitionSource","enter","phase","readChromeTransitionPhase","onChromeTransitionEnd","exit","isActive","scheduleOverflowCheck","handleOverflowFocus","handleOverflowBlur","effectiveValue","renderedSelectableTabs","hasOverflowTabs","getSelectableTabs","syncFocusedTabId","preferred","some","tab","first","find","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","scrollWidth","getHeaderGap","style","columnGap","gap","getOverflowTriggerReserveWidth","getBoundingClientRect","getProbeTabMetrics","tabList","children","Array","from","child","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","querySelector","focus","preventScroll","focusVisibleTab","focusLastVisibleTab","last","reverse","findEnabledVisibleTab","step","index","handleTabKeyDown","targetId","target","getAttribute","focusedId","key","focused","preventDefault","currentIndex","findIndex","nextIndex","setFocus","reversedIndex","toggleTabMenu","options","minWidth","focusVisible","handleTriggerKeyDown","renderTabList","probe","h","role","class","heading","ref","next","onKeyDown","onFocusin","type","panelId","disabled","tabIndex","onClick","onFocus","as","variant","emphasis","color","hasRing","render","sectionReady","hasTabs","tabGroupKey","renderedTabs","Host","inert","wrap","icon","activeFill","hasBorder","focusTabIndex","haspopup","expanded","onDsClick","onFocusout","side","align","sideOffset","alignOffset","initialFocusVisible","onDsSelect","onDsClose"],"sources":["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":["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 dot: item.dot,\n isSelected: item.id === selectedId,\n isInactive: item.isInactive,\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@import '../../utils/control-inactive.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) — bar is a transparent frame. */\n:host-context(ds-app-shell:not([gradient-preset='none'])) .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__tabs-visible {\n flex: 1;\n min-width: 0;\n width: 100%;\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 > div {\n width: max-content;\n}\n\n.bar-nav__tab-list {\n display: flex;\n align-items: center;\n gap: var(--dimension-space-050);\n position: relative;\n width: max-content;\n}\n\n.bar-nav__tab {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--dimension-space-050);\n height: var(--dimension-size-400);\n min-width: var(--dimension-size-400);\n padding: var(--dimension-space-075);\n box-sizing: border-box;\n border: none;\n border-radius: var(--dimension-radius-025);\n background-color: transparent;\n color: var(--_bar-nav-fg-secondary);\n cursor: pointer;\n position: relative;\n flex-shrink: 0;\n -webkit-user-select: none;\n user-select: none;\n transition: color var(--effect-motion-short-2);\n}\n\n.bar-nav__tab::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--dimension-radius-025);\n background: transparent;\n pointer-events: none;\n}\n\n.bar-nav__tab:hover::after {\n background: var(--_bar-nav-hover);\n}\n\n.bar-nav__tab:active::after {\n background: var(--_bar-nav-pressed);\n}\n\n.bar-nav__tab--selected {\n color: var(--_bar-nav-fg-primary);\n}\n\n.bar-nav__tab-label {\n position: relative;\n display: inline-flex;\n align-items: center;\n padding: 0 var(--dimension-space-025);\n white-space: nowrap;\n}\n\n.bar-nav__tab-label--dot {\n padding-right: calc(var(--dimension-space-025) + var(--dimension-space-050));\n}\n\n.bar-nav__tab-dot {\n position: absolute;\n top: 0;\n right: 0;\n pointer-events: none;\n}\n\n.bar-nav__tab-divider {\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: var(--dimension-space-100);\n height: var(--dimension-size-400);\n padding-block: var(--dimension-space-075);\n flex-shrink: 0;\n pointer-events: none;\n}\n\n.bar-nav__tab-divider-line {\n width: var(--dimension-stroke-width-012);\n align-self: stretch;\n background-color: var(--_bar-nav-border);\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-fg: var(--_bar-nav-fg-secondary);\n --ds-button-unfilled-fg-active: var(--_bar-nav-fg-primary);\n --ds-interaction-hover: var(--_bar-nav-hover);\n --ds-interaction-pressed: 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 Color comes from ds-text color=\"primary\"; beat Text's inline-box display. */\nds-text.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 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 '../../shell/nav-chrome';\nimport type { MenuItemData } from '../Menu/menu-types';\nimport { getSelectableTabs, isTabDivider, type TabItemTab } 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 tabsOverflowContainer,\n tabsToOverflowMenuSections,\n trimTrailingDividers,\n visibleTabCountForWidth,\n} from './bar-nav-tabs-menu-utils';\nimport {\n CHROME_TRANSITION_END,\n CHROME_TRANSITION_START,\n ChromeTransitionGate,\n createRafCoalescer,\n readChromeTransitionSource,\n readChromeTransitionPhase,\n} from '../../shell/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 @Prop() moreTabsLabel: string = 'More tabs';\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 @State() private focusedTabId = '';\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 visibleTabListEl: HTMLElement | null = null;\n private probeTabListEl: HTMLElement | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private intrinsicWidthRetryCount = 0;\n private tabLayoutPendingFrames = 0;\n private readonly panelNavTransition = new ChromeTransitionGate();\n private readonly panelToolsTransition = new ChromeTransitionGate();\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 renderedSelectableTabs(): TabItemTab[] {\n const tabs = this.hasOverflowTabs ? this.visibleTabs : this.resolvedTabs;\n return getSelectableTabs(tabs);\n }\n\n private get hasOverflowTabs(): boolean {\n return this.tabLayoutCommitted && this.tabsCollapsed && this.overflowTabs.length > 0;\n }\n\n private syncFocusedTabId(preferred: string, tabs: TabItemTab[]) {\n if (tabs.some(tab => tab.id === preferred && !tab.isInactive)) {\n this.focusedTabId = preferred;\n return;\n }\n const first = tabs.find(tab => !tab.isInactive);\n this.focusedTabId = first?.id ?? '';\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.syncFocusedTabId(this.effectiveValue, this.renderedSelectableTabs);\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 this.syncFocusedTabId(this.effectiveValue, getSelectableTabs(this.resolvedTabs));\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 return this.probeTabListEl?.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 = this.probeTabListEl;\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 this.syncFocusedTabId(\n this.effectiveValue,\n getSelectableTabs(nextCollapsed ? visibleTabs : this.resolvedTabs),\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 = this.visibleTabListEl?.querySelector(\n `[data-tab-id=\"${this.effectiveValue}\"]`,\n ) as HTMLElement | null;\n tab?.focus({ preventScroll: true });\n }\n\n private focusVisibleTab(id: string) {\n this.focusedTabId = id;\n const tab = this.visibleTabListEl?.querySelector(\n `[data-tab-id=\"${id}\"]`,\n ) as HTMLElement | null;\n tab?.focus({ preventScroll: true });\n }\n\n private focusLastVisibleTab() {\n const last = [...this.renderedSelectableTabs].reverse().find(tab => !tab.isInactive);\n if (last) this.focusVisibleTab(last.id);\n }\n\n private findEnabledVisibleTab(from: number, step: 1 | -1): number | null {\n const tabs = this.renderedSelectableTabs;\n for (let index = from + step; index >= 0 && index < tabs.length; index += step) {\n if (!tabs[index]?.isInactive) return index;\n }\n return null;\n }\n\n private handleTabKeyDown(e: KeyboardEvent) {\n const tabs = this.renderedSelectableTabs;\n if (!tabs.length) return;\n const targetId = (e.target as HTMLElement | null)?.getAttribute('data-tab-id');\n const focusedId = targetId ?? this.focusedTabId;\n\n if (e.key === 'Enter' || e.key === ' ') {\n const focused = tabs.find(tab => tab.id === focusedId);\n if (!focused || focused.isInactive) return;\n e.preventDefault();\n this.selectTab(focused.id);\n return;\n }\n\n const currentIndex = tabs.findIndex(tab => tab.id === focusedId);\n if (currentIndex < 0) return;\n\n let nextIndex: number | null;\n if (e.key === 'ArrowRight') {\n nextIndex = this.findEnabledVisibleTab(currentIndex, 1);\n if (nextIndex === null && this.hasOverflowTabs) {\n e.preventDefault();\n this.overflowRovingFocused = true;\n void this.triggerEl?.setFocus?.();\n return;\n }\n } else if (e.key === 'ArrowLeft') {\n nextIndex = this.findEnabledVisibleTab(currentIndex, -1);\n } else if (e.key === 'Home') {\n nextIndex = tabs.findIndex(tab => !tab.isInactive);\n } else if (e.key === 'End') {\n const reversedIndex = [...tabs].reverse().findIndex(tab => !tab.isInactive);\n nextIndex = reversedIndex < 0 ? null : tabs.length - 1 - reversedIndex;\n } else {\n return;\n }\n\n if (nextIndex === null || nextIndex < 0 || nextIndex === currentIndex) return;\n e.preventDefault();\n this.focusVisibleTab(tabs[nextIndex].id);\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 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 this.focusLastVisibleTab();\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 private renderTabList(tabs: BarNavTab[], probe: boolean) {\n return (\n <div\n role=\"tablist\"\n class=\"bar-nav__tab-list\"\n aria-label={this.heading}\n ref={el => {\n if (probe) {\n const next = (el as HTMLElement) ?? null;\n if (next === this.probeTabListEl) return;\n this.probeTabListEl = next;\n if (next) {\n this.intrinsicWidthRetryCount = 0;\n this.tabLayoutPendingFrames = 0;\n this.scheduleOverflowCheck();\n }\n } else {\n this.visibleTabListEl = (el as HTMLElement) ?? null;\n }\n }}\n onKeyDown={probe ? undefined : (e: KeyboardEvent) => this.handleTabKeyDown(e)}\n onFocusin={probe ? undefined : () => {\n this.overflowRovingFocused = false;\n }}\n >\n {tabs.map((tab, index) => {\n if (isTabDivider(tab)) {\n return (\n <div class=\"bar-nav__tab-divider\" key={`divider-${index}`} aria-hidden=\"true\">\n <div class=\"bar-nav__tab-divider-line\" />\n </div>\n );\n }\n\n const isSelected = tab.id === this.effectiveValue;\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n data-tab-id={tab.id}\n class={{\n 'bar-nav__tab': true,\n 'bar-nav__tab--selected': isSelected,\n 'ds-focus-ring-inset': true,\n 'ds-control-inactive': !!tab.isInactive,\n }}\n aria-selected={isSelected ? 'true' : 'false'}\n aria-disabled={tab.isInactive ? 'true' : undefined}\n aria-controls={tab.panelId ?? undefined}\n disabled={tab.isInactive}\n tabIndex={\n !probe && !this.overflowRovingFocused && tab.id === this.focusedTabId\n ? 0\n : -1\n }\n onClick={() => !probe && !tab.isInactive && this.selectTab(tab.id)}\n onFocus={() => {\n if (!probe) this.focusedTabId = tab.id;\n }}\n >\n <span\n class={{\n 'bar-nav__tab-label': true,\n 'bar-nav__tab-label--dot': !!tab.dot,\n }}\n >\n <ds-text as=\"span\" variant=\"text-body-medium\" emphasis={isSelected} color=\"inherit\">\n {tab.label}\n </ds-text>\n {tab.dot && (\n <ds-badge\n class=\"bar-nav__tab-dot\"\n variant=\"dot\"\n hasRing={false}\n label=\"\"\n aria-hidden=\"true\"\n />\n )}\n </span>\n </button>\n );\n })}\n </div>\n );\n }\n\n render() {\n // Section gating only applies when `basePath` is set (SPA section sync).\n // Tabs without a base path must still render — otherwise a single-tab bar\n // (or any non-routed tabs) silently falls through to an empty header.\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 <div key={`probe-${tabGroupKey}`}>\n {this.renderTabList(this.resolvedTabs, true)}\n </div>\n </div>\n )}\n\n {hasTabs && this.tabLayoutCommitted && renderedTabs.length > 0 && (\n <div class=\"bar-nav__left\">\n <div key={`visible-${tabGroupKey}`} class=\"bar-nav__tabs-visible\">\n {this.renderTabList(renderedTabs, false)}\n </div>\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 <ds-text\n class=\"bar-nav__heading\"\n as=\"span\"\n variant=\"text-body-medium\"\n emphasis\n color=\"primary\"\n wrap=\"nowrap\"\n >\n {this.heading}\n </ds-text>\n )}\n\n {hasTabs && this.hasOverflowTabs && (\n <ds-button-unfilled variant=\"icon\"\n class={{\n 'bar-nav__overflow-trigger': true,\n }}\n icon=\"Ellipses\"\n isActive={this.menuOpen}\n activeFill={false}\n hasBorder={false}\n focusTabIndex={this.overflowRovingFocused ? 0 : -1}\n ref={(el?: HTMLDsButtonUnfilledElement) => {\n this.triggerEl = (el as (HTMLElement & { setFocus?: () => Promise<void> })) ?? null;\n }}\n haspopup=\"menu\"\n expanded={this.menuOpen}\n aria-label={this.moreTabsLabel}\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":["tabsToMenuSections","tabs","selectedId","sections","batch","item","isTabDivider","length","push","items","label","value","id","dot","isSelected","isInactive","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","moreTabsLabel","resolvedTabs","urlDerivedValue","hideTabsForDetailRoute","tabsCollapsed","menuOpen","tabLayoutCommitted","visibleTabs","overflowTabs","menuInitialFocusVisible","overflowRovingFocused","focusedTabId","headerEl","triggerEl","menuEl","visibleTabListEl","probeTabListEl","resizeObserver","intrinsicWidthRetryCount","tabLayoutPendingFrames","panelNavTransition","ChromeTransitionGate","panelToolsTransition","overflowCoalescer","createRafCoalescer","updateTabsCollapsed","chromeTransitionShell","committedSection","pendingSection","onChromeTransitionStart","event","source","readChromeTransitionSource","enter","phase","readChromeTransitionPhase","onChromeTransitionEnd","exit","isActive","scheduleOverflowCheck","handleOverflowFocus","handleOverflowBlur","effectiveValue","renderedSelectableTabs","hasOverflowTabs","getSelectableTabs","syncFocusedTabId","preferred","some","tab","first","find","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","scrollWidth","getHeaderGap","style","columnGap","gap","getOverflowTriggerReserveWidth","getBoundingClientRect","getProbeTabMetrics","tabList","children","Array","from","child","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","querySelector","focus","preventScroll","focusVisibleTab","focusLastVisibleTab","last","reverse","findEnabledVisibleTab","step","index","handleTabKeyDown","targetId","target","getAttribute","focusedId","key","focused","preventDefault","currentIndex","findIndex","nextIndex","setFocus","reversedIndex","toggleTabMenu","options","minWidth","focusVisible","handleTriggerKeyDown","renderTabList","probe","h","role","class","heading","ref","next","onKeyDown","onFocusin","type","panelId","disabled","tabIndex","onClick","onFocus","as","variant","emphasis","color","hasRing","render","sectionReady","hasTabs","tabGroupKey","renderedTabs","Host","inert","wrap","icon","activeFill","hasBorder","focusTabIndex","haspopup","expanded","onDsClick","onFocusout","side","align","sideOffset","alignOffset","initialFocusVisible","onDsSelect","onDsClose"],"sources":["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":["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 dot: item.dot,\n isSelected: item.id === selectedId,\n isInactive: item.isInactive,\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@import '../../utils/control-inactive.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) — bar is a transparent frame. */\n:host-context(ds-app-shell:not([gradient-preset='none'])) .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__tabs-visible {\n flex: 1;\n min-width: 0;\n width: 100%;\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 > div {\n width: max-content;\n}\n\n.bar-nav__tab-list {\n display: flex;\n align-items: center;\n gap: var(--dimension-space-050);\n position: relative;\n width: max-content;\n}\n\n.bar-nav__tab {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--dimension-space-050);\n height: var(--dimension-size-400);\n min-width: var(--dimension-size-400);\n padding: var(--dimension-space-075);\n box-sizing: border-box;\n border: none;\n border-radius: var(--dimension-radius-025);\n background-color: transparent;\n color: var(--_bar-nav-fg-secondary);\n cursor: pointer;\n position: relative;\n flex-shrink: 0;\n -webkit-user-select: none;\n user-select: none;\n transition: color var(--effect-motion-short-2);\n}\n\n.bar-nav__tab::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--dimension-radius-025);\n background: transparent;\n pointer-events: none;\n}\n\n.bar-nav__tab:hover::after {\n background: var(--_bar-nav-hover);\n}\n\n.bar-nav__tab:active::after {\n background: var(--_bar-nav-pressed);\n}\n\n.bar-nav__tab--selected {\n color: var(--_bar-nav-fg-primary);\n}\n\n.bar-nav__tab-label {\n position: relative;\n display: inline-flex;\n align-items: center;\n padding: 0 var(--dimension-space-025);\n white-space: nowrap;\n}\n\n.bar-nav__tab-label--dot {\n padding-right: calc(var(--dimension-space-025) + var(--dimension-space-050));\n}\n\n.bar-nav__tab-dot {\n position: absolute;\n top: 0;\n right: 0;\n pointer-events: none;\n}\n\n.bar-nav__tab-divider {\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: var(--dimension-space-100);\n height: var(--dimension-size-400);\n padding-block: var(--dimension-space-075);\n flex-shrink: 0;\n pointer-events: none;\n}\n\n.bar-nav__tab-divider-line {\n width: var(--dimension-stroke-width-012);\n align-self: stretch;\n background-color: var(--_bar-nav-border);\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-fg: var(--_bar-nav-fg-secondary);\n --ds-button-unfilled-fg-active: var(--_bar-nav-fg-primary);\n --ds-interaction-hover: var(--_bar-nav-hover);\n --ds-interaction-pressed: 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 Color comes from ds-text color=\"primary\"; beat Text's inline-box display. */\nds-text.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 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 '../../shell/nav-chrome';\nimport type { MenuItemData } from '../Menu/menu-types';\nimport { getSelectableTabs, isTabDivider, type TabItemTab } 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 tabsOverflowContainer,\n tabsToOverflowMenuSections,\n trimTrailingDividers,\n visibleTabCountForWidth,\n} from './bar-nav-tabs-menu-utils';\nimport {\n CHROME_TRANSITION_END,\n CHROME_TRANSITION_START,\n ChromeTransitionGate,\n createRafCoalescer,\n readChromeTransitionSource,\n readChromeTransitionPhase,\n} from '../../shell/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 @Prop() moreTabsLabel: string = 'More tabs';\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 @State() private focusedTabId = '';\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 visibleTabListEl: HTMLElement | null = null;\n private probeTabListEl: HTMLElement | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private intrinsicWidthRetryCount = 0;\n private tabLayoutPendingFrames = 0;\n private readonly panelNavTransition = new ChromeTransitionGate();\n private readonly panelToolsTransition = new ChromeTransitionGate();\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 renderedSelectableTabs(): TabItemTab[] {\n const tabs = this.hasOverflowTabs ? this.visibleTabs : this.resolvedTabs;\n return getSelectableTabs(tabs);\n }\n\n private get hasOverflowTabs(): boolean {\n return this.tabLayoutCommitted && this.tabsCollapsed && this.overflowTabs.length > 0;\n }\n\n private syncFocusedTabId(preferred: string, tabs: TabItemTab[]) {\n if (tabs.some(tab => tab.id === preferred && !tab.isInactive)) {\n this.focusedTabId = preferred;\n return;\n }\n const first = tabs.find(tab => !tab.isInactive);\n this.focusedTabId = first?.id ?? '';\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.syncFocusedTabId(this.effectiveValue, this.renderedSelectableTabs);\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 this.syncFocusedTabId(this.effectiveValue, getSelectableTabs(this.resolvedTabs));\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 return this.probeTabListEl?.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 = this.probeTabListEl;\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 this.syncFocusedTabId(\n this.effectiveValue,\n getSelectableTabs(nextCollapsed ? visibleTabs : this.resolvedTabs),\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 = this.visibleTabListEl?.querySelector(\n `[data-tab-id=\"${this.effectiveValue}\"]`,\n ) as HTMLElement | null;\n tab?.focus({ preventScroll: true });\n }\n\n private focusVisibleTab(id: string) {\n this.focusedTabId = id;\n const tab = this.visibleTabListEl?.querySelector(\n `[data-tab-id=\"${id}\"]`,\n ) as HTMLElement | null;\n tab?.focus({ preventScroll: true });\n }\n\n private focusLastVisibleTab() {\n const last = [...this.renderedSelectableTabs].reverse().find(tab => !tab.isInactive);\n if (last) this.focusVisibleTab(last.id);\n }\n\n private findEnabledVisibleTab(from: number, step: 1 | -1): number | null {\n const tabs = this.renderedSelectableTabs;\n for (let index = from + step; index >= 0 && index < tabs.length; index += step) {\n if (!tabs[index]?.isInactive) return index;\n }\n return null;\n }\n\n private handleTabKeyDown(e: KeyboardEvent) {\n const tabs = this.renderedSelectableTabs;\n if (!tabs.length) return;\n const targetId = (e.target as HTMLElement | null)?.getAttribute('data-tab-id');\n const focusedId = targetId ?? this.focusedTabId;\n\n if (e.key === 'Enter' || e.key === ' ') {\n const focused = tabs.find(tab => tab.id === focusedId);\n if (!focused || focused.isInactive) return;\n e.preventDefault();\n this.selectTab(focused.id);\n return;\n }\n\n const currentIndex = tabs.findIndex(tab => tab.id === focusedId);\n if (currentIndex < 0) return;\n\n let nextIndex: number | null;\n if (e.key === 'ArrowRight') {\n nextIndex = this.findEnabledVisibleTab(currentIndex, 1);\n if (nextIndex === null && this.hasOverflowTabs) {\n e.preventDefault();\n this.overflowRovingFocused = true;\n void this.triggerEl?.setFocus?.();\n return;\n }\n } else if (e.key === 'ArrowLeft') {\n nextIndex = this.findEnabledVisibleTab(currentIndex, -1);\n } else if (e.key === 'Home') {\n nextIndex = tabs.findIndex(tab => !tab.isInactive);\n } else if (e.key === 'End') {\n const reversedIndex = [...tabs].reverse().findIndex(tab => !tab.isInactive);\n nextIndex = reversedIndex < 0 ? null : tabs.length - 1 - reversedIndex;\n } else {\n return;\n }\n\n if (nextIndex === null || nextIndex < 0 || nextIndex === currentIndex) return;\n e.preventDefault();\n this.focusVisibleTab(tabs[nextIndex].id);\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 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 this.focusLastVisibleTab();\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 private renderTabList(tabs: BarNavTab[], probe: boolean) {\n return (\n <div\n role=\"tablist\"\n class=\"bar-nav__tab-list\"\n aria-label={this.heading}\n ref={el => {\n if (probe) {\n const next = (el as HTMLElement) ?? null;\n if (next === this.probeTabListEl) return;\n this.probeTabListEl = next;\n if (next) {\n this.intrinsicWidthRetryCount = 0;\n this.tabLayoutPendingFrames = 0;\n this.scheduleOverflowCheck();\n }\n } else {\n this.visibleTabListEl = (el as HTMLElement) ?? null;\n }\n }}\n onKeyDown={probe ? undefined : (e: KeyboardEvent) => this.handleTabKeyDown(e)}\n onFocusin={probe ? undefined : () => {\n this.overflowRovingFocused = false;\n }}\n >\n {tabs.map((tab, index) => {\n if (isTabDivider(tab)) {\n return (\n <div class=\"bar-nav__tab-divider\" key={`divider-${index}`} aria-hidden=\"true\">\n <div class=\"bar-nav__tab-divider-line\" />\n </div>\n );\n }\n\n const isSelected = tab.id === this.effectiveValue;\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n data-tab-id={tab.id}\n class={{\n 'bar-nav__tab': true,\n 'bar-nav__tab--selected': isSelected,\n 'ds-focus-ring-inset': true,\n 'ds-control-inactive': !!tab.isInactive,\n }}\n aria-selected={isSelected ? 'true' : 'false'}\n aria-disabled={tab.isInactive ? 'true' : undefined}\n aria-controls={tab.panelId ?? undefined}\n disabled={tab.isInactive}\n tabIndex={\n !probe && !this.overflowRovingFocused && tab.id === this.focusedTabId\n ? 0\n : -1\n }\n onClick={() => !probe && !tab.isInactive && this.selectTab(tab.id)}\n onFocus={() => {\n if (!probe) this.focusedTabId = tab.id;\n }}\n >\n <span\n class={{\n 'bar-nav__tab-label': true,\n 'bar-nav__tab-label--dot': !!tab.dot,\n }}\n >\n <ds-text as=\"span\" variant=\"text-body-medium\" emphasis={isSelected} color=\"inherit\">\n {tab.label}\n </ds-text>\n {tab.dot && (\n <ds-badge\n class=\"bar-nav__tab-dot\"\n variant=\"dot\"\n hasRing={false}\n label=\"\"\n aria-hidden=\"true\"\n />\n )}\n </span>\n </button>\n );\n })}\n </div>\n );\n }\n\n render() {\n // Section gating only applies when `basePath` is set (SPA section sync).\n // Tabs without a base path must still render — otherwise a single-tab bar\n // (or any non-routed tabs) silently falls through to an empty header.\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 <div key={`probe-${tabGroupKey}`}>\n {this.renderTabList(this.resolvedTabs, true)}\n </div>\n </div>\n )}\n\n {hasTabs && this.tabLayoutCommitted && renderedTabs.length > 0 && (\n <div class=\"bar-nav__left\">\n <div key={`visible-${tabGroupKey}`} class=\"bar-nav__tabs-visible\">\n {this.renderTabList(renderedTabs, false)}\n </div>\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 <ds-text\n class=\"bar-nav__heading\"\n as=\"span\"\n variant=\"text-body-medium\"\n emphasis\n color=\"primary\"\n wrap=\"nowrap\"\n >\n {this.heading}\n </ds-text>\n )}\n\n {hasTabs && this.hasOverflowTabs && (\n <ds-button-unfilled variant=\"icon\"\n class={{\n 'bar-nav__overflow-trigger': true,\n }}\n icon=\"Ellipses\"\n isActive={this.menuOpen}\n activeFill={false}\n hasBorder={false}\n focusTabIndex={this.overflowRovingFocused ? 0 : -1}\n ref={(el?: HTMLDsButtonUnfilledElement) => {\n this.triggerEl = (el as (HTMLElement & { setFocus?: () => Promise<void> })) ?? null;\n }}\n haspopup=\"menu\"\n expanded={this.menuOpen}\n aria-label={this.moreTabsLabel}\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{B as
|
|
1
|
+
import{B as o,d as s}from"./p-PP5602IN.js";const t=o;const p=s;export{t as DsButtonFilled,p as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-button-filled.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{B as o,d as s}from"./p-
|
|
1
|
+
import{B as o,d as s}from"./p-CSyIAX11.js";const t=o;const p=s;export{t as DsButtonUnfilled,p as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-button-unfilled.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as t,H as
|
|
1
|
+
import{p as t,H as e,c as s,h as d,a,t as i}from"./index.js";import{d as c}from"./p-DHJZDpNk.js";import{d as n}from"./p-CSyIAX11.js";import{d as o}from"./p-KeMecQN9.js";import{d as r}from"./p-Cj4vIqqx.js";import{d as l}from"./p-Cpr3K41-.js";import{d as h}from"./p-CqsgiNwB.js";const f=()=>`.sc-ds-card-data-viz-donut-h{display:contents}.card-data-viz-donut__layout.sc-ds-card-data-viz-donut{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;height:100%;gap:var(--dimension-space-200);box-sizing:border-box}.card-data-viz-donut__chart-region.sc-ds-card-data-viz-donut{flex:1 1 auto;min-height:0;display:grid;padding:var(--dimension-space-400) var(--dimension-space-400) 0 var(--dimension-space-400);box-sizing:border-box}.card-data-viz-donut__chart-region.sc-ds-card-data-viz-donut>*.sc-ds-card-data-viz-donut{width:100%;height:100%;min-width:0;min-height:0;max-width:100%;max-height:100%}.card-data-viz-donut__legend-region.sc-ds-card-data-viz-donut{flex:0 0 auto;padding:0 var(--dimension-space-100) var(--dimension-space-100) var(--dimension-space-100);box-sizing:border-box}`;const b=t(class t extends e{constructor(t){super();if(t!==false){this.__registerHost()}this.dsFilterClick=s(this,"dsFilterClick");this.cardWidth="md";this.filterLabel="Filter";this.hasChartSlot=false;this.hasLegendSlot=false;this.handleChartHover=t=>{const e=this.el.querySelector('[slot="legend"]');if(!e||!("activeLabel"in e))return;e.activeLabel=t.detail?.label??null};this.handleLegendHover=t=>{const e=this.el.querySelector('[slot="chart"]');if(!e||!("activeLabel"in e))return;e.activeLabel=t.detail?.label??null};this.handleFilterClick=()=>{this.dsFilterClick.emit()}}componentWillRender(){this.hasChartSlot=!!this.el.querySelector('[slot="chart"]');this.hasLegendSlot=!!this.el.querySelector('[slot="legend"]')}componentDidLoad(){this.el.addEventListener("dsSliceHover",this.handleChartHover);this.el.addEventListener("dsItemHover",this.handleLegendHover)}disconnectedCallback(){this.el.removeEventListener("dsSliceHover",this.handleChartHover);this.el.removeEventListener("dsItemHover",this.handleLegendHover)}render(){return d(a,{key:"fdbc290be1fe5695d6d2e378ac9fbeef57add6d3",class:"card-data-viz-donut"},d("ds-card",{key:"b9c9d0f0c827b4d2cb57fbb4b2811ad64275e252",heading:this.heading,cardWidth:this.cardWidth},d("ds-button-unfilled",{key:"49b0a49f0eea793f3deb9180cc37c62bc7641311",slot:"actions",variant:"icon",type:"button",icon:"Filters","aria-label":this.filterLabel,onDsClick:this.handleFilterClick}),d("div",{key:"bbabbb340812512e1327645aa7f9103cb8a17540",class:"card-data-viz-donut__layout"},this.hasChartSlot&&d("div",{key:"52ba1cf13c8927b2072ff3f9afbc8472f6e8f7c5",class:"card-data-viz-donut__chart-region"},d("slot",{key:"8833da8d26d917787f88ec219fe25d266f47b35d",name:"chart"})),this.hasLegendSlot&&d("div",{key:"8765cb32805a80e44c47150dc7bdae68e6d5fefc",class:"card-data-viz-donut__legend-region"},d("slot",{key:"df94fe2b3d4a539099c698f8dccad028e8b5865b",name:"legend"})))))}get el(){return this}static get style(){return f()}},[262,"ds-card-data-viz-donut",{heading:[1],cardWidth:[1,"card-width"],filterLabel:[1,"filter-label"],hasChartSlot:[32],hasLegendSlot:[32]}]);function m(){if(typeof customElements==="undefined"){return}const t=["ds-card-data-viz-donut","ds-badge","ds-button-unfilled","ds-card","ds-icon","ds-loader","ds-text"];t.forEach((t=>{switch(t){case"ds-card-data-viz-donut":if(!customElements.get(i(t))){customElements.define(i(t),b)}break;case"ds-badge":if(!customElements.get(i(t))){c()}break;case"ds-button-unfilled":if(!customElements.get(i(t))){n()}break;case"ds-card":if(!customElements.get(i(t))){o()}break;case"ds-icon":if(!customElements.get(i(t))){r()}break;case"ds-loader":if(!customElements.get(i(t))){l()}break;case"ds-text":if(!customElements.get(i(t))){h()}break}}))}m();const u=b;const p=m;export{u as DsCardDataVizDonut,p as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-card-data-viz-donut.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["cardDataVizDonutCss","CardDataVizDonut","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","cardWidth","filterLabel","hasChartSlot","hasLegendSlot","handleChartHover","e","legend","el","querySelector","activeLabel","detail","label","handleLegendHover","chart","handleFilterClick","dsFilterClick","emit","componentWillRender","componentDidLoad","addEventListener","disconnectedCallback","removeEventListener","render","h","Host","key","class","heading","slot","variant","type","icon","onDsClick","name"],"sources":["src/wc/components/CardDataVizDonut/CardDataVizDonut.css?tag=ds-card-data-viz-donut&encapsulation=scoped","src/wc/components/CardDataVizDonut/CardDataVizDonut.tsx"],"sourcesContent":[":host {\n display: contents;\n}\n\n.card-data-viz-donut__layout {\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-height: 0;\n height: 100%;\n gap: var(--dimension-space-200);\n box-sizing: border-box;\n}\n\n/*\n * Chart region fills leftover space; legend stays content-sized.\n * Padding is per-region so the body gap isn't doubled at the shared edge.\n */\n.card-data-viz-donut__chart-region {\n flex: 1 1 auto;\n min-height: 0;\n /* Stretch the slotted donut to the full region; the donut centers its own SVG. */\n display: grid;\n padding: var(--dimension-space-400) var(--dimension-space-400) 0 var(--dimension-space-400);\n box-sizing: border-box;\n}\n\n/* Make the slotted donut stretch to the region so ResizeObserver can measure fill size. */\n.card-data-viz-donut__chart-region > * {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n max-width: 100%;\n max-height: 100%;\n}\n\n.card-data-viz-donut__legend-region {\n flex: 0 0 auto;\n padding: 0 var(--dimension-space-100) var(--dimension-space-100) var(--dimension-space-100);\n box-sizing: border-box;\n}\n","import { Component, Element, Event, EventEmitter, State, h, Host, Prop } from '@stencil/core';\nimport type { CardWidth } from '../Card/Card';\n\nexport type CardDataVizDonutWidth = CardWidth;\n\n/** Matches the `dsSliceHover`/`dsItemHover` detail shape emitted by `ds-chart-*` and `ds-chart-legend`. */\ntype HoveredDatum = { label: string } | null;\n\n/** A slotted chart/legend that opts into hover sync by exposing an `activeLabel` prop. */\ntype SyncableSlot = HTMLElement & { activeLabel?: string | null };\n\n/**\n * Donut data-viz card — shared `ds-card` chrome with a fill chart region and\n * content-sized legend. Hover sync between chart and legend stays here.\n */\n@Component({\n tag: 'ds-card-data-viz-donut',\n styleUrl: 'CardDataVizDonut.css',\n scoped: true,\n})\nexport class CardDataVizDonut {\n @Element() el!: HTMLElement;\n\n /** Widget heading shown in the card header. */\n @Prop() heading!: string;\n\n /** Card width token — also sets matching min-height. */\n @Prop() cardWidth: CardDataVizDonutWidth = 'md';\n @Prop() filterLabel: string = 'Filter';\n\n /** Emits when the header filter control is activated. */\n @Event() dsFilterClick!: EventEmitter<void>;\n\n // Scoped (light-DOM) components have no native slot projection to detect emptiness from CSS —\n // check the actual children so an unused region (e.g. no legend) doesn't render a dangling\n // padded box plus a body gap next to nothing.\n @State() private hasChartSlot = false;\n @State() private hasLegendSlot = false;\n\n componentWillRender() {\n // Not `:scope >` — Stencil's scoped slot polyfill relocates slotted children into\n // region wrappers (and here into nested `ds-card`), so they may not stay direct\n // host children across renders.\n this.hasChartSlot = !!this.el.querySelector('[slot=\"chart\"]');\n this.hasLegendSlot = !!this.el.querySelector('[slot=\"legend\"]');\n }\n\n componentDidLoad() {\n // Sync the chart's and legend's `activeLabel` from each other's hover events, so any\n // ds-chart-donut + ds-chart-legend pair cross-highlights without every consumer having to\n // wire it up by hand. Delegated on the host (rather than bound to the specific slotted\n // elements) since Stencil events bubble and the slot content can be swapped at runtime.\n this.el.addEventListener('dsSliceHover', this.handleChartHover);\n this.el.addEventListener('dsItemHover', this.handleLegendHover);\n }\n\n disconnectedCallback() {\n this.el.removeEventListener('dsSliceHover', this.handleChartHover);\n this.el.removeEventListener('dsItemHover', this.handleLegendHover);\n }\n\n private handleChartHover = (e: Event) => {\n // Not `:scope >` — Stencil's slot polyfill for scoped (non-shadow) components relocates\n // slotted children into an inner region wrapper on render, so they're no longer direct\n // children of the host by the time this fires.\n const legend = this.el.querySelector('[slot=\"legend\"]') as SyncableSlot | null;\n if (!legend || !('activeLabel' in legend)) return;\n legend.activeLabel = (e as CustomEvent<HoveredDatum>).detail?.label ?? null;\n };\n\n private handleLegendHover = (e: Event) => {\n const chart = this.el.querySelector('[slot=\"chart\"]') as SyncableSlot | null;\n if (!chart || !('activeLabel' in chart)) return;\n chart.activeLabel = (e as CustomEvent<HoveredDatum>).detail?.label ?? null;\n };\n\n private handleFilterClick = () => {\n this.dsFilterClick.emit();\n };\n\n render() {\n return (\n <Host class=\"card-data-viz-donut\">\n <ds-card heading={this.heading} cardWidth={this.cardWidth}>\n <ds-button-unfilled\n slot=\"actions\"\n variant=\"icon\"\n type=\"button\"\n icon=\"Filters\"\n aria-label={this.filterLabel}\n onDsClick={this.handleFilterClick}\n />\n <div class=\"card-data-viz-donut__layout\">\n {this.hasChartSlot && (\n <div class=\"card-data-viz-donut__chart-region\">\n <slot name=\"chart\" />\n </div>\n )}\n {this.hasLegendSlot && (\n <div class=\"card-data-viz-donut__legend-region\">\n <slot name=\"legend\" />\n </div>\n )}\n </div>\n </ds-card>\n </Host>\n );\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"names":["cardDataVizDonutCss","CardDataVizDonut","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","cardWidth","filterLabel","hasChartSlot","hasLegendSlot","handleChartHover","e","legend","el","querySelector","activeLabel","detail","label","handleLegendHover","chart","handleFilterClick","dsFilterClick","emit","componentWillRender","componentDidLoad","addEventListener","disconnectedCallback","removeEventListener","render","h","Host","key","class","heading","slot","variant","type","icon","onDsClick","name"],"sources":["src/wc/components/CardDataVizDonut/CardDataVizDonut.css?tag=ds-card-data-viz-donut&encapsulation=scoped","src/wc/components/CardDataVizDonut/CardDataVizDonut.tsx"],"sourcesContent":[":host {\n display: contents;\n}\n\n.card-data-viz-donut__layout {\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-height: 0;\n height: 100%;\n gap: var(--dimension-space-200);\n box-sizing: border-box;\n}\n\n/*\n * Chart region fills leftover space; legend stays content-sized.\n * Padding is per-region so the body gap isn't doubled at the shared edge.\n */\n.card-data-viz-donut__chart-region {\n flex: 1 1 auto;\n min-height: 0;\n /* Stretch the slotted donut to the full region; the donut centers its own SVG. */\n display: grid;\n padding: var(--dimension-space-400) var(--dimension-space-400) 0 var(--dimension-space-400);\n box-sizing: border-box;\n}\n\n/* Make the slotted donut stretch to the region so ResizeObserver can measure fill size. */\n.card-data-viz-donut__chart-region > * {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n max-width: 100%;\n max-height: 100%;\n}\n\n.card-data-viz-donut__legend-region {\n flex: 0 0 auto;\n padding: 0 var(--dimension-space-100) var(--dimension-space-100) var(--dimension-space-100);\n box-sizing: border-box;\n}\n","import { Component, Element, Event, EventEmitter, State, h, Host, Prop } from '@stencil/core';\nimport type { CardWidth } from '../Card/Card';\n\nexport type CardDataVizDonutWidth = CardWidth;\n\n/** Matches the `dsSliceHover`/`dsItemHover` detail shape emitted by `ds-chart-*` and `ds-chart-legend`. */\ntype HoveredDatum = { label: string } | null;\n\n/** A slotted chart/legend that opts into hover sync by exposing an `activeLabel` prop. */\ntype SyncableSlot = HTMLElement & { activeLabel?: string | null };\n\n/**\n * Donut data-viz card — shared `ds-card` chrome with a fill chart region and\n * content-sized legend. Hover sync between chart and legend stays here.\n */\n@Component({\n tag: 'ds-card-data-viz-donut',\n styleUrl: 'CardDataVizDonut.css',\n scoped: true,\n})\nexport class CardDataVizDonut {\n @Element() el!: HTMLElement;\n\n /** Widget heading shown in the card header. */\n @Prop() heading!: string;\n\n /** Card width token — also sets matching min-height. */\n @Prop() cardWidth: CardDataVizDonutWidth = 'md';\n @Prop() filterLabel: string = 'Filter';\n\n /** Emits when the header filter control is activated. */\n @Event() dsFilterClick!: EventEmitter<void>;\n\n // Scoped (light-DOM) components have no native slot projection to detect emptiness from CSS —\n // check the actual children so an unused region (e.g. no legend) doesn't render a dangling\n // padded box plus a body gap next to nothing.\n @State() private hasChartSlot = false;\n @State() private hasLegendSlot = false;\n\n componentWillRender() {\n // Not `:scope >` — Stencil's scoped slot polyfill relocates slotted children into\n // region wrappers (and here into nested `ds-card`), so they may not stay direct\n // host children across renders.\n this.hasChartSlot = !!this.el.querySelector('[slot=\"chart\"]');\n this.hasLegendSlot = !!this.el.querySelector('[slot=\"legend\"]');\n }\n\n componentDidLoad() {\n // Sync the chart's and legend's `activeLabel` from each other's hover events, so any\n // ds-chart-donut + ds-chart-legend pair cross-highlights without every consumer having to\n // wire it up by hand. Delegated on the host (rather than bound to the specific slotted\n // elements) since Stencil events bubble and the slot content can be swapped at runtime.\n this.el.addEventListener('dsSliceHover', this.handleChartHover);\n this.el.addEventListener('dsItemHover', this.handleLegendHover);\n }\n\n disconnectedCallback() {\n this.el.removeEventListener('dsSliceHover', this.handleChartHover);\n this.el.removeEventListener('dsItemHover', this.handleLegendHover);\n }\n\n private handleChartHover = (e: Event) => {\n // Not `:scope >` — Stencil's slot polyfill for scoped (non-shadow) components relocates\n // slotted children into an inner region wrapper on render, so they're no longer direct\n // children of the host by the time this fires.\n const legend = this.el.querySelector('[slot=\"legend\"]') as SyncableSlot | null;\n if (!legend || !('activeLabel' in legend)) return;\n legend.activeLabel = (e as CustomEvent<HoveredDatum>).detail?.label ?? null;\n };\n\n private handleLegendHover = (e: Event) => {\n const chart = this.el.querySelector('[slot=\"chart\"]') as SyncableSlot | null;\n if (!chart || !('activeLabel' in chart)) return;\n chart.activeLabel = (e as CustomEvent<HoveredDatum>).detail?.label ?? null;\n };\n\n private handleFilterClick = () => {\n this.dsFilterClick.emit();\n };\n\n render() {\n return (\n <Host class=\"card-data-viz-donut\">\n <ds-card heading={this.heading} cardWidth={this.cardWidth}>\n <ds-button-unfilled\n slot=\"actions\"\n variant=\"icon\"\n type=\"button\"\n icon=\"Filters\"\n aria-label={this.filterLabel}\n onDsClick={this.handleFilterClick}\n />\n <div class=\"card-data-viz-donut__layout\">\n {this.hasChartSlot && (\n <div class=\"card-data-viz-donut__chart-region\">\n <slot name=\"chart\" />\n </div>\n )}\n {this.hasLegendSlot && (\n <div class=\"card-data-viz-donut__legend-region\">\n <slot name=\"legend\" />\n </div>\n )}\n </div>\n </ds-card>\n </Host>\n );\n }\n}\n"],"mappings":"qRAAA,MAAMA,EAAsB,IAAM,kyB,MCoBrBC,EAAgBC,EAAA,MAAAD,UAAAE,EAL7B,WAAAC,CAAAC,G,uFAYUC,KAAAC,UAAmC,KACnCD,KAAAE,YAAsB,SAQbF,KAAAG,aAAe,MACfH,KAAAI,cAAgB,MAwBzBJ,KAAAK,iBAAoBC,IAI1B,MAAMC,EAASP,KAAKQ,GAAGC,cAAc,mBACrC,IAAKF,KAAY,gBAAiBA,GAAS,OAC3CA,EAAOG,YAAeJ,EAAgCK,QAAQC,OAAS,IAAI,EAGrEZ,KAAAa,kBAAqBP,IAC3B,MAAMQ,EAAQd,KAAKQ,GAAGC,cAAc,kBACpC,IAAKK,KAAW,gBAAiBA,GAAQ,OACzCA,EAAMJ,YAAeJ,EAAgCK,QAAQC,OAAS,IAAI,EAGpEZ,KAAAe,kBAAoB,KAC1Bf,KAAKgB,cAAcC,MAAM,CA+B5B,CArEC,mBAAAC,GAIElB,KAAKG,eAAiBH,KAAKQ,GAAGC,cAAc,kBAC5CT,KAAKI,gBAAkBJ,KAAKQ,GAAGC,cAAc,kB,CAG/C,gBAAAU,GAKEnB,KAAKQ,GAAGY,iBAAiB,eAAgBpB,KAAKK,kBAC9CL,KAAKQ,GAAGY,iBAAiB,cAAepB,KAAKa,kB,CAG/C,oBAAAQ,GACErB,KAAKQ,GAAGc,oBAAoB,eAAgBtB,KAAKK,kBACjDL,KAAKQ,GAAGc,oBAAoB,cAAetB,KAAKa,kB,CAsBlD,MAAAU,GACE,OACEC,EAACC,EAAI,CAAAC,IAAA,2CAACC,MAAM,uBACVH,EAAA,WAAAE,IAAA,2CAASE,QAAS5B,KAAK4B,QAAS3B,UAAWD,KAAKC,WAC9CuB,EAAA,sBAAAE,IAAA,2CACEG,KAAK,UACLC,QAAQ,OACRC,KAAK,SACLC,KAAK,UAAS,aACFhC,KAAKE,YACjB+B,UAAWjC,KAAKe,oBAElBS,EAAA,OAAAE,IAAA,2CAAKC,MAAM,+BACR3B,KAAKG,cACJqB,EAAA,OAAAE,IAAA,2CAAKC,MAAM,qCACTH,EAAA,QAAAE,IAAA,2CAAMQ,KAAK,WAGdlC,KAAKI,eACJoB,EAAA,OAAAE,IAAA,2CAAKC,MAAM,sCACTH,EAAA,QAAAE,IAAA,2CAAMQ,KAAK,c","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as s,H as t,c as e,h as a,a as i,t as d}from"./index.js";import{d as n}from"./p-
|
|
1
|
+
import{p as s,H as t,c as e,h as a,a as i,t as d}from"./index.js";import{d as n}from"./p-DHJZDpNk.js";import{d as c}from"./p-PP5602IN.js";import{d as o}from"./p-CSyIAX11.js";import{d as r}from"./p-KeMecQN9.js";import{d as l}from"./p-Cj4vIqqx.js";import{d as f}from"./p-Cpr3K41-.js";import{d as m}from"./p-CqsgiNwB.js";const b=()=>`.sc-ds-card-setting-h{display:contents}.card-setting__actions.sc-ds-card-setting{display:flex;flex-shrink:0;align-items:center;gap:var(--dimension-space-100)}`;const u=s(class s extends t{constructor(s){super();if(s!==false){this.__registerHost()}this.dsEditingChange=e(this,"dsEditingChange");this.cardWidth="md";this.editing=false;this.editLabel="Edit";this.cancelLabel="Cancel";this.saveLabel="Save";this.enterEdit=()=>{this.dsEditingChange.emit(true)};this.exitEdit=()=>{this.dsEditingChange.emit(false)}}render(){const s=this.editing;return a(i,{key:"da4d9dd77ddf5ca9a4eff4d74a59c07a7068a738",class:"card-setting"},a("ds-card",{key:"1d80c67ab1ea557608115964b57fdd75547aa616",heading:this.heading,cardWidth:this.cardWidth,appearance:s?"editing":"default"},!s?a("ds-button-unfilled",{slot:"actions",variant:"icon",type:"button",icon:"Pencil","aria-label":this.editLabel,onDsClick:this.enterEdit}):a("div",{slot:"actions",class:"card-setting__actions"},a("ds-button-unfilled",{variant:"icon",type:"button",icon:"Cross",background:"bold","aria-label":this.cancelLabel,onDsClick:this.exitEdit}),a("ds-button-filled",{variant:"icon",type:"button",icon:"Check",intent:"brand",contrast:"faint","aria-label":this.saveLabel,onDsClick:this.exitEdit})),a("slot",{key:"0fcf3abc7b9a9f82bd5f68f87e0bcd4d24677503"})))}static get style(){return b()}},[262,"ds-card-setting",{heading:[1],cardWidth:[1,"card-width"],editing:[4],editLabel:[1,"edit-label"],cancelLabel:[1,"cancel-label"],saveLabel:[1,"save-label"]}]);function h(){if(typeof customElements==="undefined"){return}const s=["ds-card-setting","ds-badge","ds-button-filled","ds-button-unfilled","ds-card","ds-icon","ds-loader","ds-text"];s.forEach((s=>{switch(s){case"ds-card-setting":if(!customElements.get(d(s))){customElements.define(d(s),u)}break;case"ds-badge":if(!customElements.get(d(s))){n()}break;case"ds-button-filled":if(!customElements.get(d(s))){c()}break;case"ds-button-unfilled":if(!customElements.get(d(s))){o()}break;case"ds-card":if(!customElements.get(d(s))){r()}break;case"ds-icon":if(!customElements.get(d(s))){l()}break;case"ds-loader":if(!customElements.get(d(s))){f()}break;case"ds-text":if(!customElements.get(d(s))){m()}break}}))}h();const p=u;const g=h;export{p as DsCardSetting,g as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-card-setting.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{C as o,d as s}from"./p-
|
|
1
|
+
import{C as o,d as s}from"./p-KeMecQN9.js";const t=o;const c=s;export{t as DsCard,c as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-card.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as t,H as a,h as
|
|
1
|
+
import{p as t,H as a,h as s,a as r,t as e}from"./index.js";import{c as i}from"./p-CMv_7vFs.js";import{m as c,b as o,l as n}from"./p-CzBnvtcz.js";const h=()=>`.sc-ds-chart-bar-h{display:inline-flex;font-family:var(--typography-font-family)}.chart-bar__gridline.sc-ds-chart-bar{stroke:var(--color-border-tertiary);stroke-width:1}.chart-bar__axis-label.sc-ds-chart-bar{fill:var(--color-foreground-secondary);font-family:var(--typography-font-family);font-size:var(--typography-fontsize-xs);font-weight:var(--typography-weight-medium);letter-spacing:var(--typography-letterspacing-positive);text-transform:uppercase}.chart-bar__bar.sc-ds-chart-bar{rx:var(--dimension-radius-050)}`;const d={top:16,right:16,bottom:24,left:32};const l=t(class t extends a{constructor(t){super();if(t!==false){this.__registerHost()}this.data=[];this.width=480;this.height=240}render(){const t=this.width-d.left-d.right;const a=this.height-d.top-d.bottom;const e=c(this.data,(t=>t.value))??0;const h=o().domain(this.data.map((t=>t.label))).range([0,t]).padding(.35);const l=n().domain([0,e||1]).range([a,0]).nice();const f=l.ticks(4);return s(r,{key:"b4adbf8986ac394ac30af0d4f4d5ad6e98228dd9",class:"chart-bar"},s("svg",{key:"bed8cbd21cdb9ad1bad039baa6838d61f894ed13",class:"chart-bar__svg",viewBox:`0 0 ${this.width} ${this.height}`,width:this.width,height:this.height,role:"img","aria-label":this.data.map((t=>`${t.label}: ${t.value}`)).join(", ")},s("g",{key:"0f51bd789e32a4c9d4f682af951617625416f96a",transform:`translate(${d.left}, ${d.top})`},f.map((a=>s("g",{key:`grid-${a}`,transform:`translate(0, ${l(a)})`},s("line",{class:"chart-bar__gridline",x1:0,x2:t}),s("text",{class:"chart-bar__axis-label",x:-8,"text-anchor":"end","dominant-baseline":"middle"},a)))),this.data.map(((t,r)=>{const e=h.bandwidth();const c=h(t.label)??0;const o=l(t.value);return s("g",{key:t.label},s("rect",{class:"chart-bar__bar",x:c,y:o,width:e,height:a-o,fill:t.color??i(r)}),s("text",{class:"chart-bar__axis-label",x:c+e/2,y:a+16,"text-anchor":"middle"},t.label))})))))}static get style(){return h()}},[2,"ds-chart-bar",{data:[16],width:[2],height:[2]}]);function f(){if(typeof customElements==="undefined"){return}const t=["ds-chart-bar"];t.forEach((t=>{switch(t){case"ds-chart-bar":if(!customElements.get(e(t))){customElements.define(e(t),l)}break}}))}f();const b=l;const m=f;export{b as DsChartBar,m as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-chart-bar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["chartBarCss","MARGIN","top","right","bottom","left","ChartBar","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","data","width","height","render","innerWidth","innerHeight","yMax","max","d","value","xScale","scaleBand","domain","map","label","range","padding","yScale","scaleLinear","nice","yTicks","ticks","h","Host","key","class","viewBox","role","join","transform","tick","x1","x2","x","i","barWidth","bandwidth","barX","barY","y","fill","color","categoryColor"],"sources":["src/wc/components/ChartBar/ChartBar.css?tag=ds-chart-bar&encapsulation=scoped","src/wc/components/ChartBar/ChartBar.tsx"],"sourcesContent":[":host {\n display: inline-flex;\n font-family: var(--typography-font-family);\n}\n\n.chart-bar__gridline {\n stroke: var(--color-border-tertiary);\n stroke-width: 1;\n}\n\n/* Matches ds-text text-caption regular (SVG cannot host ds-text). */\n.chart-bar__axis-label {\n fill: var(--color-foreground-
|
|
1
|
+
{"version":3,"names":["chartBarCss","MARGIN","top","right","bottom","left","ChartBar","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","data","width","height","render","innerWidth","innerHeight","yMax","max","d","value","xScale","scaleBand","domain","map","label","range","padding","yScale","scaleLinear","nice","yTicks","ticks","h","Host","key","class","viewBox","role","join","transform","tick","x1","x2","x","i","barWidth","bandwidth","barX","barY","y","fill","color","categoryColor"],"sources":["src/wc/components/ChartBar/ChartBar.css?tag=ds-chart-bar&encapsulation=scoped","src/wc/components/ChartBar/ChartBar.tsx"],"sourcesContent":[":host {\n display: inline-flex;\n font-family: var(--typography-font-family);\n}\n\n.chart-bar__gridline {\n stroke: var(--color-border-tertiary);\n stroke-width: 1;\n}\n\n/* Matches ds-text text-caption regular (SVG cannot host ds-text). */\n.chart-bar__axis-label {\n fill: var(--color-foreground-secondary);\n font-family: var(--typography-font-family);\n font-size: var(--typography-fontsize-xs);\n font-weight: var(--typography-weight-medium);\n letter-spacing: var(--typography-letterspacing-positive);\n text-transform: uppercase;\n}\n\n.chart-bar__bar {\n rx: var(--dimension-radius-050);\n}\n","import { Component, Prop, h, Host } from '@stencil/core';\nimport { scaleBand, scaleLinear } from 'd3-scale';\nimport { max } from 'd3-array';\nimport { categoryColor } from '../../utils/chart-colors';\nimport type { ChartDatum } from '../../utils/chart-types';\n\nconst MARGIN = { top: 16, right: 16, bottom: 24, left: 32 };\n\n@Component({\n tag: 'ds-chart-bar',\n styleUrl: 'ChartBar.css',\n scoped: true,\n})\nexport class ChartBar {\n /** Bars to render. Set as a JS property (not an HTML attribute). */\n @Prop() data: ChartDatum[] = [];\n @Prop() width: number = 480;\n @Prop() height: number = 240;\n\n render() {\n const innerWidth = this.width - MARGIN.left - MARGIN.right;\n const innerHeight = this.height - MARGIN.top - MARGIN.bottom;\n\n const yMax = max(this.data, d => d.value) ?? 0;\n\n const xScale = scaleBand()\n .domain(this.data.map(d => d.label))\n .range([0, innerWidth])\n .padding(0.35);\n\n const yScale = scaleLinear()\n .domain([0, yMax || 1])\n .range([innerHeight, 0])\n .nice();\n\n const yTicks = yScale.ticks(4);\n\n return (\n <Host class=\"chart-bar\">\n <svg\n class=\"chart-bar__svg\"\n viewBox={`0 0 ${this.width} ${this.height}`}\n width={this.width}\n height={this.height}\n role=\"img\"\n aria-label={this.data.map(d => `${d.label}: ${d.value}`).join(', ')}\n >\n <g transform={`translate(${MARGIN.left}, ${MARGIN.top})`}>\n {yTicks.map(tick => (\n <g key={`grid-${tick}`} transform={`translate(0, ${yScale(tick)})`}>\n <line class=\"chart-bar__gridline\" x1={0} x2={innerWidth} />\n <text class=\"chart-bar__axis-label\" x={-8} text-anchor=\"end\" dominant-baseline=\"middle\">\n {tick}\n </text>\n </g>\n ))}\n\n {this.data.map((d, i) => {\n const barWidth = xScale.bandwidth();\n const barX = xScale(d.label) ?? 0;\n const barY = yScale(d.value);\n return (\n <g key={d.label}>\n <rect\n class=\"chart-bar__bar\"\n x={barX}\n y={barY}\n width={barWidth}\n height={innerHeight - barY}\n fill={d.color ?? categoryColor(i)}\n />\n <text\n class=\"chart-bar__axis-label\"\n x={barX + barWidth / 2}\n y={innerHeight + 16}\n text-anchor=\"middle\"\n >\n {d.label}\n </text>\n </g>\n );\n })}\n </g>\n </svg>\n </Host>\n );\n }\n}\n"],"mappings":"iJAAA,MAAMA,EAAc,IAAM,wgBCM1B,MAAMC,EAAS,CAAEC,IAAK,GAAIC,MAAO,GAAIC,OAAQ,GAAIC,KAAM,I,MAO1CC,EAAQC,EAAA,MAAAD,UAAAE,EALrB,WAAAC,CAAAC,G,4CAOUC,KAAAC,KAAqB,GACrBD,KAAAE,MAAgB,IAChBF,KAAAG,OAAiB,GAsE1B,CApEC,MAAAC,GACE,MAAMC,EAAaL,KAAKE,MAAQZ,EAAOI,KAAOJ,EAAOE,MACrD,MAAMc,EAAcN,KAAKG,OAASb,EAAOC,IAAMD,EAAOG,OAEtD,MAAMc,EAAOC,EAAIR,KAAKC,MAAMQ,GAAKA,EAAEC,SAAU,EAE7C,MAAMC,EAASC,IACZC,OAAOb,KAAKC,KAAKa,KAAIL,GAAKA,EAAEM,SAC5BC,MAAM,CAAC,EAAGX,IACVY,QAAQ,KAEX,MAAMC,EAASC,IACZN,OAAO,CAAC,EAAGN,GAAQ,IACnBS,MAAM,CAACV,EAAa,IACpBc,OAEH,MAAMC,EAASH,EAAOI,MAAM,GAE5B,OACEC,EAACC,EAAI,CAAAC,IAAA,2CAACC,MAAM,aACVH,EAAA,OAAAE,IAAA,2CACEC,MAAM,iBACNC,QAAS,OAAO3B,KAAKE,SAASF,KAAKG,SACnCD,MAAOF,KAAKE,MACZC,OAAQH,KAAKG,OACbyB,KAAK,MAAK,aACE5B,KAAKC,KAAKa,KAAIL,GAAK,GAAGA,EAAEM,UAAUN,EAAEC,UAASmB,KAAK,OAE9DN,EAAA,KAAAE,IAAA,2CAAGK,UAAW,aAAaxC,EAAOI,SAASJ,EAAOC,QAC/C8B,EAAOP,KAAIiB,GACVR,EAAA,KAAGE,IAAK,QAAQM,IAAQD,UAAW,gBAAgBZ,EAAOa,OACxDR,EAAA,QAAMG,MAAM,sBAAsBM,GAAI,EAAGC,GAAI5B,IAC7CkB,EAAA,QAAMG,MAAM,wBAAwBQ,GAAG,EAAE,cAAc,MAAK,oBAAmB,UAC5EH,MAKN/B,KAAKC,KAAKa,KAAI,CAACL,EAAG0B,KACjB,MAAMC,EAAWzB,EAAO0B,YACxB,MAAMC,EAAO3B,EAAOF,EAAEM,QAAU,EAChC,MAAMwB,EAAOrB,EAAOT,EAAEC,OACtB,OACEa,EAAA,KAAGE,IAAKhB,EAAEM,OACRQ,EAAA,QACEG,MAAM,iBACNQ,EAAGI,EACHE,EAAGD,EACHrC,MAAOkC,EACPjC,OAAQG,EAAciC,EACtBE,KAAMhC,EAAEiC,OAASC,EAAcR,KAEjCZ,EAAA,QACEG,MAAM,wBACNQ,EAAGI,EAAOF,EAAW,EACrBI,EAAGlC,EAAc,GAAE,cACP,UAEXG,EAAEM,OAEH,M","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as t,H as n,c as e,h as i,a as s,t as r}from"./index.js";import{c as o}from"./p-CMv_7vFs.js";import{T as a}from"./p-drBA73M_.js";import{r as c}from"./p-BWUTr_XN.js";import{f as h}from"./p-BBpASejH.js";import{w as u,c as l,a as f}from"./p-CrCGIx8s.js";function d(t,n,e){t.textContent=n;if(e<=0||t.getComputedTextLength()<=e)return n;let i=0;let s=n.length;while(i<s){const r=Math.ceil((i+s)/2);t.textContent=`${n.slice(0,r)}…`;if(t.getComputedTextLength()<=e){i=r}else{s=r-1}}return i>0?`${n.slice(0,i)}…`:"…"}const p=Math.abs;const y=Math.atan2;const g=Math.cos;const v=Math.max;const m=Math.min;const b=Math.sin;const x=Math.sqrt;const M=1e-12;const _=Math.PI;const w=_/2;const z=2*_;function k(t){return t>1?0:t<-1?_:Math.acos(t)}function $(t){return t>=1?w:t<=-1?-w:Math.asin(t)}function A(t){return t.innerRadius}function C(t){return t.outerRadius}function S(t){return t.startAngle}function j(t){return t.endAngle}function B(t){return t&&t.padAngle}function R(t,n,e,i,s,r,o,a){var c=e-t,h=i-n,u=o-s,l=a-r,f=l*c-u*h;if(f*f<M)return;f=(u*(n-r)-l*(t-s))/f;return[t+f*c,n+f*h]}function L(t,n,e,i,s,r,o){var a=t-e,c=n-i,h=(o?r:-r)/x(a*a+c*c),u=h*c,l=-h*a,f=t+u,d=n+l,p=e+u,y=i+l,g=(f+p)/2,m=(d+y)/2,b=p-f,M=y-d,_=b*b+M*M,w=s-r,z=f*y-p*d,k=(M<0?-1:1)*x(v(0,w*w*_-z*z)),$=(z*M-b*k)/_,A=(-z*b-M*k)/_,C=(z*M+b*k)/_,S=(-z*b+M*k)/_,j=$-g,B=A-m,R=C-g,L=S-m;if(j*j+B*B>R*R+L*L)$=C,A=S;return{cx:$,cy:A,x01:-u,y01:-l,x11:$*(s/w-1),y11:A*(s/w-1)}}function N(){var t=A,n=C,e=l(0),i=null,s=S,r=j,o=B,a=null,c=u(h);function h(){var h,u,l=+t.apply(this,arguments),f=+n.apply(this,arguments),d=s.apply(this,arguments)-w,v=r.apply(this,arguments)-w,A=p(v-d),C=v>d;if(!a)a=h=c();if(f<l)u=f,f=l,l=u;if(!(f>M))a.moveTo(0,0);else if(A>z-M){a.moveTo(f*g(d),f*b(d));a.arc(0,0,f,d,v,!C);if(l>M){a.moveTo(l*g(v),l*b(v));a.arc(0,0,l,v,d,C)}}else{var S=d,j=v,B=d,N=v,P=A,E=A,F=o.apply(this,arguments)/2,H=F>M&&(i?+i.apply(this,arguments):x(l*l+f*f)),O=m(p(f-l)/2,+e.apply(this,arguments)),T=O,D=O,V,G;if(H>M){var I=$(H/l*b(F)),U=$(H/f*b(F));if((P-=I*2)>M)I*=C?1:-1,B+=I,N-=I;else P=0,B=N=(d+v)/2;if((E-=U*2)>M)U*=C?1:-1,S+=U,j-=U;else E=0,S=j=(d+v)/2}var W=f*g(S),X=f*b(S),q=l*g(N),J=l*b(N);if(O>M){var K=f*g(j),Q=f*b(j),Y=l*g(B),Z=l*b(B),tt;if(A<_){if(tt=R(W,X,Y,Z,K,Q,q,J)){var nt=W-tt[0],et=X-tt[1],it=K-tt[0],st=Q-tt[1],rt=1/b(k((nt*it+et*st)/(x(nt*nt+et*et)*x(it*it+st*st)))/2),ot=x(tt[0]*tt[0]+tt[1]*tt[1]);T=m(O,(l-ot)/(rt-1));D=m(O,(f-ot)/(rt+1))}else{T=D=0}}}if(!(E>M))a.moveTo(W,X);else if(D>M){V=L(Y,Z,W,X,f,D,C);G=L(K,Q,q,J,f,D,C);a.moveTo(V.cx+V.x01,V.cy+V.y01);if(D<O)a.arc(V.cx,V.cy,D,y(V.y01,V.x01),y(G.y01,G.x01),!C);else{a.arc(V.cx,V.cy,D,y(V.y01,V.x01),y(V.y11,V.x11),!C);a.arc(0,0,f,y(V.cy+V.y11,V.cx+V.x11),y(G.cy+G.y11,G.cx+G.x11),!C);a.arc(G.cx,G.cy,D,y(G.y11,G.x11),y(G.y01,G.x01),!C)}}else a.moveTo(W,X),a.arc(0,0,f,S,j,!C);if(!(l>M)||!(P>M))a.lineTo(q,J);else if(T>M){V=L(q,J,K,Q,l,-T,C);G=L(W,X,Y,Z,l,-T,C);a.lineTo(V.cx+V.x01,V.cy+V.y01);if(T<O)a.arc(V.cx,V.cy,T,y(V.y01,V.x01),y(G.y01,G.x01),!C);else{a.arc(V.cx,V.cy,T,y(V.y01,V.x01),y(V.y11,V.x11),!C);a.arc(0,0,l,y(V.cy+V.y11,V.cx+V.x11),y(G.cy+G.y11,G.cx+G.x11),C);a.arc(G.cx,G.cy,T,y(G.y11,G.x11),y(G.y01,G.x01),!C)}}else a.arc(0,0,l,N,B,C)}a.closePath();if(h)return a=null,h+""||null}h.centroid=function(){var e=(+t.apply(this,arguments)+ +n.apply(this,arguments))/2,i=(+s.apply(this,arguments)+ +r.apply(this,arguments))/2-_/2;return[g(i)*e,b(i)*e]};h.innerRadius=function(n){return arguments.length?(t=typeof n==="function"?n:l(+n),h):t};h.outerRadius=function(t){return arguments.length?(n=typeof t==="function"?t:l(+t),h):n};h.cornerRadius=function(t){return arguments.length?(e=typeof t==="function"?t:l(+t),h):e};h.padRadius=function(t){return arguments.length?(i=t==null?null:typeof t==="function"?t:l(+t),h):i};h.startAngle=function(t){return arguments.length?(s=typeof t==="function"?t:l(+t),h):s};h.endAngle=function(t){return arguments.length?(r=typeof t==="function"?t:l(+t),h):r};h.padAngle=function(t){return arguments.length?(o=typeof t==="function"?t:l(+t),h):o};h.context=function(t){return arguments.length?(a=t==null?null:t,h):a};return h}function P(t,n){return n<t?-1:n>t?1:n>=t?0:NaN}function E(t){return t}function F(){var t=E,n=P,e=null,i=l(0),s=l(z),r=l(0);function o(o){var a,c=(o=f(o)).length,h,u,l=0,d=new Array(c),p=new Array(c),y=+i.apply(this,arguments),g=Math.min(z,Math.max(-z,s.apply(this,arguments)-y)),v,m=Math.min(Math.abs(g)/c,r.apply(this,arguments)),b=m*(g<0?-1:1),x;for(a=0;a<c;++a){if((x=p[d[a]=a]=+t(o[a],a,o))>0){l+=x}}if(n!=null)d.sort((function(t,e){return n(p[t],p[e])}));else if(e!=null)d.sort((function(t,n){return e(o[t],o[n])}));for(a=0,u=l?(g-c*b)/l:0;a<c;++a,y=v){h=d[a],x=p[h],v=y+(x>0?x*u:0)+b,p[h]={data:o[h],index:a,value:x,startAngle:y,endAngle:v,padAngle:m}}return p}o.value=function(n){return arguments.length?(t=typeof n==="function"?n:l(+n),o):t};o.sortValues=function(t){return arguments.length?(n=t,e=null,o):n};o.sort=function(t){return arguments.length?(e=t,n=null,o):e};o.startAngle=function(t){return arguments.length?(i=typeof t==="function"?t:l(+t),o):i};o.endAngle=function(t){return arguments.length?(s=typeof t==="function"?t:l(+t),o):s};o.padAngle=function(t){return arguments.length?(r=typeof t==="function"?t:l(+t),o):r};return o}const H=()=>`.sc-ds-chart-donut-h{display:inline-block;font-family:var(--typography-font-family);user-select:none}.chart-donut--fill.sc-ds-chart-donut-h{display:block;width:100%;height:100%;min-width:0;min-height:0}.chart-donut__wrapper.sc-ds-chart-donut{position:relative}.chart-donut--fill.sc-ds-chart-donut-h .chart-donut__wrapper.sc-ds-chart-donut{width:100%;height:100%;display:flex;align-items:center;justify-content:center}.chart-donut__svg.sc-ds-chart-donut path.sc-ds-chart-donut{cursor:default;transition:opacity var(--effect-motion-short-2)}@media (prefers-reduced-motion: reduce){.chart-donut__svg.sc-ds-chart-donut path.sc-ds-chart-donut{transition:none}}.chart-donut__svg.sc-ds-chart-donut path.sc-ds-chart-donut:focus-visible{outline:none;stroke:var(--color-interaction-focus);stroke-width:2}.chart-donut__center-value.sc-ds-chart-donut{fill:var(--color-foreground-primary);font-family:var(--typography-font-family);font-size:var(--typography-fontsize-xl);line-height:var(--typography-lineheight-xl);font-weight:var(--typography-weight-semibold);letter-spacing:var(--typography-letterspacing-negative-double);cursor:default}.chart-donut__center-caption.sc-ds-chart-donut{fill:var(--color-foreground-secondary);font-family:var(--typography-font-family);font-size:var(--typography-fontsize-md);line-height:var(--typography-lineheight-md);font-weight:var(--typography-weight-regular);letter-spacing:var(--typography-letterspacing-negative-half);cursor:default}`;const O=.25;const T=0;const D=.82;const V=128;const G=t(class t extends n{constructor(t){super();if(t!==false){this.__registerHost()}this.dsSliceHover=e(this,"dsSliceHover");this.noDataLabel="No data";this.data=[];this.thickness=a.size200;this.cornerRadius=a.radius025;this.gap=1;this.activeLabel=null;this.hoveredLabel=null;this.displayedValueText="";this.displayedCaptionText="";this.measuredSize=V;this.resizeObserver=null}get isFillMode(){return this.size==null||!Number.isFinite(this.size)||this.size<=0}get fillMinPx(){return c(a.donutFillMin,V)}get fillMaxPx(){return c(a.donutFillMax,192)}clampFillSize(t){const n=this.fillMinPx;const e=this.fillMaxPx;if(!(t>0))return n;return Math.round(Math.min(e,Math.max(n,t)))}get resolvedSize(){if(!this.isFillMode)return this.size;return this.clampFillSize(this.measuredSize)}componentDidLoad(){this.syncResizeObserver()}onSizePropChange(){this.syncResizeObserver()}disconnectedCallback(){this.teardownResizeObserver()}syncResizeObserver(){this.teardownResizeObserver();if(!this.isFillMode)return;const t=this.el;if(!t||typeof ResizeObserver==="undefined")return;this.resizeObserver=new ResizeObserver((t=>{const n=t[0];if(!n)return;this.applyAvailableSize(n.contentRect.width,n.contentRect.height)}));this.resizeObserver.observe(t);this.measureHost()}measureHost(){const t=this.el.getBoundingClientRect();this.applyAvailableSize(t.width,t.height)}applyAvailableSize(t,n){const e=Math.floor(Math.min(t,n));if(e>0&&e!==this.measuredSize){this.measuredSize=e}}teardownResizeObserver(){this.resizeObserver?.disconnect();this.resizeObserver=null}handleHover(t){this.hoveredLabel=t?.label??null;this.dsSliceHover.emit(t)}componentDidRender(){if(this.isFillMode&&!this.resizeObserver){this.syncResizeObserver()}const t=this.resolvedSize;const n=t/2;const e=c(this.thickness,a.size200);const i=n-e;const s=i*2*D;const r=this.data.reduce(((t,n)=>t+n.value),0);const o=this.centerValue??h(r,this.locale);if(this.valueTextEl){const t=d(this.valueTextEl,o,s);if(t!==this.displayedValueText)this.displayedValueText=t;else this.valueTextEl.textContent=t}const u=this.centerCaption??"";if(this.captionTextEl&&u){const t=d(this.captionTextEl,u,s);if(t!==this.displayedCaptionText)this.displayedCaptionText=t;else this.captionTextEl.textContent=t}}render(){const t=this.resolvedSize;const n=t/2;const e=c(this.thickness,a.size200);const r=c(this.cornerRadius,a.radius025);const u=n-e;const l=this.data.reduce(((t,n)=>t+n.value),0);const f=l<=0;const d=this.activeLabel??this.hoveredLabel;const p=N().innerRadius(u).outerRadius(n).cornerRadius(r).padAngle(this.gap*Math.PI/180);const y=f?[]:F().value((t=>t.value)).sort(null)(this.data);const g=f?N().innerRadius(u).outerRadius(n)({startAngle:0,endAngle:Math.PI*2}):null;const v=c(a.lineheightXl,32);const m=c(a.lineheightMd,20);const b=this.centerCaption?n-(T+m)/2:n;const x=n+(v+T)/2;const M=this.centerValue??h(l,this.locale);const _=this.centerCaption??"";const w=this.isFillMode;return i(s,{key:"02a4bf80e5d7b569b182c804e72f53533a10f660",class:{"chart-donut":true,"chart-donut--fill":w,"chart-donut--fixed":!w},style:!w?{width:`${t}px`,height:`${t}px`}:undefined},i("div",{key:"7d42352be38d6d30dda0c281c8620ae72fa007d1",class:"chart-donut__wrapper",style:!w?{width:`${t}px`,height:`${t}px`}:undefined},i("svg",{key:"c5a1398fe619520bd99dc16b6f91294103d50979",class:"chart-donut__svg",viewBox:`0 0 ${t} ${t}`,width:t,height:t},i("g",{key:"bb3fa5696ffdcb5b6a499170baa87fea010a5806",transform:`translate(${n}, ${n})`},f?i("path",{d:g??undefined,fill:"var(--color-background-faint-neutral)","aria-label":this.noDataLabel}):y.map(((t,n)=>{const e=this.data[n];const s=d!=null&&e.label!==d;return i("path",{key:e.label,d:p(t)??undefined,fill:e.color??o(n),opacity:s?O:1,tabindex:0,role:"img","aria-label":`${e.label}: ${e.value}`,onMouseEnter:()=>this.handleHover(e),onMouseLeave:()=>this.handleHover(null),onFocus:()=>this.handleHover(e),onBlur:()=>this.handleHover(null)})}))),i("text",{key:"c77797bb4de1c6f0f1e16dbdf912d9d296f708c1",class:"chart-donut__center-value",x:n,y:b,"text-anchor":"middle","dominant-baseline":"central",ref:t=>{this.valueTextEl=t??undefined}},this.displayedValueText||M),_&&i("text",{key:"a7f7a687806f87e73c2a1c80f3839925e6fad641",class:"chart-donut__center-caption",x:n,y:x,"text-anchor":"middle","dominant-baseline":"central",ref:t=>{this.captionTextEl=t??undefined}},this.displayedCaptionText||_))))}get el(){return this}static get watchers(){return{size:[{onSizePropChange:0}]}}static get style(){return H()}},[2,"ds-chart-donut",{locale:[1],noDataLabel:[1,"no-data-label"],data:[16],size:[2],thickness:[8],cornerRadius:[8,"corner-radius"],gap:[2],centerValue:[1,"center-value"],centerCaption:[1,"center-caption"],activeLabel:[1,"active-label"],hoveredLabel:[32],displayedValueText:[32],displayedCaptionText:[32],measuredSize:[32]},undefined,{size:[{onSizePropChange:0}]}]);function I(){if(typeof customElements==="undefined"){return}const t=["ds-chart-donut"];t.forEach((t=>{switch(t){case"ds-chart-donut":if(!customElements.get(r(t))){customElements.define(r(t),G)}break}}))}I();const U=G;const W=I;export{U as DsChartDonut,W as defineCustomElement};
|
|
1
|
+
import{p as t,H as n,c as e,h as i,a as s,t as r}from"./index.js";import{c as o}from"./p-CMv_7vFs.js";import{T as a}from"./p-drBA73M_.js";import{r as c}from"./p-BWUTr_XN.js";import{f as h}from"./p-BBpASejH.js";import{w as u,c as l,a as f}from"./p-CrCGIx8s.js";function d(t,n,e){t.textContent=n;if(e<=0||t.getComputedTextLength()<=e)return n;let i=0;let s=n.length;while(i<s){const r=Math.ceil((i+s)/2);t.textContent=`${n.slice(0,r)}…`;if(t.getComputedTextLength()<=e){i=r}else{s=r-1}}return i>0?`${n.slice(0,i)}…`:"…"}const p=Math.abs;const y=Math.atan2;const g=Math.cos;const v=Math.max;const m=Math.min;const b=Math.sin;const x=Math.sqrt;const M=1e-12;const _=Math.PI;const w=_/2;const z=2*_;function k(t){return t>1?0:t<-1?_:Math.acos(t)}function $(t){return t>=1?w:t<=-1?-w:Math.asin(t)}function A(t){return t.innerRadius}function C(t){return t.outerRadius}function S(t){return t.startAngle}function j(t){return t.endAngle}function B(t){return t&&t.padAngle}function R(t,n,e,i,s,r,o,a){var c=e-t,h=i-n,u=o-s,l=a-r,f=l*c-u*h;if(f*f<M)return;f=(u*(n-r)-l*(t-s))/f;return[t+f*c,n+f*h]}function L(t,n,e,i,s,r,o){var a=t-e,c=n-i,h=(o?r:-r)/x(a*a+c*c),u=h*c,l=-h*a,f=t+u,d=n+l,p=e+u,y=i+l,g=(f+p)/2,m=(d+y)/2,b=p-f,M=y-d,_=b*b+M*M,w=s-r,z=f*y-p*d,k=(M<0?-1:1)*x(v(0,w*w*_-z*z)),$=(z*M-b*k)/_,A=(-z*b-M*k)/_,C=(z*M+b*k)/_,S=(-z*b+M*k)/_,j=$-g,B=A-m,R=C-g,L=S-m;if(j*j+B*B>R*R+L*L)$=C,A=S;return{cx:$,cy:A,x01:-u,y01:-l,x11:$*(s/w-1),y11:A*(s/w-1)}}function N(){var t=A,n=C,e=l(0),i=null,s=S,r=j,o=B,a=null,c=u(h);function h(){var h,u,l=+t.apply(this,arguments),f=+n.apply(this,arguments),d=s.apply(this,arguments)-w,v=r.apply(this,arguments)-w,A=p(v-d),C=v>d;if(!a)a=h=c();if(f<l)u=f,f=l,l=u;if(!(f>M))a.moveTo(0,0);else if(A>z-M){a.moveTo(f*g(d),f*b(d));a.arc(0,0,f,d,v,!C);if(l>M){a.moveTo(l*g(v),l*b(v));a.arc(0,0,l,v,d,C)}}else{var S=d,j=v,B=d,N=v,P=A,E=A,F=o.apply(this,arguments)/2,H=F>M&&(i?+i.apply(this,arguments):x(l*l+f*f)),O=m(p(f-l)/2,+e.apply(this,arguments)),T=O,D=O,V,G;if(H>M){var I=$(H/l*b(F)),U=$(H/f*b(F));if((P-=I*2)>M)I*=C?1:-1,B+=I,N-=I;else P=0,B=N=(d+v)/2;if((E-=U*2)>M)U*=C?1:-1,S+=U,j-=U;else E=0,S=j=(d+v)/2}var W=f*g(S),X=f*b(S),q=l*g(N),J=l*b(N);if(O>M){var K=f*g(j),Q=f*b(j),Y=l*g(B),Z=l*b(B),tt;if(A<_){if(tt=R(W,X,Y,Z,K,Q,q,J)){var nt=W-tt[0],et=X-tt[1],it=K-tt[0],st=Q-tt[1],rt=1/b(k((nt*it+et*st)/(x(nt*nt+et*et)*x(it*it+st*st)))/2),ot=x(tt[0]*tt[0]+tt[1]*tt[1]);T=m(O,(l-ot)/(rt-1));D=m(O,(f-ot)/(rt+1))}else{T=D=0}}}if(!(E>M))a.moveTo(W,X);else if(D>M){V=L(Y,Z,W,X,f,D,C);G=L(K,Q,q,J,f,D,C);a.moveTo(V.cx+V.x01,V.cy+V.y01);if(D<O)a.arc(V.cx,V.cy,D,y(V.y01,V.x01),y(G.y01,G.x01),!C);else{a.arc(V.cx,V.cy,D,y(V.y01,V.x01),y(V.y11,V.x11),!C);a.arc(0,0,f,y(V.cy+V.y11,V.cx+V.x11),y(G.cy+G.y11,G.cx+G.x11),!C);a.arc(G.cx,G.cy,D,y(G.y11,G.x11),y(G.y01,G.x01),!C)}}else a.moveTo(W,X),a.arc(0,0,f,S,j,!C);if(!(l>M)||!(P>M))a.lineTo(q,J);else if(T>M){V=L(q,J,K,Q,l,-T,C);G=L(W,X,Y,Z,l,-T,C);a.lineTo(V.cx+V.x01,V.cy+V.y01);if(T<O)a.arc(V.cx,V.cy,T,y(V.y01,V.x01),y(G.y01,G.x01),!C);else{a.arc(V.cx,V.cy,T,y(V.y01,V.x01),y(V.y11,V.x11),!C);a.arc(0,0,l,y(V.cy+V.y11,V.cx+V.x11),y(G.cy+G.y11,G.cx+G.x11),C);a.arc(G.cx,G.cy,T,y(G.y11,G.x11),y(G.y01,G.x01),!C)}}else a.arc(0,0,l,N,B,C)}a.closePath();if(h)return a=null,h+""||null}h.centroid=function(){var e=(+t.apply(this,arguments)+ +n.apply(this,arguments))/2,i=(+s.apply(this,arguments)+ +r.apply(this,arguments))/2-_/2;return[g(i)*e,b(i)*e]};h.innerRadius=function(n){return arguments.length?(t=typeof n==="function"?n:l(+n),h):t};h.outerRadius=function(t){return arguments.length?(n=typeof t==="function"?t:l(+t),h):n};h.cornerRadius=function(t){return arguments.length?(e=typeof t==="function"?t:l(+t),h):e};h.padRadius=function(t){return arguments.length?(i=t==null?null:typeof t==="function"?t:l(+t),h):i};h.startAngle=function(t){return arguments.length?(s=typeof t==="function"?t:l(+t),h):s};h.endAngle=function(t){return arguments.length?(r=typeof t==="function"?t:l(+t),h):r};h.padAngle=function(t){return arguments.length?(o=typeof t==="function"?t:l(+t),h):o};h.context=function(t){return arguments.length?(a=t==null?null:t,h):a};return h}function P(t,n){return n<t?-1:n>t?1:n>=t?0:NaN}function E(t){return t}function F(){var t=E,n=P,e=null,i=l(0),s=l(z),r=l(0);function o(o){var a,c=(o=f(o)).length,h,u,l=0,d=new Array(c),p=new Array(c),y=+i.apply(this,arguments),g=Math.min(z,Math.max(-z,s.apply(this,arguments)-y)),v,m=Math.min(Math.abs(g)/c,r.apply(this,arguments)),b=m*(g<0?-1:1),x;for(a=0;a<c;++a){if((x=p[d[a]=a]=+t(o[a],a,o))>0){l+=x}}if(n!=null)d.sort((function(t,e){return n(p[t],p[e])}));else if(e!=null)d.sort((function(t,n){return e(o[t],o[n])}));for(a=0,u=l?(g-c*b)/l:0;a<c;++a,y=v){h=d[a],x=p[h],v=y+(x>0?x*u:0)+b,p[h]={data:o[h],index:a,value:x,startAngle:y,endAngle:v,padAngle:m}}return p}o.value=function(n){return arguments.length?(t=typeof n==="function"?n:l(+n),o):t};o.sortValues=function(t){return arguments.length?(n=t,e=null,o):n};o.sort=function(t){return arguments.length?(e=t,n=null,o):e};o.startAngle=function(t){return arguments.length?(i=typeof t==="function"?t:l(+t),o):i};o.endAngle=function(t){return arguments.length?(s=typeof t==="function"?t:l(+t),o):s};o.padAngle=function(t){return arguments.length?(r=typeof t==="function"?t:l(+t),o):r};return o}const H=()=>`.sc-ds-chart-donut-h{display:inline-block;font-family:var(--typography-font-family);user-select:none}.chart-donut--fill.sc-ds-chart-donut-h{display:block;width:100%;height:100%;min-width:0;min-height:0}.chart-donut__wrapper.sc-ds-chart-donut{position:relative}.chart-donut--fill.sc-ds-chart-donut-h .chart-donut__wrapper.sc-ds-chart-donut{width:100%;height:100%;display:flex;align-items:center;justify-content:center}.chart-donut__svg.sc-ds-chart-donut path.sc-ds-chart-donut{cursor:default;transition:opacity var(--effect-motion-short-2)}@media (prefers-reduced-motion: reduce){.chart-donut__svg.sc-ds-chart-donut path.sc-ds-chart-donut{transition:none}}.chart-donut__svg.sc-ds-chart-donut path.sc-ds-chart-donut:focus-visible{outline:none;stroke:var(--color-interaction-focus);stroke-width:2}.chart-donut__center-value.sc-ds-chart-donut{fill:var(--color-foreground-primary);font-family:var(--typography-font-family);font-size:var(--typography-fontsize-xl);line-height:var(--typography-lineheight-xl);font-weight:var(--typography-weight-semibold);letter-spacing:var(--typography-letterspacing-negative-double);cursor:default}.chart-donut__center-caption.sc-ds-chart-donut{fill:var(--color-foreground-secondary);font-family:var(--typography-font-family);font-size:var(--typography-fontsize-md);line-height:var(--typography-lineheight-md);font-weight:var(--typography-weight-regular);letter-spacing:var(--typography-letterspacing-negative-half);cursor:default}`;const O=.25;const T=0;const D=.82;const V=128;const G=t(class t extends n{constructor(t){super();if(t!==false){this.__registerHost()}this.dsSliceHover=e(this,"dsSliceHover");this.noDataLabel="No data";this.data=[];this.thickness=a.size200;this.cornerRadius=a.radius025;this.gap=1;this.activeLabel=null;this.hoveredLabel=null;this.displayedValueText="";this.displayedCaptionText="";this.measuredSize=V;this.resizeObserver=null}get isFillMode(){return this.size==null||!Number.isFinite(this.size)||this.size<=0}get fillMinPx(){return c(a.donutFillMin,V)}get fillMaxPx(){return c(a.donutFillMax,192)}clampFillSize(t){const n=this.fillMinPx;const e=this.fillMaxPx;if(!(t>0))return n;return Math.round(Math.min(e,Math.max(n,t)))}get resolvedSize(){if(!this.isFillMode)return this.size;return this.clampFillSize(this.measuredSize)}componentDidLoad(){this.syncResizeObserver()}onSizePropChange(){this.syncResizeObserver()}disconnectedCallback(){this.teardownResizeObserver()}syncResizeObserver(){this.teardownResizeObserver();if(!this.isFillMode)return;const t=this.el;if(!t||typeof ResizeObserver==="undefined")return;this.resizeObserver=new ResizeObserver((t=>{const n=t[0];if(!n)return;this.applyAvailableSize(n.contentRect.width,n.contentRect.height)}));this.resizeObserver.observe(t);this.measureHost()}measureHost(){const t=this.el.getBoundingClientRect();this.applyAvailableSize(t.width,t.height)}applyAvailableSize(t,n){const e=Math.floor(Math.min(t,n));if(e>0&&e!==this.measuredSize){this.measuredSize=e}}teardownResizeObserver(){this.resizeObserver?.disconnect();this.resizeObserver=null}handleHover(t){this.hoveredLabel=t?.label??null;this.dsSliceHover.emit(t)}componentDidRender(){if(this.isFillMode&&!this.resizeObserver){this.syncResizeObserver()}const t=this.resolvedSize;const n=t/2;const e=c(this.thickness,a.size200);const i=n-e;const s=i*2*D;const r=this.data.reduce(((t,n)=>t+n.value),0);const o=this.centerValue??h(r,this.locale);if(this.valueTextEl){const t=d(this.valueTextEl,o,s);if(t!==this.displayedValueText)this.displayedValueText=t;else this.valueTextEl.textContent=t}const u=this.centerCaption??"";if(this.captionTextEl&&u){const t=d(this.captionTextEl,u,s);if(t!==this.displayedCaptionText)this.displayedCaptionText=t;else this.captionTextEl.textContent=t}}render(){const t=this.resolvedSize;const n=t/2;const e=c(this.thickness,a.size200);const r=c(this.cornerRadius,a.radius025);const u=n-e;const l=this.data.reduce(((t,n)=>t+n.value),0);const f=l<=0;const d=this.activeLabel??this.hoveredLabel;const p=N().innerRadius(u).outerRadius(n).cornerRadius(r).padAngle(this.gap*Math.PI/180);const y=f?[]:F().value((t=>t.value)).sort(null)(this.data);const g=f?N().innerRadius(u).outerRadius(n)({startAngle:0,endAngle:Math.PI*2}):null;const v=c(a.lineheightXl,32);const m=c(a.lineheightMd,20);const b=this.centerCaption?n-(T+m)/2:n;const x=n+(v+T)/2;const M=this.centerValue??h(l,this.locale);const _=this.centerCaption??"";const w=this.isFillMode;return i(s,{key:"6241d7433fec61bc5f65acac291e911883bf5372",class:{"chart-donut":true,"chart-donut--fill":w,"chart-donut--fixed":!w},style:!w?{width:`${t}px`,height:`${t}px`}:undefined},i("div",{key:"1eb051e72615f3f9a6e87a1ddd12def633709fea",class:"chart-donut__wrapper",style:!w?{width:`${t}px`,height:`${t}px`}:undefined},i("svg",{key:"886dca8a077c00b3ee8f0dd47775079a7be7f4e2",class:"chart-donut__svg",viewBox:`0 0 ${t} ${t}`,width:t,height:t,role:f?"img":undefined,"aria-label":f?this.noDataLabel:undefined},i("g",{key:"0b9e6bbd95d0505188932d09626b5315792505ac",transform:`translate(${n}, ${n})`},f?i("path",{d:g??undefined,fill:"var(--color-background-faint-neutral)","aria-hidden":"true"}):y.map(((t,n)=>{const e=this.data[n];const s=d!=null&&e.label!==d;return i("path",{key:e.label,d:p(t)??undefined,fill:e.color??o(n),opacity:s?O:1,tabindex:0,role:"img","aria-label":`${e.label}: ${e.value}`,onMouseEnter:()=>this.handleHover(e),onMouseLeave:()=>this.handleHover(null),onFocus:()=>this.handleHover(e),onBlur:()=>this.handleHover(null)})}))),i("text",{key:"482e6b62f16848cfde1463aaac3f2a59b1917615",class:"chart-donut__center-value",x:n,y:b,"text-anchor":"middle","dominant-baseline":"central",ref:t=>{this.valueTextEl=t??undefined}},this.displayedValueText||M),_&&i("text",{key:"a9d0c8c77e8f92b2f28f006b1490b5dcbda5c496",class:"chart-donut__center-caption",x:n,y:x,"text-anchor":"middle","dominant-baseline":"central",ref:t=>{this.captionTextEl=t??undefined}},this.displayedCaptionText||_))))}get el(){return this}static get watchers(){return{size:[{onSizePropChange:0}]}}static get style(){return H()}},[2,"ds-chart-donut",{locale:[1],noDataLabel:[1,"no-data-label"],data:[16],size:[2],thickness:[8],cornerRadius:[8,"corner-radius"],gap:[2],centerValue:[1,"center-value"],centerCaption:[1,"center-caption"],activeLabel:[1,"active-label"],hoveredLabel:[32],displayedValueText:[32],displayedCaptionText:[32],measuredSize:[32]},undefined,{size:[{onSizePropChange:0}]}]);function I(){if(typeof customElements==="undefined"){return}const t=["ds-chart-donut"];t.forEach((t=>{switch(t){case"ds-chart-donut":if(!customElements.get(r(t))){customElements.define(r(t),G)}break}}))}I();const U=G;const W=I;export{U as DsChartDonut,W as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-chart-donut.js.map
|