Skip to content

Commit 9093ab2

Browse files
JohnIsOnTheRoadjanryWang
authored andcommitted
fix(@uform/core): validate (#484)
* fix: change submit and validate function * feat: add validate unit-test compat * feat: abandon this pr` * feat: doc update * feat: add try catch to inner valodate * feat: update validate case * feat: update unitest and cod * feat: update use field
1 parent 335552d commit 9093ab2

File tree

17 files changed

+746
-96
lines changed

17 files changed

+746
-96
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"test": "npm run lint && jest",
1616
"test:core": "jest --watch packages/core/src/__tests__/*.spec.ts",
1717
"test:hook": "jest --watch packages/react/src/__tests__/*.spec.tsx",
18+
"test:renderer": "jest --watch packages/react-schema-renderer/src/__tests__/*.spec.tsx",
1819
"test:editor": "jest --watch packages/react-schema-editor/src/__tests__/*.spec.ts",
1920
"test:prod": "cross-env TEST_ENV=production npm run build && jest",
2021
"doc:core": "doc-scripts start -i packages/core",

packages/antd/README.md

+138-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ npm install --save @uform/antd
1616
- [`<SchemaMarkupField/>`](#SchemaMarkupField)
1717
- [`<Submit/>`](#Submit)
1818
- [`<Reset/>`](#Reset)
19+
- [`<FormSpy/>`](#FormSpy)
1920
- [`<Field/>(deprecated,please use <SchemaMarkupField/>)`](#<Field/>)
2021
- [Form List](#Array-Components)
2122
- [`array`](#array)
@@ -61,7 +62,7 @@ npm install --save @uform/antd
6162
- [`connect`](#connect)
6263
- [`registerFormField`](#registerFormField)
6364
- [Interfaces](#Interfaces)
64-
- [ISchema](#ischema)
65+
- [`ISchema`](#ischema)
6566
- [`IFormActions`](#IFormActions)
6667
- [`IFormAsyncActions`](#IFormAsyncActions)
6768
- [`ButtonProps`](#ButtonProps)
@@ -79,6 +80,7 @@ npm install --save @uform/antd
7980
- [`IMutators`](#IMutators)
8081
- [`IFieldProps`](#IFieldProps)
8182
- [`IConnectOptions`](#IConnectOptions)
83+
- [`ISpyHook`](#ISpyHook)
8284

8385

8486
### Quick-Start
@@ -716,6 +718,128 @@ interface IResetProps {
716718
}
717719
```
718720

721+
#### `<FormSpy/>`
722+
723+
> `<FormSpy>` Props
724+
725+
```typescript
726+
interface IFormSpyProps {
727+
// selector, eg: [ LifeCycleTypes.ON_FORM_SUBMIT_START, LifeCycleTypes.ON_FORM_SUBMIT_END ]
728+
selector?: string[] | string
729+
// reducer
730+
reducer?: (
731+
state: any,
732+
action: { type: string; payload: any },
733+
form: IForm
734+
) => any
735+
children?: React.ReactElement | ((api: IFormSpyAPI) => React.ReactElement)
736+
}
737+
```
738+
739+
**Usage**
740+
741+
Example1: Form state change counter
742+
743+
```jsx
744+
import React from 'react'
745+
import ReactDOM from 'react-dom'
746+
import { Form, Field, createFormActions, FormSpy, LifeCycleTypes } from '@uform/react'
747+
748+
const actions = createFormActions()
749+
const InputField = props => (
750+
<Field {...props}>
751+
{({ state, mutators }) => (
752+
<React.Fragment>
753+
<input
754+
disabled={!state.editable}
755+
value={state.value || ''}
756+
onChange={mutators.change}
757+
onBlur={mutators.blur}
758+
onFocus={mutators.focus}
759+
/>
760+
<span style={{ color: 'red' }}>{state.errors}</span>
761+
<span style={{ color: 'orange' }}>{state.warnings}</span>
762+
</React.Fragment>
763+
)}
764+
</Field>
765+
)
766+
767+
const App = () => {
768+
return (
769+
<Form actions={actions}>
770+
<label>username</label>
771+
<InputField name="username" />
772+
<label>age</label>
773+
<InputField name="age" />
774+
<FormSpy
775+
selector={LifeCycleTypes.ON_FORM_VALUES_CHANGE}
776+
reducer={(state, action, form) => ({
777+
count: state.count ? state.count + 1 : 1
778+
})}
779+
>
780+
{({ state, type, form }) => {
781+
return <div>count: {state.count || 0}</div>
782+
}}
783+
</FormSpy>
784+
</Form>
785+
)
786+
}
787+
788+
ReactDOM.render(<App />, document.getElementById('root'))
789+
790+
```
791+
792+
Example2:Combo
793+
794+
```jsx
795+
import React from 'react'
796+
import ReactDOM from 'react-dom'
797+
import { Form, Field, createFormActions, FormSpy } from '@uform/react'
798+
799+
const actions = createFormActions()
800+
const InputField = props => (
801+
<Field {...props}>
802+
{({ state, mutators }) => (
803+
<React.Fragment>
804+
<input
805+
disabled={!state.editable}
806+
value={state.value || ''}
807+
onChange={mutators.change}
808+
onBlur={mutators.blur}
809+
onFocus={mutators.focus}
810+
/>
811+
<span style={{ color: 'red' }}>{state.errors}</span>
812+
<span style={{ color: 'orange' }}>{state.warnings}</span>
813+
</React.Fragment>
814+
)}
815+
</Field>
816+
)
817+
818+
const App = () => {
819+
return (
820+
<Form actions={actions}>
821+
<label>username</label>
822+
<InputField name="username" />
823+
<label>age</label>
824+
<InputField name="age" />
825+
<FormSpy>
826+
{({ state, form }) => {
827+
return (
828+
<div>
829+
name: {form.getFieldValue('username')}
830+
<br />
831+
age: {form.getFieldValue('age')}
832+
</div>
833+
)
834+
}}
835+
</FormSpy>
836+
</Form>
837+
)
838+
}
839+
840+
ReactDOM.render(<App />, document.getElementById('root'))
841+
```
842+
719843
#### `<Field/>`
720844

721845
> deprecated,please use [SchemaMarkupField](#SchemaMarkupField)
@@ -2931,7 +3055,7 @@ interface IFormActions {
29313055
selector?: FormPathPattern
29323056
}): Promise<void | IFormValidateResult>
29333057
/*
2934-
* Validation form
3058+
* Validation form, throw IFormValidateResult when validation fails
29353059
*/
29363060
validate(
29373061
path?: FormPathPattern,
@@ -3040,7 +3164,7 @@ interface IFormAsyncActions {
30403164
*/
30413165
clearErrors: (pattern?: FormPathPattern) => Promise<void>
30423166
/*
3043-
* Validation form
3167+
* Validation form, throw IFormValidateResult when validation fails
30443168
*/
30453169
validate(
30463170
path?: FormPathPattern,
@@ -3460,4 +3584,15 @@ interface IConnectOptions<T> {
34603584
) => T
34613585
}
34623586
3587+
```
3588+
3589+
3590+
#### ISpyHook
3591+
3592+
```typescript
3593+
interface ISpyHook {
3594+
form: IForm
3595+
state: any
3596+
type: string
3597+
}
34633598
```

packages/antd/README.zh-cn.md

+146-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ npm install --save @uform/antd
1717
- [`<SchemaMarkupField/>`](#SchemaMarkupField)
1818
- [`<Submit/>`](#Submit)
1919
- [`<Reset/>`](#Reset)
20-
- [`<Field/>(即将废弃,请使用<SchemaMarkupField/>)`](<#Field(即将废弃,请使用SchemaMarkupField)>)
20+
- [`<FormSpy/>`](#FormSpy)
21+
- [`<Field/>(即将废弃,请使用<SchemaMarkupField/>)`](#<Field/>)
2122
- [表单List](#Array-Components)
2223
- [`array`](#array)
2324
- [`cards`](#cards)
@@ -62,7 +63,7 @@ npm install --save @uform/antd
6263
- [`connect`](#connect)
6364
- [`registerFormField`](#registerFormField)
6465
- [Interfaces](#Interfaces)
65-
- [ISchema](#ischema)
66+
- [`ISchema`](#ischema)
6667
- [`IFormActions`](#IFormActions)
6768
- [`IFormAsyncActions`](#IFormAsyncActions)
6869
- [`ButtonProps`](#ButtonProps)
@@ -80,6 +81,7 @@ npm install --save @uform/antd
8081
- [`IMutators`](#IMutators)
8182
- [`IFieldProps`](#IFieldProps)
8283
- [`IConnectOptions`](#IConnectOptions)
84+
- [`ISpyHook`](#ISpyHook)
8385

8486

8587
### 使用方式
@@ -711,6 +713,136 @@ interface IResetProps {
711713
}
712714
```
713715

716+
#### `<FormSpy/>`
717+
718+
> FormSpy 组件属性定义
719+
720+
```typescript
721+
interface IFormSpyProps {
722+
// 选择器, 如:[ LifeCycleTypes.ON_FORM_SUBMIT_START, LifeCycleTypes.ON_FORM_SUBMIT_END ]
723+
selector?: string[] | string
724+
// reducer函数,状态叠加处理,action为当前命中的生命周期的数据
725+
reducer?: (
726+
state: any,
727+
action: { type: string; payload: any },
728+
form: IForm
729+
) => any
730+
children?: React.ReactElement | ((api: IFormSpyAPI) => React.ReactElement)
731+
}
732+
```
733+
734+
**用法**
735+
736+
例子 1: 实现一个统计表单 values 改变的计数器
737+
738+
```jsx
739+
import React from 'react'
740+
import ReactDOM from 'react-dom'
741+
import { Form, Field, createFormActions, FormSpy, LifeCycleTypes } from '@uform/react'
742+
743+
const actions = createFormActions()
744+
const InputField = props => (
745+
<Field {...props}>
746+
{({ state, mutators }) => {
747+
const loading = state.props.loading
748+
return <React.Fragment>
749+
{ props.label && <label>{props.label}</label> }
750+
{ loading ? ' loading... ' : <input
751+
disabled={!state.editable}
752+
value={state.value || ''}
753+
onChange={mutators.change}
754+
onBlur={mutators.blur}
755+
onFocus={mutators.focus}
756+
/> }
757+
<span style={{ color: 'red' }}>{state.errors}</span>
758+
<span style={{ color: 'orange' }}>{state.warnings}</span>
759+
</React.Fragment>
760+
}}
761+
</Field>
762+
)
763+
764+
const App = () => {
765+
return (
766+
<Form actions={actions}>
767+
<label>username</label>
768+
<InputField name="username" />
769+
<label>age</label>
770+
<InputField name="age" />
771+
<FormSpy
772+
selector={LifeCycleTypes.ON_FORM_VALUES_CHANGE}
773+
reducer={(state, action, form) => ({
774+
count: state.count ? state.count + 1 : 1
775+
})}
776+
>
777+
{({ state, type, form }) => {
778+
return <div>count: {state.count || 0}</div>
779+
}}
780+
</FormSpy>
781+
</Form>
782+
)
783+
}
784+
785+
ReactDOM.render(<App />, document.getElementById('root'))
786+
787+
```
788+
789+
例子 2:实现常用 combo 组件
790+
791+
```jsx
792+
import React from 'react'
793+
import ReactDOM from 'react-dom'
794+
import { Form, Field, createFormActions, FormSpy } from '@uform/react'
795+
796+
const actions = createFormActions()
797+
const InputField = props => (
798+
<Field {...props}>
799+
{({ state, mutators }) => {
800+
const loading = state.props.loading
801+
return <React.Fragment>
802+
{ props.label && <label>{props.label}</label> }
803+
{ loading ? ' loading... ' : <input
804+
disabled={!state.editable}
805+
value={state.value || ''}
806+
onChange={mutators.change}
807+
onBlur={mutators.blur}
808+
onFocus={mutators.focus}
809+
/> }
810+
<span style={{ color: 'red' }}>{state.errors}</span>
811+
<span style={{ color: 'orange' }}>{state.warnings}</span>
812+
</React.Fragment>
813+
}}
814+
</Field>
815+
)
816+
817+
const App = () => {
818+
return (
819+
<Form actions={actions}>
820+
<label>username</label>
821+
<InputField name="username" />
822+
<label>age</label>
823+
<InputField name="age" />
824+
<FormSpy>
825+
{({ state, form }) => {
826+
return (
827+
<div>
828+
name: {form.getFieldValue('username')}
829+
<br />
830+
age: {form.getFieldValue('age')}
831+
</div>
832+
)
833+
}}
834+
</FormSpy>
835+
</Form>
836+
)
837+
}
838+
839+
ReactDOM.render(<App />, document.getElementById('root'))
840+
```
841+
842+
#### `<Field/>`
843+
844+
> 即将废弃,请使用 [SchemaMarkupField](#SchemaMarkupField)
845+
714846
### Array Components
715847

716848
#### array
@@ -2917,7 +3049,7 @@ interface IFormActions {
29173049
}): Promise<void | IFormValidateResult>
29183050
29193051
/*
2920-
* 校验表单
3052+
* 校验表单,当校验失败时抛出异常
29213053
*/
29223054
validate(
29233055
path?: FormPathPattern,
@@ -3096,7 +3228,7 @@ interface IFormAsyncActions {
30963228
*/
30973229
clearErrors: (pattern?: FormPathPattern) => Promise<void>
30983230
/*
3099-
* 校验表单
3231+
* 校验表单, 当校验失败时抛出异常
31003232
*/
31013233
validate(
31023234
path?: FormPathPattern,
@@ -3485,4 +3617,14 @@ interface IConnectOptions<T> {
34853617
) => T
34863618
}
34873619
3620+
```
3621+
3622+
#### ISpyHook
3623+
3624+
```typescript
3625+
interface ISpyHook {
3626+
form: IForm
3627+
state: any
3628+
type: string
3629+
}
34883630
```

0 commit comments

Comments
 (0)