Schema Form
Introduction
A React component capable of building HTML forms out of a JSON schema.
Usage
import React, { useState } from 'react';
import { SchemaForm, initFormData, JSONSchema, UISchema } from '@/components';
const schema: JSONSchema = {
title: 'General',
properties: {
name: {
type: 'string',
title: 'Name',
},
age: {
type: 'number',
title: 'Age',
},
sex: {
type: 'string',
title: 'sex',
enum: [1, 2],
enumNames: ['male', 'female'],
},
},
};
const uiSchema: UISchema = {
name: {
'ui:widget': 'input',
},
age: {
'ui:widget': 'input',
'ui:options': {
type: 'number',
},
},
sex: {
'ui:widget': 'radio',
},
};
const Form = () => {
const [formData, setFormData] = useState(initFormData(schema));
const handleChange = (data) => {
setFormData(data);
};
return (
<SchemaForm
schema={schema}
uiSchema={uiSchema}
formData={formData}
onChange={handleChange}
/>
);
};
export default Form;
Props
Property | Description | Type | Default |
---|---|---|---|
schema | Describe the form structure with schema | JSONSchema | - |
uiSchema | Describe the properties of the field | UISchema | - |
formData | Describe form data | FormData | - |
onChange | Callback function when form data changes | (data: FormData) => void | - |
onSubmit | Callback function when form is submitted | (data: React.FormEvent) => void | - |
Types Definition
JSONSchema
export interface JSONSchema {
title: string;
description?: string;
required?: string[];
properties: {
[key: string]: {
type: 'string' | 'boolean' | 'number';
title: string;
label?: string;
description?: string;
enum?: Array<string | boolean | number>;
enumNames?: string[];
default?: string | boolean | number;
};
};
}
UIOptions
export interface UIOptions {
empty?: string;
className?: string | string[];
validator?: (
value,
formData?,
) => Promise<string | true | void> | true | string;
}
InputOptions
export interface InputOptions extends UIOptions {
placeholder?: string;
type?:
| 'color'
| 'date'
| 'datetime-local'
| 'email'
| 'month'
| 'number'
| 'password'
| 'range'
| 'search'
| 'tel'
| 'text'
| 'time'
| 'url'
| 'week';
}
SelectOptions
export interface SelectOptions extends UIOptions {}
UploadOptions
export interface UploadOptions extends UIOptions {
acceptType?: string;
imageType?: 'post' | 'avatar' | 'branding';
}
SwitchOptions
export interface SwitchOptions extends UIOptions {}
TimezoneOptions
export interface TimezoneOptions extends UIOptions {
placeholder?: string;
}
CheckboxOptions
export interface CheckboxOptions extends UIOptions {}
RadioOptions
export interface RadioOptions extends UIOptions {}
TextareaOptions
export interface TextareaOptions extends UIOptions {
placeholder?: string;
rows?: number;
}
UIWidget
export type UIWidget =
| 'textarea'
| 'input'
| 'checkbox'
| 'radio'
| 'select'
| 'upload'
| 'timezone'
| 'switch';
UISchema
export interface UISchema {
[key: string]: {
'ui:widget'?: UIWidget;
'ui:options'?:
| InputOptions
| SelectOptions
| UploadOptions
| SwitchOptions
| TimezoneOptions
| CheckboxOptions
| RadioOptions
| TextareaOptions;
};
}
FormData
export interface FormValue<T = any> {
value: T;
isInvalid: boolean;
errorMsg: string;
[prop: string]: any;
}
export interface FormDataType {
[prop: string]: FormValue;
}
Backend API
For backend generating modal form you can return json like this.
Response
{
"name": "string",
"slug_name": "string",
"description": "string",
"version": "string",
"config_fields": [
{
"name": "string",
"type": "textarea" | "input" | "checkbox" | "radio" | "select" | "upload" | "timezone" | "switch",
"title": "string",
"description": "string",
"required": true,
"value": "string",
"ui_options": InputOptions | SelectOptions | UploadOptions | SwitchOptions | TimezoneOptions | CheckboxOptions | RadioOptions | TextareaOptions,
"options": [{ "value": "string", "label": "string"'}]
}
]
}