Components
The package provides pre-built form elements with validation and styling via Shadcn UI.
Available Elements
Import from @schema-engine/forms-react/registrations:
import {
InputElementRegistration,
TextareaElementRegistration,
CheckboxElementRegistration,
RadioElementRegistration,
SelectElementRegistration,
SwitchElementRegistration,
NumberElementRegistration,
ArrayElementRegistration,
FieldSetRegistration,
SubmitButtonElementRegistration,
} from '@schema-engine/forms-react/registrations';| Element | Description |
|---|---|
input | Text, email, password, tel, url inputs |
textarea | Multi-line text input |
checkbox | Single checkbox or checkbox group |
radio | Radio button group |
select | Dropdown select |
switch | Toggle switch |
number | Number input with increment/decrement |
array | Dynamic array of form elements |
fieldset | Group of related form elements |
submit-button | Form submission button |
Registration System
Import only what you need for tree-shaking:
import { createReactFormComposer } from '@schema-engine/forms-react';
import {
InputElementRegistration,
CheckboxElementRegistration,
SelectElementRegistration,
} from '@schema-engine/forms-react/registrations';
const engine = createReactFormComposer()
.addElement(InputElementRegistration)
.addElement(CheckboxElementRegistration)
.addElement(SelectElementRegistration)
.build();Element Configuration
Input Field
{
"$type": "input",
"id": "email",
"name": "email",
"label": "Email Address",
"inputType": "email",
"placeholder": "[email protected]",
"rules": [
{ "rule": "required", "message": "Email is required" },
{ "rule": "email", "message": "Invalid email format" }
]
}Select Field
{
"$type": "select",
"id": "country",
"name": "country",
"label": "Country",
"options": [
{ "value": "us", "label": "United States" },
{ "value": "ca", "label": "Canada" },
{ "value": "uk", "label": "United Kingdom" }
],
"rules": [
{ "rule": "required", "message": "Please select a country" }
]
}Grid Layout
Elements support responsive grid layouts:
{
"id": "step-1",
"grid": {
"columns": 12,
"gap": "1rem"
},
"elements": [
{
"$type": "input",
"id": "firstName",
"name": "firstName",
"label": "First Name",
"grid": { "column": "1 / 7" }
},
{
"$type": "input",
"id": "lastName",
"name": "lastName",
"label": "Last Name",
"grid": { "column": "7 / 13" }
}
]
}Creating a Custom Component
Step 1: Define Your Component
Use useControlledFormElement to integrate with the form:
import { useControlledFormElement } from '@schema-engine/forms-react';
export function CustomDatePicker(config: FormEngine.ElementConfig) {
const {
value,
error,
onChange,
onBlur,
fieldProps,
labelProps,
errorProps,
containerStyles,
} = useControlledFormElement(config);
return (
<div style={containerStyles}>
<label {...labelProps}>{config.label}</label>
<DatePicker
{...fieldProps}
selected={value}
onChange={onChange}
onBlur={onBlur}
/>
{errorProps && <span {...errorProps}>{error}</span>}
</div>
);
}Step 2: Create Schema
import { z } from 'zod';
import { BaseElementConfigSchema } from '@schema-engine/forms/schemas';
export const CustomDatePickerConfigSchema = BaseElementConfigSchema.extend({
$type: z.literal('custom-date-picker'),
minDate: z.string().optional(),
maxDate: z.string().optional(),
});Step 3: Create Registration
import type { ElementRegistration } from '@schema-engine/forms';
export const CustomDatePickerRegistration: ElementRegistration = {
$type: 'custom-date-picker',
schema: CustomDatePickerConfigSchema,
metadata: {
name: 'Custom Date Picker',
description: 'Date selection with custom styling',
category: 'input',
},
render: CustomDatePicker,
};Step 4: Register with Engine
const engine = createReactFormComposer()
.addElement(CustomDatePickerRegistration)
.build();Step 5: Use in Form Config
{
"$type": "custom-date-picker",
"id": "birthdate",
"name": "birthdate",
"label": "Date of Birth"
}