@ds-mo/ui 12.6.2 → 12.7.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.
- package/README.md +44 -115
- package/dist/.build-stamp +1 -1
- package/dist/agent-patterns.json +5 -3
- package/dist/agent.json +56 -32
- package/dist/angular/ds-menu.d.ts +1 -1
- package/dist/angular/ds-menu.js +3 -3
- package/dist/components/ds-agent-activity.js +1 -1
- package/dist/components/ds-agent-response.js +1 -1
- package/dist/components/ds-agent-source-list.js +1 -1
- package/dist/components/ds-agent-tool-call.js +1 -1
- package/dist/components/ds-attachment-list.js +1 -1
- package/dist/components/ds-badge.js +1 -1
- package/dist/components/ds-bar-nav.js +1 -1
- package/dist/components/ds-bar-nav.js.map +1 -1
- package/dist/components/ds-bar-title.js +1 -1
- package/dist/components/ds-bar-title.js.map +1 -1
- package/dist/components/ds-bar-workflow.js +1 -1
- package/dist/components/ds-bar-workflow.js.map +1 -1
- package/dist/components/ds-breadcrumb.js +1 -1
- package/dist/components/ds-button-filled.js +1 -1
- package/dist/components/ds-button-unfilled.js +1 -1
- package/dist/components/ds-card-data-viz-bar.js +1 -1
- package/dist/components/ds-card-data-viz-bar.js.map +1 -1
- package/dist/components/ds-card-data-viz-donut.js +1 -1
- package/dist/components/ds-card-data-viz-donut.js.map +1 -1
- package/dist/components/ds-card-data-viz-line.js +1 -1
- package/dist/components/ds-card-data-viz-line.js.map +1 -1
- package/dist/components/ds-card-setting.js +1 -1
- package/dist/components/ds-card-setting.js.map +1 -1
- package/dist/components/ds-card-shell-data-viz.js +1 -1
- package/dist/components/ds-chart-bar.js +1 -1
- package/dist/components/ds-chart-donut.js +1 -1
- package/dist/components/ds-chart-legend.js +1 -1
- package/dist/components/ds-chart-line.js +1 -1
- package/dist/components/ds-checkbox.js +1 -1
- package/dist/components/ds-chip.js +1 -1
- package/dist/components/ds-code-block.js +1 -1
- package/dist/components/ds-conversation-list-item.js +1 -1
- package/dist/components/ds-conversation-list-item.js.map +1 -1
- package/dist/components/ds-conversation-list-section.js +1 -1
- package/dist/components/ds-conversation-list.js +1 -1
- package/dist/components/ds-conversation-list.js.map +1 -1
- package/dist/components/ds-empty-state.js +1 -1
- package/dist/components/ds-field.js +1 -1
- package/dist/components/ds-field.js.map +1 -1
- package/dist/components/ds-input.js +1 -1
- package/dist/components/ds-input.js.map +1 -1
- package/dist/components/ds-markdown.js +1 -1
- package/dist/components/ds-menu.js +1 -1
- package/dist/components/ds-message-composer.js +1 -1
- package/dist/components/ds-message-composer.js.map +1 -1
- package/dist/components/ds-message-scroller.js +1 -1
- package/dist/components/ds-message-scroller.js.map +1 -1
- package/dist/components/ds-message.js +1 -1
- package/dist/components/ds-mobile-bar-nav.js +1 -1
- package/dist/components/ds-mobile-bar-nav.js.map +1 -1
- package/dist/components/ds-mobile-header.js +1 -1
- package/dist/components/ds-mobile-section-switcher.js +1 -1
- package/dist/components/ds-mobile-sheet-nav.js +1 -1
- package/dist/components/ds-mobile-sheet-nav.js.map +1 -1
- package/dist/components/ds-modal.js +1 -1
- package/dist/components/ds-modal.js.map +1 -1
- package/dist/components/ds-panel-nav.js +1 -1
- package/dist/components/ds-panel-nav.js.map +1 -1
- package/dist/components/ds-panel-sub-nav.js +1 -1
- package/dist/components/ds-panel-tool-header.js +1 -1
- package/dist/components/ds-panel-tool-search.js +1 -1
- package/dist/components/ds-panel-tool-search.js.map +1 -1
- package/dist/components/ds-panel-tools.js +1 -1
- package/dist/components/ds-radio.js +1 -1
- package/dist/components/ds-radio.js.map +1 -1
- package/dist/components/ds-scroll-overlay.js +1 -1
- package/dist/components/ds-scroll-overlay.js.map +1 -1
- package/dist/components/ds-select-multi.js +1 -1
- package/dist/components/ds-select-multi.js.map +1 -1
- package/dist/components/ds-select.js +1 -1
- package/dist/components/ds-select.js.map +1 -1
- package/dist/components/ds-shell-app.js +1 -1
- package/dist/components/ds-shell-app.js.map +1 -1
- package/dist/components/ds-shell-gradient-picker.js +1 -1
- package/dist/components/ds-shell-gradient-picker.js.map +1 -1
- package/dist/components/ds-shell-gradient-swatch.js +1 -1
- package/dist/components/ds-shell-page.js +1 -1
- package/dist/components/ds-shell-tools.js +1 -1
- package/dist/components/ds-shell-tools.js.map +1 -1
- package/dist/components/ds-skeleton.js +1 -1
- package/dist/components/ds-slider.js +1 -1
- package/dist/components/ds-slider.js.map +1 -1
- package/dist/components/ds-swatch-picker.js +1 -1
- package/dist/components/ds-switch.js +1 -1
- package/dist/components/ds-tab-group.js +1 -1
- package/dist/components/ds-tag.js +1 -1
- package/dist/components/ds-text.js +1 -1
- package/dist/components/ds-toast.js +1 -1
- package/dist/components/ds-tooltip-data-viz.js +1 -1
- package/dist/components/ds-tooltip.js +1 -1
- package/dist/components/ds-typing-indicator.js +1 -1
- package/dist/components/{p-DwX7UmLl.js → p--eKXTylf.js} +2 -2
- package/dist/components/p-1darPzys.js +2 -0
- package/dist/components/{p-DXLWm4PF.js.map → p-1darPzys.js.map} +1 -1
- package/dist/components/{p-DIoiApa-.js → p-5-QAFB4j.js} +2 -2
- package/dist/components/{p-D-xttdpn.js → p-B-9A0e_0.js} +2 -2
- package/dist/components/{p-CaRyxTMz.js → p-BT5hgg5i.js} +2 -2
- package/dist/components/{p-DQDpDYyF.js → p-B_5nxOeB.js} +2 -2
- package/dist/components/p-BcfC6phQ.js +2 -0
- package/dist/components/p-BcfC6phQ.js.map +1 -0
- package/dist/components/{p-BkAMkjIR.js → p-Bl001G0Y.js} +2 -2
- package/dist/components/p-BuiZcSga.js +2 -0
- package/dist/components/p-BuiZcSga.js.map +1 -0
- package/dist/components/p-Bv9frkvW.js +2 -0
- package/dist/components/p-Bv9frkvW.js.map +1 -0
- package/dist/components/{p-DWdRSOBV.js → p-C0-K8vnW.js} +2 -2
- package/dist/components/p-C61yJkfr.js +2 -0
- package/dist/components/p-C61yJkfr.js.map +1 -0
- package/dist/components/p-C6xC48hG.js +2 -0
- package/dist/components/p-C6xC48hG.js.map +1 -0
- package/dist/components/p-C9h13YnX.js +2 -0
- package/dist/components/{p-CnHrJTD5.js → p-CUAYsK44.js} +2 -2
- package/dist/components/p-C_9ZH0A3.js +2 -0
- package/dist/components/p-C_9ZH0A3.js.map +1 -0
- package/dist/components/p-Ca9-fnFl.js +2 -0
- package/dist/components/p-Ca9-fnFl.js.map +1 -0
- package/dist/components/p-CnAkobDW.js +2 -0
- package/dist/components/p-CnAkobDW.js.map +1 -0
- package/dist/components/{p-CWTih3Gc.js → p-CqWV4Hl_.js} +2 -2
- package/dist/components/{p-B9bxDfZV.js → p-Crsn82rz.js} +2 -2
- package/dist/components/p-CuwopElg.js +2 -0
- package/dist/components/p-CuwopElg.js.map +1 -0
- package/dist/components/{p-BwsGYxZx.js → p-CvyTZ4Mg.js} +2 -2
- package/dist/components/p-DIa73GJP.js +2 -0
- package/dist/components/p-DIa73GJP.js.map +1 -0
- package/dist/components/{p-DqubRds2.js → p-DNFd4Ao-.js} +2 -2
- package/dist/components/p-De7NquTI.js +2 -0
- package/dist/components/p-De7NquTI.js.map +1 -0
- package/dist/components/p-DjbTFy2B.js +2 -0
- package/dist/components/p-DjbTFy2B.js.map +1 -0
- package/dist/components/p-guQ7hv6W.js +2 -0
- package/dist/components/p-guQ7hv6W.js.map +1 -0
- package/dist/components/{p-BwGnhInj.js → p-k0Hmj1KV.js} +2 -2
- package/dist/components/p-pgxlkvUy.js +2 -0
- package/dist/docs/components.json +110 -25
- package/dist/lib/utils/control-text.d.ts +3 -1
- package/dist/lib/utils/index.d.ts +1 -1
- package/dist/lib/utils/index.js +8 -0
- package/dist/lib/utils/index.js.map +2 -2
- package/dist/mcp-data/registry/bar-nav.json +2 -2
- package/dist/mcp-data/registry/bar-title.json +2 -2
- package/dist/mcp-data/registry/bar-workflow.json +2 -2
- package/dist/mcp-data/registry/button-filled.json +5 -4
- package/dist/mcp-data/registry/button-unfilled.json +3 -2
- package/dist/mcp-data/registry/card-data-viz-bar.json +3 -2
- package/dist/mcp-data/registry/card-data-viz-donut.json +3 -2
- package/dist/mcp-data/registry/card-data-viz-line.json +3 -2
- package/dist/mcp-data/registry/card-setting.json +2 -2
- package/dist/mcp-data/registry/card-shell-data-viz.json +2 -2
- package/dist/mcp-data/registry/checkbox.json +9 -9
- package/dist/mcp-data/registry/conversation-list-item.json +2 -2
- package/dist/mcp-data/registry/conversation-list.json +2 -2
- package/dist/mcp-data/registry/empty-state.json +5 -1
- package/dist/mcp-data/registry/field.json +3 -2
- package/dist/mcp-data/registry/input.json +8 -7
- package/dist/mcp-data/registry/menu.json +22 -3
- package/dist/mcp-data/registry/message-scroller.json +2 -2
- package/dist/mcp-data/registry/mobile-bar-nav.json +3 -3
- package/dist/mcp-data/registry/mobile-header.json +2 -2
- package/dist/mcp-data/registry/mobile-sheet-nav.json +5 -3
- package/dist/mcp-data/registry/modal.json +2 -2
- package/dist/mcp-data/registry/panel-nav.json +2 -2
- package/dist/mcp-data/registry/panel-tool-header.json +2 -2
- package/dist/mcp-data/registry/panel-tool-search.json +2 -2
- package/dist/mcp-data/registry/panel-tools.json +2 -2
- package/dist/mcp-data/registry/radio.json +9 -9
- package/dist/mcp-data/registry/registry.json +55 -31
- package/dist/mcp-data/registry/select-multi.json +9 -7
- package/dist/mcp-data/registry/select.json +9 -7
- package/dist/mcp-data/registry/shell-app.json +2 -1
- package/dist/mcp-data/registry/shell-tools.json +1 -1
- package/dist/mcp-data/registry/skeleton.json +2 -2
- package/dist/mcp-data/registry/slider.json +3 -2
- package/dist/mcp-data/registry/switch.json +7 -7
- package/dist/styles/control-elevation.css +27 -2
- package/dist/types/components/ButtonFilled/ButtonFilled.d.ts +1 -1
- package/dist/types/components/Checkbox/Checkbox.d.ts +1 -1
- package/dist/types/components/Input/Input.d.ts +1 -1
- package/dist/types/components/Menu/Menu.d.ts +4 -1
- package/dist/types/components/MobileSheetNav/MobileSheetNav.d.ts +0 -1
- package/dist/types/components/Radio/Radio.d.ts +1 -1
- package/dist/types/components/Select/Select.d.ts +6 -23
- package/dist/types/components/SelectMulti/SelectMulti.d.ts +5 -20
- package/dist/types/components/ShellTools/ShellTools.d.ts +1 -0
- package/dist/types/components/Switch/Switch.d.ts +1 -1
- package/dist/types/components.d.ts +13 -2
- package/dist/types/utils/choice-list-parts.d.ts +4 -0
- package/dist/types/utils/control-press.d.ts +9 -0
- package/dist/types/utils/control-text.d.ts +3 -1
- package/dist/types/utils/index.d.ts +1 -1
- package/dist/types/utils/select-controller.d.ts +67 -0
- package/package.json +1 -1
- package/dist/components/p-B9xVWER6.js +0 -2
- package/dist/components/p-B9xVWER6.js.map +0 -1
- package/dist/components/p-BLea0TrP.js +0 -2
- package/dist/components/p-BLea0TrP.js.map +0 -1
- package/dist/components/p-BY0PzkUp.js +0 -2
- package/dist/components/p-BbgPGF2a.js +0 -2
- package/dist/components/p-BbgPGF2a.js.map +0 -1
- package/dist/components/p-BhC1YyId.js +0 -2
- package/dist/components/p-BhC1YyId.js.map +0 -1
- package/dist/components/p-Ccj5Op6E.js +0 -2
- package/dist/components/p-CiqnkENu.js +0 -2
- package/dist/components/p-CiqnkENu.js.map +0 -1
- package/dist/components/p-Cx-ywr1e.js +0 -2
- package/dist/components/p-Cx-ywr1e.js.map +0 -1
- package/dist/components/p-DPME1wUJ.js +0 -2
- package/dist/components/p-DPME1wUJ.js.map +0 -1
- package/dist/components/p-DSa0Hnd3.js +0 -2
- package/dist/components/p-DSa0Hnd3.js.map +0 -1
- package/dist/components/p-DUlqUNbE.js +0 -2
- package/dist/components/p-DUlqUNbE.js.map +0 -1
- package/dist/components/p-DXLWm4PF.js +0 -2
- package/dist/components/p-DYcC5-R9.js +0 -2
- package/dist/components/p-DYcC5-R9.js.map +0 -1
- package/dist/components/p-DbpfpeQT.js +0 -2
- package/dist/components/p-DbpfpeQT.js.map +0 -1
- package/dist/components/p-DuFm-ieS.js +0 -2
- package/dist/components/p-DuFm-ieS.js.map +0 -1
- package/dist/components/p-uQhuDEVt.js +0 -2
- package/dist/components/p-uQhuDEVt.js.map +0 -1
- /package/dist/components/{p-DwX7UmLl.js.map → p--eKXTylf.js.map} +0 -0
- /package/dist/components/{p-DIoiApa-.js.map → p-5-QAFB4j.js.map} +0 -0
- /package/dist/components/{p-D-xttdpn.js.map → p-B-9A0e_0.js.map} +0 -0
- /package/dist/components/{p-CaRyxTMz.js.map → p-BT5hgg5i.js.map} +0 -0
- /package/dist/components/{p-DQDpDYyF.js.map → p-B_5nxOeB.js.map} +0 -0
- /package/dist/components/{p-BkAMkjIR.js.map → p-Bl001G0Y.js.map} +0 -0
- /package/dist/components/{p-DWdRSOBV.js.map → p-C0-K8vnW.js.map} +0 -0
- /package/dist/components/{p-Ccj5Op6E.js.map → p-C9h13YnX.js.map} +0 -0
- /package/dist/components/{p-CnHrJTD5.js.map → p-CUAYsK44.js.map} +0 -0
- /package/dist/components/{p-CWTih3Gc.js.map → p-CqWV4Hl_.js.map} +0 -0
- /package/dist/components/{p-B9bxDfZV.js.map → p-Crsn82rz.js.map} +0 -0
- /package/dist/components/{p-BwsGYxZx.js.map → p-CvyTZ4Mg.js.map} +0 -0
- /package/dist/components/{p-DqubRds2.js.map → p-DNFd4Ao-.js.map} +0 -0
- /package/dist/components/{p-BwGnhInj.js.map → p-k0Hmj1KV.js.map} +0 -0
- /package/dist/components/{p-BY0PzkUp.js.map → p-pgxlkvUy.js.map} +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
3
|
"name": "radio",
|
|
4
4
|
"title": "Radio",
|
|
5
|
-
"description": "Form-associated one-of-many radio selection set with vertical or horizontal layout,
|
|
5
|
+
"description": "Form-associated one-of-many radio selection set with vertical or horizontal layout, four densities, per-option inactive state, and roving keyboard focus.",
|
|
6
6
|
"type": "registry:ui",
|
|
7
7
|
"meta": {
|
|
8
8
|
"library": "@ds-mo/ui",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"intent": {
|
|
14
14
|
"audience": "general",
|
|
15
15
|
"status": "stable",
|
|
16
|
-
"summary": "Form-associated one-of-many radio selection set with vertical or horizontal layout,
|
|
16
|
+
"summary": "Form-associated one-of-many radio selection set with vertical or horizontal layout, four densities, per-option inactive state, and roving keyboard focus.",
|
|
17
17
|
"useWhen": [
|
|
18
18
|
"A user must select exactly one visible option from a small set.",
|
|
19
19
|
"All available choices should remain visible for comparison.",
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
"Roving tabindex keeps one active option in the tab order, preferring the selected option."
|
|
53
53
|
],
|
|
54
54
|
"states": [
|
|
55
|
-
"Unchecked circles use a tertiary-foreground inset stroke: 1.25px at md, 1px at sm, and 0.75px at xs.",
|
|
56
|
-
"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.",
|
|
57
|
-
"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.",
|
|
55
|
+
"Unchecked circles use a tertiary-foreground inset stroke: 1.5px at lg, 1.25px at md, 1px at sm, and 0.75px at xs.",
|
|
56
|
+
"Selected circles remove the border, use a brand fill, and draw a centered on-bold foreground dot sized 10px at lg, 8px at md, 6px at sm, and 4px at xs.",
|
|
57
|
+
"Sizes are lg with a 20px circle in a 24px placement, 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.",
|
|
58
58
|
"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."
|
|
59
59
|
],
|
|
60
60
|
"responsiveBehavior": [
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
},
|
|
175
175
|
"size": {
|
|
176
176
|
"type": "RadioSize",
|
|
177
|
-
"resolvedType": "\"md\" | \"sm\" | \"xs\"",
|
|
177
|
+
"resolvedType": "\"lg\" | \"md\" | \"sm\" | \"xs\"",
|
|
178
178
|
"attribute": "size",
|
|
179
179
|
"default": "'md'",
|
|
180
180
|
"required": false,
|
|
@@ -293,7 +293,7 @@
|
|
|
293
293
|
},
|
|
294
294
|
"size": {
|
|
295
295
|
"type": "RadioSize",
|
|
296
|
-
"resolvedType": "\"md\" | \"sm\" | \"xs\"",
|
|
296
|
+
"resolvedType": "\"lg\" | \"md\" | \"sm\" | \"xs\"",
|
|
297
297
|
"attribute": "size",
|
|
298
298
|
"default": "'md'",
|
|
299
299
|
"required": false,
|
|
@@ -362,12 +362,12 @@
|
|
|
362
362
|
"files": [
|
|
363
363
|
{
|
|
364
364
|
"path": "src/wc/components/Radio/Radio.css",
|
|
365
|
-
"content": "@import '../../utils/control-inactive.css';\n@import '../../utils/control-density.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/interaction-fill.css';\n\n:host {\n display: flex;\n flex-direction: column;\n gap: var(--dimension-space-025);\n}\n\n:host(.radio--horizontal) {\n flex-direction: row;\n gap: var(--dimension-space-100);\n}\n\n:host(.radio--md) {\n --_radio-circle: var(--dimension-iconography-sm);\n --_radio-dot: var(--dimension-size-100);\n --_radio-stroke: var(--dimension-stroke-width-015);\n}\n\n:host(.radio--sm) {\n --_radio-circle: var(--dimension-iconography-xs);\n --_radio-dot: var(--dimension-size-075);\n --_radio-stroke: var(--dimension-stroke-width-012);\n}\n\n:host(.radio--xs) {\n --_radio-circle: var(--dimension-size-100);\n --_radio-dot: var(--dimension-size-050);\n --_radio-stroke: calc(var(--dimension-stroke-width-base) * 3 / 32);\n}\n\n.radio__item {\n display: inline-flex;\n align-items: center;\n box-sizing: border-box;\n gap: var(--ds-control-gap);\n height: var(--ds-control-height);\n padding: 0 var(--ds-control-padding-inline);\n border-radius: var(--ds-control-radius);\n cursor: default;\n user-select: none;\n}\n\n.radio__placement {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--ds-control-icon);\n height: var(--ds-control-icon);\n}\n\n.radio__circle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: var(--_radio-circle);\n height: var(--_radio-circle);\n border: 0;\n border-radius: var(--dimension-radius-half);\n box-shadow: inset 0 0 0 var(--_radio-stroke) var(--color-foreground-tertiary);\n transition:\n background-color var(--effect-motion-short-2),\n box-shadow var(--effect-motion-short-2);\n}\n\n.radio__circle--checked {\n background-color: var(--color-background-bold-brand);\n box-shadow: none;\n}\n\n.radio__dot {\n width: var(--_radio-dot);\n height: var(--_radio-dot);\n border-radius: var(--dimension-radius-half);\n background-color: var(--color-foreground-on-bold-background-primary);\n}\n\n.radio__label {\n flex: 1;\n min-width: 0;\n padding: 0 var(--ds-control-label-inset);\n}\n",
|
|
365
|
+
"content": "@import '../../utils/control-inactive.css';\n@import '../../utils/control-density.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/interaction-fill.css';\n\n:host {\n display: flex;\n flex-direction: column;\n gap: var(--dimension-space-025);\n}\n\n:host(.radio--horizontal) {\n flex-direction: row;\n gap: var(--dimension-space-100);\n}\n\n:host(.radio--lg) {\n --_radio-circle: var(--dimension-iconography-md);\n --_radio-dot: calc(var(--dimension-size-base) * 5 / 4);\n --_radio-stroke: var(--dimension-stroke-width-018);\n}\n\n:host(.radio--md) {\n --_radio-circle: var(--dimension-iconography-sm);\n --_radio-dot: var(--dimension-size-100);\n --_radio-stroke: var(--dimension-stroke-width-015);\n}\n\n:host(.radio--sm) {\n --_radio-circle: var(--dimension-iconography-xs);\n --_radio-dot: var(--dimension-size-075);\n --_radio-stroke: var(--dimension-stroke-width-012);\n}\n\n:host(.radio--xs) {\n --_radio-circle: var(--dimension-size-100);\n --_radio-dot: var(--dimension-size-050);\n --_radio-stroke: calc(var(--dimension-stroke-width-base) * 3 / 32);\n}\n\n.radio__item {\n display: inline-flex;\n align-items: center;\n box-sizing: border-box;\n gap: var(--ds-control-gap);\n height: var(--ds-control-height);\n padding: 0 var(--ds-control-padding-inline);\n border-radius: var(--ds-control-radius);\n cursor: default;\n user-select: none;\n}\n\n.radio__placement {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--ds-control-icon);\n height: var(--ds-control-icon);\n}\n\n.radio__circle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: var(--_radio-circle);\n height: var(--_radio-circle);\n border: 0;\n border-radius: var(--dimension-radius-half);\n box-shadow: inset 0 0 0 var(--_radio-stroke) var(--color-foreground-tertiary);\n transition:\n background-color var(--effect-motion-short-2),\n box-shadow var(--effect-motion-short-2);\n}\n\n.radio__circle--checked {\n background-color: var(--color-background-bold-brand);\n box-shadow: none;\n}\n\n.radio__dot {\n width: var(--_radio-dot);\n height: var(--_radio-dot);\n border-radius: var(--dimension-radius-half);\n background-color: var(--color-foreground-on-bold-background-primary);\n}\n\n.radio__label {\n flex: 1;\n min-width: 0;\n padding: 0 var(--ds-control-label-inset);\n}\n",
|
|
366
366
|
"type": "registry:ui"
|
|
367
367
|
},
|
|
368
368
|
{
|
|
369
369
|
"path": "src/wc/components/Radio/Radio.tsx",
|
|
370
|
-
"content": "import { AttachInternals, Component, Prop, State, Event, EventEmitter, Element, Listen, Watch, h, Host } from '@stencil/core';\nimport { DEFAULT_REQUIRED_MESSAGE, setRequiredValidity } from '../../utils';\n\nexport interface RadioOption {\n label: string;\n value: string;\n isInactive?: boolean;\n}\n\nexport type RadioSize = '
|
|
370
|
+
"content": "import { AttachInternals, Component, Prop, State, Event, EventEmitter, Element, Listen, Watch, h, Host } from '@stencil/core';\nimport { CONTROL_TEXT_VARIANT, DEFAULT_REQUIRED_MESSAGE, setRequiredValidity } from '../../utils';\n\nexport interface RadioOption {\n label: string;\n value: string;\n isInactive?: boolean;\n}\n\nexport type RadioSize = 'lg' | 'md' | 'sm' | 'xs';\n\n@Component({\n tag: 'ds-radio',\n styleUrl: 'Radio.css',\n scoped: true,\n formAssociated: true,\n})\nexport class Radio {\n @Element() el!: HTMLElement;\n @AttachInternals() internals!: ElementInternals;\n\n /** Visible choices in this one-of-many set. */\n @Prop() options: RadioOption[] = [];\n /** Selected option value. */\n @Prop({ mutable: true }) value: string = '';\n /** Visual and placement density for every option. */\n @Prop() size: RadioSize = 'md';\n /** Native form field name. */\n @Prop({ reflect: true }) name: string | undefined;\n /** Associates the radio set with a form by id when rendered outside that form. */\n @Prop({ reflect: true }) form: string | undefined;\n /** Native disabled state for the complete set. */\n @Prop({ reflect: true }) disabled: boolean = false;\n /** Require one option to be selected for form validity. */\n @Prop({ reflect: true }) required: boolean = false;\n /** Validation message used when a required set has no selection. */\n @Prop() requiredMessage: string = DEFAULT_REQUIRED_MESSAGE;\n /** Layout direction for the option set. */\n @Prop() direction: 'vertical' | 'horizontal' = 'vertical';\n /** Design-system inactive state for the complete set. */\n @Prop() isInactive: boolean = false;\n /** Accessible name when visible group labeling is unavailable. */\n @Prop({ attribute: 'aria-label' }) ariaLabel: string | null = null;\n /** Id reference for a visible group label. */\n @Prop({ attribute: 'aria-labelledby' }) ariaLabelledby: string | undefined;\n\n /** Emitted after user selection with the selected option value. */\n @Event() dsChange!: EventEmitter<string>;\n\n private initialValue = '';\n @State() private formDisabled = false;\n\n componentWillLoad() {\n this.initialValue = this.value;\n this.syncFormValue();\n }\n\n @Watch('value')\n @Watch('disabled')\n @Watch('isInactive')\n @Watch('required')\n syncFormValue() {\n const inactive = this.isInactive || this.disabled || this.formDisabled;\n this.internals.setFormValue(inactive ? null : this.value);\n const missing = this.required && !inactive && this.value.length === 0;\n setRequiredValidity(this.internals, missing, this.requiredMessage);\n }\n\n formDisabledCallback(disabled: boolean) {\n this.formDisabled = disabled;\n this.syncFormValue();\n }\n\n formResetCallback() {\n this.value = this.initialValue;\n }\n\n formStateRestoreCallback(state: string | File | FormData | null) {\n this.value = typeof state === 'string' ? state : '';\n }\n\n private get activeItems(): HTMLElement[] {\n return Array.from(this.el.querySelectorAll<HTMLElement>('[data-radio-item]:not([data-inactive])'));\n }\n\n @Listen('keydown')\n handleKeyDown(e: KeyboardEvent) {\n const items = this.activeItems;\n if (!items.length) return;\n\n const focused = items.find(item => item === document.activeElement);\n if (!focused) return;\n\n const idx = items.indexOf(focused);\n let next = -1;\n\n switch (e.key) {\n case 'ArrowDown':\n case 'ArrowRight':\n e.preventDefault();\n next = (idx + 1) % items.length;\n break;\n case 'ArrowUp':\n case 'ArrowLeft':\n e.preventDefault();\n next = (idx - 1 + items.length) % items.length;\n break;\n case 'Home':\n e.preventDefault();\n next = 0;\n break;\n case 'End':\n e.preventDefault();\n next = items.length - 1;\n break;\n }\n\n if (next >= 0) {\n items[next].focus();\n const nextValue = items[next].dataset['value'];\n if (nextValue && nextValue !== this.value) {\n this.value = nextValue;\n this.dsChange.emit(nextValue);\n }\n }\n }\n\n private selectItem(optValue: string) {\n if (this.isInactive || this.disabled || this.formDisabled) return;\n if (optValue !== this.value) {\n this.value = optValue;\n this.dsChange.emit(optValue);\n }\n }\n\n render() {\n const inactive = this.isInactive || this.disabled || this.formDisabled;\n const invalid = this.required && !inactive && this.value.length === 0;\n const selectedIdx = this.options.findIndex(option => option.value === this.value);\n const firstActiveIdx = this.options.findIndex(option => !inactive && !option.isInactive);\n const focusableIdx = selectedIdx >= 0 && !inactive && !this.options[selectedIdx]?.isInactive\n ? selectedIdx\n : firstActiveIdx;\n\n return (\n <Host\n role=\"radiogroup\"\n aria-label={this.ariaLabel}\n aria-labelledby={this.ariaLabelledby}\n aria-required={this.required ? 'true' : undefined}\n aria-invalid={invalid ? 'true' : undefined}\n class={{\n radio: true,\n 'radio--horizontal': this.direction === 'horizontal',\n [`radio--${this.size}`]: true,\n }}\n >\n {this.options.map((option, index) => {\n const isItemInactive = inactive || !!option.isInactive;\n const isChecked = option.value === this.value;\n const tabIdx = isItemInactive ? -1 : index === focusableIdx ? 0 : -1;\n\n return (\n <div\n key={option.value}\n role=\"radio\"\n aria-checked={String(isChecked)}\n aria-disabled={isItemInactive ? 'true' : undefined}\n tabIndex={tabIdx}\n data-radio-item\n data-value={option.value}\n data-inactive={isItemInactive || undefined}\n class={{\n radio__item: true,\n [`ds-control--${this.size}`]: true,\n 'ds-control-inactive': isItemInactive,\n 'ds-focus-ring-inset': !isItemInactive,\n 'ds-interaction-fill': !isItemInactive,\n }}\n onClick={() => !isItemInactive && this.selectItem(option.value)}\n onKeyDown={(e: KeyboardEvent) => {\n if ((e.key === ' ' || e.key === 'Enter') && !isItemInactive) {\n e.preventDefault();\n this.selectItem(option.value);\n }\n }}\n >\n <span class=\"radio__placement ds-interaction-fill__content\" aria-hidden=\"true\">\n <span class={{ radio__circle: true, 'radio__circle--checked': isChecked }}>\n {isChecked && <span class=\"radio__dot\" />}\n </span>\n </span>\n <ds-text\n class=\"radio__label ds-interaction-fill__content\"\n as=\"span\"\n variant={CONTROL_TEXT_VARIANT[this.size]}\n >\n {option.label}\n </ds-text>\n </div>\n );\n })}\n </Host>\n );\n }\n}\n",
|
|
371
371
|
"type": "registry:ui"
|
|
372
372
|
}
|
|
373
373
|
]
|
|
@@ -1352,6 +1352,7 @@
|
|
|
1352
1352
|
"Use native submit behavior for form submission and handle the form submit event rather than submitting from the button click event."
|
|
1353
1353
|
],
|
|
1354
1354
|
"states": [
|
|
1355
|
+
"Every size applies one complete control-density recipe across frame height, inline padding, icon zone, text-container inset, gap, and radius.",
|
|
1355
1356
|
"Use only one filled action per local decision area; render all secondary actions with ButtonUnfilled.",
|
|
1356
1357
|
"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.",
|
|
1357
1358
|
"Contrast serves both surface adaptation and hierarchy, but never permits a second filled action in the same decision area.",
|
|
@@ -1524,6 +1525,7 @@
|
|
|
1524
1525
|
"For form submission, use native submit behavior and handle the form submit event rather than submitting from the button click event."
|
|
1525
1526
|
],
|
|
1526
1527
|
"states": [
|
|
1528
|
+
"Every size applies one complete control-density recipe across frame height, inline padding, icon zone, text-container inset, gap, and radius.",
|
|
1527
1529
|
"General content UI keeps the selected interaction fill and border for persistent active state.",
|
|
1528
1530
|
"Shell, navigation, and tool-rail chrome uses foreground-only active state with no selected fill or border.",
|
|
1529
1531
|
"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.",
|
|
@@ -1719,6 +1721,7 @@
|
|
|
1719
1721
|
"The card disables decorative legend-row hover; genuine legend links retain native link semantics and affordances."
|
|
1720
1722
|
],
|
|
1721
1723
|
"states": [
|
|
1724
|
+
"Bar, Line, and Donut cards share the same fill-chart and content-sized-legend body contract so dashboard card geometry remains aligned across chart types.",
|
|
1722
1725
|
"The chart region fills the remaining card body while an optional legend remains content-sized.",
|
|
1723
1726
|
"The card disables local hover highlighting on a slotted ChartLegend because bar legends are static keys.",
|
|
1724
1727
|
"Chart and legend regions render only when their corresponding slots contain content, avoiding empty region spacing.",
|
|
@@ -1833,6 +1836,7 @@
|
|
|
1833
1836
|
"The application owns meaningful loading, empty, and error status copy when either content region is temporarily replaced or absent."
|
|
1834
1837
|
],
|
|
1835
1838
|
"states": [
|
|
1839
|
+
"Bar, Line, and Donut cards share the same fill-chart and content-sized-legend body contract so dashboard card geometry remains aligned across chart types.",
|
|
1836
1840
|
"The chart region fills remaining card height while the legend remains content-sized.",
|
|
1837
1841
|
"Chart and legend regions render only when their corresponding slots contain content, allowing the owner to substitute loading, empty, or error presentations without dangling region padding.",
|
|
1838
1842
|
"Hover synchronization changes highlight only; it never represents selection, filtering, or navigation.",
|
|
@@ -1947,6 +1951,7 @@
|
|
|
1947
1951
|
"The card disables decorative legend-row hover; genuine legend links retain native link semantics and affordances."
|
|
1948
1952
|
],
|
|
1949
1953
|
"states": [
|
|
1954
|
+
"Bar, Line, and Donut cards share the same fill-chart and content-sized-legend body contract so dashboard card geometry remains aligned across chart types.",
|
|
1950
1955
|
"The chart region fills the remaining card body while the legend remains content-sized.",
|
|
1951
1956
|
"The card disables local hover highlighting on a slotted ChartLegend because the line chart is static.",
|
|
1952
1957
|
"Chart and legend regions render only when their corresponding slots contain content, avoiding empty region spacing.",
|
|
@@ -2906,7 +2911,7 @@
|
|
|
2906
2911
|
{
|
|
2907
2912
|
"name": "checkbox",
|
|
2908
2913
|
"title": "Checkbox",
|
|
2909
|
-
"description": "Form-associated checkbox for independent choices, acknowledgment, or consent, with checked, unchecked, mixed, and
|
|
2914
|
+
"description": "Form-associated checkbox for independent choices, acknowledgment, or consent, with checked, unchecked, mixed, and four density states.",
|
|
2910
2915
|
"type": "registry:ui",
|
|
2911
2916
|
"meta": {
|
|
2912
2917
|
"library": "@ds-mo/ui",
|
|
@@ -2917,7 +2922,7 @@
|
|
|
2917
2922
|
"intent": {
|
|
2918
2923
|
"audience": "general",
|
|
2919
2924
|
"status": "stable",
|
|
2920
|
-
"summary": "Form-associated checkbox for independent choices, acknowledgment, or consent, with checked, unchecked, mixed, and
|
|
2925
|
+
"summary": "Form-associated checkbox for independent choices, acknowledgment, or consent, with checked, unchecked, mixed, and four density states.",
|
|
2921
2926
|
"useWhen": [
|
|
2922
2927
|
"A user may independently select zero or more choices.",
|
|
2923
2928
|
"A form requires acknowledgment, consent, or an opt-in value before submission.",
|
|
@@ -2957,15 +2962,15 @@
|
|
|
2957
2962
|
"Use presentation mode only inside a composite option that owns selection semantics, focus, and interaction."
|
|
2958
2963
|
],
|
|
2959
2964
|
"states": [
|
|
2960
|
-
"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.",
|
|
2965
|
+
"Unchecked boxes use a tertiary-foreground inset stroke: 1.5px at lg, 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.",
|
|
2961
2966
|
"Activating an indeterminate checkbox clears the mixed state, toggles checked, and emits dsChange with the resulting boolean.",
|
|
2962
2967
|
"The initial checked and indeterminate values are restored by native form reset; checked values submit under name and unchecked values submit nothing.",
|
|
2963
|
-
"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.",
|
|
2968
|
+
"Sizes are lg with a 20px box in a 24px placement, 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.",
|
|
2964
2969
|
"Presentation mode removes checkbox semantics, focus, interaction, label rendering, and form submission while preserving the visual state."
|
|
2965
2970
|
],
|
|
2966
2971
|
"responsiveBehavior": [
|
|
2967
2972
|
"Choose size from the density of the containing row; labels may wrap while the placement box stays fixed.",
|
|
2968
|
-
"Use the
|
|
2973
|
+
"Use the same density as the shared option icon zone in multi-select rows."
|
|
2969
2974
|
],
|
|
2970
2975
|
"frameworkCaveats": {
|
|
2971
2976
|
"customElements": [
|
|
@@ -3302,7 +3307,7 @@
|
|
|
3302
3307
|
"actionLayout footer stretches a long action between 8px side and bottom insets.",
|
|
3303
3308
|
"Both action layouts share the always-active scroll-overlay fade controller, reserve measured end clearance, and begin fading 8px before the visible action.",
|
|
3304
3309
|
"ConversationList paints its measured fade on a separate surface-aware layer so contextual row actions retain a real backdrop for blur; hovered, focused, and menu-open rows rise above that decorative fade.",
|
|
3305
|
-
"The persistent action wrapper splits its md outer shadow from a top inset-highlight overlay so opaque filled actions keep the complete TokoMo elevation; slotted
|
|
3310
|
+
"The persistent action wrapper splits its md outer shadow from a top inset-highlight overlay so opaque filled actions keep the complete TokoMo elevation; slotted buttons disable optional resting borders and the press-scale modifier moves the button and elevated surface as one unit."
|
|
3306
3311
|
],
|
|
3307
3312
|
"responsiveBehavior": [
|
|
3308
3313
|
"The list fills its owner, scrolls independently, and keeps its persistent action above scrolling rows."
|
|
@@ -3376,7 +3381,7 @@
|
|
|
3376
3381
|
"Hover and press use the shared interaction hover and pressed overlays. Only the selected conversation uses the persistent active fill.",
|
|
3377
3382
|
"The title uses body-medium, not title-small, and the body-small preview truncates after one line. Unread titles use emphasis with primary foreground; read titles use regular weight with secondary foreground.",
|
|
3378
3383
|
"The actions slot overlays the row at an 8px right inset without changing title or preview measure, and paints above the row interaction wash while that wash remains active.",
|
|
3379
|
-
"Contextual actions use the shared md control-elevation wrapper so their transparent backdrop blur is unchanged while the split inset highlight remains above the borderless slotted action."
|
|
3384
|
+
"Contextual actions use the shared md control-elevation wrapper so their transparent backdrop blur is unchanged while the split inset highlight remains above the borderless slotted action and the press-scale modifier moves the complete elevated surface."
|
|
3380
3385
|
],
|
|
3381
3386
|
"responsiveBehavior": [
|
|
3382
3387
|
"Long titles and previews truncate without displacing trailing status."
|
|
@@ -3687,7 +3692,7 @@
|
|
|
3687
3692
|
"Supported compositions are icon plus title plus body, title plus body, and body only; body copy is present in every supported composition.",
|
|
3688
3693
|
"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.",
|
|
3689
3694
|
"The visual title uses title-small primary text; body uses body-medium secondary text with a 4px title-to-body gap.",
|
|
3690
|
-
"All content is centered. The owner supplies container size and surrounding padding;
|
|
3695
|
+
"All content is centered. The owner supplies container size and surrounding padding; repeated panel and master-detail owners should share one empty-region geometry instead of wrapping each EmptyState differently. Do not compose actions into or immediately alongside the current EmptyState pattern.",
|
|
3691
3696
|
"First-use, no-content, no-results, and no-access states reuse this primitive with cause-specific localized messages rather than visual variants."
|
|
3692
3697
|
],
|
|
3693
3698
|
"responsiveBehavior": [
|
|
@@ -3709,6 +3714,10 @@
|
|
|
3709
3714
|
{
|
|
3710
3715
|
"label": "Storybook examples",
|
|
3711
3716
|
"path": "src/wc/components/EmptyState/EmptyState.stories.ts"
|
|
3717
|
+
},
|
|
3718
|
+
{
|
|
3719
|
+
"label": "Shared layout recipe foundation",
|
|
3720
|
+
"path": "docs/layout-recipe-foundation.md"
|
|
3712
3721
|
}
|
|
3713
3722
|
]
|
|
3714
3723
|
},
|
|
@@ -3790,6 +3799,7 @@
|
|
|
3790
3799
|
"Do not use placeholder text as the only label. Keep label text concise and put format or consequence guidance in description."
|
|
3791
3800
|
],
|
|
3792
3801
|
"states": [
|
|
3802
|
+
"Label, control, description, and error content follow the shared 4px vertical field flow without changing the slotted control's width or semantics.",
|
|
3793
3803
|
"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.",
|
|
3794
3804
|
"A rendered error replaces the description; preserve essential guidance in the error message so users retain what they need to correct the field.",
|
|
3795
3805
|
"Field owns validation presentation but not validation timing; the form decides when to set error and errorMessage.",
|
|
@@ -3987,7 +3997,7 @@
|
|
|
3987
3997
|
{
|
|
3988
3998
|
"name": "input",
|
|
3989
3999
|
"title": "Input",
|
|
3990
|
-
"description": "Form-associated single-line text field for primary and secondary application backgrounds, with native text input behavior,
|
|
4000
|
+
"description": "Form-associated single-line text field for primary and secondary application backgrounds, with native text input behavior, four control densities, optional leading and trailing content, search clearing, and validation.",
|
|
3991
4001
|
"type": "registry:ui",
|
|
3992
4002
|
"meta": {
|
|
3993
4003
|
"library": "@ds-mo/ui",
|
|
@@ -3998,7 +4008,7 @@
|
|
|
3998
4008
|
"intent": {
|
|
3999
4009
|
"audience": "general",
|
|
4000
4010
|
"status": "stable",
|
|
4001
|
-
"summary": "Form-associated single-line text field for primary and secondary application backgrounds, with native text input behavior,
|
|
4011
|
+
"summary": "Form-associated single-line text field for primary and secondary application backgrounds, with native text input behavior, four control densities, optional leading and trailing content, search clearing, and validation.",
|
|
4002
4012
|
"useWhen": [
|
|
4003
4013
|
"A user must enter or edit one line of text, an email address, telephone number, URL, search query, or password.",
|
|
4004
4014
|
"The value must participate in native, Angular, or React form state.",
|
|
@@ -4039,6 +4049,7 @@
|
|
|
4039
4049
|
"Suffix content must not carry information that is otherwise absent from the field's visible label, value, or description."
|
|
4040
4050
|
],
|
|
4041
4051
|
"states": [
|
|
4052
|
+
"Every size applies one complete control-density recipe across frame height, inline padding, icon zones, text-container inset, gap, and radius; supporting error content follows the shared 4px field flow.",
|
|
4042
4053
|
"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.",
|
|
4043
4054
|
"Placeholder text is secondary at rest and quaternary while the editable field is focused because it becomes decorative once typing begins.",
|
|
4044
4055
|
"Entered values use the parent surface's primary foreground; prefix icons, suffix content, and resting placeholder text use its secondary foreground.",
|
|
@@ -4050,7 +4061,7 @@
|
|
|
4050
4061
|
],
|
|
4051
4062
|
"responsiveBehavior": [
|
|
4052
4063
|
"Form fields normally fill their parent; use hug width only in a compact toolbar or filter layout with an explicit width constraint.",
|
|
4053
|
-
"Choose density from the containing layout: md for ordinary forms, sm or xs only where
|
|
4064
|
+
"Choose density from the containing layout: md for ordinary forms, lg for a touch-primary layout, and sm or xs only where surrounding controls use the same compact recipe.",
|
|
4054
4065
|
"The owner supplies layout constraints and decides when a compact field moves to its own row."
|
|
4055
4066
|
],
|
|
4056
4067
|
"frameworkCaveats": {
|
|
@@ -4446,7 +4457,7 @@
|
|
|
4446
4457
|
"Anchor the menu to the control that opens it and return focus to that control when the menu closes.",
|
|
4447
4458
|
"Open with visible initial focus only when the trigger was activated from the keyboard.",
|
|
4448
4459
|
"Keep disabled items discoverable only when their unavailable state is meaningful.",
|
|
4449
|
-
"Switch rows use menuitemcheckbox semantics on the row; the nested ds-switch is an aria-hidden
|
|
4460
|
+
"Switch rows use menuitemcheckbox semantics on the row; the nested ds-switch is an aria-hidden presentation indicator at the same density as the menu.",
|
|
4450
4461
|
"Single-selection menus use menuitemradio semantics and aria-checked on each row, but render no nested radio control; selected interaction fill and primary foreground provide the visual state.",
|
|
4451
4462
|
"A swatch-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.",
|
|
4452
4463
|
"Use notification dots only as supplemental status and not as the sole indication of important information."
|
|
@@ -4457,7 +4468,8 @@
|
|
|
4457
4468
|
"After dsSelect from a switch row, replace the items or sections array with updated switchValue data so the controlled indicator reflects the new state.",
|
|
4458
4469
|
"For selectionMode single, keep exactly one item isSelected and replace the items or sections array after dsSelect; Menu never mutates consumer-owned selection data.",
|
|
4459
4470
|
"Arrays, objects, and element anchors must be assigned as JavaScript properties.",
|
|
4460
|
-
"Use a swatch-picker section for a small curated visual preference and apply dsSwatchSelect immediately without closing the popup; the legacy gradient-picker section and dsGradientSelect remain compatibility-only."
|
|
4471
|
+
"Use a swatch-picker section for a small curated visual preference and apply dsSwatchSelect immediately without closing the popup; the legacy gradient-picker section and dsGradientSelect remain compatibility-only.",
|
|
4472
|
+
"Ordinary rows, section headings, and supporting text consume the Menu size. At xs, both the primary label and supporting text use caption metrics."
|
|
4461
4473
|
],
|
|
4462
4474
|
"responsiveBehavior": [
|
|
4463
4475
|
"Keep the default choice-cell anchor alignment so the first or last interactive row edge aligns with its trigger, matching Select; use popup-frame only for deliberate custom frame geometry.",
|
|
@@ -4546,6 +4558,10 @@
|
|
|
4546
4558
|
"sideOffset": {
|
|
4547
4559
|
"type": "number | string",
|
|
4548
4560
|
"required": false
|
|
4561
|
+
},
|
|
4562
|
+
"size": {
|
|
4563
|
+
"type": "MenuSize",
|
|
4564
|
+
"required": false
|
|
4549
4565
|
}
|
|
4550
4566
|
},
|
|
4551
4567
|
"events": [
|
|
@@ -4908,7 +4924,7 @@
|
|
|
4908
4924
|
"Selection and transcript interaction release automatic following.",
|
|
4909
4925
|
"Opening saved history, message jumps, and prepended history preserve deliberate position.",
|
|
4910
4926
|
"The scroll-to-latest action is absent at the live edge, appears only after the reader moves away, and disappears again after returning to the newest message.",
|
|
4911
|
-
"Scroll to latest uses the shared md control-elevation wrapper with a pointer-transparent top highlight, preserving its transparent backdrop blur and borderless unfilled action.",
|
|
4927
|
+
"Scroll to latest uses the shared md control-elevation wrapper with a pointer-transparent top highlight, preserving its transparent backdrop blur and borderless unfilled action while the press-scale modifier moves the complete elevated surface.",
|
|
4912
4928
|
"Place a composer container with 8px padding on every side in the overlay slot so messages scroll behind it; the shared scroll-overlay controller tracks every composer growth step, reserves matching transcript clearance, begins the fade 8px before the visible composer, and keeps scroll-to-latest above it."
|
|
4913
4929
|
],
|
|
4914
4930
|
"responsiveBehavior": [
|
|
@@ -5003,7 +5019,7 @@
|
|
|
5003
5019
|
"Direct touch paints the pressed overlay immediately, keeps a quick tap visible for one short frame, and clears it after release or cancellation without relying on Safari's latch-prone active state."
|
|
5004
5020
|
],
|
|
5005
5021
|
"responsiveBehavior": [
|
|
5006
|
-
"Render only below the mobile breakpoint
|
|
5022
|
+
"Render only below the mobile breakpoint; its secondary surface extends through the bottom safe-area inset when the application enables viewport-fit=cover.",
|
|
5007
5023
|
"The secondary-background bar keeps an 8px outer inset; its two icon-only groups anchor to opposite edges while retaining fixed 40px targets and a divider between Menu and current area.",
|
|
5008
5024
|
"Bar chrome and its divider are not text-selectable and suppress the iOS touch callout."
|
|
5009
5025
|
],
|
|
@@ -5341,7 +5357,9 @@
|
|
|
5341
5357
|
"Area, Help, and Account events express intent while the application owns navigation and product behavior."
|
|
5342
5358
|
],
|
|
5343
5359
|
"responsiveBehavior": [
|
|
5344
|
-
"The pane fills the mobile content stage while the bottom bar remains available."
|
|
5360
|
+
"The pane fills the mobile content stage while the bottom bar remains available.",
|
|
5361
|
+
"The sheet header and scrollable navigation body each use the shared 8px chrome inset; large destination controls retain their independent 40px density.",
|
|
5362
|
+
"Dashboard and Settings preserve their supplied visual groups with an 8px gap between destinations inside a section and a 32px gap between sections."
|
|
5345
5363
|
],
|
|
5346
5364
|
"references": [
|
|
5347
5365
|
{
|
|
@@ -6426,7 +6444,7 @@
|
|
|
6426
6444
|
{
|
|
6427
6445
|
"name": "radio",
|
|
6428
6446
|
"title": "Radio",
|
|
6429
|
-
"description": "Form-associated one-of-many radio selection set with vertical or horizontal layout,
|
|
6447
|
+
"description": "Form-associated one-of-many radio selection set with vertical or horizontal layout, four densities, per-option inactive state, and roving keyboard focus.",
|
|
6430
6448
|
"type": "registry:ui",
|
|
6431
6449
|
"meta": {
|
|
6432
6450
|
"library": "@ds-mo/ui",
|
|
@@ -6437,7 +6455,7 @@
|
|
|
6437
6455
|
"intent": {
|
|
6438
6456
|
"audience": "general",
|
|
6439
6457
|
"status": "stable",
|
|
6440
|
-
"summary": "Form-associated one-of-many radio selection set with vertical or horizontal layout,
|
|
6458
|
+
"summary": "Form-associated one-of-many radio selection set with vertical or horizontal layout, four densities, per-option inactive state, and roving keyboard focus.",
|
|
6441
6459
|
"useWhen": [
|
|
6442
6460
|
"A user must select exactly one visible option from a small set.",
|
|
6443
6461
|
"All available choices should remain visible for comparison.",
|
|
@@ -6476,9 +6494,9 @@
|
|
|
6476
6494
|
"Roving tabindex keeps one active option in the tab order, preferring the selected option."
|
|
6477
6495
|
],
|
|
6478
6496
|
"states": [
|
|
6479
|
-
"Unchecked circles use a tertiary-foreground inset stroke: 1.25px at md, 1px at sm, and 0.75px at xs.",
|
|
6480
|
-
"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.",
|
|
6481
|
-
"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.",
|
|
6497
|
+
"Unchecked circles use a tertiary-foreground inset stroke: 1.5px at lg, 1.25px at md, 1px at sm, and 0.75px at xs.",
|
|
6498
|
+
"Selected circles remove the border, use a brand fill, and draw a centered on-bold foreground dot sized 10px at lg, 8px at md, 6px at sm, and 4px at xs.",
|
|
6499
|
+
"Sizes are lg with a 20px circle in a 24px placement, 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.",
|
|
6482
6500
|
"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."
|
|
6483
6501
|
],
|
|
6484
6502
|
"responsiveBehavior": [
|
|
@@ -6720,6 +6738,8 @@
|
|
|
6720
6738
|
"Use errorMessage with error so the trigger is described by the rendered alert."
|
|
6721
6739
|
],
|
|
6722
6740
|
"states": [
|
|
6741
|
+
"Select and SelectMulti share popup positioning, dismissal, focus, typeahead, and listbox traversal while retaining their distinct scalar and array selection contracts.",
|
|
6742
|
+
"Every size applies one complete control-density recipe across trigger height, inline padding, icon zones, text-container inset, gap, and radius; error content follows the shared 4px field flow.",
|
|
6723
6743
|
"Value is controlled through the mutable value property; dsChange reports user selection and clearing.",
|
|
6724
6744
|
"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.",
|
|
6725
6745
|
"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.",
|
|
@@ -6731,9 +6751,9 @@
|
|
|
6731
6751
|
"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.",
|
|
6732
6752
|
"Option labels and the selected trigger label stay on one line and truncate when constrained. Option subtext may wrap to at most two lines.",
|
|
6733
6753
|
"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.",
|
|
6734
|
-
"The shared popup search control
|
|
6735
|
-
"When search contains text, the shared control shows a rounded
|
|
6736
|
-
"The shared clear footer mirrors the
|
|
6754
|
+
"The shared popup search control follows the Select density, using the same text, icon, and internal spacing as a borderless 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.",
|
|
6755
|
+
"When search contains text, the shared control shows a rounded icon-only ButtonUnfilled with the CrossCircle icon and no border, sized to remain inset within the current row density. It clears the local term, stays hidden for an empty term, and returns focus to search.",
|
|
6756
|
+
"The shared clear footer mirrors the owning density: menu-item padding surrounds a borderless density row, and the Clear label uses the same row and label insets as option text. The outer footer owns a 1px top divider.",
|
|
6737
6757
|
"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.",
|
|
6738
6758
|
"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.",
|
|
6739
6759
|
"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.",
|
|
@@ -6972,23 +6992,25 @@
|
|
|
6972
6992
|
"The popup is a listbox with aria-multiselectable and every option exposes its independent aria-selected state.",
|
|
6973
6993
|
"Disabled options expose aria-disabled and are skipped by keyboard navigation and typeahead.",
|
|
6974
6994
|
"Keyboard navigation keeps the aria-activedescendant option scrolled into the visible listbox viewport.",
|
|
6975
|
-
"Each row uses a
|
|
6995
|
+
"Each row uses a presentation-only ds-checkbox indicator at the same density as the row; multi-select option rows never add a prefix icon alongside it, and the option remains the sole selection semantic and interaction target.",
|
|
6976
6996
|
"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.",
|
|
6977
6997
|
"Use errorMessage with error so the trigger is described by the rendered alert."
|
|
6978
6998
|
],
|
|
6979
6999
|
"states": [
|
|
7000
|
+
"Select and SelectMulti share popup positioning, dismissal, focus, typeahead, and listbox traversal while retaining their distinct scalar and array selection contracts.",
|
|
7001
|
+
"Every size applies one complete control-density recipe across trigger height, inline padding, icon zones, text-container inset, gap, and radius; error content follows the shared 4px field flow.",
|
|
6980
7002
|
"Values is a controlled JavaScript array; dsChange emits a new array after each user toggle.",
|
|
6981
7003
|
"Required SelectMulti controls begin without an automatic selection and require the user to make an explicit choice.",
|
|
6982
7004
|
"Selecting an option keeps the popup open so additional values can be toggled.",
|
|
6983
|
-
"The trigger label stays left-aligned at every width; every option row uses the same leading
|
|
7005
|
+
"The trigger label stays left-aligned at every width; every option row uses the same leading Checkbox indicator at its density. The default control size is md in both forms and filter bars.",
|
|
6984
7006
|
"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.",
|
|
6985
7007
|
"Create sections only for categories that are meaningful to customers, not merely to break a long list into arbitrary chunks.",
|
|
6986
7008
|
"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.",
|
|
6987
7009
|
"Option labels stay on one line and truncate when constrained. Option subtext may wrap to at most two lines.",
|
|
6988
7010
|
"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.",
|
|
6989
|
-
"The shared popup search control
|
|
7011
|
+
"The shared popup search control follows the SelectMulti density, using the same text, icon, and internal spacing as a borderless 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.",
|
|
6990
7012
|
"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.",
|
|
6991
|
-
"The shared summary-and-clear footer mirrors the
|
|
7013
|
+
"The shared summary-and-clear footer mirrors the owning density: menu-item padding surrounds a borderless density row, and both texts use the same row and label insets as option text. The outer footer owns a 1px top divider.",
|
|
6992
7014
|
"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.",
|
|
6993
7015
|
"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.",
|
|
6994
7016
|
"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.",
|
|
@@ -7253,6 +7275,7 @@
|
|
|
7253
7275
|
"On desktop, PanelNav defaults expanded, permits user collapse or expansion, and respects the locally persisted desktop preference.",
|
|
7254
7276
|
"On tablet, ShellApp keeps PanelNav permanently collapsed and prevents user expansion without overwriting the desktop preference.",
|
|
7255
7277
|
"On mobile, ShellApp hides and inerts PanelNav and BarNav, uses a solid primary stage, and composes routed ShellPage MobileHeader presentations, MobileSheetNav, ShellTools, and the persistent five-item MobileBarNav.",
|
|
7278
|
+
"When the application enables viewport-fit=cover, ShellApp reserves the shared top safe-area inset once for the complete mobile stage; nested routed, sheet, and tool headers must not add a second top inset.",
|
|
7256
7279
|
"Mobile global surfaces conceal and inert the routed workspace without unmounting it, preserving nested routes and scroll state.",
|
|
7257
7280
|
"Keep PanelNav width, BarNav height, PanelTools chrome, and main-content origin stable except during intentional responsive or collapse transitions.",
|
|
7258
7281
|
"The bottom bar remains visible at all route and tool depths in the foundation release."
|
|
@@ -8036,6 +8059,7 @@
|
|
|
8036
8059
|
"Read-only sliders remain focusable and submittable; inactive or disabled sliders leave the tab order and form submission."
|
|
8037
8060
|
],
|
|
8038
8061
|
"states": [
|
|
8062
|
+
"The label, slider control, value display, and supporting content follow the shared 4px vertical field flow.",
|
|
8039
8063
|
"value is mutable: user pointer, keyboard, or assistive-technology input updates it and emits dsChange continuously.",
|
|
8040
8064
|
"dsCommit emits once a pointer interaction completes or the native range input commits a keyboard or assistive-technology change.",
|
|
8041
8065
|
"Assign a two-number array through the JavaScript value property to create a range; values are ordered, clamped, stepped, and prevented from crossing.",
|
|
@@ -8334,7 +8358,7 @@
|
|
|
8334
8358
|
{
|
|
8335
8359
|
"name": "switch",
|
|
8336
8360
|
"title": "Switch",
|
|
8337
|
-
"description": "Compact on/off setting control for changes that take effect immediately, with
|
|
8361
|
+
"description": "Compact on/off setting control for changes that take effect immediately, with four sizes and form-associated behavior.",
|
|
8338
8362
|
"type": "registry:ui",
|
|
8339
8363
|
"meta": {
|
|
8340
8364
|
"library": "@ds-mo/ui",
|
|
@@ -8345,7 +8369,7 @@
|
|
|
8345
8369
|
"intent": {
|
|
8346
8370
|
"audience": "general",
|
|
8347
8371
|
"status": "stable",
|
|
8348
|
-
"summary": "Compact on/off setting control for changes that take effect immediately, with
|
|
8372
|
+
"summary": "Compact on/off setting control for changes that take effect immediately, with four sizes and form-associated behavior.",
|
|
8349
8373
|
"useWhen": [
|
|
8350
8374
|
"A binary setting takes effect immediately when the user turns it on or off.",
|
|
8351
8375
|
"A settings, form, or menu row needs a compact on/off control.",
|
|
@@ -8388,7 +8412,7 @@
|
|
|
8388
8412
|
"states": [
|
|
8389
8413
|
"Activation updates checked immediately and emits dsChange with the new boolean value.",
|
|
8390
8414
|
"The initial checked value is the form-reset baseline; unchecked switches submit nothing unless uncheckedValue is provided.",
|
|
8391
|
-
"Sizes are md 32×20 with a 12px thumb and 4px
|
|
8415
|
+
"Sizes are lg 40×24 with a 16px thumb and 4px body inset, md 32×20 with a 12px thumb and 4px inset, sm 24×16 with a 10px thumb and 3px inset, and xs 20×12 with an 8px thumb and 2px inset.",
|
|
8392
8416
|
"Unchecked uses a transparent track with a density-specific tertiary-foreground inset stroke and a solid tertiary-foreground thumb without a border. Checked uses a brand track and primary-background thumb with no strokes.",
|
|
8393
8417
|
"Presentation mode removes switch semantics, focus, interaction, and form submission while retaining the checked visual."
|
|
8394
8418
|
],
|