@astryxdesign/core 0.6.0 → 0.6.1
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/CHANGELOG.md +41 -3
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts +12 -1
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetSwitcher.js +44 -15
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +3 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +3 -7
- package/dist/Center/Center.d.ts +23 -16
- package/dist/Center/Center.d.ts.map +1 -1
- package/dist/Center/Center.js +7 -5
- package/dist/CodeBlock/CodeBlock.js +2 -2
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +12 -2
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +12 -2
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +1 -0
- package/dist/Field/InputClearButton.d.ts +2 -2
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +5 -1
- package/dist/Field/PanelSearchInput.d.ts.map +1 -1
- package/dist/Field/PanelSearchInput.js +16 -4
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +12 -1
- package/dist/HoverCard/useHoverCard.js +2 -2
- package/dist/Indicator/CheckboxIndicator.js +2 -2
- package/dist/Indicator/RadioIndicator.js +2 -2
- package/dist/Layer/layerStack.d.ts +10 -0
- package/dist/Layer/layerStack.d.ts.map +1 -1
- package/dist/Layer/layerStack.js +21 -9
- package/dist/Layer/useLayerDismissal.d.ts +2 -3
- package/dist/Layer/useLayerDismissal.d.ts.map +1 -1
- package/dist/Layer/useLayerDismissal.js +2 -3
- package/dist/NavIcon/NavIcon.js +2 -2
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +12 -2
- package/dist/Popover/usePopover.d.ts +3 -2
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +4 -2
- package/dist/ProgressBar/ProgressBar.js +2 -2
- package/dist/ScrollableArea/ScrollableArea.d.ts +79 -0
- package/dist/ScrollableArea/ScrollableArea.d.ts.map +1 -0
- package/dist/ScrollableArea/ScrollableArea.js +144 -0
- package/dist/ScrollableArea/index.d.ts +11 -0
- package/dist/ScrollableArea/index.d.ts.map +1 -0
- package/dist/ScrollableArea/index.js +11 -0
- package/dist/StatusDot/StatusDot.js +2 -2
- package/dist/TextArea/TextArea.js +2 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +19 -4
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +12 -2
- package/dist/Typeahead/BaseTypeahead.d.ts +21 -14
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +56 -20
- package/dist/astryx.css +15 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/scrollGeometry.d.ts +24 -0
- package/dist/hooks/scrollGeometry.d.ts.map +1 -0
- package/dist/hooks/scrollGeometry.js +86 -0
- package/dist/hooks/scrollOwnerRegistry.d.ts +15 -0
- package/dist/hooks/scrollOwnerRegistry.d.ts.map +1 -0
- package/dist/hooks/scrollOwnerRegistry.js +24 -0
- package/dist/hooks/useFocusTrap.d.ts +8 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +22 -11
- package/dist/hooks/useScrollableArea.d.ts +51 -0
- package/dist/hooks/useScrollableArea.d.ts.map +1 -0
- package/dist/hooks/useScrollableArea.js +287 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/theme/defineTheme.d.ts +2 -6
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/defineTheme.js +1 -1
- package/dist/theme/derivedVarRegistry.js +1 -1
- package/dist/theme/localTokens.d.ts +8 -11
- package/dist/theme/localTokens.d.ts.map +1 -1
- package/dist/theme/localTokens.js +17 -71
- package/dist/theme/themeAdaptations.d.ts.map +1 -1
- package/dist/theme/themeAdaptations.js +4 -4
- package/dist/utils/themeProps.d.ts +10 -10
- package/dist/utils/themeProps.d.ts.map +1 -1
- package/dist/utils/themeProps.js +27 -10
- package/locales/en.json +16 -0
- package/locales/pseudo.json +12 -0
- package/package.json +7 -2
- package/src/AppShell/AppShell.test.tsx +36 -0
- package/src/AppShell/AppShell.tsx +4 -1
- package/src/AspectRatio/AspectRatio.doc.mjs +3 -3
- package/src/Banner/Banner.test.tsx +3 -1
- package/src/BottomSheet/BottomSheetSwitcher.doc.mjs +56 -1
- package/src/BottomSheet/BottomSheetSwitcher.spec.md +211 -0
- package/src/BottomSheet/BottomSheetSwitcher.test.tsx +134 -2
- package/src/BottomSheet/BottomSheetSwitcher.tsx +43 -20
- package/src/Breadcrumbs/BreadcrumbItem.doc.mjs +10 -5
- package/src/Breadcrumbs/BreadcrumbItem.spec.md +225 -0
- package/src/Breadcrumbs/BreadcrumbItem.tsx +8 -13
- package/src/Breadcrumbs/Breadcrumbs.doc.mjs +2 -2
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +49 -2
- package/src/Center/Center.doc.mjs +32 -28
- package/src/Center/Center.spec.md +225 -0
- package/src/Center/Center.test.tsx +42 -4
- package/src/Center/Center.tsx +24 -17
- package/src/Chat/ChatSystemMessage.test.tsx +2 -9
- package/src/CodeBlock/CodeBlock.doc.mjs +2 -2
- package/src/CodeBlock/CodeBlock.tsx +2 -2
- package/src/DateInput/DateInput.test.tsx +4 -4
- package/src/DateInput/DateInput.tsx +15 -4
- package/src/DateRangeInput/DateRangeInput.test.tsx +2 -2
- package/src/DateTimeInput/DateTimeInput.test.tsx +6 -4
- package/src/DateTimeInput/DateTimeInput.tsx +18 -7
- package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +4 -77
- package/src/Field/Field.test.tsx +42 -0
- package/src/Field/Field.tsx +6 -0
- package/src/Field/InputClearButton.test.tsx +35 -1
- package/src/Field/InputClearButton.tsx +7 -3
- package/src/Field/PanelSearchInput.tsx +21 -8
- package/src/FieldStatus/FieldStatus.spec.md +27 -17
- package/src/FieldStatus/FieldStatus.test.tsx +7 -5
- package/src/FieldStatus/__tests__/StatusMessage.a11y.chromium.spec.ts +198 -0
- package/src/FieldStatus/__tests__/StatusMessage.a11y.known-failures.ts +13 -0
- package/src/FieldStatus/__tests__/StatusMessage.a11y.renders.tsx +305 -0
- package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +317 -0
- package/src/FieldStatus/__tests__/StatusMessage.a11y.test.tsx +155 -0
- package/src/FileInput/FileInput.tsx +10 -1
- package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +3 -3
- package/src/HoverCard/HoverCard.doc.mjs +4 -4
- package/src/HoverCard/useHoverCard.tsx +2 -2
- package/src/Indicator/CheckboxIndicator.tsx +2 -2
- package/src/Indicator/Indicator.doc.mjs +2 -2
- package/src/Indicator/Indicator.test.tsx +1 -1
- package/src/Indicator/RadioIndicator.tsx +2 -2
- package/src/Layer/layerStack.ts +20 -9
- package/src/Layer/useLayerDismissal.ts +2 -3
- package/src/MultiSelector/MultiSelector.test.tsx +4 -4
- package/src/NavIcon/NavIcon.doc.mjs +4 -4
- package/src/NavIcon/NavIcon.tsx +2 -2
- package/src/NumberInput/NumberInput.tsx +18 -7
- package/src/Popover/Popover.doc.mjs +10 -10
- package/src/Popover/Popover.spec.md +55 -65
- package/src/Popover/Popover.test.tsx +29 -0
- package/src/Popover/usePopover.doc.mjs +4 -4
- package/src/Popover/usePopover.tsx +7 -4
- package/src/ProgressBar/ProgressBar.doc.mjs +4 -4
- package/src/ProgressBar/ProgressBar.test.tsx +1 -31
- package/src/ProgressBar/ProgressBar.tsx +2 -2
- package/src/RadioList/RadioList.test.tsx +5 -144
- package/src/RadioList/__tests__/RadioGroup.a11y.chromium.spec.ts +255 -0
- package/src/RadioList/__tests__/RadioGroup.a11y.known-failures.ts +12 -0
- package/src/RadioList/__tests__/RadioGroup.a11y.renders.tsx +232 -0
- package/src/RadioList/__tests__/RadioGroup.a11y.states.ts +503 -0
- package/src/RadioList/__tests__/RadioGroup.a11y.test.tsx +217 -0
- package/src/ScrollableArea/ScrollableArea.doc.mjs +100 -0
- package/src/ScrollableArea/ScrollableArea.spec.md +189 -0
- package/src/ScrollableArea/ScrollableArea.test.tsx +299 -0
- package/src/ScrollableArea/ScrollableArea.tsx +259 -0
- package/src/ScrollableArea/index.ts +26 -0
- package/src/ScrollableArea/modules/useScrollableArea.spec.md +121 -0
- package/src/SegmentedControl/SegmentedControl.test.tsx +5 -172
- package/src/Selector/Selector.test.tsx +4 -4
- package/src/Spinner/Spinner.test.tsx +0 -18
- package/src/StatusDot/StatusDot.doc.mjs +4 -4
- package/src/StatusDot/StatusDot.tsx +2 -2
- package/src/TabList/TabList.test.tsx +5 -9
- package/src/TabList/__tests__/Tabs.a11y.chromium.spec.ts +191 -0
- package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +45 -0
- package/src/TabList/__tests__/Tabs.a11y.renders.tsx +92 -0
- package/src/TabList/__tests__/Tabs.a11y.states.ts +247 -0
- package/src/TabList/__tests__/Tabs.a11y.test.tsx +153 -0
- package/src/Table/Table.doc.mjs +2 -2
- package/src/TextArea/TextArea.doc.mjs +4 -4
- package/src/TextArea/TextArea.tsx +2 -2
- package/src/TextInput/TextInput.doc.mjs +2 -1
- package/src/TextInput/TextInput.test.tsx +94 -0
- package/src/TextInput/TextInput.tsx +22 -6
- package/src/TimeInput/TimeInput.tsx +18 -7
- package/src/Toast/ToastViewport.test.tsx +1 -39
- package/src/Typeahead/BaseTypeahead.doc.mjs +229 -33
- package/src/Typeahead/BaseTypeahead.spec.md +269 -0
- package/src/Typeahead/BaseTypeahead.test.tsx +200 -0
- package/src/Typeahead/BaseTypeahead.tsx +99 -30
- package/src/hooks/index.ts +13 -0
- package/src/hooks/scrollGeometry.ts +155 -0
- package/src/hooks/scrollOwnerRegistry.ts +47 -0
- package/src/hooks/useFocusTrap.ts +22 -11
- package/src/hooks/useFocusTrapEscapeShim.test.tsx +4 -3
- package/src/hooks/useScrollableArea.doc.mjs +108 -0
- package/src/hooks/useScrollableArea.test.tsx +437 -0
- package/src/hooks/useScrollableArea.ts +469 -0
- package/src/index.ts +1 -0
- package/src/theme/defineTheme.test.ts +65 -105
- package/src/theme/defineTheme.ts +3 -9
- package/src/theme/derivedVarRegistry.ts +1 -1
- package/src/theme/localTokens.ts +25 -96
- package/src/theme/publicThemeHelperContract.test.ts +2 -2
- package/src/theme/themeAdaptations.test.ts +16 -42
- package/src/theme/themeAdaptations.ts +6 -9
- package/src/utils/themeProps.test.ts +29 -10
- package/src/utils/themeProps.ts +36 -17
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file RadioGroup.a11y.states.ts
|
|
5
|
+
* @input Uses RadioGroupStateFacts from @astryxdesign/a11y-spec
|
|
6
|
+
* @output The AST-021 binding inventory for every current radio-group part, representative states, and explicit exclusions
|
|
7
|
+
* @position Data-only inventory shared by jsdom, Storybook, and Chromium bindings.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {RadioGroupStateFacts} from '@astryxdesign/a11y-spec';
|
|
11
|
+
|
|
12
|
+
export type RadioGroupBinding =
|
|
13
|
+
| 'RadioList'
|
|
14
|
+
| 'RadioListItem'
|
|
15
|
+
| 'SegmentedControl'
|
|
16
|
+
| 'SegmentedControlItem'
|
|
17
|
+
| 'DropdownMenuRadioGroup'
|
|
18
|
+
| 'DropdownMenuRadioItem';
|
|
19
|
+
|
|
20
|
+
export interface RadioGroupRelation {
|
|
21
|
+
readonly role: 'radio' | 'menuitemradio';
|
|
22
|
+
readonly name: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface RadioGroupBindingState {
|
|
26
|
+
readonly id: string;
|
|
27
|
+
readonly binding: RadioGroupBinding;
|
|
28
|
+
readonly summary: string;
|
|
29
|
+
readonly facts: RadioGroupStateFacts;
|
|
30
|
+
readonly subjectName: string | RegExp;
|
|
31
|
+
readonly relations?: Readonly<Record<string, RadioGroupRelation>>;
|
|
32
|
+
readonly storyId: string;
|
|
33
|
+
readonly opensMenu?: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type RadioGroupBindingRow = (typeof RADIO_GROUP_BINDING_STATES)[number];
|
|
37
|
+
export type RadioGroupStateId =
|
|
38
|
+
(typeof RADIO_GROUP_BINDING_STATES)[number]['id'];
|
|
39
|
+
|
|
40
|
+
const DIRECT_RELATIONS = {
|
|
41
|
+
first: {role: 'radio', name: 'Standard'},
|
|
42
|
+
second: {role: 'radio', name: 'Express'},
|
|
43
|
+
third: {role: 'radio', name: 'Overnight'},
|
|
44
|
+
} as const;
|
|
45
|
+
|
|
46
|
+
const MENU_RELATIONS = {
|
|
47
|
+
first: {role: 'menuitemradio', name: 'Newest'},
|
|
48
|
+
second: {role: 'menuitemradio', name: 'Oldest'},
|
|
49
|
+
third: {role: 'menuitemradio', name: 'Most viewed'},
|
|
50
|
+
} as const;
|
|
51
|
+
|
|
52
|
+
function groupFacts(
|
|
53
|
+
overrides: Partial<RadioGroupStateFacts> = {},
|
|
54
|
+
): RadioGroupStateFacts {
|
|
55
|
+
return {
|
|
56
|
+
part: 'group',
|
|
57
|
+
role: 'radiogroup',
|
|
58
|
+
checked: null,
|
|
59
|
+
selection: 'one',
|
|
60
|
+
optionRelations: ['first', 'second', 'third'],
|
|
61
|
+
selectedOption: 'first',
|
|
62
|
+
disabled: false,
|
|
63
|
+
description: null,
|
|
64
|
+
required: false,
|
|
65
|
+
invalid: false,
|
|
66
|
+
operable: true,
|
|
67
|
+
tabReachable: true,
|
|
68
|
+
spaceSelection: true,
|
|
69
|
+
pointerSelection: true,
|
|
70
|
+
arrowSelection: true,
|
|
71
|
+
pointerCancellation: false,
|
|
72
|
+
visibleLabel: true,
|
|
73
|
+
movement: 'horizontal-ltr',
|
|
74
|
+
...overrides,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function optionFacts(
|
|
79
|
+
overrides: Partial<RadioGroupStateFacts> = {},
|
|
80
|
+
): RadioGroupStateFacts {
|
|
81
|
+
return {
|
|
82
|
+
part: 'option',
|
|
83
|
+
role: 'radio',
|
|
84
|
+
checked: false,
|
|
85
|
+
selection: null,
|
|
86
|
+
optionRelations: [],
|
|
87
|
+
selectedOption: null,
|
|
88
|
+
disabled: false,
|
|
89
|
+
description: null,
|
|
90
|
+
required: false,
|
|
91
|
+
invalid: false,
|
|
92
|
+
operable: true,
|
|
93
|
+
tabReachable: false,
|
|
94
|
+
spaceSelection: false,
|
|
95
|
+
pointerSelection: false,
|
|
96
|
+
arrowSelection: false,
|
|
97
|
+
pointerCancellation: true,
|
|
98
|
+
visibleLabel: true,
|
|
99
|
+
movement: 'none',
|
|
100
|
+
...overrides,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const story = (id: string) => `a11y-radio-group-pattern--${id}`;
|
|
105
|
+
|
|
106
|
+
export const RADIO_GROUP_BINDING_STATES = [
|
|
107
|
+
{
|
|
108
|
+
id: 'radio-list-group-selected-ltr',
|
|
109
|
+
binding: 'RadioList',
|
|
110
|
+
summary: 'a horizontal LTR group with one selected option',
|
|
111
|
+
facts: groupFacts(),
|
|
112
|
+
subjectName: 'Delivery speed',
|
|
113
|
+
relations: DIRECT_RELATIONS,
|
|
114
|
+
storyId: story('radio-list-group-selected-ltr'),
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
id: 'radio-list-group-selected-rtl',
|
|
118
|
+
binding: 'RadioList',
|
|
119
|
+
summary: 'a horizontal RTL group with logical arrow movement',
|
|
120
|
+
facts: groupFacts({movement: 'horizontal-rtl'}),
|
|
121
|
+
subjectName: 'Delivery speed',
|
|
122
|
+
relations: DIRECT_RELATIONS,
|
|
123
|
+
storyId: story('radio-list-group-selected-rtl'),
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
id: 'radio-list-group-selected-vertical',
|
|
127
|
+
binding: 'RadioList',
|
|
128
|
+
summary: 'a vertical group with down/up arrow movement',
|
|
129
|
+
facts: groupFacts({movement: 'vertical'}),
|
|
130
|
+
subjectName: 'Delivery speed',
|
|
131
|
+
relations: DIRECT_RELATIONS,
|
|
132
|
+
storyId: story('radio-list-group-selected-vertical'),
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: 'radio-list-group-none-selected',
|
|
136
|
+
binding: 'RadioList',
|
|
137
|
+
summary: 'a group that starts with no selected option',
|
|
138
|
+
facts: groupFacts({
|
|
139
|
+
selection: 'none',
|
|
140
|
+
selectedOption: null,
|
|
141
|
+
movement: 'vertical',
|
|
142
|
+
}),
|
|
143
|
+
subjectName: 'Delivery speed',
|
|
144
|
+
relations: DIRECT_RELATIONS,
|
|
145
|
+
storyId: story('radio-list-group-none-selected'),
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
id: 'radio-list-group-required-invalid-described',
|
|
149
|
+
binding: 'RadioList',
|
|
150
|
+
summary: 'a required invalid group with helper and error text',
|
|
151
|
+
facts: groupFacts({
|
|
152
|
+
selection: 'none',
|
|
153
|
+
selectedOption: null,
|
|
154
|
+
description: 'Choose a delivery speed. Please select an option.',
|
|
155
|
+
required: true,
|
|
156
|
+
invalid: true,
|
|
157
|
+
movement: 'vertical',
|
|
158
|
+
}),
|
|
159
|
+
subjectName: /Delivery speed/,
|
|
160
|
+
relations: DIRECT_RELATIONS,
|
|
161
|
+
storyId: story('radio-list-group-required-invalid-described'),
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: 'radio-list-group-disabled-with-message',
|
|
165
|
+
binding: 'RadioList',
|
|
166
|
+
summary: 'a disabled group whose reason is attached to the group',
|
|
167
|
+
facts: groupFacts({
|
|
168
|
+
disabled: null,
|
|
169
|
+
description: 'Managed by your administrator',
|
|
170
|
+
operable: false,
|
|
171
|
+
spaceSelection: false,
|
|
172
|
+
pointerSelection: false,
|
|
173
|
+
arrowSelection: false,
|
|
174
|
+
movement: 'vertical',
|
|
175
|
+
}),
|
|
176
|
+
subjectName: 'Delivery speed',
|
|
177
|
+
relations: DIRECT_RELATIONS,
|
|
178
|
+
storyId: story('radio-list-group-disabled-with-message'),
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
id: 'radio-list-option-unselected-described',
|
|
182
|
+
binding: 'RadioListItem',
|
|
183
|
+
summary: 'an available unselected option with supporting text',
|
|
184
|
+
facts: optionFacts({description: 'Arrives in three to five days'}),
|
|
185
|
+
subjectName: 'Standard',
|
|
186
|
+
storyId: story('radio-list-option-unselected-described'),
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
id: 'radio-list-option-selected',
|
|
190
|
+
binding: 'RadioListItem',
|
|
191
|
+
summary: 'the selected option in a direct group',
|
|
192
|
+
facts: optionFacts({checked: true, tabReachable: true}),
|
|
193
|
+
subjectName: 'Standard',
|
|
194
|
+
storyId: story('radio-list-option-selected'),
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
id: 'radio-list-option-disabled',
|
|
198
|
+
binding: 'RadioListItem',
|
|
199
|
+
summary: 'an individually disabled option outside the tab sequence',
|
|
200
|
+
facts: optionFacts({
|
|
201
|
+
disabled: true,
|
|
202
|
+
operable: false,
|
|
203
|
+
tabReachable: false,
|
|
204
|
+
pointerCancellation: false,
|
|
205
|
+
}),
|
|
206
|
+
subjectName: 'Express',
|
|
207
|
+
storyId: story('radio-list-option-disabled'),
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
id: 'radio-list-option-group-disabled',
|
|
211
|
+
binding: 'RadioListItem',
|
|
212
|
+
summary: 'an option disabled by its group without a tabReachable reason',
|
|
213
|
+
facts: optionFacts({
|
|
214
|
+
checked: true,
|
|
215
|
+
disabled: true,
|
|
216
|
+
operable: false,
|
|
217
|
+
tabReachable: false,
|
|
218
|
+
pointerCancellation: false,
|
|
219
|
+
}),
|
|
220
|
+
subjectName: 'Standard',
|
|
221
|
+
storyId: story('radio-list-option-group-disabled'),
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
id: 'radio-list-option-disabled-with-message',
|
|
225
|
+
binding: 'RadioListItem',
|
|
226
|
+
summary: 'an unavailable option kept tabReachable for a group-level reason',
|
|
227
|
+
facts: optionFacts({
|
|
228
|
+
checked: true,
|
|
229
|
+
disabled: true,
|
|
230
|
+
operable: false,
|
|
231
|
+
tabReachable: true,
|
|
232
|
+
pointerCancellation: false,
|
|
233
|
+
}),
|
|
234
|
+
subjectName: 'Standard',
|
|
235
|
+
storyId: story('radio-list-option-disabled-with-message'),
|
|
236
|
+
},
|
|
237
|
+
|
|
238
|
+
{
|
|
239
|
+
id: 'segmented-group-selected-ltr',
|
|
240
|
+
binding: 'SegmentedControl',
|
|
241
|
+
summary: 'a horizontal LTR segmented choice with one selected option',
|
|
242
|
+
facts: groupFacts({visibleLabel: false}),
|
|
243
|
+
subjectName: 'View mode',
|
|
244
|
+
relations: {
|
|
245
|
+
first: {role: 'radio', name: 'List'},
|
|
246
|
+
second: {role: 'radio', name: 'Grid'},
|
|
247
|
+
third: {role: 'radio', name: 'Table'},
|
|
248
|
+
},
|
|
249
|
+
storyId: story('segmented-group-selected-ltr'),
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
id: 'segmented-group-selected-rtl',
|
|
253
|
+
binding: 'SegmentedControl',
|
|
254
|
+
summary: 'a horizontal RTL segmented choice with logical arrow movement',
|
|
255
|
+
facts: groupFacts({visibleLabel: false, movement: 'horizontal-rtl'}),
|
|
256
|
+
subjectName: 'View mode',
|
|
257
|
+
relations: {
|
|
258
|
+
first: {role: 'radio', name: 'List'},
|
|
259
|
+
second: {role: 'radio', name: 'Grid'},
|
|
260
|
+
third: {role: 'radio', name: 'Table'},
|
|
261
|
+
},
|
|
262
|
+
storyId: story('segmented-group-selected-rtl'),
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
id: 'segmented-group-none-selected',
|
|
266
|
+
binding: 'SegmentedControl',
|
|
267
|
+
summary: 'a segmented choice whose controlled value matches no option',
|
|
268
|
+
facts: groupFacts({
|
|
269
|
+
selection: 'none',
|
|
270
|
+
selectedOption: null,
|
|
271
|
+
visibleLabel: false,
|
|
272
|
+
}),
|
|
273
|
+
subjectName: 'View mode',
|
|
274
|
+
relations: {
|
|
275
|
+
first: {role: 'radio', name: 'List'},
|
|
276
|
+
second: {role: 'radio', name: 'Grid'},
|
|
277
|
+
third: {role: 'radio', name: 'Table'},
|
|
278
|
+
},
|
|
279
|
+
storyId: story('segmented-group-none-selected'),
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
id: 'segmented-group-disabled',
|
|
283
|
+
binding: 'SegmentedControl',
|
|
284
|
+
summary: 'a disabled segmented group outside the tab sequence',
|
|
285
|
+
facts: groupFacts({
|
|
286
|
+
disabled: true,
|
|
287
|
+
operable: false,
|
|
288
|
+
tabReachable: false,
|
|
289
|
+
spaceSelection: false,
|
|
290
|
+
pointerSelection: false,
|
|
291
|
+
arrowSelection: false,
|
|
292
|
+
visibleLabel: false,
|
|
293
|
+
}),
|
|
294
|
+
subjectName: 'View mode',
|
|
295
|
+
relations: {
|
|
296
|
+
first: {role: 'radio', name: 'List'},
|
|
297
|
+
second: {role: 'radio', name: 'Grid'},
|
|
298
|
+
third: {role: 'radio', name: 'Table'},
|
|
299
|
+
},
|
|
300
|
+
storyId: story('segmented-group-disabled'),
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
id: 'segmented-group-disabled-with-message',
|
|
304
|
+
binding: 'SegmentedControl',
|
|
305
|
+
summary:
|
|
306
|
+
'a disabled segmented group with an attached reason and one tab stop',
|
|
307
|
+
facts: groupFacts({
|
|
308
|
+
disabled: true,
|
|
309
|
+
description: 'Choose a project to switch views',
|
|
310
|
+
operable: false,
|
|
311
|
+
spaceSelection: false,
|
|
312
|
+
pointerSelection: false,
|
|
313
|
+
arrowSelection: false,
|
|
314
|
+
visibleLabel: false,
|
|
315
|
+
}),
|
|
316
|
+
subjectName: 'View mode',
|
|
317
|
+
relations: {
|
|
318
|
+
first: {role: 'radio', name: 'List'},
|
|
319
|
+
second: {role: 'radio', name: 'Grid'},
|
|
320
|
+
third: {role: 'radio', name: 'Table'},
|
|
321
|
+
},
|
|
322
|
+
storyId: story('segmented-group-disabled-with-message'),
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
id: 'segmented-option-unselected',
|
|
326
|
+
binding: 'SegmentedControlItem',
|
|
327
|
+
summary: 'an available unselected segment with a visible label',
|
|
328
|
+
facts: optionFacts(),
|
|
329
|
+
subjectName: 'Grid',
|
|
330
|
+
storyId: story('segmented-option-unselected'),
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
id: 'segmented-option-selected-hidden-label',
|
|
334
|
+
binding: 'SegmentedControlItem',
|
|
335
|
+
summary: 'a selected icon-only segment named programmatically',
|
|
336
|
+
facts: optionFacts({
|
|
337
|
+
checked: true,
|
|
338
|
+
tabReachable: true,
|
|
339
|
+
visibleLabel: false,
|
|
340
|
+
}),
|
|
341
|
+
subjectName: 'List',
|
|
342
|
+
storyId: story('segmented-option-selected-hidden-label'),
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
id: 'segmented-option-disabled',
|
|
346
|
+
binding: 'SegmentedControlItem',
|
|
347
|
+
summary: 'an individually disabled segment',
|
|
348
|
+
facts: optionFacts({
|
|
349
|
+
disabled: true,
|
|
350
|
+
operable: false,
|
|
351
|
+
tabReachable: false,
|
|
352
|
+
pointerCancellation: false,
|
|
353
|
+
}),
|
|
354
|
+
subjectName: 'Grid',
|
|
355
|
+
storyId: story('segmented-option-disabled'),
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
id: 'segmented-option-group-disabled',
|
|
359
|
+
binding: 'SegmentedControlItem',
|
|
360
|
+
summary:
|
|
361
|
+
'a selected segment disabled by its group and removed from Tab order',
|
|
362
|
+
facts: optionFacts({
|
|
363
|
+
checked: true,
|
|
364
|
+
disabled: true,
|
|
365
|
+
operable: false,
|
|
366
|
+
tabReachable: false,
|
|
367
|
+
pointerCancellation: false,
|
|
368
|
+
}),
|
|
369
|
+
subjectName: 'List',
|
|
370
|
+
storyId: story('segmented-option-group-disabled'),
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
id: 'segmented-option-group-disabled-with-message',
|
|
374
|
+
binding: 'SegmentedControlItem',
|
|
375
|
+
summary:
|
|
376
|
+
'a selected unavailable segment kept tabReachable for the group reason',
|
|
377
|
+
facts: optionFacts({
|
|
378
|
+
checked: true,
|
|
379
|
+
disabled: true,
|
|
380
|
+
operable: false,
|
|
381
|
+
tabReachable: true,
|
|
382
|
+
pointerCancellation: false,
|
|
383
|
+
}),
|
|
384
|
+
subjectName: 'List',
|
|
385
|
+
storyId: story('segmented-option-group-disabled-with-message'),
|
|
386
|
+
},
|
|
387
|
+
|
|
388
|
+
{
|
|
389
|
+
id: 'menu-group-selected',
|
|
390
|
+
binding: 'DropdownMenuRadioGroup',
|
|
391
|
+
summary: 'a named menu-radio group with one selected option',
|
|
392
|
+
facts: groupFacts({
|
|
393
|
+
role: 'group',
|
|
394
|
+
disabled: null,
|
|
395
|
+
tabReachable: false,
|
|
396
|
+
spaceSelection: false,
|
|
397
|
+
arrowSelection: false,
|
|
398
|
+
visibleLabel: false,
|
|
399
|
+
movement: 'none',
|
|
400
|
+
}),
|
|
401
|
+
subjectName: 'Sort by',
|
|
402
|
+
relations: MENU_RELATIONS,
|
|
403
|
+
storyId: story('menu-group-selected'),
|
|
404
|
+
opensMenu: true,
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
id: 'menu-group-none-selected',
|
|
408
|
+
binding: 'DropdownMenuRadioGroup',
|
|
409
|
+
summary: 'a named menu-radio group with no selected option',
|
|
410
|
+
facts: groupFacts({
|
|
411
|
+
role: 'group',
|
|
412
|
+
selection: 'none',
|
|
413
|
+
selectedOption: null,
|
|
414
|
+
disabled: null,
|
|
415
|
+
tabReachable: false,
|
|
416
|
+
spaceSelection: false,
|
|
417
|
+
arrowSelection: false,
|
|
418
|
+
visibleLabel: false,
|
|
419
|
+
movement: 'none',
|
|
420
|
+
}),
|
|
421
|
+
subjectName: 'Sort by',
|
|
422
|
+
relations: MENU_RELATIONS,
|
|
423
|
+
storyId: story('menu-group-none-selected'),
|
|
424
|
+
opensMenu: true,
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
id: 'menu-option-unselected-described',
|
|
428
|
+
binding: 'DropdownMenuRadioItem',
|
|
429
|
+
summary:
|
|
430
|
+
'an unselected menu radio whose secondary text participates in its name',
|
|
431
|
+
facts: optionFacts({role: 'menuitemradio', tabReachable: false}),
|
|
432
|
+
subjectName: /Oldest\s*Oldest items first/,
|
|
433
|
+
storyId: story('menu-option-unselected-described'),
|
|
434
|
+
opensMenu: true,
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
id: 'menu-option-selected',
|
|
438
|
+
binding: 'DropdownMenuRadioItem',
|
|
439
|
+
summary: 'a selected radio item inside an opened menu',
|
|
440
|
+
facts: optionFacts({
|
|
441
|
+
role: 'menuitemradio',
|
|
442
|
+
checked: true,
|
|
443
|
+
tabReachable: false,
|
|
444
|
+
}),
|
|
445
|
+
subjectName: 'Newest',
|
|
446
|
+
storyId: story('menu-option-selected'),
|
|
447
|
+
opensMenu: true,
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
id: 'menu-option-disabled',
|
|
451
|
+
binding: 'DropdownMenuRadioItem',
|
|
452
|
+
summary: 'an unavailable radio item inside an opened menu',
|
|
453
|
+
facts: optionFacts({
|
|
454
|
+
role: 'menuitemradio',
|
|
455
|
+
disabled: true,
|
|
456
|
+
operable: false,
|
|
457
|
+
tabReachable: false,
|
|
458
|
+
pointerCancellation: false,
|
|
459
|
+
}),
|
|
460
|
+
subjectName: 'Oldest',
|
|
461
|
+
storyId: story('menu-option-disabled'),
|
|
462
|
+
opensMenu: true,
|
|
463
|
+
},
|
|
464
|
+
] as const satisfies ReadonlyArray<RadioGroupBindingState>;
|
|
465
|
+
|
|
466
|
+
export const RADIO_GROUP_EXCLUSIONS = [
|
|
467
|
+
{
|
|
468
|
+
owner: 'SelectableCard in independent or multi-select composition',
|
|
469
|
+
classification: 'preserved',
|
|
470
|
+
reason:
|
|
471
|
+
'SelectableCard exposes a native checkbox and is already bound to the checkbox contract; visual card selection does not by itself make the control a radio.',
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
owner: 'SelectableCard in caller-managed single-select composition',
|
|
475
|
+
classification: 'needs-human',
|
|
476
|
+
reason:
|
|
477
|
+
'The public API has no role-aware single-select mode or group owner. Adopting radio semantics would require an API and ownership decision, so this migration does not reinterpret the existing checkbox.',
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
owner: 'DropdownMenu and ContextMenu radio-item movement',
|
|
481
|
+
classification: 'out-of-scope',
|
|
482
|
+
reason:
|
|
483
|
+
'Menu owns composite focus, arrows, typeahead, activation, and dismissal. ContextMenu re-exports the same DropdownMenu radio parts, so a duplicate binding would test one implementation twice.',
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
owner: 'TabMenu overflow choices',
|
|
487
|
+
classification: 'out-of-scope',
|
|
488
|
+
reason:
|
|
489
|
+
'TabMenu emits menuitemradio inside its menu-owned overflow navigation; it is not a standalone radio-group part.',
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
owner: 'Pagination dots',
|
|
493
|
+
classification: 'out-of-scope',
|
|
494
|
+
reason:
|
|
495
|
+
'Pagination dots are buttons in a named group with aria-current page semantics, not radio or radiogroup nodes.',
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
owner: 'Home and End keyboard shortcuts',
|
|
499
|
+
classification: 'out-of-scope',
|
|
500
|
+
reason:
|
|
501
|
+
'The APG radio-group pattern does not require Home or End, and no current Astryx record adopts those optional shortcuts as a shared radio-group contract.',
|
|
502
|
+
},
|
|
503
|
+
] as const;
|