@ceed/cds 1.29.0 → 1.29.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/Overview.md +5 -5
- package/dist/components/data-display/Avatar.md +110 -69
- package/dist/components/data-display/Badge.md +91 -39
- package/dist/components/data-display/Chip.md +49 -20
- package/dist/components/data-display/DataTable.md +93 -0
- package/dist/components/data-display/InfoSign.md +12 -0
- package/dist/components/data-display/Table.md +72 -55
- package/dist/components/data-display/Tooltip.md +40 -40
- package/dist/components/data-display/Typography.md +53 -70
- package/dist/components/feedback/Alert.md +88 -72
- package/dist/components/feedback/CircularProgress.md +17 -0
- package/dist/components/feedback/Skeleton.md +17 -0
- package/dist/components/inputs/Button.md +94 -68
- package/dist/components/inputs/ButtonGroup.md +17 -0
- package/dist/components/inputs/Calendar.md +118 -457
- package/dist/components/inputs/Checkbox.md +185 -430
- package/dist/components/inputs/CurrencyInput.md +22 -0
- package/dist/components/inputs/DatePicker.md +36 -0
- package/dist/components/inputs/DateRangePicker.md +26 -0
- package/dist/components/inputs/FilterableCheckboxGroup.md +20 -3
- package/dist/components/inputs/FormControl.md +32 -2
- package/dist/components/inputs/IconButton.md +18 -0
- package/dist/components/inputs/Input.md +198 -136
- package/dist/components/inputs/MonthPicker.md +25 -0
- package/dist/components/inputs/MonthRangePicker.md +23 -0
- package/dist/components/inputs/PercentageInput.md +25 -0
- package/dist/components/inputs/RadioButton.md +23 -0
- package/dist/components/inputs/RadioList.md +20 -1
- package/dist/components/inputs/RadioTileGroup.md +37 -3
- package/dist/components/inputs/Select.md +56 -0
- package/dist/components/inputs/Slider.md +23 -0
- package/dist/components/inputs/Switch.md +20 -0
- package/dist/components/inputs/Textarea.md +32 -8
- package/dist/components/inputs/Uploader/Uploader.md +21 -0
- package/dist/components/layout/Box.md +52 -41
- package/dist/components/layout/Grid.md +87 -81
- package/dist/components/layout/Stack.md +88 -68
- package/dist/components/navigation/Breadcrumbs.md +57 -46
- package/dist/components/navigation/Drawer.md +17 -0
- package/dist/components/navigation/Dropdown.md +13 -0
- package/dist/components/navigation/IconMenuButton.md +17 -0
- package/dist/components/navigation/InsetDrawer.md +130 -292
- package/dist/components/navigation/Link.md +78 -0
- package/dist/components/navigation/Menu.md +17 -0
- package/dist/components/navigation/MenuButton.md +18 -0
- package/dist/components/navigation/Pagination.md +13 -0
- package/dist/components/navigation/Stepper.md +15 -0
- package/dist/components/navigation/Tabs.md +27 -0
- package/dist/components/surfaces/Accordions.md +804 -49
- package/dist/components/surfaces/Card.md +173 -97
- package/dist/components/surfaces/Divider.md +246 -82
- package/dist/components/surfaces/Sheet.md +15 -0
- package/package.json +1 -1
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Introduction
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Input comes with built-in form integration features such as labels, helper text, error states, and clearable functionality. It also provides specialized behavior for password fields with an automatic visibility toggle.
|
|
5
|
+
Input is a single-line text field component for capturing user input. Built on Joy UI's Input with Framer Motion animation support, it includes built-in form field composition (`label`, `helperText`, `error`) so you can build complete form fields without manual `FormControl` wrappers. It supports clearable inputs, password visibility toggling, and start/end decorators.
|
|
8
6
|
|
|
9
7
|
```tsx
|
|
10
8
|
<Input />
|
|
@@ -35,20 +33,8 @@ Input comes with built-in form integration features such as labels, helper text,
|
|
|
35
33
|
|
|
36
34
|
> **Use built-in form props**
|
|
37
35
|
>
|
|
38
|
-
> This component natively supports `label
|
|
39
|
-
> When building forms, use these built-in props instead of manually composing labels and helper text with Typography
|
|
40
|
-
>
|
|
41
|
-
> ```tsx
|
|
42
|
-
> // Recommended: use built-in props
|
|
43
|
-
> <Input label="Email" helperText="We'll never share your email." error={!isValid} />
|
|
44
|
-
>
|
|
45
|
-
> // Not recommended: manual composition with Typography
|
|
46
|
-
> <FormControl>
|
|
47
|
-
> <Typography component="label">Email</Typography>
|
|
48
|
-
> <Input />
|
|
49
|
-
> <Typography level="body-xs">We'll never share your email.</Typography>
|
|
50
|
-
> </FormControl>
|
|
51
|
-
> ```
|
|
36
|
+
> This component natively supports `label` and `helperText` props.
|
|
37
|
+
> When building forms, use these built-in props instead of manually composing labels and helper text with Typography.
|
|
52
38
|
|
|
53
39
|
## Usage
|
|
54
40
|
|
|
@@ -56,29 +42,22 @@ Input comes with built-in form integration features such as labels, helper text,
|
|
|
56
42
|
import { Input } from '@ceed/cds';
|
|
57
43
|
|
|
58
44
|
function MyComponent() {
|
|
45
|
+
const [value, setValue] = useState('');
|
|
46
|
+
|
|
59
47
|
return (
|
|
60
48
|
<Input
|
|
61
|
-
label="
|
|
62
|
-
placeholder="Enter your
|
|
63
|
-
|
|
49
|
+
label="Name"
|
|
50
|
+
placeholder="Enter your name"
|
|
51
|
+
value={value}
|
|
52
|
+
onChange={(e) => setValue(e.target.value)}
|
|
64
53
|
/>
|
|
65
54
|
);
|
|
66
55
|
}
|
|
67
56
|
```
|
|
68
57
|
|
|
69
|
-
##
|
|
70
|
-
|
|
71
|
-
### Basic Input
|
|
72
|
-
|
|
73
|
-
The default Input renders a single-line text field. Without any additional props, it uses the `outlined` variant at `md` size.
|
|
74
|
-
|
|
75
|
-
```tsx
|
|
76
|
-
<Input />
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Variants
|
|
58
|
+
## Variants
|
|
80
59
|
|
|
81
|
-
Input supports four visual
|
|
60
|
+
Input supports four visual styles: `outlined` (default), `solid`, `soft`, and `plain`.
|
|
82
61
|
|
|
83
62
|
```tsx
|
|
84
63
|
<>
|
|
@@ -89,9 +68,9 @@ Input supports four visual variants: `solid`, `soft`, `outlined`, and `plain`. U
|
|
|
89
68
|
</>
|
|
90
69
|
```
|
|
91
70
|
|
|
92
|
-
|
|
71
|
+
## Sizes
|
|
93
72
|
|
|
94
|
-
|
|
73
|
+
Three sizes are available: `sm`, `md` (default), and `lg`.
|
|
95
74
|
|
|
96
75
|
```tsx
|
|
97
76
|
<>
|
|
@@ -105,7 +84,7 @@ Input comes in three sizes: `sm`, `md`, and `lg`. Choose a size that fits the su
|
|
|
105
84
|
|
|
106
85
|
### Label
|
|
107
86
|
|
|
108
|
-
|
|
87
|
+
The `label` prop renders a form label above the input.
|
|
109
88
|
|
|
110
89
|
```tsx
|
|
111
90
|
<>
|
|
@@ -115,7 +94,7 @@ Use the `label` prop to display a label above the Input. This is the recommended
|
|
|
115
94
|
|
|
116
95
|
### Helper Text
|
|
117
96
|
|
|
118
|
-
|
|
97
|
+
The `helperText` prop renders descriptive text below the input.
|
|
119
98
|
|
|
120
99
|
```tsx
|
|
121
100
|
<>
|
|
@@ -127,7 +106,7 @@ Use the `helperText` prop to provide additional guidance below the Input.
|
|
|
127
106
|
|
|
128
107
|
### Disabled
|
|
129
108
|
|
|
130
|
-
|
|
109
|
+
A disabled input cannot be focused or interacted with.
|
|
131
110
|
|
|
132
111
|
```tsx
|
|
133
112
|
<Input disabled />
|
|
@@ -135,7 +114,7 @@ Set `disabled` to prevent user interaction. Disabled inputs are visually dimmed
|
|
|
135
114
|
|
|
136
115
|
### Error
|
|
137
116
|
|
|
138
|
-
Set `error` to indicate a validation failure. Combine with `helperText` to
|
|
117
|
+
Set `error` to visually indicate a validation failure. Combine with `helperText` to display an error message.
|
|
139
118
|
|
|
140
119
|
```tsx
|
|
141
120
|
<>
|
|
@@ -145,7 +124,7 @@ Set `error` to indicate a validation failure. Combine with `helperText` to expla
|
|
|
145
124
|
|
|
146
125
|
### Required
|
|
147
126
|
|
|
148
|
-
Set `required` to mark the field as
|
|
127
|
+
Set `required` to mark the field as required. An asterisk is added to the label automatically.
|
|
149
128
|
|
|
150
129
|
```tsx
|
|
151
130
|
<Input
|
|
@@ -156,20 +135,9 @@ Set `required` to mark the field as mandatory. This adds a visual indicator to t
|
|
|
156
135
|
/>
|
|
157
136
|
```
|
|
158
137
|
|
|
159
|
-
## Form Control
|
|
160
|
-
|
|
161
|
-
Combine `label`, `helperText`, and `error` props to build a complete form control. This is the recommended pattern for form fields.
|
|
162
|
-
|
|
163
|
-
```tsx
|
|
164
|
-
<>
|
|
165
|
-
<Input placeholder="Type in here..." helperText="I'm helper text" label="Label" />
|
|
166
|
-
<Input placeholder="Invalid input" helperText="I'm helper text" label="Label" error />
|
|
167
|
-
</>
|
|
168
|
-
```
|
|
169
|
-
|
|
170
138
|
## Decorators
|
|
171
139
|
|
|
172
|
-
Use `startDecorator` and `endDecorator` to
|
|
140
|
+
Use `startDecorator` and `endDecorator` to add icons, buttons, or other elements at the start or end of the input field.
|
|
173
141
|
|
|
174
142
|
```tsx
|
|
175
143
|
<Stack spacing={3}>
|
|
@@ -209,7 +177,7 @@ width: 300
|
|
|
209
177
|
</Stack>
|
|
210
178
|
```
|
|
211
179
|
|
|
212
|
-
When using `endDecorator` together with `enableClearable`,
|
|
180
|
+
When using `endDecorator` together with `enableClearable`, both elements are displayed side by side:
|
|
213
181
|
|
|
214
182
|
```tsx
|
|
215
183
|
<Input
|
|
@@ -222,7 +190,7 @@ When using `endDecorator` together with `enableClearable`, the clear button is p
|
|
|
222
190
|
|
|
223
191
|
## Clearable Input
|
|
224
192
|
|
|
225
|
-
Set `enableClearable` to show a clear button when the input has a value. Clicking the button clears the input
|
|
193
|
+
Set `enableClearable` to show a clear button when the input has a value. Clicking the button clears the input content.
|
|
226
194
|
|
|
227
195
|
```tsx
|
|
228
196
|
<>
|
|
@@ -230,9 +198,16 @@ Set `enableClearable` to show a clear button when the input has a value. Clickin
|
|
|
230
198
|
</>
|
|
231
199
|
```
|
|
232
200
|
|
|
201
|
+
```tsx
|
|
202
|
+
<Input
|
|
203
|
+
enableClearable
|
|
204
|
+
placeholder="Type something and clear it"
|
|
205
|
+
/>
|
|
206
|
+
```
|
|
207
|
+
|
|
233
208
|
## Password Input
|
|
234
209
|
|
|
235
|
-
Setting `type="password"`
|
|
210
|
+
Setting `type="password"` creates a password field with an automatic visibility toggle button.
|
|
236
211
|
|
|
237
212
|
```tsx
|
|
238
213
|
<Stack spacing={3}>
|
|
@@ -247,9 +222,17 @@ Setting `type="password"` automatically adds a visibility toggle button, allowin
|
|
|
247
222
|
</Stack>
|
|
248
223
|
```
|
|
249
224
|
|
|
250
|
-
### Password
|
|
225
|
+
### Disabling the Password Toggle
|
|
251
226
|
|
|
252
|
-
|
|
227
|
+
Use `disableTogglePasswordButton` to hide the visibility toggle button on password inputs.
|
|
228
|
+
|
|
229
|
+
```tsx
|
|
230
|
+
<Input type="password" disableTogglePasswordButton placeholder="Password" />
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Password Input Limitations
|
|
234
|
+
|
|
235
|
+
Password inputs (`type="password"`) do not support custom `endDecorator` because the password toggle button occupies that slot. If you provide `endDecorator` with a password input, the component logs a warning and ignores it.
|
|
253
236
|
|
|
254
237
|
```tsx
|
|
255
238
|
<Stack spacing={3}>
|
|
@@ -261,62 +244,69 @@ When `type="password"` is used, the `endDecorator` prop is not supported because
|
|
|
261
244
|
</Stack>
|
|
262
245
|
```
|
|
263
246
|
|
|
264
|
-
##
|
|
265
|
-
|
|
266
|
-
### Controlled Component
|
|
247
|
+
## Form Control
|
|
267
248
|
|
|
268
|
-
|
|
249
|
+
Combining `label`, `helperText`, and `error` produces a complete form field.
|
|
269
250
|
|
|
270
251
|
```tsx
|
|
271
252
|
<>
|
|
272
|
-
<Input placeholder="Type in here
|
|
253
|
+
<Input placeholder="Type in here..." helperText="I'm helper text" label="Label" />
|
|
254
|
+
<Input placeholder="Invalid input" helperText="I'm helper text" label="Label" error />
|
|
273
255
|
</>
|
|
274
256
|
```
|
|
275
257
|
|
|
276
|
-
|
|
258
|
+
```tsx
|
|
259
|
+
<Input
|
|
260
|
+
label="Email"
|
|
261
|
+
helperText="We'll never share your email"
|
|
262
|
+
required
|
|
263
|
+
/>
|
|
264
|
+
|
|
265
|
+
<Input
|
|
266
|
+
label="Email"
|
|
267
|
+
error
|
|
268
|
+
helperText="Invalid email address"
|
|
269
|
+
/>
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Controlled / Uncontrolled
|
|
277
273
|
|
|
278
|
-
|
|
274
|
+
### Controlled
|
|
275
|
+
|
|
276
|
+
Use `value` and `onChange` for controlled behavior.
|
|
279
277
|
|
|
280
278
|
```tsx
|
|
281
|
-
|
|
279
|
+
<>
|
|
280
|
+
<Input placeholder="Type in here…" label="Label" enableClearable value={value} onChange={handleChange} />
|
|
281
|
+
</>
|
|
282
282
|
```
|
|
283
283
|
|
|
284
|
-
|
|
284
|
+
```tsx
|
|
285
|
+
const [value, setValue] = useState('');
|
|
285
286
|
|
|
286
|
-
|
|
287
|
+
<Input
|
|
288
|
+
value={value}
|
|
289
|
+
onChange={(e) => setValue(e.target.value)}
|
|
290
|
+
placeholder="Controlled input"
|
|
291
|
+
/>
|
|
292
|
+
```
|
|
287
293
|
|
|
288
|
-
|
|
289
|
-
function LoginForm() {
|
|
290
|
-
const [email, setEmail] = useState('');
|
|
291
|
-
const [password, setPassword] = useState('');
|
|
294
|
+
### Uncontrolled
|
|
292
295
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
type="email"
|
|
298
|
-
placeholder="you@example.com"
|
|
299
|
-
required
|
|
300
|
-
value={email}
|
|
301
|
-
onChange={(e) => setEmail(e.target.value)}
|
|
302
|
-
/>
|
|
303
|
-
<Input
|
|
304
|
-
label="Password"
|
|
305
|
-
type="password"
|
|
306
|
-
placeholder="Enter your password"
|
|
307
|
-
required
|
|
308
|
-
value={password}
|
|
309
|
-
onChange={(e) => setPassword(e.target.value)}
|
|
310
|
-
/>
|
|
311
|
-
<Button type="submit">Sign In</Button>
|
|
312
|
-
</Stack>
|
|
313
|
-
);
|
|
314
|
-
}
|
|
296
|
+
Use `defaultValue` for uncontrolled behavior.
|
|
297
|
+
|
|
298
|
+
```tsx
|
|
299
|
+
<Input defaultValue="Initial value" placeholder="Uncontrolled input" />
|
|
315
300
|
```
|
|
316
301
|
|
|
317
|
-
|
|
302
|
+
## Common Use Cases
|
|
303
|
+
|
|
304
|
+
### Search Field
|
|
318
305
|
|
|
319
306
|
```tsx
|
|
307
|
+
import { Input } from '@ceed/cds';
|
|
308
|
+
import SearchIcon from '@mui/icons-material/Search';
|
|
309
|
+
|
|
320
310
|
function SearchField({ onSearch }) {
|
|
321
311
|
const [query, setQuery] = useState('');
|
|
322
312
|
|
|
@@ -335,80 +325,152 @@ function SearchField({ onSearch }) {
|
|
|
335
325
|
}
|
|
336
326
|
```
|
|
337
327
|
|
|
328
|
+
### Login Form
|
|
329
|
+
|
|
330
|
+
```tsx
|
|
331
|
+
import { Input, Button, Stack } from '@ceed/cds';
|
|
332
|
+
|
|
333
|
+
function LoginForm({ onSubmit }) {
|
|
334
|
+
return (
|
|
335
|
+
<form onSubmit={onSubmit}>
|
|
336
|
+
<Stack spacing={2}>
|
|
337
|
+
<Input
|
|
338
|
+
label="Email"
|
|
339
|
+
type="email"
|
|
340
|
+
required
|
|
341
|
+
placeholder="Enter your email"
|
|
342
|
+
/>
|
|
343
|
+
<Input
|
|
344
|
+
label="Password"
|
|
345
|
+
type="password"
|
|
346
|
+
required
|
|
347
|
+
placeholder="Enter your password"
|
|
348
|
+
/>
|
|
349
|
+
<Button type="submit">Sign In</Button>
|
|
350
|
+
</Stack>
|
|
351
|
+
</form>
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
338
356
|
### Form with Validation
|
|
339
357
|
|
|
340
358
|
```tsx
|
|
341
|
-
|
|
342
|
-
|
|
359
|
+
import { useState } from 'react';
|
|
360
|
+
import { Input, Button, Stack } from '@ceed/cds';
|
|
361
|
+
|
|
362
|
+
function ValidatedForm() {
|
|
363
|
+
const [email, setEmail] = useState('');
|
|
343
364
|
const [submitted, setSubmitted] = useState(false);
|
|
344
|
-
const
|
|
365
|
+
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
345
366
|
|
|
346
367
|
return (
|
|
347
|
-
<
|
|
348
|
-
<
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
368
|
+
<form onSubmit={(e) => { e.preventDefault(); setSubmitted(true); }}>
|
|
369
|
+
<Stack spacing={2}>
|
|
370
|
+
<Input
|
|
371
|
+
label="Email"
|
|
372
|
+
required
|
|
373
|
+
value={email}
|
|
374
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
375
|
+
error={submitted && !isValid}
|
|
376
|
+
helperText={submitted && !isValid ? 'Please enter a valid email' : undefined}
|
|
377
|
+
placeholder="user@example.com"
|
|
378
|
+
/>
|
|
379
|
+
<Button type="submit">Submit</Button>
|
|
380
|
+
</Stack>
|
|
381
|
+
</form>
|
|
359
382
|
);
|
|
360
383
|
}
|
|
361
384
|
```
|
|
362
385
|
|
|
386
|
+
## Props and Customization
|
|
387
|
+
|
|
388
|
+
### Key Props
|
|
389
|
+
|
|
390
|
+
| Prop | Type | Default | Description |
|
|
391
|
+
| ----------------------------- | -------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------- |
|
|
392
|
+
| `label` | `ReactNode` | - | Label text displayed above the input |
|
|
393
|
+
| `helperText` | `ReactNode` | - | Helper text displayed below the input |
|
|
394
|
+
| `error` | `boolean` | `false` | Applies danger color to indicate validation error |
|
|
395
|
+
| `enableClearable` | `boolean` | `false` | Shows a clear button when the input has a value |
|
|
396
|
+
| `disableTogglePasswordButton` | `boolean` | `false` | Hides the password visibility toggle (only applies when `type="password"`) |
|
|
397
|
+
| `value` | `string` | - | Input value for controlled mode |
|
|
398
|
+
| `defaultValue` | `string` | - | Initial value for uncontrolled mode |
|
|
399
|
+
| `onChange` | `(event: ChangeEvent<HTMLInputElement>) => void` | - | Callback when the input value changes |
|
|
400
|
+
| `placeholder` | `string` | - | Placeholder text when the input is empty |
|
|
401
|
+
| `type` | `string` | `'text'` | HTML input type (`text`, `password`, `email`, `number`, etc.) |
|
|
402
|
+
| `disabled` | `boolean` | `false` | Disables the input |
|
|
403
|
+
| `readOnly` | `boolean` | `false` | Makes the input read-only (focusable but not editable) |
|
|
404
|
+
| `required` | `boolean` | `false` | Marks the field as required (adds asterisk to label) |
|
|
405
|
+
| `name` | `string` | - | HTML name attribute for form submission |
|
|
406
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Input size |
|
|
407
|
+
| `variant` | `'outlined' \| 'solid' \| 'soft' \| 'plain'` | `'outlined'` | Visual style variant |
|
|
408
|
+
| `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'neutral'` | Color scheme |
|
|
409
|
+
| `startDecorator` | `ReactNode` | - | Content rendered at the start of the input |
|
|
410
|
+
| `endDecorator` | `ReactNode` | - | Content rendered at the end of the input (not supported with `type="password"`) |
|
|
411
|
+
| `sx` | `SxProps` | - | Custom styles using the MUI system |
|
|
412
|
+
|
|
413
|
+
> **Note**: Input also accepts all Joy UI Input props and Framer Motion props.
|
|
414
|
+
|
|
363
415
|
## Best Practices
|
|
364
416
|
|
|
365
|
-
1. **
|
|
417
|
+
1. **Use built-in `label` and `helperText`** instead of wrapping with FormControl manually.
|
|
366
418
|
|
|
367
419
|
```tsx
|
|
368
|
-
// ✅ Good
|
|
369
|
-
<Input label="Email
|
|
370
|
-
|
|
371
|
-
// ❌ Bad
|
|
372
|
-
<
|
|
420
|
+
// ✅ Good
|
|
421
|
+
<Input label="Email" helperText="Enter your work email" />
|
|
422
|
+
|
|
423
|
+
// ❌ Bad
|
|
424
|
+
<FormControl>
|
|
425
|
+
<FormLabel>Email</FormLabel>
|
|
426
|
+
<Input />
|
|
427
|
+
<FormHelperText>Enter your work email</FormHelperText>
|
|
428
|
+
</FormControl>
|
|
373
429
|
```
|
|
374
430
|
|
|
375
|
-
2. **
|
|
431
|
+
2. **Choose the right input type** for the data being captured.
|
|
376
432
|
|
|
377
433
|
```tsx
|
|
378
|
-
// ✅ Good:
|
|
379
|
-
<Input
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
helperText={hasError ? 'Must be at least 8 characters' : 'Choose a strong password'}
|
|
383
|
-
error={hasError}
|
|
384
|
-
/>
|
|
434
|
+
// ✅ Good: Appropriate types
|
|
435
|
+
<Input type="email" label="Email" />
|
|
436
|
+
<Input type="password" label="Password" />
|
|
437
|
+
<Input type="tel" label="Phone" />
|
|
385
438
|
|
|
386
|
-
// ❌ Bad:
|
|
387
|
-
<Input
|
|
439
|
+
// ❌ Bad: Generic text for everything
|
|
440
|
+
<Input type="text" label="Email" />
|
|
388
441
|
```
|
|
389
442
|
|
|
390
|
-
3. **
|
|
443
|
+
3. **Always provide labels** for accessibility. If a visible label is not appropriate, use `aria-label`.
|
|
391
444
|
|
|
392
445
|
```tsx
|
|
393
|
-
// ✅ Good:
|
|
394
|
-
<Input label="
|
|
446
|
+
// ✅ Good: Visible label
|
|
447
|
+
<Input label="Search" />
|
|
448
|
+
|
|
449
|
+
// ✅ Good: Hidden label for icon-only inputs
|
|
450
|
+
<Input aria-label="Search" startDecorator={<SearchIcon />} />
|
|
395
451
|
|
|
396
|
-
// ❌ Bad:
|
|
397
|
-
<Input
|
|
452
|
+
// ❌ Bad: No label at all
|
|
453
|
+
<Input placeholder="Search..." />
|
|
398
454
|
```
|
|
399
455
|
|
|
400
|
-
4. **Use `enableClearable` for search and filter inputs
|
|
456
|
+
4. **Use `enableClearable` for search and filter inputs** where users frequently need to clear and re-enter values.
|
|
401
457
|
|
|
402
|
-
5. **
|
|
458
|
+
5. **Do not use `endDecorator` with password inputs.** The password toggle button occupies the end slot. Use `startDecorator` instead for additional icons.
|
|
403
459
|
|
|
404
460
|
## Accessibility
|
|
405
461
|
|
|
406
|
-
- **Label association**: The `label` prop automatically
|
|
407
|
-
- **
|
|
408
|
-
- **
|
|
409
|
-
- **
|
|
462
|
+
- **Label association**: The `label` prop automatically connects the label to the input via `htmlFor`/`id` pairing.
|
|
463
|
+
- **Keyboard navigation**: Standard keyboard support — Tab to focus, type to input, Escape to blur (when applicable).
|
|
464
|
+
- **Error announcement**: When `error` is set, `aria-invalid` is applied. Pair with `helperText` so assistive technology announces the error.
|
|
465
|
+
- **Required state**: The `required` prop adds `aria-required` and a visible asterisk to the label.
|
|
466
|
+
- **Password toggle**: The visibility toggle button is keyboard-accessible and includes an appropriate `aria-label`.
|
|
467
|
+
|
|
468
|
+
## Testing Notes
|
|
469
|
+
|
|
470
|
+
When using Testing Library, always query password inputs by `textbox` role:
|
|
410
471
|
|
|
411
472
|
```tsx
|
|
412
|
-
// Finding a password input in tests
|
|
413
473
|
const passwordInput = screen.getByRole('textbox', { name: /password/i });
|
|
414
474
|
```
|
|
475
|
+
|
|
476
|
+
This is because the ARIA specification does not define a `password` role — password inputs use the default `textbox` role.
|
|
@@ -359,6 +359,31 @@ const handleChange = (e) => {
|
|
|
359
359
|
};
|
|
360
360
|
```
|
|
361
361
|
|
|
362
|
+
## Props and Customization
|
|
363
|
+
|
|
364
|
+
### Key Props
|
|
365
|
+
|
|
366
|
+
| Prop | Type | Default | Description |
|
|
367
|
+
| --------------- | ------------------------------------------------------- | -------------- | --------------------------------------------------- |
|
|
368
|
+
| `value` | `string` | - | Selected month string in `format` (controlled mode) |
|
|
369
|
+
| `defaultValue` | `string` | `''` | Initial month string (uncontrolled mode) |
|
|
370
|
+
| `onChange` | `(event: { target: { name?, value: string } }) => void` | - | Callback when the month changes |
|
|
371
|
+
| `format` | `string` | `'YYYY/MM/DD'` | Format of the `value` and `onChange` value |
|
|
372
|
+
| `displayFormat` | `string` | `'YYYY/MM'` | Format displayed in the input field |
|
|
373
|
+
| `label` | `ReactNode` | - | Form label displayed above the input |
|
|
374
|
+
| `helperText` | `ReactNode` | - | Helper text displayed below the input |
|
|
375
|
+
| `error` | `boolean` | `false` | Applies danger color to indicate validation error |
|
|
376
|
+
| `required` | `boolean` | `false` | Marks the field as required |
|
|
377
|
+
| `disabled` | `boolean` | `false` | Disables the entire component |
|
|
378
|
+
| `name` | `string` | - | HTML name attribute for form submission |
|
|
379
|
+
| `minDate` | `string` | - | Minimum selectable month (in `format`) |
|
|
380
|
+
| `maxDate` | `string` | - | Maximum selectable month (in `format`) |
|
|
381
|
+
| `disableFuture` | `boolean` | `false` | Disables all future months |
|
|
382
|
+
| `disablePast` | `boolean` | `false` | Disables all past months |
|
|
383
|
+
| `locale` | `string` | `'default'` | Locale for month names (BCP 47 format) |
|
|
384
|
+
|
|
385
|
+
> **Note**: MonthPicker also accepts all Input props (e.g., `size`, `variant`, `color`, `sx`).
|
|
386
|
+
|
|
362
387
|
## Accessibility
|
|
363
388
|
|
|
364
389
|
- The input has `role="textbox"` and the calendar toggle button has `aria-label="Toggle Calendar"` for screen reader identification.
|
|
@@ -363,6 +363,29 @@ const handleSubmit = () => {
|
|
|
363
363
|
<MonthRangePicker format="YYYY-MM" />
|
|
364
364
|
```
|
|
365
365
|
|
|
366
|
+
## Props and Customization
|
|
367
|
+
|
|
368
|
+
### Key Props
|
|
369
|
+
|
|
370
|
+
| Prop | Type | Default | Description |
|
|
371
|
+
| --------------- | ------------------------------------------------------- | ----------- | --------------------------------------------------------- |
|
|
372
|
+
| `value` | `string` | - | Selected month range string in `format` (controlled mode) |
|
|
373
|
+
| `defaultValue` | `string` | `''` | Initial month range string (uncontrolled mode) |
|
|
374
|
+
| `onChange` | `(event: { target: { name?, value: string } }) => void` | - | Callback when the month range changes |
|
|
375
|
+
| `format` | `string` | `'YYYY/MM'` | Format of the `value` and `onChange` value |
|
|
376
|
+
| `label` | `ReactNode` | - | Form label displayed above the input |
|
|
377
|
+
| `helperText` | `ReactNode` | - | Helper text displayed below the input |
|
|
378
|
+
| `error` | `boolean` | `false` | Applies danger color to indicate validation error |
|
|
379
|
+
| `required` | `boolean` | `false` | Marks the field as required |
|
|
380
|
+
| `disabled` | `boolean` | `false` | Disables the entire component |
|
|
381
|
+
| `name` | `string` | - | HTML name attribute for form submission |
|
|
382
|
+
| `minDate` | `string` | - | Minimum selectable month (in `format`) |
|
|
383
|
+
| `maxDate` | `string` | - | Maximum selectable month (in `format`) |
|
|
384
|
+
| `disableFuture` | `boolean` | `false` | Disables all future months |
|
|
385
|
+
| `disablePast` | `boolean` | `false` | Disables all past months |
|
|
386
|
+
|
|
387
|
+
> **Note**: MonthRangePicker also accepts all Input props (e.g., `size`, `variant`, `color`, `sx`).
|
|
388
|
+
|
|
366
389
|
## Accessibility
|
|
367
390
|
|
|
368
391
|
- The input has `role="textbox"` and the calendar toggle button has `aria-label="Toggle Calendar"` for screen reader identification.
|
|
@@ -277,6 +277,31 @@ function CompletionTracker({ value, onChange }) {
|
|
|
277
277
|
|
|
278
278
|
5. **Handle edge cases**: Consider what happens at boundary values (0%, 100%) and negative percentages if allowed.
|
|
279
279
|
|
|
280
|
+
## Props and Customization
|
|
281
|
+
|
|
282
|
+
### Key Props
|
|
283
|
+
|
|
284
|
+
| Prop | Type | Default | Description |
|
|
285
|
+
| ----------------- | -------------------------------------------------------- | ------- | ------------------------------------------------------ |
|
|
286
|
+
| `value` | `number` | - | Percentage value (controlled mode) |
|
|
287
|
+
| `defaultValue` | `number` | - | Initial percentage value (uncontrolled mode) |
|
|
288
|
+
| `onChange` | `(event: { target: { name?, value?: number } }) => void` | - | Callback when the value changes |
|
|
289
|
+
| `useMinorUnit` | `boolean` | `false` | When true, value is in basis points (e.g., 1000 = 10%) |
|
|
290
|
+
| `maxDecimalScale` | `number` | `0` | Maximum number of decimal places |
|
|
291
|
+
| `min` | `number` | - | Minimum allowed percentage value |
|
|
292
|
+
| `max` | `number` | - | Maximum allowed percentage value |
|
|
293
|
+
| `label` | `ReactNode` | - | Form label displayed above the input |
|
|
294
|
+
| `helperText` | `ReactNode` | - | Helper text displayed below the input |
|
|
295
|
+
| `error` | `boolean` | `false` | Applies danger color to indicate validation error |
|
|
296
|
+
| `required` | `boolean` | `false` | Marks the field as required |
|
|
297
|
+
| `disabled` | `boolean` | `false` | Disables the input |
|
|
298
|
+
| `name` | `string` | - | HTML name attribute for form submission |
|
|
299
|
+
| `placeholder` | `string` | - | Placeholder text when the input is empty |
|
|
300
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Input size |
|
|
301
|
+
| `sx` | `SxProps` | - | Custom styles using the MUI system |
|
|
302
|
+
|
|
303
|
+
> **Note**: PercentageInput also accepts all Input props and Framer Motion props.
|
|
304
|
+
|
|
280
305
|
## Accessibility
|
|
281
306
|
|
|
282
307
|
- The input has proper labeling via the `label` prop, linked with `aria-labelledby`.
|
|
@@ -470,6 +470,29 @@ function ShippingOptions() {
|
|
|
470
470
|
|
|
471
471
|
5. **Use vertical layout by default**: Vertical lists are easier to scan. Only use horizontal (`orientation="horizontal"`) when options are very short (e.g., segmented controls).
|
|
472
472
|
|
|
473
|
+
## Props and Customization
|
|
474
|
+
|
|
475
|
+
### Key Props
|
|
476
|
+
|
|
477
|
+
| Prop | Type | Default | Description |
|
|
478
|
+
| ---------------- | -------------------------------------------------------------- | ------------ | --------------------------------------------- |
|
|
479
|
+
| `checked` | `boolean` | - | Whether the radio is selected (controlled) |
|
|
480
|
+
| `defaultChecked` | `boolean` | `false` | Initial selected state (uncontrolled) |
|
|
481
|
+
| `onChange` | `(event: ChangeEvent<HTMLInputElement>) => void` | - | Callback when the state changes |
|
|
482
|
+
| `label` | `ReactNode` | - | Label content displayed next to the radio |
|
|
483
|
+
| `value` | `string` | - | Value attribute for form submission |
|
|
484
|
+
| `name` | `string` | - | Groups radios together for mutual exclusivity |
|
|
485
|
+
| `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'primary'` | Color scheme |
|
|
486
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Radio button size |
|
|
487
|
+
| `variant` | `'solid' \| 'soft' \| 'outlined' \| 'plain'` | `'outlined'` | Visual style |
|
|
488
|
+
| `disabled` | `boolean` | `false` | Disables the radio button |
|
|
489
|
+
| `overlay` | `boolean` | `false` | Extends clickable area to parent container |
|
|
490
|
+
| `disableIcon` | `boolean` | `false` | Hides the radio icon |
|
|
491
|
+
| `checkedIcon` | `ReactNode` | - | Custom icon for the checked state |
|
|
492
|
+
| `sx` | `SxProps` | - | Custom styles using the MUI system |
|
|
493
|
+
|
|
494
|
+
> **Note**: RadioButton also accepts all Joy UI Radio props and Framer Motion props.
|
|
495
|
+
|
|
473
496
|
## Accessibility
|
|
474
497
|
|
|
475
498
|
- **Keyboard navigation**: Users can move between options using `Arrow Up` / `Arrow Down` (vertical) or `Arrow Left` / `Arrow Right` (horizontal). `Space` selects the focused option.
|