Generate Json data with the controlled form based on "antd"、“lodash-es”、"immer"
npm install antd-form-json
yarn add antd-form-json
import { useState } from 'react';
import { FormJson } from 'antd-form-json';
import type { IFormItem, ETypes } from 'antd-form-json';
const App = () => {
const [formStates, setFormStates] = useState<IFormItem[]>([
{
name: 'mikasa',
value: '',
id: '1',
type: ETypes.Object,
children: [
{
name: 'name',
value: 'Ackerman',
id: '2',
type: ETypes.String,
children: [],
},
{
name: 'height',
value: 170,
id: '4',
type: ETypes.Number,
children: [],
},
{
name: 'hobby',
value: 170,
id: '5',
type: ETypes.Array,
children: [
{
name: '',
value: 'kill Alen',
id: '6',
type: ETypes.String,
children: [],
},
],
},
],
},
{
name: 'isAlenSb',
value: true,
id: '3',
type: ETypes.Boolean,
children: [],
},
]);
return (
<div>
<FormJson formStates={formStates} setFormStates={setFormStates} />
</div>
)
}
Property | Description | Type | Default | Required |
---|---|---|---|---|
formStates | The initial state | IFormItem[] | ✅ | |
setFormStates | Dispatch actions | Dispatch"<"SetStateAction"<"IFormItem[]">"">" | ✅ | |
indent | Indent size in pixels of tree data | number | 16 | |
spans | The span of grid between each element for every line | number[] | [8,5,8,3] | |
containerClassName | The container class | string | ||
itemClassName | The class for each line's container | string | ||
onAddChildren | A callback function, can be executed when clicking to the plus children icon | OnStateCurd | ||
onAddSibling | A callback function, can be executed when clicking to the plus icon | OnStateCurd | ||
onDeleteItem | A callback function, can be executed when clicking to the delete icon | OnStateCurd | ||
onStateChange | A callback function, can be executed when the input element's value has been changed | OnStateChange |
type useJsonStates = (formStates: IFormItem[]) => Object
return the memorized json object from formStates.
import { useState } from 'react';
import { FormJson, useJsonStates } from 'antd-form-json';
import type { IFormItem, ETypes } from 'antd-form-json';
const App = () => {
const [formStates, setFormStates] = useState<IFormItem[]>([
{
name: 'mikasa',
value: '',
id: '1',
type: ETypes.Object,
children: [
{
name: 'name',
value: 'Ackerman',
id: '2',
type: ETypes.String,
children: [],
},
{
name: 'height',
value: 170,
id: '4',
type: ETypes.Number,
children: [],
},
{
name: 'hobby',
value: 170,
id: '5',
type: ETypes.Array,
children: [
{
name: '',
value: 'kill Alen',
id: '6',
type: ETypes.String,
children: [],
},
],
},
],
},
{
name: 'isAlenSb',
value: true,
id: '3',
type: ETypes.Boolean,
children: [],
},
]);
const jsonState = useJsonStates(formStates);
/**
* current jsonState:
* {
* mikasa: {
* name: "Ackerman",
* height: 170,
* hobby: ["kill Alen"]
* },
* isAlenSb: true
* }
* */
return (
<div>
<FormJson formStates={formStates} setFormStates={setFormStates} />
</div>
)
}
type useFormActions = (props: IFormActions) => ReturnFormACtions
The CURD actions for the form which has already been binded to the form element event, maybe you could use it in other place.
interface IFormItem {
name: string; // The Json Key
value: string | number | boolean; // The value to the current json key
id: string; // The unique key for each line
type: string; // ETypes
children: IFormItem[]; // The nested children when the type is 'array' or 'object'
}
enum ETypes {
String = 'string',
Number = 'number',
Array = 'array',
Object = 'object',
Boolean = 'boolean',
}
type TEditField = Exclude<keyof IFormItem, 'id' | 'children' | 'path'>;
interface IFormActions extends ICallbacks {
setFormStates: Dispatch<SetStateAction<IFormItem[]>>;
}
interface ICallbacks {
onAddChildren?: OnStateCurd;
onAddSibling?: OnStateCurd;
onDeleteItem?: OnStateCurd;
onStateChange?: OnStateChange;
}
type OnStateCurd = (path: number[]) => void;
type OnStateChange = (path: number[], field: TEditField, value: string | number | boolean) => void;