@ceed/cds 1.34.1 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/dist/components/Accordions/Accordions.d.ts +1 -0
  2. package/dist/components/Alert/Alert.d.ts +5 -5
  3. package/dist/components/Autocomplete/Autocomplete.d.ts +2 -2
  4. package/dist/components/Avatar/Avatar.d.ts +7 -17
  5. package/dist/components/Box/Box.d.ts +1 -0
  6. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +6 -5
  7. package/dist/components/Button/Button.d.ts +3 -2
  8. package/dist/components/Calendar/Calendar.d.ts +1 -0
  9. package/dist/components/Card/Card.d.ts +1 -0
  10. package/dist/components/Checkbox/Checkbox.d.ts +1 -0
  11. package/dist/components/Chip/Chip.d.ts +1 -0
  12. package/dist/components/Container/Container.d.ts +6 -1
  13. package/dist/components/CurrencyInput/CurrencyInput.d.ts +1 -1
  14. package/dist/components/DialogActions/DialogActions.d.ts +1 -0
  15. package/dist/components/DialogContent/DialogContent.d.ts +1 -0
  16. package/dist/components/DialogFrame/DialogFrame.d.ts +1 -1
  17. package/dist/components/DialogTitle/DialogTitle.d.ts +1 -0
  18. package/dist/components/Divider/Divider.d.ts +1 -0
  19. package/dist/components/Drawer/Drawer.d.ts +1 -0
  20. package/dist/components/Dropdown/Dropdown.d.ts +28 -1
  21. package/dist/components/FormControl/FormControl.d.ts +1 -0
  22. package/dist/components/FormHelperText/FormHelperText.d.ts +1 -0
  23. package/dist/components/FormLabel/FormLabel.d.ts +1 -0
  24. package/dist/components/Grid/Grid.d.ts +1 -0
  25. package/dist/components/IconButton/IconButton.d.ts +3 -2
  26. package/dist/components/IconMenuButton/IconMenuButton.d.ts +7 -6
  27. package/dist/components/InfoSign/InfoSign.d.ts +3 -2
  28. package/dist/components/Input/Input.d.ts +8 -22
  29. package/dist/components/InsetDrawer/InsetDrawer.d.ts +1 -0
  30. package/dist/components/Markdown/Markdown.d.ts +9 -24
  31. package/dist/components/Menu/Menu.d.ts +2 -1
  32. package/dist/components/MenuButton/MenuButton.d.ts +10 -8
  33. package/dist/components/Modal/Modal.d.ts +4 -2
  34. package/dist/components/NavigationGroup/NavigationGroup.d.ts +3 -2
  35. package/dist/components/NavigationItem/NavigationItem.d.ts +3 -2
  36. package/dist/components/Navigator/Navigator.d.ts +5 -4
  37. package/dist/components/Pagination/Pagination.d.ts +1 -1
  38. package/dist/components/Radio/Radio.d.ts +1 -0
  39. package/dist/components/RadioList/RadioList.d.ts +3 -2
  40. package/dist/components/Select/Select.d.ts +12 -10
  41. package/dist/components/Sheet/Sheet.d.ts +1 -0
  42. package/dist/components/Stack/Stack.d.ts +1 -0
  43. package/dist/components/Stepper/Stepper.d.ts +2 -1
  44. package/dist/components/Switch/Switch.d.ts +1 -0
  45. package/dist/components/Table/Table.d.ts +7 -5
  46. package/dist/components/Tabs/Tabs.d.ts +1 -0
  47. package/dist/components/Textarea/Textarea.d.ts +8 -20
  48. package/dist/components/Tooltip/Tooltip.d.ts +1 -0
  49. package/dist/components/Typography/Typography.d.ts +1 -0
  50. package/dist/components/Uploader/Uploader.d.ts +18 -17
  51. package/dist/components/data-display/Avatar.md +60 -72
  52. package/dist/components/data-display/Badge.md +197 -181
  53. package/dist/components/data-display/Chip.md +164 -142
  54. package/dist/components/data-display/DataTable.md +843 -338
  55. package/dist/components/data-display/InfoSign.md +1 -3
  56. package/dist/components/data-display/Markdown.md +93 -125
  57. package/dist/components/data-display/Table.md +1453 -1007
  58. package/dist/components/data-display/Typography.md +113 -116
  59. package/dist/components/feedback/Alert.md +80 -86
  60. package/dist/components/feedback/CircularProgress.md +32 -36
  61. package/dist/components/feedback/Dialog.md +25 -17
  62. package/dist/components/feedback/Modal.md +296 -264
  63. package/dist/components/feedback/Skeleton.md +125 -89
  64. package/dist/components/index.d.ts +62 -2
  65. package/dist/components/inputs/Autocomplete.md +191 -95
  66. package/dist/components/inputs/Button.md +83 -83
  67. package/dist/components/inputs/ButtonGroup.md +195 -185
  68. package/dist/components/inputs/Calendar.md +25 -28
  69. package/dist/components/inputs/Checkbox.md +11 -29
  70. package/dist/components/inputs/CurrencyInput.md +4 -4
  71. package/dist/components/inputs/DatePicker.md +229 -110
  72. package/dist/components/inputs/DateRangePicker.md +248 -137
  73. package/dist/components/inputs/FilterableCheckboxGroup.md +115 -55
  74. package/dist/components/inputs/FormControl.md +75 -69
  75. package/dist/components/inputs/IconButton.md +229 -205
  76. package/dist/components/inputs/Input.md +131 -98
  77. package/dist/components/inputs/MonthPicker.md +186 -84
  78. package/dist/components/inputs/MonthRangePicker.md +73 -49
  79. package/dist/components/inputs/PercentageInput.md +15 -31
  80. package/dist/components/inputs/RadioButton.md +320 -256
  81. package/dist/components/inputs/RadioList.md +66 -50
  82. package/dist/components/inputs/RadioTileGroup.md +287 -170
  83. package/dist/components/inputs/SearchBar.md +82 -60
  84. package/dist/components/inputs/Select.md +106 -95
  85. package/dist/components/inputs/Slider.md +153 -102
  86. package/dist/components/inputs/Switch.md +193 -138
  87. package/dist/components/inputs/Textarea.md +15 -20
  88. package/dist/components/inputs/Uploader/Uploader.md +68 -39
  89. package/dist/components/layout/Box.md +841 -662
  90. package/dist/components/layout/Container.md +3 -11
  91. package/dist/components/layout/Grid.md +480 -394
  92. package/dist/components/layout/Stack.md +739 -566
  93. package/dist/components/navigation/Breadcrumbs.md +4 -4
  94. package/dist/components/navigation/Drawer.md +34 -25
  95. package/dist/components/navigation/Dropdown.md +745 -408
  96. package/dist/components/navigation/IconMenuButton.md +14 -6
  97. package/dist/components/navigation/InsetDrawer.md +8 -13
  98. package/dist/components/navigation/Link.md +1 -2
  99. package/dist/components/navigation/Menu.md +623 -502
  100. package/dist/components/navigation/MenuButton.md +18 -10
  101. package/dist/components/navigation/NavigationGroup.md +19 -50
  102. package/dist/components/navigation/NavigationItem.md +6 -6
  103. package/dist/components/navigation/Navigator.md +26 -28
  104. package/dist/components/navigation/Pagination.md +86 -75
  105. package/dist/components/navigation/Stepper.md +2 -12
  106. package/dist/components/navigation/Tabs.md +48 -36
  107. package/dist/components/surfaces/Accordions.md +89 -172
  108. package/dist/components/surfaces/Card.md +1094 -709
  109. package/dist/components/surfaces/Divider.md +562 -412
  110. package/dist/components/surfaces/Sheet.md +700 -518
  111. package/dist/guides/ThemeProvider.md +8 -8
  112. package/dist/index.browser.js +4 -4
  113. package/dist/index.browser.js.map +4 -4
  114. package/dist/index.cjs +1059 -1032
  115. package/dist/index.d.ts +2 -1
  116. package/dist/index.js +705 -670
  117. package/framer/index.js +1 -1
  118. package/package.json +32 -35
@@ -36,11 +36,7 @@ function MyComponent() {
36
36
  const [selectedValue, setSelectedValue] = useState('option1');
37
37
 
38
38
  return (
39
- <RadioGroup
40
- name="example"
41
- value={selectedValue}
42
- onChange={(e) => setSelectedValue(e.target.value)}
43
- >
39
+ <RadioGroup name="example" value={selectedValue} onChange={(e) => setSelectedValue(e.target.value)}>
44
40
  <Radio value="option1" label="Option 1" />
45
41
  <Radio value="option2" label="Option 2" />
46
42
  <Radio value="option3" label="Option 3" />
@@ -55,14 +51,14 @@ Radio supports four visual variants: `outlined` (default), `soft`, `solid`, and
55
51
 
56
52
  ```tsx
57
53
  <FormControl>
58
- <FormLabel>Variants</FormLabel>
59
- <RadioGroup defaultValue="outlined" name="radio-buttons-group">
60
- <Radio value="outlined" label="Outlined" variant="outlined" />
61
- <Radio value="soft" label="Soft" variant="soft" />
62
- <Radio value="solid" label="Solid" variant="solid" />
63
- <Radio value="plain" label="Plain" variant="plain" />
64
- </RadioGroup>
65
- </FormControl>
54
+ <FormLabel>Variants</FormLabel>
55
+ <RadioGroup defaultValue="outlined" name="radio-buttons-group">
56
+ <Radio value="outlined" label="Outlined" variant="outlined" />
57
+ <Radio value="soft" label="Soft" variant="soft" />
58
+ <Radio value="solid" label="Solid" variant="solid" />
59
+ <Radio value="plain" label="Plain" variant="plain" />
60
+ </RadioGroup>
61
+ </FormControl>
66
62
  ```
67
63
 
68
64
  ## Sizes
@@ -71,13 +67,13 @@ Three size presets are available: `sm`, `md` (default), and `lg`. Use smaller si
71
67
 
72
68
  ```tsx
73
69
  <FormControl>
74
- <FormLabel>Sizes</FormLabel>
75
- <RadioGroup defaultValue="medium" name="radio-buttons-group">
76
- <Radio value="small" label="Small" size="sm" />
77
- <Radio value="medium" label="Medium" size="md" />
78
- <Radio value="large" label="Large" size="lg" />
79
- </RadioGroup>
80
- </FormControl>
70
+ <FormLabel>Sizes</FormLabel>
71
+ <RadioGroup defaultValue="medium" name="radio-buttons-group">
72
+ <Radio value="small" label="Small" size="sm" />
73
+ <Radio value="medium" label="Medium" size="md" />
74
+ <Radio value="large" label="Large" size="lg" />
75
+ </RadioGroup>
76
+ </FormControl>
81
77
  ```
82
78
 
83
79
  ## Colors
@@ -86,15 +82,15 @@ Radio supports five semantic colors: `primary`, `neutral`, `danger`, `success`,
86
82
 
87
83
  ```tsx
88
84
  <FormControl>
89
- <FormLabel>Colors</FormLabel>
90
- <RadioGroup defaultValue="medium" name="radio-buttons-group">
91
- <Radio value="primary" label="Primary" color="primary" />
92
- <Radio value="neutral" label="Neutral" color="neutral" />
93
- <Radio value="danger" label="Danger" color="danger" />
94
- <Radio value="success" label="Success" color="success" />
95
- <Radio value="warning" label="Warning" color="warning" />
96
- </RadioGroup>
97
- </FormControl>
85
+ <FormLabel>Colors</FormLabel>
86
+ <RadioGroup defaultValue="medium" name="radio-buttons-group">
87
+ <Radio value="primary" label="Primary" color="primary" />
88
+ <Radio value="neutral" label="Neutral" color="neutral" />
89
+ <Radio value="danger" label="Danger" color="danger" />
90
+ <Radio value="success" label="Success" color="success" />
91
+ <Radio value="warning" label="Warning" color="warning" />
92
+ </RadioGroup>
93
+ </FormControl>
98
94
  ```
99
95
 
100
96
  ## Custom Icons
@@ -102,43 +98,55 @@ Radio supports five semantic colors: `primary`, `neutral`, `danger`, `success`,
102
98
  Replace the default radio indicator with custom icons using the `checkedIcon` prop. This is useful for card-style selectors where the selection state needs a distinctive visual treatment.
103
99
 
104
100
  ```tsx
105
- <RadioGroup aria-label="platform" defaultValue="Website" overlay name="platform" sx={{
106
- flexDirection: 'row',
107
- gap: 2,
108
- [`& .${radioClasses.checked}`]: {
109
- [`& .${radioClasses.action}`]: {
110
- inset: -1,
111
- border: '3px solid',
112
- borderColor: 'primary.500'
113
- }
114
- },
115
- [`& .${radioClasses.radio}`]: {
116
- display: 'contents',
117
- '& > svg': {
118
- zIndex: 2,
119
- position: 'absolute',
120
- top: '-8px',
121
- right: '-8px',
122
- bgcolor: 'background.surface',
123
- borderRadius: '50%'
124
- }
125
- }
126
- }}>
127
- {['Website', 'Documents', 'Social Account'].map(value => <Sheet key={value} variant="outlined" sx={{
128
- borderRadius: 'md',
129
- boxShadow: 'sm',
130
- display: 'flex',
131
- flexDirection: 'column',
132
- alignItems: 'center',
133
- gap: 1.5,
134
- p: 2,
135
- minWidth: 120
136
- }}>
137
- <Radio id={value} value={value} checkedIcon={<CheckCircleRoundedIcon />} />
138
- <Avatar variant="soft" size="sm" />
139
- <FormLabel htmlFor={value}>{value}</FormLabel>
140
- </Sheet>)}
141
- </RadioGroup>
101
+ <RadioGroup
102
+ aria-label="platform"
103
+ defaultValue="Website"
104
+ overlay
105
+ name="platform"
106
+ sx={{
107
+ flexDirection: "row",
108
+ gap: 2,
109
+ [`& .${radioClasses.checked}`]: {
110
+ [`& .${radioClasses.action}`]: {
111
+ inset: -1,
112
+ border: "3px solid",
113
+ borderColor: "primary.500"
114
+ }
115
+ },
116
+ [`& .${radioClasses.radio}`]: {
117
+ display: "contents",
118
+ "& > svg": {
119
+ zIndex: 2,
120
+ position: "absolute",
121
+ top: "-8px",
122
+ right: "-8px",
123
+ bgcolor: "background.surface",
124
+ borderRadius: "50%"
125
+ }
126
+ }
127
+ }}
128
+ >
129
+ {["Website", "Documents", "Social Account"].map((value) => (
130
+ <Sheet
131
+ key={value}
132
+ variant="outlined"
133
+ sx={{
134
+ borderRadius: "md",
135
+ boxShadow: "sm",
136
+ display: "flex",
137
+ flexDirection: "column",
138
+ alignItems: "center",
139
+ gap: 1.5,
140
+ p: 2,
141
+ minWidth: 120
142
+ }}
143
+ >
144
+ <Radio id={value} value={value} checkedIcon={<CheckCircleRoundedIcon />} />
145
+ <Avatar variant="soft" size="sm" />
146
+ <FormLabel htmlFor={value}>{value}</FormLabel>
147
+ </Sheet>
148
+ ))}
149
+ </RadioGroup>
142
150
  ```
143
151
 
144
152
  ## No Icon
@@ -146,52 +154,69 @@ Replace the default radio indicator with custom icons using the `checkedIcon` pr
146
154
  Use the `disableIcon` prop to hide the radio indicator entirely. This pattern is commonly used for card-style selectors where the entire card acts as the selectable target, and the selection state is conveyed through border or background styling.
147
155
 
148
156
  ```tsx
149
- <Box sx={{
150
- width: 300
151
- }}>
152
- <FormLabel id="storage-label" sx={{
153
- mb: 2,
154
- fontWeight: 'xl',
155
- fontSize: 'xs',
156
- letterSpacing: '0.15rem'
157
- }}>
158
- Storage
159
- </FormLabel>
160
- <RadioGroup aria-labelledby="storage-label" defaultValue="512GB" size="lg" sx={{
161
- gap: 1.5
162
- }}>
163
- {['512GB', '1TB', '2TB'].map(value => <Sheet key={value} sx={{
164
- p: 2,
165
- borderRadius: 'md',
166
- boxShadow: 'sm'
167
- }}>
168
- <Radio label={`${value} SSD storage`} overlay disableIcon value={value} slotProps={{
169
- label: ({
170
- checked
171
- }) => ({
172
- sx: {
173
- fontWeight: 'lg',
174
- fontSize: 'md',
175
- color: checked ? 'text.primary' : 'text.secondary'
176
- }
177
- }),
178
- action: ({
179
- checked
180
- }) => ({
181
- sx: theme => ({
182
- ...(checked && {
183
- '--variant-borderWidth': '2px',
184
- '&&': {
185
- // && to increase the specificity to win the base :hover styles
186
- borderColor: theme.vars.palette.primary[500]
187
- }
188
- })
189
- })
190
- })
191
- }} />
192
- </Sheet>)}
193
- </RadioGroup>
194
- </Box>
157
+ <Box
158
+ sx={{
159
+ width: 300
160
+ }}
161
+ >
162
+ <FormLabel
163
+ id="storage-label"
164
+ sx={{
165
+ mb: 2,
166
+ fontWeight: "xl",
167
+ fontSize: "xs",
168
+ letterSpacing: "0.15rem"
169
+ }}
170
+ >
171
+ Storage
172
+ </FormLabel>
173
+ <RadioGroup
174
+ aria-labelledby="storage-label"
175
+ defaultValue="512GB"
176
+ size="lg"
177
+ sx={{
178
+ gap: 1.5
179
+ }}
180
+ >
181
+ {["512GB", "1TB", "2TB"].map((value) => (
182
+ <Sheet
183
+ key={value}
184
+ sx={{
185
+ p: 2,
186
+ borderRadius: "md",
187
+ boxShadow: "sm"
188
+ }}
189
+ >
190
+ <Radio
191
+ label={`${value} SSD storage`}
192
+ overlay
193
+ disableIcon
194
+ value={value}
195
+ slotProps={{
196
+ label: ({ checked }) => ({
197
+ sx: {
198
+ fontWeight: "lg",
199
+ fontSize: "md",
200
+ color: checked ? "text.primary" : "text.secondary"
201
+ }
202
+ }),
203
+ action: ({ checked }) => ({
204
+ sx: (theme) => ({
205
+ ...(checked && {
206
+ "--variant-borderWidth": "2px",
207
+ "&&": {
208
+ // && to increase the specificity to win the base :hover styles
209
+ borderColor: theme.vars.palette.primary[500]
210
+ }
211
+ })
212
+ })
213
+ })
214
+ }}
215
+ />
216
+ </Sheet>
217
+ ))}
218
+ </RadioGroup>
219
+ </Box>
195
220
  ```
196
221
 
197
222
  ## Segmented Controls
@@ -199,42 +224,60 @@ Storage
199
224
  Radio buttons can be styled as segmented controls for compact, inline option switching. This pattern works well for toolbar-style controls where horizontal space is limited.
200
225
 
201
226
  ```tsx
202
- <Box sx={{
203
- display: 'flex',
204
- alignItems: 'center',
205
- gap: 2
206
- }}>
207
- <Typography id="segmented-controls-example" fontWeight="lg" fontSize="sm">
208
- Justify:
209
- </Typography>
210
- <RadioGroup orientation="horizontal" aria-labelledby="segmented-controls-example" name="justify" value={justify} onChange={(event: React.ChangeEvent<HTMLInputElement>) => setJustify(event.target.value)} sx={{
211
- minHeight: 48,
212
- padding: '4px',
213
- borderRadius: '12px',
214
- bgcolor: 'neutral.softBg',
215
- '--RadioGroup-gap': '4px',
216
- '--Radio-actionRadius': '8px'
217
- }}>
218
- {['flex-start', 'center', 'flex-end'].map(item => <Radio key={item} color="neutral" value={item} disableIcon label={item} variant="plain" sx={{
219
- px: 2,
220
- alignItems: 'center'
221
- }} slotProps={{
222
- action: ({
223
- checked
224
- }) => ({
225
- sx: {
226
- ...(checked && {
227
- bgcolor: 'background.surface',
228
- boxShadow: 'sm',
229
- '&:hover': {
230
- bgcolor: 'background.surface'
231
- }
232
- })
233
- }
234
- })
235
- }} />)}
236
- </RadioGroup>
237
- </Box>
227
+ <Box
228
+ sx={{
229
+ display: "flex",
230
+ alignItems: "center",
231
+ gap: 2
232
+ }}
233
+ >
234
+ <Typography id="segmented-controls-example" fontWeight="lg" fontSize="sm">
235
+ Justify:
236
+ </Typography>
237
+ <RadioGroup
238
+ orientation="horizontal"
239
+ aria-labelledby="segmented-controls-example"
240
+ name="justify"
241
+ value={justify}
242
+ onChange={(event: React.ChangeEvent<HTMLInputElement>) => setJustify(event.target.value)}
243
+ sx={{
244
+ minHeight: 48,
245
+ padding: "4px",
246
+ borderRadius: "12px",
247
+ bgcolor: "neutral.softBg",
248
+ "--RadioGroup-gap": "4px",
249
+ "--Radio-actionRadius": "8px"
250
+ }}
251
+ >
252
+ {["flex-start", "center", "flex-end"].map((item) => (
253
+ <Radio
254
+ key={item}
255
+ color="neutral"
256
+ value={item}
257
+ disableIcon
258
+ label={item}
259
+ variant="plain"
260
+ sx={{
261
+ px: 2,
262
+ alignItems: "center"
263
+ }}
264
+ slotProps={{
265
+ action: ({ checked }) => ({
266
+ sx: {
267
+ ...(checked && {
268
+ bgcolor: "background.surface",
269
+ boxShadow: "sm",
270
+ "&:hover": {
271
+ bgcolor: "background.surface"
272
+ }
273
+ })
274
+ }
275
+ })
276
+ }}
277
+ />
278
+ ))}
279
+ </RadioGroup>
280
+ </Box>
238
281
  ```
239
282
 
240
283
  ## Product Attributes
@@ -242,98 +285,132 @@ Radio buttons can be styled as segmented controls for compact, inline option swi
242
285
  Radio groups can be customized to represent product attributes such as colors and sizes. Using `overlay`, `disableIcon`, and custom `Sheet` containers, you can create rich visual selectors.
243
286
 
244
287
  ```tsx
245
- <Box sx={{
246
- overflow: 'auto',
247
- px: 2
248
- }}>
249
- <FormLabel id="product-color-attribute" sx={{
250
- mb: 1.5,
251
- fontWeight: 'xl',
252
- textTransform: 'uppercase',
253
- fontSize: 'xs',
254
- letterSpacing: '0.1em'
255
- }}>
256
- Color
257
- </FormLabel>
258
- <RadioGroup aria-labelledby="product-color-attribute" defaultValue="warning" sx={{
259
- gap: 2,
260
- flexWrap: 'wrap',
261
- flexDirection: 'row'
262
- }}>
263
- {(['primary', 'neutral', 'danger', 'success', 'warning'] as const).map(color => <Sheet key={color} sx={{
264
- position: 'relative',
265
- width: 40,
266
- height: 40,
267
- flexShrink: 0,
268
- bgcolor: `${color}.solidBg`,
269
- borderRadius: '50%',
270
- display: 'flex',
271
- alignItems: 'center',
272
- justifyContent: 'center'
273
- }}>
274
- <Radio overlay variant="solid" color={color} checkedIcon={<Done fontSize="large" />} value={color} slotProps={{
275
- input: {
276
- 'aria-label': color
277
- },
278
- radio: {
279
- sx: {
280
- display: 'contents',
281
- '--variant-borderWidth': '2px'
282
- }
283
- }
284
- }} sx={{
285
- '--joy-focus-outlineOffset': '4px',
286
- '--joy-palette-focusVisible': theme => theme.vars.palette[color][500],
287
- [`& .${radioClasses.action}.${radioClasses.focusVisible}`]: {
288
- outlineWidth: '2px'
289
- }
290
- }} />
291
- </Sheet>)}
292
- </RadioGroup>
293
- <br />
294
- <FormLabel id="product-size-attribute" sx={{
295
- mb: 1.5,
296
- fontWeight: 'xl',
297
- textTransform: 'uppercase',
298
- fontSize: 'xs',
299
- letterSpacing: '0.1em'
300
- }}>
301
- Size
302
- </FormLabel>
303
- <RadioGroup aria-labelledby="product-size-attribute" defaultValue="M" sx={{
304
- gap: 2,
305
- mb: 2,
306
- flexWrap: 'wrap',
307
- flexDirection: 'row'
308
- }}>
309
- {['XS', 'S', 'M', 'L', 'XL'].map(size => <Sheet key={size} sx={{
310
- position: 'relative',
311
- width: 40,
312
- height: 40,
313
- flexShrink: 0,
314
- borderRadius: '50%',
315
- display: 'flex',
316
- alignItems: 'center',
317
- justifyContent: 'center',
318
- '--joy-focus-outlineOffset': '4px',
319
- '--joy-palette-focusVisible': theme => theme.vars.palette.neutral.outlinedBorder,
320
- [`& .${radioClasses.checked}`]: {
321
- [`& .${radioClasses.label}`]: {
322
- fontWeight: 'lg'
323
- },
324
- [`& .${radioClasses.action}`]: {
325
- '--variant-borderWidth': '2px',
326
- borderColor: 'text.secondary'
327
- }
328
- },
329
- [`& .${radioClasses.action}.${radioClasses.focusVisible}`]: {
330
- outlineWidth: '2px'
331
- }
332
- }}>
333
- <Radio color="neutral" overlay disableIcon value={size} label={size} />
334
- </Sheet>)}
335
- </RadioGroup>
336
- </Box>
288
+ <Box
289
+ sx={{
290
+ overflow: "auto",
291
+ px: 2
292
+ }}
293
+ >
294
+ <FormLabel
295
+ id="product-color-attribute"
296
+ sx={{
297
+ mb: 1.5,
298
+ fontWeight: "xl",
299
+ textTransform: "uppercase",
300
+ fontSize: "xs",
301
+ letterSpacing: "0.1em"
302
+ }}
303
+ >
304
+ Color
305
+ </FormLabel>
306
+ <RadioGroup
307
+ aria-labelledby="product-color-attribute"
308
+ defaultValue="warning"
309
+ sx={{
310
+ gap: 2,
311
+ flexWrap: "wrap",
312
+ flexDirection: "row"
313
+ }}
314
+ >
315
+ {(["primary", "neutral", "danger", "success", "warning"] as const).map((color) => (
316
+ <Sheet
317
+ key={color}
318
+ sx={{
319
+ position: "relative",
320
+ width: 40,
321
+ height: 40,
322
+ flexShrink: 0,
323
+ bgcolor: `${color}.solidBg`,
324
+ borderRadius: "50%",
325
+ display: "flex",
326
+ alignItems: "center",
327
+ justifyContent: "center"
328
+ }}
329
+ >
330
+ <Radio
331
+ overlay
332
+ variant="solid"
333
+ color={color}
334
+ checkedIcon={<Done fontSize="large" />}
335
+ value={color}
336
+ slotProps={{
337
+ input: {
338
+ "aria-label": color
339
+ },
340
+ radio: {
341
+ sx: {
342
+ display: "contents",
343
+ "--variant-borderWidth": "2px"
344
+ }
345
+ }
346
+ }}
347
+ sx={{
348
+ "--joy-focus-outlineOffset": "4px",
349
+ "--joy-palette-focusVisible": (theme) => theme.vars.palette[color][500],
350
+ [`& .${radioClasses.action}.${radioClasses.focusVisible}`]: {
351
+ outlineWidth: "2px"
352
+ }
353
+ }}
354
+ />
355
+ </Sheet>
356
+ ))}
357
+ </RadioGroup>
358
+ <br />
359
+ <FormLabel
360
+ id="product-size-attribute"
361
+ sx={{
362
+ mb: 1.5,
363
+ fontWeight: "xl",
364
+ textTransform: "uppercase",
365
+ fontSize: "xs",
366
+ letterSpacing: "0.1em"
367
+ }}
368
+ >
369
+ Size
370
+ </FormLabel>
371
+ <RadioGroup
372
+ aria-labelledby="product-size-attribute"
373
+ defaultValue="M"
374
+ sx={{
375
+ gap: 2,
376
+ mb: 2,
377
+ flexWrap: "wrap",
378
+ flexDirection: "row"
379
+ }}
380
+ >
381
+ {["XS", "S", "M", "L", "XL"].map((size) => (
382
+ <Sheet
383
+ key={size}
384
+ sx={{
385
+ position: "relative",
386
+ width: 40,
387
+ height: 40,
388
+ flexShrink: 0,
389
+ borderRadius: "50%",
390
+ display: "flex",
391
+ alignItems: "center",
392
+ justifyContent: "center",
393
+ "--joy-focus-outlineOffset": "4px",
394
+ "--joy-palette-focusVisible": (theme) => theme.vars.palette.neutral.outlinedBorder,
395
+ [`& .${radioClasses.checked}`]: {
396
+ [`& .${radioClasses.label}`]: {
397
+ fontWeight: "lg"
398
+ },
399
+ [`& .${radioClasses.action}`]: {
400
+ "--variant-borderWidth": "2px",
401
+ borderColor: "text.secondary"
402
+ }
403
+ },
404
+ [`& .${radioClasses.action}.${radioClasses.focusVisible}`]: {
405
+ outlineWidth: "2px"
406
+ }
407
+ }}
408
+ >
409
+ <Radio color="neutral" overlay disableIcon value={size} label={size} />
410
+ </Sheet>
411
+ ))}
412
+ </RadioGroup>
413
+ </Box>
337
414
  ```
338
415
 
339
416
  ## Common Use Cases
@@ -347,11 +424,7 @@ function SurveyQuestion() {
347
424
  return (
348
425
  <FormControl>
349
426
  <FormLabel>How satisfied are you with our service?</FormLabel>
350
- <RadioGroup
351
- name="satisfaction"
352
- value={answer}
353
- onChange={(e) => setAnswer(e.target.value)}
354
- >
427
+ <RadioGroup name="satisfaction" value={answer} onChange={(e) => setAnswer(e.target.value)}>
355
428
  <Radio value="very-satisfied" label="Very Satisfied" color="success" />
356
429
  <Radio value="satisfied" label="Satisfied" />
357
430
  <Radio value="neutral" label="Neutral" />
@@ -372,12 +445,7 @@ function PaymentMethodSelector() {
372
445
  return (
373
446
  <FormControl>
374
447
  <FormLabel>Payment Method</FormLabel>
375
- <RadioGroup
376
- name="payment"
377
- value={method}
378
- onChange={(e) => setMethod(e.target.value)}
379
- sx={{ gap: 1.5 }}
380
- >
448
+ <RadioGroup name="payment" value={method} onChange={(e) => setMethod(e.target.value)} sx={{ gap: 1.5 }}>
381
449
  {[
382
450
  { value: 'credit-card', label: 'Credit Card' },
383
451
  { value: 'bank-transfer', label: 'Bank Transfer' },
@@ -416,11 +484,7 @@ function ShippingOptions() {
416
484
  return (
417
485
  <FormControl>
418
486
  <FormLabel>Shipping Speed</FormLabel>
419
- <RadioGroup
420
- name="shipping"
421
- value={shipping}
422
- onChange={(e) => setShipping(e.target.value)}
423
- >
487
+ <RadioGroup name="shipping" value={shipping} onChange={(e) => setShipping(e.target.value)}>
424
488
  <Radio value="standard" label="Standard (5-7 business days) - Free" />
425
489
  <Radio value="express" label="Express (2-3 business days) - $9.99" />
426
490
  <Radio value="overnight" label="Overnight (next day) - $24.99" />