@ceed/ads 1.29.0 → 1.30.0-next.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/dist/components/CurrencyInput/CurrencyInput.d.ts +1 -1
- package/dist/components/CurrencyInput/hooks/use-currency-setting.d.ts +2 -2
- package/dist/components/DataTable/hooks.d.ts +2 -1
- package/dist/components/DataTable/utils.d.ts +1 -0
- package/dist/components/ProfileMenu/ProfileMenu.d.ts +1 -1
- package/dist/components/SearchBar/SearchBar.d.ts +21 -0
- package/dist/components/SearchBar/index.d.ts +3 -0
- package/dist/components/data-display/Badge.md +39 -71
- package/dist/components/data-display/DataTable.md +1 -1
- package/dist/components/data-display/InfoSign.md +98 -74
- package/dist/components/data-display/Typography.md +97 -363
- package/dist/components/feedback/Dialog.md +62 -76
- package/dist/components/feedback/Modal.md +44 -259
- package/dist/components/feedback/llms.txt +0 -2
- package/dist/components/index.d.ts +2 -0
- package/dist/components/inputs/Autocomplete.md +107 -356
- package/dist/components/inputs/ButtonGroup.md +106 -115
- package/dist/components/inputs/Calendar.md +459 -98
- package/dist/components/inputs/CurrencyInput.md +5 -183
- package/dist/components/inputs/DatePicker.md +431 -108
- package/dist/components/inputs/DateRangePicker.md +492 -131
- package/dist/components/inputs/FilterMenu.md +19 -169
- package/dist/components/inputs/FilterableCheckboxGroup.md +23 -123
- package/dist/components/inputs/IconButton.md +88 -137
- package/dist/components/inputs/Input.md +0 -5
- package/dist/components/inputs/MonthPicker.md +422 -95
- package/dist/components/inputs/MonthRangePicker.md +466 -89
- package/dist/components/inputs/PercentageInput.md +16 -185
- package/dist/components/inputs/RadioButton.md +35 -163
- package/dist/components/inputs/RadioTileGroup.md +61 -150
- package/dist/components/inputs/SearchBar.md +44 -0
- package/dist/components/inputs/Select.md +326 -222
- package/dist/components/inputs/Switch.md +376 -136
- package/dist/components/inputs/Textarea.md +10 -213
- package/dist/components/inputs/Uploader/Uploader.md +66 -145
- package/dist/components/inputs/llms.txt +1 -3
- package/dist/components/navigation/Breadcrumbs.md +322 -80
- package/dist/components/navigation/Dropdown.md +221 -92
- package/dist/components/navigation/IconMenuButton.md +502 -40
- package/dist/components/navigation/InsetDrawer.md +738 -68
- package/dist/components/navigation/Link.md +298 -39
- package/dist/components/navigation/Menu.md +285 -92
- package/dist/components/navigation/MenuButton.md +448 -55
- package/dist/components/navigation/Pagination.md +338 -47
- package/dist/components/navigation/ProfileMenu.md +268 -45
- package/dist/components/navigation/Stepper.md +28 -160
- package/dist/components/navigation/Tabs.md +316 -57
- package/dist/components/surfaces/Sheet.md +334 -151
- package/dist/index.browser.js +15 -13
- package/dist/index.browser.js.map +4 -4
- package/dist/index.cjs +313 -291
- package/dist/index.d.ts +1 -1
- package/dist/index.js +450 -372
- package/dist/llms.txt +1 -8
- package/framer/index.js +1 -1
- package/package.json +16 -15
- package/dist/chunks/rehype-accent-FZRUD7VI.js +0 -39
- package/dist/components/feedback/CircularProgress.md +0 -257
- package/dist/components/feedback/Skeleton.md +0 -280
- package/dist/components/inputs/FormControl.md +0 -361
- package/dist/components/inputs/RadioList.md +0 -241
- package/dist/components/inputs/Slider.md +0 -334
- package/dist/guides/ThemeProvider.md +0 -116
- package/dist/guides/llms.txt +0 -9
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Introduction
|
|
4
4
|
|
|
5
|
-
FilterMenu
|
|
6
|
-
|
|
7
|
-
FilterMenu is ideal for data-heavy admin interfaces such as tables, lists, and dashboards where users need to narrow down results based on multiple criteria. It supports both controlled and uncontrolled state management, allowing flexible integration with different state architectures.
|
|
5
|
+
FilterMenu는 다양한 필터 타입을 지원하는 모달 형태의 필터 컴포넌트입니다. 여러 종류의 필터를 조합하여 복잡한 필터링 UI를 쉽게 구성할 수 있습니다.
|
|
8
6
|
|
|
9
7
|
```tsx
|
|
10
8
|
<FilterMenu {...args} defaultValues={values} onChange={newValues => {
|
|
@@ -59,11 +57,11 @@ function MyComponent() {
|
|
|
59
57
|
|
|
60
58
|
## Filter Types
|
|
61
59
|
|
|
62
|
-
FilterMenu
|
|
60
|
+
FilterMenu는 다음과 같은 필터 타입을 지원합니다:
|
|
63
61
|
|
|
64
62
|
### Checkbox Group
|
|
65
63
|
|
|
66
|
-
|
|
64
|
+
다중 선택이 가능한 체크박스 그룹 필터입니다.
|
|
67
65
|
|
|
68
66
|
```tsx
|
|
69
67
|
{
|
|
@@ -79,7 +77,7 @@ Multi-select filter with checkboxes. The selected values are stored as an array.
|
|
|
79
77
|
|
|
80
78
|
### Filterable Checkbox Group
|
|
81
79
|
|
|
82
|
-
|
|
80
|
+
검색 기능이 포함된 체크박스 그룹 필터입니다. 옵션이 많을 때 유용합니다.
|
|
83
81
|
|
|
84
82
|
```tsx
|
|
85
83
|
{
|
|
@@ -89,6 +87,7 @@ A searchable checkbox group for long option lists. Includes a text input to filt
|
|
|
89
87
|
options: [
|
|
90
88
|
{ label: 'Electronics', value: 'electronics' },
|
|
91
89
|
{ label: 'Clothing', value: 'clothing' },
|
|
90
|
+
{ label: 'Food', value: 'food' },
|
|
92
91
|
{ label: 'Books', value: 'books' },
|
|
93
92
|
],
|
|
94
93
|
placeholder: 'Search categories...',
|
|
@@ -98,7 +97,7 @@ A searchable checkbox group for long option lists. Includes a text input to filt
|
|
|
98
97
|
|
|
99
98
|
### Radio Group
|
|
100
99
|
|
|
101
|
-
|
|
100
|
+
단일 선택이 가능한 라디오 버튼 그룹 필터입니다.
|
|
102
101
|
|
|
103
102
|
```tsx
|
|
104
103
|
{
|
|
@@ -115,7 +114,7 @@ Single-select filter with radio buttons. The selected value is stored as a singl
|
|
|
115
114
|
|
|
116
115
|
### Date Range
|
|
117
116
|
|
|
118
|
-
|
|
117
|
+
날짜 범위를 선택할 수 있는 필터입니다.
|
|
119
118
|
|
|
120
119
|
```tsx
|
|
121
120
|
{
|
|
@@ -130,7 +129,7 @@ A date range picker filter. The value is stored as a two-element array of date s
|
|
|
130
129
|
|
|
131
130
|
### Currency Input
|
|
132
131
|
|
|
133
|
-
|
|
132
|
+
단일 통화 값을 입력할 수 있는 필터입니다.
|
|
134
133
|
|
|
135
134
|
```tsx
|
|
136
135
|
{
|
|
@@ -144,7 +143,7 @@ A single currency value input field.
|
|
|
144
143
|
|
|
145
144
|
### Currency Range
|
|
146
145
|
|
|
147
|
-
|
|
146
|
+
통화 범위를 입력할 수 있는 필터입니다.
|
|
148
147
|
|
|
149
148
|
```tsx
|
|
150
149
|
{
|
|
@@ -158,7 +157,7 @@ A currency range filter with min and max inputs.
|
|
|
158
157
|
|
|
159
158
|
### Percentage Input
|
|
160
159
|
|
|
161
|
-
|
|
160
|
+
단일 퍼센트 값을 입력할 수 있는 필터입니다.
|
|
162
161
|
|
|
163
162
|
```tsx
|
|
164
163
|
{
|
|
@@ -173,7 +172,7 @@ A single percentage value input field.
|
|
|
173
172
|
|
|
174
173
|
### Percentage Range
|
|
175
174
|
|
|
176
|
-
|
|
175
|
+
퍼센트 범위를 입력할 수 있는 필터입니다.
|
|
177
176
|
|
|
178
177
|
```tsx
|
|
179
178
|
{
|
|
@@ -187,7 +186,7 @@ A percentage range filter with min and max inputs.
|
|
|
187
186
|
|
|
188
187
|
### Autocomplete
|
|
189
188
|
|
|
190
|
-
|
|
189
|
+
자동완성을 지원하는 선택 필터입니다.
|
|
191
190
|
|
|
192
191
|
```tsx
|
|
193
192
|
{
|
|
@@ -203,8 +202,6 @@ A searchable single-select filter with autocomplete support.
|
|
|
203
202
|
|
|
204
203
|
### Controlled Mode
|
|
205
204
|
|
|
206
|
-
In controlled mode, you manage the filter state externally using `values` (or `defaultValues` with an `onChange` handler).
|
|
207
|
-
|
|
208
205
|
```tsx
|
|
209
206
|
<FilterMenu {...args} defaultValues={values} onChange={newValues => {
|
|
210
207
|
setValues(newValues);
|
|
@@ -214,167 +211,20 @@ In controlled mode, you manage the filter state externally using `values` (or `d
|
|
|
214
211
|
|
|
215
212
|
### Uncontrolled Mode
|
|
216
213
|
|
|
217
|
-
In uncontrolled mode, FilterMenu manages its own internal state. This is useful when you only need the final filter values on submission.
|
|
218
|
-
|
|
219
214
|
```tsx
|
|
220
215
|
<FilterMenu />
|
|
221
216
|
```
|
|
222
217
|
|
|
223
|
-
## Common Use Cases
|
|
224
|
-
|
|
225
|
-
### Table Filters
|
|
226
|
-
|
|
227
|
-
```tsx
|
|
228
|
-
function DataTable() {
|
|
229
|
-
const [filters, setFilters] = useState({});
|
|
230
|
-
const { data } = useQuery(['items', filters], () => fetchItems(filters));
|
|
231
|
-
|
|
232
|
-
return (
|
|
233
|
-
<Box>
|
|
234
|
-
<FilterMenu
|
|
235
|
-
filters={[
|
|
236
|
-
{
|
|
237
|
-
id: 'status',
|
|
238
|
-
type: 'checkbox-group',
|
|
239
|
-
label: 'Status',
|
|
240
|
-
options: [
|
|
241
|
-
{ label: 'Active', value: 'active' },
|
|
242
|
-
{ label: 'Pending', value: 'pending' },
|
|
243
|
-
{ label: 'Archived', value: 'archived' },
|
|
244
|
-
],
|
|
245
|
-
},
|
|
246
|
-
{
|
|
247
|
-
id: 'dateRange',
|
|
248
|
-
type: 'date-range',
|
|
249
|
-
label: 'Created Date',
|
|
250
|
-
displayFormat: 'MM/DD/YYYY',
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
id: 'amount',
|
|
254
|
-
type: 'currency-range',
|
|
255
|
-
label: 'Amount',
|
|
256
|
-
currency: 'USD',
|
|
257
|
-
},
|
|
258
|
-
]}
|
|
259
|
-
defaultValues={filters}
|
|
260
|
-
onChange={setFilters}
|
|
261
|
-
useReset
|
|
262
|
-
/>
|
|
263
|
-
<Table data={data} />
|
|
264
|
-
</Box>
|
|
265
|
-
);
|
|
266
|
-
}
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
### Dashboard Filters
|
|
270
|
-
|
|
271
|
-
```tsx
|
|
272
|
-
function DashboardFilters({ onFilterChange }) {
|
|
273
|
-
return (
|
|
274
|
-
<FilterMenu
|
|
275
|
-
filters={[
|
|
276
|
-
{
|
|
277
|
-
id: 'region',
|
|
278
|
-
type: 'filterable-checkbox-group',
|
|
279
|
-
label: 'Region',
|
|
280
|
-
options: regions.map((r) => ({ label: r.name, value: r.id })),
|
|
281
|
-
placeholder: 'Search regions...',
|
|
282
|
-
maxHeight: 200,
|
|
283
|
-
},
|
|
284
|
-
{
|
|
285
|
-
id: 'period',
|
|
286
|
-
type: 'radio-group',
|
|
287
|
-
label: 'Time Period',
|
|
288
|
-
options: [
|
|
289
|
-
{ label: 'Last 7 days', value: '7d' },
|
|
290
|
-
{ label: 'Last 30 days', value: '30d' },
|
|
291
|
-
{ label: 'Last 90 days', value: '90d' },
|
|
292
|
-
{ label: 'Custom', value: 'custom' },
|
|
293
|
-
],
|
|
294
|
-
},
|
|
295
|
-
]}
|
|
296
|
-
onChange={onFilterChange}
|
|
297
|
-
useReset
|
|
298
|
-
/>
|
|
299
|
-
);
|
|
300
|
-
}
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
### Invoice Filters
|
|
304
|
-
|
|
305
|
-
```tsx
|
|
306
|
-
function InvoiceFilters({ onFilterChange }) {
|
|
307
|
-
return (
|
|
308
|
-
<FilterMenu
|
|
309
|
-
filters={[
|
|
310
|
-
{
|
|
311
|
-
id: 'status',
|
|
312
|
-
type: 'checkbox-group',
|
|
313
|
-
label: 'Invoice Status',
|
|
314
|
-
options: [
|
|
315
|
-
{ label: 'Paid', value: 'paid' },
|
|
316
|
-
{ label: 'Pending', value: 'pending' },
|
|
317
|
-
{ label: 'Overdue', value: 'overdue' },
|
|
318
|
-
],
|
|
319
|
-
},
|
|
320
|
-
{
|
|
321
|
-
id: 'amount',
|
|
322
|
-
type: 'currency-range',
|
|
323
|
-
label: 'Amount Range',
|
|
324
|
-
currency: 'USD',
|
|
325
|
-
useMinorUnit: true,
|
|
326
|
-
},
|
|
327
|
-
{
|
|
328
|
-
id: 'date',
|
|
329
|
-
type: 'date-range',
|
|
330
|
-
label: 'Invoice Date',
|
|
331
|
-
displayFormat: 'MM/DD/YYYY',
|
|
332
|
-
},
|
|
333
|
-
]}
|
|
334
|
-
onChange={onFilterChange}
|
|
335
|
-
useReset
|
|
336
|
-
/>
|
|
337
|
-
);
|
|
338
|
-
}
|
|
339
|
-
```
|
|
340
|
-
|
|
341
218
|
## Best Practices
|
|
342
219
|
|
|
343
|
-
1.
|
|
344
|
-
|
|
345
|
-
```tsx
|
|
346
|
-
// ✅ Good: Unique IDs
|
|
347
|
-
filters={[
|
|
348
|
-
{ id: 'status', type: 'checkbox-group', ... },
|
|
349
|
-
{ id: 'priority', type: 'radio-group', ... },
|
|
350
|
-
]}
|
|
351
|
-
|
|
352
|
-
// ❌ Bad: Duplicate IDs cause state conflicts
|
|
353
|
-
filters={[
|
|
354
|
-
{ id: 'filter1', type: 'checkbox-group', ... },
|
|
355
|
-
{ id: 'filter1', type: 'radio-group', ... },
|
|
356
|
-
]}
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
2. **Choose the right reset strategy**: Use `useReset` when the FilterMenu contains multiple filters that users may want to clear all at once. Use `useClear` for single-filter scenarios.
|
|
360
|
-
|
|
361
|
-
3. **Provide descriptive labels**: Each filter should have a clear `label` that tells users what they are filtering. Avoid generic names like "Filter 1".
|
|
362
|
-
|
|
363
|
-
```tsx
|
|
364
|
-
// ✅ Good: Descriptive labels
|
|
365
|
-
{ id: 'invoiceStatus', type: 'checkbox-group', label: 'Invoice Status', ... }
|
|
366
|
-
|
|
367
|
-
// ❌ Bad: Vague labels
|
|
368
|
-
{ id: 'filter1', type: 'checkbox-group', label: 'Options', ... }
|
|
369
|
-
```
|
|
220
|
+
1. **필터 ID 관리**: 각 필터의 `id`는 고유해야 하며, 상태 관리의 키로 사용됩니다.
|
|
370
221
|
|
|
371
|
-
|
|
222
|
+
2. **타입 안전성**: TypeScript를 사용할 때 FilterItem 타입을 활용하여 타입 안전성을 보장하세요.
|
|
372
223
|
|
|
373
|
-
|
|
224
|
+
3. **Reset vs Clear**:
|
|
225
|
+
- `useReset`: 여러 필터가 있을 때 모든 필터를 초기화
|
|
226
|
+
- `useClear`: 단일 필터만 있을 때 해당 필터를 초기화
|
|
374
227
|
|
|
375
|
-
|
|
228
|
+
4. **상태 관리**: 제어 모드(`values` prop 사용) 또는 비제어 모드(`defaultValues` prop 사용) 중 하나를 선택하여 사용하세요.
|
|
376
229
|
|
|
377
|
-
|
|
378
|
-
- Checkbox and radio groups follow standard form control patterns with proper labeling.
|
|
379
|
-
- The reset button is keyboard-accessible and clearly labeled, allowing users to quickly clear all filters.
|
|
380
|
-
- Use the `placeholder` prop on filterable checkbox groups and autocomplete filters to provide instructional text for assistive technology users.
|
|
230
|
+
5. **접근성**: 각 필터에는 적절한 `label`을 제공하여 접근성을 보장하세요.
|
|
@@ -2,14 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Introduction
|
|
4
4
|
|
|
5
|
-
FilterableCheckboxGroup
|
|
6
|
-
|
|
7
|
-
Key capabilities include a "Select all" toggle for bulk selection, automatic sorting (selected items first, then alphabetical), customizable list height, and built-in form integration via `label`, `helperText`, and `required` props. The component accepts options as either simple strings or `{ value, label }` objects.
|
|
8
|
-
|
|
9
|
-
> **Form 구성 시 내장 prop 사용을 권장합니다**
|
|
10
|
-
>
|
|
11
|
-
> 이 컴포넌트는 `label`, `helperText` 등의 Form 요소를 자체적으로 지원합니다.
|
|
12
|
-
> Form을 구성할 때 Typography로 별도의 label이나 helperText를 만드는 대신, 컴포넌트의 내장 prop을 사용하세요.
|
|
5
|
+
FilterableCheckboxGroup 컴포넌트는 대량의 옵션 중에서 여러 항목을 선택할 수 있는 검색 가능한 체크박스 그룹입니다. 검색 필터링과 가상 스크롤링을 통해 많은 수의 옵션을 효율적으로 처리할 수 있으며, "Select all" 기능으로 일괄 선택이 가능합니다. 필터링, 다중 선택 폼, 설정 화면 등에서 유용하게 사용됩니다.
|
|
13
6
|
|
|
14
7
|
```tsx
|
|
15
8
|
<FilterableCheckboxGroup
|
|
@@ -57,9 +50,11 @@ function MyComponent() {
|
|
|
57
50
|
}
|
|
58
51
|
```
|
|
59
52
|
|
|
60
|
-
##
|
|
53
|
+
## Examples
|
|
54
|
+
|
|
55
|
+
### Sizes
|
|
61
56
|
|
|
62
|
-
|
|
57
|
+
다양한 크기의 FilterableCheckboxGroup을 사용할 수 있습니다.
|
|
63
58
|
|
|
64
59
|
```tsx
|
|
65
60
|
<Stack spacing={3}>
|
|
@@ -69,11 +64,9 @@ Three sizes are available: `sm`, `md`, and `lg`. The size affects the search inp
|
|
|
69
64
|
</Stack>
|
|
70
65
|
```
|
|
71
66
|
|
|
72
|
-
## Label and Helper Text
|
|
73
|
-
|
|
74
67
|
### With Label
|
|
75
68
|
|
|
76
|
-
|
|
69
|
+
라벨을 추가할 수 있습니다.
|
|
77
70
|
|
|
78
71
|
```tsx
|
|
79
72
|
<FilterableCheckboxGroup
|
|
@@ -85,7 +78,7 @@ Use the `label` prop to describe the purpose of the checkbox group.
|
|
|
85
78
|
|
|
86
79
|
### With Helper Text
|
|
87
80
|
|
|
88
|
-
|
|
81
|
+
도움말 텍스트를 추가할 수 있습니다.
|
|
89
82
|
|
|
90
83
|
```tsx
|
|
91
84
|
<FilterableCheckboxGroup
|
|
@@ -98,7 +91,7 @@ Add a `helperText` prop to provide additional guidance below the component.
|
|
|
98
91
|
|
|
99
92
|
### Required Field
|
|
100
93
|
|
|
101
|
-
|
|
94
|
+
필수 입력 필드로 표시할 수 있습니다.
|
|
102
95
|
|
|
103
96
|
```tsx
|
|
104
97
|
<FilterableCheckboxGroup
|
|
@@ -110,9 +103,9 @@ Set `required` to append a required indicator to the label.
|
|
|
110
103
|
/>
|
|
111
104
|
```
|
|
112
105
|
|
|
113
|
-
|
|
106
|
+
### Custom Max Height
|
|
114
107
|
|
|
115
|
-
|
|
108
|
+
목록의 최대 높이를 커스터마이징할 수 있습니다.
|
|
116
109
|
|
|
117
110
|
```tsx
|
|
118
111
|
<Stack spacing={3}>
|
|
@@ -121,9 +114,9 @@ Control the visible height of the options list with the `maxHeight` prop (defaul
|
|
|
121
114
|
</Stack>
|
|
122
115
|
```
|
|
123
116
|
|
|
124
|
-
|
|
117
|
+
### Long List
|
|
125
118
|
|
|
126
|
-
|
|
119
|
+
많은 수의 옵션을 가상 스크롤링으로 효율적으로 표시합니다.
|
|
127
120
|
|
|
128
121
|
```tsx
|
|
129
122
|
<FilterableCheckboxGroup
|
|
@@ -136,9 +129,9 @@ When the options list is large, the component uses virtual scrolling to render o
|
|
|
136
129
|
/>
|
|
137
130
|
```
|
|
138
131
|
|
|
139
|
-
|
|
132
|
+
### No Options
|
|
140
133
|
|
|
141
|
-
|
|
134
|
+
옵션이 없을 때의 상태입니다.
|
|
142
135
|
|
|
143
136
|
```tsx
|
|
144
137
|
<FilterableCheckboxGroup
|
|
@@ -148,9 +141,9 @@ When no options are provided, the component displays an empty state. This is use
|
|
|
148
141
|
/>
|
|
149
142
|
```
|
|
150
143
|
|
|
151
|
-
|
|
144
|
+
### Controlled
|
|
152
145
|
|
|
153
|
-
|
|
146
|
+
외부에서 값을 제어하는 예제입니다.
|
|
154
147
|
|
|
155
148
|
```tsx
|
|
156
149
|
<Stack spacing={2}>
|
|
@@ -162,9 +155,9 @@ Pass `value` and `onChange` to manage the selection state externally. This is th
|
|
|
162
155
|
</Stack>
|
|
163
156
|
```
|
|
164
157
|
|
|
165
|
-
|
|
158
|
+
### Sorting
|
|
166
159
|
|
|
167
|
-
|
|
160
|
+
정렬 동작을 확인할 수 있는 예제입니다. 초기 렌더링 시 선택된 항목이 먼저 표시되고, 그 다음 알파벳 순으로 정렬됩니다.
|
|
168
161
|
|
|
169
162
|
```tsx
|
|
170
163
|
<Stack spacing={2}>
|
|
@@ -198,13 +191,13 @@ The component automatically sorts options on initial render: selected items appe
|
|
|
198
191
|
</Stack>
|
|
199
192
|
```
|
|
200
193
|
|
|
201
|
-
|
|
194
|
+
### Disabled
|
|
202
195
|
|
|
203
|
-
|
|
196
|
+
컴포넌트 전체 또는 특정 옵션을 비활성화할 수 있습니다.
|
|
204
197
|
|
|
205
|
-
-
|
|
206
|
-
-
|
|
207
|
-
- **"Select all"
|
|
198
|
+
- **컴포넌트 전체 비활성화**: `disabled` prop을 사용하여 검색 input, "Select all", 모든 옵션을 비활성화합니다.
|
|
199
|
+
- **특정 옵션 비활성화**: 옵션 객체의 `disabled` 속성을 사용하여 개별 옵션을 비활성화합니다.
|
|
200
|
+
- **"Select all" 동작**: 비활성화된 옵션은 "Select all"의 영향을 받지 않으며, 선택 상태가 유지됩니다.
|
|
208
201
|
|
|
209
202
|
```tsx
|
|
210
203
|
<Stack spacing={3}>
|
|
@@ -223,96 +216,3 @@ The component supports both full and partial disabling.
|
|
|
223
216
|
</Stack>
|
|
224
217
|
</Stack>
|
|
225
218
|
```
|
|
226
|
-
|
|
227
|
-
## Common Use Cases
|
|
228
|
-
|
|
229
|
-
### Filter Panel
|
|
230
|
-
|
|
231
|
-
Use FilterableCheckboxGroup in a sidebar or panel to let users filter a data table or list by multiple criteria.
|
|
232
|
-
|
|
233
|
-
```tsx
|
|
234
|
-
import { FilterableCheckboxGroup } from '@ceed/ads';
|
|
235
|
-
|
|
236
|
-
function FilterPanel({ categories, onFilterChange }) {
|
|
237
|
-
const [selected, setSelected] = useState<string[]>([]);
|
|
238
|
-
|
|
239
|
-
const handleChange = (values: string[]) => {
|
|
240
|
-
setSelected(values);
|
|
241
|
-
onFilterChange(values);
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
return (
|
|
245
|
-
<FilterableCheckboxGroup
|
|
246
|
-
label="Categories"
|
|
247
|
-
placeholder="Search categories..."
|
|
248
|
-
options={categories}
|
|
249
|
-
value={selected}
|
|
250
|
-
onChange={handleChange}
|
|
251
|
-
maxHeight={200}
|
|
252
|
-
/>
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### User Role Assignment
|
|
258
|
-
|
|
259
|
-
Assign multiple roles to a user from a searchable list.
|
|
260
|
-
|
|
261
|
-
```tsx
|
|
262
|
-
<FilterableCheckboxGroup
|
|
263
|
-
label="Assign Roles"
|
|
264
|
-
placeholder="Search roles..."
|
|
265
|
-
helperText="Select all roles that apply to this user"
|
|
266
|
-
options={[
|
|
267
|
-
{ value: 'admin', label: 'Administrator' },
|
|
268
|
-
{ value: 'editor', label: 'Editor' },
|
|
269
|
-
{ value: 'viewer', label: 'Viewer' },
|
|
270
|
-
{ value: 'moderator', label: 'Moderator' },
|
|
271
|
-
{ value: 'billing', label: 'Billing Manager' },
|
|
272
|
-
]}
|
|
273
|
-
required
|
|
274
|
-
value={selectedRoles}
|
|
275
|
-
onChange={setSelectedRoles}
|
|
276
|
-
/>
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
### Region / Country Selection
|
|
280
|
-
|
|
281
|
-
When dealing with a large set of options like countries, the search filter and virtual scrolling work together for fast selection.
|
|
282
|
-
|
|
283
|
-
```tsx
|
|
284
|
-
<FilterableCheckboxGroup
|
|
285
|
-
label="Service Regions"
|
|
286
|
-
placeholder="Search countries..."
|
|
287
|
-
options={allCountries.map((c) => ({ value: c.code, label: c.name }))}
|
|
288
|
-
value={selectedCountries}
|
|
289
|
-
onChange={setSelectedCountries}
|
|
290
|
-
/>
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
## Best Practices
|
|
294
|
-
|
|
295
|
-
1. **Provide a meaningful placeholder.** The search input placeholder should hint at the type of content being filtered (e.g., "Search countries..." instead of a generic "Search...").
|
|
296
|
-
|
|
297
|
-
```tsx
|
|
298
|
-
// ✅ Specific and helpful
|
|
299
|
-
<FilterableCheckboxGroup placeholder="Search countries..." />
|
|
300
|
-
|
|
301
|
-
// ❌ Too generic
|
|
302
|
-
<FilterableCheckboxGroup placeholder="Type here..." />
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
2. **Use `maxHeight` to fit the layout.** In tight spaces like sidebars or modals, set a smaller `maxHeight` to prevent the component from dominating the layout.
|
|
306
|
-
|
|
307
|
-
3. **Prefer controlled mode for form integration.** Always pass `value` and `onChange` when the selected values participate in form submission or affect other UI state.
|
|
308
|
-
|
|
309
|
-
4. **Leverage individual `disabled` for permissions.** When some options should be visible but not selectable (e.g., due to user permissions), disable them individually rather than hiding them. This communicates availability without surprising users.
|
|
310
|
-
|
|
311
|
-
5. **Keep option labels concise.** Long labels will be truncated with an ellipsis. If detailed descriptions are needed, consider using a tooltip or a separate detail view.
|
|
312
|
-
|
|
313
|
-
## Accessibility
|
|
314
|
-
|
|
315
|
-
- The search input is labeled by the component's `label` prop, ensuring screen readers announce its purpose.
|
|
316
|
-
- Each checkbox option uses a native `<input type="checkbox">` with an associated `<label>`, enabling click-on-label and proper screen reader announcements.
|
|
317
|
-
- The "Select all" toggle clearly communicates its tri-state behavior (all, none, indeterminate) to assistive technologies.
|
|
318
|
-
- Keyboard navigation is fully supported: Tab to move between the search input and the checkbox list, Space to toggle individual checkboxes, and standard arrow keys to navigate within the list.
|