@ds-mo/ui 8.0.1 → 8.2.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 (192) hide show
  1. package/README.md +1 -1
  2. package/dist/.build-stamp +1 -1
  3. package/dist/agent.json +1123 -65
  4. package/dist/angular/ds-badge.d.ts +1 -1
  5. package/dist/angular/ds-badge.js +3 -3
  6. package/dist/angular/ds-button-filled.d.ts +1 -1
  7. package/dist/angular/ds-button-filled.js +3 -3
  8. package/dist/angular/ds-button-unfilled.d.ts +1 -1
  9. package/dist/angular/ds-button-unfilled.js +3 -3
  10. package/dist/angular/ds-checkbox.d.ts +4 -1
  11. package/dist/angular/ds-checkbox.js +3 -3
  12. package/dist/angular/ds-empty-state.d.ts +1 -1
  13. package/dist/angular/ds-empty-state.js +3 -3
  14. package/dist/angular/ds-field.d.ts +1 -1
  15. package/dist/angular/ds-field.js +3 -3
  16. package/dist/angular/ds-input.d.ts +1 -1
  17. package/dist/angular/ds-input.js +3 -3
  18. package/dist/angular/ds-panel-nav.d.ts +1 -1
  19. package/dist/angular/ds-panel-nav.js +3 -3
  20. package/dist/angular/ds-radio.d.ts +18 -0
  21. package/dist/angular/{ds-radio-group.js → ds-radio.js} +12 -12
  22. package/dist/angular/ds-select-multi.d.ts +28 -0
  23. package/dist/angular/ds-select-multi.js +49 -0
  24. package/dist/angular/ds-select.d.ts +12 -2
  25. package/dist/angular/ds-select.js +11 -4
  26. package/dist/angular/ds-slider.d.ts +12 -3
  27. package/dist/angular/ds-slider.js +8 -4
  28. package/dist/angular/index.d.ts +1 -1
  29. package/dist/angular/index.js +2 -1
  30. package/dist/angular/proxies.d.ts +2 -1
  31. package/dist/angular/proxies.js +2 -1
  32. package/dist/angular/radio-value-accessor.d.ts +1 -1
  33. package/dist/angular/radio-value-accessor.js +2 -2
  34. package/dist/components/ds-app-shell.js +1 -1
  35. package/dist/components/ds-badge.js +1 -1
  36. package/dist/components/ds-banner.js +1 -1
  37. package/dist/components/ds-bar-nav.js +1 -1
  38. package/dist/components/ds-bar-nav.js.map +1 -1
  39. package/dist/components/ds-button-filled.js +1 -1
  40. package/dist/components/ds-button-unfilled.js +1 -1
  41. package/dist/components/ds-card-data-viz-donut.js +1 -1
  42. package/dist/components/ds-card-data-viz-donut.js.map +1 -1
  43. package/dist/components/ds-card-setting.js +1 -1
  44. package/dist/components/ds-card.js +1 -1
  45. package/dist/components/ds-chart-bar.js +1 -1
  46. package/dist/components/ds-chart-bar.js.map +1 -1
  47. package/dist/components/ds-chart-donut.js +1 -1
  48. package/dist/components/ds-chart-donut.js.map +1 -1
  49. package/dist/components/ds-chart-legend.js +1 -1
  50. package/dist/components/ds-chart-line.js +1 -1
  51. package/dist/components/ds-chart-line.js.map +1 -1
  52. package/dist/components/ds-checkbox.js +1 -1
  53. package/dist/components/ds-checkbox.js.map +1 -1
  54. package/dist/components/ds-chip.js +1 -1
  55. package/dist/components/ds-divider.js +1 -1
  56. package/dist/components/ds-empty-state.js +1 -1
  57. package/dist/components/ds-empty-state.js.map +1 -1
  58. package/dist/components/ds-field.js +1 -1
  59. package/dist/components/ds-field.js.map +1 -1
  60. package/dist/components/ds-icon.js +1 -1
  61. package/dist/components/ds-input.js +1 -1
  62. package/dist/components/ds-input.js.map +1 -1
  63. package/dist/components/ds-loader.js +1 -1
  64. package/dist/components/ds-menu.js +1 -1
  65. package/dist/components/ds-modal.js +1 -1
  66. package/dist/components/ds-modal.js.map +1 -1
  67. package/dist/components/ds-pagination.js +1 -1
  68. package/dist/components/ds-panel-nav.js +1 -1
  69. package/dist/components/ds-panel-nav.js.map +1 -1
  70. package/dist/components/ds-panel-sub-nav.js +1 -1
  71. package/dist/components/ds-panel-sub-nav.js.map +1 -1
  72. package/dist/components/ds-panel-tools.js +1 -1
  73. package/dist/components/{ds-radio-group.d.ts → ds-radio.d.ts} +4 -4
  74. package/dist/components/ds-radio.js +2 -0
  75. package/dist/components/ds-radio.js.map +1 -0
  76. package/dist/components/ds-select-multi.d.ts +11 -0
  77. package/dist/components/ds-select-multi.js +2 -0
  78. package/dist/components/ds-select-multi.js.map +1 -0
  79. package/dist/components/ds-select.js +1 -1
  80. package/dist/components/ds-select.js.map +1 -1
  81. package/dist/components/ds-shell-gradient-picker.js +1 -1
  82. package/dist/components/ds-shell-gradient-swatch.js +1 -1
  83. package/dist/components/ds-skeleton.js +1 -1
  84. package/dist/components/ds-slider.js +1 -1
  85. package/dist/components/ds-slider.js.map +1 -1
  86. package/dist/components/ds-switch.js +1 -1
  87. package/dist/components/ds-tab-group.js +1 -1
  88. package/dist/components/ds-tab-group.js.map +1 -1
  89. package/dist/components/ds-table.js +1 -1
  90. package/dist/components/ds-tag.js +1 -1
  91. package/dist/components/ds-text.js +1 -1
  92. package/dist/components/ds-tooltip-data-viz.js +1 -1
  93. package/dist/components/ds-tooltip.js +1 -1
  94. package/dist/components/p-BU_gxTiw.js +2 -0
  95. package/dist/components/p-BU_gxTiw.js.map +1 -0
  96. package/dist/components/{p-DavEAOUa.js → p-BjhTeU17.js} +2 -2
  97. package/dist/components/p-C91iXoXj.js +2 -0
  98. package/dist/components/p-C91iXoXj.js.map +1 -0
  99. package/dist/components/{p-3bRWSqaN.js → p-CDu_LfhF.js} +2 -2
  100. package/dist/components/{p-Mx6VFEQc.js → p-CSyIAX11.js} +2 -2
  101. package/dist/components/p-CSyIAX11.js.map +1 -0
  102. package/dist/components/p-C_cu-HIT.js +2 -0
  103. package/dist/components/p-C_cu-HIT.js.map +1 -0
  104. package/dist/components/{p-DoZU8RH0.js → p-Cj4vIqqx.js} +2 -2
  105. package/dist/components/{p-DoZU8RH0.js.map → p-Cj4vIqqx.js.map} +1 -1
  106. package/dist/components/{p-wxw8arTd.js → p-Cpr3K41-.js} +1 -1
  107. package/dist/components/{p-wxw8arTd.js.map → p-Cpr3K41-.js.map} +1 -1
  108. package/dist/components/{p-Dt0XnMxc.js → p-CqsgiNwB.js} +2 -2
  109. package/dist/components/p-CqsgiNwB.js.map +1 -0
  110. package/dist/components/p-DHJZDpNk.js +2 -0
  111. package/dist/components/p-DHJZDpNk.js.map +1 -0
  112. package/dist/components/{p-clDpFcdU.js → p-DKVDYHxb.js} +2 -2
  113. package/dist/components/p-DRqbwDzo.js +2 -0
  114. package/dist/components/p-DRqbwDzo.js.map +1 -0
  115. package/dist/components/{p-CPD_mML6.js → p-KeMecQN9.js} +2 -2
  116. package/dist/components/p-NwPqPArp.js +2 -0
  117. package/dist/components/p-NwPqPArp.js.map +1 -0
  118. package/dist/components/p-PP5602IN.js +2 -0
  119. package/dist/components/p-PP5602IN.js.map +1 -0
  120. package/dist/components/p-VKIsOVza.js +2 -0
  121. package/dist/components/p-VKIsOVza.js.map +1 -0
  122. package/dist/components/p-kGSowBA8.js +2 -0
  123. package/dist/components/{p-DsiueSMI.js.map → p-kGSowBA8.js.map} +1 -1
  124. package/dist/docs/components.json +3778 -816
  125. package/dist/framework/angular.d.ts +1 -0
  126. package/dist/framework/angular.js +1 -0
  127. package/dist/framework/select-multi-value-accessor.d.ts +9 -0
  128. package/dist/framework/select-multi-value-accessor.js +40 -0
  129. package/dist/lib/components/Menu/menu-position.d.ts +6 -19
  130. package/dist/lib/components/Text/text-types.d.ts +1 -1
  131. package/dist/lib/utils/anchored-popup.d.ts +19 -0
  132. package/dist/react/components.d.ts +2 -1
  133. package/dist/react/components.js +2 -1
  134. package/dist/react/ds-radio.d.ts +12 -0
  135. package/dist/react/ds-radio.js +12 -0
  136. package/dist/react/ds-select-multi.d.ts +14 -0
  137. package/dist/react/ds-select-multi.js +16 -0
  138. package/dist/react/ds-select.d.ts +2 -0
  139. package/dist/react/ds-select.js +5 -1
  140. package/dist/react/ds-slider.d.ts +4 -3
  141. package/dist/react/ds-slider.js +4 -1
  142. package/dist/types/components/Badge/Badge.d.ts +2 -0
  143. package/dist/types/components/ButtonFilled/ButtonFilled.d.ts +2 -0
  144. package/dist/types/components/ButtonUnfilled/ButtonUnfilled.d.ts +4 -1
  145. package/dist/types/components/Checkbox/Checkbox.d.ts +16 -0
  146. package/dist/types/components/Checkbox/index.d.ts +1 -1
  147. package/dist/types/components/EmptyState/EmptyState.d.ts +6 -5
  148. package/dist/types/components/Field/Field.d.ts +37 -2
  149. package/dist/types/components/Icon/Icon.d.ts +6 -1
  150. package/dist/types/components/Input/Input.d.ts +26 -0
  151. package/dist/types/components/Loader/Loader.d.ts +6 -1
  152. package/dist/types/components/Menu/Menu.d.ts +6 -0
  153. package/dist/types/components/Menu/menu-position.d.ts +6 -19
  154. package/dist/types/components/Modal/Modal.d.ts +5 -0
  155. package/dist/types/components/PanelNav/PanelNav.d.ts +9 -0
  156. package/dist/types/components/{RadioGroup/RadioGroup.d.ts → Radio/Radio.d.ts} +18 -2
  157. package/dist/types/components/Radio/index.d.ts +2 -0
  158. package/dist/types/components/Select/Select.d.ts +94 -48
  159. package/dist/types/components/Select/index.d.ts +1 -1
  160. package/dist/types/components/SelectMulti/SelectMulti.d.ts +131 -0
  161. package/dist/types/components/SelectMulti/index.d.ts +2 -0
  162. package/dist/types/components/Slider/Slider.d.ts +101 -7
  163. package/dist/types/components/Switch/Switch.d.ts +4 -0
  164. package/dist/types/components/TabGroup/TabGroup.d.ts +1 -0
  165. package/dist/types/components/Text/Text.d.ts +7 -0
  166. package/dist/types/components/Text/text-types.d.ts +1 -1
  167. package/dist/types/components.d.ts +1130 -117
  168. package/dist/types/utils/anchored-popup.d.ts +20 -0
  169. package/dist/types/utils/choice-list-parts.d.ts +33 -0
  170. package/dist/types/utils/choice-list.d.ts +26 -0
  171. package/package.json +10 -5
  172. package/dist/angular/ds-radio-group.d.ts +0 -15
  173. package/dist/components/ds-radio-group.js +0 -2
  174. package/dist/components/ds-radio-group.js.map +0 -1
  175. package/dist/components/p-B8ERbwc9.js +0 -2
  176. package/dist/components/p-B8ERbwc9.js.map +0 -1
  177. package/dist/components/p-Ca1H1HPf.js +0 -2
  178. package/dist/components/p-Ca1H1HPf.js.map +0 -1
  179. package/dist/components/p-CpX87AQy.js +0 -2
  180. package/dist/components/p-CpX87AQy.js.map +0 -1
  181. package/dist/components/p-CyMmsNCF.js +0 -2
  182. package/dist/components/p-CyMmsNCF.js.map +0 -1
  183. package/dist/components/p-DsiueSMI.js +0 -2
  184. package/dist/components/p-Dt0XnMxc.js.map +0 -1
  185. package/dist/components/p-Mx6VFEQc.js.map +0 -1
  186. package/dist/react/ds-radio-group.d.ts +0 -12
  187. package/dist/react/ds-radio-group.js +0 -12
  188. package/dist/types/components/RadioGroup/index.d.ts +0 -2
  189. /package/dist/components/{p-DavEAOUa.js.map → p-BjhTeU17.js.map} +0 -0
  190. /package/dist/components/{p-3bRWSqaN.js.map → p-CDu_LfhF.js.map} +0 -0
  191. /package/dist/components/{p-clDpFcdU.js.map → p-DKVDYHxb.js.map} +0 -0
  192. /package/dist/components/{p-CPD_mML6.js.map → p-KeMecQN9.js.map} +0 -0
package/dist/agent.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
3
  "package": "@ds-mo/ui",
4
- "packageVersion": "8.0.1",
4
+ "packageVersion": "8.2.0",
5
5
  "kind": "components",
6
6
  "entries": [
7
7
  {
@@ -139,7 +139,7 @@
139
139
  "useWhen": [
140
140
  "An existing control, navigation item, or label needs a compact unread notification count.",
141
141
  "An owning element needs a small visual dot indicating that supplemental notification information exists.",
142
- "The immediate backing surface can be identified so the badge ring visually separates the mark from its owner."
142
+ "When the badge overlaps an icon or content, the immediate backing surface can be identified so its separation ring matches."
143
143
  ],
144
144
  "avoidWhen": [
145
145
  "The status must stand alone without an owning label or control.",
@@ -182,8 +182,9 @@
182
182
  "Non-positive counter values hide the badge.",
183
183
  "Counts above the configured compact limit display the limit with a plus suffix while accessible text retains meaningful context.",
184
184
  "Badge keeps one brand treatment; semantic severity belongs to another component or adjacent content.",
185
- "The ring matches the immediate backing surface for both variants. Use a direct ring override only for a component-local fill that no surface preset represents.",
186
- "Shell gradient rings align automatically inside active AppShell gradient chrome and may be explicitly enabled or disabled when composition requires it."
185
+ "Use the ring only when Badge overlaps an icon or other content. Disable it in a reserved safe-area slot.",
186
+ "When enabled, the ring matches the immediate backing surface for both variants. Use a direct ring override only for a component-local fill that no surface preset represents.",
187
+ "Enabled shell gradient rings align automatically inside active AppShell gradient chrome and may be explicitly enabled or disabled when composition requires it."
187
188
  ],
188
189
  "responsiveBehavior": [
189
190
  "The owning control or layout positions Badge and decides whether notification indicators remain visible, condense, or move at responsive breakpoints.",
@@ -221,6 +222,10 @@
221
222
  "type": "boolean",
222
223
  "required": false
223
224
  },
225
+ "hasRing": {
226
+ "type": "boolean",
227
+ "required": false
228
+ },
224
229
  "label": {
225
230
  "type": "string | undefined",
226
231
  "required": false
@@ -516,14 +521,15 @@
516
521
  "Provide an explicit accessible name for icon-only buttons.",
517
522
  "Use inactive state only when the action must remain visible but unavailable.",
518
523
  "Do not encode the action meaning through color alone.",
519
- "Loading keeps the action's accessible name and exposes busy state; announce broader operation progress from the owning workflow when users need confirmation.",
524
+ "Loading keeps the action focused and named, exposes busy and disabled state, and blocks activation; announce broader operation progress from the owning workflow when users need confirmation.",
520
525
  "Use native submit behavior for form submission and handle the form submit event rather than submitting from the button click event."
521
526
  ],
522
527
  "states": [
523
528
  "Use only one filled action per local decision area; render all secondary actions with ButtonUnfilled.",
524
529
  "Choose brand or neutral for general commands. Reserve positive, negative, warning, and caution for matching action consequences, and AI, guide, or walkthrough for actions that enter those feature experiences.",
525
530
  "Contrast serves both surface adaptation and hierarchy, but never permits a second filled action in the same decision area.",
526
- "Loading prevents duplicate activation without applying inactive opacity.",
531
+ "Rounded changes only the control radius to the half-radius treatment; it does not change hierarchy, size, variant, intent, or interaction semantics.",
532
+ "Loading prevents duplicate activation without applying inactive opacity or removing the current keyboard focus.",
527
533
  "Icon and icon-label loading replace the icon in place. Label-only loading centers the loader while preserving the button's measured width."
528
534
  ],
529
535
  "responsiveBehavior": [
@@ -577,6 +583,10 @@
577
583
  "type": "string",
578
584
  "required": false
579
585
  },
586
+ "rounded": {
587
+ "type": "boolean",
588
+ "required": false
589
+ },
580
590
  "size": {
581
591
  "type": "ButtonFilledSize",
582
592
  "required": false
@@ -666,7 +676,7 @@
666
676
  "Provide an explicit accessible name for every icon-only action.",
667
677
  "Use active state only for a persistent toggle or mode, and synchronize pressed semantics unless an owning composite exposes the selection state.",
668
678
  "Treat notification dots as supplemental unread or status information; never use a dot as the sole state, meaning, or accessible name.",
669
- "Loading keeps the action's accessible name and exposes busy state; announce broader operation progress from the owning workflow when needed.",
679
+ "Loading keeps the action focused and named, exposes busy and disabled state, and blocks activation; announce broader operation progress from the owning workflow when needed.",
670
680
  "Use inactive state only when an unavailable action must remain visible.",
671
681
  "For form submission, use native submit behavior and handle the form submit event rather than submitting from the button click event."
672
682
  ],
@@ -675,7 +685,8 @@
675
685
  "Shell, navigation, and tool-rail chrome uses foreground-only active state with no selected fill or border.",
676
686
  "The omitted default surface treatment is for primary and secondary parent surfaces and uses the brand-active selected fill; pass faint explicitly on faint surfaces to use the neutral active fill.",
677
687
  "Surface context must match the actual parent surface; translucent, inverted, media, and always-dark treatments are reserved for those surfaces.",
678
- "Loading prevents duplicate activation without applying inactive opacity.",
688
+ "Loading prevents duplicate activation without applying inactive opacity or removing the current keyboard focus.",
689
+ "Rounded changes only the control radius to the half-radius treatment; it does not change hierarchy, size, variant, or interaction semantics.",
679
690
  "Icon and icon-label loading replace the icon in place. Label-only loading centers the loader while preserving the button's measured width."
680
691
  ],
681
692
  "responsiveBehavior": [
@@ -736,7 +747,7 @@
736
747
  "required": false
737
748
  },
738
749
  "haspopup": {
739
- "type": "string | undefined",
750
+ "type": "ButtonUnfilledPopup | undefined",
740
751
  "required": false
741
752
  },
742
753
  "icon": {
@@ -763,6 +774,10 @@
763
774
  "type": "boolean | undefined",
764
775
  "required": false
765
776
  },
777
+ "rounded": {
778
+ "type": "boolean",
779
+ "required": false
780
+ },
766
781
  "size": {
767
782
  "type": "ButtonUnfilledSize",
768
783
  "required": false
@@ -1164,9 +1179,84 @@
1164
1179
  "tag": "ds-checkbox",
1165
1180
  "name": "checkbox",
1166
1181
  "title": "Checkbox",
1167
- "summary": "Three-state checkbox (checked, unchecked, indeterminate) with keyboard support and custom icon slots.",
1168
- "intentStatus": "migration-pending",
1169
- "intent": null,
1182
+ "summary": "Form-associated checkbox for independent choices, acknowledgment, or consent, with checked, unchecked, mixed, and three density states.",
1183
+ "intentStatus": "complete",
1184
+ "intent": {
1185
+ "audience": "general",
1186
+ "status": "stable",
1187
+ "summary": "Form-associated checkbox for independent choices, acknowledgment, or consent, with checked, unchecked, mixed, and three density states.",
1188
+ "useWhen": [
1189
+ "A user may independently select zero or more choices.",
1190
+ "A form requires acknowledgment, consent, or an opt-in value before submission.",
1191
+ "A composite multi-select option needs a presentation-only checkbox indicator."
1192
+ ],
1193
+ "avoidWhen": [
1194
+ "Exactly one option must be chosen from a mutually exclusive set.",
1195
+ "A binary setting takes effect immediately rather than being submitted or confirmed.",
1196
+ "The control triggers a one-time command instead of maintaining selection state."
1197
+ ],
1198
+ "alternatives": [
1199
+ {
1200
+ "when": "Exactly one option must be chosen from a mutually exclusive set.",
1201
+ "component": "component:ds-radio",
1202
+ "reason": "Radio communicates one-of-many selection."
1203
+ },
1204
+ {
1205
+ "when": "A binary setting takes effect immediately.",
1206
+ "component": "component:ds-switch",
1207
+ "reason": "Switch communicates an immediately applied on/off setting."
1208
+ },
1209
+ {
1210
+ "when": "The interaction triggers a one-time command.",
1211
+ "component": "component:ds-button-filled",
1212
+ "reason": "Button semantics communicate an action rather than persistent selection."
1213
+ }
1214
+ ],
1215
+ "commonlyComposedWith": [
1216
+ "component:ds-field",
1217
+ "component:ds-select-multi",
1218
+ "component:ds-text"
1219
+ ],
1220
+ "accessibility": [
1221
+ "Every interactive checkbox requires a visible label that provides its accessible name.",
1222
+ "Enter and Space activate the checkbox; checked and mixed state are exposed through aria-checked.",
1223
+ "Disabled and inactive checkboxes leave the tab order and are omitted from form submission.",
1224
+ "Use presentation mode only inside a composite option that owns selection semantics, focus, and interaction."
1225
+ ],
1226
+ "states": [
1227
+ "Unchecked boxes use a tertiary-foreground inset stroke: 1.25px at md, 1px at sm, and 0.75px at xs. Selected and mixed boxes remove the border, use a brand fill, and draw a component-owned check or subtract mark at the same density-specific stroke width.",
1228
+ "Activating an indeterminate checkbox clears the mixed state, toggles checked, and emits dsChange with the resulting boolean.",
1229
+ "The initial checked and indeterminate values are restored by native form reset; checked values submit under name and unchecked values submit nothing.",
1230
+ "Sizes are md with a 16px box in a 20px placement, sm with a 12px box in a 16px placement, and xs with an 8px box in a 12px placement.",
1231
+ "Presentation mode removes checkbox semantics, focus, interaction, label rendering, and form submission while preserving the visual state."
1232
+ ],
1233
+ "responsiveBehavior": [
1234
+ "Choose size from the density of the containing row; labels may wrap while the placement box stays fixed.",
1235
+ "Use the md indicator centered by the shared 20px option icon zone in multi-select rows."
1236
+ ],
1237
+ "frameworkCaveats": {
1238
+ "customElements": [
1239
+ "Bind checked and indeterminate as properties for application state updates and listen for dsChange.",
1240
+ "Use the form attribute on the host when associating a checkbox rendered outside its owning form."
1241
+ ],
1242
+ "react": [
1243
+ "Use DsCheckbox and handle onDsChange; checked and indeterminate are mutable and update after user activation."
1244
+ ],
1245
+ "angular": [
1246
+ "Use DsCheckbox with checked binding and dsChange, or the generated boolean value accessor in Angular forms."
1247
+ ]
1248
+ },
1249
+ "references": [
1250
+ {
1251
+ "label": "Storybook examples",
1252
+ "path": "src/wc/components/Checkbox/Checkbox.stories.ts"
1253
+ },
1254
+ {
1255
+ "label": "Cross-browser form and accessibility coverage",
1256
+ "path": "tests/e2e/forms.spec.ts"
1257
+ }
1258
+ ]
1259
+ },
1170
1260
  "api": {
1171
1261
  "props": {
1172
1262
  "checked": {
@@ -1193,6 +1283,10 @@
1193
1283
  "type": "string | undefined",
1194
1284
  "required": false
1195
1285
  },
1286
+ "presentation": {
1287
+ "type": "boolean",
1288
+ "required": false
1289
+ },
1196
1290
  "required": {
1197
1291
  "type": "boolean",
1198
1292
  "required": false
@@ -1201,6 +1295,10 @@
1201
1295
  "type": "string",
1202
1296
  "required": false
1203
1297
  },
1298
+ "size": {
1299
+ "type": "CheckboxSize",
1300
+ "required": false
1301
+ },
1204
1302
  "value": {
1205
1303
  "type": "string",
1206
1304
  "required": false
@@ -1474,21 +1572,92 @@
1474
1572
  "tag": "ds-empty-state",
1475
1573
  "name": "empty-state",
1476
1574
  "title": "EmptyState",
1477
- "summary": "Centered placeholder for empty content, no results, or no access states.",
1478
- "intentStatus": "migration-pending",
1479
- "intent": null,
1575
+ "summary": "Centered empty-content message composed as icon plus title plus body, title plus body, or compact body-only content.",
1576
+ "intentStatus": "complete",
1577
+ "intent": {
1578
+ "audience": "general",
1579
+ "status": "stable",
1580
+ "summary": "Centered empty-content message composed as icon plus title plus body, title plus body, or compact body-only content.",
1581
+ "useWhen": [
1582
+ "A bounded content area is in a first-use, no-content, filtered no-results, or no-access state and needs a calm explanatory message tailored to that cause.",
1583
+ "A prominent empty region benefits from a decorative icon, visual title, and supporting body copy.",
1584
+ "A compact owner such as a Select popup needs only centered body copy."
1585
+ ],
1586
+ "avoidWhen": [
1587
+ "Content is still loading; use Skeleton for predictable structure or Loader for an indeterminate operation.",
1588
+ "The state is an error, warning, or confirmation that needs semantic intent and announcement from the owning workflow.",
1589
+ "The state needs a recovery action, link, or other interactive content; the current EmptyState pattern is intentionally message-only.",
1590
+ "A decorative illustration, arbitrary rich content, or custom layout is required."
1591
+ ],
1592
+ "alternatives": [
1593
+ {
1594
+ "when": "A content region is waiting for structured data.",
1595
+ "component": "component:ds-skeleton",
1596
+ "reason": "Skeleton preserves expected geometry while content is pending."
1597
+ },
1598
+ {
1599
+ "when": "An operation is progressing without predictable content structure.",
1600
+ "component": "component:ds-loader",
1601
+ "reason": "Loader owns indeterminate progress rather than an empty outcome."
1602
+ },
1603
+ {
1604
+ "when": "Only ordinary prose is needed without empty-state layout.",
1605
+ "component": "component:ds-text",
1606
+ "reason": "Text owns typography without adding centered empty-state composition."
1607
+ }
1608
+ ],
1609
+ "commonlyComposedWith": [
1610
+ "component:ds-select",
1611
+ "component:ds-text",
1612
+ "component:ds-icon"
1613
+ ],
1614
+ "accessibility": [
1615
+ "The optional icon is decorative; the title and body provide all meaning in text.",
1616
+ "EmptyState does not create a live region or alert automatically. The owner decides whether a dynamic transition requires announcement.",
1617
+ "The visual title does not impose a document heading level because the correct hierarchy belongs to the consuming page or region.",
1618
+ "Keep localized body copy concise and sufficient when using the body-only variant."
1619
+ ],
1620
+ "states": [
1621
+ "Supported compositions are icon plus title plus body, title plus body, and body only; body copy is present in every supported composition.",
1622
+ "The decorative icon renders at xl in the primary foreground with an 8px gap before the text group and only when a title is also provided.",
1623
+ "The visual title uses title-small primary text; body uses body-medium secondary text with a 4px title-to-body gap.",
1624
+ "All content is centered. The owner supplies container size and surrounding padding; do not compose actions into or immediately alongside the current EmptyState pattern.",
1625
+ "First-use, no-content, no-results, and no-access states reuse this primitive with cause-specific localized messages rather than visual variants."
1626
+ ],
1627
+ "responsiveBehavior": [
1628
+ "The owner controls available width and height; text wraps naturally while remaining centered.",
1629
+ "EmptyState does not infer breakpoints or change composition automatically."
1630
+ ],
1631
+ "frameworkCaveats": {
1632
+ "customElements": [
1633
+ "Pass canonical IcoMo icon names and localized heading/body strings through properties or attributes."
1634
+ ],
1635
+ "react": [
1636
+ "Choose one supported composition by passing body with optional heading and icon props."
1637
+ ],
1638
+ "angular": [
1639
+ "Choose one supported composition by binding body with optional heading and icon inputs."
1640
+ ]
1641
+ },
1642
+ "references": [
1643
+ {
1644
+ "label": "Storybook examples",
1645
+ "path": "src/wc/components/EmptyState/EmptyState.stories.ts"
1646
+ }
1647
+ ]
1648
+ },
1480
1649
  "api": {
1481
1650
  "props": {
1482
- "message": {
1483
- "type": "string | undefined",
1651
+ "body": {
1652
+ "type": "string",
1484
1653
  "required": false
1485
1654
  },
1486
- "messages": {
1487
- "type": "Partial<Record<EmptyStateType, string>>",
1655
+ "heading": {
1656
+ "type": "string | undefined",
1488
1657
  "required": false
1489
1658
  },
1490
- "type": {
1491
- "type": "EmptyStateType",
1659
+ "icon": {
1660
+ "type": "string | undefined",
1492
1661
  "required": false
1493
1662
  }
1494
1663
  },
@@ -1502,9 +1671,11 @@
1502
1671
  },
1503
1672
  "dependencies": [
1504
1673
  "@ds-mo/ui",
1505
- "@ds-mo/tokens"
1674
+ "@ds-mo/tokens",
1675
+ "@ds-mo/icons"
1506
1676
  ],
1507
1677
  "componentDependencies": [
1678
+ "icon",
1508
1679
  "text"
1509
1680
  ]
1510
1681
  },
@@ -1513,11 +1684,89 @@
1513
1684
  "tag": "ds-field",
1514
1685
  "name": "field",
1515
1686
  "title": "Field",
1516
- "summary": "Simple label wrapper that links to child input via htmlFor.",
1517
- "intentStatus": "migration-pending",
1518
- "intent": null,
1687
+ "summary": "Accessible form-field composition that gives one Input or Select a persistent label, optional guidance, shared error presentation, stable IDs, and observable interaction state.",
1688
+ "intentStatus": "complete",
1689
+ "intent": {
1690
+ "audience": "general",
1691
+ "status": "stable",
1692
+ "summary": "Accessible form-field composition that gives one Input or Select a persistent label, optional guidance, shared error presentation, stable IDs, and observable interaction state.",
1693
+ "useWhen": [
1694
+ "An Input, Select, or SelectMulti needs a persistent visible label in a form.",
1695
+ "Help text or an error message must be programmatically associated with one control.",
1696
+ "A form layout needs one consistent label-control-message rhythm."
1697
+ ],
1698
+ "avoidWhen": [
1699
+ "The component already owns its visible label and complete selection semantics, such as Checkbox, Radio, or Switch.",
1700
+ "Several controls belong to one question; use a semantic fieldset and legend instead.",
1701
+ "Text describes a region or group rather than one form control."
1702
+ ],
1703
+ "alternatives": [
1704
+ {
1705
+ "when": "Several related controls answer one question.",
1706
+ "component": "component:ds-text",
1707
+ "reason": "Use native fieldset and legend semantics, then compose Text only for supporting content."
1708
+ }
1709
+ ],
1710
+ "commonlyComposedWith": [
1711
+ "component:ds-input",
1712
+ "component:ds-select",
1713
+ "component:ds-select-multi",
1714
+ "component:ds-text"
1715
+ ],
1716
+ "accessibility": [
1717
+ "Slot exactly one form control. Field assigns its stable control ID and connects the visible label automatically.",
1718
+ "Description and rendered error IDs are merged with any authored aria-describedby references rather than replacing them.",
1719
+ "The error prop forwards aria-invalid and supported design-system control error styling; put visible error text on Field, not again on the child control.",
1720
+ "Clicking the label focuses the slotted design-system control without opening a Select popup.",
1721
+ "Do not use placeholder text as the only label. Keep label text concise and put format or consequence guidance in description."
1722
+ ],
1723
+ "states": [
1724
+ "Field exposes data-focused, data-filled, data-dirty, data-touched, data-invalid, data-disabled, and data-required hooks while the slotted control remains the source of value and interaction behavior.",
1725
+ "Description remains visible during error so guidance and validation do not replace each other.",
1726
+ "Field owns validation presentation but not validation timing; the form decides when to set error and errorMessage.",
1727
+ "The label uses primary body-small emphasis, description uses secondary body-small text, and error uses negative body-small text."
1728
+ ],
1729
+ "responsiveBehavior": [
1730
+ "Field fills the width supplied by its parent and makes the slotted control fill that field width.",
1731
+ "The form layout owns column count, wrapping, and responsive placement; Field keeps the vertical label-control-message composition intact."
1732
+ ],
1733
+ "frameworkCaveats": {
1734
+ "customElements": [
1735
+ "Set fieldId only when another element must reference a predictable control ID; otherwise use the generated association.",
1736
+ "Assign child component values and option arrays through their normal JavaScript properties."
1737
+ ],
1738
+ "react": [
1739
+ "Compose one DsInput, DsSelect, or DsSelectMulti child and control validation timing in the form owner."
1740
+ ],
1741
+ "angular": [
1742
+ "Compose the generated Field adapter around the control adapter and its matching Angular value accessor."
1743
+ ]
1744
+ },
1745
+ "references": [
1746
+ {
1747
+ "label": "Storybook examples",
1748
+ "path": "src/wc/components/Field/Field.stories.ts"
1749
+ },
1750
+ {
1751
+ "label": "Cross-browser form and accessibility coverage",
1752
+ "path": "tests/e2e/forms.spec.ts"
1753
+ }
1754
+ ]
1755
+ },
1519
1756
  "api": {
1520
1757
  "props": {
1758
+ "description": {
1759
+ "type": "string | undefined",
1760
+ "required": false
1761
+ },
1762
+ "error": {
1763
+ "type": "boolean",
1764
+ "required": false
1765
+ },
1766
+ "errorMessage": {
1767
+ "type": "string | undefined",
1768
+ "required": false
1769
+ },
1521
1770
  "fieldId": {
1522
1771
  "type": "string | undefined",
1523
1772
  "required": false
@@ -1592,11 +1841,13 @@
1592
1841
  "Icons are decorative by default and remain hidden from assistive technology when visible text or an owning control already communicates the meaning.",
1593
1842
  "The owning button, link, or composite control provides the accessible name; do not repeat that name on its nested Icon.",
1594
1843
  "Provide an explicit label only when the non-interactive icon itself communicates otherwise unavailable meaning.",
1844
+ "Tertiary and quaternary foregrounds are restricted to icons inside genuinely inactive or disabled UI, or to purely decorative icons; quaternary is the fainter tier, and informative icons and meaningful status graphics retain sufficient rendered contrast even when aria-hidden.",
1595
1845
  "Informative flags require an explicit localized country or region label; never derive accessible text from the export name.",
1596
1846
  "Icon never receives focus or owns interaction."
1597
1847
  ],
1598
1848
  "states": [
1599
1849
  "Omitted color inherits currentColor from the owning context. Explicit semantic aliases and CSS-variable references are available when the icon has an independent color role.",
1850
+ "Prefer the owning control's isInactive or native disabled state over manually selecting tertiary or quaternary so visual treatment and inactive semantics remain synchronized.",
1600
1851
  "Built-in glyph lookup accepts exact canonical IcoMo export names only. Names beginning with Flag select the flag catalog automatically.",
1601
1852
  "A cache miss lazy-loads into a fixed-size box without layout shift. Unknown names, failed loads, and rejected markup leave that box empty.",
1602
1853
  "Critical first-paint glyphs may be pre-registered before rendering; all resolved glyphs share a global cache.",
@@ -1667,9 +1918,89 @@
1667
1918
  "tag": "ds-input",
1668
1919
  "name": "input",
1669
1920
  "title": "Input",
1670
- "summary": "Text input supporting text, email, tel, url, search, and password types. Search type includes auto clear button.",
1671
- "intentStatus": "migration-pending",
1672
- "intent": null,
1921
+ "summary": "Form-associated single-line text field for primary and secondary application backgrounds, with native text input behavior, three control densities, optional leading and trailing content, search clearing, and validation.",
1922
+ "intentStatus": "complete",
1923
+ "intent": {
1924
+ "audience": "general",
1925
+ "status": "stable",
1926
+ "summary": "Form-associated single-line text field for primary and secondary application backgrounds, with native text input behavior, three control densities, optional leading and trailing content, search clearing, and validation.",
1927
+ "useWhen": [
1928
+ "A user must enter or edit one line of text, an email address, telephone number, URL, search query, or password.",
1929
+ "The value must participate in native, Angular, or React form state.",
1930
+ "A compact filter or toolbar needs a single-line search field that follows the shared control-density recipe."
1931
+ ],
1932
+ "avoidWhen": [
1933
+ "The user chooses from a finite set of known values.",
1934
+ "The user must enter multiple paragraphs or formatted content.",
1935
+ "The value is adjusted primarily by dragging within a numeric range."
1936
+ ],
1937
+ "alternatives": [
1938
+ {
1939
+ "when": "The value comes from a finite set of known choices.",
1940
+ "component": "component:ds-select",
1941
+ "reason": "Select exposes the available values and owns listbox selection behavior."
1942
+ },
1943
+ {
1944
+ "when": "The value is an immediate on/off setting.",
1945
+ "component": "component:ds-switch",
1946
+ "reason": "Switch communicates a binary setting instead of free text entry."
1947
+ },
1948
+ {
1949
+ "when": "The value is chosen from a bounded numeric range.",
1950
+ "component": "component:ds-slider",
1951
+ "reason": "Slider supports direct range adjustment and communicates the current position."
1952
+ }
1953
+ ],
1954
+ "commonlyComposedWith": [
1955
+ "component:ds-field",
1956
+ "component:ds-icon",
1957
+ "component:ds-text"
1958
+ ],
1959
+ "accessibility": [
1960
+ "Provide a persistent visible label through the owning field or an external native label; placeholder text is guidance and must not be the field's only label.",
1961
+ "Choose the native input type that matches the value so browsers and assistive technology can provide appropriate semantics and keyboards.",
1962
+ "Error text is associated with the native input and announced as an alert when the invalid state is rendered.",
1963
+ "Read-only fields remain focusable and submittable while preventing edits; inactive or disabled fields leave the tab order and are omitted from form submission.",
1964
+ "Suffix content must not carry information that is otherwise absent from the field's visible label, value, or description."
1965
+ ],
1966
+ "states": [
1967
+ "The normal field boundary uses the shared secondary inset border. Focus promotes it to the thicker bold-brand inset stroke, while error uses the thicker bold-negative inset stroke without changing geometry.",
1968
+ "Placeholder text is secondary at rest and quaternary while the editable field is focused because it becomes decorative once typing begins.",
1969
+ "Entered values use the parent surface's primary foreground; prefix icons, suffix content, and resting placeholder text use its secondary foreground.",
1970
+ "Search fields show a standard borderless CrossCircle icon action only while they contain a value. Clearing emits the empty value and restores focus to the native field.",
1971
+ "The suffix slot is for compact units or decorations. The optional leading icon is decorative and does not replace the field label.",
1972
+ "Use autoComplete, inputMode, and enterKeyHint to provide browser and virtual-keyboard hints without changing the value's semantic type.",
1973
+ "The host exposes focused, filled, dirty, touched, invalid, disabled, read-only, and required data attributes for Field integration and diagnostics.",
1974
+ "Use Input only on primary or secondary application backgrounds. It intentionally does not expose alternate surface contexts."
1975
+ ],
1976
+ "responsiveBehavior": [
1977
+ "Form fields normally fill their parent; use hug width only in a compact toolbar or filter layout with an explicit width constraint.",
1978
+ "Choose density from the containing layout: md for ordinary forms, sm or xs only where the surrounding controls use the same compact recipe.",
1979
+ "The owner supplies layout constraints and decides when a compact field moves to its own row."
1980
+ ],
1981
+ "frameworkCaveats": {
1982
+ "customElements": [
1983
+ "Listen for dsChange for user edits and dsClear for the search clear action.",
1984
+ "Use the form attribute on the host when associating an input rendered outside its owning form."
1985
+ ],
1986
+ "react": [
1987
+ "Use DsInput, bind value for controlled application state, and handle onDsChange and onDsClear."
1988
+ ],
1989
+ "angular": [
1990
+ "Import DsInput with TextValueAccessor when integrating with Angular Forms."
1991
+ ]
1992
+ },
1993
+ "references": [
1994
+ {
1995
+ "label": "Storybook examples",
1996
+ "path": "src/wc/components/Input/Input.stories.ts"
1997
+ },
1998
+ {
1999
+ "label": "Cross-browser form and accessibility coverage",
2000
+ "path": "tests/e2e/forms.spec.ts"
2001
+ }
2002
+ ]
2003
+ },
1673
2004
  "api": {
1674
2005
  "props": {
1675
2006
  "ariaDescribedby": {
@@ -1684,6 +2015,10 @@
1684
2015
  "type": "string | undefined",
1685
2016
  "required": false
1686
2017
  },
2018
+ "autoComplete": {
2019
+ "type": "string | undefined",
2020
+ "required": false
2021
+ },
1687
2022
  "autoFocus": {
1688
2023
  "type": "boolean",
1689
2024
  "required": false
@@ -1696,6 +2031,10 @@
1696
2031
  "type": "boolean",
1697
2032
  "required": false
1698
2033
  },
2034
+ "enterKeyHint": {
2035
+ "type": "string",
2036
+ "required": false
2037
+ },
1699
2038
  "error": {
1700
2039
  "type": "boolean",
1701
2040
  "required": false
@@ -1704,10 +2043,26 @@
1704
2043
  "type": "string | undefined",
1705
2044
  "required": false
1706
2045
  },
2046
+ "form": {
2047
+ "type": "string | undefined",
2048
+ "required": false
2049
+ },
2050
+ "hasBorder": {
2051
+ "type": "boolean",
2052
+ "required": false
2053
+ },
2054
+ "icon": {
2055
+ "type": "string | undefined",
2056
+ "required": false
2057
+ },
1707
2058
  "inputId": {
1708
2059
  "type": "string | undefined",
1709
2060
  "required": false
1710
2061
  },
2062
+ "inputMode": {
2063
+ "type": "string",
2064
+ "required": false
2065
+ },
1711
2066
  "isInactive": {
1712
2067
  "type": "boolean",
1713
2068
  "required": false
@@ -1720,6 +2075,10 @@
1720
2075
  "type": "string | undefined",
1721
2076
  "required": false
1722
2077
  },
2078
+ "readOnly": {
2079
+ "type": "boolean",
2080
+ "required": false
2081
+ },
1723
2082
  "required": {
1724
2083
  "type": "boolean",
1725
2084
  "required": false
@@ -1728,6 +2087,10 @@
1728
2087
  "type": "string",
1729
2088
  "required": false
1730
2089
  },
2090
+ "size": {
2091
+ "type": "InputSize",
2092
+ "required": false
2093
+ },
1731
2094
  "type": {
1732
2095
  "type": "InputType",
1733
2096
  "required": false
@@ -1735,8 +2098,12 @@
1735
2098
  "value": {
1736
2099
  "type": "string",
1737
2100
  "required": false
1738
- }
1739
- },
2101
+ },
2102
+ "width": {
2103
+ "type": "InputWidth",
2104
+ "required": false
2105
+ }
2106
+ },
1740
2107
  "events": [
1741
2108
  {
1742
2109
  "name": "dsChange",
@@ -1756,9 +2123,12 @@
1756
2123
  },
1757
2124
  "dependencies": [
1758
2125
  "@ds-mo/ui",
1759
- "@ds-mo/tokens"
2126
+ "@ds-mo/tokens",
2127
+ "@ds-mo/icons"
1760
2128
  ],
1761
2129
  "componentDependencies": [
2130
+ "button-unfilled",
2131
+ "icon",
1762
2132
  "text"
1763
2133
  ]
1764
2134
  },
@@ -1805,12 +2175,14 @@
1805
2175
  "accessibility": [
1806
2176
  "When Loader is nested in a busy button, field, or region, keep it unnamed and expose busy state from the owner.",
1807
2177
  "Standalone Loader requires contextual status text that explains what is loading; do not rely on a generic visual spinner alone.",
2178
+ "Loader is an informative progress graphic and must retain sufficient rendered contrast; tertiary and quaternary are not supported standalone or informative Loader treatments.",
1808
2179
  "Avoid duplicate announcements from both Loader and its owning busy region.",
1809
2180
  "Reduced motion stops rotation while keeping the glyph and status semantics visible."
1810
2181
  ],
1811
2182
  "states": [
1812
2183
  "Loader communicates indeterminate progress only and does not emit completion or failure events.",
1813
2184
  "Omitted color inherits currentColor. Explicit semantic aliases and CSS-variable references match Icon when an independent progress color is required.",
2185
+ "Nested Loader inherits a readable color from its owning busy control or region rather than selecting tertiary or quaternary directly.",
1814
2186
  "The owner decides whether to delay Loader visibility for short operations and removes it when the operation settles.",
1815
2187
  "The owner reserves space and supplies centering or overlay layout so Loader never causes unexpected layout movement."
1816
2188
  ],
@@ -1870,15 +2242,15 @@
1870
2242
  "tag": "ds-menu",
1871
2243
  "name": "menu",
1872
2244
  "title": "Menu",
1873
- "summary": "Anchored action or option menu with flat items, grouped sections, selection, supplemental notification dots, switches, and destructive actions.",
2245
+ "summary": "Anchored action menu with flat commands, grouped sections, selected command state, supplemental notification dots, switches, and destructive actions.",
1874
2246
  "intentStatus": "complete",
1875
2247
  "intent": {
1876
2248
  "audience": "general",
1877
2249
  "status": "stable",
1878
- "summary": "Anchored action or option menu with flat items, grouped sections, selection, supplemental notification dots, switches, and destructive actions.",
2250
+ "summary": "Anchored action menu with flat commands, grouped sections, selected command state, supplemental notification dots, switches, and destructive actions.",
1879
2251
  "useWhen": [
1880
- "A trigger reveals a short contextual list of commands or options.",
1881
- "Options need grouping, selected state, supplemental notification dots, switch rows, or destructive treatment."
2252
+ "A trigger reveals a short contextual list of commands or state-changing actions.",
2253
+ "Actions need grouping, selected state, supplemental notification dots, switch rows, or destructive treatment."
1882
2254
  ],
1883
2255
  "avoidWhen": [
1884
2256
  "The user is selecting a value for a form field.",
@@ -1891,6 +2263,11 @@
1891
2263
  "component": "component:ds-select",
1892
2264
  "reason": "Select provides form-control semantics and value ownership."
1893
2265
  },
2266
+ {
2267
+ "when": "Several form values may be selected.",
2268
+ "component": "component:ds-select-multi",
2269
+ "reason": "SelectMulti provides multi-select listbox semantics, array value ownership, and count presentation."
2270
+ },
1894
2271
  {
1895
2272
  "when": "The interaction needs substantial content, confirmation, or a form.",
1896
2273
  "component": "component:ds-modal",
@@ -1907,7 +2284,8 @@
1907
2284
  "Anchor the menu to the control that opens it and return focus to that control when the menu closes.",
1908
2285
  "Open with visible initial focus only when the trigger was activated from the keyboard.",
1909
2286
  "Keep disabled items discoverable only when their unavailable state is meaningful.",
1910
- "Switch rows use menuitemcheckbox semantics on the row; the nested ds-switch is an aria-hidden presentation indicator.",
2287
+ "Switch rows use menuitemcheckbox semantics on the row; the nested ds-switch is an aria-hidden md presentation indicator.",
2288
+ "A gradient-picker section changes the popup to a non-modal dialog so its radio group and ordinary preference buttons keep valid nested semantics; Tab moves between its controls, then leaves and closes at the popup boundary.",
1911
2289
  "Use notification dots only as supplemental status and not as the sole indication of important information."
1912
2290
  ],
1913
2291
  "states": [
@@ -1915,7 +2293,7 @@
1915
2293
  "Use either flat items or sections, not both.",
1916
2294
  "After dsSelect from a switch row, update switchValue in the items property so the controlled indicator reflects the new state.",
1917
2295
  "Arrays, objects, and element anchors must be assigned as JavaScript properties.",
1918
- "Use one gradient-picker section in the user or account Appearance or Theme menu for the global AppShell wash preference; apply dsGradientSelect immediately without closing the menu."
2296
+ "Use one gradient-picker section in the user or account Appearance or Theme popup for the global AppShell wash preference; apply dsGradientSelect immediately without closing the popup."
1919
2297
  ],
1920
2298
  "responsiveBehavior": [
1921
2299
  "Choose placement relative to the trigger and allow the component to clamp the popup to the viewport.",
@@ -2192,6 +2570,7 @@
2192
2570
  "Provide localized dashboard, settings, account, navigation, collapse, and expand labels.",
2193
2571
  "Preserve accessible destination names when the panel is collapsed to icon-only presentation.",
2194
2572
  "Use notification dots as supplemental status and never as the only indication of important information.",
2573
+ "When the destination body overflows, it becomes a localized keyboard-focusable scroll region in addition to the roving destination controls.",
2195
2574
  "Keep the standard dashboard/settings switch and user/account entry available in the footer."
2196
2575
  ],
2197
2576
  "states": [
@@ -2292,6 +2671,10 @@
2292
2671
  "type": "NavChromeStyle",
2293
2672
  "required": false
2294
2673
  },
2674
+ "navigationItemsLabel": {
2675
+ "type": "string",
2676
+ "required": false
2677
+ },
2295
2678
  "routerMode": {
2296
2679
  "type": "PanelNavRouterMode",
2297
2680
  "required": false
@@ -2656,13 +3039,86 @@
2656
3039
  ]
2657
3040
  },
2658
3041
  {
2659
- "id": "component:ds-radio-group",
2660
- "tag": "ds-radio-group",
2661
- "name": "radio-group",
2662
- "title": "RadioGroup",
2663
- "summary": "Radio selection group with vertical/horizontal layout, per-option inactive state, and keyboard navigation.",
2664
- "intentStatus": "migration-pending",
2665
- "intent": null,
3042
+ "id": "component:ds-radio",
3043
+ "tag": "ds-radio",
3044
+ "name": "radio",
3045
+ "title": "Radio",
3046
+ "summary": "Form-associated one-of-many radio selection set with vertical or horizontal layout, three densities, per-option inactive state, and roving keyboard focus.",
3047
+ "intentStatus": "complete",
3048
+ "intent": {
3049
+ "audience": "general",
3050
+ "status": "stable",
3051
+ "summary": "Form-associated one-of-many radio selection set with vertical or horizontal layout, three densities, per-option inactive state, and roving keyboard focus.",
3052
+ "useWhen": [
3053
+ "A user must select exactly one visible option from a small set.",
3054
+ "All available choices should remain visible for comparison.",
3055
+ "A form needs one selected string value with native validation, reset, or external form association."
3056
+ ],
3057
+ "avoidWhen": [
3058
+ "A user may select zero or multiple independent choices.",
3059
+ "A binary setting applies immediately rather than selecting from a set.",
3060
+ "The option list is too long or space-constrained to remain visible."
3061
+ ],
3062
+ "alternatives": [
3063
+ {
3064
+ "when": "A user may select zero or multiple independent choices.",
3065
+ "component": "component:ds-checkbox",
3066
+ "reason": "Checkbox communicates independent selection rather than one-of-many choice."
3067
+ },
3068
+ {
3069
+ "when": "A binary setting applies immediately.",
3070
+ "component": "component:ds-switch",
3071
+ "reason": "Switch communicates an immediately applied on/off setting."
3072
+ },
3073
+ {
3074
+ "when": "The option list is long or the available space is constrained.",
3075
+ "component": "component:ds-select",
3076
+ "reason": "Select keeps a larger one-of-many choice set compact."
3077
+ }
3078
+ ],
3079
+ "commonlyComposedWith": [
3080
+ "component:ds-field",
3081
+ "component:ds-text"
3082
+ ],
3083
+ "accessibility": [
3084
+ "The host exposes radiogroup semantics and requires an accessible group name from aria-label or aria-labelledby.",
3085
+ "Each visible option exposes radio semantics, its checked state, its label text, and any inactive state.",
3086
+ "Arrow keys move and select through active options; Home and End select the first and last active options; Space and Enter select the focused option.",
3087
+ "Roving tabindex keeps one active option in the tab order, preferring the selected option."
3088
+ ],
3089
+ "states": [
3090
+ "Unchecked circles use a tertiary-foreground inset stroke: 1.25px at md, 1px at sm, and 0.75px at xs.",
3091
+ "Selected circles remove the border, use a brand fill, and draw a centered on-bold foreground dot sized 8px at md, 6px at sm, and 4px at xs.",
3092
+ "Sizes are md with a 16px circle in a 20px placement, sm with a 12px circle in a 16px placement, and xs with an 8px circle in a 12px placement.",
3093
+ "The initial value is restored by native form reset; the selected value submits under name and a required set is invalid until one active option is selected."
3094
+ ],
3095
+ "responsiveBehavior": [
3096
+ "Choose size from the density of the containing form or settings row.",
3097
+ "Prefer vertical layout when labels may wrap or horizontal space is constrained; horizontal layout is appropriate for short labels in a small set."
3098
+ ],
3099
+ "frameworkCaveats": {
3100
+ "customElements": [
3101
+ "Assign options as a JavaScript property, set value as a property for application state updates, and listen for dsChange.",
3102
+ "Use the form attribute on the host when associating a radio set rendered outside its owning form."
3103
+ ],
3104
+ "react": [
3105
+ "Use DsRadio, pass options as an array, and handle onDsChange; value is mutable and updates after user selection."
3106
+ ],
3107
+ "angular": [
3108
+ "Use DsRadio with options and value bindings plus dsChange, or import the generated radio value accessor with the component adapter."
3109
+ ]
3110
+ },
3111
+ "references": [
3112
+ {
3113
+ "label": "Storybook examples",
3114
+ "path": "src/wc/components/Radio/Radio.stories.ts"
3115
+ },
3116
+ {
3117
+ "label": "Cross-browser form and accessibility coverage",
3118
+ "path": "tests/e2e/forms.spec.ts"
3119
+ }
3120
+ ]
3121
+ },
2666
3122
  "api": {
2667
3123
  "props": {
2668
3124
  "ariaLabel": {
@@ -2681,6 +3137,10 @@
2681
3137
  "type": "boolean",
2682
3138
  "required": false
2683
3139
  },
3140
+ "form": {
3141
+ "type": "string | undefined",
3142
+ "required": false
3143
+ },
2684
3144
  "isInactive": {
2685
3145
  "type": "boolean",
2686
3146
  "required": false
@@ -2701,6 +3161,10 @@
2701
3161
  "type": "string",
2702
3162
  "required": false
2703
3163
  },
3164
+ "size": {
3165
+ "type": "RadioSize",
3166
+ "required": false
3167
+ },
2704
3168
  "value": {
2705
3169
  "type": "string",
2706
3170
  "required": false
@@ -2715,9 +3179,9 @@
2715
3179
  "slots": []
2716
3180
  },
2717
3181
  "exports": {
2718
- "customElement": "ds-radio-group",
2719
- "react": "DsRadioGroup",
2720
- "angular": "DsRadioGroup"
3182
+ "customElement": "ds-radio",
3183
+ "react": "DsRadio",
3184
+ "angular": "DsRadio"
2721
3185
  },
2722
3186
  "dependencies": [
2723
3187
  "@ds-mo/ui",
@@ -2732,15 +3196,119 @@
2732
3196
  "tag": "ds-select",
2733
3197
  "name": "select",
2734
3198
  "title": "Select",
2735
- "summary": "Dropdown select with unfilled-button chrome in control-density sizes and width hug/fill. Uses ds-menu for the option list.",
2736
- "intentStatus": "migration-pending",
2737
- "intent": null,
3199
+ "summary": "Form-associated single-value select with listbox semantics, local search, rich flat options, grouped sections, loading, clearing, and surface-aware trigger chrome.",
3200
+ "intentStatus": "complete",
3201
+ "intent": {
3202
+ "audience": "general",
3203
+ "status": "stable",
3204
+ "summary": "Form-associated single-value select with listbox semantics, local search, rich flat options, grouped sections, loading, clearing, and surface-aware trigger chrome.",
3205
+ "useWhen": [
3206
+ "The user must choose one value from a finite set.",
3207
+ "The option set benefits from local search, subtext, prefix icons, grouping, or disabled choices.",
3208
+ "The choice set has more than roughly 20 options, comes from a user-managed listing, or represents a large domain such as addresses where search materially improves retrieval.",
3209
+ "The selected value must participate in native, Angular, or React form state."
3210
+ ],
3211
+ "avoidWhen": [
3212
+ "Several values may be selected at once.",
3213
+ "The rows perform commands rather than choosing a form value.",
3214
+ "The choices form a hierarchy with expandable parents."
3215
+ ],
3216
+ "alternatives": [
3217
+ {
3218
+ "when": "Several independent values may be selected.",
3219
+ "component": "component:ds-select-multi",
3220
+ "reason": "SelectMulti owns array values, multi-selection semantics, and count presentation."
3221
+ },
3222
+ {
3223
+ "when": "The popup contains commands or state-changing actions.",
3224
+ "component": "component:ds-menu",
3225
+ "reason": "Menu uses action-menu roles and command-focused keyboard behavior."
3226
+ },
3227
+ {
3228
+ "when": "A small set of choices should remain visible.",
3229
+ "component": "component:ds-radio",
3230
+ "reason": "Prefer Radio for roughly two to five mutually exclusive choices when the available space allows all choices to remain visible."
3231
+ }
3232
+ ],
3233
+ "commonlyComposedWith": [
3234
+ "component:ds-text",
3235
+ "component:ds-icon",
3236
+ "component:ds-empty-state",
3237
+ "component:ds-loader"
3238
+ ],
3239
+ "accessibility": [
3240
+ "In forms, provide a persistent visible external field label; placeholder text is guidance and must not be the field's only label. In a compact filter bar, the trigger's visible text may supply the accessible name.",
3241
+ "The trigger uses combobox semantics and the popup uses listbox and option semantics; do not replace them with menu roles.",
3242
+ "Disabled options remain visible, expose aria-disabled, and are skipped by keyboard navigation and typeahead.",
3243
+ "Keyboard navigation keeps the aria-activedescendant option scrolled into the visible listbox viewport.",
3244
+ "Selected options rely on active fill and foreground treatment without a redundant trailing check icon.",
3245
+ "Local search moves focus into the search field while preserving the active option through aria-activedescendant.",
3246
+ "Use errorMessage with error so the trigger is described by the rendered alert."
3247
+ ],
3248
+ "states": [
3249
+ "Value is controlled through the mutable value property; dsChange reports user selection and clearing.",
3250
+ "Required Selects begin without an automatic selection and require the user to make an explicit choice; do not preselect the first option merely to satisfy validity.",
3251
+ "When allowClear is enabled, the clear affordance appears only after a value exists. Clearing is valid for optional and required fields; a required field becomes invalid until the user selects again.",
3252
+ "Clearing emits dsChange with an empty string and dsClear, keeps the popup open, and restores useful focus.",
3253
+ "Loading keeps the trigger visible, replaces its prefix icon, marks the control busy, and makes selection interaction temporarily unavailable without presenting the control as inactive.",
3254
+ "The trigger label stays left-aligned at every width. The default size is md in both forms and filter bars; smaller sizes require an explicit density need.",
3255
+ "Use option icons only when they help users differentiate choices. Icons render only when every option in the complete list provides one; mixed icon data falls back to the text-only row layout.",
3256
+ "Create sections only for categories that are meaningful to customers, not merely to break a long list into arbitrary chunks.",
3257
+ "When any option supplies subtext, every row uses the same subtext structure and missing values render an em dash. Subtext should disambiguate or add decision-helpful information.",
3258
+ "Option labels and the selected trigger label stay on one line and truncate when constrained. Option subtext may wrap to at most two lines.",
3259
+ "The optional prefix icon and chevron always use the parent surface's secondary foreground color, including when a selected value promotes the label to primary.",
3260
+ "The shared popup search control stays md at every trigger size, using body-medium text, a 20px icon, and the same internal spacing as a borderless Select trigger. Its container uses menu-item padding on every side and owns a 1px bottom divider that becomes a 1.5px bold-brand stroke while search has focus. Search placeholder text is secondary at rest and quaternary while focused because it becomes decorative once the editable field is active.",
3261
+ "When search contains text, the shared control shows a rounded sm icon-only ButtonUnfilled with the CrossCircle icon and no border. It clears the local term, stays hidden for an empty term, and returns focus to search.",
3262
+ "The shared clear footer mirrors the search region's sizing: menu-item padding surrounds an md-height borderless row, and the Clear label uses the same row and label insets as option text. The outer footer owns a 1px top divider.",
3263
+ "An empty filtered list composes the message-only body variant of EmptyState. Keep the default neutral no-results message unless localized product guidance makes the outcome clearer.",
3264
+ "Enable searchable for more than roughly 20 options, user-managed listings, large domains such as addresses, or sets users cannot efficiently scan. Local matching includes option labels, subtext, and section headings; the owner resolves remote data before assigning options.",
3265
+ "Validation timing belongs to the form owner and may be immediate or deferred until blur or submit; the Select exposes validity and error presentation without imposing that policy.",
3266
+ "The error trigger uses a 1.5px bold-negative inset stroke so invalid state remains distinguishable from the normal 1px border without changing control geometry.",
3267
+ "An initially empty option set is not an expected Select use case. The no-results state describes a search with no matches, not a source with no choices.",
3268
+ "Use options for a flat list or sections for grouped choices; when sections are present they take precedence.",
3269
+ "The background prop describes the actual parent surface and uses the same surface set as ButtonUnfilled."
3270
+ ],
3271
+ "responsiveBehavior": [
3272
+ "Use width fill for form fields and width hug for compact filter bars. Override those defaults only when the owning layout has a clear constraint.",
3273
+ "The popup matches the trigger minimum width, may grow for content, and clamps to the viewport.",
3274
+ "Long option collections scroll inside the popup; virtualization and remote search are not part of this component."
3275
+ ],
3276
+ "frameworkCaveats": {
3277
+ "customElements": [
3278
+ "Assign options and sections through JavaScript properties because arrays and objects cannot be represented safely as attributes."
3279
+ ],
3280
+ "react": [
3281
+ "Pass options or sections as wrapper props and handle onDsChange, onDsClear, and onDsOpenChange."
3282
+ ],
3283
+ "angular": [
3284
+ "Import DsSelect and SelectValueAccessor when integrating with Angular Forms; bind options and sections as properties."
3285
+ ]
3286
+ },
3287
+ "references": [
3288
+ {
3289
+ "label": "Storybook examples",
3290
+ "path": "src/wc/components/Select/Select.stories.ts"
3291
+ },
3292
+ {
3293
+ "label": "Selection patterns",
3294
+ "path": "src/docs/SelectionPatterns.mdx"
3295
+ }
3296
+ ]
3297
+ },
2738
3298
  "api": {
2739
3299
  "props": {
2740
3300
  "activeFill": {
2741
3301
  "type": "boolean",
2742
3302
  "required": false
2743
3303
  },
3304
+ "allowClear": {
3305
+ "type": "boolean",
3306
+ "required": false
3307
+ },
3308
+ "ariaDescribedby": {
3309
+ "type": "string | undefined",
3310
+ "required": false
3311
+ },
2744
3312
  "ariaLabel": {
2745
3313
  "type": "string | null",
2746
3314
  "required": false
@@ -2749,22 +3317,62 @@
2749
3317
  "type": "string | undefined",
2750
3318
  "required": false
2751
3319
  },
3320
+ "background": {
3321
+ "type": "SelectBackground | undefined",
3322
+ "required": false
3323
+ },
3324
+ "clearLabel": {
3325
+ "type": "string",
3326
+ "required": false
3327
+ },
2752
3328
  "disabled": {
2753
3329
  "type": "boolean",
2754
3330
  "required": false
2755
3331
  },
3332
+ "error": {
3333
+ "type": "boolean",
3334
+ "required": false
3335
+ },
3336
+ "errorMessage": {
3337
+ "type": "string | undefined",
3338
+ "required": false
3339
+ },
2756
3340
  "hasBorder": {
2757
3341
  "type": "boolean",
2758
3342
  "required": false
2759
3343
  },
3344
+ "icon": {
3345
+ "type": "string | undefined",
3346
+ "required": false
3347
+ },
3348
+ "inputId": {
3349
+ "type": "string | undefined",
3350
+ "required": false
3351
+ },
2760
3352
  "isInactive": {
2761
3353
  "type": "boolean",
2762
3354
  "required": false
2763
3355
  },
3356
+ "isLoading": {
3357
+ "type": "boolean",
3358
+ "required": false
3359
+ },
3360
+ "loadingLabel": {
3361
+ "type": "string",
3362
+ "required": false
3363
+ },
2764
3364
  "name": {
2765
3365
  "type": "string | undefined",
2766
3366
  "required": false
2767
3367
  },
3368
+ "noResultsText": {
3369
+ "type": "string",
3370
+ "required": false
3371
+ },
3372
+ "open": {
3373
+ "type": "boolean",
3374
+ "required": false
3375
+ },
2768
3376
  "options": {
2769
3377
  "type": "SelectOption[]",
2770
3378
  "required": false
@@ -2781,6 +3389,18 @@
2781
3389
  "type": "string",
2782
3390
  "required": false
2783
3391
  },
3392
+ "searchPlaceholder": {
3393
+ "type": "string",
3394
+ "required": false
3395
+ },
3396
+ "searchable": {
3397
+ "type": "boolean",
3398
+ "required": false
3399
+ },
3400
+ "sections": {
3401
+ "type": "SelectSection[]",
3402
+ "required": false
3403
+ },
2784
3404
  "size": {
2785
3405
  "type": "SelectSize",
2786
3406
  "required": false
@@ -2798,6 +3418,14 @@
2798
3418
  {
2799
3419
  "name": "dsChange",
2800
3420
  "detail": "string"
3421
+ },
3422
+ {
3423
+ "name": "dsClear",
3424
+ "detail": "void"
3425
+ },
3426
+ {
3427
+ "name": "dsOpenChange",
3428
+ "detail": "boolean"
2801
3429
  }
2802
3430
  ],
2803
3431
  "slots": []
@@ -2813,8 +3441,270 @@
2813
3441
  "@ds-mo/icons"
2814
3442
  ],
2815
3443
  "componentDependencies": [
3444
+ "button-unfilled",
3445
+ "empty-state",
2816
3446
  "icon",
2817
- "menu",
3447
+ "loader",
3448
+ "text"
3449
+ ]
3450
+ },
3451
+ {
3452
+ "id": "component:ds-select-multi",
3453
+ "tag": "ds-select-multi",
3454
+ "name": "select-multi",
3455
+ "title": "SelectMulti",
3456
+ "summary": "Form-associated multi-value select with a persistent trigger label, inline selected count, local search, rich flat options, grouped sections, loading, and clear-all behavior.",
3457
+ "intentStatus": "complete",
3458
+ "intent": {
3459
+ "audience": "general",
3460
+ "status": "stable",
3461
+ "summary": "Form-associated multi-value select with a persistent trigger label, inline selected count, local search, rich flat options, grouped sections, loading, and clear-all behavior.",
3462
+ "useWhen": [
3463
+ "The user may choose several independent values from one finite set.",
3464
+ "A compact trigger should summarize selection with the field label and a count.",
3465
+ "The option set benefits from local search, subtext, grouping, or disabled choices.",
3466
+ "The choice set has more than roughly 20 options, comes from a user-managed listing, or represents a large domain where search materially improves retrieval."
3467
+ ],
3468
+ "avoidWhen": [
3469
+ "Exactly one value may be selected.",
3470
+ "Selected values must remain individually removable as persistent tags outside the popup.",
3471
+ "The choices form a hierarchy with cascading parent selection.",
3472
+ "The customer task benefits more from keeping every choice and checkbox directly visible; choose between SelectMulti and a visible checkbox list from the use-case context rather than a fixed option-count threshold."
3473
+ ],
3474
+ "alternatives": [
3475
+ {
3476
+ "when": "Exactly one value may be selected.",
3477
+ "component": "component:ds-select",
3478
+ "reason": "Select owns scalar form value and single-select listbox behavior."
3479
+ },
3480
+ {
3481
+ "when": "The popup contains actions rather than values.",
3482
+ "component": "component:ds-menu",
3483
+ "reason": "Menu uses command semantics and closes according to action-menu expectations."
3484
+ }
3485
+ ],
3486
+ "commonlyComposedWith": [
3487
+ "component:ds-text",
3488
+ "component:ds-checkbox",
3489
+ "component:ds-empty-state",
3490
+ "component:ds-loader"
3491
+ ],
3492
+ "accessibility": [
3493
+ "In forms, provide a persistent visible external field label. In a compact filter bar, the trigger's visible persistent label and count may supply the accessible name.",
3494
+ "The popup is a listbox with aria-multiselectable and every option exposes its independent aria-selected state.",
3495
+ "Disabled options expose aria-disabled and are skipped by keyboard navigation and typeahead.",
3496
+ "Keyboard navigation keeps the aria-activedescendant option scrolled into the visible listbox viewport.",
3497
+ "Each row uses a medium-size presentation-only ds-checkbox indicator; multi-select option rows never add a prefix icon alongside it, and the option remains the sole selection semantic and interaction target.",
3498
+ "The trigger keeps its field label visible and appends the current selected count; an explicit aria-label or aria-labelledby remains the authoritative accessible name when supplied.",
3499
+ "Use errorMessage with error so the trigger is described by the rendered alert."
3500
+ ],
3501
+ "states": [
3502
+ "Values is a controlled JavaScript array; dsChange emits a new array after each user toggle.",
3503
+ "Required SelectMulti controls begin without an automatic selection and require the user to make an explicit choice.",
3504
+ "Selecting an option keeps the popup open so additional values can be toggled.",
3505
+ "The trigger label stays left-aligned at every width; every option row uses the same leading medium Checkbox indicator. The default control size is md in both forms and filter bars.",
3506
+ "The selected count always follows the persistent label as plain text separated by a centered dot, including for one selection, and counts every selected value even when search or grouping hides it. Never replace the count with selected option names.",
3507
+ "Create sections only for categories that are meaningful to customers, not merely to break a long list into arbitrary chunks.",
3508
+ "When any option supplies subtext, every row uses the same subtext structure and missing values render an em dash. Subtext should disambiguate or add decision-helpful information.",
3509
+ "Option labels stay on one line and truncate when constrained. Option subtext may wrap to at most two lines.",
3510
+ "The optional prefix icon and chevron always use the parent surface's secondary foreground color, including when selection promotes the label and count to primary.",
3511
+ "The shared popup search control stays md at every trigger size, using body-medium text, a 20px icon, and the same internal spacing as a borderless Select trigger. Its container uses menu-item padding on every side and owns a 1px bottom divider that becomes a 1.5px bold-brand stroke while search has focus. Search placeholder text is secondary at rest and quaternary while focused because it becomes decorative once the editable field is active.",
3512
+ "When search contains text, the shared control shows a rounded sm icon-only ButtonUnfilled with the Cross icon and no border. It clears the local term, stays hidden for an empty term, and returns focus to search.",
3513
+ "The shared summary-and-clear footer mirrors the search region's sizing: menu-item padding surrounds an md-height borderless row, and both texts use the same row and label insets as option text. The outer footer owns a 1px top divider.",
3514
+ "An empty filtered list composes the message-only body variant of EmptyState. Keep the default neutral no-results message unless localized product guidance makes the outcome clearer.",
3515
+ "Enable searchable for more than roughly 20 options, user-managed listings, large domains such as addresses, or sets users cannot efficiently scan. Local matching includes option labels, subtext, and section headings; the owner resolves remote data before assigning options.",
3516
+ "When allowClear is enabled, clear-all appears only after at least one value exists. Clearing is valid for optional and required fields; a required field becomes invalid until the user selects again.",
3517
+ "Clear-all emits an empty dsChange and dsClear while preserving useful popup or search focus.",
3518
+ "Loading keeps the trigger visible, marks the control busy, and makes selection interaction temporarily unavailable without presenting the control as inactive.",
3519
+ "SelectMulti has no maximum-selection behavior; every available non-inactive option may be selected.",
3520
+ "Validation timing belongs to the form owner and may be immediate or deferred until blur or submit; the component exposes validity and error presentation without imposing that policy.",
3521
+ "The error trigger uses a 1.5px bold-negative inset stroke so invalid state remains distinguishable from the normal 1px border without changing control geometry.",
3522
+ "An initially empty option set is not an expected SelectMulti use case. The no-results state describes a search with no matches, not a source with no choices.",
3523
+ "Native form submission emits one entry per selected value under the component name.",
3524
+ "Use options for a flat list or sections for grouped choices. Multi-select option contracts intentionally exclude icons because the leading checkbox owns that row zone; hierarchical parent selection is deferred."
3525
+ ],
3526
+ "responsiveBehavior": [
3527
+ "Use width fill for form fields and width hug for compact filter bars; the persistent trigger label avoids variable-width selected labels.",
3528
+ "The popup matches the trigger minimum width, may grow for content, and clamps to the viewport.",
3529
+ "Long option collections scroll inside the popup; virtualization and remote search are not part of this version."
3530
+ ],
3531
+ "frameworkCaveats": {
3532
+ "customElements": [
3533
+ "Assign values, options, and sections through JavaScript properties; array values cannot be represented safely as attributes."
3534
+ ],
3535
+ "react": [
3536
+ "Pass values, options, and sections as wrapper props and handle onDsChange, onDsClear, and onDsOpenChange."
3537
+ ],
3538
+ "angular": [
3539
+ "Import DsSelectMulti and SelectMultiValueAccessor when integrating with Angular Forms."
3540
+ ]
3541
+ },
3542
+ "references": [
3543
+ {
3544
+ "label": "Storybook examples",
3545
+ "path": "src/wc/components/SelectMulti/SelectMulti.stories.ts"
3546
+ },
3547
+ {
3548
+ "label": "Selection patterns",
3549
+ "path": "src/docs/SelectionPatterns.mdx"
3550
+ }
3551
+ ]
3552
+ },
3553
+ "api": {
3554
+ "props": {
3555
+ "activeFill": {
3556
+ "type": "boolean",
3557
+ "required": false
3558
+ },
3559
+ "allowClear": {
3560
+ "type": "boolean",
3561
+ "required": false
3562
+ },
3563
+ "ariaDescribedby": {
3564
+ "type": "string | undefined",
3565
+ "required": false
3566
+ },
3567
+ "ariaLabel": {
3568
+ "type": "string | null",
3569
+ "required": false
3570
+ },
3571
+ "ariaLabelledby": {
3572
+ "type": "string | undefined",
3573
+ "required": false
3574
+ },
3575
+ "background": {
3576
+ "type": "SelectMultiBackground | undefined",
3577
+ "required": false
3578
+ },
3579
+ "clearLabel": {
3580
+ "type": "string",
3581
+ "required": false
3582
+ },
3583
+ "disabled": {
3584
+ "type": "boolean",
3585
+ "required": false
3586
+ },
3587
+ "error": {
3588
+ "type": "boolean",
3589
+ "required": false
3590
+ },
3591
+ "errorMessage": {
3592
+ "type": "string | undefined",
3593
+ "required": false
3594
+ },
3595
+ "hasBorder": {
3596
+ "type": "boolean",
3597
+ "required": false
3598
+ },
3599
+ "icon": {
3600
+ "type": "string | undefined",
3601
+ "required": false
3602
+ },
3603
+ "inputId": {
3604
+ "type": "string | undefined",
3605
+ "required": false
3606
+ },
3607
+ "isInactive": {
3608
+ "type": "boolean",
3609
+ "required": false
3610
+ },
3611
+ "isLoading": {
3612
+ "type": "boolean",
3613
+ "required": false
3614
+ },
3615
+ "loadingLabel": {
3616
+ "type": "string",
3617
+ "required": false
3618
+ },
3619
+ "name": {
3620
+ "type": "string | undefined",
3621
+ "required": false
3622
+ },
3623
+ "noResultsText": {
3624
+ "type": "string",
3625
+ "required": false
3626
+ },
3627
+ "open": {
3628
+ "type": "boolean",
3629
+ "required": false
3630
+ },
3631
+ "options": {
3632
+ "type": "SelectMultiOption[]",
3633
+ "required": false
3634
+ },
3635
+ "placeholder": {
3636
+ "type": "string",
3637
+ "required": false
3638
+ },
3639
+ "required": {
3640
+ "type": "boolean",
3641
+ "required": false
3642
+ },
3643
+ "requiredMessage": {
3644
+ "type": "string",
3645
+ "required": false
3646
+ },
3647
+ "searchPlaceholder": {
3648
+ "type": "string",
3649
+ "required": false
3650
+ },
3651
+ "searchable": {
3652
+ "type": "boolean",
3653
+ "required": false
3654
+ },
3655
+ "sections": {
3656
+ "type": "SelectMultiSection[]",
3657
+ "required": false
3658
+ },
3659
+ "selectedLabel": {
3660
+ "type": "string",
3661
+ "required": false
3662
+ },
3663
+ "size": {
3664
+ "type": "SelectMultiSize",
3665
+ "required": false
3666
+ },
3667
+ "values": {
3668
+ "type": "string[]",
3669
+ "required": false
3670
+ },
3671
+ "width": {
3672
+ "type": "SelectMultiWidth",
3673
+ "required": false
3674
+ }
3675
+ },
3676
+ "events": [
3677
+ {
3678
+ "name": "dsChange",
3679
+ "detail": "string[]"
3680
+ },
3681
+ {
3682
+ "name": "dsClear",
3683
+ "detail": "void"
3684
+ },
3685
+ {
3686
+ "name": "dsOpenChange",
3687
+ "detail": "boolean"
3688
+ }
3689
+ ],
3690
+ "slots": []
3691
+ },
3692
+ "exports": {
3693
+ "customElement": "ds-select-multi",
3694
+ "react": "DsSelectMulti",
3695
+ "angular": "DsSelectMulti"
3696
+ },
3697
+ "dependencies": [
3698
+ "@ds-mo/ui",
3699
+ "@ds-mo/tokens",
3700
+ "@ds-mo/icons"
3701
+ ],
3702
+ "componentDependencies": [
3703
+ "button-unfilled",
3704
+ "checkbox",
3705
+ "empty-state",
3706
+ "icon",
3707
+ "loader",
2818
3708
  "text"
2819
3709
  ]
2820
3710
  },
@@ -3160,11 +4050,118 @@
3160
4050
  "tag": "ds-slider",
3161
4051
  "name": "slider",
3162
4052
  "title": "Slider",
3163
- "summary": "Range input with visual fill track, label, and current value display.",
3164
- "intentStatus": "migration-pending",
3165
- "intent": null,
4053
+ "summary": "Form-associated single or two-thumb range input with native slider semantics, pointer dragging, keyboard operation, formatting, density, and orientation controls.",
4054
+ "intentStatus": "complete",
4055
+ "intent": {
4056
+ "audience": "general",
4057
+ "status": "stable",
4058
+ "summary": "Form-associated single or two-thumb range input with native slider semantics, pointer dragging, keyboard operation, formatting, density, and orientation controls.",
4059
+ "useWhen": [
4060
+ "A person should choose or tune an approximate numeric value within known bounds.",
4061
+ "A bounded minimum and maximum range needs two independently focusable thumbs.",
4062
+ "A value benefits from direct manipulation, immediate preview, and native form submission."
4063
+ ],
4064
+ "avoidWhen": [
4065
+ "The exact numeric value is more important than direct spatial adjustment.",
4066
+ "The choices are categorical rather than ordered numeric values.",
4067
+ "The value is progress, measurement, or read-only status rather than user input."
4068
+ ],
4069
+ "alternatives": [
4070
+ {
4071
+ "when": "People must enter or verify a precise numeric value.",
4072
+ "component": "component:ds-input",
4073
+ "reason": "A typed field supports exact entry and review more efficiently than spatial adjustment."
4074
+ },
4075
+ {
4076
+ "when": "The available values are a short finite set with meaningful labels.",
4077
+ "component": "component:ds-radio",
4078
+ "reason": "Visible named choices communicate categorical meaning more clearly."
4079
+ },
4080
+ {
4081
+ "when": "The setting is binary and applies immediately.",
4082
+ "component": "component:ds-switch",
4083
+ "reason": "Switch communicates an immediate on/off state without implying intermediate values."
4084
+ }
4085
+ ],
4086
+ "commonlyComposedWith": [
4087
+ "component:ds-text",
4088
+ "component:ds-input"
4089
+ ],
4090
+ "accessibility": [
4091
+ "Each thumb contains a native range input and must have an accessible name; a visible label names a single thumb, while startLabel and endLabel distinguish a two-thumb range.",
4092
+ "Arrow keys adjust one step, Home and End reach the allowed bounds, and browser-supported Page Up and Page Down make larger changes.",
4093
+ "Every range thumb remains in a constant tab order and exposes dynamic minimum and maximum values when the other thumb constrains it.",
4094
+ "Use valueText for one authored description or valueTexts for per-thumb range descriptions when numeric values are not understandable on their own, such as named levels, dates, durations, or units.",
4095
+ "Read-only sliders remain focusable and submittable; inactive or disabled sliders leave the tab order and form submission."
4096
+ ],
4097
+ "states": [
4098
+ "value is mutable: user pointer, keyboard, or assistive-technology input updates it and emits dsChange continuously.",
4099
+ "dsCommit emits once a pointer interaction completes or the native range input commits a keyboard or assistive-technology change.",
4100
+ "Assign a two-number array through the JavaScript value property to create a range; values are ordered, clamped, stepped, and prevented from crossing.",
4101
+ "minStepsBetweenValues reserves a minimum stepped distance between range thumbs.",
4102
+ "The initial normalized value is the native form-reset baseline and range values submit as repeated entries under the same name.",
4103
+ "Focused, filled, dirty, touched, dragging, valid, disabled, read-only, and orientation data hooks expose interaction state without changing the value contract."
4104
+ ],
4105
+ "responsiveBehavior": [
4106
+ "Horizontal Slider fills the width supplied by its parent; the parent chooses an appropriate readable track length.",
4107
+ "Vertical Slider owns a token-based default length that may be overridden with --ds-slider-vertical-length in layout-specific compositions.",
4108
+ "Use md in ordinary forms and sm or xs only when the surrounding control density uses the same recipe.",
4109
+ "Track thickness scales with density: 8px at md, 6px at sm, and 4px at xs. The unfilled track is transparent with a tertiary-foreground inset outline, the filled range is brand, and the thumb uses a 1.5px brand inset ring.",
4110
+ "Horizontal value direction is left-to-right; the design system does not author RTL-specific component behavior."
4111
+ ],
4112
+ "frameworkCaveats": {
4113
+ "customElements": [
4114
+ "Assign range arrays and formatOptions through JavaScript properties, not string attributes.",
4115
+ "Listen for dsChange during adjustment and dsCommit for expensive work that should run after the interaction settles."
4116
+ ],
4117
+ "react": [
4118
+ "Use DsSlider with a number or two-number value array and handle onDsChange and onDsCommit custom events."
4119
+ ],
4120
+ "angular": [
4121
+ "Use DsSlider with property binding for range arrays; the generated number value accessor is appropriate only for a single numeric value."
4122
+ ]
4123
+ },
4124
+ "references": [
4125
+ {
4126
+ "label": "Storybook design review",
4127
+ "path": "src/wc/components/Slider/Slider.stories.ts"
4128
+ },
4129
+ {
4130
+ "label": "Cross-browser form and interaction coverage",
4131
+ "path": "tests/e2e/forms.spec.ts"
4132
+ }
4133
+ ]
4134
+ },
3166
4135
  "api": {
3167
4136
  "props": {
4137
+ "ariaDescribedby": {
4138
+ "type": "string | undefined",
4139
+ "required": false
4140
+ },
4141
+ "ariaLabel": {
4142
+ "type": "string | null",
4143
+ "required": false
4144
+ },
4145
+ "ariaLabelledby": {
4146
+ "type": "string | undefined",
4147
+ "required": false
4148
+ },
4149
+ "disabled": {
4150
+ "type": "boolean",
4151
+ "required": false
4152
+ },
4153
+ "endLabel": {
4154
+ "type": "string",
4155
+ "required": false
4156
+ },
4157
+ "form": {
4158
+ "type": "string | undefined",
4159
+ "required": false
4160
+ },
4161
+ "formatOptions": {
4162
+ "type": "Intl.NumberFormatOptions | undefined",
4163
+ "required": false
4164
+ },
3168
4165
  "inputId": {
3169
4166
  "type": "string | undefined",
3170
4167
  "required": false
@@ -3174,8 +4171,12 @@
3174
4171
  "required": false
3175
4172
  },
3176
4173
  "label": {
3177
- "type": "string",
3178
- "required": true
4174
+ "type": "string | undefined",
4175
+ "required": false
4176
+ },
4177
+ "locale": {
4178
+ "type": "string | undefined",
4179
+ "required": false
3179
4180
  },
3180
4181
  "max": {
3181
4182
  "type": "number",
@@ -3185,23 +4186,75 @@
3185
4186
  "type": "number",
3186
4187
  "required": false
3187
4188
  },
4189
+ "minStepsBetweenValues": {
4190
+ "type": "number",
4191
+ "required": false
4192
+ },
4193
+ "name": {
4194
+ "type": "string | undefined",
4195
+ "required": false
4196
+ },
4197
+ "orientation": {
4198
+ "type": "SliderOrientation",
4199
+ "required": false
4200
+ },
4201
+ "rangeSeparator": {
4202
+ "type": "string",
4203
+ "required": false
4204
+ },
4205
+ "readOnly": {
4206
+ "type": "boolean",
4207
+ "required": false
4208
+ },
4209
+ "showValue": {
4210
+ "type": "boolean",
4211
+ "required": false
4212
+ },
4213
+ "size": {
4214
+ "type": "SliderSize",
4215
+ "required": false
4216
+ },
4217
+ "startLabel": {
4218
+ "type": "string",
4219
+ "required": false
4220
+ },
3188
4221
  "step": {
3189
4222
  "type": "number",
3190
4223
  "required": false
3191
4224
  },
4225
+ "thumbAlignment": {
4226
+ "type": "SliderThumbAlignment",
4227
+ "required": false
4228
+ },
3192
4229
  "value": {
3193
- "type": "number",
4230
+ "type": "SliderValue",
4231
+ "required": false
4232
+ },
4233
+ "valuePrefix": {
4234
+ "type": "string",
4235
+ "required": false
4236
+ },
4237
+ "valueSuffix": {
4238
+ "type": "string",
3194
4239
  "required": false
3195
4240
  },
3196
4241
  "valueText": {
3197
4242
  "type": "string | undefined",
3198
4243
  "required": false
4244
+ },
4245
+ "valueTexts": {
4246
+ "type": "string[]",
4247
+ "required": false
3199
4248
  }
3200
4249
  },
3201
4250
  "events": [
3202
4251
  {
3203
4252
  "name": "dsChange",
3204
- "detail": "number"
4253
+ "detail": "SliderValue"
4254
+ },
4255
+ {
4256
+ "name": "dsCommit",
4257
+ "detail": "SliderValue"
3205
4258
  }
3206
4259
  ],
3207
4260
  "slots": []
@@ -3248,8 +4301,8 @@
3248
4301
  },
3249
4302
  {
3250
4303
  "when": "The user must choose one option from a mutually exclusive group.",
3251
- "component": "component:ds-radio-group",
3252
- "reason": "RadioGroup communicates one-of-many selection."
4304
+ "component": "component:ds-radio",
4305
+ "reason": "Radio communicates one-of-many selection."
3253
4306
  },
3254
4307
  {
3255
4308
  "when": "The control triggers a one-time command or submission.",
@@ -3266,17 +4319,20 @@
3266
4319
  "Every standalone switch requires an accessible name from a native label, aria-label, or aria-labelledby.",
3267
4320
  "Checked state is exposed through switch semantics and thumb position, so state does not rely on color alone.",
3268
4321
  "Read-only switches remain focusable and submitted but cannot change; inactive or disabled switches leave the tab order and are omitted from form submission.",
4322
+ "Required and invalid state are exposed explicitly on the switch role; focused, filled, dirty, touched, valid, and invalid data hooks support form diagnostics without imposing visual validation timing.",
3269
4323
  "Use presentation mode only when a composite owner such as a menuitemcheckbox provides the interaction and accessible state."
3270
4324
  ],
3271
4325
  "states": [
3272
4326
  "Activation updates checked immediately and emits dsChange with the new boolean value.",
3273
4327
  "The initial checked value is the form-reset baseline; unchecked switches submit nothing unless uncheckedValue is provided.",
3274
- "Sizes are md 36×24 with a 16px thumb and 4px body inset, sm 24×16 with a 12px thumb and 2px inset, and xs 12×8 with a 6px thumb and 1px inset.",
4328
+ "Sizes are md 32×20 with a 12px thumb and 4px body inset, sm 24×16 with a 10px thumb and 3px inset, and xs 20×12 with an 8px thumb and 2px inset.",
4329
+ "Unchecked track and thumb are transparent and each uses a tertiary-foreground inset stroke: 1.25px at md, 1px at sm, and 0.75px at xs. Checked uses a brand track and primary-background thumb with both strokes removed.",
3275
4330
  "Presentation mode removes switch semantics, focus, interaction, and form submission while retaining the checked visual."
3276
4331
  ],
3277
4332
  "responsiveBehavior": [
3278
4333
  "Choose size from the density of the containing row; do not enlarge the switch to the full control height.",
3279
- "Keep the switch from shrinking when adjacent labels wrap."
4334
+ "Keep the switch from shrinking when adjacent labels wrap.",
4335
+ "Thumb movement is left-to-right; the design system does not author RTL-specific component behavior."
3280
4336
  ],
3281
4337
  "frameworkCaveats": {
3282
4338
  "customElements": [
@@ -3804,15 +4860,17 @@
3804
4860
  "Visible content and the selected native element provide accessible meaning; avoid redundant roles and labels.",
3805
4861
  "Use label semantics and its for association only for a real form control.",
3806
4862
  "When truncating essential content, the owner provides an accessible way to obtain the omitted text.",
3807
- "Use solid underline only when Text is composed inside a real link.",
3808
- "Use dotted underline to signal hidden or supplemental interaction such as a tooltip; the owning trigger must provide focus, keyboard interaction, and accessible tooltip semantics."
4863
+ "Tertiary and quaternary foregrounds are restricted to text inside genuinely inactive or disabled UI, or to purely decorative content whose removal would not change meaning; quaternary is the fainter tier, and aria-hidden alone does not exempt meaningful visible text from contrast requirements.",
4864
+ "Underline link text by default. Brand-blue links may omit the resting underline when color already supplies the affordance.",
4865
+ "Use dotted underline for hidden or supplemental interaction such as a tooltip; the owning trigger must provide focus, keyboard interaction, and accessible tooltip semantics."
3809
4866
  ],
3810
4867
  "states": [
3811
4868
  "A variant is atomic: font size, line height, weight, and letter spacing stay together and are not overridden by consumers.",
3812
4869
  "Emphasis selects the supported stronger recipe for local hierarchy; it does not independently mean selected or active.",
3813
4870
  "Omitted color inherits currentColor. Explicit semantic aliases or CSS-variable references are used only when Text has an independent color role.",
4871
+ "Prefer the owning control's isInactive or native disabled state over manually selecting tertiary or quaternary so visual treatment and inactive semantics remain synchronized.",
3814
4872
  "Line truncation and wrapping require an owner-supplied width constraint and content-aware composition decision.",
3815
- "Solid underline communicates a real link; dotted underline communicates hidden or supplemental interaction such as a tooltip. Decoration does not make Text interactive by itself.",
4873
+ "Solid underline is the default link affordance; brand-blue links may omit it at rest. Dotted underline communicates hidden or supplemental interaction such as a tooltip. Decoration does not make Text interactive by itself.",
3816
4874
  "Tabular numbers are for changing numeric values or aligned numeric columns where stable glyph width matters.",
3817
4875
  "Shimmer is reserved for visible generating/loading status text whose owner provides status semantics; reduced motion keeps static readable text."
3818
4876
  ],