@ds-mo/ui 2.14.0 → 2.15.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 (155) 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-setting.js.map +1 -1
  14. package/dist/components/ds-card.js +1 -1
  15. package/dist/components/ds-chart-bar.js +1 -1
  16. package/dist/components/ds-chart-bar.js.map +1 -1
  17. package/dist/components/ds-chart-donut.js +1 -1
  18. package/dist/components/ds-chart-donut.js.map +1 -1
  19. package/dist/components/ds-chart-legend.js +1 -1
  20. package/dist/components/ds-chart-legend.js.map +1 -1
  21. package/dist/components/ds-chart-line.js +1 -1
  22. package/dist/components/ds-chart-line.js.map +1 -1
  23. package/dist/components/ds-checkbox.js +1 -1
  24. package/dist/components/ds-checkbox.js.map +1 -1
  25. package/dist/components/ds-chip.js +1 -1
  26. package/dist/components/ds-chip.js.map +1 -1
  27. package/dist/components/ds-divider.js +1 -1
  28. package/dist/components/ds-empty-state.js +1 -1
  29. package/dist/components/ds-empty-state.js.map +1 -1
  30. package/dist/components/ds-field.js +1 -1
  31. package/dist/components/ds-field.js.map +1 -1
  32. package/dist/components/ds-icon.js +1 -1
  33. package/dist/components/ds-input.js +1 -1
  34. package/dist/components/ds-input.js.map +1 -1
  35. package/dist/components/ds-menu.js +1 -1
  36. package/dist/components/ds-modal.js +1 -1
  37. package/dist/components/ds-modal.js.map +1 -1
  38. package/dist/components/ds-pagination.js +1 -1
  39. package/dist/components/ds-pagination.js.map +1 -1
  40. package/dist/components/ds-panel-nav.js +1 -1
  41. package/dist/components/ds-panel-nav.js.map +1 -1
  42. package/dist/components/ds-panel-tools.js +1 -1
  43. package/dist/components/ds-panel-tools.js.map +1 -1
  44. package/dist/components/ds-radio-group.js +1 -1
  45. package/dist/components/ds-radio-group.js.map +1 -1
  46. package/dist/components/ds-select.js +1 -1
  47. package/dist/components/ds-select.js.map +1 -1
  48. package/dist/components/ds-shell-gradient-picker.js +1 -1
  49. package/dist/components/ds-shell-gradient-swatch.js +1 -1
  50. package/dist/components/ds-slider.js +1 -1
  51. package/dist/components/ds-slider.js.map +1 -1
  52. package/dist/components/ds-tab-group-nav.js +1 -1
  53. package/dist/components/ds-tab-group.js +1 -1
  54. package/dist/components/ds-tab-group.js.map +1 -1
  55. package/dist/components/ds-table.js +1 -1
  56. package/dist/components/ds-table.js.map +1 -1
  57. package/dist/components/ds-tag.js +1 -1
  58. package/dist/components/ds-tag.js.map +1 -1
  59. package/dist/components/ds-text.js +1 -1
  60. package/dist/components/ds-toggle.js +1 -1
  61. package/dist/components/ds-tooltip-data-viz.js +1 -1
  62. package/dist/components/ds-tooltip.js +1 -1
  63. package/dist/components/p-061wD4FM.js +2 -0
  64. package/dist/components/p-061wD4FM.js.map +1 -0
  65. package/dist/components/p-AiGt4dQS.js +2 -0
  66. package/dist/components/p-AiGt4dQS.js.map +1 -0
  67. package/dist/components/p-BDQgqw5J.js +2 -0
  68. package/dist/components/p-BDQgqw5J.js.map +1 -0
  69. package/dist/components/p-BvF44IQK.js +2 -0
  70. package/dist/components/p-BvF44IQK.js.map +1 -0
  71. package/dist/components/{p-CYmVDfd_.js → p-C3ORQUOp.js} +2 -2
  72. package/dist/components/{p-B82KZX9D.js → p-CyFVn2Sc.js} +2 -2
  73. package/dist/components/p-DIgHkkPe.js +2 -0
  74. package/dist/components/p-DIgHkkPe.js.map +1 -0
  75. package/dist/components/p-DOqi-Vkb.js +2 -0
  76. package/dist/components/p-DOqi-Vkb.js.map +1 -0
  77. package/dist/components/p-DQ3MyAC7.js +2 -0
  78. package/dist/components/p-DQ3MyAC7.js.map +1 -0
  79. package/dist/components/{p-BAeKw2pj.js → p-DkcH8mRl.js} +2 -2
  80. package/dist/components/p-DrhmNrKD.js +2 -0
  81. package/dist/components/p-DrhmNrKD.js.map +1 -0
  82. package/dist/components/{p-B2_D4IDN.js → p-DujEDZ7f.js} +2 -2
  83. package/dist/components/p-DujEDZ7f.js.map +1 -0
  84. package/dist/components/p-DwQ-zdqa.js +2 -0
  85. package/dist/components/p-DwQ-zdqa.js.map +1 -0
  86. package/dist/lib/components/Text/text-types.d.ts +9 -0
  87. package/dist/lib/utils/control-text.d.ts +5 -0
  88. package/dist/lib/utils/index.d.ts +2 -0
  89. package/dist/lib/utils/index.js +8 -0
  90. package/dist/lib/utils/index.js.map +3 -3
  91. package/dist/types/components/ButtonFilled/ButtonFilled.d.ts +1 -1
  92. package/dist/types/components/ButtonUnfilled/ButtonUnfilled.d.ts +1 -1
  93. package/dist/types/components/Select/Select.d.ts +1 -1
  94. package/dist/types/components/Text/Text.d.ts +9 -9
  95. package/dist/types/components/Text/index.d.ts +2 -1
  96. package/dist/types/components/Text/text-types.d.ts +10 -0
  97. package/dist/types/components/Text/text-utils.d.ts +4 -0
  98. package/dist/types/components/Tooltip/Tooltip.d.ts +1 -0
  99. package/dist/types/components.d.ts +22 -2
  100. package/dist/types/utils/control-text.d.ts +6 -0
  101. package/dist/types/utils/index.d.ts +2 -0
  102. package/package.json +2 -2
  103. package/src/angular/proxies.ts +2 -2
  104. package/src/wc/components/Badge/Badge.tsx +6 -8
  105. package/src/wc/components/Banner/Banner.tsx +5 -1
  106. package/src/wc/components/BarNav/BarNav.tsx +5 -1
  107. package/src/wc/components/ButtonFilled/ButtonFilled.tsx +6 -11
  108. package/src/wc/components/ButtonUnfilled/ButtonUnfilled.tsx +6 -11
  109. package/src/wc/components/Card/Card.tsx +10 -8
  110. package/src/wc/components/Checkbox/Checkbox.tsx +4 -2
  111. package/src/wc/components/Chip/Chip.tsx +6 -10
  112. package/src/wc/components/EmptyState/EmptyState.tsx +2 -2
  113. package/src/wc/components/Field/Field.tsx +3 -1
  114. package/src/wc/components/Menu/Menu.tsx +14 -4
  115. package/src/wc/components/Modal/Modal.tsx +17 -3
  116. package/src/wc/components/Pagination/Pagination.tsx +3 -3
  117. package/src/wc/components/PanelNav/PanelNav.tsx +5 -4
  118. package/src/wc/components/PanelTools/PanelTools.tsx +5 -7
  119. package/src/wc/components/RadioGroup/RadioGroup.tsx +5 -1
  120. package/src/wc/components/Select/Select.tsx +12 -18
  121. package/src/wc/components/Slider/Slider.tsx +6 -2
  122. package/src/wc/components/TabGroup/TabGroup.tsx +3 -2
  123. package/src/wc/components/TabGroupNav/TabGroupNav.tsx +3 -2
  124. package/src/wc/components/Table/Table.tsx +12 -10
  125. package/src/wc/components/Tag/Tag.tsx +6 -10
  126. package/src/wc/components/Text/Text.tsx +51 -57
  127. package/src/wc/components/Text/index.ts +12 -1
  128. package/src/wc/components/Text/text-types.ts +23 -0
  129. package/src/wc/components/Text/text-utils.ts +6 -0
  130. package/src/wc/components/Tooltip/Tooltip.tsx +58 -41
  131. package/src/wc/components/TooltipDataViz/TooltipDataViz.tsx +1 -1
  132. package/src/wc/components.d.ts +22 -2
  133. package/src/wc/utils/control-density.css +6 -1
  134. package/src/wc/utils/control-text.ts +11 -0
  135. package/src/wc/utils/index.ts +2 -0
  136. package/dist/components/p-1m8r0wFg.js +0 -2
  137. package/dist/components/p-1m8r0wFg.js.map +0 -1
  138. package/dist/components/p-B2_D4IDN.js.map +0 -1
  139. package/dist/components/p-B5NcWtpp.js +0 -2
  140. package/dist/components/p-B5NcWtpp.js.map +0 -1
  141. package/dist/components/p-CDHRJqea.js +0 -2
  142. package/dist/components/p-CDHRJqea.js.map +0 -1
  143. package/dist/components/p-CtwNUCnp.js +0 -2
  144. package/dist/components/p-CtwNUCnp.js.map +0 -1
  145. package/dist/components/p-CuRjYmBk.js +0 -2
  146. package/dist/components/p-CuRjYmBk.js.map +0 -1
  147. package/dist/components/p-Dlol7hPg.js +0 -2
  148. package/dist/components/p-Dlol7hPg.js.map +0 -1
  149. package/dist/components/p-EK1hOP19.js +0 -2
  150. package/dist/components/p-EK1hOP19.js.map +0 -1
  151. package/dist/components/p-XNHSe8Mg.js +0 -2
  152. package/dist/components/p-XNHSe8Mg.js.map +0 -1
  153. /package/dist/components/{p-CYmVDfd_.js.map → p-C3ORQUOp.js.map} +0 -0
  154. /package/dist/components/{p-B82KZX9D.js.map → p-CyFVn2Sc.js.map} +0 -0
  155. /package/dist/components/{p-BAeKw2pj.js.map → p-DkcH8mRl.js.map} +0 -0
@@ -180,9 +180,10 @@ export class TabGroup {
180
180
  <span class={{
181
181
  tab__label: true,
182
182
  'tab__label--dot': !!tab.dot,
183
- [isSelected ? 'text-body-small-emphasis' : 'text-body-small']: true,
184
183
  }}>
185
- {tab.label}
184
+ <ds-text as="span" variant="text-body-small" emphasis={isSelected} color="inherit">
185
+ {tab.label}
186
+ </ds-text>
186
187
  {tab.dot && (
187
188
  <ds-badge
188
189
  class="tab__dot"
@@ -323,9 +323,10 @@ export class TabGroupNav {
323
323
  <span class={{
324
324
  tab__label: true,
325
325
  'tab__label--dot': !!tab.dot,
326
- [isSelected ? 'text-body-medium-emphasis' : 'text-body-medium']: true,
327
326
  }}>
328
- {tab.label}
327
+ <ds-text as="span" variant="text-body-medium" emphasis={isSelected} color="inherit">
328
+ {tab.label}
329
+ </ds-text>
329
330
  {tab.dot && (
330
331
  <ds-badge
331
332
  class="tab__dot"
@@ -150,9 +150,9 @@ export class Table {
150
150
  }}
151
151
  style={col.minWidth ? { minWidth: typeof col.minWidth === 'number' ? `${col.minWidth}px` : col.minWidth as string } : undefined}
152
152
  >
153
- <span class="text-body-small-emphasis" style={{ color: 'var(--color-foreground-secondary)' }}>
153
+ <ds-text as="span" variant="text-body-small" emphasis color="secondary">
154
154
  {col.header}
155
- </span>
155
+ </ds-text>
156
156
  {isSorted && (
157
157
  <span class="sort-indicator" aria-hidden="true">
158
158
  {sort.direction === 'asc' ? '↑' : '↓'}
@@ -182,9 +182,9 @@ export class Table {
182
182
  {/* Empty state */}
183
183
  {isEmpty && (
184
184
  <div class="empty-row" style={{ gridColumn: '1 / -1' }}>
185
- <p class="text-body-medium" style={{ margin: '0', color: 'var(--color-foreground-secondary)' }}>
185
+ <ds-text as="p" variant="text-body-medium" color="secondary">
186
186
  {this.emptyMessage}
187
- </p>
187
+ </ds-text>
188
188
  </div>
189
189
  )}
190
190
 
@@ -220,8 +220,10 @@ export class Table {
220
220
  }}
221
221
  role="cell"
222
222
  >
223
- <span class="text-body-medium cell-value">
224
- {String(getCellValue(col, row) ?? '')}
223
+ <span class="cell-value">
224
+ <ds-text as="span" variant="text-body-medium">
225
+ {String(getCellValue(col, row) ?? '')}
226
+ </ds-text>
225
227
  </span>
226
228
  </div>
227
229
  ))}
@@ -243,11 +245,11 @@ export class Table {
243
245
  this.dsPageChange.emit({ pageIndex: this.pageIndex });
244
246
  }}
245
247
  >
246
- <span class="text-body-small">Previous</span>
248
+ <ds-text as="span" variant="text-body-small">Previous</ds-text>
247
249
  </button>
248
- <span class="text-body-small" style={{ color: 'var(--color-foreground-secondary)' }}>
250
+ <ds-text as="span" variant="text-body-small" color="secondary">
249
251
  Page {this.pageIndex! + 1} of {totalPages}
250
- </span>
252
+ </ds-text>
251
253
  <button
252
254
  type="button"
253
255
  class="page-button"
@@ -257,7 +259,7 @@ export class Table {
257
259
  this.dsPageChange.emit({ pageIndex: this.pageIndex });
258
260
  }}
259
261
  >
260
- <span class="text-body-small">Next</span>
262
+ <ds-text as="span" variant="text-body-small">Next</ds-text>
261
263
  </button>
262
264
  </div>
263
265
  )}
@@ -1,16 +1,10 @@
1
1
  import { Component, Prop, h, Host } from '@stencil/core';
2
+ import { CONTROL_TEXT_VARIANT } from '../../utils';
2
3
 
3
4
  export type TagIntent = 'neutral' | 'brand' | 'ai' | 'negative' | 'warning' | 'caution' | 'positive';
4
5
  export type TagContrast = 'strong' | 'bold' | 'medium' | 'faint';
5
6
  export type TagSize = 'md' | 'sm' | 'xs';
6
7
 
7
- /** Text variant per control-density recipe (md / sm / xs). */
8
- const TEXT_VARIANT: Record<TagSize, string> = {
9
- md: 'text-body-medium',
10
- sm: 'text-body-small',
11
- xs: 'text-caption',
12
- };
13
-
14
8
  /**
15
9
  * `ds-icon` size prop matching control-density icon metrics
16
10
  * (md→20 / sm→16 / xs→12 via `--dimension-iconography-*`).
@@ -35,7 +29,7 @@ export class Tag {
35
29
  @Prop() maxWidth: string | number | undefined;
36
30
 
37
31
  render() {
38
- const textVariant = TEXT_VARIANT[this.size];
32
+ const textVariant = CONTROL_TEXT_VARIANT[this.size];
39
33
  const iconSize = ICON_SIZE[this.size];
40
34
 
41
35
  const maxWidthStyle = this.maxWidth != null
@@ -60,8 +54,10 @@ export class Tag {
60
54
  <span class="tag__icon-slot" data-icon-size={iconSize}>
61
55
  <slot name="icon" />
62
56
  </span>
63
- <span class={{ 'tag__label': true, [textVariant]: true }}>
64
- {this.label}
57
+ <span class="tag__label">
58
+ <ds-text as="span" variant={textVariant} color="inherit">
59
+ {this.label}
60
+ </ds-text>
65
61
  </span>
66
62
  </Host>
67
63
  );
@@ -1,32 +1,15 @@
1
1
  import { Component, Prop, h, Host } from '@stencil/core';
2
-
3
- export type TextVariant =
4
- | 'text-display-medium'
5
- | 'text-display-small'
6
- | 'text-title-large'
7
- | 'text-title-medium'
8
- | 'text-title-small'
9
- | 'text-body-large'
10
- | 'text-body-large-emphasis'
11
- | 'text-body-medium'
12
- | 'text-body-medium-emphasis'
13
- | 'text-body-small'
14
- | 'text-body-small-emphasis'
15
- | 'text-caption'
16
- | 'text-caption-emphasis';
17
-
18
- export type TextColorToken =
19
- | 'primary' | 'secondary' | 'tertiary'
20
- | 'brand' | 'negative' | 'positive' | 'warning' | 'caution' | 'ai'
21
- | 'on-strong' | 'on-bold' | 'inherit';
22
-
23
- export type TextColor = TextColorToken | `var(--${string})`;
24
- export type TextDecoration = 'none' | 'underline' | 'dotted-underline';
25
- export type TextAlign = 'left' | 'center' | 'right';
26
- export type LineTruncation = 1 | 2 | 3 | 4 | 5 | 'none';
27
- export type TextWrap = 'wrap' | 'nowrap' | 'balance' | 'pretty';
28
- export type TextElement = 'p' | 'span' | 'div' | 'label' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
29
- export type TextFontFeature = 'normal' | 'tabular-nums';
2
+ import { textVariantClass } from './text-utils';
3
+ import type {
4
+ TextAlign,
5
+ TextColor,
6
+ TextDecoration,
7
+ TextElement,
8
+ TextFontFeature,
9
+ TextVariant,
10
+ LineTruncation,
11
+ TextWrap,
12
+ } from './text-types';
30
13
 
31
14
  @Component({
32
15
  tag: 'ds-text',
@@ -35,6 +18,12 @@ export type TextFontFeature = 'normal' | 'tabular-nums';
35
18
  })
36
19
  export class Text {
37
20
  @Prop() variant: TextVariant = 'text-body-medium';
21
+ /**
22
+ * Heavier weight + tighter letter-spacing for the variant.
23
+ * `false` (default): regular weight (caption stays medium).
24
+ * `true`: display bold, title/caption semibold, body medium.
25
+ */
26
+ @Prop() emphasis: boolean = false;
38
27
  @Prop() color: TextColor | undefined;
39
28
  @Prop() decoration: TextDecoration | undefined;
40
29
  @Prop() italic: boolean = false;
@@ -45,6 +34,8 @@ export class Text {
45
34
  @Prop() as: TextElement = 'p';
46
35
  /** Maps to `for` attribute on <label> elements. */
47
36
  @Prop() for: string | undefined;
37
+ /** Forwarded to the inner element (e.g. aria-labelledby targets). */
38
+ @Prop() textId: string | undefined;
48
39
 
49
40
  render() {
50
41
  // Polymorphic element: TSX treats a variable tag as a component, so a
@@ -54,35 +45,37 @@ export class Text {
54
45
  const isCustomColor = (c: TextColor) => typeof c === 'string' && c.startsWith('var(--');
55
46
 
56
47
  const cls: Record<string, boolean> = {
57
- [this.variant]: true,
58
- 'text': true,
59
- 'text--nowrap': this.wrap === 'nowrap',
60
- 'text--balance': this.wrap === 'balance',
61
- 'text--pretty': this.wrap === 'pretty',
62
- 'text--truncate-1': this.lineTruncation === 1 && this.wrap !== 'nowrap',
63
- 'text--truncate-2': this.lineTruncation === 2 && this.wrap !== 'nowrap',
64
- 'text--truncate-3': this.lineTruncation === 3 && this.wrap !== 'nowrap',
65
- 'text--truncate-4': this.lineTruncation === 4 && this.wrap !== 'nowrap',
66
- 'text--truncate-5': this.lineTruncation === 5 && this.wrap !== 'nowrap',
67
- 'text--color-primary': this.color === 'primary',
68
- 'text--color-secondary': this.color === 'secondary',
69
- 'text--color-tertiary': this.color === 'tertiary',
70
- 'text--color-brand': this.color === 'brand',
71
- 'text--color-negative': this.color === 'negative',
72
- 'text--color-positive': this.color === 'positive',
73
- 'text--color-warning': this.color === 'warning',
74
- 'text--color-caution': this.color === 'caution',
75
- 'text--color-ai': this.color === 'ai',
76
- 'text--color-on-strong': this.color === 'on-strong',
77
- 'text--color-on-bold': this.color === 'on-bold',
78
- 'text--color-inherit': this.color === 'inherit',
79
- 'text--decoration-underline': this.decoration === 'underline',
80
- 'text--decoration-dotted-underline': this.decoration === 'dotted-underline',
81
- 'text--italic': this.italic,
82
- 'text--align-left': this.align === 'left',
83
- 'text--align-center': this.align === 'center',
84
- 'text--align-right': this.align === 'right',
85
- 'text--font-feature-tabular-nums': this.fontFeature === 'tabular-nums',
48
+ 'ds-text': true,
49
+ [textVariantClass(this.variant)]: true,
50
+ 'ds-text--emphasis': this.emphasis,
51
+ 'ds-text--regular': !this.emphasis,
52
+ 'ds-text--nowrap': this.wrap === 'nowrap',
53
+ 'ds-text--balance': this.wrap === 'balance',
54
+ 'ds-text--pretty': this.wrap === 'pretty',
55
+ 'ds-text--truncate-1': this.lineTruncation === 1 && this.wrap !== 'nowrap',
56
+ 'ds-text--truncate-2': this.lineTruncation === 2 && this.wrap !== 'nowrap',
57
+ 'ds-text--truncate-3': this.lineTruncation === 3 && this.wrap !== 'nowrap',
58
+ 'ds-text--truncate-4': this.lineTruncation === 4 && this.wrap !== 'nowrap',
59
+ 'ds-text--truncate-5': this.lineTruncation === 5 && this.wrap !== 'nowrap',
60
+ 'ds-text--color-primary': this.color === 'primary',
61
+ 'ds-text--color-secondary': this.color === 'secondary',
62
+ 'ds-text--color-tertiary': this.color === 'tertiary',
63
+ 'ds-text--color-brand': this.color === 'brand',
64
+ 'ds-text--color-negative': this.color === 'negative',
65
+ 'ds-text--color-positive': this.color === 'positive',
66
+ 'ds-text--color-warning': this.color === 'warning',
67
+ 'ds-text--color-caution': this.color === 'caution',
68
+ 'ds-text--color-ai': this.color === 'ai',
69
+ 'ds-text--color-on-strong': this.color === 'on-strong',
70
+ 'ds-text--color-on-bold': this.color === 'on-bold',
71
+ 'ds-text--color-inherit': this.color === 'inherit',
72
+ 'ds-text--decoration-underline': this.decoration === 'underline',
73
+ 'ds-text--decoration-dotted-underline': this.decoration === 'dotted-underline',
74
+ 'ds-text--italic': this.italic,
75
+ 'ds-text--align-left': this.align === 'left',
76
+ 'ds-text--align-center': this.align === 'center',
77
+ 'ds-text--align-right': this.align === 'right',
78
+ 'ds-text--font-feature-tabular-nums': this.fontFeature === 'tabular-nums',
86
79
  };
87
80
 
88
81
  const style = this.color && isCustomColor(this.color)
@@ -91,6 +84,7 @@ export class Text {
91
84
 
92
85
  const extraProps: Record<string, string> = {};
93
86
  if (this.as === 'label' && this.for) extraProps['for'] = this.for;
87
+ if (this.textId) extraProps['id'] = this.textId;
94
88
 
95
89
  return (
96
90
  <Host style={{ display: 'contents' }}>
@@ -1 +1,12 @@
1
- export type { TextVariant, TextColor, TextColorToken, TextDecoration, TextAlign, LineTruncation, TextWrap, TextElement } from './Text';
1
+ export type {
2
+ TextVariant,
3
+ TextColor,
4
+ TextColorToken,
5
+ TextDecoration,
6
+ TextAlign,
7
+ LineTruncation,
8
+ TextWrap,
9
+ TextElement,
10
+ TextFontFeature,
11
+ } from './text-types';
12
+ export { textVariantClass } from './text-utils';
@@ -0,0 +1,23 @@
1
+ export type TextVariant =
2
+ | 'text-display-medium'
3
+ | 'text-display-small'
4
+ | 'text-title-large'
5
+ | 'text-title-medium'
6
+ | 'text-title-small'
7
+ | 'text-body-large'
8
+ | 'text-body-medium'
9
+ | 'text-body-small'
10
+ | 'text-caption';
11
+
12
+ export type TextColorToken =
13
+ | 'primary' | 'secondary' | 'tertiary'
14
+ | 'brand' | 'negative' | 'positive' | 'warning' | 'caution' | 'ai'
15
+ | 'on-strong' | 'on-bold' | 'inherit';
16
+
17
+ export type TextColor = TextColorToken | `var(--${string})`;
18
+ export type TextDecoration = 'none' | 'underline' | 'dotted-underline';
19
+ export type TextAlign = 'left' | 'center' | 'right';
20
+ export type LineTruncation = 1 | 2 | 3 | 4 | 5 | 'none';
21
+ export type TextWrap = 'wrap' | 'nowrap' | 'balance' | 'pretty';
22
+ export type TextElement = 'p' | 'span' | 'div' | 'label' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
23
+ export type TextFontFeature = 'normal' | 'tabular-nums';
@@ -0,0 +1,6 @@
1
+ import type { TextVariant } from './text-types';
2
+
3
+ /** `text-body-medium` → `ds-text--body-medium` */
4
+ export function textVariantClass(variant: TextVariant): string {
5
+ return `ds-text--${variant.replace(/^text-/, '')}`;
6
+ }
@@ -1,23 +1,19 @@
1
1
  import { Component, Prop, Element, Watch, h, Host } from '@stencil/core';
2
- import { resolveCssLengthPx, resolveCssTimeMs, TOKEN_CSS_LENGTHS, TOKEN_DEFAULTS } from '../../utils';
2
+ import {
3
+ CONTROL_TEXT_VARIANT,
4
+ resolveCssLengthPx,
5
+ resolveCssTimeMs,
6
+ TOKEN_CSS_LENGTHS,
7
+ TOKEN_DEFAULTS,
8
+ } from '../../utils';
9
+ import type { TextVariant } from '../Text/text-types';
10
+ // Side-effect: register `ds-text` — the portal builds it via createElement, not JSX.
11
+ import '../Text/Text';
3
12
 
4
13
  export type TooltipSide = 'top' | 'right' | 'bottom' | 'left';
5
14
  export type TooltipAlign = 'start' | 'center' | 'end';
6
15
  export type TooltipSize = 'md' | 'sm' | 'xs';
7
16
 
8
- /** Body text per control-density size (regular weight — not emphasis). */
9
- const TEXT_VARIANT: Record<TooltipSize, string> = {
10
- md: 'text-body-medium',
11
- sm: 'text-body-small',
12
- xs: 'text-caption',
13
- };
14
-
15
- const LINE_HEIGHT: Record<TooltipSize, string> = {
16
- md: 'var(--typography-lineheight-md)',
17
- sm: 'var(--typography-lineheight-sm)',
18
- xs: 'var(--typography-lineheight-xs)',
19
- };
20
-
21
17
  const FALLBACK_HEIGHT: Record<TooltipSize, string> = {
22
18
  md: TOKEN_DEFAULTS.size400,
23
19
  sm: TOKEN_DEFAULTS.size300,
@@ -29,6 +25,28 @@ let tooltipIdCounter = 0;
29
25
  /** Currently open tooltip — force-cleared on warm handoff so tips don't cross-fade. */
30
26
  let activeTooltip: Tooltip | null = null;
31
27
 
28
+ type DsTextEl = HTMLElement & {
29
+ as: string;
30
+ variant: TextVariant;
31
+ emphasis: boolean;
32
+ color: string;
33
+ };
34
+
35
+ function createDsText(opts: {
36
+ variant: TextVariant;
37
+ emphasis?: boolean;
38
+ color?: string;
39
+ text: string;
40
+ }): DsTextEl {
41
+ const el = document.createElement('ds-text') as DsTextEl;
42
+ el.as = 'span';
43
+ el.variant = opts.variant;
44
+ el.emphasis = opts.emphasis ?? false;
45
+ el.color = opts.color ?? 'inherit';
46
+ el.textContent = opts.text;
47
+ return el;
48
+ }
49
+
32
50
  /**
33
51
  * Imperative body portal for the popup.
34
52
  * Stencil must not own the portaled node — moving a VDOM child to `document.body`
@@ -263,28 +281,36 @@ export class Tooltip {
263
281
 
264
282
  private renderPopupContent() {
265
283
  if (!this.popupEl) return;
266
- const textVariant = TEXT_VARIANT[this.size];
267
- const lineHeight = LINE_HEIGHT[this.size];
284
+ const textVariant = CONTROL_TEXT_VARIANT[this.size];
268
285
  const density =
269
286
  this.size === 'md' ? 'ds-control--md' : this.size === 'sm' ? 'ds-control--sm' : 'ds-control--xs';
270
- // Every node needs `sc-ds-tooltip` so scoped selectors (`.foo.sc-ds-tooltip`) match.
287
+ // Every layout node needs `sc-ds-tooltip` so scoped selectors (`.foo.sc-ds-tooltip`) match.
271
288
  const sc = 'sc-ds-tooltip';
272
289
 
273
- const startKey =
274
- this.shortcutKey && this.shortcutKeyPosition === 'start'
275
- ? `<div class="key-hint ${sc}" aria-hidden="true"><span class="text-caption-emphasis ${sc}">${escapeHtml(this.shortcutKey)}</span></div>`
276
- : '';
277
- const endKey =
278
- this.shortcutKey && this.shortcutKeyPosition === 'end'
279
- ? `<div class="key-hint ${sc}" aria-hidden="true"><span class="text-caption-emphasis ${sc}">${escapeHtml(this.shortcutKey)}</span></div>`
280
- : '';
281
-
282
- this.popupEl.innerHTML =
283
- `<div class="tooltip-inner ${density} ${sc}">` +
284
- startKey +
285
- `<span class="tooltip-label ${textVariant} ${sc}" style="line-height:${lineHeight}">${escapeHtml(this.label)}</span>` +
286
- endKey +
287
- `</div>`;
290
+ const inner = document.createElement('div');
291
+ inner.className = `tooltip-inner ${density} ${sc}`;
292
+
293
+ const appendShortcut = (position: 'start' | 'end') => {
294
+ if (!this.shortcutKey || this.shortcutKeyPosition !== position) return;
295
+ const hint = document.createElement('div');
296
+ hint.className = `key-hint ${sc}`;
297
+ hint.setAttribute('aria-hidden', 'true');
298
+ hint.appendChild(
299
+ createDsText({ variant: 'text-caption', emphasis: true, text: this.shortcutKey }),
300
+ );
301
+ inner.appendChild(hint);
302
+ };
303
+
304
+ appendShortcut('start');
305
+
306
+ const labelWrap = document.createElement('span');
307
+ labelWrap.className = `tooltip-label ${sc}`;
308
+ labelWrap.appendChild(createDsText({ variant: textVariant, text: this.label }));
309
+ inner.appendChild(labelWrap);
310
+
311
+ appendShortcut('end');
312
+
313
+ this.popupEl.replaceChildren(inner);
288
314
  }
289
315
 
290
316
  private calculatePosition() {
@@ -338,12 +364,3 @@ export class Tooltip {
338
364
  );
339
365
  }
340
366
  }
341
-
342
- function escapeHtml(value: string): string {
343
- return value
344
- .replace(/&/g, '&amp;')
345
- .replace(/</g, '&lt;')
346
- .replace(/>/g, '&gt;')
347
- .replace(/"/g, '&quot;')
348
- .replace(/'/g, '&#39;');
349
- }
@@ -126,7 +126,7 @@ export class TooltipDataViz {
126
126
  </ds-text>
127
127
  </span>
128
128
  <span class="tooltip-data-viz__value">
129
- <ds-text as="span" variant="text-body-medium-emphasis" color="var(--color-foreground-on-translucent-background-primary)">
129
+ <ds-text as="span" variant="text-body-medium" emphasis color="var(--color-foreground-on-translucent-background-primary)">
130
130
  {this.value}
131
131
  </ds-text>
132
132
  </span>
@@ -37,7 +37,7 @@ import { TabBackground } from "./components/TabGroup/TabGroup";
37
37
  import { TabGroupNavBackground } from "./components/TabGroupNav/TabGroupNav";
38
38
  import { SortState, TableColumn } from "./components/Table/Table";
39
39
  import { TagContrast, TagIntent, TagSize } from "./components/Tag/Tag";
40
- import { LineTruncation, TextAlign, TextColor, TextDecoration, TextElement, TextFontFeature, TextVariant, TextWrap } from "./components/Text/Text";
40
+ import { LineTruncation, TextAlign, TextColor, TextDecoration, TextElement, TextFontFeature, TextVariant, TextWrap } from "./components/Text/text-types";
41
41
  import { TooltipAlign, TooltipSide, TooltipSize } from "./components/Tooltip/Tooltip";
42
42
  export { NavChromeStyle } from "./nav/nav-chrome";
43
43
  export { ShellGradientPreset } from "./nav/shell-gradient-presets";
@@ -71,7 +71,7 @@ export { TabBackground } from "./components/TabGroup/TabGroup";
71
71
  export { TabGroupNavBackground } from "./components/TabGroupNav/TabGroupNav";
72
72
  export { SortState, TableColumn } from "./components/Table/Table";
73
73
  export { TagContrast, TagIntent, TagSize } from "./components/Tag/Tag";
74
- export { LineTruncation, TextAlign, TextColor, TextDecoration, TextElement, TextFontFeature, TextVariant, TextWrap } from "./components/Text/Text";
74
+ export { LineTruncation, TextAlign, TextColor, TextDecoration, TextElement, TextFontFeature, TextVariant, TextWrap } from "./components/Text/text-types";
75
75
  export { TooltipAlign, TooltipSide, TooltipSize } from "./components/Tooltip/Tooltip";
76
76
  export namespace Components {
77
77
  interface DsAppShell {
@@ -1069,6 +1069,11 @@ export namespace Components {
1069
1069
  "as": TextElement;
1070
1070
  "color": TextColor | undefined;
1071
1071
  "decoration": TextDecoration | undefined;
1072
+ /**
1073
+ * Heavier weight + tighter letter-spacing for the variant. `false` (default): regular weight (caption stays medium). `true`: display bold, title/caption semibold, body medium.
1074
+ * @default false
1075
+ */
1076
+ "emphasis": boolean;
1072
1077
  /**
1073
1078
  * @default 'normal'
1074
1079
  */
@@ -1085,6 +1090,10 @@ export namespace Components {
1085
1090
  * @default 'none'
1086
1091
  */
1087
1092
  "lineTruncation": LineTruncation;
1093
+ /**
1094
+ * Forwarded to the inner element (e.g. aria-labelledby targets).
1095
+ */
1096
+ "textId": string | undefined;
1088
1097
  /**
1089
1098
  * @default 'text-body-medium'
1090
1099
  */
@@ -2975,6 +2984,11 @@ declare namespace LocalJSX {
2975
2984
  "as"?: TextElement;
2976
2985
  "color"?: TextColor | undefined;
2977
2986
  "decoration"?: TextDecoration | undefined;
2987
+ /**
2988
+ * Heavier weight + tighter letter-spacing for the variant. `false` (default): regular weight (caption stays medium). `true`: display bold, title/caption semibold, body medium.
2989
+ * @default false
2990
+ */
2991
+ "emphasis"?: boolean;
2978
2992
  /**
2979
2993
  * @default 'normal'
2980
2994
  */
@@ -2991,6 +3005,10 @@ declare namespace LocalJSX {
2991
3005
  * @default 'none'
2992
3006
  */
2993
3007
  "lineTruncation"?: LineTruncation;
3008
+ /**
3009
+ * Forwarded to the inner element (e.g. aria-labelledby targets).
3010
+ */
3011
+ "textId"?: string | undefined;
2994
3012
  /**
2995
3013
  * @default 'text-body-medium'
2996
3014
  */
@@ -3367,6 +3385,7 @@ declare namespace LocalJSX {
3367
3385
  }
3368
3386
  interface DsTextAttributes {
3369
3387
  "variant": TextVariant;
3388
+ "emphasis": boolean;
3370
3389
  "color": TextColor | undefined;
3371
3390
  "decoration": TextDecoration | undefined;
3372
3391
  "italic": boolean;
@@ -3376,6 +3395,7 @@ declare namespace LocalJSX {
3376
3395
  "fontFeature": TextFontFeature;
3377
3396
  "as": TextElement;
3378
3397
  "for": string | undefined;
3398
+ "textId": string | undefined;
3379
3399
  }
3380
3400
  interface DsToggleAttributes {
3381
3401
  "checked": boolean;
@@ -3,7 +3,8 @@
3
3
  * (Tag, PanelNav items, BarNav tabs, Menu items, Chip, etc.).
4
4
  *
5
5
  * Apply `.ds-control--md|sm|xs` on the control (host or inner row). Then use the
6
- * `--ds-control-*` vars for height, padding, icon box, label inset, gap, and radius.
6
+ * `--ds-control-*` vars for height, padding, icon box, label inset, gap, radius,
7
+ * and line-height (for wrappers around `ds-text`).
7
8
  *
8
9
  * Both `:host(.ds-control--*)` and `.ds-control--*` are listed so Stencil scoped
9
10
  * components work whether the class is on the host (Tag) or an inner item (PanelNav).
@@ -19,6 +20,8 @@
19
20
  --ds-control-label-inset: var(--dimension-space-025);
20
21
  --ds-control-gap: var(--dimension-space-050);
21
22
  --ds-control-radius: var(--dimension-radius-025);
23
+ /* Matches text-body-medium line-height — wrappers around ds-text need this. */
24
+ --ds-control-line-height: var(--typography-lineheight-md);
22
25
  }
23
26
 
24
27
  :host(.ds-control--sm),
@@ -29,6 +32,7 @@
29
32
  --ds-control-label-inset: var(--dimension-space-025);
30
33
  --ds-control-gap: var(--dimension-space-025);
31
34
  --ds-control-radius: var(--dimension-radius-025);
35
+ --ds-control-line-height: var(--typography-lineheight-sm);
32
36
  }
33
37
 
34
38
  :host(.ds-control--xs),
@@ -39,4 +43,5 @@
39
43
  --ds-control-label-inset: var(--dimension-space-025);
40
44
  --ds-control-gap: var(--dimension-space-025);
41
45
  --ds-control-radius: var(--dimension-radius-025);
46
+ --ds-control-line-height: var(--typography-lineheight-xs);
42
47
  }
@@ -0,0 +1,11 @@
1
+ import type { TextVariant } from '../components/Text/text-types';
2
+
3
+ /** Control-density sizes shared by buttons, tags, chips, select, tooltip. */
4
+ export type ControlDensitySize = 'md' | 'sm' | 'xs';
5
+
6
+ /** Body/caption variant per control-density size (emphasis is separate). */
7
+ export const CONTROL_TEXT_VARIANT: Record<ControlDensitySize, TextVariant> = {
8
+ md: 'text-body-medium',
9
+ sm: 'text-body-small',
10
+ xs: 'text-caption',
11
+ };
@@ -23,3 +23,5 @@ export { TOKEN_DEFAULTS, TOKEN_CSS_LENGTHS } from './token-defaults';
23
23
  export type { TokenDefaultKey } from './token-defaults';
24
24
  export { controlWidthClass } from './control-width';
25
25
  export type { ControlWidth } from './control-width';
26
+ export { CONTROL_TEXT_VARIANT } from './control-text';
27
+ export type { ControlDensitySize } from './control-text';
@@ -1,2 +0,0 @@
1
- import{p as o,H as r,c as t,h as s,a as n,t as a}from"./index.js";import{g as i,i as e}from"./p-BQq26pt9.js";import{d}from"./p-EK1hOP19.js";const c=()=>`.sc-ds-tab-group-nav-h{--ds-focus-ring-width:var(--dimension-stroke-width-025, 2px);--ds-focus-ring-offset:var(--dimension-space-025, 2px);--ds-focus-ring-color:var(--color-interaction-focus)}.ds-focus-ring.sc-ds-tab-group-nav:focus-visible{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:var(--ds-focus-ring-offset)}.ds-focus-ring.ds-focus-ring--visible.sc-ds-tab-group-nav{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:var(--ds-focus-ring-offset)}.ds-focus-ring-inset.sc-ds-tab-group-nav:focus-visible{outline:none}.ds-focus-ring-inset.sc-ds-tab-group-nav:focus-visible::after{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:calc(-1 * var(--ds-focus-ring-width))}.ds-focus-ring-inset.ds-focus-ring--visible.sc-ds-tab-group-nav{outline:none}.ds-focus-ring-inset.ds-focus-ring--visible.sc-ds-tab-group-nav::after{outline:var(--ds-focus-ring-width) solid var(--ds-focus-ring-color);outline-offset:calc(-1 * var(--ds-focus-ring-width))}.ds-control-inactive.sc-ds-tab-group-nav-h,.ds-control-inactive.sc-ds-tab-group-nav{opacity:0.25;pointer-events:none;cursor:not-allowed}.sc-ds-tab-group-nav-h{display:block}.tab-list.sc-ds-tab-group-nav{display:flex;align-items:center;gap:var(--dimension-space-050);position:relative}.tab-list--vertical.sc-ds-tab-group-nav{flex-direction:column;align-items:stretch}.tab.sc-ds-tab-group-nav{display:flex;align-items:center;justify-content:center;gap:var(--dimension-space-050);padding:var(--dimension-space-075);background-color:transparent;border:none;border-radius:var(--dimension-radius-025);cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--color-foreground-secondary);position:relative;transition:color var(--effect-motion-short-2);flex-shrink:0;height:var(--dimension-size-400);min-width:var(--dimension-size-400);box-sizing:border-box;--_hover-bg:var(--color-interaction-hover);--_pressed-bg:var(--color-interaction-pressed);--_dot:var(--color-foreground-bold-brand);--_dot-ring:var(--color-background-secondary)}.tab.sc-ds-tab-group-nav::after{content:'';position:absolute;inset:0;border-radius:var(--dimension-radius-025, 2px);background:transparent;pointer-events:none;transition:none}.tab.sc-ds-tab-group-nav:hover::after{background:var(--_hover-bg);transition:none}.tab.sc-ds-tab-group-nav:active::after{background:var(--_pressed-bg);transition:none}.tab--selected.sc-ds-tab-group-nav{color:var(--color-foreground-primary)}.tab-list--vertical.sc-ds-tab-group-nav .tab.sc-ds-tab-group-nav{justify-content:flex-start}.tab__label.sc-ds-tab-group-nav{position:relative;display:inline-flex;align-items:center;padding:0 var(--dimension-space-025);white-space:nowrap}.tab__label--dot.sc-ds-tab-group-nav{padding-right:calc(var(--dimension-space-025) + var(--dimension-space-050))}.tab__dot.sc-ds-tab-group-nav{position:absolute;top:0;right:0;pointer-events:none}.on-medium.sc-ds-tab-group-nav{--_hover-bg:var(--color-interaction-on-medium-background-hover);--_pressed-bg:var(--color-interaction-on-medium-background-pressed);--_dot-ring:var(--color-background-medium-neutral);--ds-focus-ring-color:var(--color-interaction-on-medium-background-focus)}.on-bold.sc-ds-tab-group-nav{--_hover-bg:var(--color-interaction-on-bold-background-hover);--_pressed-bg:var(--color-interaction-on-bold-background-pressed);--_dot-ring:var(--color-background-bold-neutral);--ds-focus-ring-color:var(--color-interaction-on-bold-background-focus);color:var(--color-foreground-on-bold-background-secondary)}.on-bold.tab--selected.sc-ds-tab-group-nav{color:var(--color-foreground-on-bold-background-primary)}.on-strong.sc-ds-tab-group-nav{--_hover-bg:var(--color-interaction-on-strong-background-hover);--_pressed-bg:var(--color-interaction-on-strong-background-pressed);--_dot-ring:var(--color-background-strong-neutral);--ds-focus-ring-color:var(--color-interaction-on-strong-background-focus);color:var(--color-foreground-on-bold-background-secondary)}.on-strong.tab--selected.sc-ds-tab-group-nav{color:var(--color-foreground-on-bold-background-primary)}.on-always-dark.sc-ds-tab-group-nav{--_hover-bg:var(--color-always-dark-interaction-hover);--_pressed-bg:var(--color-always-dark-interaction-pressed);--_dot-ring:var(--color-always-dark-background);--ds-focus-ring-color:var(--color-always-dark-interaction-focus);color:var(--color-always-dark-foreground-secondary)}.on-always-dark.tab--selected.sc-ds-tab-group-nav{color:var(--color-always-dark-foreground-primary)}.on-navigation.sc-ds-tab-group-nav{color:var(--color-navigation-foreground-secondary);--_hover-bg:var(--color-navigation-interaction-hover);--_pressed-bg:var(--color-navigation-interaction-pressed);--_dot:var(--color-navigation-foreground-brand);--_dot-ring:var(--color-navigation-background);--ds-focus-ring-color:var(--color-navigation-interaction-focus)}.on-navigation.tab--selected.sc-ds-tab-group-nav{color:var(--color-navigation-foreground-primary)}.tab-list--on-navigation.sc-ds-tab-group-nav .tab-divider__line.sc-ds-tab-group-nav{background-color:var(--color-navigation-border-tertiary)}.tab-divider.sc-ds-tab-group-nav{display:flex;align-items:center;justify-content:center;box-sizing:border-box;width:var(--dimension-space-100);height:var(--dimension-size-400);padding-block:var(--dimension-space-075);flex-shrink:0;pointer-events:none}.tab-divider__line.sc-ds-tab-group-nav{width:var(--dimension-stroke-width-012);align-self:stretch;background-color:var(--color-border-secondary)}.tab-divider--vertical.sc-ds-tab-group-nav{width:auto;height:var(--dimension-space-100);align-self:stretch;padding-block:0;padding-inline:var(--dimension-space-075)}.tab-divider--vertical.sc-ds-tab-group-nav .tab-divider__line.sc-ds-tab-group-nav{width:auto;height:var(--dimension-stroke-width-012);align-self:stretch}`;const l=o(class o extends r{constructor(o){super();if(o!==false){this.__registerHost()}this.dsChange=t(this,"dsChange");this.dsRovingExit=t(this,"dsRovingExit");this.value="";this.tabs=[];this.orientation="horizontal";this.selectionFollowsFocus=true;this.rovingEnabled=true;this.focusedTabId=""}get selectableTabs(){return i(this.tabs)}componentWillLoad(){this.syncFocusedTabId(this.value)}onValueChange(o,r){if(!this.selectionFollowsFocus){if(r===undefined||o!==this.focusedTabId){this.syncFocusedTabId(o)}return}if(r===undefined||o===r)return;requestAnimationFrame((()=>{const r=document.activeElement;if(!r||!this.el.contains(r))return;const t=r.getAttribute("data-tab-id");if(t===o)return;const s=this.el.querySelector(`[data-tab-id="${o}"]`);if(s){s.focus({preventScroll:true})}else{r.blur()}}))}onTabsChange(){if(!this.selectableTabs.some((o=>o.id===this.focusedTabId))){this.syncFocusedTabId(this.value)}}async focusTab(o){this.focusedTabId=o;const r=this.el.querySelector(`[data-tab-id="${o}"]`);r?.focus({preventScroll:true})}async focusLastTab(){const o=this.selectableTabs;const r=[...o].reverse().find((o=>!o.isInactive));if(r)await this.focusTab(r.id)}async focusFirstTab(){const o=this.selectableTabs.find((o=>!o.isInactive));if(o)await this.focusTab(o.id)}syncFocusedTabId(o){const r=this.selectableTabs;if(r.some((r=>r.id===o&&!r.isInactive))){this.focusedTabId=o;return}const t=r.find((o=>!o.isInactive));this.focusedTabId=t?.id??""}selectTab(o,r){this.value=o;this.focusedTabId=o;this.dsChange.emit(o);if(r?.focus!==false){void this.focusTab(o)}}getFocusedIndex(){return this.selectableTabs.findIndex((o=>o.id===this.focusedTabId))}findEnabledLinear(o,r){const t=this.selectableTabs;for(let s=o+r;s>=0&&s<t.length;s+=r){if(!t[s]?.isInactive)return s}return null}findEnabled(o,r){const t=this.selectableTabs;const s=t.length;for(let n=0;n<s;n++){const a=(o+r*(n+1)+s*(n+1))%s;if(!t[a]?.isInactive)return a}return o}moveFocusToIndex(o){const r=this.selectableTabs[o];if(!r)return;this.focusedTabId=r.id;void this.focusTab(r.id)}activateFocusedTab(o){if(o.key!=="Enter"&&o.key!==" ")return;const r=this.selectableTabs.find((o=>o.id===this.focusedTabId));if(!r||r.isInactive)return;o.preventDefault();this.selectTab(r.id,{focus:true})}handleKeyDown(o){const r=this.selectableTabs;if(!r.length)return;if(!this.selectionFollowsFocus){if(o.key==="Enter"||o.key===" "){this.activateFocusedTab(o);return}}const t=this.selectionFollowsFocus?r.findIndex((o=>o.id===this.value)):this.getFocusedIndex();if(t<0)return;const s=this.orientation==="vertical";let n=null;let a=null;if(!s){if(o.key==="ArrowRight"){if(this.selectionFollowsFocus){n=this.findEnabled(t,1)}else{const o=this.findEnabledLinear(t,1);if(o===null)a="end";else n=o}}else if(o.key==="ArrowLeft"){if(this.selectionFollowsFocus){n=this.findEnabled(t,-1)}else{const o=this.findEnabledLinear(t,-1);if(o===null)a="start";else n=o}}}else{if(o.key==="ArrowDown"){if(this.selectionFollowsFocus){n=this.findEnabled(t,1)}else{const o=this.findEnabledLinear(t,1);if(o===null)a="end";else n=o}}else if(o.key==="ArrowUp"){if(this.selectionFollowsFocus){n=this.findEnabled(t,-1)}else{const o=this.findEnabledLinear(t,-1);if(o===null)a="start";else n=o}}}if(o.key==="Home"){const o=r.findIndex((o=>!o.isInactive));n=o===-1?null:o}else if(o.key==="End"){const o=[...r].reverse().findIndex((o=>!o.isInactive));n=o===-1?null:r.length-1-o}if(a){o.preventDefault();this.dsRovingExit.emit(a);return}if(n!==null&&n!==t){o.preventDefault();const t=r[n];if(this.selectionFollowsFocus){this.selectTab(t.id)}else{this.moveFocusToIndex(n)}}}getBgClass(){if(!this.background||this.background==="faint")return"";if(this.background==="always-dark")return"on-always-dark";if(this.background==="navigation")return"on-navigation";return`on-${this.background}`}tabIndexForTab(o){if(!this.rovingEnabled)return-1;if(this.selectionFollowsFocus){return o.id===this.value?0:-1}return o.id===this.focusedTabId?0:-1}render(){const o=this.getBgClass();const r=this.orientation==="vertical";const t=this.background==="navigation";return s(n,{key:"78efd00569e0f71d8a3cecc991d3ced1b369353f",class:"tab-group-nav-host"},s("div",{key:"d810f8b9d3a081271c52747a751ca5ad0347f8dd",role:"tablist",class:{"tab-list":true,"tab-list--vertical":r,"tab-list--on-navigation":t},"aria-label":this.ariaLabel,"aria-labelledby":this.ariaLabelledby,"aria-orientation":r?"vertical":undefined},this.tabs.map(((t,n)=>{if(e(t)){return s("div",{key:`divider-${n}`,class:{"tab-divider":true,"tab-divider--vertical":r},"aria-hidden":"true"},s("div",{class:"tab-divider__line"}))}const a=t.id===this.value;return s("button",{key:t.id,type:"button",role:"tab","data-tab-id":t.id,class:{tab:true,"tab--selected":a,"ds-focus-ring-inset":true,"ds-control-inactive":!!t.isInactive,[o]:!!o},"aria-selected":a,"aria-disabled":t.isInactive||undefined,"aria-controls":t.panelId??undefined,disabled:t.isInactive,tabIndex:this.tabIndexForTab(t),onClick:()=>!t.isInactive&&this.selectTab(t.id),onFocus:()=>{if(!this.selectionFollowsFocus){this.focusedTabId=t.id}}},s("span",{class:{tab__label:true,"tab__label--dot":!!t.dot,[a?"text-body-medium-emphasis":"text-body-medium"]:true}},t.label,t.dot&&s("ds-badge",{class:"tab__dot",variant:"dot",background:"var(--_dot-ring)",label:"","aria-hidden":"true"})))}))))}get el(){return this}static get watchers(){return{value:[{onValueChange:0}],tabs:[{onTabsChange:0}]}}static get style(){return c()}},[2,"ds-tab-group-nav",{value:[1025],tabs:[16],background:[1],ariaLabel:[1,"aria-label"],ariaLabelledby:[1,"aria-labelledby"],orientation:[1],selectionFollowsFocus:[4,"selection-follows-focus"],rovingEnabled:[4,"roving-enabled"],focusedTabId:[32],focusTab:[64],focusLastTab:[64],focusFirstTab:[64]},[[0,"keydown","handleKeyDown"]],{value:[{onValueChange:0}],tabs:[{onTabsChange:0}]}]);function u(){if(typeof customElements==="undefined"){return}const o=["ds-tab-group-nav","ds-badge"];o.forEach((o=>{switch(o){case"ds-tab-group-nav":if(!customElements.get(a(o))){customElements.define(a(o),l)}break;case"ds-badge":if(!customElements.get(a(o))){d()}break}}))}u();export{l as T,u as d};
2
- //# sourceMappingURL=p-1m8r0wFg.js.map