0
# Widget Components
1
2
Widget components provide the actual form input controls for different data input types. They handle user interaction, validation, and data formatting for specific input scenarios.
3
4
## Capabilities
5
6
### Widget Component Types
7
8
Built-in widget components that provide input controls for form fields.
9
10
```typescript { .api }
11
interface RegistryWidgetsType<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
12
/** Alternative date picker with custom formatting */
13
AltDateWidget: ComponentType<WidgetProps<T, S, F>>;
14
/** Alternative datetime picker with timezone support */
15
AltDateTimeWidget: ComponentType<WidgetProps<T, S, F>>;
16
/** Single checkbox for boolean values */
17
CheckboxWidget: ComponentType<WidgetProps<T, S, F>>;
18
/** Multiple checkboxes for enum array values */
19
CheckboxesWidget: ComponentType<WidgetProps<T, S, F>>;
20
/** Color picker input */
21
ColorWidget: ComponentType<WidgetProps<T, S, F>>;
22
/** Standard HTML5 date input */
23
DateWidget: ComponentType<WidgetProps<T, S, F>>;
24
/** Standard HTML5 datetime-local input */
25
DateTimeWidget: ComponentType<WidgetProps<T, S, F>>;
26
/** Email input with validation */
27
EmailWidget: ComponentType<WidgetProps<T, S, F>>;
28
/** File upload input */
29
FileWidget: ComponentType<WidgetProps<T, S, F>>;
30
/** Hidden input field */
31
HiddenWidget: ComponentType<WidgetProps<T, S, F>>;
32
/** Password input with masking */
33
PasswordWidget: ComponentType<WidgetProps<T, S, F>>;
34
/** Radio button group for enum values */
35
RadioWidget: ComponentType<WidgetProps<T, S, F>>;
36
/** Range slider for numeric values */
37
RangeWidget: ComponentType<WidgetProps<T, S, F>>;
38
/** Dropdown select for enum values */
39
SelectWidget: ComponentType<WidgetProps<T, S, F>>;
40
/** Standard text input */
41
TextWidget: ComponentType<WidgetProps<T, S, F>>;
42
/** Multiline text input */
43
TextareaWidget: ComponentType<WidgetProps<T, S, F>>;
44
/** HTML5 time input */
45
TimeWidget: ComponentType<WidgetProps<T, S, F>>;
46
/** Number input with up/down buttons */
47
UpDownWidget: ComponentType<WidgetProps<T, S, F>>;
48
/** URL input with validation */
49
URLWidget: ComponentType<WidgetProps<T, S, F>>;
50
}
51
```
52
53
### WidgetProps Interface
54
55
Common props interface shared by all widget components.
56
57
```typescript { .api }
58
interface WidgetProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
59
/** Unique identifier for the widget */
60
id: string;
61
/** Current widget value */
62
value: any;
63
/** Whether field is required */
64
required?: boolean;
65
/** Whether widget is disabled */
66
disabled?: boolean;
67
/** Whether widget is read-only */
68
readonly?: boolean;
69
/** Whether widget accepts multiple values */
70
multiple?: boolean;
71
/** Whether widget should auto-focus */
72
autofocus?: boolean;
73
/** Called when widget value changes */
74
onChange: (value: any) => void;
75
/** Called when widget loses focus */
76
onBlur: (id: string, value: any) => void;
77
/** Called when widget gains focus */
78
onFocus: (id: string, value: any) => void;
79
/** Widget options from UI schema */
80
options: NonNullable<UiSchema<T, S, F>['ui:options']> & {
81
enumOptions?: { value: any; label: string }[];
82
};
83
/** JSON schema for this field */
84
schema: S;
85
/** UI schema for this field */
86
uiSchema?: UiSchema<T, S, F>;
87
/** Validation errors for this field */
88
rawErrors?: string[];
89
/** Form context object */
90
formContext: F;
91
/** Registry containing all components */
92
registry: Registry<T, S, F>;
93
/** Widget label text */
94
label: string;
95
/** Placeholder text */
96
placeholder?: string;
97
/** Field name */
98
name: string;
99
}
100
```
101
102
## Text Input Widgets
103
104
### TextWidget
105
106
Standard single-line text input widget.
107
108
```typescript { .api }
109
/**
110
* Standard text input widget for string values
111
* Supports placeholder, validation, and formatting
112
*/
113
const TextWidget: ComponentType<WidgetProps<T, S, F>>;
114
```
115
116
**Usage Examples:**
117
118
```typescript
119
// Basic text input
120
const textSchema = {
121
type: "string",
122
title: "Name"
123
};
124
125
// Text with validation
126
const validatedTextSchema = {
127
type: "string",
128
title: "Username",
129
minLength: 3,
130
maxLength: 20,
131
pattern: "^[a-zA-Z0-9_]+$"
132
};
133
134
const textUI = {
135
"ui:placeholder": "Enter username",
136
"ui:help": "Only letters, numbers, and underscores allowed"
137
};
138
```
139
140
### TextareaWidget
141
142
Multiline text input widget for longer content.
143
144
```typescript { .api }
145
/**
146
* Multiline text input widget for longer string content
147
* Configurable rows and columns
148
*/
149
const TextareaWidget: ComponentType<WidgetProps<T, S, F>>;
150
```
151
152
**Configuration:**
153
154
```typescript
155
const textareaUI = {
156
"ui:widget": "textarea",
157
"ui:options": {
158
rows: 5,
159
cols: 40
160
},
161
"ui:placeholder": "Enter your message here..."
162
};
163
```
164
165
### PasswordWidget
166
167
Password input with value masking.
168
169
```typescript { .api }
170
/**
171
* Password input widget with value masking
172
* Supports strength validation
173
*/
174
const PasswordWidget: ComponentType<WidgetProps<T, S, F>>;
175
```
176
177
### EmailWidget
178
179
Email input with built-in validation.
180
181
```typescript { .api }
182
/**
183
* Email input widget with format validation
184
* Uses HTML5 email input type
185
*/
186
const EmailWidget: ComponentType<WidgetProps<T, S, F>>;
187
```
188
189
### URLWidget
190
191
URL input with validation.
192
193
```typescript { .api }
194
/**
195
* URL input widget with format validation
196
* Uses HTML5 url input type
197
*/
198
const URLWidget: ComponentType<WidgetProps<T, S, F>>;
199
```
200
201
## Numeric Input Widgets
202
203
### UpDownWidget
204
205
Number input with increment/decrement buttons.
206
207
```typescript { .api }
208
/**
209
* Number input widget with up/down buttons
210
* Supports step, min, max constraints
211
*/
212
const UpDownWidget: ComponentType<WidgetProps<T, S, F>>;
213
```
214
215
**Usage Examples:**
216
217
```typescript
218
const numberSchema = {
219
type: "number",
220
title: "Quantity",
221
minimum: 1,
222
maximum: 100,
223
multipleOf: 1
224
};
225
226
const upDownUI = {
227
"ui:widget": "updown"
228
};
229
```
230
231
### RangeWidget
232
233
Range slider for numeric values.
234
235
```typescript { .api }
236
/**
237
* Range slider widget for numeric values
238
* Visual slider with min/max bounds
239
*/
240
const RangeWidget: ComponentType<WidgetProps<T, S, F>>;
241
```
242
243
**Configuration:**
244
245
```typescript
246
const rangeSchema = {
247
type: "number",
248
title: "Volume",
249
minimum: 0,
250
maximum: 100,
251
default: 50
252
};
253
254
const rangeUI = {
255
"ui:widget": "range"
256
};
257
```
258
259
## Selection Widgets
260
261
### SelectWidget
262
263
Dropdown select for enum values.
264
265
```typescript { .api }
266
/**
267
* Dropdown select widget for enum values
268
* Supports single and multiple selection
269
*/
270
const SelectWidget: ComponentType<WidgetProps<T, S, F>>;
271
```
272
273
**Usage Examples:**
274
275
```typescript
276
// Single select
277
const selectSchema = {
278
type: "string",
279
title: "Country",
280
enum: ["us", "ca", "uk", "de"],
281
enumNames: ["United States", "Canada", "United Kingdom", "Germany"]
282
};
283
284
// Multiple select
285
const multiSelectSchema = {
286
type: "array",
287
title: "Skills",
288
items: {
289
type: "string",
290
enum: ["javascript", "python", "java", "go"]
291
},
292
uniqueItems: true
293
};
294
295
const multiSelectUI = {
296
"ui:widget": "select"
297
};
298
```
299
300
### RadioWidget
301
302
Radio button group for enum values.
303
304
```typescript { .api }
305
/**
306
* Radio button group widget for enum values
307
* Single selection with visible options
308
*/
309
const RadioWidget: ComponentType<WidgetProps<T, S, F>>;
310
```
311
312
**Configuration:**
313
314
```typescript
315
const radioUI = {
316
"ui:widget": "radio",
317
"ui:options": {
318
inline: true // Horizontal layout
319
}
320
};
321
```
322
323
### CheckboxesWidget
324
325
Multiple checkboxes for array enum values.
326
327
```typescript { .api }
328
/**
329
* Multiple checkboxes widget for array enum values
330
* Multiple selection with individual checkboxes
331
*/
332
const CheckboxesWidget: ComponentType<WidgetProps<T, S, F>>;
333
```
334
335
**Usage Example:**
336
337
```typescript
338
const checkboxesSchema = {
339
type: "array",
340
title: "Preferences",
341
items: {
342
type: "string",
343
enum: ["email", "sms", "push", "phone"]
344
},
345
uniqueItems: true
346
};
347
348
const checkboxesUI = {
349
"ui:widget": "checkboxes",
350
"ui:options": {
351
inline: false // Vertical layout
352
}
353
};
354
```
355
356
### CheckboxWidget
357
358
Single checkbox for boolean values.
359
360
```typescript { .api }
361
/**
362
* Single checkbox widget for boolean values
363
* True/false toggle
364
*/
365
const CheckboxWidget: ComponentType<WidgetProps<T, S, F>>;
366
```
367
368
## Date and Time Widgets
369
370
### DateWidget
371
372
Standard HTML5 date input.
373
374
```typescript { .api }
375
/**
376
* HTML5 date input widget
377
* Standard date picker with YYYY-MM-DD format
378
*/
379
const DateWidget: ComponentType<WidgetProps<T, S, F>>;
380
```
381
382
### TimeWidget
383
384
HTML5 time input.
385
386
```typescript { .api }
387
/**
388
* HTML5 time input widget
389
* Time picker with HH:MM format
390
*/
391
const TimeWidget: ComponentType<WidgetProps<T, S, F>>;
392
```
393
394
### DateTimeWidget
395
396
HTML5 datetime-local input.
397
398
```typescript { .api }
399
/**
400
* HTML5 datetime-local input widget
401
* Combined date and time picker
402
*/
403
const DateTimeWidget: ComponentType<WidgetProps<T, S, F>>;
404
```
405
406
### AltDateWidget
407
408
Alternative date picker with custom formatting.
409
410
```typescript { .api }
411
/**
412
* Alternative date picker widget with custom formatting
413
* Supports different date formats and locales
414
*/
415
const AltDateWidget: ComponentType<WidgetProps<T, S, F>>;
416
```
417
418
### AltDateTimeWidget
419
420
Alternative datetime picker with timezone support.
421
422
```typescript { .api }
423
/**
424
* Alternative datetime picker widget with timezone support
425
* Enhanced datetime handling with custom formatting
426
*/
427
const AltDateTimeWidget: ComponentType<WidgetProps<T, S, F>>;
428
```
429
430
## Special Purpose Widgets
431
432
### FileWidget
433
434
File upload input.
435
436
```typescript { .api }
437
/**
438
* File upload widget
439
* Supports single and multiple file selection
440
*/
441
const FileWidget: ComponentType<WidgetProps<T, S, F>>;
442
```
443
444
**Configuration:**
445
446
```typescript
447
const fileSchema = {
448
type: "string",
449
format: "data-url",
450
title: "Upload File"
451
};
452
453
const fileUI = {
454
"ui:options": {
455
accept: ".pdf,.doc,.docx",
456
multiple: false
457
}
458
};
459
```
460
461
### ColorWidget
462
463
Color picker input.
464
465
```typescript { .api }
466
/**
467
* Color picker widget for color values
468
* HTML5 color input with hex values
469
*/
470
const ColorWidget: ComponentType<WidgetProps<T, S, F>>;
471
```
472
473
### HiddenWidget
474
475
Hidden input field.
476
477
```typescript { .api }
478
/**
479
* Hidden input widget for values not displayed to user
480
* Useful for IDs, tokens, and computed values
481
*/
482
const HiddenWidget: ComponentType<WidgetProps<T, S, F>>;
483
```
484
485
## Custom Widget Implementation
486
487
### Creating Custom Widgets
488
489
```typescript
490
import { WidgetProps } from "@rjsf/utils";
491
492
const CustomSliderWidget = (props: WidgetProps) => {
493
const { id, value, onChange, options, disabled, readonly } = props;
494
495
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
496
onChange(Number(event.target.value));
497
};
498
499
return (
500
<div className="custom-slider">
501
<input
502
id={id}
503
type="range"
504
value={value || 0}
505
min={options.min || 0}
506
max={options.max || 100}
507
step={options.step || 1}
508
onChange={handleChange}
509
disabled={disabled}
510
readOnly={readonly}
511
/>
512
<div className="slider-value">{value || 0}</div>
513
</div>
514
);
515
};
516
517
// Register custom widget
518
const customWidgets = {
519
CustomSliderWidget
520
};
521
522
// Use in UI schema
523
const uiSchema = {
524
rating: {
525
"ui:widget": "CustomSliderWidget",
526
"ui:options": {
527
min: 1,
528
max: 10,
529
step: 1
530
}
531
}
532
};
533
534
<Form
535
schema={schema}
536
uiSchema={uiSchema}
537
widgets={customWidgets}
538
validator={validator}
539
/>
540
```
541
542
### Widget with External Library
543
544
```typescript
545
import Select from 'react-select';
546
547
const ReactSelectWidget = (props: WidgetProps) => {
548
const { value, onChange, options, disabled, multiple } = props;
549
550
const selectOptions = options.enumOptions?.map(({ value, label }) => ({
551
value,
552
label
553
})) || [];
554
555
const handleChange = (selectedOption: any) => {
556
if (multiple) {
557
onChange(selectedOption ? selectedOption.map((opt: any) => opt.value) : []);
558
} else {
559
onChange(selectedOption ? selectedOption.value : undefined);
560
}
561
};
562
563
return (
564
<Select
565
value={selectOptions.filter(opt =>
566
multiple ? value?.includes(opt.value) : opt.value === value
567
)}
568
onChange={handleChange}
569
options={selectOptions}
570
isDisabled={disabled}
571
isMulti={multiple}
572
/>
573
);
574
};
575
```
576
577
### Async Widget with Validation
578
579
```typescript
580
const AsyncValidationWidget = (props: WidgetProps) => {
581
const { value, onChange, onBlur } = props;
582
const [isValidating, setIsValidating] = useState(false);
583
const [isValid, setIsValid] = useState(true);
584
585
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
586
const newValue = event.target.value;
587
onChange(newValue);
588
589
// Async validation
590
setIsValidating(true);
591
validateAsync(newValue).then(valid => {
592
setIsValid(valid);
593
setIsValidating(false);
594
});
595
};
596
597
const handleBlur = () => {
598
onBlur(props.id, value);
599
};
600
601
return (
602
<div className="async-validation-widget">
603
<input
604
type="text"
605
value={value || ''}
606
onChange={handleChange}
607
onBlur={handleBlur}
608
className={`${!isValid ? 'error' : ''} ${isValidating ? 'validating' : ''}`}
609
/>
610
{isValidating && <span>Validating...</span>}
611
{!isValid && <span className="error">Invalid value</span>}
612
</div>
613
);
614
};
615
```