Skip to content

Commit

Permalink
feat(@uform/react): support useFieldState/useFormState (#433)
Browse files Browse the repository at this point in the history
* feat(@uform/antd/next): improve form step

* feat(@uform/react): support useFieldState/useFormState
  • Loading branch information
janryWang authored Nov 26, 2019
1 parent b446c02 commit 9440ac4
Show file tree
Hide file tree
Showing 13 changed files with 240 additions and 120 deletions.
16 changes: 16 additions & 0 deletions docs/Examples/antd/Layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ const { onFormInit$ } = FormEffectHooks

const actions = createFormActions()

let cache = {}

export default () => (
<SchemaForm
onSubmit={values => {
Expand Down Expand Up @@ -340,6 +342,20 @@ export default () => (
<Button onClick={() => actions.dispatch(FormStep.ON_FORM_STEP_NEXT)}>
下一步
</Button>
<Button
onClick={() => {
cache = actions.getFormGraph()
}}
>
存储当前状态
</Button>
<Button
onClick={() => {
actions.setFormGraph(cache)
}}
>
回滚状态
</Button>
</FormButtonGroup>
</SchemaForm>
)
Expand Down
81 changes: 59 additions & 22 deletions docs/Examples/next/Layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,33 +171,55 @@ const App = () => {
<Field name="ccc" type="date" title="字段3" />
</FormCard>
<FormCard title="详细信息">
<FormItemGrid title="字段3" gutter={10} cols={[11, 15]}>
<Field name="ddd" type="number" />
<Field name="eee" type="date" />
</FormItemGrid>
<Field type="object" name="mmm" title="对象字段">
<FormItemGrid gutter={10} cols={[11, 15]}>
<Field name="ddd1" default={123} type="number" />
<Field name="[startDate,endDate]" type="daterange" />
</FormItemGrid>
</Field>
<FormItemGrid title="字段3" gutter={10} cols={[11, 15]}>
<Field name="ddd" type="number" />
<Field name="eee" type="date" />
</FormItemGrid>
<Field type="object" name="mmm" title="对象字段">
<FormItemGrid gutter={10} cols={[11, 15]}>
<Field name="ddd1" default={123} type="number" />
<Field name="[startDate,endDate]" type="daterange" />
</FormItemGrid>
</Field>
<FormLayout labelCol={8} wrapperCol={16}>
<FormTextBox title="文本串联" text="订%s元/票 退%s元/票 改%s元/票" gutter={8}>
<Field type="string" default={10} required name="aa1" x-props={{style:{width:80}}} description="简单描述" />
<Field type="number" default={20} required name="aa2" description="简单描述" />
<Field type="number" default={30} required name="aa3" description="简单描述" />
<FormTextBox
title="文本串联"
text="订%s元/票 退%s元/票 改%s元/票"
gutter={8}
>
<Field
type="string"
default={10}
required
name="aa1"
x-props={{ style: { width: 80 } }}
description="简单描述"
/>
<Field
type="number"
default={20}
required
name="aa2"
description="简单描述"
/>
<Field
type="number"
default={30}
required
name="aa3"
description="简单描述"
/>
</FormTextBox>
</FormLayout>
<Field name="aas" type="string" title="字段4" /><FormBlock title="区块">
<Field name="ddd2" type="string" title="字段5" />
<Field name="eee2" type="string" title="字段6" />
</FormBlock>
</FormCard>
<FormButtonGroup offset={8} sticky>
</FormCard><FormButtonGroup offset={8} sticky>
<Submit>提交</Submit>
<Button
type="primary"
onClick={() => setState({ editable: !state.editable })}
type="primary"
onClick={() => setState({ editable: !state.editable })}
>
{state.editable ? '详情' : '编辑'}
</Button>
Expand Down Expand Up @@ -258,7 +280,6 @@ ReactDOM.render(<App />, document.getElementById('root'))

## 分步表单


```jsx
import {
SchemaForm,
Expand All @@ -284,6 +305,8 @@ const { onFormInit$ } = FormEffectHooks

const actions = createFormActions()

let cache = {}

export default () => (
<SchemaForm
onSubmit={values => {
Expand All @@ -305,9 +328,9 @@ export default () => (
<FormStep
style={{ marginBottom: 20 }}
dataSource={[
{ title: '基本信息',name:'step-1' },
{ title: '财务信息',name:'step-2' },
{ title: '条款信息',name:'step-3' }
{ title: '基本信息', name: 'step-1' },
{ title: '财务信息', name: 'step-2' },
{ title: '条款信息', name: 'step-3' }
]}
/>
<FormCard name="step-1" title="基本信息">
Expand All @@ -327,6 +350,20 @@ export default () => (
<Button onClick={() => actions.dispatch(FormStep.ON_FORM_STEP_NEXT)}>
下一步
</Button>
<Button
onClick={() => {
cache = actions.getFormGraph()
}}
>
存储当前状态
</Button>
<Button
onClick={() => {
actions.setFormGraph(cache)
}}
>
回滚状态
</Button>
</FormButtonGroup>
</SchemaForm>
)
Expand Down
66 changes: 28 additions & 38 deletions packages/antd/src/components/FormStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {
createControllerBox,
ISchemaVirtualFieldComponentProps,
createEffectHook,
useFormEffects
useFormEffects,
useFieldState
} from '@uform/react-schema-renderer'
import { toArr } from '@uform/shared'
import { Steps } from 'antd'
Expand All @@ -30,13 +31,10 @@ type StepComponentExtendsProps = StateMap
export const FormStep: React.FC<IFormStep> &
StepComponentExtendsProps = createControllerBox<IFormStep>(
'step',
({
form,
path,
schema,
current,
children
}: ISchemaVirtualFieldComponentProps) => {
({ form, schema, children }: ISchemaVirtualFieldComponentProps) => {
const [{ current }, setFieldState] = useFieldState({
current: 0
})
const ref = useRef(current)
const { dataSource, ...stepProps } = schema.getExtendsComponentProps()
const items = toArr(dataSource)
Expand All @@ -45,18 +43,17 @@ export const FormStep: React.FC<IFormStep> &
value: cur,
preValue: current
})
form.setFieldState(path, state => {
state.current = cur
setFieldState({
current: cur
})
}
current = current || 0
useFormEffects(({ setFieldState }) => {
useFormEffects(($, { setFieldState }) => {
items.forEach(({ name }, index) => {
setFieldState(name, (state: any) => {
state.display = index === current
})
})
EffectHooks.onStepCurrentChange$().subscribe(({ value }) => {
$(StateMap.ON_FORM_STEP_CURRENT_CHANGE).subscribe(({ value }) => {
items.forEach(({ name }, index) => {
if (!name)
throw new Error('FormStep dataSource must include `name` property')
Expand All @@ -65,34 +62,27 @@ export const FormStep: React.FC<IFormStep> &
})
})
})
})
useMemo(() => {
update(ref.current)
form.subscribe(({ type, payload }) => {
switch (type) {
case StateMap.ON_FORM_STEP_NEXT:
form.validate().then(({ errors }) => {
if (errors.length === 0) {
update(
ref.current + 1 > items.length - 1
? ref.current
: ref.current + 1
)
}
})

break
case StateMap.ON_FORM_STEP_PREVIOUS:
update(ref.current - 1 < 0 ? ref.current : ref.current - 1)
break
case StateMap.ON_FORM_STEP_GO_TO:
if (!(payload < 0 || payload > items.length)) {
update(payload)
}
break
$(StateMap.ON_FORM_STEP_NEXT).subscribe(() => {
form.validate().then(({ errors }) => {
if (errors.length === 0) {
update(
ref.current + 1 > items.length - 1 ? ref.current : ref.current + 1
)
}
})
})

$(StateMap.ON_FORM_STEP_PREVIOUS).subscribe(() => {
update(ref.current - 1 < 0 ? ref.current : ref.current - 1)
})

$(StateMap.ON_FORM_STEP_GO_TO).subscribe(payload => {
if (!(payload < 0 || payload > items.length)) {
update(payload)
}
})
}, [])
})
ref.current = current
return (
<Fragment>
Expand Down
71 changes: 30 additions & 41 deletions packages/next/src/components/FormStep.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { useMemo, useRef, Fragment } from 'react'
import React, { useRef, Fragment } from 'react'
import {
createControllerBox,
ISchemaVirtualFieldComponentProps,
createEffectHook,
useFormEffects
useFormEffects,
useFieldState
} from '@uform/react-schema-renderer'
import { toArr } from '@uform/shared'
import { Step } from '@alifd/next'
Expand All @@ -30,70 +31,58 @@ type StepComponentExtendsProps = StateMap
export const FormStep: React.FC<IFormStep> &
StepComponentExtendsProps = createControllerBox<IFormStep>(
'step',
({
props,
form,
path,
current,
children
}: ISchemaVirtualFieldComponentProps) => {
({ form, schema, children }: ISchemaVirtualFieldComponentProps) => {
const [{ current }, setFieldState] = useFieldState({
current: 0
})
const ref = useRef(current)
const { dataSource, ...stepProps } = props['x-component-props'] || {}
const { dataSource, ...stepProps } = schema.getExtendsComponentProps()
const items = toArr(dataSource)
const update = (cur: number) => {
form.notify(StateMap.ON_FORM_STEP_CURRENT_CHANGE, {
value: cur,
preValue: current
})
form.setFieldState(path, state => {
state.current = cur
setFieldState({
current: cur
})
}
current = current || 0
useFormEffects(({ setFieldState }) => {
useFormEffects(($, { setFieldState }) => {
items.forEach(({ name }, index) => {
setFieldState(name, (state: any) => {
state.display = index === current
})
})
EffectHooks.onStepCurrentChange$().subscribe(({ value }) => {
$(StateMap.ON_FORM_STEP_CURRENT_CHANGE).subscribe(({ value }) => {
items.forEach(({ name }, index) => {
if (!name)
throw new Error('FormStep dataSource must include `name` property')

setFieldState(name, (state: any) => {
state.display = index === value
})
})
})
})
useMemo(() => {
update(ref.current)
form.subscribe(({ type, payload }) => {
switch (type) {
case StateMap.ON_FORM_STEP_NEXT:
form.validate().then(({ errors }) => {
if (errors.length === 0) {
update(
ref.current + 1 > items.length - 1
? ref.current
: ref.current + 1
)
}
})

break
case StateMap.ON_FORM_STEP_PREVIOUS:
update(ref.current - 1 < 0 ? ref.current : ref.current - 1)
break
case StateMap.ON_FORM_STEP_GO_TO:
if (!(payload < 0 || payload > items.length)) {
update(payload)
}
break
$(StateMap.ON_FORM_STEP_NEXT).subscribe(() => {
form.validate().then(({ errors }) => {
if (errors.length === 0) {
update(
ref.current + 1 > items.length - 1 ? ref.current : ref.current + 1
)
}
})
})

$(StateMap.ON_FORM_STEP_PREVIOUS).subscribe(() => {
update(ref.current - 1 < 0 ? ref.current : ref.current - 1)
})

$(StateMap.ON_FORM_STEP_GO_TO).subscribe(payload => {
if (!(payload < 0 || payload > items.length)) {
update(payload)
}
})
}, [])
})
ref.current = current
return (
<Fragment>
Expand Down
Loading

0 comments on commit 9440ac4

Please sign in to comment.