Skip to content

Commit c50bb07

Browse files
committed
support valuePropName
1 parent e96f3ed commit c50bb07

File tree

6 files changed

+60
-21
lines changed

6 files changed

+60
-21
lines changed

README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,17 @@ We use typescript to create the Type definition. You can view directly in IDE. B
7373

7474
## Field
7575

76-
| Prop | Description | Type | Default |
77-
| ----------------- | --------------------------------------- | -------------------------------------------- | -------- |
78-
| dependencies | Will re-render if dependencies changed | [NamePath](#namepath)[] | - |
79-
| getValueFromEvent | Specify how to get value from event | (..args: any[]) => any | - |
80-
| name | Field name path | [NamePath](#namepath) | - |
81-
| normalize | Normalize value before update | (value, prevValue, prevValues) => any | - |
82-
| rules | Validate rules | [Rule](#rule)[] | - |
76+
| Prop | Description | Type | Default |
77+
| ----------------- | --------------------------------------- | ----------------------------------------- | -------- |
78+
| dependencies | Will re-render if dependencies changed | [NamePath](#namepath)[] | - |
79+
| getValueFromEvent | Specify how to get value from event | (..args: any[]) => any | - |
80+
| name | Field name path | [NamePath](#namepath) | - |
81+
| normalize | Normalize value before update | (value, prevValue, prevValues) => any | - |
82+
| rules | Validate rules | [Rule](#rule)[] | - |
8383
| shouldUpdate | Check if Field should update | true \| (prevValues, nextValues): boolean | - |
84-
| trigger | Collect value update by event trigger | string | onChange |
85-
| validateTrigger | Config trigger point with rule validate | string \| string[] | onChange |
84+
| trigger | Collect value update by event trigger | string | onChange |
85+
| validateTrigger | Config trigger point with rule validate | string \| string[] | onChange |
86+
| valuePropName | Config value mapping prop with element | string | value |
8687

8788
## List
8889

examples/StateForm-validate-perf.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export default class Demo extends React.Component {
3939
style={{ padding: 16 }}
4040
onFinish={this.onFinish}
4141
validateMessages={myMessages}
42+
initialValues={{ remember: true }}
4243
>
4344
<LabelField name="password" rules={[{ required: true }]}>
4445
<Input placeholder="password" />
@@ -78,9 +79,16 @@ export default class Demo extends React.Component {
7879
<Input />
7980
</LabelField>
8081

82+
<div>
83+
<Field name="remember" valuePropName="checked">
84+
<input type="checkbox" />
85+
</Field>
86+
Remember Me
87+
</div>
88+
8189
<Field shouldUpdate>
8290
{(_, __, { getFieldsError, isFieldsTouched }) => {
83-
const isAllTouched = isFieldsTouched(true);
91+
const isAllTouched = isFieldsTouched(['password', 'password2'], true);
8492
const hasErrors = !!getFieldsError().filter(({ errors }) => errors.length).length;
8593

8694
return (

src/Field.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,8 @@ import {
2727
} from './utils/valueUtil';
2828

2929
interface ChildProps {
30-
value?: StoreValue;
31-
onChange?: (...args: EventArgs) => void;
32-
onFocus?: (...args: EventArgs) => void;
33-
onBlur?: (...args: EventArgs) => void;
30+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
31+
[name: string]: any;
3432
}
3533

3634
export interface FieldProps {
@@ -52,6 +50,7 @@ export interface FieldProps {
5250
| ((prevValues: Store, nextValues: Store, info: { source?: string }) => boolean);
5351
trigger?: string;
5452
validateTrigger?: string | string[] | false;
53+
valuePropName?: string;
5554
}
5655

5756
export interface FieldState {
@@ -65,6 +64,7 @@ class Field extends React.Component<FieldProps, FieldState> implements FieldEnti
6564
public static defaultProps = {
6665
trigger: 'onChange',
6766
validateTrigger: 'onChange',
67+
valuePropName: 'value',
6868
};
6969

7070
public state = {
@@ -328,7 +328,7 @@ class Field extends React.Component<FieldProps, FieldState> implements FieldEnti
328328
};
329329

330330
public getControlled = (childProps: ChildProps = {}) => {
331-
const { trigger, validateTrigger, getValueFromEvent, normalize } = this.props;
331+
const { trigger, validateTrigger, getValueFromEvent, normalize, valuePropName } = this.props;
332332
const namePath = this.getNamePath();
333333
const { getInternalHooks, getFieldsValue }: InternalFormInstance = this.context;
334334
const { dispatch } = getInternalHooks(HOOK_MARK);
@@ -339,15 +339,20 @@ class Field extends React.Component<FieldProps, FieldState> implements FieldEnti
339339

340340
const control = {
341341
...childProps,
342-
value,
342+
[valuePropName]: value,
343343
};
344344

345345
// Add trigger
346346
control[trigger] = (...args: EventArgs) => {
347347
// Mark as touched
348348
this.touched = true;
349349

350-
let newValue = (getValueFromEvent || defaultGetValueFromEvent)(...args);
350+
let newValue;
351+
if (getValueFromEvent) {
352+
newValue = getValueFromEvent(...args);
353+
} else {
354+
newValue = defaultGetValueFromEvent(valuePropName, ...args);
355+
}
351356

352357
if (normalize) {
353358
newValue = normalize(newValue, value, getFieldsValue());

src/useForm.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ export class FormStore {
202202
if (containsNamePath(namePathList, fieldNamePath)) {
203203
return field.isFieldTouched();
204204
}
205-
return false;
205+
return isAllFieldsTouched;
206206
};
207207

208208
return isAllFieldsTouched

src/utils/valueUtil.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,10 @@ export function isSimilar(source: SimilarObject, target: SimilarObject) {
112112
});
113113
}
114114

115-
export function defaultGetValueFromEvent(...args: EventArgs) {
115+
export function defaultGetValueFromEvent(valuePropName: string, ...args: EventArgs) {
116116
const event = args[0];
117-
if (event && event.target && 'value' in event.target) {
118-
return (event.target as HTMLInputElement).value;
117+
if (event && event.target && valuePropName in event.target) {
118+
return (event.target as HTMLInputElement)[valuePropName];
119119
}
120120

121121
return event;

tests/index.test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,31 @@ describe('Basic', () => {
353353
errorSpy.mockRestore();
354354
});
355355

356+
it('valuePropName', async () => {
357+
let form;
358+
const wrapper = mount(
359+
<div>
360+
<Form
361+
ref={instance => {
362+
form = instance;
363+
}}
364+
>
365+
<Field name="check" valuePropName="checked">
366+
<Input type="checkbox" />
367+
</Field>
368+
</Form>
369+
</div>,
370+
);
371+
372+
wrapper.find('input[type="checkbox"]').simulate('change', { target: { checked: true } });
373+
await timeout();
374+
expect(form.getFieldsValue()).toEqual({ check: true });
375+
376+
wrapper.find('input[type="checkbox"]').simulate('change', { target: { checked: false } });
377+
await timeout();
378+
expect(form.getFieldsValue()).toEqual({ check: false });
379+
});
380+
356381
it('shouldUpdate', async () => {
357382
let isAllTouched;
358383
let hasError;

0 commit comments

Comments
 (0)