A React component that automatically generates interactive web forms from JSON Schema definitions.
—
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.
Built-in widget components that provide input controls for form fields.
interface RegistryWidgetsType<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
/** Alternative date picker with custom formatting */
AltDateWidget: ComponentType<WidgetProps<T, S, F>>;
/** Alternative datetime picker with timezone support */
AltDateTimeWidget: ComponentType<WidgetProps<T, S, F>>;
/** Single checkbox for boolean values */
CheckboxWidget: ComponentType<WidgetProps<T, S, F>>;
/** Multiple checkboxes for enum array values */
CheckboxesWidget: ComponentType<WidgetProps<T, S, F>>;
/** Color picker input */
ColorWidget: ComponentType<WidgetProps<T, S, F>>;
/** Standard HTML5 date input */
DateWidget: ComponentType<WidgetProps<T, S, F>>;
/** Standard HTML5 datetime-local input */
DateTimeWidget: ComponentType<WidgetProps<T, S, F>>;
/** Email input with validation */
EmailWidget: ComponentType<WidgetProps<T, S, F>>;
/** File upload input */
FileWidget: ComponentType<WidgetProps<T, S, F>>;
/** Hidden input field */
HiddenWidget: ComponentType<WidgetProps<T, S, F>>;
/** Password input with masking */
PasswordWidget: ComponentType<WidgetProps<T, S, F>>;
/** Radio button group for enum values */
RadioWidget: ComponentType<WidgetProps<T, S, F>>;
/** Range slider for numeric values */
RangeWidget: ComponentType<WidgetProps<T, S, F>>;
/** Dropdown select for enum values */
SelectWidget: ComponentType<WidgetProps<T, S, F>>;
/** Standard text input */
TextWidget: ComponentType<WidgetProps<T, S, F>>;
/** Multiline text input */
TextareaWidget: ComponentType<WidgetProps<T, S, F>>;
/** HTML5 time input */
TimeWidget: ComponentType<WidgetProps<T, S, F>>;
/** Number input with up/down buttons */
UpDownWidget: ComponentType<WidgetProps<T, S, F>>;
/** URL input with validation */
URLWidget: ComponentType<WidgetProps<T, S, F>>;
}Common props interface shared by all widget components.
interface WidgetProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
/** Unique identifier for the widget */
id: string;
/** Current widget value */
value: any;
/** Whether field is required */
required?: boolean;
/** Whether widget is disabled */
disabled?: boolean;
/** Whether widget is read-only */
readonly?: boolean;
/** Whether widget accepts multiple values */
multiple?: boolean;
/** Whether widget should auto-focus */
autofocus?: boolean;
/** Called when widget value changes */
onChange: (value: any) => void;
/** Called when widget loses focus */
onBlur: (id: string, value: any) => void;
/** Called when widget gains focus */
onFocus: (id: string, value: any) => void;
/** Widget options from UI schema */
options: NonNullable<UiSchema<T, S, F>['ui:options']> & {
enumOptions?: { value: any; label: string }[];
};
/** JSON schema for this field */
schema: S;
/** UI schema for this field */
uiSchema?: UiSchema<T, S, F>;
/** Validation errors for this field */
rawErrors?: string[];
/** Form context object */
formContext: F;
/** Registry containing all components */
registry: Registry<T, S, F>;
/** Widget label text */
label: string;
/** Placeholder text */
placeholder?: string;
/** Field name */
name: string;
}Standard single-line text input widget.
/**
* Standard text input widget for string values
* Supports placeholder, validation, and formatting
*/
const TextWidget: ComponentType<WidgetProps<T, S, F>>;Usage Examples:
// Basic text input
const textSchema = {
type: "string",
title: "Name"
};
// Text with validation
const validatedTextSchema = {
type: "string",
title: "Username",
minLength: 3,
maxLength: 20,
pattern: "^[a-zA-Z0-9_]+$"
};
const textUI = {
"ui:placeholder": "Enter username",
"ui:help": "Only letters, numbers, and underscores allowed"
};Multiline text input widget for longer content.
/**
* Multiline text input widget for longer string content
* Configurable rows and columns
*/
const TextareaWidget: ComponentType<WidgetProps<T, S, F>>;Configuration:
const textareaUI = {
"ui:widget": "textarea",
"ui:options": {
rows: 5,
cols: 40
},
"ui:placeholder": "Enter your message here..."
};Password input with value masking.
/**
* Password input widget with value masking
* Supports strength validation
*/
const PasswordWidget: ComponentType<WidgetProps<T, S, F>>;Email input with built-in validation.
/**
* Email input widget with format validation
* Uses HTML5 email input type
*/
const EmailWidget: ComponentType<WidgetProps<T, S, F>>;URL input with validation.
/**
* URL input widget with format validation
* Uses HTML5 url input type
*/
const URLWidget: ComponentType<WidgetProps<T, S, F>>;Number input with increment/decrement buttons.
/**
* Number input widget with up/down buttons
* Supports step, min, max constraints
*/
const UpDownWidget: ComponentType<WidgetProps<T, S, F>>;Usage Examples:
const numberSchema = {
type: "number",
title: "Quantity",
minimum: 1,
maximum: 100,
multipleOf: 1
};
const upDownUI = {
"ui:widget": "updown"
};Range slider for numeric values.
/**
* Range slider widget for numeric values
* Visual slider with min/max bounds
*/
const RangeWidget: ComponentType<WidgetProps<T, S, F>>;Configuration:
const rangeSchema = {
type: "number",
title: "Volume",
minimum: 0,
maximum: 100,
default: 50
};
const rangeUI = {
"ui:widget": "range"
};Dropdown select for enum values.
/**
* Dropdown select widget for enum values
* Supports single and multiple selection
*/
const SelectWidget: ComponentType<WidgetProps<T, S, F>>;Usage Examples:
// Single select
const selectSchema = {
type: "string",
title: "Country",
enum: ["us", "ca", "uk", "de"],
enumNames: ["United States", "Canada", "United Kingdom", "Germany"]
};
// Multiple select
const multiSelectSchema = {
type: "array",
title: "Skills",
items: {
type: "string",
enum: ["javascript", "python", "java", "go"]
},
uniqueItems: true
};
const multiSelectUI = {
"ui:widget": "select"
};Radio button group for enum values.
/**
* Radio button group widget for enum values
* Single selection with visible options
*/
const RadioWidget: ComponentType<WidgetProps<T, S, F>>;Configuration:
const radioUI = {
"ui:widget": "radio",
"ui:options": {
inline: true // Horizontal layout
}
};Multiple checkboxes for array enum values.
/**
* Multiple checkboxes widget for array enum values
* Multiple selection with individual checkboxes
*/
const CheckboxesWidget: ComponentType<WidgetProps<T, S, F>>;Usage Example:
const checkboxesSchema = {
type: "array",
title: "Preferences",
items: {
type: "string",
enum: ["email", "sms", "push", "phone"]
},
uniqueItems: true
};
const checkboxesUI = {
"ui:widget": "checkboxes",
"ui:options": {
inline: false // Vertical layout
}
};Single checkbox for boolean values.
/**
* Single checkbox widget for boolean values
* True/false toggle
*/
const CheckboxWidget: ComponentType<WidgetProps<T, S, F>>;Standard HTML5 date input.
/**
* HTML5 date input widget
* Standard date picker with YYYY-MM-DD format
*/
const DateWidget: ComponentType<WidgetProps<T, S, F>>;HTML5 time input.
/**
* HTML5 time input widget
* Time picker with HH:MM format
*/
const TimeWidget: ComponentType<WidgetProps<T, S, F>>;HTML5 datetime-local input.
/**
* HTML5 datetime-local input widget
* Combined date and time picker
*/
const DateTimeWidget: ComponentType<WidgetProps<T, S, F>>;Alternative date picker with custom formatting.
/**
* Alternative date picker widget with custom formatting
* Supports different date formats and locales
*/
const AltDateWidget: ComponentType<WidgetProps<T, S, F>>;Alternative datetime picker with timezone support.
/**
* Alternative datetime picker widget with timezone support
* Enhanced datetime handling with custom formatting
*/
const AltDateTimeWidget: ComponentType<WidgetProps<T, S, F>>;File upload input.
/**
* File upload widget
* Supports single and multiple file selection
*/
const FileWidget: ComponentType<WidgetProps<T, S, F>>;Configuration:
const fileSchema = {
type: "string",
format: "data-url",
title: "Upload File"
};
const fileUI = {
"ui:options": {
accept: ".pdf,.doc,.docx",
multiple: false
}
};Color picker input.
/**
* Color picker widget for color values
* HTML5 color input with hex values
*/
const ColorWidget: ComponentType<WidgetProps<T, S, F>>;Hidden input field.
/**
* Hidden input widget for values not displayed to user
* Useful for IDs, tokens, and computed values
*/
const HiddenWidget: ComponentType<WidgetProps<T, S, F>>;import { WidgetProps } from "@rjsf/utils";
const CustomSliderWidget = (props: WidgetProps) => {
const { id, value, onChange, options, disabled, readonly } = props;
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
onChange(Number(event.target.value));
};
return (
<div className="custom-slider">
<input
id={id}
type="range"
value={value || 0}
min={options.min || 0}
max={options.max || 100}
step={options.step || 1}
onChange={handleChange}
disabled={disabled}
readOnly={readonly}
/>
<div className="slider-value">{value || 0}</div>
</div>
);
};
// Register custom widget
const customWidgets = {
CustomSliderWidget
};
// Use in UI schema
const uiSchema = {
rating: {
"ui:widget": "CustomSliderWidget",
"ui:options": {
min: 1,
max: 10,
step: 1
}
}
};
<Form
schema={schema}
uiSchema={uiSchema}
widgets={customWidgets}
validator={validator}
/>import Select from 'react-select';
const ReactSelectWidget = (props: WidgetProps) => {
const { value, onChange, options, disabled, multiple } = props;
const selectOptions = options.enumOptions?.map(({ value, label }) => ({
value,
label
})) || [];
const handleChange = (selectedOption: any) => {
if (multiple) {
onChange(selectedOption ? selectedOption.map((opt: any) => opt.value) : []);
} else {
onChange(selectedOption ? selectedOption.value : undefined);
}
};
return (
<Select
value={selectOptions.filter(opt =>
multiple ? value?.includes(opt.value) : opt.value === value
)}
onChange={handleChange}
options={selectOptions}
isDisabled={disabled}
isMulti={multiple}
/>
);
};const AsyncValidationWidget = (props: WidgetProps) => {
const { value, onChange, onBlur } = props;
const [isValidating, setIsValidating] = useState(false);
const [isValid, setIsValid] = useState(true);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const newValue = event.target.value;
onChange(newValue);
// Async validation
setIsValidating(true);
validateAsync(newValue).then(valid => {
setIsValid(valid);
setIsValidating(false);
});
};
const handleBlur = () => {
onBlur(props.id, value);
};
return (
<div className="async-validation-widget">
<input
type="text"
value={value || ''}
onChange={handleChange}
onBlur={handleBlur}
className={`${!isValid ? 'error' : ''} ${isValidating ? 'validating' : ''}`}
/>
{isValidating && <span>Validating...</span>}
{!isValid && <span className="error">Invalid value</span>}
</div>
);
};Install with Tessl CLI
npx tessl i tessl/npm-rjsf--core