Skip to content

Commit a59e846

Browse files
committed
feat: test
1 parent a93e68b commit a59e846

4 files changed

Lines changed: 80 additions & 29 deletions

File tree

docs/examples/components/Input.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
import React from 'react';
1+
import React, { InputHTMLAttributes } from 'react';
22

33
const Input = (props: any) => {
44
return <input {...props} />;
55
};
66

7-
const CustomizeInput = ({ value = '', ...props }: any) => (
8-
<div style={{ padding: 10 }}>
7+
const CustomizeInput = ({
8+
value = '',
9+
style,
10+
...props
11+
}: { value?: string } & InputHTMLAttributes<HTMLInputElement>) => (
12+
<div style={{ padding: 10, ...style }}>
913
<Input style={{ outline: 'none' }} value={value} {...props} />
1014
</div>
1115
);

docs/examples/multiple.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,39 @@ import React from 'react';
22
import Form, { Field } from 'rc-field-form';
33
import Input from './components/Input';
44

5+
const RangeInput = ({
6+
value = [],
7+
onChange,
8+
}: {
9+
value?: string[];
10+
onChange?: (value: string[]) => void;
11+
}) => {
12+
const [one, two] = value;
13+
14+
return (
15+
<div style={{ display: 'flex' }}>
16+
<Input style={{ padding: 0 }} value={one} onChange={e => onChange([e.target.value, two])} />
17+
<Input style={{ padding: 0 }} value={two} onChange={e => onChange([one, e.target.value])} />
18+
</div>
19+
);
20+
};
21+
type FieldType = { one?: string; two?: string };
22+
523
export default () => {
624
const [form] = Form.useForm();
725
return (
826
<>
927
<Form
1028
form={form}
11-
initialValues={{ range: 'aa' }}
29+
initialValues={{ one: '11', two: '22' }}
1230
onFinish={v => console.log('submit values', v)}
1331
>
14-
<Field name="range">
15-
<Input />
32+
<Field<FieldType> names={['one', 'two']}>
33+
<RangeInput />
1634
</Field>
35+
{/* <Field<FieldType> name="two">
36+
<Input />
37+
</Field> */}
1738
<button type="submit">submit</button>
1839
</Form>
1940
<button

src/Field.tsx

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export interface InternalFieldProps<Values = any> {
6969
dependencies?: NamePath[];
7070
getValueFromEvent?: (...args: EventArgs) => StoreValue;
7171
name?: InternalNamePath;
72+
names?: InternalNamePath[];
7273
normalize?: (value: StoreValue, prevValue: StoreValue, allValues: Store) => StoreValue;
7374
rules?: Rule[];
7475
shouldUpdate?: ShouldUpdate<Values>;
@@ -99,8 +100,9 @@ export interface InternalFieldProps<Values = any> {
99100
}
100101

101102
export interface FieldProps<Values = any>
102-
extends Omit<InternalFieldProps<Values>, 'name' | 'fieldContext'> {
103+
extends Omit<InternalFieldProps<Values>, 'name' | 'names' | 'fieldContext'> {
103104
name?: NamePath<Values>;
105+
names?: NamePath<Values>[];
104106
}
105107

106108
export interface FieldState {
@@ -194,11 +196,24 @@ class Field extends React.Component<InternalFieldProps, FieldState> implements F
194196
};
195197

196198
// ================================== Utils ==================================
197-
public getNamePath = (): InternalNamePath => {
198-
const { name, fieldContext } = this.props;
199+
public getNamePath = (name?: InternalNamePath): InternalNamePath => {
200+
const { name: propsName, fieldContext } = this.props;
201+
const _name = name ?? propsName;
202+
203+
const { prefixName = [] }: InternalFormInstance = fieldContext;
204+
205+
return _name !== undefined ? [...prefixName, ..._name] : [];
206+
};
207+
208+
public getNamesPath = (): InternalNamePath | InternalNamePath[] => {
209+
const { name, names, fieldContext } = this.props;
210+
199211
const { prefixName = [] }: InternalFormInstance = fieldContext;
212+
if (name) {
213+
return name !== undefined ? [...prefixName, ...name] : [];
214+
}
200215

201-
return name !== undefined ? [...prefixName, ...name] : [];
216+
return names !== undefined ? names.map(name => [...prefixName, ...name]) : [];
202217
};
203218

204219
public getRules = (): RuleObject[] => {
@@ -554,9 +569,15 @@ class Field extends React.Component<InternalFieldProps, FieldState> implements F
554569

555570
// ============================== Field Control ==============================
556571
public getValue = (store?: Store) => {
572+
const { names } = this.props;
557573
const { getFieldsValue }: FormInstance = this.props.fieldContext;
558-
const namePath = this.getNamePath();
559-
return getValue(store || getFieldsValue(true), namePath);
574+
if (names) {
575+
const namesValue = names.map(name => {
576+
return getValue(store || getFieldsValue(true), this.getNamePath(name));
577+
});
578+
return namesValue;
579+
}
580+
return getValue(store || getFieldsValue(true), this.getNamePath());
560581
};
561582

562583
public getControlled = (childProps: ChildProps = {}) => {
@@ -573,7 +594,7 @@ class Field extends React.Component<InternalFieldProps, FieldState> implements F
573594
const mergedValidateTrigger =
574595
validateTrigger !== undefined ? validateTrigger : fieldContext.validateTrigger;
575596

576-
const namePath = this.getNamePath();
597+
const namesPath = this.getNamesPath();
577598
const { getInternalHooks, getFieldsValue }: InternalFormInstance = fieldContext;
578599
const { dispatch } = getInternalHooks(HOOK_MARK);
579600
const value = this.getValue();
@@ -593,7 +614,6 @@ class Field extends React.Component<InternalFieldProps, FieldState> implements F
593614
);
594615
});
595616
}
596-
597617
const control = {
598618
...childProps,
599619
...valueProps,
@@ -617,11 +637,12 @@ class Field extends React.Component<InternalFieldProps, FieldState> implements F
617637
if (normalize) {
618638
newValue = normalize(newValue, value, getFieldsValue(true));
619639
}
620-
621-
dispatch({
622-
type: 'updateValue',
623-
namePath,
624-
value: newValue,
640+
namesPath.forEach((name, index) => {
641+
dispatch({
642+
type: 'updateValue',
643+
namePath: this.getNamePath(name),
644+
value: newValue[index],
645+
});
625646
});
626647

627648
if (originTriggerFunc) {
@@ -645,10 +666,12 @@ class Field extends React.Component<InternalFieldProps, FieldState> implements F
645666
if (rules && rules.length) {
646667
// We dispatch validate to root,
647668
// since it will update related data with other field with same name
648-
dispatch({
649-
type: 'validateField',
650-
namePath,
651-
triggerName,
669+
namesPath.forEach(name => {
670+
dispatch({
671+
type: 'validateField',
672+
namePath: this.getNamePath(name),
673+
triggerName,
674+
});
652675
});
653676
}
654677
};
@@ -681,14 +704,15 @@ class Field extends React.Component<InternalFieldProps, FieldState> implements F
681704
}
682705
}
683706

684-
function WrapperField<Values = any>({ name, ...restProps }: FieldProps<Values>) {
707+
function WrapperField<Values = any>({ name, names, ...restProps }: FieldProps<Values>) {
685708
const fieldContext = React.useContext(FieldContext);
686709
const listContext = React.useContext(ListContext);
687710
const namePath = name !== undefined ? getNamePath(name) : undefined;
711+
const namesPath = names !== undefined ? names.map(name => getNamePath(name)) : undefined;
688712

689713
let key: string = 'keep';
690714
if (!restProps.isListField) {
691-
key = `_${(namePath || []).join('_')}`;
715+
key = `_${(namePath || namesPath || []).join('_')}`;
692716
}
693717

694718
// Warning if it's a directly list field.
@@ -697,7 +721,7 @@ function WrapperField<Values = any>({ name, ...restProps }: FieldProps<Values>)
697721
process.env.NODE_ENV !== 'production' &&
698722
restProps.preserve === false &&
699723
restProps.isListField &&
700-
namePath.length <= 1
724+
(namePath.length <= 1 || namesPath.length <= 1)
701725
) {
702726
warning(false, '`preserve` should not apply on Form.List fields.');
703727
}
@@ -706,6 +730,7 @@ function WrapperField<Values = any>({ name, ...restProps }: FieldProps<Values>)
706730
<Field
707731
key={key}
708732
name={namePath}
733+
names={namesPath}
709734
isListField={!!listContext}
710735
{...restProps}
711736
fieldContext={fieldContext}

src/interface.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ export interface FieldEntity {
105105
isPreserve: () => boolean;
106106
validateRules: (options?: InternalValidateOptions) => Promise<RuleError[]>;
107107
getMeta: () => Meta;
108-
getNamePath: () => InternalNamePath;
108+
getNamePath: (name?: InternalNamePath) => InternalNamePath;
109+
getNamesPath: () => InternalNamePath | InternalNamePath[];
109110
getErrors: () => string[];
110111
getWarnings: () => string[];
111112
props: {
@@ -240,8 +241,8 @@ type RecursivePartial<T> = NonNullable<T> extends object
240241
[P in keyof T]?: NonNullable<T[P]> extends (infer U)[]
241242
? RecursivePartial<U>[]
242243
: NonNullable<T[P]> extends object
243-
? RecursivePartial<T[P]>
244-
: T[P];
244+
? RecursivePartial<T[P]>
245+
: T[P];
245246
}
246247
: T;
247248

0 commit comments

Comments
 (0)