@ds-mo/ui 2.15.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/dist/.build-stamp +1 -1
  2. package/dist/components/ds-app-shell.js +1 -1
  3. package/dist/components/ds-badge.js +1 -1
  4. package/dist/components/ds-banner.js +1 -1
  5. package/dist/components/ds-banner.js.map +1 -1
  6. package/dist/components/ds-bar-nav.js +1 -1
  7. package/dist/components/ds-bar-nav.js.map +1 -1
  8. package/dist/components/ds-button-filled.js +1 -1
  9. package/dist/components/ds-button-unfilled.js +1 -1
  10. package/dist/components/ds-card-data-viz-donut.js +1 -1
  11. package/dist/components/ds-card-data-viz-donut.js.map +1 -1
  12. package/dist/components/ds-card-setting.js +1 -1
  13. package/dist/components/ds-card.js +1 -1
  14. package/dist/components/ds-chart-bar.js +1 -1
  15. package/dist/components/ds-chart-donut.js +1 -1
  16. package/dist/components/ds-chart-donut.js.map +1 -1
  17. package/dist/components/ds-chart-legend.js +1 -1
  18. package/dist/components/ds-chart-legend.js.map +1 -1
  19. package/dist/components/ds-chart-line.js +1 -1
  20. package/dist/components/ds-checkbox.js +1 -1
  21. package/dist/components/ds-checkbox.js.map +1 -1
  22. package/dist/components/ds-chip.js +1 -1
  23. package/dist/components/ds-chip.js.map +1 -1
  24. package/dist/components/ds-divider.js +1 -1
  25. package/dist/components/ds-empty-state.js +1 -1
  26. package/dist/components/ds-empty-state.js.map +1 -1
  27. package/dist/components/ds-field.js +1 -1
  28. package/dist/components/ds-icon.js +1 -1
  29. package/dist/components/ds-input.js +1 -1
  30. package/dist/components/ds-input.js.map +1 -1
  31. package/dist/components/ds-loader.js +1 -1
  32. package/dist/components/ds-loader.js.map +1 -1
  33. package/dist/components/ds-menu.js +1 -1
  34. package/dist/components/ds-modal.js +1 -1
  35. package/dist/components/ds-modal.js.map +1 -1
  36. package/dist/components/ds-pagination.js +1 -1
  37. package/dist/components/ds-pagination.js.map +1 -1
  38. package/dist/components/ds-panel-nav.js +1 -1
  39. package/dist/components/ds-panel-nav.js.map +1 -1
  40. package/dist/components/ds-panel-tools.js +1 -1
  41. package/dist/components/ds-panel-tools.js.map +1 -1
  42. package/dist/components/ds-radio-group.js +1 -1
  43. package/dist/components/ds-radio-group.js.map +1 -1
  44. package/dist/components/ds-select.js +1 -1
  45. package/dist/components/ds-select.js.map +1 -1
  46. package/dist/components/ds-shell-gradient-picker.js +1 -1
  47. package/dist/components/ds-shell-gradient-swatch.js +1 -1
  48. package/dist/components/ds-slider.js +1 -1
  49. package/dist/components/ds-tab-group-nav.js +1 -1
  50. package/dist/components/ds-tab-group.js +1 -1
  51. package/dist/components/ds-tab-group.js.map +1 -1
  52. package/dist/components/ds-table.js +1 -1
  53. package/dist/components/ds-table.js.map +1 -1
  54. package/dist/components/ds-tag.js +1 -1
  55. package/dist/components/ds-tag.js.map +1 -1
  56. package/dist/components/ds-text.js +1 -1
  57. package/dist/components/ds-toggle.js +1 -1
  58. package/dist/components/ds-tooltip-data-viz.js +1 -1
  59. package/dist/components/ds-tooltip-data-viz.js.map +1 -1
  60. package/dist/components/ds-tooltip.js +1 -1
  61. package/dist/components/p-8WTsyLQ9.js +2 -0
  62. package/dist/components/p-8WTsyLQ9.js.map +1 -0
  63. package/dist/components/{p-CyFVn2Sc.js → p-9Qu1ls2y.js} +2 -2
  64. package/dist/components/p-BSNlp8Di.js +2 -0
  65. package/dist/components/p-BSNlp8Di.js.map +1 -0
  66. package/dist/components/p-BVNJnFI9.js +2 -0
  67. package/dist/components/p-BVNJnFI9.js.map +1 -0
  68. package/dist/components/p-B_ENgncs.js +2 -0
  69. package/dist/components/p-B_ENgncs.js.map +1 -0
  70. package/dist/components/p-CNgNgezy.js +2 -0
  71. package/dist/components/p-CNgNgezy.js.map +1 -0
  72. package/dist/components/p-CQmul5NK.js +2 -0
  73. package/dist/components/{p-DujEDZ7f.js.map → p-CQmul5NK.js.map} +1 -1
  74. package/dist/components/p-CsaW5gDM.js +2 -0
  75. package/dist/components/{p-C3ORQUOp.js.map → p-CsaW5gDM.js.map} +1 -1
  76. package/dist/components/{p-BvF44IQK.js → p-Cx-ywr1e.js} +1 -1
  77. package/dist/components/p-Cx-ywr1e.js.map +1 -0
  78. package/dist/components/p-DQ3l2TXw.js +2 -0
  79. package/dist/components/p-DQ3l2TXw.js.map +1 -0
  80. package/dist/components/p-DRqJ3RUb.js +2 -0
  81. package/dist/components/p-DRqJ3RUb.js.map +1 -0
  82. package/dist/components/p-V2qW8NL0.js +2 -0
  83. package/dist/components/p-V2qW8NL0.js.map +1 -0
  84. package/dist/components/p-sBx2MuF2.js +2 -0
  85. package/dist/components/p-sBx2MuF2.js.map +1 -0
  86. package/dist/lib/utils/control-text.d.ts +4 -4
  87. package/dist/lib/utils/index.d.ts +1 -1
  88. package/dist/lib/utils/index.js.map +2 -2
  89. package/dist/types/components/ChartDonut/ChartDonut.d.ts +2 -7
  90. package/dist/types/components/Loader/Loader.d.ts +7 -3
  91. package/dist/types/components/Loader/index.d.ts +1 -1
  92. package/dist/types/components/Text/text-utils.d.ts +3 -1
  93. package/dist/types/components/TooltipDataViz/TooltipDataViz.d.ts +3 -2
  94. package/dist/types/components.d.ts +32 -17
  95. package/dist/types/utils/control-text.d.ts +4 -4
  96. package/dist/types/utils/index.d.ts +1 -1
  97. package/package.json +7 -7
  98. package/src/angular/proxies.ts +2 -2
  99. package/src/wc/components/Banner/Banner.tsx +3 -5
  100. package/src/wc/components/BarNav/BarNav.tsx +10 -5
  101. package/src/wc/components/ButtonFilled/ButtonFilled.tsx +9 -5
  102. package/src/wc/components/ButtonUnfilled/ButtonUnfilled.tsx +9 -5
  103. package/src/wc/components/Card/Card.tsx +9 -12
  104. package/src/wc/components/ChartDonut/ChartDonut.tsx +4 -47
  105. package/src/wc/components/ChartLegend/ChartLegend.tsx +23 -15
  106. package/src/wc/components/Checkbox/Checkbox.tsx +3 -5
  107. package/src/wc/components/Chip/Chip.tsx +3 -5
  108. package/src/wc/components/EmptyState/EmptyState.tsx +3 -5
  109. package/src/wc/components/Input/Input.tsx +10 -3
  110. package/src/wc/components/Loader/Loader.tsx +77 -30
  111. package/src/wc/components/Loader/index.ts +1 -1
  112. package/src/wc/components/Menu/Menu.tsx +22 -17
  113. package/src/wc/components/Modal/Modal.tsx +10 -11
  114. package/src/wc/components/Pagination/Pagination.tsx +3 -3
  115. package/src/wc/components/PanelNav/PanelNav.tsx +30 -31
  116. package/src/wc/components/PanelTools/PanelTools.tsx +10 -5
  117. package/src/wc/components/RadioGroup/RadioGroup.tsx +3 -5
  118. package/src/wc/components/Select/Select.tsx +9 -5
  119. package/src/wc/components/Table/Table.tsx +15 -12
  120. package/src/wc/components/Tag/Tag.tsx +3 -5
  121. package/src/wc/components/Text/Text.tsx +4 -3
  122. package/src/wc/components/Text/text-utils.ts +8 -1
  123. package/src/wc/components/Tooltip/Tooltip.tsx +10 -4
  124. package/src/wc/components/TooltipDataViz/TooltipDataViz.tsx +20 -12
  125. package/src/wc/components.d.ts +32 -17
  126. package/src/wc/utils/control-density.css +2 -6
  127. package/src/wc/utils/control-text.ts +4 -4
  128. package/src/wc/utils/index.ts +1 -1
  129. package/src/wc/utils/interaction-fill.css +2 -2
  130. package/src/wc/utils/typography.css +146 -0
  131. package/dist/components/p-061wD4FM.js +0 -2
  132. package/dist/components/p-061wD4FM.js.map +0 -1
  133. package/dist/components/p-AiGt4dQS.js +0 -2
  134. package/dist/components/p-AiGt4dQS.js.map +0 -1
  135. package/dist/components/p-BDQgqw5J.js +0 -2
  136. package/dist/components/p-BDQgqw5J.js.map +0 -1
  137. package/dist/components/p-B_g8X0eh.js +0 -2
  138. package/dist/components/p-B_g8X0eh.js.map +0 -1
  139. package/dist/components/p-BvF44IQK.js.map +0 -1
  140. package/dist/components/p-C3ORQUOp.js +0 -2
  141. package/dist/components/p-DIgHkkPe.js +0 -2
  142. package/dist/components/p-DIgHkkPe.js.map +0 -1
  143. package/dist/components/p-DOqi-Vkb.js +0 -2
  144. package/dist/components/p-DOqi-Vkb.js.map +0 -1
  145. package/dist/components/p-DQ3MyAC7.js +0 -2
  146. package/dist/components/p-DQ3MyAC7.js.map +0 -1
  147. package/dist/components/p-DkcH8mRl.js +0 -2
  148. package/dist/components/p-DkcH8mRl.js.map +0 -1
  149. package/dist/components/p-DrhmNrKD.js +0 -2
  150. package/dist/components/p-DrhmNrKD.js.map +0 -1
  151. package/dist/components/p-DujEDZ7f.js +0 -2
  152. package/dist/components/p-DwQ-zdqa.js +0 -2
  153. package/dist/components/p-DwQ-zdqa.js.map +0 -1
  154. /package/dist/components/{p-CyFVn2Sc.js.map → p-9Qu1ls2y.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"names":["tabGroupNavCss","TabGroupNav","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","value","tabs","orientation","selectionFollowsFocus","rovingEnabled","focusedTabId","selectableTabs","getSelectableTabs","componentWillLoad","syncFocusedTabId","onValueChange","next","prev","undefined","requestAnimationFrame","active","document","activeElement","el","contains","activeId","getAttribute","nextTab","querySelector","focus","preventScroll","blur","onTabsChange","some","tab","id","focusTab","btn","focusLastTab","last","reverse","find","isInactive","focusFirstTab","first","preferred","selectTab","options","dsChange","emit","getFocusedIndex","findIndex","findEnabledLinear","from","step","i","length","findEnabled","len","n","moveFocusToIndex","nextIdx","activateFocusedTab","e","key","item","preventDefault","handleKeyDown","currentIdx","t","isVertical","exit","candidate","lastEnabled","dsRovingExit","getBgClass","background","tabIndexForTab","render","bgClass","isNavigation","h","Host","class","role","ariaLabel","ariaLabelledby","map","index","isTabDivider","isSelected","type","panelId","disabled","tabIndex","onClick","onFocus","tab__label","dot","as","variant","emphasis","color","label"],"sources":["src/wc/components/TabGroupNav/TabGroupNav.css?tag=ds-tab-group-nav&encapsulation=scoped","src/wc/components/TabGroupNav/TabGroupNav.tsx"],"sourcesContent":["@import '../../utils/focus-ring.css';\n@import '../../utils/control-inactive.css';\n\n:host {\n display: block;\n}\n\n.tab-list {\n display: flex;\n align-items: center;\n gap: var(--dimension-space-050);\n position: relative;\n}\n\n/* Vertical orientation */\n.tab-list--vertical {\n flex-direction: column;\n align-items: stretch;\n}\n\n.tab {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--dimension-space-050);\n padding: var(--dimension-space-075);\n background-color: transparent;\n border: none;\n border-radius: var(--dimension-radius-025);\n cursor: pointer;\n -webkit-user-select: none;\n user-select: none;\n color: var(--color-foreground-secondary);\n position: relative;\n /* Only transition color — hover bg is instant (see ::after below) */\n transition: color var(--effect-motion-short-2);\n flex-shrink: 0;\n height: var(--dimension-size-400);\n min-width: var(--dimension-size-400);\n box-sizing: border-box;\n --_hover-bg: var(--color-interaction-hover);\n --_pressed-bg: var(--color-interaction-pressed);\n --_dot: var(--color-foreground-bold-brand);\n --_dot-ring: var(--color-background-secondary);\n}\n\n/* Interaction layer — same pattern as PanelNav */\n.tab::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--dimension-radius-025, 2px);\n background: transparent;\n pointer-events: none;\n transition: none;\n}\n\n.tab:hover::after { background: var(--_hover-bg); transition: none; }\n.tab:active::after { background: var(--_pressed-bg); transition: none; }\n\n.tab--selected { color: var(--color-foreground-primary); }\n\n/* Inactive: `.ds-control-inactive` (25% opacity) — applied via class in TSX. */\n\n/* Vertical tabs read as a list — left-align the label */\n.tab-list--vertical .tab { justify-content: flex-start; }\n\n/* Label — dot anchors top-right like BarNav action icon zone */\n.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/* Clearance for top-right dot — slightly less than space-025 + space-075 */\n.tab__label--dot {\n padding-right: calc(var(--dimension-space-025) + var(--dimension-space-050));\n}\n\n/* Notification dot — top-right corner of the label zone */\n.tab__dot {\n position: absolute;\n top: 0;\n right: 0;\n pointer-events: none;\n}\n\n/* Background context */\n.on-medium {\n --_hover-bg: var(--color-interaction-on-medium-background-hover);\n --_pressed-bg: var(--color-interaction-on-medium-background-pressed);\n --_dot-ring: var(--color-background-medium-neutral);\n --ds-focus-ring-color: var(--color-interaction-on-medium-background-focus);\n}\n\n.on-bold {\n --_hover-bg: var(--color-interaction-on-bold-background-hover);\n --_pressed-bg: var(--color-interaction-on-bold-background-pressed);\n --_dot-ring: var(--color-background-bold-neutral);\n --ds-focus-ring-color: var(--color-interaction-on-bold-background-focus);\n color: var(--color-foreground-on-bold-background-secondary);\n}\n\n.on-bold.tab--selected { color: var(--color-foreground-on-bold-background-primary); }\n\n.on-strong {\n --_hover-bg: var(--color-interaction-on-strong-background-hover);\n --_pressed-bg: var(--color-interaction-on-strong-background-pressed);\n --_dot-ring: var(--color-background-strong-neutral);\n --ds-focus-ring-color: var(--color-interaction-on-strong-background-focus);\n color: var(--color-foreground-on-bold-background-secondary);\n}\n\n.on-strong.tab--selected { color: var(--color-foreground-on-bold-background-primary); }\n\n.on-always-dark {\n --_hover-bg: var(--color-always-dark-interaction-hover);\n --_pressed-bg: var(--color-always-dark-interaction-pressed);\n --_dot-ring: var(--color-always-dark-background);\n --ds-focus-ring-color: var(--color-always-dark-interaction-focus);\n color: var(--color-always-dark-foreground-secondary);\n}\n\n.on-always-dark.tab--selected { color: var(--color-always-dark-foreground-primary); }\n\n.on-navigation {\n color: var(--color-navigation-foreground-secondary);\n --_hover-bg: var(--color-navigation-interaction-hover);\n --_pressed-bg: var(--color-navigation-interaction-pressed);\n --_dot: var(--color-navigation-foreground-brand);\n --_dot-ring: var(--color-navigation-background);\n --ds-focus-ring-color: var(--color-navigation-interaction-focus);\n}\n\n.on-navigation.tab--selected { color: var(--color-navigation-foreground-primary); }\n\n.tab-list--on-navigation .tab-divider__line {\n background-color: var(--color-navigation-border-tertiary);\n}\n\n/* In-tablist visual group separator — not focusable, skipped by keyboard nav */\n.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.tab-divider__line {\n width: var(--dimension-stroke-width-012);\n align-self: stretch;\n background-color: var(--color-border-secondary);\n}\n\n.tab-divider--vertical {\n width: auto;\n height: var(--dimension-space-100);\n align-self: stretch;\n padding-block: 0;\n padding-inline: var(--dimension-space-075);\n}\n\n.tab-divider--vertical .tab-divider__line {\n width: auto;\n height: var(--dimension-stroke-width-012);\n align-self: stretch;\n}\n","import { Component, Prop, Event, EventEmitter, Element, Listen, Watch, Method, State, h, Host } from '@stencil/core';\nimport {\n getSelectableTabs,\n isTabDivider,\n type TabItem,\n type TabItemTab,\n} from '../TabGroup/tab-item-utils';\n\nexport type TabGroupNavBackground = 'faint' | 'medium' | 'bold' | 'strong' | 'always-dark' | 'navigation';\n\n@Component({\n tag: 'ds-tab-group-nav',\n styleUrl: 'TabGroupNav.css',\n scoped: true,\n})\nexport class TabGroupNav {\n @Element() el!: HTMLElement;\n\n @Prop({ mutable: true }) value: string = '';\n @Prop() tabs: TabItem[] = [];\n @Prop() background: TabGroupNavBackground | undefined;\n @Prop({ attribute: 'aria-label' }) ariaLabel: string | undefined;\n @Prop({ attribute: 'aria-labelledby' }) ariaLabelledby: string | undefined;\n @Prop() orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n /**\n * When `false`, arrow keys move focus only — Space/Enter (or click) commits selection.\n * Used by bar nav where each tab is a full page transition.\n */\n @Prop() selectionFollowsFocus: boolean = true;\n\n /** When `false`, every tab uses `tabindex=\"-1\"` (another chrome control owns the tab stop). */\n @Prop() rovingEnabled: boolean = true;\n\n @Event() dsChange!: EventEmitter<string>;\n\n /** Fired when arrow navigation reaches the first/last tab in manual selection mode. */\n @Event() dsRovingExit!: EventEmitter<'start' | 'end'>;\n\n @State() private focusedTabId: string = '';\n\n private get selectableTabs(): TabItemTab[] {\n return getSelectableTabs(this.tabs);\n }\n\n componentWillLoad() {\n this.syncFocusedTabId(this.value);\n }\n\n @Watch('value')\n onValueChange(next: string, prev: string | undefined) {\n if (!this.selectionFollowsFocus) {\n if (prev === undefined || next !== this.focusedTabId) {\n this.syncFocusedTabId(next);\n }\n return;\n }\n\n if (prev === undefined || next === prev) return;\n\n requestAnimationFrame(() => {\n const active = document.activeElement as HTMLElement | null;\n if (!active || !this.el.contains(active)) return;\n\n const activeId = active.getAttribute('data-tab-id');\n if (activeId === next) return;\n\n const nextTab = this.el.querySelector(`[data-tab-id=\"${next}\"]`) as HTMLElement | null;\n if (nextTab) {\n nextTab.focus({ preventScroll: true });\n } else {\n active.blur();\n }\n });\n }\n\n @Watch('tabs')\n onTabsChange() {\n if (!this.selectableTabs.some(tab => tab.id === this.focusedTabId)) {\n this.syncFocusedTabId(this.value);\n }\n }\n\n @Method()\n async focusTab(id: string) {\n this.focusedTabId = id;\n const btn = this.el.querySelector(`[data-tab-id=\"${id}\"]`) as HTMLElement | null;\n btn?.focus({ preventScroll: true });\n }\n\n @Method()\n async focusLastTab() {\n const tabs = this.selectableTabs;\n const last = [...tabs].reverse().find(tab => !tab.isInactive);\n if (last) await this.focusTab(last.id);\n }\n\n @Method()\n async focusFirstTab() {\n const first = this.selectableTabs.find(tab => !tab.isInactive);\n if (first) await this.focusTab(first.id);\n }\n\n private syncFocusedTabId(preferred: string) {\n const tabs = this.selectableTabs;\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 selectTab(id: string, options?: { focus?: boolean }) {\n this.value = id;\n this.focusedTabId = id;\n this.dsChange.emit(id);\n if (options?.focus !== false) {\n void this.focusTab(id);\n }\n }\n\n private getFocusedIndex(): number {\n return this.selectableTabs.findIndex(tab => tab.id === this.focusedTabId);\n }\n\n private findEnabledLinear(from: number, step: 1 | -1): number | null {\n const tabs = this.selectableTabs;\n for (let i = from + step; i >= 0 && i < tabs.length; i += step) {\n if (!tabs[i]?.isInactive) return i;\n }\n return null;\n }\n\n /**\n * Find the next non-inactive tab index relative to `from`, stepping by `step`.\n * Returns `from` unchanged if no other enabled tab exists.\n */\n private findEnabled(from: number, step: 1 | -1): number {\n const tabs = this.selectableTabs;\n const len = tabs.length;\n for (let n = 0; n < len; n++) {\n const i = (from + step * (n + 1) + len * (n + 1)) % len;\n if (!tabs[i]?.isInactive) return i;\n }\n return from;\n }\n\n private moveFocusToIndex(nextIdx: number) {\n const next = this.selectableTabs[nextIdx];\n if (!next) return;\n this.focusedTabId = next.id;\n void this.focusTab(next.id);\n }\n\n private activateFocusedTab(e: KeyboardEvent) {\n if (e.key !== 'Enter' && e.key !== ' ') return;\n const tab = this.selectableTabs.find(item => item.id === this.focusedTabId);\n if (!tab || tab.isInactive) return;\n e.preventDefault();\n this.selectTab(tab.id, { focus: true });\n }\n\n @Listen('keydown')\n handleKeyDown(e: KeyboardEvent) {\n const tabs = this.selectableTabs;\n if (!tabs.length) return;\n\n if (!this.selectionFollowsFocus) {\n if (e.key === 'Enter' || e.key === ' ') {\n this.activateFocusedTab(e);\n return;\n }\n }\n\n const currentIdx = this.selectionFollowsFocus\n ? tabs.findIndex(t => t.id === this.value)\n : this.getFocusedIndex();\n if (currentIdx < 0) return;\n\n const isVertical = this.orientation === 'vertical';\n let nextIdx: number | null = null;\n let exit: 'start' | 'end' | null = null;\n\n if (!isVertical) {\n if (e.key === 'ArrowRight') {\n if (this.selectionFollowsFocus) {\n nextIdx = this.findEnabled(currentIdx, 1);\n } else {\n const candidate = this.findEnabledLinear(currentIdx, 1);\n if (candidate === null) exit = 'end';\n else nextIdx = candidate;\n }\n } else if (e.key === 'ArrowLeft') {\n if (this.selectionFollowsFocus) {\n nextIdx = this.findEnabled(currentIdx, -1);\n } else {\n const candidate = this.findEnabledLinear(currentIdx, -1);\n if (candidate === null) exit = 'start';\n else nextIdx = candidate;\n }\n }\n } else {\n if (e.key === 'ArrowDown') {\n if (this.selectionFollowsFocus) {\n nextIdx = this.findEnabled(currentIdx, 1);\n } else {\n const candidate = this.findEnabledLinear(currentIdx, 1);\n if (candidate === null) exit = 'end';\n else nextIdx = candidate;\n }\n } else if (e.key === 'ArrowUp') {\n if (this.selectionFollowsFocus) {\n nextIdx = this.findEnabled(currentIdx, -1);\n } else {\n const candidate = this.findEnabledLinear(currentIdx, -1);\n if (candidate === null) exit = 'start';\n else nextIdx = candidate;\n }\n }\n }\n\n if (e.key === 'Home') {\n const first = tabs.findIndex(t => !t.isInactive);\n nextIdx = first === -1 ? null : first;\n } else if (e.key === 'End') {\n const lastEnabled = [...tabs].reverse().findIndex(t => !t.isInactive);\n nextIdx = lastEnabled === -1 ? null : tabs.length - 1 - lastEnabled;\n }\n\n if (exit) {\n e.preventDefault();\n this.dsRovingExit.emit(exit);\n return;\n }\n\n if (nextIdx !== null && nextIdx !== currentIdx) {\n e.preventDefault();\n const next = tabs[nextIdx];\n if (this.selectionFollowsFocus) {\n this.selectTab(next.id);\n } else {\n this.moveFocusToIndex(nextIdx);\n }\n }\n }\n\n private getBgClass(): string {\n if (!this.background || this.background === 'faint') return '';\n if (this.background === 'always-dark') return 'on-always-dark';\n if (this.background === 'navigation') return 'on-navigation';\n return `on-${this.background}`;\n }\n\n private tabIndexForTab(tab: TabItemTab): number {\n if (!this.rovingEnabled) return -1;\n if (this.selectionFollowsFocus) {\n return tab.id === this.value ? 0 : -1;\n }\n return tab.id === this.focusedTabId ? 0 : -1;\n }\n\n render() {\n const bgClass = this.getBgClass();\n const isVertical = this.orientation === 'vertical';\n const isNavigation = this.background === 'navigation';\n\n return (\n <Host class=\"tab-group-nav-host\">\n <div\n role=\"tablist\"\n class={{\n 'tab-list': true,\n 'tab-list--vertical': isVertical,\n 'tab-list--on-navigation': isNavigation,\n }}\n aria-label={this.ariaLabel}\n aria-labelledby={this.ariaLabelledby}\n aria-orientation={isVertical ? 'vertical' : undefined}\n >\n {this.tabs.map((tab, index) => {\n if (isTabDivider(tab)) {\n return (\n <div\n key={`divider-${index}`}\n class={{\n 'tab-divider': true,\n 'tab-divider--vertical': isVertical,\n }}\n aria-hidden=\"true\"\n >\n <div class=\"tab-divider__line\" />\n </div>\n );\n }\n\n const isSelected = tab.id === this.value;\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n data-tab-id={tab.id}\n class={{\n tab: true,\n 'tab--selected': isSelected,\n 'ds-focus-ring-inset': true,\n 'ds-control-inactive': !!tab.isInactive,\n [bgClass]: !!bgClass,\n }}\n aria-selected={isSelected}\n aria-disabled={tab.isInactive || undefined}\n aria-controls={tab.panelId ?? undefined}\n disabled={tab.isInactive}\n tabIndex={this.tabIndexForTab(tab)}\n onClick={() => !tab.isInactive && this.selectTab(tab.id)}\n onFocus={() => {\n if (!this.selectionFollowsFocus) {\n this.focusedTabId = tab.id;\n }\n }}\n >\n <span class={{\n tab__label: true,\n 'tab__label--dot': !!tab.dot,\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=\"tab__dot\"\n variant=\"dot\"\n background=\"var(--_dot-ring)\"\n label=\"\"\n aria-hidden=\"true\"\n />\n )}\n </span>\n </button>\n );\n })}\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ import{p as t,H as e,h as s,a as d,t as r}from"./index.js";function i(t){return`ds-text--${t.replace(/^text-/,"")}`}function a(t){return t==="span"||t==="label"?"ds-text--inline-box":"ds-text--block-box"}const o=()=>`.ds-text--display-medium.sc-ds-text-h,.ds-text--display-medium.sc-ds-text{font-size:var(--typography-fontsize-3xl);line-height:var(--typography-lineheight-3xl)}.ds-text--display-small.sc-ds-text-h,.ds-text--display-small.sc-ds-text{font-size:var(--typography-fontsize-2xl);line-height:var(--typography-lineheight-2xl)}.ds-text--title-large.sc-ds-text-h,.ds-text--title-large.sc-ds-text{font-size:var(--typography-fontsize-xl);line-height:var(--typography-lineheight-xl)}.ds-text--title-medium.sc-ds-text-h,.ds-text--title-medium.sc-ds-text{font-size:var(--typography-fontsize-lg);line-height:var(--typography-lineheight-lg)}.ds-text--title-small.sc-ds-text-h,.ds-text--title-small.sc-ds-text{font-size:var(--typography-fontsize-md);line-height:var(--typography-lineheight-md)}.ds-text--body-large.sc-ds-text-h,.ds-text--body-large.sc-ds-text{font-size:var(--typography-fontsize-lg);line-height:var(--typography-lineheight-lg)}.ds-text--body-medium.sc-ds-text-h,.ds-text--body-medium.sc-ds-text{font-size:var(--typography-fontsize-md);line-height:var(--typography-lineheight-md)}.ds-text--body-small.sc-ds-text-h,.ds-text--body-small.sc-ds-text{font-size:var(--typography-fontsize-sm);line-height:var(--typography-lineheight-sm)}.ds-text--caption.sc-ds-text-h,.ds-text--caption.sc-ds-text{font-size:var(--typography-fontsize-xs);line-height:var(--typography-lineheight-xs);text-transform:uppercase}.ds-text--display-medium.ds-text--emphasis.sc-ds-text-h,.ds-text--display-small.ds-text--emphasis.sc-ds-text-h,.ds-text--display-medium.ds-text--emphasis.sc-ds-text,.ds-text--display-small.ds-text--emphasis.sc-ds-text{font-weight:var(--typography-weight-bold);letter-spacing:var(--typography-letterspacing-negative-double)}.ds-text--display-medium.ds-text--regular.sc-ds-text-h,.ds-text--display-small.ds-text--regular.sc-ds-text-h,.ds-text--display-medium.ds-text--regular.sc-ds-text,.ds-text--display-small.ds-text--regular.sc-ds-text{font-weight:var(--typography-weight-regular);letter-spacing:var(--typography-letterspacing-negative)}.ds-text--title-large.ds-text--emphasis.sc-ds-text-h,.ds-text--title-large.ds-text--emphasis.sc-ds-text{font-weight:var(--typography-weight-semibold);letter-spacing:var(--typography-letterspacing-negative-double)}.ds-text--title-large.ds-text--regular.sc-ds-text-h,.ds-text--title-large.ds-text--regular.sc-ds-text{font-weight:var(--typography-weight-regular);letter-spacing:var(--typography-letterspacing-negative)}.ds-text--title-medium.ds-text--emphasis.sc-ds-text-h,.ds-text--title-small.ds-text--emphasis.sc-ds-text-h,.ds-text--title-medium.ds-text--emphasis.sc-ds-text,.ds-text--title-small.ds-text--emphasis.sc-ds-text{font-weight:var(--typography-weight-semibold);letter-spacing:var(--typography-letterspacing-negative)}.ds-text--title-medium.ds-text--regular.sc-ds-text-h,.ds-text--title-small.ds-text--regular.sc-ds-text-h,.ds-text--title-medium.ds-text--regular.sc-ds-text,.ds-text--title-small.ds-text--regular.sc-ds-text{font-weight:var(--typography-weight-regular);letter-spacing:var(--typography-letterspacing-negative-half)}.ds-text--body-large.ds-text--emphasis.sc-ds-text-h,.ds-text--body-medium.ds-text--emphasis.sc-ds-text-h,.ds-text--body-large.ds-text--emphasis.sc-ds-text,.ds-text--body-medium.ds-text--emphasis.sc-ds-text{font-weight:var(--typography-weight-medium);letter-spacing:var(--typography-letterspacing-negative)}.ds-text--body-large.ds-text--regular.sc-ds-text-h,.ds-text--body-medium.ds-text--regular.sc-ds-text-h,.ds-text--body-large.ds-text--regular.sc-ds-text,.ds-text--body-medium.ds-text--regular.sc-ds-text{font-weight:var(--typography-weight-regular);letter-spacing:var(--typography-letterspacing-negative-half)}.ds-text--body-small.ds-text--emphasis.sc-ds-text-h,.ds-text--body-small.ds-text--emphasis.sc-ds-text{font-weight:var(--typography-weight-medium);letter-spacing:var(--typography-letterspacing-negative-half)}.ds-text--body-small.ds-text--regular.sc-ds-text-h,.ds-text--body-small.ds-text--regular.sc-ds-text{font-weight:var(--typography-weight-regular);letter-spacing:var(--typography-letterspacing-none)}.ds-text--caption.ds-text--emphasis.sc-ds-text-h,.ds-text--caption.ds-text--emphasis.sc-ds-text{font-weight:var(--typography-weight-semibold);letter-spacing:var(--typography-letterspacing-positive)}.ds-text--caption.ds-text--regular.sc-ds-text-h,.ds-text--caption.ds-text--regular.sc-ds-text{font-weight:var(--typography-weight-medium);letter-spacing:var(--typography-letterspacing-positive)}.sc-ds-text-h{box-sizing:border-box;max-width:100%;min-width:0;margin:0;padding:0;border:0;font-family:var(--typography-font-family)}.ds-text--inline-box.sc-ds-text-h{display:inline-block}.ds-text--block-box.sc-ds-text-h{display:block;width:100%}.ds-text__element.sc-ds-text{display:block;box-sizing:border-box;width:100%;min-width:0;margin:0;padding:0;border:0;font:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;text-transform:inherit;text-align:inherit;text-decoration:inherit;font-style:inherit;font-variant-numeric:inherit;font-feature-settings:inherit;white-space:inherit;text-wrap:inherit;overflow-wrap:inherit;word-break:inherit;overflow:inherit;text-overflow:inherit}.ds-text--truncate-1.sc-ds-text-h{overflow:hidden}.ds-text--truncate-1.sc-ds-text-h .ds-text__element.sc-ds-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ds-text--truncate-2.sc-ds-text-h,.ds-text--truncate-3.sc-ds-text-h,.ds-text--truncate-4.sc-ds-text-h,.ds-text--truncate-5.sc-ds-text-h{overflow:hidden}.ds-text--truncate-2.sc-ds-text-h .ds-text__element.sc-ds-text,.ds-text--truncate-3.sc-ds-text-h .ds-text__element.sc-ds-text,.ds-text--truncate-4.sc-ds-text-h .ds-text__element.sc-ds-text,.ds-text--truncate-5.sc-ds-text-h .ds-text__element.sc-ds-text{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;word-break:break-word}.ds-text--truncate-2.sc-ds-text-h .ds-text__element.sc-ds-text{-webkit-line-clamp:2}.ds-text--truncate-3.sc-ds-text-h .ds-text__element.sc-ds-text{-webkit-line-clamp:3}.ds-text--truncate-4.sc-ds-text-h .ds-text__element.sc-ds-text{-webkit-line-clamp:4}.ds-text--truncate-5.sc-ds-text-h .ds-text__element.sc-ds-text{-webkit-line-clamp:5}.ds-text--nowrap.sc-ds-text-h,.ds-text--nowrap.sc-ds-text-h .ds-text__element.sc-ds-text{white-space:nowrap;word-break:normal;overflow:hidden;text-overflow:ellipsis;min-width:0}.ds-text--balance.sc-ds-text-h,.ds-text--balance.sc-ds-text-h .ds-text__element.sc-ds-text{text-wrap:balance}.ds-text--pretty.sc-ds-text-h,.ds-text--pretty.sc-ds-text-h .ds-text__element.sc-ds-text{text-wrap:pretty}.ds-text--color-primary.sc-ds-text-h{color:var(--color-foreground-primary)}.ds-text--color-secondary.sc-ds-text-h{color:var(--color-foreground-secondary)}.ds-text--color-tertiary.sc-ds-text-h{color:var(--color-foreground-tertiary)}.ds-text--color-brand.sc-ds-text-h{color:var(--color-foreground-bold-brand)}.ds-text--color-negative.sc-ds-text-h{color:var(--color-foreground-bold-negative)}.ds-text--color-positive.sc-ds-text-h{color:var(--color-foreground-bold-positive)}.ds-text--color-warning.sc-ds-text-h{color:var(--color-foreground-bold-warning)}.ds-text--color-caution.sc-ds-text-h{color:var(--color-foreground-bold-caution)}.ds-text--color-ai.sc-ds-text-h{color:var(--color-foreground-bold-ai)}.ds-text--color-on-strong.sc-ds-text-h{color:var(--color-foreground-on-strong-background-primary)}.ds-text--color-on-bold.sc-ds-text-h{color:var(--color-foreground-on-bold-background-primary)}.ds-text--color-inherit.sc-ds-text-h{color:inherit}.ds-text--decoration-underline.sc-ds-text-h{text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px}.ds-text--decoration-dotted-underline.sc-ds-text-h{text-decoration:underline dotted;text-underline-offset:2px;text-decoration-thickness:1px}.ds-text--italic.sc-ds-text-h{font-style:italic}.ds-text--font-feature-tabular-nums.sc-ds-text-h{font-variant-numeric:tabular-nums;font-feature-settings:'tnum'}.ds-text--align-left.sc-ds-text-h{text-align:left}.ds-text--align-center.sc-ds-text-h{text-align:center}.ds-text--align-right.sc-ds-text-h{text-align:right}`;const n=t(class t extends e{constructor(t){super();if(t!==false){this.__registerHost()}this.variant="text-body-medium";this.emphasis=false;this.italic=false;this.lineTruncation="none";this.fontFeature="normal";this.as="p"}render(){const t=this.as;const e=t=>typeof t==="string"&&t.startsWith("var(--");const r={"ds-text":true,[a(this.as)]:true,[i(this.variant)]:true,"ds-text--emphasis":this.emphasis,"ds-text--regular":!this.emphasis,"ds-text--nowrap":this.wrap==="nowrap","ds-text--balance":this.wrap==="balance","ds-text--pretty":this.wrap==="pretty","ds-text--truncate-1":this.lineTruncation===1&&this.wrap!=="nowrap","ds-text--truncate-2":this.lineTruncation===2&&this.wrap!=="nowrap","ds-text--truncate-3":this.lineTruncation===3&&this.wrap!=="nowrap","ds-text--truncate-4":this.lineTruncation===4&&this.wrap!=="nowrap","ds-text--truncate-5":this.lineTruncation===5&&this.wrap!=="nowrap","ds-text--color-primary":this.color==="primary","ds-text--color-secondary":this.color==="secondary","ds-text--color-tertiary":this.color==="tertiary","ds-text--color-brand":this.color==="brand","ds-text--color-negative":this.color==="negative","ds-text--color-positive":this.color==="positive","ds-text--color-warning":this.color==="warning","ds-text--color-caution":this.color==="caution","ds-text--color-ai":this.color==="ai","ds-text--color-on-strong":this.color==="on-strong","ds-text--color-on-bold":this.color==="on-bold","ds-text--color-inherit":this.color==="inherit","ds-text--decoration-underline":this.decoration==="underline","ds-text--decoration-dotted-underline":this.decoration==="dotted-underline","ds-text--italic":this.italic,"ds-text--align-left":this.align==="left","ds-text--align-center":this.align==="center","ds-text--align-right":this.align==="right","ds-text--font-feature-tabular-nums":this.fontFeature==="tabular-nums"};const o=this.color&&e(this.color)?{color:this.color}:undefined;const n={};if(this.as==="label"&&this.for)n["for"]=this.for;if(this.textId)n["id"]=this.textId;return s(d,{key:"57e8236cb273f91e020d20865626aaa0722d87b9",class:r,style:o},s(t,{key:"b651222dcdd1b8c1d7b58d59a677cd0b5786c35a",class:"ds-text__element",...n},s("slot",{key:"bc73684e85c5536ee3a490e81fa9ac9dd91bd2d9"})))}static get style(){return o()}},[262,"ds-text",{variant:[1],emphasis:[4],color:[1],decoration:[1],italic:[4],align:[1],lineTruncation:[8,"line-truncation"],wrap:[1],fontFeature:[1,"font-feature"],as:[1],for:[1],textId:[1,"text-id"]}]);function x(){if(typeof customElements==="undefined"){return}const t=["ds-text"];t.forEach((t=>{switch(t){case"ds-text":if(!customElements.get(r(t))){customElements.define(r(t),n)}break}}))}x();export{n as T,x as d};
2
+ //# sourceMappingURL=p-sBx2MuF2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["textVariantClass","variant","replace","textDisplayClass","element","textCss","Text","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","emphasis","italic","lineTruncation","fontFeature","as","render","Tag","isCustomColor","c","startsWith","cls","wrap","color","decoration","align","style","undefined","extraProps","for","textId","h","Host","key","class"],"sources":["src/wc/components/Text/text-utils.ts","src/wc/components/Text/Text.css?tag=ds-text&encapsulation=scoped","src/wc/components/Text/Text.tsx"],"sourcesContent":["import type { TextElement, TextVariant } from './text-types';\n\n/** `text-body-medium` → `ds-text--body-medium` */\nexport function textVariantClass(variant: TextVariant): string {\n return `ds-text--${variant.replace(/^text-/, '')}`;\n}\n\n/** Inline semantics get a measurable inline box; paragraphs/headings get a block box. */\nexport function textDisplayClass(element: TextElement): string {\n return element === 'span' || element === 'label'\n ? 'ds-text--inline-box'\n : 'ds-text--block-box';\n}\n","@import '../../utils/typography.css';\n\n:host {\n box-sizing: border-box;\n max-width: 100%;\n min-width: 0;\n margin: 0;\n padding: 0;\n border: 0;\n font-family: var(--typography-font-family);\n}\n\n:host(.ds-text--inline-box) {\n display: inline-block;\n}\n\n:host(.ds-text--block-box) {\n display: block;\n width: 100%;\n}\n\n/*\n * The host is the measurable typography box. The semantic inner element fills\n * it and inherits every text metric without adding margins, padding, or its own\n * line-height strut. One rendered line therefore measures exactly one token\n * line-height; N lines measure N × that token.\n */\n.ds-text__element {\n display: block;\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n margin: 0;\n padding: 0;\n border: 0;\n font: inherit;\n line-height: inherit;\n letter-spacing: inherit;\n color: inherit;\n text-transform: inherit;\n text-align: inherit;\n text-decoration: inherit;\n font-style: inherit;\n font-variant-numeric: inherit;\n font-feature-settings: inherit;\n white-space: inherit;\n text-wrap: inherit;\n overflow-wrap: inherit;\n word-break: inherit;\n /* Consumer truncation on the host (PanelNav, ChartLegend, …) must reach the\n text node — overflow/text-overflow are not inherited by default. */\n overflow: inherit;\n text-overflow: inherit;\n}\n\n/* ── Truncation ─────────────────────────────────────────────────────────── */\n\n:host(.ds-text--truncate-1) {\n overflow: hidden;\n}\n\n:host(.ds-text--truncate-1) .ds-text__element {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n:host(.ds-text--truncate-2),\n:host(.ds-text--truncate-3),\n:host(.ds-text--truncate-4),\n:host(.ds-text--truncate-5) {\n overflow: hidden;\n}\n\n:host(.ds-text--truncate-2) .ds-text__element,\n:host(.ds-text--truncate-3) .ds-text__element,\n:host(.ds-text--truncate-4) .ds-text__element,\n:host(.ds-text--truncate-5) .ds-text__element {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n overflow: hidden;\n text-overflow: ellipsis;\n word-break: break-word;\n}\n\n:host(.ds-text--truncate-2) .ds-text__element { -webkit-line-clamp: 2; }\n:host(.ds-text--truncate-3) .ds-text__element { -webkit-line-clamp: 3; }\n:host(.ds-text--truncate-4) .ds-text__element { -webkit-line-clamp: 4; }\n:host(.ds-text--truncate-5) .ds-text__element { -webkit-line-clamp: 5; }\n\n/* ── Wrap ───────────────────────────────────────────────────────────────── */\n\n:host(.ds-text--nowrap),\n:host(.ds-text--nowrap) .ds-text__element {\n white-space: nowrap;\n word-break: normal;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n}\n\n:host(.ds-text--balance),\n:host(.ds-text--balance) .ds-text__element { text-wrap: balance; }\n\n:host(.ds-text--pretty),\n:host(.ds-text--pretty) .ds-text__element { text-wrap: pretty; }\n\n/* ── Color ──────────────────────────────────────────────────────────────── */\n\n:host(.ds-text--color-primary) { color: var(--color-foreground-primary); }\n:host(.ds-text--color-secondary) { color: var(--color-foreground-secondary); }\n:host(.ds-text--color-tertiary) { color: var(--color-foreground-tertiary); }\n:host(.ds-text--color-brand) { color: var(--color-foreground-bold-brand); }\n:host(.ds-text--color-negative) { color: var(--color-foreground-bold-negative); }\n:host(.ds-text--color-positive) { color: var(--color-foreground-bold-positive); }\n:host(.ds-text--color-warning) { color: var(--color-foreground-bold-warning); }\n:host(.ds-text--color-caution) { color: var(--color-foreground-bold-caution); }\n:host(.ds-text--color-ai) { color: var(--color-foreground-bold-ai); }\n:host(.ds-text--color-on-strong) { color: var(--color-foreground-on-strong-background-primary); }\n:host(.ds-text--color-on-bold) { color: var(--color-foreground-on-bold-background-primary); }\n:host(.ds-text--color-inherit) { color: inherit; }\n\n/* ── Decorations ─────────────────────────────────────────────────────────── */\n\n:host(.ds-text--decoration-underline) {\n text-decoration: underline;\n text-underline-offset: 2px;\n text-decoration-thickness: 1px;\n}\n\n:host(.ds-text--decoration-dotted-underline) {\n text-decoration: underline dotted;\n text-underline-offset: 2px;\n text-decoration-thickness: 1px;\n}\n\n/* ── Style ──────────────────────────────────────────────────────────────── */\n\n:host(.ds-text--italic) { font-style: italic; }\n\n:host(.ds-text--font-feature-tabular-nums) {\n font-variant-numeric: tabular-nums;\n font-feature-settings: 'tnum';\n}\n\n/* ── Align ──────────────────────────────────────────────────────────────── */\n\n:host(.ds-text--align-left) { text-align: left; }\n:host(.ds-text--align-center) { text-align: center; }\n:host(.ds-text--align-right) { text-align: right; }\n","import { Component, Prop, h, Host } from '@stencil/core';\nimport { textDisplayClass, textVariantClass } from './text-utils';\nimport type {\n TextAlign,\n TextColor,\n TextDecoration,\n TextElement,\n TextFontFeature,\n TextVariant,\n LineTruncation,\n TextWrap,\n} from './text-types';\n\n@Component({\n tag: 'ds-text',\n styleUrl: 'Text.css',\n scoped: true,\n})\nexport class Text {\n @Prop() variant: TextVariant = 'text-body-medium';\n /**\n * Heavier weight + tighter letter-spacing for the variant.\n * `false` (default): regular weight (caption stays medium).\n * `true`: display bold, title/caption semibold, body medium.\n */\n @Prop() emphasis: boolean = false;\n @Prop() color: TextColor | undefined;\n @Prop() decoration: TextDecoration | undefined;\n @Prop() italic: boolean = false;\n @Prop() align: TextAlign | undefined;\n @Prop() lineTruncation: LineTruncation = 'none';\n @Prop() wrap: TextWrap | undefined;\n @Prop() fontFeature: TextFontFeature = 'normal';\n @Prop() as: TextElement = 'p';\n /** Maps to `for` attribute on <label> elements. */\n @Prop() for: string | undefined;\n /** Forwarded to the inner element (e.g. aria-labelledby targets). */\n @Prop() textId: string | undefined;\n\n render() {\n // Polymorphic element: TSX treats a variable tag as a component, so a\n // dynamic intrinsic element name must be cast to `any` to render.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const Tag = this.as as any;\n const isCustomColor = (c: TextColor) => typeof c === 'string' && c.startsWith('var(--');\n\n const cls: Record<string, boolean> = {\n 'ds-text': true,\n [textDisplayClass(this.as)]: true,\n [textVariantClass(this.variant)]: true,\n 'ds-text--emphasis': this.emphasis,\n 'ds-text--regular': !this.emphasis,\n 'ds-text--nowrap': this.wrap === 'nowrap',\n 'ds-text--balance': this.wrap === 'balance',\n 'ds-text--pretty': this.wrap === 'pretty',\n 'ds-text--truncate-1': this.lineTruncation === 1 && this.wrap !== 'nowrap',\n 'ds-text--truncate-2': this.lineTruncation === 2 && this.wrap !== 'nowrap',\n 'ds-text--truncate-3': this.lineTruncation === 3 && this.wrap !== 'nowrap',\n 'ds-text--truncate-4': this.lineTruncation === 4 && this.wrap !== 'nowrap',\n 'ds-text--truncate-5': this.lineTruncation === 5 && this.wrap !== 'nowrap',\n 'ds-text--color-primary': this.color === 'primary',\n 'ds-text--color-secondary': this.color === 'secondary',\n 'ds-text--color-tertiary': this.color === 'tertiary',\n 'ds-text--color-brand': this.color === 'brand',\n 'ds-text--color-negative': this.color === 'negative',\n 'ds-text--color-positive': this.color === 'positive',\n 'ds-text--color-warning': this.color === 'warning',\n 'ds-text--color-caution': this.color === 'caution',\n 'ds-text--color-ai': this.color === 'ai',\n 'ds-text--color-on-strong': this.color === 'on-strong',\n 'ds-text--color-on-bold': this.color === 'on-bold',\n 'ds-text--color-inherit': this.color === 'inherit',\n 'ds-text--decoration-underline': this.decoration === 'underline',\n 'ds-text--decoration-dotted-underline': this.decoration === 'dotted-underline',\n 'ds-text--italic': this.italic,\n 'ds-text--align-left': this.align === 'left',\n 'ds-text--align-center': this.align === 'center',\n 'ds-text--align-right': this.align === 'right',\n 'ds-text--font-feature-tabular-nums': this.fontFeature === 'tabular-nums',\n };\n\n const style = this.color && isCustomColor(this.color)\n ? { color: this.color as string }\n : undefined;\n\n const extraProps: Record<string, string> = {};\n if (this.as === 'label' && this.for) extraProps['for'] = this.for;\n if (this.textId) extraProps['id'] = this.textId;\n\n return (\n <Host class={cls} style={style}>\n <Tag class=\"ds-text__element\" {...extraProps}>\n <slot />\n </Tag>\n </Host>\n );\n }\n}\n"],"mappings":"2DAGM,SAAUA,EAAiBC,GAC/B,MAAO,YAAYA,EAAQC,QAAQ,SAAU,KAC/C,CAGM,SAAUC,EAAiBC,GAC/B,OAAOA,IAAY,QAAUA,IAAY,QACrC,sBACA,oBACN,CCZA,MAAMC,EAAU,IAAM,w7P,MCkBTC,EAAIC,EAAA,MAAAD,UAAAE,EALjB,WAAAC,CAAAC,G,4CAMUC,KAAAV,QAAuB,mBAMvBU,KAAAC,SAAoB,MAGpBD,KAAAE,OAAkB,MAElBF,KAAAG,eAAiC,OAEjCH,KAAAI,YAA+B,SAC/BJ,KAAAK,GAAkB,GAgE3B,CA1DC,MAAAC,GAIE,MAAMC,EAAMP,KAAKK,GACjB,MAAMG,EAAiBC,UAAwBA,IAAM,UAAYA,EAAEC,WAAW,UAE9E,MAAMC,EAA+B,CACnC,UAAW,KACX,CAACnB,EAAiBQ,KAAKK,KAAM,KAC7B,CAAChB,EAAiBW,KAAKV,UAAW,KAClC,oBAAqBU,KAAKC,SAC1B,oBAAqBD,KAAKC,SAC1B,kBAAmBD,KAAKY,OAAS,SACjC,mBAAoBZ,KAAKY,OAAS,UAClC,kBAAmBZ,KAAKY,OAAS,SACjC,sBAAuBZ,KAAKG,iBAAmB,GAAKH,KAAKY,OAAS,SAClE,sBAAuBZ,KAAKG,iBAAmB,GAAKH,KAAKY,OAAS,SAClE,sBAAuBZ,KAAKG,iBAAmB,GAAKH,KAAKY,OAAS,SAClE,sBAAuBZ,KAAKG,iBAAmB,GAAKH,KAAKY,OAAS,SAClE,sBAAuBZ,KAAKG,iBAAmB,GAAKH,KAAKY,OAAS,SAClE,yBAA4BZ,KAAKa,QAAU,UAC3C,2BAA4Bb,KAAKa,QAAU,YAC3C,0BAA4Bb,KAAKa,QAAU,WAC3C,uBAA4Bb,KAAKa,QAAU,QAC3C,0BAA4Bb,KAAKa,QAAU,WAC3C,0BAA4Bb,KAAKa,QAAU,WAC3C,yBAA4Bb,KAAKa,QAAU,UAC3C,yBAA4Bb,KAAKa,QAAU,UAC3C,oBAA4Bb,KAAKa,QAAU,KAC3C,2BAA4Bb,KAAKa,QAAU,YAC3C,yBAA4Bb,KAAKa,QAAU,UAC3C,yBAA4Bb,KAAKa,QAAU,UAC3C,gCAAwCb,KAAKc,aAAe,YAC5D,uCAAwCd,KAAKc,aAAe,mBAC5D,kBAAmBd,KAAKE,OACxB,sBAAyBF,KAAKe,QAAU,OACxC,wBAAyBf,KAAKe,QAAU,SACxC,uBAAyBf,KAAKe,QAAU,QACxC,qCAAsCf,KAAKI,cAAgB,gBAG7D,MAAMY,EAAQhB,KAAKa,OAASL,EAAcR,KAAKa,OAC3C,CAAEA,MAAOb,KAAKa,OACdI,UAEJ,MAAMC,EAAqC,GAC3C,GAAIlB,KAAKK,KAAO,SAAWL,KAAKmB,IAAKD,EAAW,OAASlB,KAAKmB,IAC9D,GAAInB,KAAKoB,OAAQF,EAAW,MAAQlB,KAAKoB,OAEzC,OACEC,EAACC,EAAI,CAAAC,IAAA,2CAACC,MAAOb,EAAKK,MAAOA,GACvBK,EAACd,EAAG,CAAAgB,IAAA,2CAACC,MAAM,sBAAuBN,GAChCG,EAAA,QAAAE,IAAA,8C","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  import type { TextVariant } from '../components/Text/text-types';
2
- /** Control-density sizes shared by buttons, tags, chips, select, tooltip. */
3
- export type ControlDensitySize = 'md' | 'sm' | 'xs';
4
- /** Body/caption variant per control-density size (emphasis is separate). */
5
- export declare const CONTROL_TEXT_VARIANT: Record<ControlDensitySize, TextVariant>;
2
+ /** Shared public control sizes. Typography is derived; it is not a separate density API. */
3
+ export type ControlSize = 'md' | 'sm' | 'xs';
4
+ /** Complete text variant selected internally by each control size. */
5
+ export declare const CONTROL_TEXT_VARIANT: Record<ControlSize, TextVariant>;
@@ -10,4 +10,4 @@ export type { TokenDefaultKey } from './token-defaults';
10
10
  export { controlWidthClass } from './control-width';
11
11
  export type { ControlWidth } from './control-width';
12
12
  export { CONTROL_TEXT_VARIANT } from './control-text';
13
- export type { ControlDensitySize } from './control-text';
13
+ export type { ControlSize } from './control-text';
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/wc/components/Icon/icon-cache.ts", "../../../src/wc/utils/resolve-css-length-px.ts", "../../../src/wc/utils/format-compact-number.ts", "../../../src/wc/utils/truncate-svg-text.ts", "../../../src/wc/utils/resolve-css-time-ms.ts", "../../../src/wc/utils/scroll-edge-fade.ts", "../../../src/wc/utils/token-defaults.ts", "../../../src/wc/utils/control-width.ts", "../../../src/wc/utils/control-text.ts"],
4
- "sourcesContent": ["/**\n * Shared SVG glyph cache for ds-icon.\n *\n * Keyed on a global symbol so every module instance (the compiled Stencil chunk\n * inside dist/components and any direct source import, e.g. via `@ds-mo/ui/utils`)\n * reads and writes the same cache. Without this, `registerIcons` called from an\n * app would fill a different Map than the one ds-icon resolves from.\n */\nconst CACHE_KEY = Symbol.for('ds-mo.icon-svg-cache');\n\ntype IconCacheMap = Map<string, string>;\n\ntype GlobalWithIconCache = { [CACHE_KEY]?: IconCacheMap };\n\nexport function iconCacheKey(name: string, flag: boolean): string {\n return flag ? `flag:${name}` : `system:${name}`;\n}\n\nexport function iconCache(): IconCacheMap {\n const g = globalThis as GlobalWithIconCache;\n return (g[CACHE_KEY] ??= new Map());\n}\n\n/**\n * Pre-register glyphs so ds-icon renders them synchronously \u2014 no lazy-chunk\n * fetch, no first-paint pop-in. Import the SVG strings from `@ds-mo/icons`\n * in the app (statically, so they ship in the app's own bundle):\n *\n * ```ts\n * import { Bell } from '@ds-mo/icons/svg/Bell';\n * import { US } from '@ds-mo/icons/svg/flags/US';\n * import { registerIcons } from '@ds-mo/ui/utils';\n *\n * registerIcons({ Bell });\n * registerIcons({ US }, { flag: true });\n * ```\n *\n * Icons that are not registered still work \u2014 they lazy-load on first render\n * and stay cached afterwards.\n */\nexport function registerIcons(icons: Record<string, string>, options?: { flag?: boolean }): void {\n const cache = iconCache();\n const flag = options?.flag === true;\n for (const [name, svg] of Object.entries(icons)) {\n cache.set(iconCacheKey(name, flag), svg);\n }\n}\n", "const lengthPxCache = new Map<string, number>();\n\nlet probeEl: HTMLElement | null = null;\n\nfunction getProbeElement(): HTMLElement | null {\n if (typeof document === 'undefined') return null;\n\n if (!probeEl) {\n probeEl = document.createElement('div');\n probeEl.setAttribute('aria-hidden', 'true');\n probeEl.style.cssText =\n 'position:absolute;visibility:hidden;pointer-events:none;top:0;left:0;width:0;height:0;overflow:hidden;';\n document.documentElement.appendChild(probeEl);\n }\n\n return probeEl;\n}\n\n/** Clear session cache (tests only). */\nexport function clearCssLengthPxCache(): void {\n lengthPxCache.clear();\n}\n\n/**\n * Resolve a CSS length to pixels for layout math.\n * Numbers pass through; `var(--dimension-*)`, `calc(...)`, and `16px` resolve via a hidden probe.\n */\nexport function resolveCssLengthPx(\n value: number | string | undefined,\n fallback: number | string,\n): number {\n const resolved = value === undefined || value === null || value === '' ? fallback : value;\n if (typeof resolved === 'number') return resolved;\n\n const trimmed = resolved.trim();\n if (!trimmed) return resolveCssLengthPx(fallback, 0);\n\n const cached = lengthPxCache.get(trimmed);\n if (cached !== undefined) return cached;\n\n if (/^-?\\d+(\\.\\d+)?$/.test(trimmed)) {\n const n = Number(trimmed);\n lengthPxCache.set(trimmed, n);\n return n;\n }\n\n const pxMatch = trimmed.match(/^(-?\\d+(\\.\\d+)?)px$/);\n if (pxMatch) {\n const px = parseFloat(pxMatch[1]);\n lengthPxCache.set(trimmed, px);\n return px;\n }\n\n const cssLength = /^--[\\w-]+$/.test(trimmed) ? `var(${trimmed})` : trimmed;\n\n const probe = getProbeElement();\n if (!probe) {\n return typeof fallback === 'number' ? fallback : 0;\n }\n\n probe.style.width = cssLength;\n const px = probe.getBoundingClientRect().width;\n probe.style.width = '';\n lengthPxCache.set(trimmed, px);\n return px;\n}\n", "const COMPACT_UNITS: { threshold: number; suffix: string }[] = [\n { threshold: 1_000_000_000, suffix: 'b' },\n { threshold: 1_000_000, suffix: 'm' },\n { threshold: 1_000, suffix: 'k' },\n];\n\n/** Compact large numbers for display: 1000 -> \"1k\", 1500 -> \"1.5k\", 110100 -> \"110.1k\", 1000000 -> \"1m\". */\nexport function formatCompactNumber(value: number): string {\n const sign = value < 0 ? '-' : '';\n const abs = Math.abs(value);\n if (abs < 1000) return String(value);\n\n for (let i = 0; i < COMPACT_UNITS.length; i++) {\n const unit = COMPACT_UNITS[i];\n if (abs < unit.threshold) continue;\n\n let scaled = Math.round((abs / unit.threshold) * 10) / 10;\n // Carry over, e.g. 999.96k rounds to \"1000k\" \u2014 bump to the next unit instead.\n if (scaled >= 1000 && i > 0) {\n const next = COMPACT_UNITS[i - 1];\n scaled = Math.round((abs / next.threshold) * 10) / 10;\n return `${sign}${scaled}${next.suffix}`;\n }\n return `${sign}${scaled}${unit.suffix}`;\n }\n return String(value);\n}\n", "/**\n * Binary-searches the longest prefix of `text` (plus an ellipsis) that fits within `maxWidth`\n * px when rendered by `el`, using the SVG `getComputedTextLength()` API for exact measurement \u2014\n * `text-overflow: ellipsis` doesn't apply to raw SVG `<text>` nodes.\n *\n * Mutates `el.textContent` during measurement; the caller's next render (driven by the\n * returned string going into state) overwrites it with the final value.\n */\nexport function truncateSvgTextToWidth(el: SVGTextElement, text: string, maxWidth: number): string {\n el.textContent = text;\n if (maxWidth <= 0 || el.getComputedTextLength() <= maxWidth) return text;\n\n let lo = 0;\n let hi = text.length;\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2);\n el.textContent = `${text.slice(0, mid)}\u2026`;\n if (el.getComputedTextLength() <= maxWidth) {\n lo = mid;\n } else {\n hi = mid - 1;\n }\n }\n return lo > 0 ? `${text.slice(0, lo)}\u2026` : '\u2026';\n}\n", "/** Parse a CSS <time> value (or motion shorthand's first token) to milliseconds. */\nexport function parseCssTimeMs(value: string, fallback: number): number {\n const firstToken = value.trim().split(/\\s+/)[0] ?? '';\n const num = parseFloat(firstToken);\n if (Number.isNaN(num)) return fallback;\n if (/ms\\s*$/.test(firstToken)) return num;\n if (/s\\s*$/.test(firstToken)) return num * 1000;\n return num;\n}\n\nfunction extractCssCustomProp(ref: string): string | null {\n const varMatch = ref.match(/^var\\(\\s*(--[^),]+)/);\n if (varMatch) return varMatch[1].trim();\n if (ref.startsWith('--')) return ref.trim();\n return null;\n}\n\nfunction readTokenTimeMs(token: string, fallback: number): number {\n if (typeof document === 'undefined') return fallback;\n\n const prop = extractCssCustomProp(token);\n if (!prop) return parseCssTimeMs(token, fallback);\n\n const raw = getComputedStyle(document.documentElement).getPropertyValue(prop).trim();\n return parseCssTimeMs(raw, fallback);\n}\n\n/**\n * Resolve a duration to milliseconds for JS timers aligned with CSS motion tokens.\n * Accepts numbers (ms), raw times (`200ms`, `0.75s`), or `var(--effect-*)` references.\n */\nexport function resolveCssTimeMs(\n value: number | string | undefined,\n fallbackToken: string,\n): number {\n if (typeof value === 'number') return value;\n\n const token = typeof value === 'string' && value.trim() ? value.trim() : fallbackToken;\n const prop = extractCssCustomProp(token);\n\n if (prop) {\n return readTokenTimeMs(token, readTokenTimeMs(fallbackToken, 200));\n }\n\n return parseCssTimeMs(token, readTokenTimeMs(fallbackToken, 200));\n}\n", "/** CSS custom property for scroll-edge fade depth (dimension token or length). */\nexport const SCROLL_EDGE_FADE_SIZE_VAR = '--ds-scroll-edge-fade-size';\n\nexport const SCROLL_EDGE_FADE_DEFAULT_SIZE = 'var(--dimension-size-600)';\n\nexport type ScrollEdgeFadeEdge = 'top' | 'bottom' | 'left' | 'right';\n\nexport type ScrollEdgeFadeSizeToken =\n | 'size-000'\n | 'size-050'\n | 'size-075'\n | 'size-100'\n | 'size-150'\n | 'size-200'\n | 'size-250'\n | 'size-300'\n | 'size-400'\n | 'size-500'\n | 'size-600'\n | 'size-800';\n\nexport type ScrollEdgeFadeSize = ScrollEdgeFadeSizeToken | (string & {});\n\nconst SIZE_VALUE: Record<ScrollEdgeFadeSizeToken, string> = {\n 'size-000': 'var(--dimension-size-000)',\n 'size-050': 'var(--dimension-size-050)',\n 'size-075': 'var(--dimension-size-075)',\n 'size-100': 'var(--dimension-size-100)',\n 'size-150': 'var(--dimension-size-150)',\n 'size-200': 'var(--dimension-size-200)',\n 'size-250': 'var(--dimension-size-250)',\n 'size-300': 'var(--dimension-size-300)',\n 'size-400': 'var(--dimension-size-400)',\n 'size-500': 'var(--dimension-size-500)',\n 'size-600': 'var(--dimension-size-600)',\n 'size-800': 'var(--dimension-size-800)',\n};\n\nconst SIZE_REF = `var(${SCROLL_EDGE_FADE_SIZE_VAR}, ${SCROLL_EDGE_FADE_DEFAULT_SIZE})`;\n\nexport interface ScrollEdgeFadeOptions {\n /** One or more edges to fade. */\n edges: ScrollEdgeFadeEdge | ScrollEdgeFadeEdge[];\n /**\n * When true, or when every listed edge is at its scroll limit, removes the mask.\n * Pass a per-edge map to hide only the edges that are flush (panel-nav bottom fade).\n */\n atEnd?: boolean | Partial<Record<ScrollEdgeFadeEdge, boolean>>;\n /** Force the mask off regardless of scroll position (`ds-fade` `visible={false}`). */\n hidden?: boolean;\n}\n\n/** Resolve a dimension size token name or raw CSS length for `--ds-scroll-edge-fade-size`. */\nexport function resolveScrollEdgeFadeSize(\n size: ScrollEdgeFadeSize = 'size-600',\n height?: string,\n): string {\n if (height) return height;\n return Object.prototype.hasOwnProperty.call(SIZE_VALUE, size)\n ? SIZE_VALUE[size as ScrollEdgeFadeSizeToken]\n : size;\n}\n\n/** Inline style map setting fade depth on a scroll container. */\nexport function scrollEdgeFadeSizeStyle(\n size: ScrollEdgeFadeSize = 'size-600',\n height?: string,\n): Record<string, string> {\n return {\n [SCROLL_EDGE_FADE_SIZE_VAR]: resolveScrollEdgeFadeSize(size, height),\n };\n}\n\n/**\n * Alpha mask for a scroll container edge \u2014 content fades to transparent so\n * textured backgrounds (shell gradients, images) show through.\n */\nexport function scrollEdgeFadeMaskImage(edge: ScrollEdgeFadeEdge): string {\n switch (edge) {\n case 'top':\n return `linear-gradient(to bottom, #000 0, #000 50%, transparent 100%)`;\n case 'bottom':\n return `linear-gradient(to bottom, #000 0, #000 calc(100% - ${SIZE_REF}), transparent 100%)`;\n case 'left':\n return `linear-gradient(to right, #000 0, #000 calc(100% - ${SIZE_REF}), transparent 100%)`;\n case 'right':\n return `linear-gradient(to left, #000 0, #000 calc(100% - ${SIZE_REF}), transparent 100%)`;\n }\n}\n\n/** Inline style map for a masked scroll region (single edge). */\nexport function scrollEdgeFadeMaskStyle(\n edge: ScrollEdgeFadeEdge,\n size: ScrollEdgeFadeSize = 'size-600',\n height?: string,\n): Record<string, string> {\n const mask = scrollEdgeFadeMaskImage(edge);\n return {\n ...scrollEdgeFadeSizeStyle(size, height),\n WebkitMaskImage: mask,\n maskImage: mask,\n WebkitMaskSize: '100% 100%',\n maskSize: '100% 100%',\n };\n}\n\n/** Class map for `scroll-edge-fade` modifiers \u2014 pair with `scroll-edge-fade.css`. */\nexport function scrollEdgeFadeClassMap(opts: ScrollEdgeFadeOptions): Record<string, boolean> {\n const edges = Array.isArray(opts.edges) ? opts.edges : [opts.edges];\n const classes: Record<string, boolean> = {\n 'scroll-edge-fade': true,\n 'scroll-edge-fade--hidden': opts.hidden === true,\n };\n\n for (const edge of edges) {\n classes[`scroll-edge-fade--${edge}`] = true;\n }\n\n const { atEnd } = opts;\n if (atEnd === true) {\n classes['scroll-edge-fade--at-end'] = true;\n } else if (atEnd && typeof atEnd === 'object') {\n const allAtEnd = edges.every(edge => atEnd[edge]);\n if (allAtEnd) {\n classes['scroll-edge-fade--at-end'] = true;\n }\n }\n\n return classes;\n}\n\n/** Whether a scroll container is flush with the given edge (within `threshold` px). */\nexport function isScrollAtEdge(\n el: HTMLElement,\n edge: ScrollEdgeFadeEdge,\n threshold = 2,\n): boolean {\n switch (edge) {\n case 'top':\n return el.scrollTop <= threshold;\n case 'bottom':\n return el.scrollHeight - el.scrollTop - el.clientHeight <= threshold;\n case 'left':\n return el.scrollLeft <= threshold;\n case 'right':\n return el.scrollWidth - el.scrollLeft - el.clientWidth <= threshold;\n }\n}\n", "import {\n dimensionIconographyMd,\n dimensionIconographySm,\n dimensionIconographyXs,\n dimensionMenuWidthXs,\n dimensionPanelWidth2xs,\n dimensionPanelWidthLg,\n dimensionPanelWidthMd,\n dimensionRadius025,\n dimensionSize200,\n dimensionSize300,\n dimensionSize400,\n dimensionSize600,\n dimensionSize800,\n dimensionSpace050,\n dimensionSpace200,\n typographyLineheightLg,\n typographyLineheightMd,\n typographyLineheightSm,\n typographyLineheightXl,\n typographyLineheightXs,\n effectAnimationDelayLong2,\n effectAnimationDelayMedium1,\n effectAnimationDelayMedium3,\n effectAnimationDelayInstant,\n effectAnimationDelayShort2,\n effectAnimationDurationMedium1,\n effectAnimationDurationShort3,\n effectMotionShort2,\n effectMotionShort3,\n} from '@ds-mo/tokens/ts';\n\n/** TokoMo CSS custom-property names for shared component defaults (runtime resolution). */\nexport const TOKEN_DEFAULTS = {\n space050: dimensionSpace050,\n space200: dimensionSpace200,\n radius025: dimensionRadius025,\n size200: dimensionSize200,\n size300: dimensionSize300,\n size400: dimensionSize400,\n size600: dimensionSize600,\n size800: dimensionSize800,\n iconographyMd: dimensionIconographyMd,\n iconographySm: dimensionIconographySm,\n iconographyXs: dimensionIconographyXs,\n panelWidth2xs: dimensionPanelWidth2xs,\n panelWidthMd: dimensionPanelWidthMd,\n panelWidthLg: dimensionPanelWidthLg,\n menuWidthXs: dimensionMenuWidthXs,\n lineheightLg: typographyLineheightLg,\n lineheightMd: typographyLineheightMd,\n lineheightSm: typographyLineheightSm,\n lineheightXl: typographyLineheightXl,\n lineheightXs: typographyLineheightXs,\n motionShort2: effectMotionShort2,\n motionShort3: effectMotionShort3,\n animationDurationShort3: effectAnimationDurationShort3,\n animationDurationMedium1: effectAnimationDurationMedium1,\n animationDelayInstant: effectAnimationDelayInstant,\n animationDelayMedium1: effectAnimationDelayMedium1,\n animationDelayMedium3: effectAnimationDelayMedium3,\n animationDelayShort2: effectAnimationDelayShort2,\n animationDelayLong2: effectAnimationDelayLong2,\n /** Unmeasured menu height fallback: 20\u00D7 base (160px at default scale). */\n menuFallbackHeight: 'calc(var(--dimension-size-base) * 20)',\n /** Unmeasured tooltip width fallback: size-800 + size-200 (80px). */\n tooltipFallbackWidth: 'calc(var(--dimension-size-800) + var(--dimension-size-200))',\n /** Fill-mode donut diameter floor: 16\u00D7 size-base (128px). */\n donutFillMin: 'calc(var(--dimension-size-base) * 16)',\n /** Fill-mode donut diameter ceiling: 24\u00D7 size-base (192px). */\n donutFillMax: 'calc(var(--dimension-size-base) * 24)',\n} as const;\n\nexport type TokenDefaultKey = keyof typeof TOKEN_DEFAULTS;\n\n/** Valid CSS length strings for overlay offset props \u2014 bind on `sideOffset` / `alignOffset` in hosts. */\nexport const TOKEN_CSS_LENGTHS = {\n space050: `var(${dimensionSpace050})`,\n space200: `var(${dimensionSpace200})`,\n menuWidthXs: `var(${dimensionMenuWidthXs})`,\n} as const;\n", "/** Shared width fit for interactive controls (buttons, select, \u2026). */\nexport type ControlWidth = 'hug' | 'fill';\n\n/** Host / control class map for `width=\"hug\" | \"fill\"`. */\nexport function controlWidthClass(width: ControlWidth): Record<string, boolean> {\n return {\n 'ds-control-width--hug': width === 'hug',\n 'ds-control-width--fill': width === 'fill',\n };\n}\n", "import type { TextVariant } from '../components/Text/text-types';\n\n/** Control-density sizes shared by buttons, tags, chips, select, tooltip. */\nexport type ControlDensitySize = 'md' | 'sm' | 'xs';\n\n/** Body/caption variant per control-density size (emphasis is separate). */\nexport const CONTROL_TEXT_VARIANT: Record<ControlDensitySize, TextVariant> = {\n md: 'text-body-medium',\n sm: 'text-body-small',\n xs: 'text-caption',\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Shared SVG glyph cache for ds-icon.\n *\n * Keyed on a global symbol so every module instance (the compiled Stencil chunk\n * inside dist/components and any direct source import, e.g. via `@ds-mo/ui/utils`)\n * reads and writes the same cache. Without this, `registerIcons` called from an\n * app would fill a different Map than the one ds-icon resolves from.\n */\nconst CACHE_KEY = Symbol.for('ds-mo.icon-svg-cache');\n\ntype IconCacheMap = Map<string, string>;\n\ntype GlobalWithIconCache = { [CACHE_KEY]?: IconCacheMap };\n\nexport function iconCacheKey(name: string, flag: boolean): string {\n return flag ? `flag:${name}` : `system:${name}`;\n}\n\nexport function iconCache(): IconCacheMap {\n const g = globalThis as GlobalWithIconCache;\n return (g[CACHE_KEY] ??= new Map());\n}\n\n/**\n * Pre-register glyphs so ds-icon renders them synchronously \u2014 no lazy-chunk\n * fetch, no first-paint pop-in. Import the SVG strings from `@ds-mo/icons`\n * in the app (statically, so they ship in the app's own bundle):\n *\n * ```ts\n * import { Bell } from '@ds-mo/icons/svg/Bell';\n * import { US } from '@ds-mo/icons/svg/flags/US';\n * import { registerIcons } from '@ds-mo/ui/utils';\n *\n * registerIcons({ Bell });\n * registerIcons({ US }, { flag: true });\n * ```\n *\n * Icons that are not registered still work \u2014 they lazy-load on first render\n * and stay cached afterwards.\n */\nexport function registerIcons(icons: Record<string, string>, options?: { flag?: boolean }): void {\n const cache = iconCache();\n const flag = options?.flag === true;\n for (const [name, svg] of Object.entries(icons)) {\n cache.set(iconCacheKey(name, flag), svg);\n }\n}\n", "const lengthPxCache = new Map<string, number>();\n\nlet probeEl: HTMLElement | null = null;\n\nfunction getProbeElement(): HTMLElement | null {\n if (typeof document === 'undefined') return null;\n\n if (!probeEl) {\n probeEl = document.createElement('div');\n probeEl.setAttribute('aria-hidden', 'true');\n probeEl.style.cssText =\n 'position:absolute;visibility:hidden;pointer-events:none;top:0;left:0;width:0;height:0;overflow:hidden;';\n document.documentElement.appendChild(probeEl);\n }\n\n return probeEl;\n}\n\n/** Clear session cache (tests only). */\nexport function clearCssLengthPxCache(): void {\n lengthPxCache.clear();\n}\n\n/**\n * Resolve a CSS length to pixels for layout math.\n * Numbers pass through; `var(--dimension-*)`, `calc(...)`, and `16px` resolve via a hidden probe.\n */\nexport function resolveCssLengthPx(\n value: number | string | undefined,\n fallback: number | string,\n): number {\n const resolved = value === undefined || value === null || value === '' ? fallback : value;\n if (typeof resolved === 'number') return resolved;\n\n const trimmed = resolved.trim();\n if (!trimmed) return resolveCssLengthPx(fallback, 0);\n\n const cached = lengthPxCache.get(trimmed);\n if (cached !== undefined) return cached;\n\n if (/^-?\\d+(\\.\\d+)?$/.test(trimmed)) {\n const n = Number(trimmed);\n lengthPxCache.set(trimmed, n);\n return n;\n }\n\n const pxMatch = trimmed.match(/^(-?\\d+(\\.\\d+)?)px$/);\n if (pxMatch) {\n const px = parseFloat(pxMatch[1]);\n lengthPxCache.set(trimmed, px);\n return px;\n }\n\n const cssLength = /^--[\\w-]+$/.test(trimmed) ? `var(${trimmed})` : trimmed;\n\n const probe = getProbeElement();\n if (!probe) {\n return typeof fallback === 'number' ? fallback : 0;\n }\n\n probe.style.width = cssLength;\n const px = probe.getBoundingClientRect().width;\n probe.style.width = '';\n lengthPxCache.set(trimmed, px);\n return px;\n}\n", "const COMPACT_UNITS: { threshold: number; suffix: string }[] = [\n { threshold: 1_000_000_000, suffix: 'b' },\n { threshold: 1_000_000, suffix: 'm' },\n { threshold: 1_000, suffix: 'k' },\n];\n\n/** Compact large numbers for display: 1000 -> \"1k\", 1500 -> \"1.5k\", 110100 -> \"110.1k\", 1000000 -> \"1m\". */\nexport function formatCompactNumber(value: number): string {\n const sign = value < 0 ? '-' : '';\n const abs = Math.abs(value);\n if (abs < 1000) return String(value);\n\n for (let i = 0; i < COMPACT_UNITS.length; i++) {\n const unit = COMPACT_UNITS[i];\n if (abs < unit.threshold) continue;\n\n let scaled = Math.round((abs / unit.threshold) * 10) / 10;\n // Carry over, e.g. 999.96k rounds to \"1000k\" \u2014 bump to the next unit instead.\n if (scaled >= 1000 && i > 0) {\n const next = COMPACT_UNITS[i - 1];\n scaled = Math.round((abs / next.threshold) * 10) / 10;\n return `${sign}${scaled}${next.suffix}`;\n }\n return `${sign}${scaled}${unit.suffix}`;\n }\n return String(value);\n}\n", "/**\n * Binary-searches the longest prefix of `text` (plus an ellipsis) that fits within `maxWidth`\n * px when rendered by `el`, using the SVG `getComputedTextLength()` API for exact measurement \u2014\n * `text-overflow: ellipsis` doesn't apply to raw SVG `<text>` nodes.\n *\n * Mutates `el.textContent` during measurement; the caller's next render (driven by the\n * returned string going into state) overwrites it with the final value.\n */\nexport function truncateSvgTextToWidth(el: SVGTextElement, text: string, maxWidth: number): string {\n el.textContent = text;\n if (maxWidth <= 0 || el.getComputedTextLength() <= maxWidth) return text;\n\n let lo = 0;\n let hi = text.length;\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2);\n el.textContent = `${text.slice(0, mid)}\u2026`;\n if (el.getComputedTextLength() <= maxWidth) {\n lo = mid;\n } else {\n hi = mid - 1;\n }\n }\n return lo > 0 ? `${text.slice(0, lo)}\u2026` : '\u2026';\n}\n", "/** Parse a CSS <time> value (or motion shorthand's first token) to milliseconds. */\nexport function parseCssTimeMs(value: string, fallback: number): number {\n const firstToken = value.trim().split(/\\s+/)[0] ?? '';\n const num = parseFloat(firstToken);\n if (Number.isNaN(num)) return fallback;\n if (/ms\\s*$/.test(firstToken)) return num;\n if (/s\\s*$/.test(firstToken)) return num * 1000;\n return num;\n}\n\nfunction extractCssCustomProp(ref: string): string | null {\n const varMatch = ref.match(/^var\\(\\s*(--[^),]+)/);\n if (varMatch) return varMatch[1].trim();\n if (ref.startsWith('--')) return ref.trim();\n return null;\n}\n\nfunction readTokenTimeMs(token: string, fallback: number): number {\n if (typeof document === 'undefined') return fallback;\n\n const prop = extractCssCustomProp(token);\n if (!prop) return parseCssTimeMs(token, fallback);\n\n const raw = getComputedStyle(document.documentElement).getPropertyValue(prop).trim();\n return parseCssTimeMs(raw, fallback);\n}\n\n/**\n * Resolve a duration to milliseconds for JS timers aligned with CSS motion tokens.\n * Accepts numbers (ms), raw times (`200ms`, `0.75s`), or `var(--effect-*)` references.\n */\nexport function resolveCssTimeMs(\n value: number | string | undefined,\n fallbackToken: string,\n): number {\n if (typeof value === 'number') return value;\n\n const token = typeof value === 'string' && value.trim() ? value.trim() : fallbackToken;\n const prop = extractCssCustomProp(token);\n\n if (prop) {\n return readTokenTimeMs(token, readTokenTimeMs(fallbackToken, 200));\n }\n\n return parseCssTimeMs(token, readTokenTimeMs(fallbackToken, 200));\n}\n", "/** CSS custom property for scroll-edge fade depth (dimension token or length). */\nexport const SCROLL_EDGE_FADE_SIZE_VAR = '--ds-scroll-edge-fade-size';\n\nexport const SCROLL_EDGE_FADE_DEFAULT_SIZE = 'var(--dimension-size-600)';\n\nexport type ScrollEdgeFadeEdge = 'top' | 'bottom' | 'left' | 'right';\n\nexport type ScrollEdgeFadeSizeToken =\n | 'size-000'\n | 'size-050'\n | 'size-075'\n | 'size-100'\n | 'size-150'\n | 'size-200'\n | 'size-250'\n | 'size-300'\n | 'size-400'\n | 'size-500'\n | 'size-600'\n | 'size-800';\n\nexport type ScrollEdgeFadeSize = ScrollEdgeFadeSizeToken | (string & {});\n\nconst SIZE_VALUE: Record<ScrollEdgeFadeSizeToken, string> = {\n 'size-000': 'var(--dimension-size-000)',\n 'size-050': 'var(--dimension-size-050)',\n 'size-075': 'var(--dimension-size-075)',\n 'size-100': 'var(--dimension-size-100)',\n 'size-150': 'var(--dimension-size-150)',\n 'size-200': 'var(--dimension-size-200)',\n 'size-250': 'var(--dimension-size-250)',\n 'size-300': 'var(--dimension-size-300)',\n 'size-400': 'var(--dimension-size-400)',\n 'size-500': 'var(--dimension-size-500)',\n 'size-600': 'var(--dimension-size-600)',\n 'size-800': 'var(--dimension-size-800)',\n};\n\nconst SIZE_REF = `var(${SCROLL_EDGE_FADE_SIZE_VAR}, ${SCROLL_EDGE_FADE_DEFAULT_SIZE})`;\n\nexport interface ScrollEdgeFadeOptions {\n /** One or more edges to fade. */\n edges: ScrollEdgeFadeEdge | ScrollEdgeFadeEdge[];\n /**\n * When true, or when every listed edge is at its scroll limit, removes the mask.\n * Pass a per-edge map to hide only the edges that are flush (panel-nav bottom fade).\n */\n atEnd?: boolean | Partial<Record<ScrollEdgeFadeEdge, boolean>>;\n /** Force the mask off regardless of scroll position (`ds-fade` `visible={false}`). */\n hidden?: boolean;\n}\n\n/** Resolve a dimension size token name or raw CSS length for `--ds-scroll-edge-fade-size`. */\nexport function resolveScrollEdgeFadeSize(\n size: ScrollEdgeFadeSize = 'size-600',\n height?: string,\n): string {\n if (height) return height;\n return Object.prototype.hasOwnProperty.call(SIZE_VALUE, size)\n ? SIZE_VALUE[size as ScrollEdgeFadeSizeToken]\n : size;\n}\n\n/** Inline style map setting fade depth on a scroll container. */\nexport function scrollEdgeFadeSizeStyle(\n size: ScrollEdgeFadeSize = 'size-600',\n height?: string,\n): Record<string, string> {\n return {\n [SCROLL_EDGE_FADE_SIZE_VAR]: resolveScrollEdgeFadeSize(size, height),\n };\n}\n\n/**\n * Alpha mask for a scroll container edge \u2014 content fades to transparent so\n * textured backgrounds (shell gradients, images) show through.\n */\nexport function scrollEdgeFadeMaskImage(edge: ScrollEdgeFadeEdge): string {\n switch (edge) {\n case 'top':\n return `linear-gradient(to bottom, #000 0, #000 50%, transparent 100%)`;\n case 'bottom':\n return `linear-gradient(to bottom, #000 0, #000 calc(100% - ${SIZE_REF}), transparent 100%)`;\n case 'left':\n return `linear-gradient(to right, #000 0, #000 calc(100% - ${SIZE_REF}), transparent 100%)`;\n case 'right':\n return `linear-gradient(to left, #000 0, #000 calc(100% - ${SIZE_REF}), transparent 100%)`;\n }\n}\n\n/** Inline style map for a masked scroll region (single edge). */\nexport function scrollEdgeFadeMaskStyle(\n edge: ScrollEdgeFadeEdge,\n size: ScrollEdgeFadeSize = 'size-600',\n height?: string,\n): Record<string, string> {\n const mask = scrollEdgeFadeMaskImage(edge);\n return {\n ...scrollEdgeFadeSizeStyle(size, height),\n WebkitMaskImage: mask,\n maskImage: mask,\n WebkitMaskSize: '100% 100%',\n maskSize: '100% 100%',\n };\n}\n\n/** Class map for `scroll-edge-fade` modifiers \u2014 pair with `scroll-edge-fade.css`. */\nexport function scrollEdgeFadeClassMap(opts: ScrollEdgeFadeOptions): Record<string, boolean> {\n const edges = Array.isArray(opts.edges) ? opts.edges : [opts.edges];\n const classes: Record<string, boolean> = {\n 'scroll-edge-fade': true,\n 'scroll-edge-fade--hidden': opts.hidden === true,\n };\n\n for (const edge of edges) {\n classes[`scroll-edge-fade--${edge}`] = true;\n }\n\n const { atEnd } = opts;\n if (atEnd === true) {\n classes['scroll-edge-fade--at-end'] = true;\n } else if (atEnd && typeof atEnd === 'object') {\n const allAtEnd = edges.every(edge => atEnd[edge]);\n if (allAtEnd) {\n classes['scroll-edge-fade--at-end'] = true;\n }\n }\n\n return classes;\n}\n\n/** Whether a scroll container is flush with the given edge (within `threshold` px). */\nexport function isScrollAtEdge(\n el: HTMLElement,\n edge: ScrollEdgeFadeEdge,\n threshold = 2,\n): boolean {\n switch (edge) {\n case 'top':\n return el.scrollTop <= threshold;\n case 'bottom':\n return el.scrollHeight - el.scrollTop - el.clientHeight <= threshold;\n case 'left':\n return el.scrollLeft <= threshold;\n case 'right':\n return el.scrollWidth - el.scrollLeft - el.clientWidth <= threshold;\n }\n}\n", "import {\n dimensionIconographyMd,\n dimensionIconographySm,\n dimensionIconographyXs,\n dimensionMenuWidthXs,\n dimensionPanelWidth2xs,\n dimensionPanelWidthLg,\n dimensionPanelWidthMd,\n dimensionRadius025,\n dimensionSize200,\n dimensionSize300,\n dimensionSize400,\n dimensionSize600,\n dimensionSize800,\n dimensionSpace050,\n dimensionSpace200,\n typographyLineheightLg,\n typographyLineheightMd,\n typographyLineheightSm,\n typographyLineheightXl,\n typographyLineheightXs,\n effectAnimationDelayLong2,\n effectAnimationDelayMedium1,\n effectAnimationDelayMedium3,\n effectAnimationDelayInstant,\n effectAnimationDelayShort2,\n effectAnimationDurationMedium1,\n effectAnimationDurationShort3,\n effectMotionShort2,\n effectMotionShort3,\n} from '@ds-mo/tokens/ts';\n\n/** TokoMo CSS custom-property names for shared component defaults (runtime resolution). */\nexport const TOKEN_DEFAULTS = {\n space050: dimensionSpace050,\n space200: dimensionSpace200,\n radius025: dimensionRadius025,\n size200: dimensionSize200,\n size300: dimensionSize300,\n size400: dimensionSize400,\n size600: dimensionSize600,\n size800: dimensionSize800,\n iconographyMd: dimensionIconographyMd,\n iconographySm: dimensionIconographySm,\n iconographyXs: dimensionIconographyXs,\n panelWidth2xs: dimensionPanelWidth2xs,\n panelWidthMd: dimensionPanelWidthMd,\n panelWidthLg: dimensionPanelWidthLg,\n menuWidthXs: dimensionMenuWidthXs,\n lineheightLg: typographyLineheightLg,\n lineheightMd: typographyLineheightMd,\n lineheightSm: typographyLineheightSm,\n lineheightXl: typographyLineheightXl,\n lineheightXs: typographyLineheightXs,\n motionShort2: effectMotionShort2,\n motionShort3: effectMotionShort3,\n animationDurationShort3: effectAnimationDurationShort3,\n animationDurationMedium1: effectAnimationDurationMedium1,\n animationDelayInstant: effectAnimationDelayInstant,\n animationDelayMedium1: effectAnimationDelayMedium1,\n animationDelayMedium3: effectAnimationDelayMedium3,\n animationDelayShort2: effectAnimationDelayShort2,\n animationDelayLong2: effectAnimationDelayLong2,\n /** Unmeasured menu height fallback: 20\u00D7 base (160px at default scale). */\n menuFallbackHeight: 'calc(var(--dimension-size-base) * 20)',\n /** Unmeasured tooltip width fallback: size-800 + size-200 (80px). */\n tooltipFallbackWidth: 'calc(var(--dimension-size-800) + var(--dimension-size-200))',\n /** Fill-mode donut diameter floor: 16\u00D7 size-base (128px). */\n donutFillMin: 'calc(var(--dimension-size-base) * 16)',\n /** Fill-mode donut diameter ceiling: 24\u00D7 size-base (192px). */\n donutFillMax: 'calc(var(--dimension-size-base) * 24)',\n} as const;\n\nexport type TokenDefaultKey = keyof typeof TOKEN_DEFAULTS;\n\n/** Valid CSS length strings for overlay offset props \u2014 bind on `sideOffset` / `alignOffset` in hosts. */\nexport const TOKEN_CSS_LENGTHS = {\n space050: `var(${dimensionSpace050})`,\n space200: `var(${dimensionSpace200})`,\n menuWidthXs: `var(${dimensionMenuWidthXs})`,\n} as const;\n", "/** Shared width fit for interactive controls (buttons, select, \u2026). */\nexport type ControlWidth = 'hug' | 'fill';\n\n/** Host / control class map for `width=\"hug\" | \"fill\"`. */\nexport function controlWidthClass(width: ControlWidth): Record<string, boolean> {\n return {\n 'ds-control-width--hug': width === 'hug',\n 'ds-control-width--fill': width === 'fill',\n };\n}\n", "import type { TextVariant } from '../components/Text/text-types';\n\n/** Shared public control sizes. Typography is derived; it is not a separate density API. */\nexport type ControlSize = 'md' | 'sm' | 'xs';\n\n/** Complete text variant selected internally by each control size. */\nexport const CONTROL_TEXT_VARIANT: Record<ControlSize, TextVariant> = {\n md: 'text-body-medium',\n sm: 'text-body-small',\n xs: 'text-caption',\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["px"]
7
7
  }
@@ -25,13 +25,11 @@ export declare class ChartDonut {
25
25
  * Externally controlled highlight, matched by `label` — e.g. drive this from a sibling
26
26
  * `ds-chart-legend`'s `dsItemHover` event to keep chart and legend hover in sync.
27
27
  * Falls back to this component's own pointer/focus hover when unset.
28
- * External sync dims slices only the data-viz tooltip is reserved for this
29
- * component's own pointer/keyboard interaction.
28
+ * Slice hover dims peer slices and emits `dsSliceHover` for legend sync no data-viz
29
+ * tooltip (the legend already surfaces label/value).
30
30
  */
31
31
  activeLabel: string | null;
32
32
  private hoveredLabel;
33
- /** Own-hover tooltip (cursor-following). Cleared on leave; not driven by `activeLabel`. */
34
- private tooltip;
35
33
  /** Center text, truncated with an ellipsis if it doesn't fit inside the inner circle. */
36
34
  private displayedValueText;
37
35
  private displayedCaptionText;
@@ -41,7 +39,6 @@ export declare class ChartDonut {
41
39
  dsSliceHover: EventEmitter<ChartDatum | null>;
42
40
  private valueTextEl?;
43
41
  private captionTextEl?;
44
- private wrapperEl?;
45
42
  private resizeObserver;
46
43
  private get isFillMode();
47
44
  private get fillMinPx();
@@ -57,8 +54,6 @@ export declare class ChartDonut {
57
54
  private applyAvailableSize;
58
55
  private teardownResizeObserver;
59
56
  private handleHover;
60
- private handleSliceMove;
61
- private updateTooltip;
62
57
  componentDidRender(): void;
63
58
  render(): any;
64
59
  }
@@ -1,13 +1,17 @@
1
+ import type { IconColor, IconSize } from '../Icon/Icon';
2
+ export type LoaderSize = IconSize;
3
+ export type LoaderColor = IconColor;
1
4
  export declare class Loader {
2
- /** Render size number (px) or TokoMo length (`var(--dimension-iconography-md)`, etc.). */
3
- size: number | string;
5
+ /** Iconography size token. Maps to `--dimension-iconography-{size}`. Default `md` = 20 px. */
6
+ size: LoaderSize;
7
+ /** Semantic foreground color token, or a raw CSS var reference. Same tokens as `ds-icon`. */
8
+ color: LoaderColor | undefined;
4
9
  /**
5
10
  * Accessible label for standalone usage. Wraps the spinner in a live region
6
11
  * and renders the label visually-hidden. Omit when the host element already
7
12
  * conveys busy state via aria-busy.
8
13
  */
9
14
  label: string | undefined;
10
- private get sizePx();
11
15
  render(): any;
12
16
  }
13
17
  //# sourceMappingURL=Loader.d.ts.map
@@ -1,2 +1,2 @@
1
- export type {} from './Loader';
1
+ export type { LoaderSize, LoaderColor } from './Loader';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,6 @@
1
- import type { TextVariant } from './text-types';
1
+ import type { TextElement, TextVariant } from './text-types';
2
2
  /** `text-body-medium` → `ds-text--body-medium` */
3
3
  export declare function textVariantClass(variant: TextVariant): string;
4
+ /** Inline semantics get a measurable inline box; paragraphs/headings get a block box. */
5
+ export declare function textDisplayClass(element: TextElement): string;
4
6
  //# sourceMappingURL=text-utils.d.ts.map
@@ -1,8 +1,9 @@
1
1
  export type TooltipDataVizSide = 'left' | 'right';
2
2
  export type TooltipDataVizAlign = 'top' | 'bottom';
3
3
  /**
4
- * Positioned value/label callout for chart hover interactions (donut slice, bar,
5
- * line point, ...). Unlike `ds-tooltip`, this doesn't bind to a slotted anchor element
4
+ * Positioned value/label callout for chart hover interactions (bar, line point, …).
5
+ * Donut charts skip this legend sync already surfaces the hovered slice.
6
+ * Unlike `ds-tooltip`, this doesn't bind to a slotted anchor element —
6
7
  * charts hover-highlight data that lives inside an SVG, so the chart itself computes
7
8
  * the anchor point (e.g. the cursor position while hovering) and passes it in as `x`/`y`.
8
9
  *
@@ -22,6 +22,7 @@ import { DividerInset, DividerLength, DividerOrientation, DividerSurface } from
22
22
  import { EmptyStateType } from "./components/EmptyState/EmptyState";
23
23
  import { IconColor, IconSize } from "./components/Icon/Icon";
24
24
  import { InputType } from "./components/Input/Input";
25
+ import { LoaderColor, LoaderSize } from "./components/Loader/Loader";
25
26
  import { MenuItemData, MenuSection } from "./components/Menu/menu-types";
26
27
  import { MenuAlign, MenuSide } from "./components/Menu/menu-position";
27
28
  import { ModalWidth } from "./components/Modal/Modal";
@@ -56,6 +57,7 @@ export { DividerInset, DividerLength, DividerOrientation, DividerSurface } from
56
57
  export { EmptyStateType } from "./components/EmptyState/EmptyState";
57
58
  export { IconColor, IconSize } from "./components/Icon/Icon";
58
59
  export { InputType } from "./components/Input/Input";
60
+ export { LoaderColor, LoaderSize } from "./components/Loader/Loader";
59
61
  export { MenuItemData, MenuSection } from "./components/Menu/menu-types";
60
62
  export { MenuAlign, MenuSide } from "./components/Menu/menu-position";
61
63
  export { ModalWidth } from "./components/Modal/Modal";
@@ -401,7 +403,7 @@ export namespace Components {
401
403
  }
402
404
  interface DsChartDonut {
403
405
  /**
404
- * Externally controlled highlight, matched by `label` — e.g. drive this from a sibling `ds-chart-legend`'s `dsItemHover` event to keep chart and legend hover in sync. Falls back to this component's own pointer/focus hover when unset. External sync dims slices onlythe data-viz tooltip is reserved for this component's own pointer/keyboard interaction.
406
+ * Externally controlled highlight, matched by `label` — e.g. drive this from a sibling `ds-chart-legend`'s `dsItemHover` event to keep chart and legend hover in sync. Falls back to this component's own pointer/focus hover when unset. Slice hover dims peer slices and emits `dsSliceHover` for legend sync no data-viz tooltip (the legend already surfaces label/value).
405
407
  * @default null
406
408
  */
407
409
  "activeLabel": string | null;
@@ -639,15 +641,19 @@ export namespace Components {
639
641
  "value": string;
640
642
  }
641
643
  interface DsLoader {
644
+ /**
645
+ * Semantic foreground color token, or a raw CSS var reference. Same tokens as `ds-icon`.
646
+ */
647
+ "color": LoaderColor | undefined;
642
648
  /**
643
649
  * Accessible label for standalone usage. Wraps the spinner in a live region and renders the label visually-hidden. Omit when the host element already conveys busy state via aria-busy.
644
650
  */
645
651
  "label": string | undefined;
646
652
  /**
647
- * Render size number (px) or TokoMo length (`var(--dimension-iconography-md)`, etc.).
648
- * @default TOKEN_DEFAULTS.iconographyMd
653
+ * Iconography size token. Maps to `--dimension-iconography-{size}`. Default `md` = 20 px.
654
+ * @default 'md'
649
655
  */
650
- "size": number | string;
656
+ "size": LoaderSize;
651
657
  }
652
658
  interface DsMenu {
653
659
  /**
@@ -1156,8 +1162,9 @@ export namespace Components {
1156
1162
  "size": TooltipSize;
1157
1163
  }
1158
1164
  /**
1159
- * Positioned value/label callout for chart hover interactions (donut slice, bar,
1160
- * line point, ...). Unlike `ds-tooltip`, this doesn't bind to a slotted anchor element
1165
+ * Positioned value/label callout for chart hover interactions (bar, line point, …).
1166
+ * Donut charts skip this legend sync already surfaces the hovered slice.
1167
+ * Unlike `ds-tooltip`, this doesn't bind to a slotted anchor element —
1161
1168
  * charts hover-highlight data that lives inside an SVG, so the chart itself computes
1162
1169
  * the anchor point (e.g. the cursor position while hovering) and passes it in as `x`/`y`.
1163
1170
  * Renders `position: absolute` — place inside a `position: relative` chart wrapper,
@@ -1851,8 +1858,9 @@ declare global {
1851
1858
  new (): HTMLDsTooltipElement;
1852
1859
  };
1853
1860
  /**
1854
- * Positioned value/label callout for chart hover interactions (donut slice, bar,
1855
- * line point, ...). Unlike `ds-tooltip`, this doesn't bind to a slotted anchor element
1861
+ * Positioned value/label callout for chart hover interactions (bar, line point, …).
1862
+ * Donut charts skip this legend sync already surfaces the hovered slice.
1863
+ * Unlike `ds-tooltip`, this doesn't bind to a slotted anchor element —
1856
1864
  * charts hover-highlight data that lives inside an SVG, so the chart itself computes
1857
1865
  * the anchor point (e.g. the cursor position while hovering) and passes it in as `x`/`y`.
1858
1866
  * Renders `position: absolute` — place inside a `position: relative` chart wrapper,
@@ -2255,7 +2263,7 @@ declare namespace LocalJSX {
2255
2263
  }
2256
2264
  interface DsChartDonut {
2257
2265
  /**
2258
- * Externally controlled highlight, matched by `label` — e.g. drive this from a sibling `ds-chart-legend`'s `dsItemHover` event to keep chart and legend hover in sync. Falls back to this component's own pointer/focus hover when unset. External sync dims slices onlythe data-viz tooltip is reserved for this component's own pointer/keyboard interaction.
2266
+ * Externally controlled highlight, matched by `label` — e.g. drive this from a sibling `ds-chart-legend`'s `dsItemHover` event to keep chart and legend hover in sync. Falls back to this component's own pointer/focus hover when unset. Slice hover dims peer slices and emits `dsSliceHover` for legend sync no data-viz tooltip (the legend already surfaces label/value).
2259
2267
  * @default null
2260
2268
  */
2261
2269
  "activeLabel"?: string | null;
@@ -2511,15 +2519,19 @@ declare namespace LocalJSX {
2511
2519
  "value"?: string;
2512
2520
  }
2513
2521
  interface DsLoader {
2522
+ /**
2523
+ * Semantic foreground color token, or a raw CSS var reference. Same tokens as `ds-icon`.
2524
+ */
2525
+ "color"?: LoaderColor | undefined;
2514
2526
  /**
2515
2527
  * Accessible label for standalone usage. Wraps the spinner in a live region and renders the label visually-hidden. Omit when the host element already conveys busy state via aria-busy.
2516
2528
  */
2517
2529
  "label"?: string | undefined;
2518
2530
  /**
2519
- * Render size number (px) or TokoMo length (`var(--dimension-iconography-md)`, etc.).
2520
- * @default TOKEN_DEFAULTS.iconographyMd
2531
+ * Iconography size token. Maps to `--dimension-iconography-{size}`. Default `md` = 20 px.
2532
+ * @default 'md'
2521
2533
  */
2522
- "size"?: number | string;
2534
+ "size"?: LoaderSize;
2523
2535
  }
2524
2536
  interface DsMenu {
2525
2537
  /**
@@ -3072,8 +3084,9 @@ declare namespace LocalJSX {
3072
3084
  "size"?: TooltipSize;
3073
3085
  }
3074
3086
  /**
3075
- * Positioned value/label callout for chart hover interactions (donut slice, bar,
3076
- * line point, ...). Unlike `ds-tooltip`, this doesn't bind to a slotted anchor element
3087
+ * Positioned value/label callout for chart hover interactions (bar, line point, …).
3088
+ * Donut charts skip this legend sync already surfaces the hovered slice.
3089
+ * Unlike `ds-tooltip`, this doesn't bind to a slotted anchor element —
3077
3090
  * charts hover-highlight data that lives inside an SVG, so the chart itself computes
3078
3091
  * the anchor point (e.g. the cursor position while hovering) and passes it in as `x`/`y`.
3079
3092
  * Renders `position: absolute` — place inside a `position: relative` chart wrapper,
@@ -3264,7 +3277,8 @@ declare namespace LocalJSX {
3264
3277
  "ariaDescribedby": string | undefined;
3265
3278
  }
3266
3279
  interface DsLoaderAttributes {
3267
- "size": string;
3280
+ "size": LoaderSize;
3281
+ "color": LoaderColor | undefined;
3268
3282
  "label": string | undefined;
3269
3283
  }
3270
3284
  interface DsMenuAttributes {
@@ -3537,8 +3551,9 @@ declare module "@stencil/core" {
3537
3551
  */
3538
3552
  "ds-tooltip": LocalJSX.IntrinsicElements["ds-tooltip"] & JSXBase.HTMLAttributes<HTMLDsTooltipElement>;
3539
3553
  /**
3540
- * Positioned value/label callout for chart hover interactions (donut slice, bar,
3541
- * line point, ...). Unlike `ds-tooltip`, this doesn't bind to a slotted anchor element
3554
+ * Positioned value/label callout for chart hover interactions (bar, line point, …).
3555
+ * Donut charts skip this legend sync already surfaces the hovered slice.
3556
+ * Unlike `ds-tooltip`, this doesn't bind to a slotted anchor element —
3542
3557
  * charts hover-highlight data that lives inside an SVG, so the chart itself computes
3543
3558
  * the anchor point (e.g. the cursor position while hovering) and passes it in as `x`/`y`.
3544
3559
  * Renders `position: absolute` — place inside a `position: relative` chart wrapper,
@@ -1,6 +1,6 @@
1
1
  import type { TextVariant } from '../components/Text/text-types';
2
- /** Control-density sizes shared by buttons, tags, chips, select, tooltip. */
3
- export type ControlDensitySize = 'md' | 'sm' | 'xs';
4
- /** Body/caption variant per control-density size (emphasis is separate). */
5
- export declare const CONTROL_TEXT_VARIANT: Record<ControlDensitySize, TextVariant>;
2
+ /** Shared public control sizes. Typography is derived; it is not a separate density API. */
3
+ export type ControlSize = 'md' | 'sm' | 'xs';
4
+ /** Complete text variant selected internally by each control size. */
5
+ export declare const CONTROL_TEXT_VARIANT: Record<ControlSize, TextVariant>;
6
6
  //# sourceMappingURL=control-text.d.ts.map
@@ -10,5 +10,5 @@ export type { TokenDefaultKey } from './token-defaults';
10
10
  export { controlWidthClass } from './control-width';
11
11
  export type { ControlWidth } from './control-width';
12
12
  export { CONTROL_TEXT_VARIANT } from './control-text';
13
- export type { ControlDensitySize } from './control-text';
13
+ export type { ControlSize } from './control-text';
14
14
  //# sourceMappingURL=index.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ds-mo/ui",
3
- "version": "2.15.0",
3
+ "version": "3.0.0",
4
4
  "description": "CompoMo — composable web components styled with TokoMo design tokens",
5
5
  "keywords": [
6
6
  "web-components",
@@ -69,9 +69,9 @@
69
69
  "pretest": "node scripts/generate-icon-catalog.mjs",
70
70
  "build": "stencil build && node scripts/patch-index-types.mjs && node scripts/verify-icons-externalized.mjs && node scripts/write-build-stamp.mjs && node scripts/build-lib-exports.mjs",
71
71
  "verify:pack": "node scripts/verify-npm-pack.mjs && node scripts/verify-nav-import.mjs",
72
- "test": "node --import tsx/esm --test tests/panel-nav-utils.test.ts tests/panel-tools.test.ts tests/text.test.ts tests/shell-shortcuts.test.ts tests/shell-gradient-presets.test.ts tests/shell-view-transition.test.ts tests/shell-gradient.test.ts tests/shell-chrome-metrics.test.ts tests/shell-chrome-layer.test.ts tests/chrome-transition.test.ts tests/bar-nav-overflow-hysteresis.test.ts tests/badge-gradient-ring.test.ts tests/scroll-edge-fade.test.ts tests/resolve-css-length-px.test.ts tests/resolve-css-time-ms.test.ts tests/overlay-positioning.test.ts tests/menu-position.test.ts tests/menu-placement.test.ts tests/bar-nav-utils.test.ts tests/bar-nav-tabs-menu-utils.test.ts tests/bar-nav-dom-utils.test.ts tests/icon-catalog.test.ts tests/icon-cache.test.ts tests/icon-svg.test.ts",
72
+ "test": "node --import tsx/esm --test tests/panel-nav-utils.test.ts tests/panel-tools.test.ts tests/text.test.ts tests/eslint-plugin-local.test.ts tests/shell-shortcuts.test.ts tests/shell-gradient-presets.test.ts tests/shell-view-transition.test.ts tests/shell-gradient.test.ts tests/shell-chrome-metrics.test.ts tests/shell-chrome-layer.test.ts tests/chrome-transition.test.ts tests/bar-nav-overflow-hysteresis.test.ts tests/badge-gradient-ring.test.ts tests/scroll-edge-fade.test.ts tests/resolve-css-length-px.test.ts tests/resolve-css-time-ms.test.ts tests/overlay-positioning.test.ts tests/menu-position.test.ts tests/menu-placement.test.ts tests/bar-nav-utils.test.ts tests/bar-nav-tabs-menu-utils.test.ts tests/bar-nav-dom-utils.test.ts tests/icon-catalog.test.ts tests/icon-cache.test.ts tests/icon-svg.test.ts",
73
73
  "test:e2e": "npm run build && playwright test",
74
- "test:e2e:install": "playwright install chromium",
74
+ "test:e2e:install": "playwright install chromium firefox",
75
75
  "build:docs": "stencil build --docs",
76
76
  "dev": "node scripts/generate-icon-catalog.mjs && stencil build --watch",
77
77
  "storybook:ui": "node scripts/storybook-ui.mjs",
@@ -114,9 +114,9 @@
114
114
  "@stencil/angular-output-target": "^1.3.1",
115
115
  "@stencil/core": "^4.43.4",
116
116
  "@stencil/react-output-target": "^1.5.3",
117
- "@storybook/addon-docs": "^10.4.2",
118
- "@storybook/web-components": "^10.4.2",
119
- "@storybook/web-components-vite": "^10.4.2",
117
+ "@storybook/addon-docs": "^10.5.0",
118
+ "@storybook/web-components": "^10.5.0",
119
+ "@storybook/web-components-vite": "^10.5.0",
120
120
  "@types/d3-array": "^3.2.2",
121
121
  "@types/d3-scale": "^4.0.9",
122
122
  "@types/d3-shape": "^3.1.8",
@@ -130,7 +130,7 @@
130
130
  "lit": "^3.3.3",
131
131
  "react": "^19.2.7",
132
132
  "react-dom": "^19.2.7",
133
- "storybook": "^10.4.2",
133
+ "storybook": "^10.5.0",
134
134
  "stylelint": "^17.14.0",
135
135
  "stylelint-config-standard": "^40.0.0",
136
136
  "tsx": "^4.20.3",
@@ -553,14 +553,14 @@ export declare interface DsInput extends Components.DsInput {
553
553
 
554
554
 
555
555
  @ProxyCmp({
556
- inputs: ['label', 'size']
556
+ inputs: ['color', 'label', 'size']
557
557
  })
558
558
  @Component({
559
559
  selector: 'ds-loader',
560
560
  changeDetection: ChangeDetectionStrategy.OnPush,
561
561
  template: '<ng-content></ng-content>',
562
562
  // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
563
- inputs: ['label', 'size'],
563
+ inputs: ['color', 'label', 'size'],
564
564
  standalone: false
565
565
  })
566
566
  export class DsLoader {
@@ -121,11 +121,9 @@ export class Banner {
121
121
  </div>
122
122
  )}
123
123
  <div class="banner-body">
124
- <span class="banner-message">
125
- <ds-text as="span" variant="text-body-medium" color="inherit">
126
- {this.message}
127
- </ds-text>
128
- </span>
124
+ <ds-text class="banner-message" as="div" variant="text-body-medium" color="inherit">
125
+ {this.message}
126
+ </ds-text>
129
127
  {this.showDismiss && (
130
128
  <button
131
129
  type="button"