A React component that automatically generates interactive web forms from JSON Schema definitions.
—
Field components handle different JSON Schema types and provide the foundation for form rendering. Each field component is responsible for interpreting a specific schema type and rendering the appropriate form structure.
Built-in field components that handle different JSON Schema types and structures.
interface RegistryFieldsType<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
/** Handles anyOf schema unions allowing multiple possible schemas */
AnyOfField: ComponentType<FieldProps<T, S, F>>;
/** Handles array type schemas with dynamic item management */
ArrayField: ComponentType<FieldProps<T, S, F>>;
/** Handles boolean type schemas with checkbox or select widgets */
BooleanField: ComponentType<FieldProps<T, S, F>>;
/** Handles number and integer type schemas with numeric widgets */
NumberField: ComponentType<FieldProps<T, S, F>>;
/** Handles object type schemas with nested field rendering */
ObjectField: ComponentType<FieldProps<T, S, F>>;
/** Handles oneOf schema unions with radio or select widgets */
OneOfField: ComponentType<FieldProps<T, S, F>>;
/** Root field router that determines which field type to render */
SchemaField: ComponentType<FieldProps<T, S, F>>;
/** Handles string type schemas with various text input widgets */
StringField: ComponentType<FieldProps<T, S, F>>;
/** Handles null type schemas with hidden or disabled widgets */
NullField: ComponentType<FieldProps<T, S, F>>;
}Common props interface shared by all field components.
interface FieldProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
/** JSON schema for this field */
schema: S;
/** UI schema for customizing appearance and behavior */
uiSchema: UiSchema<T, S, F>;
/** ID schema for field identification */
idSchema: IdSchema<T>;
/** Current field data value */
formData?: T;
/** Error schema for validation errors */
errorSchema: ErrorSchema<T>;
/** Called when field data changes */
onChange: (newFormData: any, newErrorSchema?: ErrorSchema<T>, id?: string) => void;
/** Called when field loses focus */
onBlur: (id: string, data: any) => void;
/** Called when field gains focus */
onFocus: (id: string, data: any) => void;
/** Registry containing all available components */
registry: Registry<T, S, F>;
/** Form context object */
formContext: F;
/** Whether field should auto-focus */
autofocus?: boolean;
/** Whether field is disabled */
disabled?: boolean;
/** Whether field is read-only */
readonly?: boolean;
/** Whether to hide field-level errors */
hideError?: boolean;
/** Field name */
name: string;
}Root field component that routes to appropriate field types based on schema.
/**
* Root field router that determines which field component to render
* based on schema type and other properties
*/
const SchemaField: ComponentType<FieldProps<T, S, F>>;Schema Routing Logic:
// SchemaField determines field type based on:
// 1. UI schema field override: uiSchema["ui:field"]
// 2. Custom registry fields by name
// 3. Schema type: "string", "number", "object", "array", "boolean", "null"
// 4. Schema unions: anyOf, oneOf
// 5. Fallback to UnsupportedField
const schema = { type: "string" }; // -> StringField
const schema = { type: "object" }; // -> ObjectField
const schema = { anyOf: [...] }; // -> AnyOfField
const schema = { oneOf: [...] }; // -> OneOfFieldHandles string type schemas with format-specific widget selection.
/**
* Field component for string type schemas
* Automatically selects appropriate widget based on format and enum
*/
const StringField: ComponentType<FieldProps<T, S, F>>;Widget Selection Logic:
// StringField selects widgets based on:
const stringSchema = {
type: "string",
format: "email" // -> EmailWidget
// format: "uri" // -> URLWidget
// format: "date" // -> DateWidget
// format: "time" // -> TimeWidget
// format: "color" // -> ColorWidget
// enum: ["a", "b"] // -> SelectWidget
// no format/enum // -> TextWidget
};
const uiSchema = {
"ui:widget": "textarea" // -> TextareaWidget (override)
};Handles number and integer type schemas with numeric widgets.
/**
* Field component for number and integer type schemas
* Supports range widgets and up/down controls
*/
const NumberField: ComponentType<FieldProps<T, S, F>>;Usage Examples:
// Integer with up/down widget
const integerSchema = {
type: "integer",
minimum: 0,
maximum: 100
};
const integerUI = {
"ui:widget": "updown"
};
// Number with range slider
const rangeSchema = {
type: "number",
minimum: 0,
maximum: 1,
multipleOf: 0.1
};
const rangeUI = {
"ui:widget": "range"
};Handles object type schemas with nested property rendering.
/**
* Field component for object type schemas
* Renders nested properties and handles additional properties
*/
const ObjectField: ComponentType<FieldProps<T, S, F>>;Features:
// Object with required and optional properties
const objectSchema = {
type: "object",
properties: {
firstName: { type: "string", title: "First Name" },
lastName: { type: "string", title: "Last Name" },
age: { type: "number", title: "Age", minimum: 0 }
},
required: ["firstName", "lastName"],
additionalProperties: true // Allow extra properties
};
// UI schema for property ordering and styling
const objectUI = {
"ui:order": ["firstName", "lastName", "age", "*"], // * = additional props
firstName: { "ui:autofocus": true },
age: { "ui:widget": "updown" }
};Handles array type schemas with dynamic item management.
/**
* Field component for array type schemas
* Provides add, remove, reorder functionality for array items
*/
const ArrayField: ComponentType<FieldProps<T, S, F>>;Array Types:
// Fixed items array (tuple)
const tupleSchema = {
type: "array",
items: [
{ type: "string", title: "Name" },
{ type: "number", title: "Age" },
{ type: "boolean", title: "Active" }
]
};
// Variable items array
const listSchema = {
type: "array",
items: { type: "string" },
minItems: 1,
maxItems: 10
};
// Array of objects
const objectArraySchema = {
type: "array",
items: {
type: "object",
properties: {
name: { type: "string" },
email: { type: "string", format: "email" }
}
}
};
// UI schema for arrays
const arrayUI = {
"ui:options": {
addable: true,
removable: true,
orderable: true
},
items: {
name: { "ui:placeholder": "Enter name" }
}
};Handles boolean type schemas with checkbox or select widgets.
/**
* Field component for boolean type schemas
* Renders checkbox, radio, or select widgets
*/
const BooleanField: ComponentType<FieldProps<T, S, F>>;Widget Options:
// Default checkbox
const booleanSchema = {
type: "boolean",
title: "Accept Terms"
};
// Radio buttons for boolean
const radioUI = {
"ui:widget": "radio",
"ui:options": {
inline: true
}
};
// Select dropdown for boolean
const selectUI = {
"ui:widget": "select"
};Handle schema unions with multiple possible schemas.
/**
* Field component for anyOf schema unions
* Allows any of the specified schemas to match
*/
const AnyOfField: ComponentType<FieldProps<T, S, F>>;
/**
* Field component for oneOf schema unions
* Requires exactly one of the specified schemas to match
*/
const OneOfField: ComponentType<FieldProps<T, S, F>>;Union Schema Examples:
// OneOf - choose one schema
const oneOfSchema = {
oneOf: [
{
type: "string",
title: "Text Option"
},
{
type: "number",
title: "Number Option"
},
{
type: "object",
title: "Object Option",
properties: {
name: { type: "string" },
value: { type: "number" }
}
}
]
};
// AnyOf - match any schemas
const anyOfSchema = {
anyOf: [
{ type: "string", minLength: 5 },
{ type: "number", minimum: 10 }
]
};Handles null type schemas with hidden or disabled presentation.
/**
* Field component for null type schemas
* Typically renders as hidden input or disabled field
*/
const NullField: ComponentType<FieldProps<T, S, F>>;import { FieldProps } from "@rjsf/utils";
const CustomDateRangeField = (props: FieldProps) => {
const { schema, formData, onChange, registry } = props;
// Custom field logic for date range
const handleStartDateChange = (startDate: string) => {
onChange({
...formData,
startDate
});
};
const handleEndDateChange = (endDate: string) => {
onChange({
...formData,
endDate
});
};
return (
<div className="date-range-field">
<label>Start Date</label>
<input
type="date"
value={formData?.startDate || ''}
onChange={(e) => handleStartDateChange(e.target.value)}
/>
<label>End Date</label>
<input
type="date"
value={formData?.endDate || ''}
onChange={(e) => handleEndDateChange(e.target.value)}
/>
</div>
);
};
// Register custom field
const customFields = {
DateRangeField: CustomDateRangeField
};
// Use in schema
const schema = {
type: "object",
properties: {
dateRange: {
type: "object",
title: "Date Range"
}
}
};
const uiSchema = {
dateRange: {
"ui:field": "DateRangeField"
}
};
<Form
schema={schema}
uiSchema={uiSchema}
fields={customFields}
validator={validator}
/>const ConditionalField = (props: FieldProps) => {
const { schema, formData, registry, uiSchema } = props;
const { fields } = registry;
// Show different fields based on condition
if (formData?.type === 'advanced') {
return <fields.ObjectField {...props} />;
} else {
return <fields.StringField {...props} />;
}
};Install with Tessl CLI
npx tessl i tessl/npm-rjsf--core