### Install
npm install @uform/next``bash`
npm install --save @uform/next
- Quick-Start
- Components
-
-
-
-
-
-
- Form List
- array
- cards
- table
- Layout Components
-
-
-
-
-
-
-
-
-
- Type of SchemaMarkupField
- string
- textarea
- password
- number
- boolean
- date
- time
- range
- upload
- checkbox
- radio
- rating
- transfer
- Hook
- useFormEffects
- useFormState
- useFieldState
- useForm
- useField
- useVirtualField
- useFormSpy
- API
- createFormActions
- createAsyncFormActions
- FormEffectHooks
- createEffectHook
- connect
- registerFormField
- Interfaces
- ISchema
- IFormActions
- IFormAsyncActions
- ButtonProps
- CardProps
- ICompatItemProps
- IFieldState
- ISchemaFieldComponentProps
- ISchemaVirtualFieldComponentProps
- ISchemaFieldWrapper
- ISchemaFieldComponent
- ISchemaVirtualFieldComponent
- ISchemaFormRegistry
- InternalFormats
- CustomValidator
- ValidateDescription
- ValidateArrayRules
- ValidatePatternRules
- INextSchemaFieldProps
- IPreviewTextProps
- IMutators
- IFieldProps
- IConnectOptions
- ISpyHook
---
Example:develop with JSX
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import { Button } from '@alifd/next'
import '@alifd/next/dist/next.css'
const actions = createFormActions()
const App = () => {
return (
enum={['1', '2', '3', '4']}
title="Radio"
name="radio"
/>
enum={['1', '2', '3', '4']}
required
title="Select"
name="select"
/>
enum={['1', '2', '3', '4']}
required
title="Checkbox"
name="checkbox"
/>
title="TextArea"
name="textarea"
x-component="textarea"
/>
title="daterange"
default={['2018-12-19', '2018-12-19']}
name="daterange"
/>
title="upload(card)"
name="upload"
x-props={{ listType: 'card' }}
/>
title="upload(dragge)"
name="upload2"
x-props={{ listType: 'dragger' }}
/>
title="upload(text)"
name="upload3"
x-props={{ listType: 'text' }}
/>
title="range"
name="range"
x-props={{ min: 0, max: 1024, marks: [0, 1024] }}
/>
enum={[{ value: 1, label: 'opt1' }, { value: 2, label: 'opt2' }]}
title="transfer"
name="transfer"
/>
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
onClick={() => {
actions.setFormState(state => {
state.values = {
radio: '4',
checkbox: ['2', '3']
}
})
}}
>
Set Value
)
}
ReactDOM.render(
`
Example:develop with JSON Schema
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import { Button } from '@alifd/next'
import '@alifd/next/dist/next.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: [
{
value: 1,
label: 'opt1'
},
{
value: 2,
label: 'opt2'
}
],
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
}
ReactDOM.render(
`
---
####
Base on of @uform/react-schema-renderer. Recommended for production environments.
`typescripthtmlType="submit"
interface INextSchemaFormProps {
// render by schema
schema?: ISchema;
fields?: ISchemaFormRegistry['fields'];
virtualFields?: ISchemaFormRegistry['virtualFields'];
// pre-registered Form Component
formComponent?: ISchemaFormRegistry['formComponent'];
// pre-registered FormItem Component
formItemComponent?: ISchemaFormRegistry['formItemComponent'];
// label column settiing
labelCol?: number | { span: number; offset?: number }
// FormItem column settiing
wrapperCol?: number | { span: number; offset?: number }
// custom placeholder when preivew
previewPlaceholder?: string | ((props: IPreviewTextProps) => string);
// prefix
prefix?: string;
// is it inline
inline?: boolean;
// The size of a single Item is customized, and takes precedence over the size of the Form, and when a component is used with an Item, the component itself does not set the size property.
size?: 'large' | 'medium' | 'small';
// position of label
labelAlign?: 'top' | 'left' | 'inset';
// aligment of label
labelTextAlign?: 'left' | 'right';
// labelCol of FormItem
labelCol?: {};
// wrapperCol of FormItem
wrapperCol?: {};
children?: any;
className?: string;
style?: React.CSSProperties;
// type of component
component?: string | (() => void);
// form state value
value?: Value;
// form state defaultValue
defaultValue?: DefaultValue;
// form state initialValues
initialValues?: DefaultValue;
// FormActions instance
actions?: FormActions;
// IFormEffect instance
effects?: IFormEffect
// form instance
form?: IForm;
// Form change event callback
onChange?: (values: Value) => void;
// triggered by or actions.submit时`
onSubmit?: (values: Value) => void | Promise
// triggered by
onReset?: () => void;
// Form verification failure event callback
onValidateFailed?: (valideted: IFormValidateResult) => void;
children?: React.ReactElement | ((form: IForm) => React.ReactElement);
// Whether to use the dirty check, the default will go immer accurate update
useDirty?: boolean;
// Is it editable, overall control in the Form dimension
editable?: boolean | ((name: string) => boolean);
// Whether to go pessimistic check, stop the subsequent check when the first check fails
validateFirst?: boolean;
}
Usage
Example1: Sync value of a and a-mirror
`jsx
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
registerFormField,
Field,
connect,
createFormActions
} from '@uform/next'
const actions = createFormActions()
ReactDOM.render(
$('onFieldChange','a').subscribe((fieldState)=>{
actions.setFieldState('a-mirror',state=>{
state.value = fieldState.value
})
})
}}>
document.getElementById('root')
)
`
Example:Layout
`jsx
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
Field,
createFormActions,
FormLayout,
FormButtonGroup,
Submit,
Reset,
} from '@uform/next'
const actions = createFormActions()
ReactDOM.render(
####
> Core components of @uform/next, used to describe form fields
`typescript
interface IMarkupSchemaFieldProps {
name?: string
/ base json schema spec/
title?: SchemaMessage
description?: SchemaMessage
default?: any
readOnly?: boolean
writeOnly?: boolean
type?: 'string' | 'object' | 'array' | 'number' | string
enum?: Array
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
/ nested json schema spec /
properties?: {
[key: string]: ISchema
}
items?: ISchema | ISchema[]
additionalItems?: ISchema
patternProperties?: {
[key: string]: ISchema
}
additionalProperties?: ISchema
/* extend json schema specs /
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']?: (
props: T & {
renderComponent: () => React.ReactElement
}
) => React.ReactElement
['x-effect']?: (
dispatch: (type: string, payload: any) => void,
option?: object
) => { [key: string]: any }
}
`##### Usage
`jsx
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
FormSlot,
Field,
createFormActions,
FormLayout,
FormButtonGroup,
Submit,
Reset,
} from '@uform/next'const actions = createFormActions()
ReactDOM.render(
required
description
default value
readOnly
visible = false
display = false
editable = false
,
document.getElementById('root')
)
`
####
> Props of
`typescript
interface ISubmitProps {
/ reset pops /
onSubmit?: ISchemaFormProps['onSubmit']
showLoading?: boolean
/ nextBtnProps /
// type of btn
type?: 'primary' | 'secondary' | 'normal'
// size of btn
size?: 'small' | 'medium' | 'large'
// size of Icon
iconSize?: 'xxs' | 'xs' | 'small' | 'medium' | 'large' | 'xl' | 'xxl' | 'xxxl'
// type of button when component = 'button'
htmlType?: 'submit' | 'reset' | 'button'
// typeof btn
component?: 'button' | 'a'
// Set the loading state of the button
loading?: boolean
// Whether it is a ghost button
ghost?: true | false | 'light' | 'dark'
// Whether it is a text button
text?: boolean
// Whether it is a warning button
warning?: boolean
// Whether it is disabled
disabled?: boolean
// Callback for button click
onClick?: (e: {}) => void
// Valid when Button component is set to 'a', which represents the URL of the linked page
href?: string
// Valid when Button component is set to 'a', which represents the way of open the linked document
target?: string
}
`####
> Props of
`typescript
interface IResetProps {
/ reset pops /
forceClear?: boolean
validate?: boolean
/ nextBtnProps /
// type of btn
type?: 'primary' | 'secondary' | 'normal'
// size of btn
size?: 'small' | 'medium' | 'large'
// size of Icon
iconSize?: 'xxs' | 'xs' | 'small' | 'medium' | 'large' | 'xl' | 'xxl' | 'xxxl'
// type of button when component = 'button'
htmlType?: 'submit' | 'reset' | 'button'
// typeof btn
component?: 'button' | 'a'
// Set the loading state of the button
loading?: boolean
// Whether it is a ghost button
ghost?: true | false | 'light' | 'dark'
// Whether it is a text button
text?: boolean
// Whether it is a warning button
warning?: boolean
// Whether it is disabled
disabled?: boolean
// Callback for button click
onClick?: (e: {}) => void
// Valid when Button component is set to 'a', which represents the URL of the linked page
href?: string
// Valid when Button component is set to 'a', which represents the way of open the linked document
target?: string
}
`####
>
Props`typescript
interface IFormSpyProps {
// selector, eg: [ LifeCycleTypes.ON_FORM_SUBMIT_START, LifeCycleTypes.ON_FORM_SUBMIT_END ]
selector?: string[] | string
// reducer
reducer?: (
state: any,
action: { type: string; payload: any },
form: IForm
) => any
children?: React.ReactElement | ((api: IFormSpyAPI) => React.ReactElement)
}
`####
> deprecated,please use SchemaMarkupField
Usage
Example1: Form state change counter
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import { Form, Field, createFormActions, FormSpy, LifeCycleTypes } from '@uform/react'const actions = createFormActions()
const InputField = props => (
{({ state, mutators }) => (
disabled={!state.editable}
value={state.value || ''}
onChange={mutators.change}
onBlur={mutators.blur}
onFocus={mutators.focus}
/>
{state.errors}
{state.warnings}
)}
)
const App = () => {
return (
ReactDOM.render(
`
Example2:Combo
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import { Form, Field, createFormActions, FormSpy } from '@uform/react'
const actions = createFormActions()
const InputField = props => (
{({ state, mutators }) => (
disabled={!state.editable}
value={state.value || ''}
onChange={mutators.change}
onBlur={mutators.blur}
onFocus={mutators.focus}
/>
{state.errors}
{state.warnings}
)}
)
const App = () => {
return (
ReactDOM.render(
`
#### array
`jsx
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
Field,
FormItemGrid,
FormButtonGroup,
Submit,
Reset,
FormBlock,
FormLayout
} from '@uform/next'
import '@alifd/next/dist/next.css'
import Printer from '@uform/printer'
const App = () => {
const [value, setValues] = useState({})
useEffect(() => {
setTimeout(() => {
setValues({
array: [{ array2: [{ aa: '123', bb: '321' }] }]
})
}, 1000)
}, [])
return (
name="array"
maxItems={3}
type="array"
x-props={{
renderAddition: 'Add Text',
renderRemove: 'Remove Text'
}}
>
)
}
ReactDOM.render(
`
#### cards
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
Field,
FormItemGrid,
FormButtonGroup,
Submit,
Reset,
FormBlock,
FormLayout
} from '@uform/next'
import '@alifd/next/dist/next.css'
import Printer from '@uform/printer'
const App = () => (
maxItems={3}
type="array"
x-component="cards"
x-props={{
title: 'Title of cards',
renderAddition: 'Add Text',
renderRemove: 'Remove Text'
}}
>
type="string"
description="hello world"
title="field1"
/>
maxItems={3}
type="array"
x-component="cards"
x-props={{ title: 'Title of cards' }}
>
type="string"
description="hello world"
title="field1"
/>
)
ReactDOM.render(
`
#### table
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
Field,
FormItemGrid,
FormButtonGroup,
Submit,
Reset,
FormBlock,
FormLayout
} from '@uform/next'
import '@alifd/next/dist/next.css'
import Printer from '@uform/printer'
const App = () => (
name="array"
maxItems={3}
type="array"
x-component="table"
x-props={{
renderExtraOperations() {
return Hello worldasdasdasdasd
},
operationsWidth: 300
}}
>
type="string"
description="hello world"
title="field1"
/>
)
ReactDOM.render(
`
####
> Props of , fully inherited from CardProps。
> The only difference between FormCard FormBlock is a border on the style
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, { FormCard, SchemaMarkupField as Field } from '@uform/next'
import '@alifd/next/dist/next.css'
const App = () => (
)
ReactDOM.render(
`
####
> Props of , fully inherited from CardProps
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, { FormBlock, SchemaMarkupField as Field } from '@uform/next'
import '@alifd/next/dist/next.css'
const App = () => (
)
ReactDOM.render(
`
####
> Props of
`typescript`
interface IFormStep {
dataSource: StepItemProps[]
/ next step props/
// current
current?: number
// direction of step
direction?: 'hoz' | 'ver'
// Content arrangement in horizontal layout
labelPlacement?: 'hoz' | 'ver'
// shape of step
shape?: 'circle' | 'arrow' | 'dot'
readOnly?: boolean
// Whether to activate animation
animation?: boolean
className?: string
// Custom StepItem render
itemRender?: (index: number, status: string) => React.ReactNode
}
Usage
`jsx
import {
SchemaForm,
Field,
FormButtonGroup,
Submit,
FormEffectHooks,
createFormActions,
FormGridRow,
FormItemGrid,
FormGridCol,
FormPath,
FormLayout,
FormBlock,
FormCard,
FormTextBox,
FormStep
} from '@uform/next'
import { Button } from '@alifd/next'
import '@alifd/next/dist/next.css'
const { onFormInit$ } = FormEffectHooks
const actions = createFormActions()
let cache = {}
export default () => (
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
})
})
}}
>
dataSource={[
{ title: 'Step1', name: 'step-1' },
{ title: 'Step2', name: 'step-2' },
{ title: 'Step3', name: 'step-3' }
]}
/>
onClick={() => {
cache = actions.getFormGraph()
}}
>
Save State
onClick={() => {
actions.setFormGraph(cache)
}}
>
Rollback State
)
`
####
> Props of
`typescript`
interface IFormItemTopProps {
inline?: boolean
className?: string
style?: React.CSSProperties
labelCol?: number | { span: number; offset?: number }
wrapperCol?: number | { span: number; offset?: number }
}
Usage
`jsx`
import React from 'react'
import ReactDOM from 'react-dom'
import {
SchemaForm,
Field,
FormButtonGroup,
Submit,
Reset,
FormItemGrid,
FormCard,
FormBlock,
FormLayout
} from '@uform/next'
import { Button } from '@alifd/next'
import Printer from '@uform/printer'
import '@alifd/next/dist/next.css'
const App = () => (
)
ReactDOM.render(
####
> Props of
`typescript
interface IFormItemGridProps {
cols?: Array
gutter?: number
/ next Form.Item props/
// prefix od FormItem
prefix?: string
// label od FormItem
label?: React.ReactNode
// label layout setting, eg, {span: 8, offset: 16}
labelCol?: {}
wrapperCol?: {}
// Custom prompt information, if not set, it will be automatically generated according to the verification rules.
help?: React.ReactNode
// Additional prompt information, similar to help, can be used when error messages and prompt copy are required at the same time. Behind the error message.
extra?: React.ReactNode
// Check status, if not set, it will be generated automatically according to check rules
validateState?: 'error' | 'success' | 'loading'
// Used in conjunction with the validateState property, whether to display the success / loading validation status icon. Currently only Input supports
hasFeedback?: boolean
// Custom inline style
style?: React.CSSProperties
// node or function(values)
children?: React.ReactNode | (() => void)
// The size of a single Item is customized, and takes precedence over the size of the Form, and when a component is used with an Item, the component itself does not set the size property.
size?: 'large' | 'small' | 'medium'
// Position of the label
labelAlign?: 'top' | 'left' | 'inset'
// alignment of labels
labelTextAlign?: 'left' | 'right'
className?: string
// [validation] required
required?: boolean
// whether required asterisks are displayed
asterisk?: boolean
// required custom error message
requiredMessage?: string
// required Custom trigger method
requiredTrigger?: string | Array
// [validation] min
min?: number
// [validation] max
max?: number
// min/max error message
minmaxMessage?: string
// min/max custom trigger method
minmaxTrigger?: string | Array
// [validation] min length of string / min length of array
minLength?: number
// [validation] max length of string / max length of array
maxLength?: number
// minLength/maxLength custom error message
minmaxLengthMessage?: string
// minLength/maxLength custom trigger method
minmaxLengthTrigger?: string | Array
// [validation] length of string / length of array
length?: number
// length custom error message
lengthMessage?: string
// length custom trigger method
lengthTrigger?: string | Array
// Regular pattern
pattern?: any
// pattern custom error message
patternMessage?: string
// pattern custom trigger method
patternTrigger?: string | Array
// [validation] regular pattern
format?: 'number' | 'email' | 'url' | 'tel'
// format custom error message
formatMessage?: string
// format custom trigger method
formatTrigger?: string | Array
// [validation] custom validator
validator?: () => void
// validator custom trigger method
validatorTrigger?: string | Array
// Whether to automatically trigger validate when data is modified
autoValidate?: boolean
}
`
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import {
SchemaForm,
Field,
FormButtonGroup,
Submit,
Reset,
FormItemGrid,
FormCard,
FormBlock,
FormLayout
} from '@uform/next'
import { Button } from '@alifd/next'
import Printer from '@uform/printer'
import '@alifd/next/dist/next.css'
const App = () => (
)
ReactDOM.render(
`
####
> Props of
`typescript`
interface IFormTextBox {
text?: string
gutter?: number
title?: React.ReactText
description?: React.ReactText
}
Usage
`jsx
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
import {
SchemaForm,
Field,
FormTextBox,
FormCard,
FormLayout
} from '@uform/next'
import { Button } from '@alifd/next'
import Printer from '@uform/printer'
import '@alifd/next/dist/next.css'
const App = () => {
return (
text="prefix%suffix prefix2%suffix2 prefix3%suffix3"
gutter={8}
>
default={10}
required
name="aa1"
x-props={{ style: { width: 80 } }}
description="desc1"
/>
default={20}
required
name="aa2"
description="desc2"
/>
default={30}
required
name="aa3"
description="desc3"
/>
)
}
ReactDOM.render(
`
####
> Props of
`typescript`
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
`jsx
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
import {
SchemaForm,
Field,
FormButtonGroup,
Submit,
Reset,
FormItemGrid,
FormCard,
FormBlock,
FormLayout
} from '@uform/next'
import { Button } from '@alifd/next'
import Printer from '@uform/printer'
import '@alifd/next/dist/next.css'
const App = () => {
const [state, setState] = useState({ editable: true })
return (
normal
sticky
type="primary"
onClick={() => setState({ editable: !state.editable })}
>
{state.editable ? 'Preview' : 'Edit'}
)
}
ReactDOM.render(
`
####
> Props of , fully inherited from ButtonProps
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, { TextButton } from '@uform/next'
import '@alifd/next/dist/next.css'
const App = () => (
)
ReactDOM.render(
`
####
> Props of , fully inherited from ButtonProps
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, { CircleButton } from '@uform/next'
import '@alifd/next/dist/next.css'
const App = () => (
)
ReactDOM.render(
`
#### string
* Schema Type : string
* Schema UI Component: Fusion-Next , ,
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import '@alifd/next/dist/next.css'
const actions = createFormActions()
const App = () => {
return (
required
title="Text"
name="text"
x-component-props={{
placeholder: 'input'
}}
/>
enum={['1', '2', '3', '4']}
required
title="Simple Select"
name="simpleSelect"
x-component-props={{
placeholder: 'select'
}}
/>
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'
}}
/>
title="TextArea"
name="textarea"
x-component="textarea"
x-component-props={{
placeholder: 'textarea'
}}
/>
)
}
ReactDOM.render(
`
#### textarea
* Schema Type : string
* Schema UI Component: Fusion-Next
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import '@alifd/next/dist/next.css'
const actions = createFormActions()
const App = () => {
return (
title="TextArea"
name="textarea"
x-component="textarea"
x-component-props={{
placeholder: 'textarea'
}}
/>
)
}
ReactDOM.render(
`
#### password
* Schema Type : password
* Schema UI Component: Fusion-Next
`typescript
interface IPasswordProps {
checkStrength: boolean
/ next input props /
// value
value?: string | number
// default value
defaultValue?: string | number
// callback triggered when value change
onChange?: (value: string, e: React.ChangeEvent
// callback triggered when keyboard is press
onKeyDown?: (e: React.KeyboardEvent
// Disabled
disabled?: boolean
// Max length
maxLength?: number
// Whether to show the maximum length style
hasLimitHint?: boolean
// When maxLength is set, whether to truncate beyond the string
cutString?: boolean
// readOnly
readOnly?: boolean
// Automatically remove the leading and trailing blank characters when trigger onChange
trim?: boolean
// placeholder
placeholder?: string
// callback triggered when focus
onFocus?: () => void
// callback triggered when blur
onBlur?: () => void
// Custom string length calculation
getValueLength?: (value: string) => number
className?: string
style?: React.CSSProperties
htmlType?: string
// name of field
name?: string
// state of field
state?: 'error' | 'loading' | 'success'
// label
label?: React.ReactNode
// whether to show clear
hasClear?: boolean
// whether to show border
hasBorder?: boolean
// size of field
size?: 'small' | 'medium' | 'large'
// callback triggered when enter is press
onPressEnter?: () => void
// Watermark (Icon type, shared with hasClear)
hint?: string
// Append content before text
innerBefore?: React.ReactNode
// Append content after text
innerAfter?: React.ReactNode
// Append content before input
addonBefore?: React.ReactNode
// Append content after input
addonAfter?: React.ReactNode
// Append text before input
addonTextBefore?: React.ReactNode
// Append text after input
addonTextAfter?: React.ReactNode
// (Native supported by input)
autoComplete?: string
// (Native supported by input)
autoFocus?: boolean
}
`
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import '@alifd/next/dist/next.css'
const actions = createFormActions()
const App = () => {
return (
title="Password"
name="password"
x-component="password"
x-component-props={{
placeholder: 'password'
}}
/>
)
}
ReactDOM.render(
`
#### number
* Schema Type : number
* Schema UI Component: Fusion-Next
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import '@alifd/next/dist/next.css'
const actions = createFormActions()
const App = () => {
return (
)
}
ReactDOM.render(
`
#### boolean
* Schema Type : boolean
* Schema UI Component: Fusion-Next
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import '@alifd/next/dist/next.css'
const actions = createFormActions()
const App = () => {
return (
required
title="Boolean"
name="boolean"
x-component-props={{
checkedChildren: 'on',
unCheckedChildren: 'off'
}}
/>
)
}
ReactDOM.render(
`
#### date
* Schema Type : date
* Schema UI Component: Fusion-Next
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import '@alifd/next/dist/next.css'
const actions = createFormActions()
const App = () => {
return (
required
title="DatePicker"
name="datePicker"
x-component-props={{
format: 'YYYY-MM-DD HH:mm:ss'
}}
/>
)
}
ReactDOM.render(
`
#### time
* Schema Type : time
* Schema UI Component: Fusion-Next
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import '@alifd/next/dist/next.css'
const actions = createFormActions()
const App = () => {
return (
required
title="TimePicker"
name="timePicker"
x-component-props={{
format: 'YYYY-MM-DD HH:mm:ss'
}}
/>
)
}
ReactDOM.render(
`
#### range
* Schema Type : range
* Schema UI Component: Fusion-Next
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import '@alifd/next/dist/next.css'
const actions = createFormActions()
const App = () => {
return (
required
title="Range"
name="range"
x-component-props={{
min: 0,
max: 1024,
marks: [0, 1024]
}}
/>
)
}
ReactDOM.render(
`
#### upload
* Schema Type : upload
* Schema UI Component: Fusion-Next
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import '@alifd/next/dist/next.css'
const actions = createFormActions()
const App = () => {
return (
required
title="Card Upload"
name="upload2"
x-component-props={{
listType: 'card'
}}
/>
required
title="Dragger Upload"
name="upload1"
x-component-props={{
listType: 'dragger'
}}
/>
required
title="Text Upload"
name="upload3"
x-component-props={{
listType: 'text'
}}
/>
)
}
ReactDOM.render(
`
#### checkbox
* Schema Type : checkbox
* Schema UI Component: Fusion-Next
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import '@alifd/next/dist/next.css'
const actions = createFormActions()
const App = () => {
return (
required
title="Simple Checkbox"
name="checkbox"
enum={['1', '2', '3', '4']}
/>
required
title="Object Checkbox"
name="checkbox2"
enum={[
{ label: 'One', value: '1' },
{ label: 'Two', value: '2' },
{ label: 'Three', value: '3' },
{ label: 'Four', value: '4' }
]}
/>
)
}
ReactDOM.render(
`
#### radio
* Schema Type : radio
* Schema UI Component: Fusion-Next
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import '@alifd/next/dist/next.css'
const actions = createFormActions()
const App = () => {
return (
required
title="Simple Radio"
name="radio"
enum={['1', '2', '3', '4']}
/>
required
title="Object Radio"
name="radio2"
enum={[
{ label: 'One', value: '1' },
{ label: 'Two', value: '2' },
{ label: 'Three', value: '3' },
{ label: 'Four', value: '4' }
]}
/>
)
}
ReactDOM.render(
`
#### rating
* Schema Type : rating
* Schema UI Component: Fusion-Next
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import '@alifd/next/dist/next.css'
const actions = createFormActions()
const App = () => {
return (
title="Rating"
name="rating"
x-component-props={{
allowHalf: true
}}
/>
)
}
ReactDOM.render(
`
#### transfer
* Schema Type : transfer
* Schema UI Component: Fusion-Next
Usage
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
createFormActions,
FormBlock,
FormLayout,
FormButtonGroup,
Submit,
Reset
} from '@uform/next'
import '@alifd/next/dist/next.css'
const actions = createFormActions()
const App = () => {
return (
title="Transfer"
name="transfer"
enum={[
{ label: 'One', value: '1' },
{ label: 'Two', value: '2' },
{ label: 'Three', value: '3' },
{ label: 'Four', value: '4' }
]}
x-component-props={{
showSearch: true
}}
/>
)
}
ReactDOM.render(
`
#### 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
`typescript`
(effects: IFormEffect): void
`jsx
import React from 'react'
import ReactDOM from 'react-dom'
import SchemaForm, {
SchemaMarkupField as Field,
VirtualField,
createFormActions,
useFormEffects,
LifeCycleTypes,
createVirtualBox
} from '@uform/next'
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 (
{props.children}
)
});
const FormFragment = () => {
return
name="trigger"
title="trigger"
enum={[{ label: 'show', value: true }, { label: 'hide', value: false } ]}
/>
}
const App = () => {
return (
)
}
ReactDOM.render(
`
#### useFormState
> 使用 useFormState 为自定义组件提供FormState扩展和管理能力
签名
`typescript`
(defaultState: T): [state: IFormState, setFormState: (state?: IFormState) => void]
用法
`jsx
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 => (
{({ state, mutators }) => {
const loading = state.props.loading
return
{ props.label && }
{ loading ? ' loading... ' : disabled={!state.editable}
value={state.value || ''}
onChange={mutators.change}
onBlur={mutators.blur}
onFocus={mutators.focus}
/> }
{state.errors}
{state.warnings}
}}
)
const actions = createFormActions()
const FormFragment = (props) => {
const [formState, setFormState ] = useFormState({ extendVar: 0 })
const { extendVar } = formState
return
const App = () => {
return (
ReactDOM.render(
`
#### useFieldState
> Manage state of custom field by using useFieldState
Signature
`typescript`
(defaultState: T): [state: IFieldState, setFieldState: (state?: IFieldState) => void]
`jsx
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 => (
{({ state, mutators }) => {
const loading = state.props.loading
return
{ props.label && }
{ loading ? ' loading... ' : disabled={!state.editable}
value={state.value || ''}
onChange={mutators.change}
onBlur={mutators.blur}
onFocus={mutators.focus}
/> }
{state.errors}
{state.warnings}
}}
)
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
})
return btns
}
const FormTab = (props) => {
return
{({ form }) => {
return
}}
}
const App = () => {
return (
ReactDOM.render(
`
#### useForm
> get IForm instance
Signature
`typescript`
type useForm = <
Value = any,
DefaultValue = any,
EffectPayload = any,
EffectAction = any
>(
props: IFormProps
) => IForm
Usage
`typescript
import { useForm } from '@uform/react'
const FormFragment = () => {
const form = useForm()
return
#### useField
> get IFieldHook instance
Signature
`typescript
type useField = (options: IFieldStateUIProps): IFieldHook
`Usage
`typescript
import { useField } from '@uform/react'const FormFragment = (props) => {
const {
form,
state,
props: fieldProps,
mutators
} = useField({ name: 'username' })
return
}
`#### useVirtualField
> get IVirtualFieldHook instance
Signature
`typescript
type UseVirtualField = (options: IVirtualFieldStateProps): IVirtualFieldHook
`Usage
`typescript
import { UseVirtualField } from '@uform/react'const FormFragment = (props) => {
const {
form,
state,
props: fieldProps,
} = UseVirtualField({ name: 'username' })
return
{props.children}
}
`#### useFormSpy
> get ISpyHook instance. Same effect as the first example of FormSpy.
Signature
`typescript
type useFormSpy = (props: IFormSpyProps): ISpyHook
`Usage
`typescript
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
count: {state.count || 0}
}
`$3
> Fully inherited from @uform/react, The specific API of @uform/next is listed below.
---
####
createFormActions> Return IFormActions
Signature
`typescript
createFormActions(): IFormActions
`Usage
`typescript
import { createFormActions } from '@uform/next'const actions = createFormActions()
console.log(actions.getFieldValue('username'))
`####
createAsyncFormActions> Return IFormAsyncActions
Signature
`typescript
createAsyncFormActions(): IFormAsyncActions
`Usage
`typescript
import { createAsyncFormActions } from '@uform/next'const actions = createAsyncFormActions()
actions.getFieldValue('username').then(val => console.log(val))
`####
FormEffectHooks> Return all @uform/core lifeCycles hook which can be subscribe
Usage
``tsxconst App = () => {
return (