@ceed/ads 1.29.1 → 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/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 +289 -288
- package/dist/index.d.ts +1 -1
- package/dist/index.js +426 -369
- 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
|
@@ -1,334 +0,0 @@
|
|
|
1
|
-
# Slider
|
|
2
|
-
|
|
3
|
-
## Introduction
|
|
4
|
-
|
|
5
|
-
The Slider component allows users to select a value or a range of values along a track. It is based on Joy UI's Slider and is useful for settings that require selecting from a continuous or discrete range, such as volume, brightness, price ranges, or percentage values.
|
|
6
|
-
|
|
7
|
-
```tsx
|
|
8
|
-
<Slider
|
|
9
|
-
defaultValue={40}
|
|
10
|
-
sx={{
|
|
11
|
-
width: 300
|
|
12
|
-
}}
|
|
13
|
-
/>
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
| Field | Description | Default |
|
|
17
|
-
| ----------------- | ----------- | ------- |
|
|
18
|
-
| size | — | — |
|
|
19
|
-
| color | — | — |
|
|
20
|
-
| variant | — | — |
|
|
21
|
-
| disabled | — | — |
|
|
22
|
-
| orientation | — | — |
|
|
23
|
-
| valueLabelDisplay | — | — |
|
|
24
|
-
| min | — | — |
|
|
25
|
-
| max | — | — |
|
|
26
|
-
| step | — | — |
|
|
27
|
-
|
|
28
|
-
## Usage
|
|
29
|
-
|
|
30
|
-
```tsx
|
|
31
|
-
import { Slider } from '@ceed/ads';
|
|
32
|
-
|
|
33
|
-
function MyComponent() {
|
|
34
|
-
return <Slider defaultValue={40} />;
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Sizes
|
|
39
|
-
|
|
40
|
-
Slider supports three sizes: `sm`, `md` (default), and `lg`.
|
|
41
|
-
|
|
42
|
-
```tsx
|
|
43
|
-
<Stack gap={3} sx={{
|
|
44
|
-
width: 300
|
|
45
|
-
}}>
|
|
46
|
-
<Box>
|
|
47
|
-
<Typography level="body-sm" sx={{
|
|
48
|
-
mb: 1
|
|
49
|
-
}}>Small</Typography>
|
|
50
|
-
<Slider size="sm" defaultValue={30} />
|
|
51
|
-
</Box>
|
|
52
|
-
<Box>
|
|
53
|
-
<Typography level="body-sm" sx={{
|
|
54
|
-
mb: 1
|
|
55
|
-
}}>Medium</Typography>
|
|
56
|
-
<Slider size="md" defaultValue={50} />
|
|
57
|
-
</Box>
|
|
58
|
-
<Box>
|
|
59
|
-
<Typography level="body-sm" sx={{
|
|
60
|
-
mb: 1
|
|
61
|
-
}}>Large</Typography>
|
|
62
|
-
<Slider size="lg" defaultValue={70} />
|
|
63
|
-
</Box>
|
|
64
|
-
</Stack>
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
```tsx
|
|
68
|
-
<Slider size="sm" defaultValue={30} />
|
|
69
|
-
<Slider size="md" defaultValue={50} />
|
|
70
|
-
<Slider size="lg" defaultValue={70} />
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Colors
|
|
74
|
-
|
|
75
|
-
Five semantic colors are available via the `color` prop.
|
|
76
|
-
|
|
77
|
-
```tsx
|
|
78
|
-
<Stack gap={3} sx={{
|
|
79
|
-
width: 300
|
|
80
|
-
}}>
|
|
81
|
-
<Slider color="primary" defaultValue={40} />
|
|
82
|
-
<Slider color="neutral" defaultValue={40} />
|
|
83
|
-
<Slider color="danger" defaultValue={40} />
|
|
84
|
-
<Slider color="success" defaultValue={40} />
|
|
85
|
-
<Slider color="warning" defaultValue={40} />
|
|
86
|
-
</Stack>
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
## Variants
|
|
90
|
-
|
|
91
|
-
Four visual variants are supported: `solid`, `soft` (default), `outlined`, and `plain`.
|
|
92
|
-
|
|
93
|
-
```tsx
|
|
94
|
-
<Stack gap={3} sx={{
|
|
95
|
-
width: 300
|
|
96
|
-
}}>
|
|
97
|
-
<Slider variant="solid" defaultValue={40} />
|
|
98
|
-
<Slider variant="soft" defaultValue={40} />
|
|
99
|
-
<Slider variant="outlined" defaultValue={40} />
|
|
100
|
-
<Slider variant="plain" defaultValue={40} />
|
|
101
|
-
</Stack>
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Range Slider
|
|
105
|
-
|
|
106
|
-
Pass an array of two values to `defaultValue` (or `value`) to create a range slider with two thumbs.
|
|
107
|
-
|
|
108
|
-
```tsx
|
|
109
|
-
<Box sx={{
|
|
110
|
-
width: 300
|
|
111
|
-
}}>
|
|
112
|
-
<Slider defaultValue={[20, 60]} />
|
|
113
|
-
</Box>
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
```tsx
|
|
117
|
-
<Slider defaultValue={[20, 60]} />
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## With Marks
|
|
121
|
-
|
|
122
|
-
Use the `marks` prop to display labeled marks along the track.
|
|
123
|
-
|
|
124
|
-
```tsx
|
|
125
|
-
<Box sx={{
|
|
126
|
-
width: 300
|
|
127
|
-
}}>
|
|
128
|
-
<Slider defaultValue={50} marks={[{
|
|
129
|
-
value: 0,
|
|
130
|
-
label: '0'
|
|
131
|
-
}, {
|
|
132
|
-
value: 25,
|
|
133
|
-
label: '25'
|
|
134
|
-
}, {
|
|
135
|
-
value: 50,
|
|
136
|
-
label: '50'
|
|
137
|
-
}, {
|
|
138
|
-
value: 75,
|
|
139
|
-
label: '75'
|
|
140
|
-
}, {
|
|
141
|
-
value: 100,
|
|
142
|
-
label: '100'
|
|
143
|
-
}]} />
|
|
144
|
-
</Box>
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
```tsx
|
|
148
|
-
<Slider
|
|
149
|
-
defaultValue={50}
|
|
150
|
-
marks={[
|
|
151
|
-
{ value: 0, label: '0' },
|
|
152
|
-
{ value: 25, label: '25' },
|
|
153
|
-
{ value: 50, label: '50' },
|
|
154
|
-
{ value: 75, label: '75' },
|
|
155
|
-
{ value: 100, label: '100' },
|
|
156
|
-
]}
|
|
157
|
-
/>
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
## Steps
|
|
161
|
-
|
|
162
|
-
Set the `step` prop to control the increment between values. Use `marks={true}` to show a mark at each step.
|
|
163
|
-
|
|
164
|
-
```tsx
|
|
165
|
-
<Box sx={{
|
|
166
|
-
width: 300
|
|
167
|
-
}}>
|
|
168
|
-
<Slider defaultValue={30} step={10} marks min={0} max={100} />
|
|
169
|
-
</Box>
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
```tsx
|
|
173
|
-
<Slider defaultValue={30} step={10} marks min={0} max={100} />
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
## Vertical Orientation
|
|
177
|
-
|
|
178
|
-
Set `orientation="vertical"` to render a vertical slider. Ensure the container has a defined height.
|
|
179
|
-
|
|
180
|
-
```tsx
|
|
181
|
-
<Box sx={{
|
|
182
|
-
height: 200
|
|
183
|
-
}}>
|
|
184
|
-
<Slider orientation="vertical" defaultValue={40} />
|
|
185
|
-
</Box>
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
```tsx
|
|
189
|
-
<Box sx={{ height: 200 }}>
|
|
190
|
-
<Slider orientation="vertical" defaultValue={40} />
|
|
191
|
-
</Box>
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
## Value Label
|
|
195
|
-
|
|
196
|
-
Control the value label tooltip display with `valueLabelDisplay`. Options: `on` (always visible), `auto` (on hover/focus), and `off` (hidden).
|
|
197
|
-
|
|
198
|
-
```tsx
|
|
199
|
-
<Stack gap={4} sx={{
|
|
200
|
-
width: 300,
|
|
201
|
-
pt: 4
|
|
202
|
-
}}>
|
|
203
|
-
<Box>
|
|
204
|
-
<Typography level="body-sm" sx={{
|
|
205
|
-
mb: 2
|
|
206
|
-
}}>Always on</Typography>
|
|
207
|
-
<Slider defaultValue={40} valueLabelDisplay="on" />
|
|
208
|
-
</Box>
|
|
209
|
-
<Box>
|
|
210
|
-
<Typography level="body-sm" sx={{
|
|
211
|
-
mb: 1
|
|
212
|
-
}}>Auto (on hover)</Typography>
|
|
213
|
-
<Slider defaultValue={60} valueLabelDisplay="auto" />
|
|
214
|
-
</Box>
|
|
215
|
-
</Stack>
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
```tsx
|
|
219
|
-
<Slider defaultValue={40} valueLabelDisplay="on" />
|
|
220
|
-
<Slider defaultValue={60} valueLabelDisplay="auto" />
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
## Disabled
|
|
224
|
-
|
|
225
|
-
Set `disabled` to prevent user interaction.
|
|
226
|
-
|
|
227
|
-
```tsx
|
|
228
|
-
<Box sx={{
|
|
229
|
-
width: 300
|
|
230
|
-
}}>
|
|
231
|
-
<Slider defaultValue={40} disabled />
|
|
232
|
-
</Box>
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
## Common Use Cases
|
|
236
|
-
|
|
237
|
-
### Controlled Slider
|
|
238
|
-
|
|
239
|
-
```tsx
|
|
240
|
-
function VolumeControl() {
|
|
241
|
-
const [volume, setVolume] = React.useState(50);
|
|
242
|
-
|
|
243
|
-
return (
|
|
244
|
-
<Stack gap={1}>
|
|
245
|
-
<Typography level="body-sm">Volume: {volume}%</Typography>
|
|
246
|
-
<Slider
|
|
247
|
-
value={volume}
|
|
248
|
-
onChange={(_, newValue) => setVolume(newValue as number)}
|
|
249
|
-
min={0}
|
|
250
|
-
max={100}
|
|
251
|
-
/>
|
|
252
|
-
</Stack>
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### Price Range Filter
|
|
258
|
-
|
|
259
|
-
```tsx
|
|
260
|
-
function PriceRangeFilter() {
|
|
261
|
-
const [range, setRange] = React.useState([20, 80]);
|
|
262
|
-
|
|
263
|
-
return (
|
|
264
|
-
<Stack gap={1}>
|
|
265
|
-
<Typography level="body-sm">
|
|
266
|
-
Price: ${range[0]} — ${range[1]}
|
|
267
|
-
</Typography>
|
|
268
|
-
<Slider
|
|
269
|
-
value={range}
|
|
270
|
-
onChange={(_, newValue) => setRange(newValue as number[])}
|
|
271
|
-
min={0}
|
|
272
|
-
max={200}
|
|
273
|
-
valueLabelDisplay="auto"
|
|
274
|
-
valueLabelFormat={(value) => `$${value}`}
|
|
275
|
-
/>
|
|
276
|
-
</Stack>
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
### Temperature Setting
|
|
282
|
-
|
|
283
|
-
```tsx
|
|
284
|
-
function TemperatureSetting() {
|
|
285
|
-
return (
|
|
286
|
-
<Slider
|
|
287
|
-
defaultValue={22}
|
|
288
|
-
min={16}
|
|
289
|
-
max={30}
|
|
290
|
-
step={0.5}
|
|
291
|
-
marks={[
|
|
292
|
-
{ value: 16, label: '16°C' },
|
|
293
|
-
{ value: 22, label: '22°C' },
|
|
294
|
-
{ value: 30, label: '30°C' },
|
|
295
|
-
]}
|
|
296
|
-
valueLabelDisplay="auto"
|
|
297
|
-
valueLabelFormat={(value) => `${value}°C`}
|
|
298
|
-
/>
|
|
299
|
-
);
|
|
300
|
-
}
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
## Best Practices
|
|
304
|
-
|
|
305
|
-
1. **Always set `min` and `max`**: Provide explicit bounds so users understand the valid range.
|
|
306
|
-
|
|
307
|
-
2. **Use marks for discrete values**: When the slider has meaningful steps, display marks with labels.
|
|
308
|
-
|
|
309
|
-
```tsx
|
|
310
|
-
// ✅ Clear discrete steps
|
|
311
|
-
<Slider step={25} marks={[
|
|
312
|
-
{ value: 0, label: 'Off' },
|
|
313
|
-
{ value: 25, label: 'Low' },
|
|
314
|
-
{ value: 50, label: 'Mid' },
|
|
315
|
-
{ value: 75, label: 'High' },
|
|
316
|
-
{ value: 100, label: 'Max' },
|
|
317
|
-
]} />
|
|
318
|
-
|
|
319
|
-
// ❌ Unlabeled discrete steps — user cannot tell what values mean
|
|
320
|
-
<Slider step={25} />
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
3. **Show the current value**: For precise selections, use `valueLabelDisplay="on"` or display the value in nearby text.
|
|
324
|
-
|
|
325
|
-
4. **Use range sliders for bounds**: When users need to define a range (min–max), pass an array value instead of two separate sliders.
|
|
326
|
-
|
|
327
|
-
5. **Set a reasonable `step`**: For large ranges (0–1000), use a step > 1 to prevent overwhelming precision. For small ranges (0–1), use decimal steps.
|
|
328
|
-
|
|
329
|
-
## Accessibility
|
|
330
|
-
|
|
331
|
-
- Slider renders with `role="slider"` and appropriate `aria-valuemin`, `aria-valuemax`, and `aria-valuenow` attributes.
|
|
332
|
-
- Keyboard support: Arrow keys increment/decrement by one step; Home/End jump to min/max.
|
|
333
|
-
- Add an `aria-label` or visible label to describe what the slider controls (e.g., `aria-label="Volume"`).
|
|
334
|
-
- For range sliders, each thumb has independent ARIA attributes for screen reader navigation.
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
# ThemeProvider
|
|
2
|
-
|
|
3
|
-
## Introduction
|
|
4
|
-
|
|
5
|
-
`ThemeProvider` is the root provider that supplies design tokens across ADS components.
|
|
6
|
-
Internally, it applies Joy UI `CssVarsProvider` and `CssBaseline`, so the default usage is to wrap your app once at the root.
|
|
7
|
-
Because this is an internal design system with pre-defined brand identity, changing tokens via `CustomTheme` is considered an anti-pattern.
|
|
8
|
-
|
|
9
|
-
```tsx
|
|
10
|
-
<ThemeProvider>
|
|
11
|
-
<DemoContent />
|
|
12
|
-
</ThemeProvider>
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
| Field | Description | Default |
|
|
16
|
-
| ---------------------------- | ----------- | ------- |
|
|
17
|
-
| Controls resolved at runtime | — | — |
|
|
18
|
-
|
|
19
|
-
## Usage
|
|
20
|
-
|
|
21
|
-
```tsx
|
|
22
|
-
import { ThemeProvider } from '@ceed/ads';
|
|
23
|
-
|
|
24
|
-
function App() {
|
|
25
|
-
return (
|
|
26
|
-
<ThemeProvider>
|
|
27
|
-
<YourRoutes />
|
|
28
|
-
</ThemeProvider>
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Why It Matters
|
|
34
|
-
|
|
35
|
-
Some components may still render without the provider, but token consistency and baseline styles are not guaranteed.
|
|
36
|
-
Use `ThemeProvider` at the root to ensure a consistent UI across the application.
|
|
37
|
-
|
|
38
|
-
```tsx
|
|
39
|
-
<Stack direction={{
|
|
40
|
-
xs: 'column',
|
|
41
|
-
md: 'row'
|
|
42
|
-
}} spacing={2}>
|
|
43
|
-
<Sheet variant="soft" color="success" sx={{
|
|
44
|
-
p: 1.5,
|
|
45
|
-
borderRadius: 'sm'
|
|
46
|
-
}}>
|
|
47
|
-
<Typography level="title-sm">Without ThemeProvider</Typography>
|
|
48
|
-
</Sheet>
|
|
49
|
-
<Sheet variant="soft" color="primary" sx={{
|
|
50
|
-
p: 1.5,
|
|
51
|
-
borderRadius: 'sm'
|
|
52
|
-
}}>
|
|
53
|
-
<Typography level="title-sm">With ThemeProvider</Typography>
|
|
54
|
-
</Sheet>
|
|
55
|
-
|
|
56
|
-
<Sheet variant="outlined" sx={{
|
|
57
|
-
p: 2,
|
|
58
|
-
flex: 1
|
|
59
|
-
}}>
|
|
60
|
-
<Typography level="title-sm">Without ThemeProvider</Typography>
|
|
61
|
-
<Input label="Project Name" placeholder="Type here" sx={{
|
|
62
|
-
mt: 1.5
|
|
63
|
-
}} />
|
|
64
|
-
</Sheet>
|
|
65
|
-
|
|
66
|
-
<ThemeProvider>
|
|
67
|
-
<Sheet variant="outlined" sx={{
|
|
68
|
-
p: 2,
|
|
69
|
-
flex: 1
|
|
70
|
-
}}>
|
|
71
|
-
<Typography level="title-sm">With ThemeProvider</Typography>
|
|
72
|
-
<Input label="Project Name" placeholder="Type here" sx={{
|
|
73
|
-
mt: 1.5
|
|
74
|
-
}} />
|
|
75
|
-
</Sheet>
|
|
76
|
-
</ThemeProvider>
|
|
77
|
-
</Stack>
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
## Common Use Cases
|
|
81
|
-
|
|
82
|
-
### App Root
|
|
83
|
-
|
|
84
|
-
```tsx
|
|
85
|
-
import { ThemeProvider } from '@ceed/ads';
|
|
86
|
-
|
|
87
|
-
createRoot(document.getElementById('root')!).render(
|
|
88
|
-
<ThemeProvider>
|
|
89
|
-
<App />
|
|
90
|
-
</ThemeProvider>,
|
|
91
|
-
);
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### Storybook/Test Wrapper
|
|
95
|
-
|
|
96
|
-
```tsx
|
|
97
|
-
import { ThemeProvider } from '@ceed/ads';
|
|
98
|
-
|
|
99
|
-
const renderWithTheme = (ui: React.ReactElement) => {
|
|
100
|
-
return render(<ThemeProvider>{ui}</ThemeProvider>);
|
|
101
|
-
};
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Best Practices
|
|
105
|
-
|
|
106
|
-
1. **Use a single provider at the app root**: nested providers increase maintenance complexity.
|
|
107
|
-
2. **Do not create custom themes**: ADS is a standardized internal system with built-in brand identity, and `CustomTheme` usage is an anti-pattern.
|
|
108
|
-
3. **Do not remove the provider**: components may drift from intended tokens and baseline styles.
|
|
109
|
-
4. **Do not mix packages**: use only `@ceed/ads` ThemeProvider in ADS applications.
|
|
110
|
-
|
|
111
|
-
## Accessibility
|
|
112
|
-
|
|
113
|
-
1. **Check color contrast**: make sure text remains readable across component combinations.
|
|
114
|
-
2. **Do not rely on color alone for state**: pair color with text and/or icons.
|
|
115
|
-
3. **Keep focus visibility intact**: ensure keyboard focus rings stay clearly visible.
|
|
116
|
-
4. **Maintain typography consistency**: root-level provider usage ensures predictable reading experience.
|