Skip to main content

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

PropertyDescriptionTypeDefault
schemaDescribe the form structure with schemaJSONSchema-
uiSchemaDescribe the properties of the fieldUISchema-
formDataDescribe form dataFormData-
onChangeCallback function when form data changes(data: FormData) => void-
onSubmitCallback 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"'}]
}
]
}

reference