@uform/antd
Install
npm install --save @uform/antd
Table Of Contents
Quick-Start
Example:develop with JSX
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import { Button } from 'antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions}>
<Field
type="radio"
enum={['1', '2', '3', '4']}
title="Radio"
name="radio"
/>
<Field
type="string"
enum={['1', '2', '3', '4']}
required
title="Select"
name="select"
/>
<Field
type="checkbox"
enum={['1', '2', '3', '4']}
required
title="Checkbox"
name="checkbox"
/>
<Field
type="string"
title="TextArea"
name="textarea"
x-component="textarea"
/>
<Field type="number" title="number" name="number" />
<Field type="boolean" title="boolean" name="boolean" />
<Field type="date" title="date" name="date" />
<Field
type="daterange"
title="daterange"
default={['2018-12-19', '2018-12-19']}
name="daterange"
/>
<Field type="year" title="year" name="year" />
<Field type="time" title="time" name="time" />
<Field
type="upload"
title="upload(card)"
name="upload"
x-props={{ listType: 'card' }}
/>
<Field
type="upload"
title="upload(dragge)"
name="upload2"
x-props={{ listType: 'dragger' }}
/>
<Field
type="upload"
title="upload(text)"
name="upload3"
x-props={{ listType: 'text' }}
/>
<Field
type="range"
title="range"
name="range"
x-props={{ min: 0, max: 1024, marks: [0, 1024] }}
/>
<Field
type="transfer"
enum={[{ value: 1, title: 'opt1' }, { value: 2, title: 'opt2' }]}
x-props={{
render: (item) => item.title
}}
title="transfer"
name="transfer"
/>
<Field type="rating" title="rating" name="rating" />
<FormButtonGroup offset={7} sticky>
<Submit />
<Reset />
<Button
onClick={() => {
actions.setFieldState('upload', state => {
state.value = [
{
downloadURL:
'//img.alicdn.com/tfs/TB1n8jfr1uSBuNjy1XcXXcYjFXa-200-200.png',
imgURL:
'//img.alicdn.com/tfs/TB1n8jfr1uSBuNjy1XcXXcYjFXa-200-200.png',
name: 'doc.svg'
}
]
})
}}
>
Upload
</Button>
<Button
onClick={() => {
actions.setFormState(state => {
state.values = {
radio: '4',
checkbox: ['2', '3']
}
})
}}
>
Set Value
</Button>
</FormButtonGroup>
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
Example:develop with JSON Schema
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import { Button } from 'antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
const schema = {
type: 'object',
properties: {
radio: {
type: 'radio',
enum: ['1', '2', '3', '4'],
title: 'Radio'
},
select: {
type: 'string',
enum: ['1', '2', '3', '4'],
title: 'Select',
required: true
},
checkbox: {
type: 'checkbox',
enum: ['1', '2', '3', '4'],
title: 'Checkbox',
required: true
},
textarea: {
type: 'string',
'x-component': 'textarea',
title: 'TextArea'
},
number: {
type: 'number',
title: 'number'
},
boolean: {
type: 'boolean',
title: 'boolean'
},
date: {
type: 'date',
title: 'date'
},
daterange: {
type: 'daterange',
default: ['2018-12-19', '2018-12-19'],
title: 'daterange'
},
year: {
type: 'year',
title: 'year'
},
time: {
type: 'time',
title: 'time'
},
upload: {
type: 'upload',
'x-props': {
listType: 'card'
},
title: 'upload(card)'
},
upload2: {
type: 'upload',
'x-props': {
listType: 'dragger'
},
title: 'uplaod(dragger)'
},
upload3: {
type: 'upload',
'x-props': {
listType: 'text'
},
title: 'upload(text)'
},
range: {
type: 'range',
'x-props': {
min: 0,
max: 1024,
marks: [0, 1024]
},
title: 'range'
},
transfer: {
type: 'transfer',
enum: [
{
key: 1,
title: 'opt1'
},
{
key: 2,
title: 'opt2'
}
],
'x-props': {
render: (item) => item.title
},
title: 'transfer'
},
rating: {
type: 'rating',
title: 'rating'
},
layout_btb_group: {
type: 'object',
'x-component': 'button-group',
'x-component-props': {
offset:7,
sticky: true,
},
properties: {
submit_btn: {
type: 'object',
'x-component': 'submit',
'x-component-props': {
children: 'Submit',
},
},
reset_btn: {
type: 'object',
'x-component': 'reset',
'x-component-props': {
children: 'Reset',
},
},
}
},
}
}
return <SchemaForm actions={actions} schema={schema} />
}
ReactDOM.render(<App />, document.getElementById('root'))
Components
<SchemaForm/>
Base on <SchemaMarkupForm/>
of @uform/react-schema-renderer. Recommended for production environments.
interface IAntdSchemaFormProps {
schema?: ISchema;
fields?: ISchemaFormRegistry['fields'];
virtualFields?: ISchemaFormRegistry['virtualFields'];
formComponent?: ISchemaFormRegistry['formComponent'];
formItemComponent?: ISchemaFormRegistry['formItemComponent'];
layout?: FormLayout;
form?: WrappedFormUtils;
onSubmit?: React.FormEventHandler<HTMLFormElement>;
style?: React.CSSProperties;
className?: string;
prefixCls?: string;
hideRequiredMark?: boolean;
wrapperCol?: ColProps;
labelCol?: ColProps;
colon?: boolean;
labelAlign?: FormLabelAlign;
inline?: boolean
className?: string
style?: React.CSSProperties
previewPlaceholder?: string | ((props: IPreviewTextProps) => string);
value?: Value;
defaultValue?: DefaultValue;
initialValues?: DefaultValue;
actions?: FormActions;
effects?: IFormEffect<FormEffectPayload, FormActions>;
form?: IForm;
onChange?: (values: Value) => void;
onSubmit?: (values: Value) => void | Promise<Value>;
onReset?: () => void;
onValidateFailed?: (valideted: IFormValidateResult) => void;
children?: React.ReactElement | ((form: IForm) => React.ReactElement);
useDirty?: boolean;
editable?: boolean | ((name: string) => boolean);
validateFirst?: boolean;
}
Usage
Example1: Sync value of a and a-mirror
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
registerFormField,
Field,
connect,
createFormActions
} from '@uform/antd'
import'antd/dist/antd.css'
const actions = createFormActions()
ReactDOM.render(
<SchemaForm actions={actions} effects={($)=>{
$('onFieldChange','aa').subscribe((fieldState)=>{
actions.setFieldState('bb',state=>{
state.value = fieldState.value
})
})
}}>
<Field type="string" name="a" title="a"/>
<Field type="string" name="a-mirror" title="a-mirror"/>
</SchemaForm>,
document.getElementById('root')
)
Example:Layout
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
Field,
createFormActions,
FormLayout,
FormButtonGroup,
Submit,
Reset,
} from '@uform/antd'
const actions = createFormActions()
ReactDOM.render(
<div>
<h5>Basic Layout</h5>
<SchemaForm>
<FormLayout labelCol={8} wrapperCol={6}>
<Field name="aaa" type="string" title="field1" />
<Field name="bbb" type="number" title="field2" />
<Field name="ccc" type="date" title="field3" />
</FormLayout>
<FormButtonGroup offset={8}>
<Submit>Submit</Submit> <Reset>Reset</Reset>
</FormButtonGroup>
</SchemaForm>
<h5>Inline Layout</h5>
<SchemaForm inline>
<Field name="aaa" type="string" title="field1" />
<Field name="bbb" type="number" title="field2" />
<Field name="ccc" type="date" title="field3" />
<FormButtonGroup>
<Submit>Submit</Submit> <Reset>Reset</Reset>
</FormButtonGroup>
</SchemaForm>
<h5>editable = false</h5>
<SchemaForm inline editable={false}>
<Field name="aaa" type="string" title="field1" />
<Field name="bbb" type="number" title="field2" />
<Field name="ccc" type="date" title="field3" />
<FormButtonGroup>
<Submit>Submit</Submit> <Reset>Reset</Reset>
</FormButtonGroup>
</SchemaForm>
</div>,
document.getElementById('root')
)
<SchemaMarkupField/>
Core components of @uform/antd, used to describe form fields
interface IMarkupSchemaFieldProps {
name?: string
title?: SchemaMessage
description?: SchemaMessage
default?: any
readOnly?: boolean
writeOnly?: boolean
type?: 'string' | 'object' | 'array' | 'number' | string
enum?: Array<string | number | { label: SchemaMessage; value: any }>
const?: any
multipleOf?: number
maximum?: number
exclusiveMaximum?: number
minimum?: number
exclusiveMinimum?: number
maxLength?: number
minLength?: number
pattern?: string | RegExp
maxItems?: number
minItems?: number
uniqueItems?: boolean
maxProperties?: number
minProperties?: number
required?: string[] | boolean
format?: string
properties?: {
[key: string]: ISchema
}
items?: ISchema | ISchema[]
additionalItems?: ISchema
patternProperties?: {
[key: string]: ISchema
}
additionalProperties?: ISchema
editable?: boolean
visible?: boolean
display?: boolean
['x-props']?: { [name: string]: any }
['x-index']?: number
['x-rules']?: ValidatePatternRules
['x-component']?: string
['x-component-props']?: { [name: string]: any }
['x-render']?: <T = ISchemaFieldComponentProps>(
props: T & {
renderComponent: () => React.ReactElement
}
) => React.ReactElement
['x-effect']?: (
dispatch: (type: string, payload: any) => void,
option?: object
) => { [key: string]: any }
}
Usage
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
FormSlot,
Field,
createFormActions,
FormLayout,
FormButtonGroup,
Submit,
Reset,
} from '@uform/antd'
const actions = createFormActions()
ReactDOM.render(
<SchemaForm>
<FormSlot><div>required</div></FormSlot>
<Field name="a" required type="string" title="field1" />
<FormSlot><div>description</div></FormSlot>
<Field name="b" description="description" type="string" title="field1" />
<FormSlot><div>default value</div></FormSlot>
<Field name="c" default={10} type="string" title="field1" />
<FormSlot><div>readOnly</div></FormSlot>
<Field name="d" readOnly default={10} type="string" title="field1" />
<FormSlot><div>visible = false</div></FormSlot>
<Field name="e" visible={false} default={10} type="string" title="field1" />
<FormSlot><div>display = false</div></FormSlot>
<Field name="f" visible={false} default={10} type="string" title="field1" />
<FormSlot><div>editable = false</div></FormSlot>
<Field name="g" editable={false} default={10} type="string" title="field1" />
</SchemaForm>,
document.getElementById('root')
)
<Submit/>
Props of <Submit/>
interface ISubmitProps {
onSubmit?: ISchemaFormProps['onSubmit']
showLoading?: boolean
type?: 'primary' | 'secondary' | 'normal'
size?: 'small' | 'medium' | 'large'
iconSize?: 'xxs' | 'xs' | 'small' | 'medium' | 'large' | 'xl' | 'xxl' | 'xxxl'
htmlType?: 'submit' | 'reset' | 'button'
component?: 'button' | 'a'
loading?: boolean
ghost?: true | false | 'light' | 'dark'
text?: boolean
warning?: boolean
disabled?: boolean
onClick?: (e: {}) => void
href?: string
target?: string
}
<Reset/>
Props of <Reset/>
interface IResetProps {
forceClear?: boolean
validate?: boolean
type?: 'primary' | 'secondary' | 'normal'
size?: 'small' | 'medium' | 'large'
iconSize?: 'xxs' | 'xs' | 'small' | 'medium' | 'large' | 'xl' | 'xxl' | 'xxxl'
htmlType?: 'submit' | 'reset' | 'button'
component?: 'button' | 'a'
loading?: boolean
ghost?: true | false | 'light' | 'dark'
text?: boolean
warning?: boolean
disabled?: boolean
onClick?: (e: {}) => void
href?: string
target?: string
}
<FormSpy/>
<FormSpy>
Props
interface IFormSpyProps {
selector?: string[] | string
reducer?: (
state: any,
action: { type: string; payload: any },
form: IForm
) => any
children?: React.ReactElement | ((api: IFormSpyAPI) => React.ReactElement)
}
Usage
Example1: Form state change counter
import React from 'react'
import ReactDOM from 'react-dom'
import { Form, Field, createFormActions, FormSpy, LifeCycleTypes } from '@uform/react'
const actions = createFormActions()
const InputField = props => (
<Field {...props}>
{({ state, mutators }) => (
<React.Fragment>
<input
disabled={!state.editable}
value={state.value || ''}
onChange={mutators.change}
onBlur={mutators.blur}
onFocus={mutators.focus}
/>
<span style={{ color: 'red' }}>{state.errors}</span>
<span style={{ color: 'orange' }}>{state.warnings}</span>
</React.Fragment>
)}
</Field>
)
const App = () => {
return (
<Form actions={actions}>
<label>username</label>
<InputField name="username" />
<label>age</label>
<InputField name="age" />
<FormSpy
selector={LifeCycleTypes.ON_FORM_VALUES_CHANGE}
reducer={(state, action, form) => ({
count: state.count ? state.count + 1 : 1
})}
>
{({ state, type, form }) => {
return <div>count: {state.count || 0}</div>
}}
</FormSpy>
</Form>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
Example2:Combo
import React from 'react'
import ReactDOM from 'react-dom'
import { Form, Field, createFormActions, FormSpy } from '@uform/react'
const actions = createFormActions()
const InputField = props => (
<Field {...props}>
{({ state, mutators }) => (
<React.Fragment>
<input
disabled={!state.editable}
value={state.value || ''}
onChange={mutators.change}
onBlur={mutators.blur}
onFocus={mutators.focus}
/>
<span style={{ color: 'red' }}>{state.errors}</span>
<span style={{ color: 'orange' }}>{state.warnings}</span>
</React.Fragment>
)}
</Field>
)
const App = () => {
return (
<Form actions={actions}>
<label>username</label>
<InputField name="username" />
<label>age</label>
<InputField name="age" />
<FormSpy>
{({ state, form }) => {
return (
<div>
name: {form.getFieldValue('username')}
<br />
age: {form.getFieldValue('age')}
</div>
)
}}
</FormSpy>
</Form>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
<Field/>
deprecated,please use SchemaMarkupField
Array Components
array
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
Field,
FormItemGrid,
FormButtonGroup,
Submit,
Reset,
FormBlock,
FormLayout
} from '@uform/antd'
import'antd/dist/antd.css'
import Printer from '@uform/printer'
const App = () => {
const [value, setValues] = useState({})
useEffect(() => {
setTimeout(() => {
setValues({
array: [{ array2: [{ aa: '123', bb: '321' }] }]
})
}, 1000)
}, [])
return (
<Printer>
<SchemaForm initialValues={value} onSubmit={v => console.log(v)}>
<Field
title="Array"
name="array"
maxItems={3}
type="array"
x-props={{
renderAddition: 'Add Text',
renderRemove: 'Remove Text'
}}
>
<Field type="object">
<FormBlock title="Object Field">
<FormLayout labelCol={9} wrapperCol={6}>
<Field name="aa" type="string" title="field1" />
<Field name="bb" type="string" title="field2" />
<FormItemGrid title="field3" gutter={10}>
<Field name="cc" type="string" />
<Field name="dd" type="string" />
</FormItemGrid>
</FormLayout>
</FormBlock>
<FormBlock title="Nested Array Field">
<Field name="array2" maxItems={3} type="array">
<Field type="object">
<FormLayout labelCol={9} wrapperCol={6}>
<Field name="aa" type="string" title="field1" />
<Field name="bb" type="string" title="field2" />
<FormItemGrid title="field3" gutter={10}>
<Field name="cc" type="string" />
<Field name="dd" type="string" />
</FormItemGrid>
</FormLayout>
</Field>
</Field>
</FormBlock>
</Field>
</Field>
<FormButtonGroup>
<Submit>Submit</Submit>
<Reset>Reset</Reset>
</FormButtonGroup>
</SchemaForm>
</Printer>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
cards
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
Field,
FormItemGrid,
FormButtonGroup,
Submit,
Reset,
FormBlock,
FormLayout
} from '@uform/antd'
import'antd/dist/antd.css'
import Printer from '@uform/printer'
const App = () => (
<Printer>
<SchemaForm>
<Field
name="array"
maxItems={3}
type="array"
x-component="cards"
x-props={{
title: 'Title of cards',
renderAddition: 'Add Text',
renderRemove: 'Remove Text'
}}
>
<Field type="object">
<FormLayout labelCol={6} wrapperCol={8}>
<Field
name="aa"
type="string"
description="hello world"
title="field1"
/>
<Field name="bb" type="string" title="field2" />
<Field name="cc" type="string" title="field3" />
<Field name="dd" type="string" title="field4" />
<Field name="dd" type="string" title="field5" />
<Field name="ee" type="string" title="field6" />
<Field name="ff" type="string" title="field7" />
<Field name="gg" type="daterange" title="field8" />
</FormLayout>
<Field
name="array"
maxItems={3}
type="array"
x-component="cards"
x-props={{ title: 'Title of cards' }}
>
<Field type="object">
<FormLayout labelCol={6} wrapperCol={8}>
<Field
name="aa"
type="string"
description="hello world"
title="field1"
/>
<Field name="bb" type="string" title="field2" />
<Field name="cc" type="string" title="field3" />
<Field name="dd" type="string" title="field4" />
<Field name="dd" type="string" title="field5" />
<Field name="ee" type="string" title="field6" />
<Field name="ff" type="string" title="field7" />
<Field name="gg" type="daterange" title="field8" />
</FormLayout>
</Field>
</Field>
</Field>
</Field>
</SchemaForm>
</Printer>
)
ReactDOM.render(<App />, document.getElementById('root'))
table
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
Field,
FormItemGrid,
FormButtonGroup,
Submit,
Reset,
FormBlock,
FormLayout
} from '@uform/antd'
import'antd/dist/antd.css'
import Printer from '@uform/printer'
const App = () => (
<Printer>
<SchemaForm>
<FormLayout>
<Field
title="Array"
name="array"
maxItems={3}
type="array"
x-component="table"
x-props={{
renderExtraOperations() {
return <div>Hello worldasdasdasdasd</div>
},
operationsWidth: 300
}}
>
<Field type="object">
<Field
name="aa"
type="string"
description="hello world"
title="field1"
/>
<Field name="bb" type="string" title="field2" />
<Field name="cc" type="string" title="field3" />
<Field name="dd" type="string" title="field4" x-index={1} />
<Field name="ee" type="string" title="field5" />
<Field name="ff" type="string" title="field6" />
<Field name="gg" type="string" title="field7" />
<Field name="hh" type="daterange" title="field8" />
</Field>
</Field>
</FormLayout>
</SchemaForm>
</Printer>
)
ReactDOM.render(<App />, document.getElementById('root'))
Layout Components
<FormCard/>
Props of <FormCard/>
, fully inherited from CardProps。
The only difference between FormCard FormBlock is a border on the style
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, { FormCard, SchemaMarkupField as Field } from '@uform/antd'
import'antd/dist/antd.css'
const App = () => (
<SchemaForm>
<FormCard title="block">
<Field type="string" name="username" title="username" />
</FormCard>
</SchemaForm>
)
ReactDOM.render(<App />, document.getElementById('root'))
<FormBlock/>
Props of <FormBlock/>
, fully inherited from CardProps
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, { FormBlock, SchemaMarkupField as Field } from '@uform/antd'
import'antd/dist/antd.css'
const App = () => (
<SchemaForm>
<FormBlock title="block">
<Field type="string" name="username" title="username" />
</FormBlock>
</SchemaForm>
)
ReactDOM.render(<App />, document.getElementById('root'))
<FormStep/>
Props of <FormStep/>
interface IFormStep {
dataSource: StepItemProps[]
current?: number
direction?: 'hoz' | 'ver'
labelPlacement?: 'hoz' | 'ver'
shape?: 'circle' | 'arrow' | 'dot'
readOnly?: boolean
animation?: boolean
className?: string
itemRender?: (index: number, status: string) => React.ReactNode
}
Usage
import {
SchemaForm,
Field,
FormButtonGroup,
Submit,
FormEffectHooks,
createFormActions,
FormGridRow,
FormItemGrid,
FormGridCol,
FormPath,
FormLayout,
FormBlock,
FormCard,
FormTextBox,
FormStep
} from '@uform/antd'
import { Button } from 'antd'
import'antd/dist/antd.css'
const { onFormInit$ } = FormEffectHooks
const actions = createFormActions()
let cache = {}
export default () => (
<SchemaForm
onSubmit={values => {
console.log('submit')
console.log(values)
}}
actions={actions}
labelCol={{ span: 8 }}
wrapperCol={{ span: 6 }}
validateFirst
effects={({ setFieldState, getFormGraph }) => {
onFormInit$().subscribe(() => {
setFieldState('col1', state => {
state.visible = false
})
})
}}
>
<FormStep
style={{ marginBottom: 20 }}
dataSource={[
{ title: 'Step1', name: 'step-1' },
{ title: 'Step2', name: 'step-2' },
{ title: 'Step3', name: 'step-3' }
]}
/>
<FormCard name="step-1" title="Step1">
<Field name="a1" required title="A1" type="string" />
</FormCard>
<FormCard name="step-2" title="Step2">
<Field name="a2" required title="A2" type="string" />
</FormCard>
<FormCard name="step-3" title="Step3">
<Field name="a3" required title="A3" type="string" />
</FormCard>
<FormButtonGroup>
<Submit>Submit</Submit>
<Button onClick={() => actions.dispatch(FormStep.ON_FORM_STEP_PREVIOUS)}>
Prev
</Button>
<Button onClick={() => actions.dispatch(FormStep.ON_FORM_STEP_NEXT)}>
Next
</Button>
<Button
onClick={() => {
cache = actions.getFormGraph()
}}
>
Save State
</Button>
<Button
onClick={() => {
actions.setFormGraph(cache)
}}
>
Rollback State
</Button>
</FormButtonGroup>
</SchemaForm>
)
<FormLayout/>
Props of <FormLayout/>
interface IFormItemTopProps {
inline?: boolean
className?: string
style?: React.CSSProperties
labelCol?: number | { span: number; offset?: number }
wrapperCol?: number | { span: number; offset?: number }
}
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import {
SchemaForm,
Field,
FormButtonGroup,
Submit,
Reset,
FormItemGrid,
FormCard,
FormBlock,
FormLayout
} from '@uform/antd'
import { Button } from 'antd'
import Printer from '@uform/printer'
import'antd/dist/antd.css'
const App = () => (
<Printer>
<SchemaForm>
<FormLayout labelCol={8} wrapperCol={6}>
<Field name="aaa" type="string" title="field1" />
<Field name="bbb" type="number" title="field2" />
<Field name="ccc" type="date" title="field3" />
</FormLayout>
<FormButtonGroup offset={8}>
<Submit>Submit</Submit> <Reset>Reset</Reset>
</FormButtonGroup>
</SchemaForm>
</Printer>
)
ReactDOM.render(<App />, document.getElementById('root'))
<FormItemGrid/>
Props of <FormItemGrid/>
interface IFormItemGridProps {
cols?: Array<number | { span: number; offset: number }>
gutter?: number
prefix?: string
label?: React.ReactNode
labelCol?: {}
wrapperCol?: {}
help?: React.ReactNode
extra?: React.ReactNode
validateState?: 'error' | 'success' | 'loading'
hasFeedback?: boolean
style?: React.CSSProperties
children?: React.ReactNode | (() => void)
size?: 'large' | 'small' | 'medium'
labelAlign?: 'top' | 'left' | 'inset'
labelTextAlign?: 'left' | 'right'
className?: string
required?: boolean
asterisk?: boolean
requiredMessage?: string
requiredTrigger?: string | Array<any>
min?: number
max?: number
minmaxMessage?: string
minmaxTrigger?: string | Array<any>
minLength?: number
maxLength?: number
minmaxLengthMessage?: string
minmaxLengthTrigger?: string | Array<any>
length?: number
lengthMessage?: string
lengthTrigger?: string | Array<any>
pattern?: any
patternMessage?: string
patternTrigger?: string | Array<any>
format?: 'number' | 'email' | 'url' | 'tel'
formatMessage?: string
formatTrigger?: string | Array<any>
validator?: () => void
validatorTrigger?: string | Array<any>
autoValidate?: boolean
}
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import {
SchemaForm,
Field,
FormButtonGroup,
Submit,
Reset,
FormItemGrid,
FormCard,
FormBlock,
FormLayout
} from '@uform/antd'
import { Button } from 'antd'
import Printer from '@uform/printer'
import'antd/dist/antd.css'
const App = () => (
<Printer>
<SchemaForm onSubmit={v => console.log(v)}>
<FormItemGrid gutter={20}>
<Field type="string" name="a1" title="field1" />
<Field type="string" name="a2" title="field2" />
<Field type="string" name="a3" title="field3" />
<Field type="string" name="a4" title="field4" />
</FormItemGrid>
<FormItemGrid gutter={20} cols={[6, 6]}>
<Field type="string" name="a5" title="field5" />
<Field type="string" name="a6" title="field6" />
</FormItemGrid>
<FormButtonGroup style={{ minWidth: 150 }}>
<Submit>Submit</Submit><Reset>Reset</Reset>
</FormButtonGroup>
</SchemaForm>
</Printer>
)
ReactDOM.render(<App />, document.getElementById('root'))
<FormTextBox/>
Props of <FormTextBox/>
interface IFormTextBox {
text?: string
gutter?: number
title?: React.ReactText
description?: React.ReactText
}
Usage
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
import {
SchemaForm,
Field,
FormTextBox,
FormCard,
FormLayout
} from '@uform/antd'
import { Button } from 'antd'
import Printer from '@uform/printer'
import'antd/dist/antd.css'
const App = () => {
return (
<Printer>
<SchemaForm labelCol={8} wrapperCol={6} onSubmit={v => console.log(v)}>
<FormCard title="FormTextBox">
<FormLayout labelCol={8} wrapperCol={16}>
<FormTextBox
title="text label"
text="prefix%suffix prefix2%suffix2 prefix3%suffix3"
gutter={8}
>
<Field
type="string"
default={10}
required
name="aa1"
x-props={{ style: { width: 80 } }}
description="desc1"
/>
<Field
type="number"
default={20}
required
name="aa2"
description="desc2"
/>
<Field
type="number"
default={30}
required
name="aa3"
description="desc3"
/>
</FormTextBox>
</FormLayout>
</FormCard>
</SchemaForm>
</Printer>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
<FormButtonGroup/>
Props of <FormButtonGroup/>
interface IFormButtonGroupProps {
sticky?: boolean
style?: React.CSSProperties
itemStyle?: React.CSSProperties
className?: string
align?: 'left' | 'right' | 'start' | 'end' | 'top' | 'bottom' | 'center'
triggerDistance?: number
zIndex?: number
span?: ColSpanType
offset?: ColSpanType
}
Usage
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
import {
SchemaForm,
Field,
FormButtonGroup,
Submit,
Reset,
FormItemGrid,
FormCard,
FormBlock,
FormLayout
} from '@uform/antd'
import { Button } from 'antd'
import Printer from '@uform/printer'
import'antd/dist/antd.css'
const App = () => {
const [state, setState] = useState({ editable: true })
return (
<Printer>
<SchemaForm onSubmit={v => console.log(v)}>
<div>normal</div>
<FormButtonGroup style={{ minWidth: 150 }}>
<Submit>Submit</Submit><Reset>Reset</Reset>
</FormButtonGroup>
<div>sticky</div>
<FormButtonGroup offset={8} sticky>
<Submit>Submit</Submit>
<Button
type="primary"
onClick={() => setState({ editable: !state.editable })}
>
{state.editable ? 'Preview' : 'Edit'}
</Button>
<Reset>Reset</Reset>
</FormButtonGroup>
</SchemaForm>
</Printer>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
<TextButton/>
Props of <TextButton/>
, fully inherited from ButtonProps
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, { TextButton } from '@uform/antd'
import'antd/dist/antd.css'
const App = () => (
<SchemaForm>
<TextButton>content</TextButton>
</SchemaForm>
)
ReactDOM.render(<App />, document.getElementById('root'))
<CircleButton/>
Props of <CircleButton/>
, fully inherited from ButtonProps
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, { CircleButton } from '@uform/antd'
import'antd/dist/antd.css'
const App = () => (
<SchemaForm>
<CircleButton>ok</CircleButton>
</SchemaForm>
)
ReactDOM.render(<App />, document.getElementById('root'))
Type of SchemaMarkupField
string
- Schema Type :
string
- Schema UI Component: Fusion-Next
<Input/>
, <Input.Textarea/>
, <Select/>
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions}>
<Field
type="string"
required
title="Text"
name="text"
x-component-props={{
placeholder: 'input'
}}
/>
<Field
type="string"
enum={['1', '2', '3', '4']}
required
title="Simple Select"
name="simpleSelect"
x-component-props={{
placeholder: 'select'
}}
/>
<Field
type="string"
enum={[
{ label: 'One', value: '1' },
{ label: 'Two', value: '2' },
{ label: 'Three', value: '3' },
{ label: 'Four', value: '4' }
]}
required
title="Object Select"
name="objSelect"
x-component-props={{
placeholder: 'select'
}}
/>
<Field
type="string"
title="TextArea"
name="textarea"
x-component="textarea"
x-component-props={{
placeholder: 'textarea'
}}
/>
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
textarea
- Schema Type :
string
- Schema UI Component: Fusion-Next
<Input.Textarea/>
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions}>
<Field
type="string"
title="TextArea"
name="textarea"
x-component="textarea"
x-component-props={{
placeholder: 'textarea'
}}
/>
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
password
- Schema Type :
password
- Schema UI Component: Fusion-Next
<Input htmlType="password"/>
interface IPasswordProps {
checkStrength: boolean
value?: string | number
defaultValue?: string | number
onChange?: (value: string, e: React.ChangeEvent<HTMLInputElement>) => void
onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>, opts: {}) => void
disabled?: boolean
maxLength?: number
hasLimitHint?: boolean
cutString?: boolean
readOnly?: boolean
trim?: boolean
placeholder?: string
onFocus?: () => void
onBlur?: () => void
getValueLength?: (value: string) => number
className?: string
style?: React.CSSProperties
htmlType?: string
name?: string
state?: 'error' | 'loading' | 'success'
label?: React.ReactNode
hasClear?: boolean
hasBorder?: boolean
size?: 'small' | 'medium' | 'large'
onPressEnter?: () => void
hint?: string
innerBefore?: React.ReactNode
innerAfter?: React.ReactNode
addonBefore?: React.ReactNode
addonAfter?: React.ReactNode
addonTextBefore?: React.ReactNode
addonTextAfter?: React.ReactNode
autoComplete?: string
autoFocus?: boolean
}
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions}>
<Field
type="string"
title="Password"
name="password"
x-component="password"
x-component-props={{
placeholder: 'password'
}}
/>
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
number
- Schema Type :
number
- Schema UI Component: Fusion-Next
<NumberPicker/>
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions}>
<Field type="number" required title="Number" name="number" />
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
boolean
- Schema Type :
boolean
- Schema UI Component: Fusion-Next
<Switch/>
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions}>
<Field
type="boolean"
required
title="Boolean"
name="boolean"
x-component-props={{
checkedChildren: 'on',
unCheckedChildren: 'off'
}}
/>
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
date
- Schema Type :
date
- Schema UI Component: Fusion-Next
<DatePicker/>
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions}>
<Field
type="date"
required
title="DatePicker"
name="datePicker"
x-component-props={{
format: 'YYYY-MM-DD HH:mm:ss'
}}
/>
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
time
- Schema Type :
time
- Schema UI Component: Fusion-Next
<TimePicker/>
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions}>
<Field
type="time"
required
title="TimePicker"
name="timePicker"
x-component-props={{
format: 'YYYY-MM-DD HH:mm:ss'
}}
/>
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
range
- Schema Type :
range
- Schema UI Component: Fusion-Next
<Range/>
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions}>
<Field
type="range"
required
title="Range"
name="range"
x-component-props={{
min: 0,
max: 1024,
marks: [0, 1024]
}}
/>
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
upload
- Schema Type :
upload
- Schema UI Component: Fusion-Next
<Upload/>
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions}>
<Field
type="upload"
required
title="Card Upload"
name="upload2"
x-component-props={{
listType: 'card'
}}
/>
<Field
type="upload"
required
title="Dragger Upload"
name="upload1"
x-component-props={{
listType: 'dragger'
}}
/>
<Field
type="upload"
required
title="Text Upload"
name="upload3"
x-component-props={{
listType: 'text'
}}
/>
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
checkbox
- Schema Type :
checkbox
- Schema UI Component: Fusion-Next
<Checkbox/>
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions}>
<Field
type="checkbox"
required
title="Simple Checkbox"
name="checkbox"
enum={['1', '2', '3', '4']}
/>
<Field
type="checkbox"
required
title="Object Checkbox"
name="checkbox2"
enum={[
{ label: 'One', value: '1' },
{ label: 'Two', value: '2' },
{ label: 'Three', value: '3' },
{ label: 'Four', value: '4' }
]}
/>
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
radio
- Schema Type :
radio
- Schema UI Component: Fusion-Next
<Radio/>
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions}>
<Field
type="radio"
required
title="Simple Radio"
name="radio"
enum={['1', '2', '3', '4']}
/>
<Field
type="radio"
required
title="Object Radio"
name="radio2"
enum={[
{ label: 'One', value: '1' },
{ label: 'Two', value: '2' },
{ label: 'Three', value: '3' },
{ label: 'Four', value: '4' }
]}
/>
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
rating
- Schema Type :
rating
- Schema UI Component: Fusion-Next
<Rating/>
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions}>
<Field
type="rating"
title="Rating"
name="rating"
x-component-props={{
allowHalf: true
}}
/>
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
transfer
- Schema Type :
transfer
- Schema UI Component: Fusion-Next
<Transfer/>
Usage
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/antd'
import'antd/dist/antd.css'
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions}>
<Field
type="transfer"
title="Transfer"
name="transfer"
enum={[
{ title: 'One', key: '1' },
{ title: 'Two', key: '2' },
{ title: 'Three', key: '3' },
{ title: 'Four', key: '4' }
]}
x-props={{
render: (item) => item.title
}}
x-component-props={{
showSearch: true
}}
/>
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
Hook
useFormEffects
Implement local effects by using useFormEffects. Same effect as the example of Linkage
Note: The life cycle of the listener starts from ON_FORM_MOUNT
Signature
(effects: IFormEffect): void
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
VirtualField,
createFormActions,
useFormEffects,
LifeCycleTypes,
createVirtualBox
} from '@uform/antd'
const actions = createFormActions()
const FragmentContainer = createVirtualBox('ffb', (props) => {
useFormEffects(($, { setFieldState }) => {
$(LifeCycleTypes.ON_FORM_MOUNT).subscribe(() => {
setFieldState('a~', state => state.visible = false)
})
$(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe((triggerState) => {
setFieldState('a~', state => {
state.visible = triggerState.value
})
})
$(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe((fieldState) => {
setFieldState('a-copy', state => {
state.value = fieldState.value
})
})
})
return (
<React.Fragment>
{props.children}
</React.Fragment>
)
});
const FormFragment = () => {
return <FragmentContainer>
<Field
type="radio"
name="trigger"
title="trigger"
enum={[{ label: 'show', value: true }, { label: 'hide', value: false } ]}
/>
<Field type="string" name="a" title="a" />
<Field type="string" name="a-copy" title="a-copy" />
</FragmentContainer>
}
const App = () => {
return (
<SchemaForm actions={actions}>
<FormFragment />
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
useFormState
使用 useFormState 为自定义组件提供FormState扩展和管理能力
签名
(defaultState: T): [state: IFormState, setFormState: (state?: IFormState) => void]
用法
import React, { useRef } from 'react'
import ReactDOM from 'react-dom'
import { Form, Field, VirtualField,
createFormActions, createEffectHook,
useForm,
useFormState,
useFormEffects,
useFieldState,
LifeCycleTypes
} from '@uform/react'
const InputField = props => (
<Field {...props}>
{({ state, mutators }) => {
const loading = state.props.loading
return <React.Fragment>
{ props.label && <label>{props.label}</label> }
{ loading ? ' loading... ' : <input
disabled={!state.editable}
value={state.value || ''}
onChange={mutators.change}
onBlur={mutators.blur}
onFocus={mutators.focus}
/> }
<span style={{ color: 'red' }}>{state.errors}</span>
<span style={{ color: 'orange' }}>{state.warnings}</span>
</React.Fragment>
}}
</Field>
)
const actions = createFormActions()
const FormFragment = (props) => {
const [formState, setFormState ] = useFormState({ extendVar: 0 })
const { extendVar } = formState
return <div>
<button onClick={() => {
setFormState({ extendVar: extendVar + 1 })
}}>add</button>
<div>count: {extendVar}</div>
</div>
}
const App = () => {
return (
<Form actions={actions}>
<FormFragment />
</Form>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
useFieldState
Manage state of custom field by using useFieldState
Signature
(defaultState: T): [state: IFieldState, setFieldState: (state?: IFieldState) => void]
import React, { useRef } from 'react'
import ReactDOM from 'react-dom'
import { Form, Field, VirtualField,
createFormActions, createEffectHook,
useForm,
useFormEffects,
useFieldState,
LifeCycleTypes
} from '@uform/react'
const InputField = props => (
<Field {...props}>
{({ state, mutators }) => {
const loading = state.props.loading
return <React.Fragment>
{ props.label && <label>{props.label}</label> }
{ loading ? ' loading... ' : <input
disabled={!state.editable}
value={state.value || ''}
onChange={mutators.change}
onBlur={mutators.blur}
onFocus={mutators.focus}
/> }
<span style={{ color: 'red' }}>{state.errors}</span>
<span style={{ color: 'orange' }}>{state.warnings}</span>
</React.Fragment>
}}
</Field>
)
const changeTab$ = createEffectHook('changeTab')
const actions = createFormActions()
const TabFragment = (props) => {
const [fieldState, setLocalFieldState ] = useFieldState({ current: 0 })
const { current } = fieldState
const { children, dataSource, form } = props
const ref = useRef(current)
const update = (cur) => {
form.notify('changeTab', cur)
setLocalFieldState({
current: cur
})
}
useFormEffects(($, { setFieldState }) => {
dataSource.forEach((item, itemIdx) => {
setFieldState(item.name, state => {
state.display = itemIdx === current
})
})
changeTab$().subscribe((idx) => {
dataSource.forEach((item, itemIdx) => {
setFieldState(item.name, state => {
state.display = itemIdx === idx
})
})
})
})
ref.current = current
const btns = dataSource.map((item, idx) => {
console.log('current', current, ref.current)
const focusStyle = idx === current ? { color: '#fff', background: 'blue' } : {}
return <button style={focusStyle} onClick={() => {
update(idx)
}}>{item.label}</button>
})
return btns
}
const FormTab = (props) => {
return <VirtualField name="layout_tab">
{({ form }) => {
return <TabFragment {...props} form={form} />
}}
</VirtualField>
}
const App = () => {
return (
<Form actions={actions}>
<FormTab dataSource={[
{ label: 'tab-1', name: 'username' },
{ label: 'tab-2', name: 'age' }
]} />
<div>
<InputField name="username" label="username"/>
<InputField name="age" label="age"/>
</div>
</Form>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
useForm
get IForm instance
Signature
type useForm = <
Value = any,
DefaultValue = any,
EffectPayload = any,
EffectAction = any
>(
props: IFormProps<Value, DefaultValue, EffectPayload, EffectAction>
) => IForm
Usage
import { useForm } from '@uform/react'
const FormFragment = () => {
const form = useForm()
return <div>{form.getFieldValue('username')}</div>
}
useField
get IFieldHook instance
Signature
type useField = (options: IFieldStateUIProps): IFieldHook
Usage
import { useField } from '@uform/react'
const FormFragment = (props) => {
const {
form,
state,
props: fieldProps,
mutators
} = useField({ name: 'username' })
return <input {...fieldProps} {...props} value={state.value} onChange={mutators.change} />
}
useVirtualField
get IVirtualFieldHook instance
Signature
type UseVirtualField = (options: IVirtualFieldStateProps): IVirtualFieldHook
Usage
import { UseVirtualField } from '@uform/react'
const FormFragment = (props) => {
const {
form,
state,
props: fieldProps,
} = UseVirtualField({ name: 'username' })
return <div style={{ width: fieldProps.width, height: fieldProps.height }}>
{props.children}
</div>
}
useFormSpy
get ISpyHook instance. Same effect as the first example of FormSpy.
Signature
type useFormSpy = (props: IFormSpyProps): ISpyHook
Usage
import { useFormSpy, LifeCycleTypes } from '@uform/react'
const FormFragment = (props) => {
const {
form,
state,
type,
} = useFormSpy({
selector: LifeCycleTypes.ON_FORM_VALUES_CHANGE,
reducer: (state, action, form) => ({
count: state.count ? state.count + 1 : 1
})
})
return <div>
<div>count: {state.count || 0}</div>
</div>
}
API
Fully inherited from @uform/react, The specific API of @uform/antd is listed below.
createFormActions
Return IFormActions
Signature
createFormActions(): IFormActions
Usage
import { createFormActions } from '@uform/antd'
const actions = createFormActions()
console.log(actions.getFieldValue('username'))
createAsyncFormActions
Return IFormAsyncActions
Signature
createAsyncFormActions(): IFormAsyncActions
Usage
import { createAsyncFormActions } from '@uform/antd'
const actions = createAsyncFormActions()
actions.getFieldValue('username').then(val => console.log(val))
FormEffectHooks
Return all @uform/core lifeCycles hook which can be subscribe
Usage
import { FormEffectHooks, Form } from '@uform/react'
const {
onFormWillInit$,
onFormInit$,
onFormChange$,
onFormInputChange$,
onFormInitialValueChange$,
onFormReset$,
onFormSubmit$,
onFormSubmitStart$,
onFormSubmitEnd$,
onFormMount$,
onFormUnmount$,
onFormValidateStart$,
onFormValidateEnd$,
onFormValuesChange$,
onFormGraphChange$,
onFieldWillInit$,
onFieldInit$,
onFieldChange$,
onFieldMount$,
onFieldUnmount$,
onFieldInputChange$,
onFieldValueChange$,
onFieldInitialValueChange$
} = FormEffectHooks
const App = () => {
return (
<Form
effects={() => {
onFormInit$().subscribe(() => {
console.log('initialized')
})
}}
>
...
</Form>
)
}
createEffectHook
Custom your own hook by this api
Usage
import SchemaForm, { createEffectHook, createFormActions } from '@uform/antd'
const actions = createFormActions()
const diyHook1$ = createEffectHook('diy1')
const diyHook2$ = createEffectHook('diy2')
const App = () => {
return (
<SchemaForm
actions={actions}
effects={() => {
diyHook1$().subscribe(payload => {
console.log('diy1 hook triggered', payload)
})
diyHook2$().subscribe(payload => {
console.log('diy2 hook triggered', payload)
})
}}
>
<button
onClick={() => {
actions.notify('diy1', { index: 1 })
}}
>
notify diy1
</button>
<button
onClick={() => {
actions.notify('diy2', { index: 2 })
}}
>
notify diy2
</button>
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
connect
Wrap field components with value / defaultValue / onChange of field, which make it esaily make custom field
type Connect = <T extends React.ComponentType<IFieldProps>>(options?: IConnectOptions<T>) =>
(Target: T) => React.PureComponent<IFieldProps>
Usage
import {registerFormField,connect} from '@uform/antd'
registerFormField(
'string',
connect()(props => <input {...props} value={props.value || ''} />)
)
registerFormField
type registerFormField(
name : string,
component : React.ComponentType<IFieldProps>,
noMiddleware: boolean
)
Usage
import SchemaForm, { SchemaMarkupField as Field, registerFormField, connect, createFormActions } from '@uform/antd'
registerFormField(
'custom-string',
connect()(props => <input {...props} value={props.value || ''} />)
)
const actions = createFormActions()
const App = () => {
return (
<SchemaForm actions={actions} >
<Field type="custom-string" name="custom-string" title="Custom Field" />
</SchemaForm>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
Interfaces
The Interfaces is fully inherited from @uform/react. The specific Interfaces of @uform/antd is listed below.
ISchema
Schema protocol object, mainly used to constrain a json structure to satisfy the Schema protocol
interface ISchema {
title?: React.ReactNode
description?: React.ReactNode
default?: any
readOnly?: boolean
writeOnly?: boolean
type?: 'string' | 'object' | 'array' | 'number' | string
enum?: Array<string | number | { label: React.ReactNode; value: any }>
const?: any
multipleOf?: number
maximum?: number
exclusiveMaximum?: number
minimum?: number
exclusiveMinimum?: number
maxLength?: number
minLength?: number
pattern?: string | RegExp
maxItems?: number
minItems?: number
uniqueItems?: boolean
maxProperties?: number
minProperties?: number
required?: string[] | boolean
format?: string
properties?: {
[key: string]: ISchema
}
items?: ISchema | ISchema[]
additionalItems?: ISchema
patternProperties?: {
[key: string]: ISchema
}
additionalProperties?: ISchema
visible?: boolean
display?: boolean
editable?: boolean
['x-props']?: { [name: string]: any }
['x-index']?: number
['x-rules']?: ValidatePatternRules
['x-component']?: string
['x-component-props']?: { [name: string]: any }
['x-render']?: <T = ISchemaFieldComponentProps>(
props: T & {
renderComponent: () => React.ReactElement
}
) => React.ReactElement
['x-effect']?: (
dispatch: (type: string, payload: any) => void,
option?: object
) => { [key: string]: any }
}
IFormActions
interface IFormActions {
submit(
onSubmit?: (values: IFormState['values']) => any | Promise<any>
): Promise<{
Validated: IFormValidateResult
Payload: any
}>
getFormSchema(): Schema
clearErrors: (pattern?: FormPathPattern) => void
hasChanged(
target: IFormState | IFieldState | IVirtualFieldState,
path: FormPathPattern
): boolean
reset(options?: {
forceClear?: boolean
validate?: boolean
selector?: FormPathPattern
clearInitialValue?:boolean
}): Promise<void | IFormValidateResult>
validate(
path?: FormPathPattern,
options?: {
first?: boolean
}
): Promise<IFormValidateResult>
setFormState(
callback?: (state: IFormState) => any,
silent?: boolean
): void
getFormState(
callback?: (state: IFormState) => any
): any
setFieldState(
path: FormPathPattern,
callback?: (state: IFieldState) => void,
silent?: boolean
): void
getFieldState(
path: FormPathPattern,
callback?: (state: IFieldState) => any
): any
getFormGraph(): IFormGraph
setFormGraph(graph: IFormGraph): void
subscribe(
callback?: ({ type, payload }: { type: string; payload: any }) => void
): number
unsubscribe(id: number): void
notify: <T>(type: string, payload?: T) => void
setFieldValue(path?: FormPathPattern, value?: any): void
getFieldValue(path?: FormPathPattern): any
setFieldInitialValue(path?: FormPathPattern, value?: any): void
getFieldInitialValue(path?: FormPathPattern): any
}
IFormAsyncActions
interface IFormAsyncActions {
submit(
onSubmit?: (values: IFormState['values']) => void | Promise<any>
): Promise<IFormSubmitResult>
getFormSchema(): Promise<Schema>
reset(options?: {
forceClear?: boolean
validate?: boolean
selector?: FormPathPattern
clearInitialValue?:boolean
}): Promise<void>
hasChanged(target: any, path: FormPathPattern): Promise<boolean>
clearErrors: (pattern?: FormPathPattern) => Promise<void>
validate(
path?: FormPathPattern,
options?: {
first?: boolean
}
): Promise<IFormValidateResult>
setFormState(
callback?: (state: IFormState) => any,
silent?: boolean
): Promise<void>
getFormState(
callback?: (state: IFormState) => any
): Promise<any>
setFieldState(
path: FormPathPattern,
callback?: (state: IFieldState) => void,
silent?: boolean
): Promise<void>
getFieldState(
path: FormPathPattern,
callback?: (state: IFieldState) => any
): Promise<void>
getFormGraph(): Promise<IFormGraph>
setFormGraph(graph: IFormGraph): Promise<void>
subscribe(callback?: FormHeartSubscriber): Promise<number>
unsubscribe(id: number): Promise<void>
notify: <T>(type: string, payload: T) => Promise<void>
dispatch: <T>(type: string, payload: T) => void
setFieldValue(path?: FormPathPattern, value?: any): Promise<void>
getFieldValue(path?: FormPathPattern): Promise<any>
setFieldInitialValue(path?: FormPathPattern, value?: any): Promise<void>
getFieldInitialValue(path?: FormPathPattern): Promise<any>
}
ButtonProps
interface ButtonProps {
href: string;
target?: string;
onClick?: React.MouseEventHandler<HTMLElement>;
htmlType?: ButtonHTMLType;
onClick?: React.MouseEventHandler<HTMLElement>;
}
CardProps
interface CardProps extends HTMLAttributesWeak, CommonProps {
prefixCls?: string;
title?: React.ReactNode;
extra?: React.ReactNode;
bordered?: boolean;
headStyle?: React.CSSProperties;
bodyStyle?: React.CSSProperties;
style?: React.CSSProperties;
loading?: boolean;
noHovering?: boolean;
hoverable?: boolean;
children?: React.ReactNode;
id?: string;
className?: string;
size?: CardSize;
type?: CardType;
cover?: React.ReactNode;
actions?: React.ReactNode[];
tabList?: CardTabListType[];
tabBarExtraContent?: React.ReactNode | null;
onTabChange?: (key: string) => void;
activeTabKey?: string;
defaultActiveTabKey?: string;
}
ICompatItemProps
interface ICompatItemProps
extends Exclude<ItemProps, 'labelCol' | 'wrapperCol'>,
Partial<ISchemaFieldComponentProps> {
labelCol?: number | { span: number; offset?: number }
wrapperCol?: number | { span: number; offset?: number }
}
IFieldState
interface IFieldState<FieldProps = any> {
displayName?: string
name: string
path: string
initialized: boolean
pristine: boolean
valid: boolean
invalid: boolean
validating: boolean
modified: boolean
touched: boolean
active: boolean
visited: boolean
visible: boolean
display: boolean
editable: boolean
loading: boolean
values: any[]
errors: string[]
warnings: string[]
value: any
initialValue: any
rules: ValidatePatternRules[]
required: boolean
mounted: boolean
unmounted: boolean
props: FieldProps
}
ISchemaFieldComponentProps
interface ISchemaFieldComponentProps extends IFieldState {
schema: Schema
mutators: IMutators
form: IForm
renderField: (
addtionKey: string | number,
reactKey?: string | number
) => React.ReactElement
}
ISchemaVirtualFieldComponentProps
interface ISchemaVirtualFieldComponentProps extends IVirtualFieldState {
schema: Schema
form: IForm
children: React.ReactElement[]
renderField: (
addtionKey: string | number,
reactKey?: string | number
) => React.ReactElement
}
ISchemaFieldWrapper
interface ISchemaFieldWrapper<Props = any> {
(Traget: ISchemaFieldComponent):
| React.FC<Props>
| React.ClassicComponent<Props>
}
ISchemaFieldComponent
declare type ISchemaFieldComponent = ComponentWithStyleComponent<
ISchemaFieldComponentProps
> & {
__WRAPPERS__?: ISchemaFieldWrapper[]
}
ISchemaVirtualFieldComponent
declare type ISchemaVirtualFieldComponent = ComponentWithStyleComponent<
ISchemaVirtualFieldComponentProps
> & {
__WRAPPERS__?: ISchemaFieldWrapper[]
}
ISchemaFormRegistry
interface ISchemaFormRegistry {
fields: {
[key: string]: ISchemaFieldComponent
}
virtualFields: {
[key: string]: ISchemaVirtualFieldComponent
}
wrappers?: ISchemaFieldWrapper[]
formItemComponent: React.JSXElementConstructor<any>
formComponent: string | React.JSXElementConstructor<any>
}
InternalFormats
type InternalFormats =
| 'url'
| 'email'
| 'ipv6'
| 'ipv4'
| 'idcard'
| 'taodomain'
| 'qq'
| 'phone'
| 'money'
| 'zh'
| 'date'
| 'zip'
| string
CustomValidator
declare type CustomValidator = (
value: any,
rescription?: ValidateDescription
) => ValidateResponse
ValidateDescription
interface ValidateDescription {
format?: InternalFormats
validator?: CustomValidator
required?: boolean
pattern?: RegExp | string
max?: number
maximum?: number
exclusiveMaximum?: number
exclusiveMinimum?: number
minimum?: number
min?: number
len?: number
whitespace?: boolean
enum?: any[]
message?: string
[key: string]: any
}
ValidateArrayRules
declare type ValidateArrayRules = Array<
InternalFormats | CustomValidator | ValidateDescription
>
ValidatePatternRules
declare type ValidatePatternRules =
| InternalFormats
| CustomValidator
| ValidateDescription
| ValidateArrayRules
INextSchemaFieldProps
interface INextSchemaFieldProps {
name?: string;
title?: SchemaMessage;
description?: SchemaMessage;
default?: any;
readOnly?: boolean;
writeOnly?: boolean;
type?: 'string' | 'object' | 'array' | 'number' | string;
enum?: Array<string | number | {
label: SchemaMessage;
value: any;
}>;
const?: any;
multipleOf?: number;
maximum?: number;
exclusiveMaximum?: number;
minimum?: number;
exclusiveMinimum?: number;
maxLength?: number;
minLength?: number;
pattern?: string | RegExp;
maxItems?: number;
minItems?: number;
uniqueItems?: boolean;
maxProperties?: number;
minProperties?: number;
required?: string[] | boolean;
format?: string;
properties?: {
[key: string]: ISchema;
};
items?: ISchema | ISchema[];
additionalItems?: ISchema;
patternProperties?: {
[key: string]: ISchema;
};
additionalProperties?: ISchema;
editable?: boolean;
visible?: boolean;
display?: boolean;
['x-props']?: {
[name: string]: any;
};
['x-index']?: number;
['x-rules']?: ValidatePatternRules;
['x-component']?: string;
['x-component-props']?: {
[name: string]: any;
};
['x-render']?: <T = ISchemaFieldComponentProps>(props: T & {
renderComponent: () => React.ReactElement;
}) => React.ReactElement;
['x-effect']?: (dispatch: (type: string, payload: any) => void, option?: object) => {
[key: string]: any;
};
IPreviewTextProps
interface IPreviewTextProps {
className?: React.ReactText
dataSource?: any[]
value?: any
addonBefore?: React.ReactNode
innerBefore?: React.ReactNode
addonTextBefore?: React.ReactNode
addonTextAfter?: React.ReactNode
innerAfter?: React.ReactNode
addonAfter?: React.ReactNode
}
IMutators
The instance API created by crewikiutators is mainly used to operate field data.
interface IMutators {
change(...values: any[]): any
focus(): void
blur(): void
validate(): Promise<IFormValidateResult>
exist(index?: number | string): Boolean
push(value?: any): any[]
pop(): any[]
insert(index: number, value: any): any[]
remove(index: number | string): any
unshift(value: any): any[]
shift(): any[]
move($from: number, $to: number): any[]
moveDown(index: number): any[]
moveUp(index: number): any[]
}
IFieldProps
interface IFieldProps<V = any> {
name : string
path : Array<string>
value : V
errors : Array<string>
editable : boolean | ((name:string) => boolean)
locale : Locale
loading : boolean
schemaPath : Array<string>
getSchema : (path: string) => ISchema
renderField : (childKey: string, reactKey: string | number) => JSX.Element | string | null
renderComponent : React.FunctionComponent<Partial<IFieldProps> | undefined>,
getOrderProperties : () => Array<{schema: ISchema, key: number, path: string, name: string }>,
mutators : IMutators,
schema : ISchema
}
IConnectOptions
interface IConnectOptions<T> {
valueName?: string
eventName?: string
defaultProps?: Partial<IConnectProps>
getValueFromEvent?: (props: IFieldProps['x-props'], event: Event, ...args: any[]) => any
getProps?: (connectProps: IConnectProps, fieldProps: IFieldProps) => IConnectProps
getComponent?: (
target: T,
connectProps: IConnectProps,
fieldProps: IFieldProps
) => T
}
ISpyHook
interface ISpyHook {
form: IForm
state: any
type: string
}