Skip to content

Commit 324d0f5

Browse files
fireairforcezoomdong
andauthored
feat: add() support index param (#177)
* feat: add support add random index formItem * adjust case * feat: add warning * warning set * add devWarning test case Co-authored-by: zoomdong <[email protected]>
1 parent a966e7b commit 324d0f5

File tree

2 files changed

+122
-6
lines changed

2 files changed

+122
-6
lines changed

src/List.tsx

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ interface ListField {
1212
}
1313

1414
interface ListOperations {
15-
add: (defaultValue?: StoreValue) => void;
15+
add: (defaultValue?: StoreValue, index?: number) => void;
1616
remove: (index: number | number[]) => void;
1717
move: (from: number, to: number) => void;
1818
}
@@ -59,13 +59,31 @@ const List: React.FunctionComponent<ListProps> = ({ name, children }) => {
5959
* Always get latest value in case user update fields by `form` api.
6060
*/
6161
const operations: ListOperations = {
62-
add: defaultValue => {
62+
add: (defaultValue, index?: number) => {
6363
// Mapping keys
64-
keyManager.keys = [...keyManager.keys, keyManager.id];
65-
keyManager.id += 1;
66-
6764
const newValue = getNewValue();
68-
onChange([...newValue, defaultValue]);
65+
66+
if (index >= 0 && index <= newValue.length) {
67+
keyManager.keys = [
68+
...keyManager.keys.slice(0, index),
69+
keyManager.id,
70+
...keyManager.keys.slice(index),
71+
];
72+
onChange([...newValue.slice(0, index), defaultValue, ...newValue.slice(index)]);
73+
} else {
74+
if (
75+
process.env.NODE_ENV !== 'production' &&
76+
(index < 0 || index > newValue.length)
77+
) {
78+
warning(
79+
false,
80+
'The second parameter of the add function should be a valid positive number.',
81+
);
82+
}
83+
keyManager.keys = [...keyManager.keys, keyManager.id];
84+
onChange([...newValue, defaultValue]);
85+
}
86+
keyManager.id += 1;
6987
},
7088
remove: (index: number | number[]) => {
7189
const newValue = getNewValue();

tests/list.test.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,58 @@ describe('Form.List', () => {
321321
matchKey(0, '3');
322322
});
323323

324+
it('add when the second param is number', () => {
325+
let operation;
326+
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
327+
const [wrapper, getList] = generateForm((fields, opt) => {
328+
operation = opt;
329+
return (
330+
<div>
331+
{fields.map(field => (
332+
<Field {...field}>
333+
<Input />
334+
</Field>
335+
))}
336+
</div>
337+
);
338+
});
339+
340+
act(() => {
341+
operation.add();
342+
});
343+
act(() => {
344+
operation.add('1', 2);
345+
});
346+
347+
act(() => {
348+
operation.add('2', -1);
349+
});
350+
351+
expect(errorSpy).toHaveBeenCalledWith(
352+
'Warning: The second parameter of the add function should be a valid positive number.',
353+
);
354+
errorSpy.mockRestore();
355+
356+
wrapper.update();
357+
expect(getList().find(Field).length).toEqual(3);
358+
expect(form.getFieldsValue()).toEqual({
359+
list: [undefined, '1', '2'],
360+
});
361+
362+
act(() => {
363+
operation.add('0', 0);
364+
});
365+
act(() => {
366+
operation.add('4', 3);
367+
});
368+
369+
wrapper.update();
370+
expect(getList().find(Field).length).toEqual(5);
371+
expect(form.getFieldsValue()).toEqual({
372+
list: ['0', undefined, '1', '4', '2'],
373+
});
374+
});
375+
324376
describe('validate', () => {
325377
it('basic', async () => {
326378
const [, getList] = generateForm(
@@ -417,6 +469,52 @@ describe('Form.List', () => {
417469
expect(form.getFieldError(['list', 0])).toEqual(["'list.1' must be at least 5 characters"]);
418470
expect(wrapper.find('input').props().value).toEqual('test');
419471
});
472+
473+
it('when add() second param is number', async () => {
474+
const [wrapper, getList] = generateForm(
475+
(fields, { add }) => (
476+
<div>
477+
{fields.map(field => (
478+
<Field {...field} rules={[{ required: true }, { min: 5 }]}>
479+
<Input />
480+
</Field>
481+
))}
482+
483+
<button
484+
className="button"
485+
type="button"
486+
onClick={() => {
487+
add('test4', 1);
488+
}}
489+
/>
490+
491+
<button
492+
className="button1"
493+
type="button"
494+
onClick={() => {
495+
add('test5', 0);
496+
}}
497+
/>
498+
</div>
499+
),
500+
{
501+
initialValues: { list: ['test1', 'test2', 'test3'] },
502+
},
503+
);
504+
505+
expect(wrapper.find(Input)).toHaveLength(3);
506+
await changeValue(getField(getList(), 0), '');
507+
expect(form.getFieldError(['list', 0])).toEqual(["'list.0' is required"]);
508+
509+
wrapper.find('.button').simulate('click');
510+
wrapper.find('.button1').simulate('click');
511+
512+
expect(wrapper.find(Input)).toHaveLength(5);
513+
expect(form.getFieldError(['list', 1])).toEqual(["'list.0' is required"]);
514+
515+
await changeValue(getField(getList(), 1), 'test');
516+
expect(form.getFieldError(['list', 1])).toEqual(["'list.1' must be at least 5 characters"]);
517+
});
420518
});
421519

422520
it('warning if children is not function', () => {

0 commit comments

Comments
 (0)