@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
@@ -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;
@@ -0,0 +1,6 @@
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>;
6
+ //# sourceMappingURL=control-text.d.ts.map
@@ -9,4 +9,6 @@ export { TOKEN_DEFAULTS, TOKEN_CSS_LENGTHS } from './token-defaults';
9
9
  export type { TokenDefaultKey } from './token-defaults';
10
10
  export { controlWidthClass } from './control-width';
11
11
  export type { ControlWidth } from './control-width';
12
+ export { CONTROL_TEXT_VARIANT } from './control-text';
13
+ export type { ControlDensitySize } from './control-text';
12
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.14.0",
3
+ "version": "2.15.0",
4
4
  "description": "CompoMo — composable web components styled with TokoMo design tokens",
5
5
  "keywords": [
6
6
  "web-components",
@@ -69,7 +69,7 @@
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/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/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
74
  "test:e2e:install": "playwright install chromium",
75
75
  "build:docs": "stencil build --docs",
@@ -1058,14 +1058,14 @@ export declare interface DsTag extends Components.DsTag {}
1058
1058
 
1059
1059
 
1060
1060
  @ProxyCmp({
1061
- inputs: ['align', 'as', 'color', 'decoration', 'fontFeature', 'for', 'italic', 'lineTruncation', 'variant', 'wrap']
1061
+ inputs: ['align', 'as', 'color', 'decoration', 'emphasis', 'fontFeature', 'for', 'italic', 'lineTruncation', 'textId', 'variant', 'wrap']
1062
1062
  })
1063
1063
  @Component({
1064
1064
  selector: 'ds-text',
1065
1065
  changeDetection: ChangeDetectionStrategy.OnPush,
1066
1066
  template: '<ng-content></ng-content>',
1067
1067
  // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
1068
- inputs: ['align', 'as', 'color', 'decoration', 'fontFeature', 'for', 'italic', 'lineTruncation', 'variant', 'wrap'],
1068
+ inputs: ['align', 'as', 'color', 'decoration', 'emphasis', 'fontFeature', 'for', 'italic', 'lineTruncation', 'textId', 'variant', 'wrap'],
1069
1069
  standalone: false
1070
1070
  })
1071
1071
  export class DsText {
@@ -166,14 +166,12 @@ export class Badge {
166
166
  aria-label={ariaLabel}
167
167
  style={this.ringHostStyle(ring)}
168
168
  >
169
- <span
170
- class={{
171
- 'badge__mark': true,
172
- 'text-caption-emphasis': !isDot,
173
- }}
174
- aria-hidden="true"
175
- >
176
- {!isDot && display}
169
+ <span class="badge__mark" aria-hidden="true">
170
+ {!isDot && (
171
+ <ds-text as="span" variant="text-caption" emphasis color="inherit">
172
+ {display}
173
+ </ds-text>
174
+ )}
177
175
  </span>
178
176
  </Host>
179
177
  );
@@ -121,7 +121,11 @@ export class Banner {
121
121
  </div>
122
122
  )}
123
123
  <div class="banner-body">
124
- <span class="text-body-medium banner-message">{this.message}</span>
124
+ <span class="banner-message">
125
+ <ds-text as="span" variant="text-body-medium" color="inherit">
126
+ {this.message}
127
+ </ds-text>
128
+ </span>
125
129
  {this.showDismiss && (
126
130
  <button
127
131
  type="button"
@@ -683,7 +683,11 @@ export class BarNav {
683
683
  )}
684
684
 
685
685
  {!hasTabs && this.heading && (
686
- <span class="bar-nav__heading text-body-medium-emphasis">{this.heading}</span>
686
+ <span class="bar-nav__heading">
687
+ <ds-text as="span" variant="text-body-medium" emphasis color="inherit" wrap="nowrap">
688
+ {this.heading}
689
+ </ds-text>
690
+ </span>
687
691
  )}
688
692
 
689
693
  {hasTabs && this.hasOverflowTabs && (
@@ -1,5 +1,5 @@
1
1
  import { Component, Element, Event, EventEmitter, h, Host, Method, Prop } from '@stencil/core';
2
- import { controlWidthClass, type ControlWidth } from '../../utils/control-width';
2
+ import { controlWidthClass, CONTROL_TEXT_VARIANT, type ControlWidth } from '../../utils';
3
3
 
4
4
  export type ButtonFilledIntent =
5
5
  | 'neutral'
@@ -20,13 +20,6 @@ export type ButtonFilledSize = 'md' | 'sm' | 'xs';
20
20
 
21
21
  export type ButtonFilledWidth = ControlWidth;
22
22
 
23
- /** Emphasis text per control-density size (buttons use emphasis, unlike Tag). */
24
- const TEXT_VARIANT: Record<ButtonFilledSize, string> = {
25
- md: 'text-body-medium-emphasis',
26
- sm: 'text-body-small-emphasis',
27
- xs: 'text-caption-emphasis',
28
- };
29
-
30
23
  /**
31
24
  * `ds-icon` size prop matching control-density icon metrics
32
25
  * (md→20 / sm→16 / xs→12 via `--dimension-iconography-*`).
@@ -110,7 +103,7 @@ export class ButtonFilled {
110
103
  }
111
104
 
112
105
  render() {
113
- const textVariant = TEXT_VARIANT[this.size];
106
+ const textVariant = CONTROL_TEXT_VARIANT[this.size];
114
107
  const iconSize = ICON_SIZE[this.size];
115
108
 
116
109
  const cls: Record<string, boolean> = {
@@ -161,8 +154,10 @@ export class ButtonFilled {
161
154
  </span>
162
155
  )}
163
156
  {this.showLabel && (
164
- <span class={{ 'button-filled__label': true, [textVariant]: true, 'ds-interaction-fill__content': true }}>
165
- {this.label}
157
+ <span class="button-filled__label ds-interaction-fill__content">
158
+ <ds-text as="span" variant={textVariant} emphasis color="inherit">
159
+ {this.label}
160
+ </ds-text>
166
161
  </span>
167
162
  )}
168
163
  </button>
@@ -1,5 +1,5 @@
1
1
  import { Component, Element, Event, EventEmitter, h, Host, Method, Prop } from '@stencil/core';
2
- import { controlWidthClass, type ControlWidth } from '../../utils/control-width';
2
+ import { controlWidthClass, CONTROL_TEXT_VARIANT, type ControlWidth } from '../../utils';
3
3
 
4
4
  export type ButtonUnfilledOnBackgroundContrast = 'default' | 'medium' | 'bold' | 'strong';
5
5
 
@@ -11,13 +11,6 @@ export type ButtonUnfilledSize = 'md' | 'sm' | 'xs';
11
11
 
12
12
  export type ButtonUnfilledWidth = ControlWidth;
13
13
 
14
- /** Emphasis text per control-density size (buttons use emphasis, unlike Tag). */
15
- const TEXT_VARIANT: Record<ButtonUnfilledSize, string> = {
16
- md: 'text-body-medium-emphasis',
17
- sm: 'text-body-small-emphasis',
18
- xs: 'text-caption-emphasis',
19
- };
20
-
21
14
  /**
22
15
  * `ds-icon` size prop matching control-density icon metrics
23
16
  * (md→20 / sm→16 / xs→12 via `--dimension-iconography-*`).
@@ -148,7 +141,7 @@ export class ButtonUnfilled {
148
141
  render() {
149
142
  const bg = this.background;
150
143
  const contrast = this.effectiveContrast();
151
- const textVariant = TEXT_VARIANT[this.size];
144
+ const textVariant = CONTROL_TEXT_VARIANT[this.size];
152
145
  const iconSize = ICON_SIZE[this.size];
153
146
 
154
147
  const cls: Record<string, boolean> = {
@@ -219,8 +212,10 @@ export class ButtonUnfilled {
219
212
  </span>
220
213
  )}
221
214
  {this.showLabel && (
222
- <span class={{ 'button-unfilled__label': true, [textVariant]: true, 'ds-interaction-fill__content': true }}>
223
- {this.label}
215
+ <span class="button-unfilled__label ds-interaction-fill__content">
216
+ <ds-text as="span" variant={textVariant} emphasis color="inherit">
217
+ {this.label}
218
+ </ds-text>
224
219
  </span>
225
220
  )}
226
221
  </button>
@@ -57,14 +57,16 @@ export class Card {
57
57
  >
58
58
  <header class="card__header">
59
59
  <div class="card__title-wrap">
60
- <ds-text
61
- class="card__title"
62
- variant="text-title-small"
63
- color={editing ? FAINT_BRAND_TITLE_COLOR : 'primary'}
64
- as="h2"
65
- >
66
- {this.heading}
67
- </ds-text>
60
+ <span class="card__title">
61
+ <ds-text
62
+ variant="text-title-small"
63
+ emphasis
64
+ color={editing ? FAINT_BRAND_TITLE_COLOR : 'primary'}
65
+ as="h2"
66
+ >
67
+ {this.heading}
68
+ </ds-text>
69
+ </span>
68
70
  </div>
69
71
  <div class="card__actions">
70
72
  <slot name="actions" />
@@ -51,8 +51,10 @@ export class Checkbox {
51
51
  </span>
52
52
  )}
53
53
  </span>
54
- <span id={this.labelId} class="text-body-medium checkbox__label">
55
- {this.label}
54
+ <span class="checkbox__label">
55
+ <ds-text as="span" variant="text-body-medium" textId={this.labelId}>
56
+ {this.label}
57
+ </ds-text>
56
58
  </span>
57
59
  </Host>
58
60
  );
@@ -1,4 +1,5 @@
1
1
  import { Component, Prop, Event, EventEmitter, h, Host } from '@stencil/core';
2
+ import { CONTROL_TEXT_VARIANT } from '../../utils';
2
3
 
3
4
  /**
4
5
  * Semantic chip state — replaces Tag’s intent × contrast matrix.
@@ -11,13 +12,6 @@ export type ChipState = 'default' | 'active' | 'error' | 'caution';
11
12
  export type ChipSize = 'md' | 'sm' | 'xs';
12
13
  export type ChipBackground = 'faint' | 'medium' | 'bold' | 'strong' | 'always-dark';
13
14
 
14
- /** Text variant per control-density recipe (md / sm / xs). */
15
- const TEXT_VARIANT: Record<ChipSize, string> = {
16
- md: 'text-body-medium',
17
- sm: 'text-body-small',
18
- xs: 'text-caption',
19
- };
20
-
21
15
  /** Dismiss `ds-icon` size — same iconography metrics as Tag’s leading icon. */
22
16
  const ICON_SIZE: Record<ChipSize, 'md' | 'sm' | 'xs'> = {
23
17
  md: 'md',
@@ -58,7 +52,7 @@ export class Chip {
58
52
  };
59
53
 
60
54
  render() {
61
- const textVariant = TEXT_VARIANT[this.size];
55
+ const textVariant = CONTROL_TEXT_VARIANT[this.size];
62
56
  const iconSize = ICON_SIZE[this.size];
63
57
 
64
58
  const maxWidthStyle = this.maxWidth != null
@@ -88,8 +82,10 @@ export class Chip {
88
82
  style={maxWidthStyle}
89
83
  aria-disabled={this.isInactive || undefined}
90
84
  >
91
- <span class={{ 'tag__label': true, [textVariant]: true }}>
92
- {this.label}
85
+ <span class="tag__label">
86
+ <ds-text as="span" variant={textVariant} color="inherit">
87
+ {this.label}
88
+ </ds-text>
93
89
  </span>
94
90
  {this.removable && (
95
91
  <button
@@ -22,9 +22,9 @@ export class EmptyState {
22
22
  return (
23
23
  <Host>
24
24
  <div class="empty-state">
25
- <p class="text-body-medium" style={{ color: 'var(--color-foreground-secondary)' }}>
25
+ <ds-text as="p" variant="text-body-medium" color="secondary">
26
26
  {this.message || DEFAULT_MESSAGES[this.type]}
27
- </p>
27
+ </ds-text>
28
28
  </div>
29
29
  </Host>
30
30
  );
@@ -19,7 +19,9 @@ export class Field {
19
19
  return (
20
20
  <Host>
21
21
  <div class="field">
22
- <label class="text-body-small-emphasis field__label" htmlFor={id}>{this.label}</label>
22
+ <ds-text as="label" variant="text-body-small" emphasis for={id}>
23
+ {this.label}
24
+ </ds-text>
23
25
  <slot />
24
26
  </div>
25
27
  </Host>
@@ -358,7 +358,11 @@ export class Menu {
358
358
  >
359
359
  {section.header && (
360
360
  <div class="section-header ds-control--md" aria-hidden="true">
361
- <span class="text-body-small-emphasis section-label">{section.header}</span>
361
+ <span class="section-label">
362
+ <ds-text as="span" variant="text-body-small" emphasis color="inherit">
363
+ {section.header}
364
+ </ds-text>
365
+ </span>
362
366
  </div>
363
367
  )}
364
368
  {isMenuGradientPickerSection(section) ? (
@@ -398,11 +402,17 @@ export class Menu {
398
402
  onFocus={() => { this.focusedIndex = idx; }}
399
403
  >
400
404
  <div class="menu-item__content ds-interaction-fill__content">
401
- <span class={item.isSelected ? 'text-body-medium-emphasis menu-item__label' : 'text-body-medium menu-item__label'}>
402
- {item.label}
405
+ <span class="menu-item__label">
406
+ <ds-text as="span" variant="text-body-medium" emphasis={!!item.isSelected} color="inherit">
407
+ {item.label}
408
+ </ds-text>
403
409
  </span>
404
410
  {item.subtext && (
405
- <span class="text-body-small menu-item__subtext">{item.subtext}</span>
411
+ <span class="menu-item__subtext">
412
+ <ds-text as="span" variant="text-body-small" color="inherit">
413
+ {item.subtext}
414
+ </ds-text>
415
+ </span>
406
416
  )}
407
417
  </div>
408
418
  {item.showToggle && (
@@ -179,10 +179,24 @@ export class Modal {
179
179
  style={{ width: `min(${this.resolvedWidth}, calc(100vw - 2 * var(--dimension-space-200)))` }}
180
180
  >
181
181
  <div class="modal-header">
182
- <h2 id={this.titleId} class="text-title-small modal-title">{this.heading}</h2>
182
+ <ds-text
183
+ as="h2"
184
+ variant="text-title-small"
185
+ textId={this.titleId}
186
+ >
187
+ {this.heading}
188
+ </ds-text>
183
189
  {this.subtitle && (
184
- <div id={this.subtitleId} class="modal-subtitle text-body-medium">
185
- {this.subtitle}
190
+ <div class="modal-subtitle">
191
+ <ds-text
192
+ as="div"
193
+ variant="text-body-medium"
194
+ color="secondary"
195
+ wrap="balance"
196
+ textId={this.subtitleId}
197
+ >
198
+ {this.subtitle}
199
+ </ds-text>
186
200
  </div>
187
201
  )}
188
202
  </div>
@@ -63,7 +63,7 @@ export class Pagination {
63
63
  {pages.map((item, i) =>
64
64
  item === 'ellipsis' ? (
65
65
  <span key={`e${i}`} class="ellipsis">
66
- <span class="text-body-small" style={{ color: 'var(--color-foreground-tertiary)' }}>…</span>
66
+ <ds-text as="span" variant="text-body-small" color="tertiary">…</ds-text>
67
67
  </span>
68
68
  ) : (
69
69
  <button
@@ -74,9 +74,9 @@ export class Pagination {
74
74
  aria-current={item === this.page ? 'page' : undefined}
75
75
  disabled={this.isInactive}
76
76
  >
77
- <span class={item === this.page ? 'text-body-small-emphasis' : 'text-body-small'}>
77
+ <ds-text as="span" variant="text-body-small" emphasis={item === this.page}>
78
78
  {item}
79
- </span>
79
+ </ds-text>
80
80
  </button>
81
81
  )
82
82
  )}
@@ -517,7 +517,7 @@ export class PanelNav {
517
517
  >
518
518
  <span class="panel-nav__item-label panel-nav__footer-user-label">
519
519
  <span class="panel-nav__item-label-text">
520
- <ds-text as="span" variant="text-body-medium-emphasis" color="inherit">
520
+ <ds-text as="span" variant="text-body-medium" emphasis color="inherit">
521
521
  {userName}
522
522
  </ds-text>
523
523
  </span>
@@ -529,7 +529,7 @@ export class PanelNav {
529
529
  <span class="panel-nav__footer-icon-collapsed">
530
530
  <ds-icon name="Circle" size="md" color="inherit" />
531
531
  <span class="panel-nav__user-initial">
532
- <ds-text as="span" variant="text-caption-emphasis" color="inherit">
532
+ <ds-text as="span" variant="text-caption" emphasis color="inherit">
533
533
  {userInitial}
534
534
  </ds-text>
535
535
  </span>
@@ -557,7 +557,8 @@ export class PanelNav {
557
557
  <span class="panel-nav__item-label-text">
558
558
  <ds-text
559
559
  as="span"
560
- variant={isActive ? 'text-body-medium-emphasis' : 'text-body-medium'}
560
+ variant="text-body-medium"
561
+ emphasis={isActive}
561
562
  color="inherit"
562
563
  >
563
564
  {item.label}
@@ -668,7 +669,7 @@ export class PanelNav {
668
669
  {group.label && (
669
670
  <span class="panel-nav__group-label">
670
671
  <span class="panel-nav__item-label-text">
671
- <ds-text as="span" variant="text-caption-emphasis" color="inherit">
672
+ <ds-text as="span" variant="text-caption" emphasis color="inherit">
672
673
  {group.label}
673
674
  </ds-text>
674
675
  </span>
@@ -290,14 +290,17 @@ export class PanelTools {
290
290
  >
291
291
  <div class="panel-tools__drawer-surface">
292
292
  <header class="panel-tools__header">
293
- <span class="panel-tools__title text-body-medium-emphasis">{headerLabel}</span>
293
+ <span class="panel-tools__title">
294
+ <ds-text as="span" variant="text-body-medium" emphasis color="inherit" wrap="nowrap">
295
+ {headerLabel}
296
+ </ds-text>
297
+ </span>
294
298
  </header>
295
299
  <div class="panel-tools__body">
296
300
  <div
297
301
  class={{
298
302
  'panel-tools__view': true,
299
303
  'panel-tools__view--active': this.isViewActive('search'),
300
- 'text-body-medium': true,
301
304
  }}
302
305
  hidden={!this.isViewActive('search')}
303
306
  >
@@ -307,7 +310,6 @@ export class PanelTools {
307
310
  class={{
308
311
  'panel-tools__view': true,
309
312
  'panel-tools__view--active': this.isViewActive('messages'),
310
- 'text-body-medium': true,
311
313
  }}
312
314
  hidden={!this.isViewActive('messages')}
313
315
  >
@@ -317,7 +319,6 @@ export class PanelTools {
317
319
  class={{
318
320
  'panel-tools__view': true,
319
321
  'panel-tools__view--active': this.isViewActive('stacks'),
320
- 'text-body-medium': true,
321
322
  }}
322
323
  hidden={!this.isViewActive('stacks')}
323
324
  >
@@ -327,7 +328,6 @@ export class PanelTools {
327
328
  class={{
328
329
  'panel-tools__view': true,
329
330
  'panel-tools__view--active': this.isViewActive('activity'),
330
- 'text-body-medium': true,
331
331
  }}
332
332
  hidden={!this.isViewActive('activity')}
333
333
  >
@@ -337,7 +337,6 @@ export class PanelTools {
337
337
  class={{
338
338
  'panel-tools__view': true,
339
339
  'panel-tools__view--active': this.isViewActive('agents'),
340
- 'text-body-medium': true,
341
340
  }}
342
341
  hidden={!this.isViewActive('agents')}
343
342
  >
@@ -347,7 +346,6 @@ export class PanelTools {
347
346
  class={{
348
347
  'panel-tools__view': true,
349
348
  'panel-tools__view--active': this.isViewActive('help'),
350
- 'text-body-medium': true,
351
349
  }}
352
350
  hidden={!this.isViewActive('help')}
353
351
  >
@@ -118,7 +118,11 @@ export class RadioGroup {
118
118
  <span class={{ circle: true, 'circle--checked': isChecked }}>
119
119
  {isChecked && <span class="dot" />}
120
120
  </span>
121
- <span class="text-body-medium radio-label">{opt.label}</span>
121
+ <span class="radio-label">
122
+ <ds-text as="span" variant="text-body-medium">
123
+ {opt.label}
124
+ </ds-text>
125
+ </span>
122
126
  </div>
123
127
  );
124
128
  })}
@@ -1,6 +1,11 @@
1
1
  import { Component, Prop, State, Event, EventEmitter, Element, Watch, Listen, h, Host } from '@stencil/core';
2
- import { controlWidthClass, type ControlWidth } from '../../utils/control-width';
3
- import { resolveCssLengthPx, TOKEN_DEFAULTS } from '../../utils';
2
+ import {
3
+ controlWidthClass,
4
+ CONTROL_TEXT_VARIANT,
5
+ resolveCssLengthPx,
6
+ TOKEN_DEFAULTS,
7
+ type ControlWidth,
8
+ } from '../../utils';
4
9
  import type { MenuItemData } from '../Menu/menu-types';
5
10
 
6
11
  export interface SelectOption {
@@ -12,13 +17,6 @@ export type SelectSize = 'md' | 'sm' | 'xs';
12
17
 
13
18
  export type SelectWidth = ControlWidth;
14
19
 
15
- /** Regular (non-emphasis) type per density — selects stay visually lighter than buttons. */
16
- const TEXT_VARIANT: Record<SelectSize, string> = {
17
- md: 'text-body-medium',
18
- sm: 'text-body-small',
19
- xs: 'text-caption',
20
- };
21
-
22
20
  /** `ds-icon` size matching control-density icon metrics. */
23
21
  const ICON_SIZE: Record<SelectSize, 'md' | 'sm' | 'xs'> = {
24
22
  md: 'md',
@@ -207,7 +205,7 @@ export class Select {
207
205
  const showPlaceholder = !this.hasSelection;
208
206
  const hasValue = !showPlaceholder;
209
207
  const label = showPlaceholder ? this.placeholder : this.selectedLabel;
210
- const textVariant = TEXT_VARIANT[this.size];
208
+ const textVariant = CONTROL_TEXT_VARIANT[this.size];
211
209
  const iconSize = ICON_SIZE[this.size];
212
210
  const density = `ds-control--${this.size}`;
213
211
  // Selected fill when a value is set (or while open), gated by `activeFill`.
@@ -249,14 +247,10 @@ export class Select {
249
247
  aria-labelledby={this.ariaLabelledby}
250
248
  onClick={() => this.toggle({ focusVisible: false })}
251
249
  >
252
- <span
253
- class={{
254
- 'trigger__label': true,
255
- [textVariant]: true,
256
- 'ds-interaction-fill__content': true,
257
- }}
258
- >
259
- {label}
250
+ <span class="trigger__label ds-interaction-fill__content">
251
+ <ds-text as="span" variant={textVariant} color="inherit" lineTruncation={1}>
252
+ {label}
253
+ </ds-text>
260
254
  </span>
261
255
  <span class="trigger__chevron ds-interaction-fill__content" aria-hidden="true">
262
256
  <ds-icon name="ChevronDown" size={iconSize} color="inherit" />
@@ -38,8 +38,12 @@ export class Slider {
38
38
  return (
39
39
  <Host class="field">
40
40
  <div class="label-row">
41
- <label class="text-body-small-emphasis" htmlFor={finalId}>{this.label}</label>
42
- <span class="text-body-small-emphasis">{this.value}</span>
41
+ <ds-text as="label" variant="text-body-small" emphasis for={finalId}>
42
+ {this.label}
43
+ </ds-text>
44
+ <ds-text as="span" variant="text-body-small" emphasis>
45
+ {this.value}
46
+ </ds-text>
43
47
  </div>
44
48
  <div
45
49
  class={{