@ceed/ads 1.23.3 → 1.23.4
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/dist/components/data-display/Badge.md +71 -39
- package/dist/components/data-display/InfoSign.md +74 -98
- package/dist/components/data-display/Typography.md +310 -61
- package/dist/components/feedback/CircularProgress.md +257 -0
- package/dist/components/feedback/Skeleton.md +280 -0
- package/dist/components/feedback/llms.txt +2 -0
- package/dist/components/inputs/ButtonGroup.md +115 -106
- package/dist/components/inputs/Calendar.md +98 -459
- package/dist/components/inputs/CurrencyInput.md +181 -8
- package/dist/components/inputs/DatePicker.md +108 -436
- package/dist/components/inputs/DateRangePicker.md +130 -496
- package/dist/components/inputs/FilterMenu.md +169 -19
- package/dist/components/inputs/FilterableCheckboxGroup.md +119 -24
- package/dist/components/inputs/FormControl.md +368 -0
- package/dist/components/inputs/IconButton.md +137 -88
- package/dist/components/inputs/MonthPicker.md +95 -427
- package/dist/components/inputs/MonthRangePicker.md +89 -471
- package/dist/components/inputs/PercentageInput.md +183 -19
- package/dist/components/inputs/RadioButton.md +163 -35
- package/dist/components/inputs/RadioList.md +241 -0
- package/dist/components/inputs/RadioTileGroup.md +146 -62
- package/dist/components/inputs/Select.md +219 -328
- package/dist/components/inputs/Slider.md +334 -0
- package/dist/components/inputs/Switch.md +136 -376
- package/dist/components/inputs/Textarea.md +209 -11
- package/dist/components/inputs/Uploader/Uploader.md +145 -66
- package/dist/components/inputs/llms.txt +3 -0
- package/dist/components/navigation/Breadcrumbs.md +80 -322
- package/dist/components/navigation/Dropdown.md +92 -221
- package/dist/components/navigation/IconMenuButton.md +40 -502
- package/dist/components/navigation/InsetDrawer.md +68 -738
- package/dist/components/navigation/Link.md +39 -298
- package/dist/components/navigation/Menu.md +92 -285
- package/dist/components/navigation/MenuButton.md +55 -448
- package/dist/components/navigation/Pagination.md +47 -338
- package/dist/components/navigation/ProfileMenu.md +45 -268
- package/dist/components/navigation/Stepper.md +160 -28
- package/dist/components/navigation/Tabs.md +57 -316
- package/dist/components/surfaces/Sheet.md +150 -333
- package/dist/guides/ThemeProvider.md +116 -0
- package/dist/guides/llms.txt +9 -0
- package/dist/llms.txt +8 -0
- package/package.json +1 -1
|
@@ -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,8 +1,12 @@
|
|
|
1
1
|
# RadioTileGroup
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Introduction
|
|
4
4
|
|
|
5
|
-
|
|
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 사용을 권장합니다**
|
|
6
10
|
>
|
|
7
11
|
> 이 컴포넌트는 `label`, `helperText` 등의 Form 요소를 자체적으로 지원합니다.
|
|
8
12
|
> Form을 구성할 때 Typography로 별도의 label이나 helperText를 만드는 대신, 컴포넌트의 내장 prop을 사용하세요.
|
|
@@ -33,18 +37,36 @@ RadioTileGroup 컴포넌트는 타일 형태의 라디오 옵션을 표시하는
|
|
|
33
37
|
| error | — | — |
|
|
34
38
|
| required | — | — |
|
|
35
39
|
|
|
36
|
-
##
|
|
37
|
-
|
|
38
|
-
RadioTileGroup의 기본 형태입니다. 필수 속성 값으로 `options`를 받으며, 각 옵션은 `value`와 `label`을 포함해야 합니다.
|
|
40
|
+
## Usage
|
|
39
41
|
|
|
40
42
|
```tsx
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
+
}
|
|
45
65
|
```
|
|
46
66
|
|
|
47
|
-
|
|
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.
|
|
48
70
|
|
|
49
71
|
```tsx
|
|
50
72
|
<RadioTileGroup
|
|
@@ -55,10 +77,6 @@ RadioTileGroup의 기본 형태입니다. 필수 속성 값으로 `options`를
|
|
|
55
77
|
/>
|
|
56
78
|
```
|
|
57
79
|
|
|
58
|
-
## 필수 값 표시
|
|
59
|
-
|
|
60
|
-
`required` 속성을 사용하여 필수 입력 필드임을 표시할 수 있습니다.
|
|
61
|
-
|
|
62
80
|
```tsx
|
|
63
81
|
<RadioTileGroup
|
|
64
82
|
options={simpleOptions}
|
|
@@ -69,11 +87,11 @@ RadioTileGroup의 기본 형태입니다. 필수 속성 값으로 `options`를
|
|
|
69
87
|
/>
|
|
70
88
|
```
|
|
71
89
|
|
|
72
|
-
##
|
|
90
|
+
## Layout Options
|
|
73
91
|
|
|
74
92
|
### Flex
|
|
75
93
|
|
|
76
|
-
`flex`
|
|
94
|
+
Enable the `flex` prop to make tiles stretch and fill all available horizontal space equally.
|
|
77
95
|
|
|
78
96
|
```tsx
|
|
79
97
|
<RadioTileGroup
|
|
@@ -85,7 +103,7 @@ RadioTileGroup의 기본 형태입니다. 필수 속성 값으로 `options`를
|
|
|
85
103
|
|
|
86
104
|
### Columns
|
|
87
105
|
|
|
88
|
-
`columns`
|
|
106
|
+
Use the `columns` prop to arrange tiles in a specific number of columns using a grid layout.
|
|
89
107
|
|
|
90
108
|
```tsx
|
|
91
109
|
<RadioTileGroup
|
|
@@ -95,9 +113,9 @@ RadioTileGroup의 기본 형태입니다. 필수 속성 값으로 `options`를
|
|
|
95
113
|
/>
|
|
96
114
|
```
|
|
97
115
|
|
|
98
|
-
### Flex
|
|
116
|
+
### Flex with Columns
|
|
99
117
|
|
|
100
|
-
`flex
|
|
118
|
+
Combine `flex` and `columns` to create a grid where each tile stretches to fill its column width evenly.
|
|
101
119
|
|
|
102
120
|
```tsx
|
|
103
121
|
<Box sx={{
|
|
@@ -113,9 +131,9 @@ Flex with Columns
|
|
|
113
131
|
</Box>
|
|
114
132
|
```
|
|
115
133
|
|
|
116
|
-
###
|
|
134
|
+
### Vertical Layout
|
|
117
135
|
|
|
118
|
-
`columns
|
|
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.
|
|
119
137
|
|
|
120
138
|
```tsx
|
|
121
139
|
<Box sx={{
|
|
@@ -131,9 +149,9 @@ Vertical Layout (columns: 1)
|
|
|
131
149
|
</Box>
|
|
132
150
|
```
|
|
133
151
|
|
|
134
|
-
##
|
|
152
|
+
## Text Alignment
|
|
135
153
|
|
|
136
|
-
`textAlign`
|
|
154
|
+
The `textAlign` prop controls the alignment of content inside each tile. The default is `center`. Set it to `start` for left-aligned content.
|
|
137
155
|
|
|
138
156
|
```tsx
|
|
139
157
|
<Box sx={{
|
|
@@ -162,9 +180,9 @@ Vertical Layout (columns: 1)
|
|
|
162
180
|
</Box>
|
|
163
181
|
```
|
|
164
182
|
|
|
165
|
-
##
|
|
183
|
+
## Sizes
|
|
166
184
|
|
|
167
|
-
RadioTileGroup
|
|
185
|
+
RadioTileGroup supports three sizes: `sm` (default), `md`, and `lg`. Choose the size that best fits the density of your layout.
|
|
168
186
|
|
|
169
187
|
```tsx
|
|
170
188
|
<Box sx={{
|
|
@@ -201,9 +219,9 @@ RadioTileGroup은 세 가지 크기를 지원합니다: `sm`, `md`, `lg`. 기본
|
|
|
201
219
|
</Box>
|
|
202
220
|
```
|
|
203
221
|
|
|
204
|
-
##
|
|
222
|
+
## Icons
|
|
205
223
|
|
|
206
|
-
|
|
224
|
+
Add icons to tiles using the `startDecorator` property on each option. Icons help users visually distinguish between choices at a glance.
|
|
207
225
|
|
|
208
226
|
```tsx
|
|
209
227
|
<RadioTileGroup
|
|
@@ -224,11 +242,11 @@ RadioTileGroup은 세 가지 크기를 지원합니다: `sm`, `md`, `lg`. 기본
|
|
|
224
242
|
/>
|
|
225
243
|
```
|
|
226
244
|
|
|
227
|
-
##
|
|
245
|
+
## State Management
|
|
228
246
|
|
|
229
|
-
### Controlled
|
|
247
|
+
### Controlled
|
|
230
248
|
|
|
231
|
-
|
|
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.
|
|
232
250
|
|
|
233
251
|
```tsx
|
|
234
252
|
<Box sx={{
|
|
@@ -244,9 +262,9 @@ Selected value: {selectedValue}
|
|
|
244
262
|
</Box>
|
|
245
263
|
```
|
|
246
264
|
|
|
247
|
-
### Uncontrolled
|
|
265
|
+
### Uncontrolled
|
|
248
266
|
|
|
249
|
-
|
|
267
|
+
Use `defaultValue` to set an initial selection without managing state externally. The component tracks its own selection internally.
|
|
250
268
|
|
|
251
269
|
```tsx
|
|
252
270
|
<Box sx={{
|
|
@@ -279,11 +297,11 @@ Uncontrolled Example (without Indicator)
|
|
|
279
297
|
</Box>
|
|
280
298
|
```
|
|
281
299
|
|
|
282
|
-
##
|
|
300
|
+
## Disabled State
|
|
283
301
|
|
|
284
|
-
###
|
|
302
|
+
### Fully Disabled
|
|
285
303
|
|
|
286
|
-
`disabled`
|
|
304
|
+
Set the `disabled` prop on the group to disable all tiles.
|
|
287
305
|
|
|
288
306
|
```tsx
|
|
289
307
|
<RadioTileGroup
|
|
@@ -292,9 +310,9 @@ Uncontrolled Example (without Indicator)
|
|
|
292
310
|
/>
|
|
293
311
|
```
|
|
294
312
|
|
|
295
|
-
###
|
|
313
|
+
### Individual Disabled
|
|
296
314
|
|
|
297
|
-
|
|
315
|
+
Set `disabled: true` on specific option objects to disable only those tiles while keeping the rest interactive.
|
|
298
316
|
|
|
299
317
|
```tsx
|
|
300
318
|
<RadioTileGroup
|
|
@@ -312,11 +330,9 @@ Uncontrolled Example (without Indicator)
|
|
|
312
330
|
/>
|
|
313
331
|
```
|
|
314
332
|
|
|
315
|
-
##
|
|
333
|
+
## Error State
|
|
316
334
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
`error` 속성을 사용하여 오류 상태를 표시할 수 있습니다.
|
|
335
|
+
Use the `error` prop to indicate validation errors. Pair it with `helperText` to communicate the issue to the user.
|
|
320
336
|
|
|
321
337
|
```tsx
|
|
322
338
|
<RadioTileGroup
|
|
@@ -328,9 +344,9 @@ Uncontrolled Example (without Indicator)
|
|
|
328
344
|
/>
|
|
329
345
|
```
|
|
330
346
|
|
|
331
|
-
###
|
|
347
|
+
### Form Validation Example
|
|
332
348
|
|
|
333
|
-
`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.
|
|
334
350
|
|
|
335
351
|
```tsx
|
|
336
352
|
<Stack spacing={2} sx={{
|
|
@@ -347,11 +363,32 @@ Uncontrolled Example (without Indicator)
|
|
|
347
363
|
</Stack>
|
|
348
364
|
```
|
|
349
365
|
|
|
350
|
-
##
|
|
366
|
+
## Common Use Cases
|
|
367
|
+
|
|
368
|
+
### Shipping Method Selection
|
|
369
|
+
|
|
370
|
+
Display delivery options with icons so users can choose intuitively.
|
|
351
371
|
|
|
352
|
-
|
|
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';
|
|
353
377
|
|
|
354
|
-
RadioTileGroup
|
|
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
|
+
```
|
|
355
392
|
|
|
356
393
|
```tsx
|
|
357
394
|
<Box sx={{
|
|
@@ -374,9 +411,25 @@ RadioTileGroup은 배송 방법을 시각적으로 선택할 수 있는 인터
|
|
|
374
411
|
</Box>
|
|
375
412
|
```
|
|
376
413
|
|
|
377
|
-
###
|
|
414
|
+
### Survey / Preference Selection
|
|
378
415
|
|
|
379
|
-
|
|
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
|
+
```
|
|
380
433
|
|
|
381
434
|
```tsx
|
|
382
435
|
<Box sx={{
|
|
@@ -403,21 +456,52 @@ RadioTileGroup은 배송 방법을 시각적으로 선택할 수 있는 인터
|
|
|
403
456
|
</Box>
|
|
404
457
|
```
|
|
405
458
|
|
|
406
|
-
###
|
|
459
|
+
### Pricing Plan Picker
|
|
407
460
|
|
|
408
|
-
|
|
461
|
+
Use a vertical layout with `columns={1}` for plan or tier selection.
|
|
409
462
|
|
|
410
463
|
```tsx
|
|
411
|
-
<
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
<
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
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
|
+
/>
|
|
423
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>
|
|
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`.
|