@ceed/ads 1.25.1-next.3 → 1.26.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 (60) hide show
  1. package/dist/chunks/rehype-accent-FZRUD7VI.js +39 -0
  2. package/dist/components/CurrencyInput/CurrencyInput.d.ts +1 -1
  3. package/dist/components/CurrencyInput/hooks/use-currency-setting.d.ts +2 -2
  4. package/dist/components/DataTable/components.d.ts +2 -1
  5. package/dist/components/DataTable/styled.d.ts +3 -1
  6. package/dist/components/DataTable/types.d.ts +1 -0
  7. package/dist/components/ProfileMenu/ProfileMenu.d.ts +1 -1
  8. package/dist/components/data-display/Badge.md +71 -39
  9. package/dist/components/data-display/DataTable.md +77 -1
  10. package/dist/components/data-display/InfoSign.md +74 -98
  11. package/dist/components/data-display/Typography.md +363 -97
  12. package/dist/components/feedback/CircularProgress.md +257 -0
  13. package/dist/components/feedback/Dialog.md +76 -62
  14. package/dist/components/feedback/Modal.md +259 -44
  15. package/dist/components/feedback/Skeleton.md +280 -0
  16. package/dist/components/feedback/llms.txt +2 -0
  17. package/dist/components/inputs/Autocomplete.md +356 -107
  18. package/dist/components/inputs/ButtonGroup.md +115 -106
  19. package/dist/components/inputs/Calendar.md +98 -459
  20. package/dist/components/inputs/CurrencyInput.md +183 -5
  21. package/dist/components/inputs/DatePicker.md +108 -431
  22. package/dist/components/inputs/DateRangePicker.md +131 -492
  23. package/dist/components/inputs/FilterMenu.md +169 -19
  24. package/dist/components/inputs/FilterableCheckboxGroup.md +123 -23
  25. package/dist/components/inputs/FormControl.md +361 -0
  26. package/dist/components/inputs/IconButton.md +137 -88
  27. package/dist/components/inputs/Input.md +5 -0
  28. package/dist/components/inputs/MonthPicker.md +95 -422
  29. package/dist/components/inputs/MonthRangePicker.md +89 -466
  30. package/dist/components/inputs/PercentageInput.md +185 -16
  31. package/dist/components/inputs/RadioButton.md +163 -35
  32. package/dist/components/inputs/RadioList.md +241 -0
  33. package/dist/components/inputs/RadioTileGroup.md +150 -61
  34. package/dist/components/inputs/Select.md +222 -326
  35. package/dist/components/inputs/Slider.md +334 -0
  36. package/dist/components/inputs/Switch.md +136 -376
  37. package/dist/components/inputs/Textarea.md +213 -10
  38. package/dist/components/inputs/Uploader/Uploader.md +145 -66
  39. package/dist/components/inputs/llms.txt +3 -0
  40. package/dist/components/navigation/Breadcrumbs.md +80 -322
  41. package/dist/components/navigation/Dropdown.md +92 -221
  42. package/dist/components/navigation/IconMenuButton.md +40 -502
  43. package/dist/components/navigation/InsetDrawer.md +68 -738
  44. package/dist/components/navigation/Link.md +39 -298
  45. package/dist/components/navigation/Menu.md +92 -285
  46. package/dist/components/navigation/MenuButton.md +55 -448
  47. package/dist/components/navigation/Pagination.md +47 -338
  48. package/dist/components/navigation/ProfileMenu.md +45 -268
  49. package/dist/components/navigation/Stepper.md +160 -28
  50. package/dist/components/navigation/Tabs.md +57 -316
  51. package/dist/components/surfaces/Sheet.md +151 -334
  52. package/dist/guides/ThemeProvider.md +116 -0
  53. package/dist/guides/llms.txt +9 -0
  54. package/dist/index.browser.js +16 -18
  55. package/dist/index.browser.js.map +4 -4
  56. package/dist/index.cjs +303 -209
  57. package/dist/index.js +381 -343
  58. package/dist/llms.txt +8 -0
  59. package/framer/index.js +1 -166
  60. package/package.json +15 -16
@@ -0,0 +1,241 @@
1
+ # RadioList
2
+
3
+ ## Introduction
4
+
5
+ RadioList is a convenience component that renders a group of radio buttons from a data array. It wraps RadioGroup and Radio internally, providing a simpler API for the common pattern of rendering a list of options. Pass an array of `{ label, value }` items and the component handles the rest.
6
+
7
+ ```tsx
8
+ <RadioList
9
+ items={defaultItems}
10
+ defaultValue="option1"
11
+ />
12
+ ```
13
+
14
+ | Field | Description | Default |
15
+ | ----------- | ----------- | ------- |
16
+ | size | — | — |
17
+ | color | — | — |
18
+ | orientation | — | — |
19
+ | disabled | — | — |
20
+
21
+ ## Usage
22
+
23
+ ```tsx
24
+ import { RadioList } from '@ceed/ads';
25
+
26
+ function MyComponent() {
27
+ return (
28
+ <RadioList
29
+ items={[
30
+ { label: 'Small', value: 'sm' },
31
+ { label: 'Medium', value: 'md' },
32
+ { label: 'Large', value: 'lg' },
33
+ ]}
34
+ defaultValue="md"
35
+ />
36
+ );
37
+ }
38
+ ```
39
+
40
+ ## Basic List
41
+
42
+ A simple radio list with three options and a default selection.
43
+
44
+ ```tsx
45
+ <RadioList items={[{
46
+ label: 'Small',
47
+ value: 'sm'
48
+ }, {
49
+ label: 'Medium',
50
+ value: 'md'
51
+ }, {
52
+ label: 'Large',
53
+ value: 'lg'
54
+ }]} defaultValue="md" />
55
+ ```
56
+
57
+ ## Controlled
58
+
59
+ Use `value` and `onChange` for controlled state management.
60
+
61
+ ```tsx
62
+ <Stack gap={2}>
63
+ <Typography level="body-sm">Selected: {value}</Typography>
64
+ <RadioList items={defaultItems} value={value} onChange={e => setValue((e.target as HTMLInputElement).value)} />
65
+ </Stack>
66
+ ```
67
+
68
+ ```tsx
69
+ function ControlledExample() {
70
+ const [value, setValue] = React.useState('option1');
71
+ return (
72
+ <RadioList
73
+ items={items}
74
+ value={value}
75
+ onChange={(e) => setValue((e.target as HTMLInputElement).value)}
76
+ />
77
+ );
78
+ }
79
+ ```
80
+
81
+ ## With Default Value
82
+
83
+ Use `defaultValue` for uncontrolled usage with an initial selection.
84
+
85
+ ```tsx
86
+ <RadioList items={defaultItems} defaultValue="option2" />
87
+ ```
88
+
89
+ ## Disabled
90
+
91
+ Set `disabled` to prevent all radio buttons from being interacted with.
92
+
93
+ ```tsx
94
+ <RadioList items={defaultItems} defaultValue="option1" disabled />
95
+ ```
96
+
97
+ ## Horizontal Layout
98
+
99
+ Set `orientation="horizontal"` to display options in a row.
100
+
101
+ ```tsx
102
+ <RadioList items={defaultItems} defaultValue="option1" orientation="horizontal" />
103
+ ```
104
+
105
+ ```tsx
106
+ <RadioList
107
+ items={items}
108
+ defaultValue="option1"
109
+ orientation="horizontal"
110
+ />
111
+ ```
112
+
113
+ ## Sizes
114
+
115
+ RadioList supports `sm`, `md` (default), and `lg` sizes. The size is applied to all radio buttons in the group.
116
+
117
+ ```tsx
118
+ <Stack gap={3}>
119
+ <Box>
120
+ <Typography level="body-sm" sx={{
121
+ mb: 1
122
+ }}>Small</Typography>
123
+ <RadioList items={defaultItems} defaultValue="option1" size="sm" />
124
+ </Box>
125
+ <Box>
126
+ <Typography level="body-sm" sx={{
127
+ mb: 1
128
+ }}>Medium</Typography>
129
+ <RadioList items={defaultItems} defaultValue="option1" size="md" />
130
+ </Box>
131
+ <Box>
132
+ <Typography level="body-sm" sx={{
133
+ mb: 1
134
+ }}>Large</Typography>
135
+ <RadioList items={defaultItems} defaultValue="option1" size="lg" />
136
+ </Box>
137
+ </Stack>
138
+ ```
139
+
140
+ ## Colors
141
+
142
+ Five semantic colors are available via the `color` prop.
143
+
144
+ ```tsx
145
+ <Stack gap={3}>
146
+ <RadioList items={defaultItems} defaultValue="option1" color="primary" />
147
+ <RadioList items={defaultItems} defaultValue="option1" color="neutral" />
148
+ <RadioList items={defaultItems} defaultValue="option1" color="danger" />
149
+ <RadioList items={defaultItems} defaultValue="option1" color="success" />
150
+ <RadioList items={defaultItems} defaultValue="option1" color="warning" />
151
+ </Stack>
152
+ ```
153
+
154
+ ## Common Use Cases
155
+
156
+ ### Settings Selection
157
+
158
+ ```tsx
159
+ function LanguageSetting() {
160
+ const [language, setLanguage] = React.useState('en');
161
+
162
+ return (
163
+ <FormControl>
164
+ <FormLabel>Language</FormLabel>
165
+ <RadioList
166
+ items={[
167
+ { label: 'English', value: 'en' },
168
+ { label: '한국어', value: 'ko' },
169
+ { label: '日本語', value: 'ja' },
170
+ ]}
171
+ value={language}
172
+ onChange={(e) => setLanguage((e.target as HTMLInputElement).value)}
173
+ />
174
+ </FormControl>
175
+ );
176
+ }
177
+ ```
178
+
179
+ ### Survey Options
180
+
181
+ ```tsx
182
+ function SatisfactionSurvey() {
183
+ return (
184
+ <FormControl>
185
+ <FormLabel>How satisfied are you?</FormLabel>
186
+ <RadioList
187
+ orientation="horizontal"
188
+ items={[
189
+ { label: 'Very Unsatisfied', value: '1' },
190
+ { label: 'Unsatisfied', value: '2' },
191
+ { label: 'Neutral', value: '3' },
192
+ { label: 'Satisfied', value: '4' },
193
+ { label: 'Very Satisfied', value: '5' },
194
+ ]}
195
+ />
196
+ </FormControl>
197
+ );
198
+ }
199
+ ```
200
+
201
+ ### Dynamic Options from API
202
+
203
+ ```tsx
204
+ function RoleSelector({ roles }: { roles: { id: string; name: string }[] }) {
205
+ return (
206
+ <RadioList
207
+ items={roles.map((role) => ({
208
+ label: role.name,
209
+ value: role.id,
210
+ }))}
211
+ />
212
+ );
213
+ }
214
+ ```
215
+
216
+ ## Best Practices
217
+
218
+ 1. **Use for mutually exclusive choices**: RadioList is for selecting exactly one option from a set. For multiple selections, use Checkbox or FilterableCheckboxGroup.
219
+
220
+ ```tsx
221
+ // ✅ Mutually exclusive — only one role allowed
222
+ <RadioList items={roles} />
223
+
224
+ // ❌ Multiple selections needed — use Checkbox instead
225
+ <RadioList items={permissions} />
226
+ ```
227
+
228
+ 2. **Provide a default value**: Pre-select the most common or recommended option to reduce user effort.
229
+
230
+ 3. **Keep labels concise**: Radio button labels should be short and scannable. Use descriptions elsewhere if more context is needed.
231
+
232
+ 4. **Limit visible options**: For more than 7 options, consider using a Select dropdown instead to save space.
233
+
234
+ 5. **Use horizontal layout sparingly**: Horizontal orientation works well for 2–4 short options. For longer lists, vertical is more readable.
235
+
236
+ ## Accessibility
237
+
238
+ - RadioList renders a `<RadioGroup>` with `role="radiogroup"`, and each option is a `<Radio>` with `role="radio"`.
239
+ - Keyboard navigation: Arrow keys move between options, Space selects the focused option.
240
+ - Wrap in a FormControl with FormLabel to provide an accessible group label.
241
+ - The `disabled` prop sets `aria-disabled` on all radio buttons in the group.
@@ -1,6 +1,15 @@
1
1
  # RadioTileGroup
2
2
 
3
- RadioTileGroup 컴포넌트는 타일 형태의 라디오 옵션을 표시하는 컴포넌트입니다. 각 옵션이 타일 형태로 나타나며, 사용자가 선택할 수 있습니다.
3
+ ## Introduction
4
+
5
+ RadioTileGroup is a selection component that displays radio options as visually distinct tiles. Unlike a standard radio button list, each option occupies a tile card, making selections more prominent and scannable. This is especially useful for choices that benefit from visual emphasis, such as plan selection, category picking, or preference surveys.
6
+
7
+ The component supports flexible layouts (horizontal, grid, vertical), icons via `startDecorator`, three sizes, and built-in form integration with `label`, `helperText`, `error`, and `required` props. It works in both controlled and uncontrolled modes.
8
+
9
+ > **Form 구성 시 내장 prop 사용을 권장합니다**
10
+ >
11
+ > 이 컴포넌트는 `label`, `helperText` 등의 Form 요소를 자체적으로 지원합니다.
12
+ > Form을 구성할 때 Typography로 별도의 label이나 helperText를 만드는 대신, 컴포넌트의 내장 prop을 사용하세요.
4
13
 
5
14
  ```tsx
6
15
  <RadioTileGroup
@@ -28,18 +37,36 @@ RadioTileGroup 컴포넌트는 타일 형태의 라디오 옵션을 표시하는
28
37
  | error | — | — |
29
38
  | required | — | — |
30
39
 
31
- ## 기본형
32
-
33
- RadioTileGroup의 기본 형태입니다. 필수 속성 값으로 `options`를 받으며, 각 옵션은 `value`와 `label`을 포함해야 합니다.
40
+ ## Usage
34
41
 
35
42
  ```tsx
36
- <RadioTileGroup
37
- options={simpleOptions}
38
- useIndicator
39
- />
43
+ import { RadioTileGroup } from '@ceed/ads';
44
+
45
+ function MyComponent() {
46
+ const [value, setValue] = useState('');
47
+
48
+ const options = [
49
+ { value: 'option1', label: 'Option 1' },
50
+ { value: 'option2', label: 'Option 2' },
51
+ { value: 'option3', label: 'Option 3' },
52
+ ];
53
+
54
+ return (
55
+ <RadioTileGroup
56
+ label="Choose an option"
57
+ helperText="Select one of the options below"
58
+ options={options}
59
+ value={value}
60
+ onChange={(e) => setValue(e.target.value)}
61
+ useIndicator
62
+ />
63
+ );
64
+ }
40
65
  ```
41
66
 
42
- `label`과 `helperText`를 함께 사용하면 아래와 같은 모습입니다.
67
+ ## Label and Helper Text
68
+
69
+ Use the `label` and `helperText` props to add descriptive text above and below the tile group. The `required` prop appends a required indicator to the label.
43
70
 
44
71
  ```tsx
45
72
  <RadioTileGroup
@@ -50,10 +77,6 @@ RadioTileGroup의 기본 형태입니다. 필수 속성 값으로 `options`를
50
77
  />
51
78
  ```
52
79
 
53
- ## 필수 값 표시
54
-
55
- `required` 속성을 사용하여 필수 입력 필드임을 표시할 수 있습니다.
56
-
57
80
  ```tsx
58
81
  <RadioTileGroup
59
82
  options={simpleOptions}
@@ -64,11 +87,11 @@ RadioTileGroup의 기본 형태입니다. 필수 속성 값으로 `options`를
64
87
  />
65
88
  ```
66
89
 
67
- ## 레이아웃 옵션
90
+ ## Layout Options
68
91
 
69
92
  ### Flex
70
93
 
71
- `flex` 속성을 활성화하면 RadioTileGroup이 사용 가능한 공간을 균등하게 채웁니다.
94
+ Enable the `flex` prop to make tiles stretch and fill all available horizontal space equally.
72
95
 
73
96
  ```tsx
74
97
  <RadioTileGroup
@@ -80,7 +103,7 @@ RadioTileGroup의 기본 형태입니다. 필수 속성 값으로 `options`를
80
103
 
81
104
  ### Columns
82
105
 
83
- `columns` 속성을 사용하여 타일을 특정 수로 배치할 있습니다.
106
+ Use the `columns` prop to arrange tiles in a specific number of columns using a grid layout.
84
107
 
85
108
  ```tsx
86
109
  <RadioTileGroup
@@ -90,9 +113,9 @@ RadioTileGroup의 기본 형태입니다. 필수 속성 값으로 `options`를
90
113
  />
91
114
  ```
92
115
 
93
- ### Flex Columns 함께 사용
116
+ ### Flex with Columns
94
117
 
95
- `flex`와 `columns` 속성을 함께 사용하여 타일이 균등하게 공간을 채우면서 특정 수로 배치할 있습니다.
118
+ Combine `flex` and `columns` to create a grid where each tile stretches to fill its column width evenly.
96
119
 
97
120
  ```tsx
98
121
  <Box sx={{
@@ -108,9 +131,9 @@ Flex with Columns
108
131
  </Box>
109
132
  ```
110
133
 
111
- ### 수직 레이아웃
134
+ ### Vertical Layout
112
135
 
113
- `columns: 1`로 설정하면 타일이 수직으로 쌓이는 레이아웃을 만들 있습니다.
136
+ Set `columns={1}` to stack tiles vertically. This layout is well-suited for list-style selections like pricing plans or step-by-step options.
114
137
 
115
138
  ```tsx
116
139
  <Box sx={{
@@ -126,9 +149,9 @@ Vertical Layout (columns: 1)
126
149
  </Box>
127
150
  ```
128
151
 
129
- ## 정렬 옵션
152
+ ## Text Alignment
130
153
 
131
- `textAlign` 속성을 사용하여 타일 내부의 콘텐츠 정렬 방식을 설정할 있습니다. 기본값은 `center`이며, `start`로 설정하면 텍스트가 왼쪽으로 정렬됩니다.
154
+ The `textAlign` prop controls the alignment of content inside each tile. The default is `center`. Set it to `start` for left-aligned content.
132
155
 
133
156
  ```tsx
134
157
  <Box sx={{
@@ -157,9 +180,9 @@ Vertical Layout (columns: 1)
157
180
  </Box>
158
181
  ```
159
182
 
160
- ## Size
183
+ ## Sizes
161
184
 
162
- RadioTileGroup 가지 크기를 지원합니다: `sm`, `md`, `lg`. 기본값은 `sm`입니다.
185
+ RadioTileGroup supports three sizes: `sm` (default), `md`, and `lg`. Choose the size that best fits the density of your layout.
163
186
 
164
187
  ```tsx
165
188
  <Box sx={{
@@ -196,9 +219,9 @@ RadioTileGroup은 세 가지 크기를 지원합니다: `sm`, `md`, `lg`. 기본
196
219
  </Box>
197
220
  ```
198
221
 
199
- ## 아이콘 사용
222
+ ## Icons
200
223
 
201
- 옵션에 `startDecorator` 속성을 사용하여 아이콘을 추가할 있습니다.
224
+ Add icons to tiles using the `startDecorator` property on each option. Icons help users visually distinguish between choices at a glance.
202
225
 
203
226
  ```tsx
204
227
  <RadioTileGroup
@@ -219,11 +242,11 @@ RadioTileGroup은 세 가지 크기를 지원합니다: `sm`, `md`, `lg`. 기본
219
242
  />
220
243
  ```
221
244
 
222
- ## 상태 관리
245
+ ## State Management
223
246
 
224
- ### Controlled Component
247
+ ### Controlled
225
248
 
226
- RadioTileGroup은 상태 관리를 위한 제어 컴포넌트(Controlled Component)로 사용할 있습니다.
249
+ Pass `value` and `onChange` to fully control the selected state from the parent component. This is recommended when the selection participates in form state or triggers side effects.
227
250
 
228
251
  ```tsx
229
252
  <Box sx={{
@@ -239,9 +262,9 @@ Selected value: {selectedValue}
239
262
  </Box>
240
263
  ```
241
264
 
242
- ### Uncontrolled Component
265
+ ### Uncontrolled
243
266
 
244
- 또한 비제어 컴포넌트(Uncontrolled Component)로도 사용 가능합니다.
267
+ Use `defaultValue` to set an initial selection without managing state externally. The component tracks its own selection internally.
245
268
 
246
269
  ```tsx
247
270
  <Box sx={{
@@ -274,11 +297,11 @@ Uncontrolled Example (without Indicator)
274
297
  </Box>
275
298
  ```
276
299
 
277
- ## 비활성화 상태
300
+ ## Disabled State
278
301
 
279
- ### 전체 비활성화
302
+ ### Fully Disabled
280
303
 
281
- `disabled` 속성을 사용하여 모든 옵션을 비활성화할 있습니다.
304
+ Set the `disabled` prop on the group to disable all tiles.
282
305
 
283
306
  ```tsx
284
307
  <RadioTileGroup
@@ -287,9 +310,9 @@ Uncontrolled Example (without Indicator)
287
310
  />
288
311
  ```
289
312
 
290
- ### 개별 옵션 비활성화
313
+ ### Individual Disabled
291
314
 
292
- 옵션별로 `disabled` 속성을 설정하여 특정 옵션만 비활성화할 있습니다.
315
+ Set `disabled: true` on specific option objects to disable only those tiles while keeping the rest interactive.
293
316
 
294
317
  ```tsx
295
318
  <RadioTileGroup
@@ -307,11 +330,9 @@ Uncontrolled Example (without Indicator)
307
330
  />
308
331
  ```
309
332
 
310
- ## 상태 표시
311
-
312
- ### 오류 상태
333
+ ## Error State
313
334
 
314
- `error` 속성을 사용하여 오류 상태를 표시할 있습니다.
335
+ Use the `error` prop to indicate validation errors. Pair it with `helperText` to communicate the issue to the user.
315
336
 
316
337
  ```tsx
317
338
  <RadioTileGroup
@@ -323,9 +344,9 @@ Uncontrolled Example (without Indicator)
323
344
  />
324
345
  ```
325
346
 
326
- ### 필수 검증 예제
347
+ ### Form Validation Example
327
348
 
328
- `required` 속성과 함께 오류 상태를 활용하여 필수 검증을 있습니다. 아래는 제출 유효성 검사를 포함한 예제입니다.
349
+ Combine `required`, `error`, and `helperText` to build a complete form validation flow. The example below validates that the user has made a selection before submitting.
329
350
 
330
351
  ```tsx
331
352
  <Stack spacing={2} sx={{
@@ -342,11 +363,32 @@ Uncontrolled Example (without Indicator)
342
363
  </Stack>
343
364
  ```
344
365
 
345
- ## 활용 사례
366
+ ## Common Use Cases
367
+
368
+ ### Shipping Method Selection
346
369
 
347
- ### 배송 방법 선택
370
+ Display delivery options with icons so users can choose intuitively.
348
371
 
349
- RadioTileGroup은 배송 방법을 시각적으로 선택할 수 있는 인터페이스로 활용할 수 있습니다. 각 타일에 아이콘과 함께 배송 방법 정보를 표시하여 사용자가 직관적으로 선택할 수 있도록 합니다.
372
+ ```tsx
373
+ import { RadioTileGroup } from '@ceed/ads';
374
+ import HomeIcon from '@mui/icons-material/Home';
375
+ import LocalShippingIcon from '@mui/icons-material/LocalShipping';
376
+ import BusinessIcon from '@mui/icons-material/Business';
377
+
378
+ <RadioTileGroup
379
+ label="Shipping Method"
380
+ helperText="Delivery fees may vary by method."
381
+ options={[
382
+ { value: 'standard', label: 'Standard', startDecorator: <HomeIcon /> },
383
+ { value: 'express', label: 'Express', startDecorator: <LocalShippingIcon /> },
384
+ { value: 'business', label: 'Business', startDecorator: <BusinessIcon /> },
385
+ ]}
386
+ value={selected}
387
+ onChange={(e) => setSelected(e.target.value)}
388
+ size="md"
389
+ useIndicator
390
+ />
391
+ ```
350
392
 
351
393
  ```tsx
352
394
  <Box sx={{
@@ -369,9 +411,25 @@ RadioTileGroup은 배송 방법을 시각적으로 선택할 수 있는 인터
369
411
  </Box>
370
412
  ```
371
413
 
372
- ### 설문조사
414
+ ### Survey / Preference Selection
373
415
 
374
- 설문조사나 선호도 조사에서 다양한 선택지를 제공하는 활용할 있습니다. 타일에 선택지를 시각적으로 표현하여 사용자가 직관적으로 응답할 수 있도록 합니다.
416
+ Present survey options with icons in a multi-column grid for a clear, scannable layout.
417
+
418
+ ```tsx
419
+ <RadioTileGroup
420
+ label="What type of exercise do you prefer?"
421
+ options={[
422
+ { value: 'cardio', label: 'Cardio', startDecorator: <DirectionsRunIcon /> },
423
+ { value: 'strength', label: 'Strength', startDecorator: <FitnessCenterIcon /> },
424
+ { value: 'flexibility', label: 'Flexibility', startDecorator: <SelfImprovementIcon /> },
425
+ { value: 'balance', label: 'Balance', startDecorator: <BalanceIcon /> },
426
+ ]}
427
+ columns={2}
428
+ size="md"
429
+ value={selected}
430
+ onChange={(e) => setSelected(e.target.value)}
431
+ />
432
+ ```
375
433
 
376
434
  ```tsx
377
435
  <Box sx={{
@@ -398,21 +456,52 @@ RadioTileGroup은 배송 방법을 시각적으로 선택할 수 있는 인터
398
456
  </Box>
399
457
  ```
400
458
 
401
- ### 검증과 함께 사용
459
+ ### Pricing Plan Picker
402
460
 
403
- 검증 기능과 함께 사용하여 사용자가 필수 항목을 선택했는지 확인할 수 있습니다.
461
+ Use a vertical layout with `columns={1}` for plan or tier selection.
404
462
 
405
463
  ```tsx
406
- <Stack spacing={2} sx={{
407
- width: '100%',
408
- maxWidth: 500
409
- }}>
410
- <RadioTileGroup options={simpleOptions} value={selectedValue} onChange={handleChange} label="Choose your preferred option" helperText={error ? 'Please select an option' : 'This selection is required'} error={error} useIndicator={true} required={true} />
411
- <Box sx={{
412
- display: 'flex',
413
- justifyContent: 'flex-end'
414
- }}>
415
- <Button onClick={handleSubmit}>Submit</Button>
416
- </Box>
417
- </Stack>
464
+ <RadioTileGroup
465
+ label="Subscription Plan"
466
+ helperText="Select your preferred plan"
467
+ options={[
468
+ { value: 'basic', label: 'Basic Plan', startDecorator: <AttachMoneyIcon /> },
469
+ { value: 'pro', label: 'Pro Plan', startDecorator: <AttachMoneyIcon /> },
470
+ { value: 'premium', label: 'Premium Plan', startDecorator: <StarIcon /> },
471
+ ]}
472
+ columns={1}
473
+ size="md"
474
+ useIndicator
475
+ value={selected}
476
+ onChange={(e) => setSelected(e.target.value)}
477
+ />
478
+ ```
479
+
480
+ ## Best Practices
481
+
482
+ 1. **Use built-in form props instead of external labels.** The component's `label`, `helperText`, `required`, and `error` props ensure consistent layout and accessibility. Avoid wrapping with separate Typography elements.
483
+
484
+ ```tsx
485
+ // ✅ Recommended
486
+ <RadioTileGroup label="Select option" helperText="Required field" required />
487
+
488
+ // ❌ Avoid
489
+ <Typography>Select option</Typography>
490
+ <RadioTileGroup options={options} />
491
+ <Typography color="danger">Required field</Typography>
418
492
  ```
493
+
494
+ 2. **Choose the right layout for the number of options.** Use the default horizontal flow for 2-4 options. Use `columns` for 5+ options. Use `columns={1}` when each option has long labels or descriptions.
495
+
496
+ 3. **Prefer controlled mode in forms.** When RadioTileGroup is part of a form with validation or submission logic, use `value` and `onChange` for predictable state management.
497
+
498
+ 4. **Add icons only when they aid comprehension.** Icons via `startDecorator` are helpful for visually distinct categories (e.g., shipping methods). Avoid decorating every option if icons do not add meaning.
499
+
500
+ 5. **Always provide an error message.** When `error` is true, update `helperText` to explain the validation issue so users know how to fix it.
501
+
502
+ ## Accessibility
503
+
504
+ - RadioTileGroup renders a `<fieldset>` with a `<legend>` derived from the `label` prop, providing proper grouping for screen readers.
505
+ - Each tile is backed by a native `<input type="radio">`, ensuring full keyboard navigation (arrow keys to move between options, Space/Enter to select).
506
+ - The `disabled` prop correctly applies `aria-disabled` semantics to prevent interaction while keeping elements discoverable by assistive technologies.
507
+ - When `error` is set, pair it with descriptive `helperText` so that screen readers can announce the validation message via `aria-describedby`.