Skip to content

Commit ec3a5bc

Browse files
committed
feat: rules support warningOnly (#304)
* 1.20.1 * feat: Support onError event * fix: Every update errors should trigger event * test: Test driven of onError * feat: All message support variable * fix: Fill template logic * feat: support warning * test: Test driven * chore: export getFieldWarning * fix: summary validate logic * test: Update coverage * test: Update coverage
1 parent 29be013 commit ec3a5bc

File tree

15 files changed

+561
-327
lines changed

15 files changed

+561
-327
lines changed

docs/examples/components/LabelField.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import * as React from 'react';
22
import Form from 'rc-field-form';
3-
import { FieldProps } from '@/Field';
3+
import type { FieldProps } from '@/Field';
44

55
const { Field } = Form;
66

7-
const Error = ({ children }) => (
8-
<ul style={{ color: 'red' }}>
7+
interface ErrorProps {
8+
warning?: boolean;
9+
children?: React.ReactNode[];
10+
}
11+
12+
const Error = ({ children, warning }: ErrorProps) => (
13+
<ul style={{ color: warning ? 'orange' : 'red' }}>
914
{children.map((error: React.ReactNode, index: number) => (
1015
<li key={index}>{error}</li>
1116
))}
@@ -55,6 +60,7 @@ const LabelField: React.FunctionComponent<LabelFieldProps> = ({
5560

5661
<FieldState {...meta} />
5762
<Error>{meta.errors}</Error>
63+
<Error warning>{meta.warnings}</Error>
5864
</div>
5965
);
6066
}}

docs/examples/validate-perf.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ export default class Demo extends React.Component {
3434
console.log('Failed:', errorInfo);
3535
};
3636

37+
public onPasswordError = (errors: string[]) => {
38+
console.log('🐞 Password Error:', errors);
39+
};
40+
3741
public render() {
3842
return (
3943
<div>
@@ -49,7 +53,18 @@ export default class Demo extends React.Component {
4953
<LabelField
5054
name="password"
5155
messageVariables={{ displayName: '密码' }}
52-
rules={[{ required: true }]}
56+
rules={[
57+
{ required: true },
58+
{
59+
warningOnly: true,
60+
validator: async (_, value: string = '') => {
61+
if (value.length < 6) {
62+
throw new Error('你的 ${displayName} 太短了……');
63+
}
64+
},
65+
},
66+
]}
67+
onError={this.onPasswordError}
5368
>
5469
<Input placeholder="password" />
5570
</LabelField>
@@ -118,6 +133,7 @@ export default class Demo extends React.Component {
118133
>
119134
Reset
120135
</button>
136+
<button type="reset">Reset Native</button>
121137
</Form>
122138
</div>
123139
);

docs/examples/validate.tsx

Lines changed: 132 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -33,139 +33,141 @@ const FieldState = ({ form, name }) => {
3333
);
3434
};
3535

36-
export default class Demo extends React.Component {
37-
onFinish = values => {
36+
export default () => {
37+
const onFinish = (values: object) => {
3838
console.log('Finish:', values);
3939
};
4040

41-
render() {
42-
return (
43-
<div>
44-
<h3>Validate Form</h3>
45-
<Form style={{ padding: 16 }} onFinish={this.onFinish}>
46-
{(values, form) => {
47-
const usernameError = form.getFieldError('username');
48-
const passwordError = form.getFieldError('password');
49-
const password2Error = form.getFieldError('password2');
50-
const errors = form.getFieldsError();
51-
if (errors) {
52-
console.log('Render with Errors:', values, form.getFieldsError());
53-
}
54-
55-
return (
56-
<React.Fragment>
57-
<Field name="username" rules={[{ required: true }]}>
58-
<Input
59-
placeholder="Username"
60-
onChange={({ target: { value } }) => {
61-
console.log('Username change:', value);
62-
}}
63-
/>
64-
</Field>
65-
<FieldState form={form} name="username" />
66-
<Error>{usernameError}</Error>
67-
68-
<Field
69-
name="password"
70-
rules={[
71-
{ required: true },
72-
context => ({
73-
validator(_, __, callback) {
74-
if (context.isFieldTouched('password2')) {
75-
context.validateFields(['password2']);
76-
callback();
77-
return;
78-
}
41+
const onNameError = (errors: string[]) => {
42+
console.log('🐞 Name Error Change:', errors);
43+
};
44+
45+
return (
46+
<div style={{ position: 'relative' }}>
47+
<h3>Validate Form</h3>
48+
<Form style={{ padding: 16 }} onFinish={onFinish}>
49+
{(values, form) => {
50+
const usernameError = form.getFieldError('username');
51+
const passwordError = form.getFieldError('password');
52+
const password2Error = form.getFieldError('password2');
53+
const errors = form.getFieldsError();
54+
if (errors) {
55+
console.log('Render with Errors:', values, form.getFieldsError());
56+
}
57+
58+
return (
59+
<React.Fragment>
60+
<Field name="username" rules={[{ required: true }]} onError={onNameError}>
61+
<Input
62+
placeholder="Username"
63+
onChange={({ target: { value } }) => {
64+
console.log('Username change:', value);
65+
}}
66+
/>
67+
</Field>
68+
<FieldState form={form} name="username" />
69+
<Error>{usernameError}</Error>
70+
71+
<Field
72+
name="password"
73+
rules={[
74+
{ required: true },
75+
context => ({
76+
validator(_, __, callback) {
77+
if (context.isFieldTouched('password2')) {
78+
context.validateFields(['password2']);
7979
callback();
80-
},
81-
}),
82-
]}
83-
>
84-
<Input placeholder="Password" />
85-
</Field>
86-
<FieldState form={form} name="password" />
87-
<Error>{passwordError}</Error>
88-
89-
<Field
90-
name="password2"
91-
rules={[
92-
{ required: true },
93-
context => ({
94-
validator(rule, value, callback) {
95-
const { password } = context.getFieldsValue(true);
96-
if (password !== value) {
97-
callback('Not Same as password1!!!');
80+
return;
81+
}
82+
callback();
83+
},
84+
}),
85+
]}
86+
>
87+
<Input placeholder="Password" />
88+
</Field>
89+
<FieldState form={form} name="password" />
90+
<Error>{passwordError}</Error>
91+
92+
<Field
93+
name="password2"
94+
rules={[
95+
{ required: true },
96+
context => ({
97+
validator(rule, value, callback) {
98+
const { password } = context.getFieldsValue(true);
99+
if (password !== value) {
100+
callback('Not Same as password1!!!');
101+
}
102+
callback();
103+
},
104+
}),
105+
]}
106+
>
107+
<Input placeholder="Password 2" />
108+
</Field>
109+
<FieldState form={form} name="password2" />
110+
<Error>{password2Error}</Error>
111+
112+
<Field name="renderProps" rules={[{ required: true }]}>
113+
{(control, meta) => (
114+
<div>
115+
Use Meta:
116+
<Input {...control} placeholder="render props" />
117+
<FieldState form={form} name="renderProps" />
118+
<Error>{meta.errors}</Error>
119+
</div>
120+
)}
121+
</Field>
122+
123+
<Field
124+
name="validateTrigger"
125+
validateTrigger={['onSubmit', 'onChange']}
126+
rules={[
127+
{ required: true, validateTrigger: 'onSubmit' },
128+
{
129+
validator(rule, value, callback) {
130+
setTimeout(() => {
131+
if (Number(value).toString() === value) {
132+
callback();
98133
}
99-
callback();
100-
},
101-
}),
102-
]}
103-
>
104-
<Input placeholder="Password 2" />
105-
</Field>
106-
<FieldState form={form} name="password2" />
107-
<Error>{password2Error}</Error>
108-
109-
<Field name="renderProps" rules={[{ required: true }]}>
110-
{(control, meta) => (
111-
<div>
112-
Use Meta:
113-
<Input {...control} placeholder="render props" />
114-
<FieldState form={form} name="renderProps" />
115-
<Error>{meta.errors}</Error>
116-
</div>
117-
)}
118-
</Field>
119-
120-
<Field
121-
name="validateTrigger"
122-
validateTrigger={['onSubmit', 'onChange']}
123-
rules={[
124-
{ required: true, validateTrigger: 'onSubmit' },
125-
{
126-
validator(rule, value, callback) {
127-
setTimeout(() => {
128-
if (Number(value).toString() === value) {
129-
callback();
130-
}
131-
callback('Integer number only!');
132-
}, 1000);
133-
},
134-
validateTrigger: 'onChange',
134+
callback('Integer number only!');
135+
}, 1000);
135136
},
136-
]}
137-
>
138-
{(control, meta) => (
139-
<div>
140-
Multiple `validateTrigger`:
141-
<ul>
142-
<li>Required check on submit</li>
143-
<li>Number check on change</li>
144-
</ul>
145-
<Input {...control} placeholder="validateTrigger" />
146-
<FieldState form={form} name="validateTrigger" />
147-
<Error>{meta.errors}</Error>
148-
</div>
149-
)}
150-
</Field>
151-
152-
<br />
153-
154-
<button
155-
type="button"
156-
onClick={() => {
157-
form.validateFields();
158-
}}
159-
>
160-
Validate All
161-
</button>
162-
163-
<button type="submit">Submit</button>
164-
</React.Fragment>
165-
);
166-
}}
167-
</Form>
168-
</div>
169-
);
170-
}
171-
}
137+
validateTrigger: 'onChange',
138+
},
139+
]}
140+
>
141+
{(control, meta) => (
142+
<div>
143+
Multiple `validateTrigger`:
144+
<ul>
145+
<li>Required check on submit</li>
146+
<li>Number check on change</li>
147+
</ul>
148+
<Input {...control} placeholder="validateTrigger" />
149+
<FieldState form={form} name="validateTrigger" />
150+
<Error>{meta.errors}</Error>
151+
</div>
152+
)}
153+
</Field>
154+
155+
<br />
156+
157+
<button
158+
type="button"
159+
onClick={() => {
160+
form.validateFields();
161+
}}
162+
>
163+
Validate All
164+
</button>
165+
166+
<button type="submit">Submit</button>
167+
</React.Fragment>
168+
);
169+
}}
170+
</Form>
171+
</div>
172+
);
173+
};

0 commit comments

Comments
 (0)