소스 검색

test: add e2e test

pointhalo 2 년 전
부모
커밋
5f805fed49

+ 59 - 25
cypress/integration/form.spec.js

@@ -50,7 +50,6 @@ describe('Form', () => {
         // cy.get('body').find('.semi-popover .semi-datepicker').should('have.length', 0);
     });
 
-
     it('Basic usage - add withInitValue row、add blank row', () => {
         cy.visit('http://127.0.0.1:6006/iframe.html?path=/story/form--basic-array-field-demo');
 
@@ -610,51 +609,86 @@ describe('Form', () => {
         cy.get('#data-1-rule-0-desc').should('have.value', `1-0-desc`);
     });
 
-    // it('2 Nested ArrayField - formApi.setValues', () => { });
-    // it('Sync setValues - modify', () => { });
-    // it('Sync setValues - add', () => { });
-    // it('Sync setValues - remove', () => { });
-    // it('Async setValues', () => { });
+    // // it('2 Nested ArrayField - formApi.setValues', () => { });
 
-    it('sync setValues - modify value, 2 -> 2', () => {
-    });
+    // // it('Async setValues', () => { });
 
-    it('sync setValues - add, 2 -> 3, add tail', () => {
-    });
+    // it('sync setValues - modify value, 2 -> 2', () => {
 
-    it('sync setValues - add, 2 -> 3, add first', () => {
+    // });
+
+    // it('sync setValues - add, 2 -> 3, add tail', () => {
+    // });
+
+    // it('sync setValues - add, 2 -> 3, add first', () => {
        
-    });
+    // });
 
-    it('sync setValues - add, 2 -> 3, add middle', () => {
+    // it('sync setValues - add, 2 -> 3, add middle', () => {
     
-    });
+    // });
 
-    it('sync setValues - remove, 3 -> 2, remove first', () => {
+    // it('sync setValues - remove, 3 -> 2, remove first', () => {
        
-    });
+    // });
 
-    it('sync setValues - remove, 3 -> 2, remove middle', () => {
+    // it('sync setValues - remove, 3 -> 2, remove middle', () => {
        
-    });
+    // });
 
-    it('sync setValues - remove, 3 -> 2, remove tail', () => {
+    // it('sync setValues - remove, 3 -> 2, remove tail', () => {
        
-    });
+    // });
 
-    it('sync setValues - remove, 2 -> 0, remove all', () => {
+    // it('sync setValues - remove, 2 -> 0, remove all', () => {
        
-    });
+    // });
 
 
     it('Init - Form Props initValues、ArrayField initValue、Field initValue', () => { 
         // 一个 Form 三个 ArrayField
-        
-    });
+        cy.visit('http://127.0.0.1:6006/iframe.html?path=/story/form--init-demo');
 
-    // it('Init - combine', () => {});
+        // Form Props initValues
+        cy.get('#data-0-name').should('have.value', `${D2C.name}`);
+        cy.get('#data-0-role').should('have.value', `${D2C.role}`);
+        cy.get('#data-1-name').should('have.value', `${C2D.name}`);
+        cy.get('#data-1-role').should('have.value', `${C2D.role}`);
+        cy.get('#dataAddWithInit').click();
+        cy.get('#data-2-name').should('have.value', 'Data-3');
+        cy.get('#data-2-role').should('have.value', 'Designer');
 
 
+        // ArrayField Props initValue
+        cy.get('#dataB-0-name').should('have.value', 'NameInArrayFieldProp');
+        cy.get('#dataB-0-role').should('have.value', 'RoleInArrayFieldProp');
+        cy.get('#dataB-1-name').should('not.exist');
+        cy.get('#dataB-1-role').should('not.exist');
+        cy.get('#dataBAddWithInit').click();
+        cy.get('#dataB-1-name').should('have.value', 'DataB-2');
+        cy.get('#dataB-1-role').should('have.value', 'Designer');
+
+        // Field Props initValue
+        cy.get('#dataCAddWithInit').click();
+        cy.get('#dataC-0-name').should('have.value', 'DataC-1');
+        cy.get('#dataC-0-role').should('have.value', 'Designer');
+        cy.get('#dataCAdd').click();
+        // if add empty, should use field props
+        // TODO
+    });
+
+    it('Init - combine, test priority', () => {
+        cy.visit('http://127.0.0.1:6006/iframe.html?path=/story/form--init-combine-demo');
+        // FormProps + ArrayField Props, should use ArrayField Props first
+        cy.get('#data-0-name').should('have.value', 'NameInArrayFieldProp');
+        cy.get('#data-0-role').should('have.value', 'RoleInArrayFieldProp');
+
+        // ArrayField Props + Field Props, should use FieldProps first
+        cy.get('#dataB-0-name').should('have.value', 'NameInFieldProp');
+        cy.get('#dataB-0-role').should('have.value', 'RoleInFieldProp');
+    });
 
+    // it('Init - Nested', () => {
 
+    // });
 });

+ 115 - 0
packages/semi-ui/form/_story/ArrayField/10-initCombineUsage.jsx

@@ -0,0 +1,115 @@
+import React, { useState, useRef } from 'react';
+import { Form, Col, Row, Button, ArrayField, Space, useFormState } from '@douyinfe/semi-ui';
+import { IconMinusCircle, IconPlusCircle } from '@douyinfe/semi-icons';
+
+import { JSONTree } from 'react-json-tree';
+
+const FormStateTree = () => {
+    const formState = useFormState();
+    return (
+        <JSONTree
+            shouldExpandNodeInitially={() => true}
+            hideRoot
+            data={formState}
+        />
+    );
+};
+
+function InitCombineDemo() {
+    const formRef = useRef();
+
+    return (
+        <Form ref={formRef} initValues={{
+            data: [
+                { name: 'NameInFormProp', role: 'RoleInFormProp' },
+            ]
+        }}>
+            <div>
+                <Button htmlType='reset'>Reset</Button>
+            </div>
+            {/* <ArrayField field="data"
+                initValue={[{ name: 'NameInArrayFieldProp', role: 'RoleInArrayFieldProp' }]}
+            >
+                {({ add, addWithInitValue, arrayFields }) => (
+                    <React.Fragment>
+                        <Space>
+                            <Button id='dataAdd' onClick={add} icon={<IconPlusCircle />} type="primary">Add</Button>
+                            <Button
+                                id='dataAddWithInit'
+                                onClick={() => addWithInitValue({ name: `Data-${arrayFields.length + 1}`, role: 'Designer' })}
+                                icon={<IconPlusCircle />}
+                                type="primary">
+                                Add with row initValue
+                            </Button>
+                        </Space>
+                        {
+                            arrayFields.map(({ field, key, remove }, i) => (
+                                <div key={key} style={{ display: 'flex', width: 600 }} id={`data-${i}`} className='line'>
+                                    <Space>
+                                        <Form.Input
+                                            id={`data-${i}-name`}
+                                            field={`${field}[name]`}
+                                            label={`${field}.name`}
+                                            style={{ width: 200 }}
+                                        />
+                                        <Form.Input
+                                            id={`data-${i}-role`}
+                                            field={`${field}[role]`}
+                                            label={`${field}.role`}
+                                            style={{ width: 200 }}
+                                        />
+                                    </Space>
+                                    <Button style={{ margin: "36px 0 0 12px" }} type="danger" icon={<IconMinusCircle/>} onClick={remove}>remove this line</Button>
+                                </div>
+                            ))
+                        }
+                    </React.Fragment>
+                )}
+            </ArrayField> */}
+            <ArrayField field="dataB" initValue={[{ name: 'NameInArrayFieldProp', role: 'RoleInArrayFieldProp' }]}>
+                {({ add, addWithInitValue, arrayFields }) => (
+                    <React.Fragment>
+                        <Space>
+                            <Button id='dataBAdd' onClick={add} icon={<IconPlusCircle />} type="primary">Add</Button>
+                            <Button
+                                id='dataBAddWithInit'
+                                onClick={() => addWithInitValue({ name: `Data-${arrayFields.length + 1}`, role: 'Designer' })}
+                                icon={<IconPlusCircle />}
+                                type="primary">
+                                Add with row initValue
+                            </Button>
+                        </Space>
+                        {
+                            arrayFields.map(({ field, key, remove }, i) => (
+                                <div key={key} style={{ display: 'flex', width: 600 }} id={`dataB-${i}`} className='line'>
+                                    <Space>
+                                        <Form.Input
+                                            id={`dataB-${i}-name`}
+                                            field={`${field}[name]`}
+                                            label={`${field}.name`}
+                                            style={{ width: 200 }}
+                                            initValue={'NameInFieldProp'}
+                                        />
+                                        <Form.Input
+                                            id={`dataB-${i}-role`}
+                                            field={`${field}[role]`}
+                                            label={`${field}.role`}
+                                            style={{ width: 200 }}
+                                            initValue={'RoleInFieldProp'}
+                                        />
+                                    </Space>
+                                    <Button style={{ margin: "36px 0 0 12px" }} type="danger" icon={<IconMinusCircle/>} onClick={remove}>remove this line</Button>
+                                </div>
+                            ))
+                        }
+                    </React.Fragment>
+                )}
+            </ArrayField>
+            <FormStateTree></FormStateTree>
+        </Form>
+    );
+}
+
+InitCombineDemo.storyName = 'ArrayField-init combine';
+
+export default InitCombineDemo;

+ 180 - 0
packages/semi-ui/form/_story/ArrayField/11-initNestedUsage.jsx

@@ -0,0 +1,180 @@
+import React, { useState, useRef } from 'react';
+import { Form, Col, Row, Button, ArrayField, Space, useFormState } from '@douyinfe/semi-ui';
+import { IconMinusCircle, IconPlusCircle, IconRefresh } from '@douyinfe/semi-icons';
+import { JSONTree } from 'react-json-tree';
+
+const FormStateTree = () => {
+    const formState = useFormState();
+    return (
+        <JSONTree
+            shouldExpandNodeInitially={() => true}
+            hideRoot
+            data={formState}
+        />
+    );
+};
+
+const NestDemo = () => {
+    const formRef = useRef();
+
+    const getFormApi = () => {
+        const formApi = formRef.current.formApi;  
+        return formApi;
+    };
+
+    const formInitValues = {
+        data: [
+            {
+                name: '0',
+                rules: [
+                    { desc: '0-0-desc', type: '0-0-type' },
+                    { desc: '0-1-desc', type: '0-1-type' },
+                ],
+            },
+            {
+                name: '1',
+                rules: [
+                    { desc: '1-0-desc', type: '1-0-type' }
+                ],
+            }
+        ]
+    };
+
+    // const setValueChangeOutSide = () => {
+    //     const formApi = getFormApi();
+    //     formApi.setValue('data', [
+    //         {
+    //             name: 'new-0',
+    //             rules: [
+    //                 { desc: 'new-0-0-desc', type: 'new-0-0-type' },
+    //                 { desc: 'new-0-1-desc', type: 'new-0-1-type' },
+    //             ],
+    //         },
+    //         {
+    //             name: 'new-1',
+    //             rules: [
+    //                 { desc: 'new-1-0-desc', type: 'new-1-0-type' },
+    //             ],
+    //         },
+    //         {
+    //             name: 'new-2',
+    //             rules: [
+    //                 { desc: 'new-2-0-desc', type: 'new-2-0-type' },
+    //                 { desc: 'new-2-1-desc', type: 'new-2-1-type' },
+    //                 { desc: 'new-2-2-desc', type: 'new-2-2-type' },
+    //             ],
+    //         }
+    //     ]);
+    // };
+
+    // const setValueChangeInside = () => {
+    //     const formApi = getFormApi();
+    //     formApi.setValue('data[0].rules', [{ desc: 'new-0-0-desc-in', type: 'new-0-0-type-in' }]);
+    // };
+
+    // const setValueChangeRow = () => {
+    //     const formApi = getFormApi();
+    //     formApi.setValue('data[0].rules[0]', { type: 'special-row-type', desc: 'special-row-desc' });
+    // };
+    
+    return (
+        <Form
+            ref={formRef}
+            initValues={formInitValues}
+            labelPosition='inset'
+        >
+            <ArrayField field='data'>
+                {({ add, arrayFields, addWithInitValue }) => (
+                    <React.Fragment>
+                        <Space>
+                            <Button htmlType='reset' theme='solid' type='secondary' icon={<IconRefresh />}>Reset</Button>
+                            {/* <Button id='changeOutSide' theme='solid' type='primary' onClick={() => setValueChangeOutSide()}>ChangeOutSide</Button>
+                            <Button id='changeInside' theme='solid' type='tertiary' onClick={() => setValueChangeInside()}>ChangeInsideSide</Button>
+                            <Button id='changeRow' theme='solid' type='tertiary' onClick={() => setValueChangeRow()}>ChangeSpecialRow</Button> */}
+                        </Space>
+                        {
+                            arrayFields.map(({ field, key, remove }, i) => (
+                                <div key={key} style={{ width: 1000, display: 'flex', flexWrap: 'wrap' }} id={`data-${i}`} className='line'>
+                                    {key.slice(0, 10)}
+                                    <Space>
+                                        <Form.Input
+                                            field={`${field}.name`}
+                                            label={`${field}.name`}
+                                            style={{ width: 700 }}
+                                            id={`data-${i}-name`}
+                                        >
+                                        </Form.Input>
+                                        <Button
+                                            onClick={() => addWithInitValue({
+                                                name: arrayFields.length,
+                                                rules: [
+                                                    { desc: `${arrayFields.length}-0-desc`, type: `${arrayFields.length}-0-type` }
+                                                ]
+                                            })}
+                                            icon={<IconPlusCircle/>}
+                                            id={`data-${i}-add`} 
+                                            disabled={i !== arrayFields.length - 1}
+                                        />
+                                        <Button
+                                            type='danger'
+                                            onClick={remove}
+                                            id={`data-${i}-remove`} 
+                                            icon={<IconMinusCircle />}
+                                        />
+                                    </Space>
+                           
+                                    <ArrayField field={`${field}.rules`}>
+                                        {({ add: addNested, arrayFields: nestedArrayFields, addWithInitValue: addNestedWithInitValue }, ) => (
+                                            <React.Fragment>
+                                                {
+                                                    nestedArrayFields.map(({ field: f, key: k, remove: r }, n) => (
+                                                        <section className='rules' key={k} style={{ display: 'flex', flexWrap: 'wrap', marginLeft: 36 }}>
+                                                            <Space>
+                                                                {k.slice(0, 10)}
+                                                                <Form.Input
+                                                                    style={{ width: 300, marginRight: 12 }}
+                                                                    field={`${f}.type`}
+                                                                    label={`${f}.type`}
+                                                                    id={`data-${i}-rule-${n}-type`} 
+                                                                />
+                                                                <Form.Input
+                                                                    style={{ width: 300 }}
+                                                                    field={`${f}.desc`}
+                                                                    label={`${f}.desc`}
+                                                                    id={`data-${i}-rule-${n}-desc`} 
+                                                                />
+                                                                <Button
+                                                                    onClick={() => addNestedWithInitValue({ type: `${i}-${n+1}-type`, desc: `${i}-${n+1}-desc` })}
+                                                                    icon={<IconPlusCircle/>}
+                                                                    id={`data-${i}-rule-${n}-add`}
+                                                                    disabled={n !== nestedArrayFields.length - 1}
+                                                                >
+                                                                    add new line
+                                                                </Button>
+                                                                <Button
+                                                                    type='danger'
+                                                                    onClick={r}
+                                                                    id={`data-${i}-rule-${n}-remove`} 
+                                                                    icon={<IconMinusCircle />}
+                                                                />
+                                                            </Space>
+                                                        </section>
+                                                    ))
+                                                }
+                                            </React.Fragment>
+                                        )}
+                                    </ArrayField>
+                                </div>
+                            ))
+                        }
+                    </React.Fragment>
+                )}
+            </ArrayField>
+            <FormStateTree></FormStateTree>
+        </Form>
+    );
+};
+
+NestDemo.storyName = 'ArrayField-Nested init value';
+
+export default NestDemo;

+ 122 - 120
packages/semi-ui/form/_story/ArrayField/7-manualSyncBatchSetUsage.jsx

@@ -26,165 +26,167 @@ const FormStateTree = () => {
     );
 };
 
-const SetValues = () => {
+function SetValues() {
     const formRef = useRef();
+    const formInitValues = {
+        data: [
+            { name: 'Semi D2C', role: 'Engineer' },
+            { name: 'Semi C2D', role: 'Designer' },
+            // { name: 'Semi DSM', role: 'Designer' },
+        ]
+    };
 
     const getFormApi = () => {
         const formApi = formRef.current.formApi;  
         return formApi;
     };
 
-    const formInitValues = {
-        data: [
-            {
-                name: '0',
-                rules: [
-                    { desc: '0-0-desc', type: '0-0-type' },
-                    { desc: '0-1-desc', type: '0-1-type' },
-                ],
-            },
-            {
-                name: '1',
-                rules: [
-                    { desc: '1-0-desc', type: '1-0-type' }
-                ],
-            }
-        ]
+    const setValuesAsync = () => {
+        const formApi = getFormApi();
+        // setTimeout(() => {
+        formApi.setValues({
+            data: [
+                { name: 'Semi D2C-0', role: 'Engineer-0' },
+                { name: 'Semi C2D-1', role: 'Designer' },
+            ]
+        }, { isOverride: true });
+        // }, 200);
+    };
+
+    const removeHeadAsync = () => {
+        const formApi = getFormApi();
+        // setTimeout(() => {
+        formApi.setValues({ data: [
+            { name: 'Semi C2D', role: 'Designer' },
+            { name: 'Semi DSM', role: 'Designer' },
+        ] }, { isOverride: true });
+        // }, 200);
+
+    };
+
+    const removeTailAsync = () => {
+        const formApi = getFormApi();
+        // setTimeout(() => {
+        formApi.setValues({ data: [
+            { name: 'Semi D2C', role: 'Engineer' },
+            { name: 'Semi C2D', role: 'Designer' },
+        ] }, { isOverride: true });
+        // }, 200);
+    };
+
+    const removeMiddleAsync = () => {
+        const formApi = getFormApi();
+        // setTimeout(() => {
+        formApi.setValues({ data: [
+            { name: 'Semi D2C', role: 'Engineer' },
+            { name: 'Semi DSM', role: 'Designer' },
+        ] }, { isOverride: true });
+        // }, 200);
+
+    };
+
+    const removeAllAsync = () => {
+        const formApi = getFormApi();
+        // setTimeout(() => {
+        formApi.setValues({}, { isOverride: true });
+        // }, 200);
+
     };
 
-    const setValueChangeOutSide = () => {
+    const addHeadAsync = () => {
         const formApi = getFormApi();
-        formApi.setValue('data', [
-            {
-                name: 'new-0',
-                rules: [
-                    { desc: 'new-0-0-desc', type: 'new-0-0-type' },
-                    { desc: 'new-0-1-desc', type: 'new-0-1-type' },
-                ],
-            },
-            {
-                name: 'new-1',
-                rules: [
-                    { desc: 'new-1-0-desc', type: 'new-1-0-type' },
-                ],
-            },
-            {
-                name: 'new-2',
-                rules: [
-                    { desc: 'new-2-0-desc', type: 'new-2-0-type' },
-                    { desc: 'new-2-1-desc', type: 'new-2-1-type' },
-                    { desc: 'new-2-2-desc', type: 'new-2-2-type' },
-                ],
-            }
-        ]);
+        // setTimeout(() => {
+        formApi.setValues({ data: [
+            { name: 'Semi DSM', role: 'Designer' },
+            { name: 'Semi D2C', role: 'Engineer' },
+            { name: 'Semi C2D', role: 'Designer' },
+        ] }, { isOverride: true });
+        // }, 200);
     };
 
-    const setValueChangeInside = () => {
+    const addMiddleAsync = () => {
         const formApi = getFormApi();
-        // formApi.setValue('data[0].rules', [{ desc: 'new-0-0-desc-in', type: 'new-0-0-type-in' }]);
+        // setTimeout(() => {
+        formApi.setValues({ data: [
+            { name: 'Semi D2C', role: 'Engineer' },
+            { name: 'Semi DSM', role: 'Designer' },
+            { name: 'Semi C2D', role: 'Designer' },
+        ] }, { isOverride: true });
+        // }, 200);
     };
 
-    const setValueChangeRow = () => {
+    const addTailAsync = () => {
         const formApi = getFormApi();
-        // formApi.setValue('data[0].rules[0]', { name: 'special-row-name', rules: [{ desc: 'abc', type: 'efg' }] });
+        // setTimeout(() => {
+        formApi.setValues({ data: [
+            { name: 'Semi D2C', role: 'Engineer' },
+            { name: 'Semi C2D', role: 'Designer' },
+            { name: 'Semi DSM', role: 'Designer' },
+        ] }, { isOverride: true });
+        // }, 200);
     };
+
     
     return (
-        <Form
-            ref={formRef}
-            initValues={formInitValues}
-            labelPosition='inset'
-        >
-            <ArrayField field='data'>
-                {({ add, arrayFields, addWithInitValue }) => (
+        <Form ref={formRef} initValues={formInitValues}>
+            <div>
+                <Space>
+                    <Button id='updateAsync' onClick={setValuesAsync}>setValuesAsync</Button>
+                    <Button id='addHeadAsync' onClick={addHeadAsync}>addHeadAsync</Button>
+                    <Button id='addMiddleAsync' onClick={addMiddleAsync}>addMiddleAsync</Button>
+                    <Button id='addTailAsync' onClick={addTailAsync}>addTailAsync</Button>
+                </Space>
+            </div>
+            <div style={{ marginTop: 12, marginBottom: 12 }}>
+                <Space>
+                    <Button id='removeHeadAsync' onClick={removeHeadAsync} icon={<IconMinusCircle />} type='danger'>removeHeadAsync</Button>
+                    <Button id='removeTailAsync' onClick={removeTailAsync} icon={<IconMinusCircle />} type='danger'>removeTailAsync</Button>
+                    <Button id='removeMiddleAsync' onClick={removeMiddleAsync} icon={<IconMinusCircle />} type='danger'>removeMiddleAsync</Button>
+                    <Button id='removeAllAsync' onClick={removeAllAsync} icon={<IconMinusCircle />} type='danger'>removeAllAsync</Button>
+                </Space>
+            </div>
+            <ArrayField field="data">
+                {({ add, addWithInitValue, arrayFields }) => (
                     <React.Fragment>
                         <Space>
-                            <Button htmlType='reset' theme='solid' type='secondary' icon={<IconRefresh />}>Reset</Button>
-                            <Button id='changeOutSide' theme='solid' type='primary' onClick={() => setValueChangeOutSide()}>ChangeOutSide</Button>
-                            <Button id='changeInside' theme='solid' type='tertiary' onClick={() => setValueChangeInside()}>ChangeInsideSide</Button>
+                            <Button id='add' onClick={add} icon={<IconPlusCircle />} type="primary">Add</Button>
+                            <Button
+                                id='addWithInit'
+                                onClick={() => addWithInitValue({ name: `Semi New-${arrayFields.length + 1}`, role: 'Designer' })}
+                                icon={<IconPlusCircle />}
+                                type="primary">
+                                Add with row initValue
+                            </Button>
                         </Space>
                         {
                             arrayFields.map(({ field, key, remove }, i) => (
-                                <div key={key} style={{ width: 1000, display: 'flex', flexWrap: 'wrap' }} id={`data-${i}`} className='line'>
-                                    {key.slice(0, 10)}
+                                <div key={key} style={{ display: 'flex', width: 600 }} id={`data-${i}`} className='line'>
                                     <Space>
                                         <Form.Input
-                                            field={`${field}.name`}
-                                            label={`${field}.name`}
-                                            style={{ width: 700 }}
                                             id={`data-${i}-name`}
-                                        >
-                                        </Form.Input>
-                                        <Button
-                                            onClick={() => addWithInitValue({
-                                                name: arrayFields.length,
-                                                rules: [
-                                                    { desc: `${arrayFields.length}-0-desc`, type: `${arrayFields.length}-0-type` }
-                                                ]
-                                            })}
-                                            icon={<IconPlusCircle/>}
-                                            id={`data-${i}-add`} 
-                                            disabled={i !== arrayFields.length - 1}
+                                            field={`${field}[name]`}
+                                            label={`${field}.name`}
+                                            style={{ width: 200 }}
                                         />
-                                        <Button
-                                            type='danger'
-                                            onClick={remove}
-                                            id={`data-${i}-remove`} 
-                                            icon={<IconMinusCircle />}
+                                        <Form.Input
+                                            id={`data-${i}-role`}
+                                            field={`${field}[role]`}
+                                            label={`${field}.role`}
+                                            style={{ width: 200 }}
                                         />
                                     </Space>
-                           
-                                    <ArrayField field={`${field}.rules`}>
-                                        {({ add: addNested, arrayFields: nestedArrayFields, addWithInitValue: addNestedWithInitValue }, ) => (
-                                            <React.Fragment>
-                                                {
-                                                    nestedArrayFields.map(({ field: f, key: k, remove: r }, n) => (
-                                                        <section className='rules' key={k} style={{ display: 'flex', flexWrap: 'wrap', marginLeft: 36 }}>
-                                                            <Space>
-                                                                {k.slice(0, 10)}
-                                                                <Form.Input
-                                                                    style={{ width: 300, marginRight: 12 }}
-                                                                    field={`${f}.type`}
-                                                                    label={`${f}.type`}
-                                                                    id={`data-${i}-rule-${n}-type`} 
-                                                                />
-                                                                <Form.Input
-                                                                    style={{ width: 300 }}
-                                                                    field={`${f}.desc`}
-                                                                    label={`${f}.desc`}
-                                                                    id={`data-${i}-rule-${n}-desc`} 
-                                                                />
-                                                                <Button
-                                                                    onClick={() => addNestedWithInitValue({ type: `${i}-${n+1}-type`, desc: `${i}-${n+1}-desc` })}
-                                                                    icon={<IconPlusCircle/>}
-                                                                    id={`data-${i}-rule-${n}-add`}
-                                                                    disabled={n !== nestedArrayFields.length - 1}
-                                                                >
-                                                                    add new line
-                                                                </Button>
-                                                                <Button
-                                                                    type='danger'
-                                                                    onClick={r}
-                                                                    id={`data-${i}-rule-${n}-remove`} 
-                                                                    icon={<IconMinusCircle />}
-                                                                />
-                                                            </Space>
-                                                        </section>
-                                                    ))
-                                                }
-                                            </React.Fragment>
-                                        )}
-                                    </ArrayField>
+                                    <Button style={{ margin: "36px 0 0 12px" }} type="danger" icon={<IconMinusCircle/>} onClick={remove}>remove this line</Button>
                                 </div>
                             ))
                         }
+                        <Button htmlType='reset'>Reset</Button>
                     </React.Fragment>
                 )}
             </ArrayField>
             <FormStateTree></FormStateTree>
         </Form>
     );
-};
+}
 
 SetValues.storyName = 'ArrayField-ManualBatchSet Sync';
 

+ 19 - 18
packages/semi-ui/form/_story/ArrayField/9-initUsage.jsx

@@ -26,21 +26,23 @@ function InitDemo() {
     };
 
     const arrayFieldInitValue = [
-        { name: 'Semi D2C', role: 'Engineer' },
+        { name: 'NameInArrayFieldProp', role: 'RoleInArrayFieldProp' },
         // { name: 'Semi C2D', role: 'Designer' },
     ];
 
     return (
         <Form ref={formRef} initValues={formInitValues}>
-            {/* <ArrayField field="data">
+            <div>
+                <Button htmlType='reset'>Reset</Button>
+            </div>
+            <ArrayField field="data">
                 {({ add, addWithInitValue, arrayFields }) => (
                     <React.Fragment>
                         <Space>
-                            <Button htmlType='reset'>Reset</Button>
-                            <Button id='add' onClick={add} icon={<IconPlusCircle />} type="primary">Add</Button>
+                            <Button id='dataAdd' onClick={add} icon={<IconPlusCircle />} type="primary">Add</Button>
                             <Button
-                                id='addWithInit'
-                                onClick={() => addWithInitValue({ name: `Semi New-${arrayFields.length + 1}`, role: 'Designer' })}
+                                id='dataAddWithInit'
+                                onClick={() => addWithInitValue({ name: `Data-${arrayFields.length + 1}`, role: 'Designer' })}
                                 icon={<IconPlusCircle />}
                                 type="primary">
                                 Add with row initValue
@@ -67,18 +69,17 @@ function InitDemo() {
                                 </div>
                             ))
                         }
-                        <Button htmlType='reset'>Reset</Button>
                     </React.Fragment>
                 )}
-            </ArrayField> */}
+            </ArrayField>
             <ArrayField field="dataB" initValue={arrayFieldInitValue}>
                 {({ add, addWithInitValue, arrayFields }) => (
                     <React.Fragment>
                         <Space>
-                            <Button id='add' onClick={add} icon={<IconPlusCircle />} type="primary">Add</Button>
+                            <Button id='dataBAdd' onClick={add} icon={<IconPlusCircle />} type="primary">Add</Button>
                             <Button
-                                id='addWithInit'
-                                onClick={() => addWithInitValue({ name: `Semi New-${arrayFields.length + 1}`, role: 'Designer' })}
+                                id='dataBAddWithInit'
+                                onClick={() => addWithInitValue({ name: `DataB-${arrayFields.length + 1}`, role: 'Designer' })}
                                 icon={<IconPlusCircle />}
                                 type="primary">
                                 Add with row initValue
@@ -109,14 +110,14 @@ function InitDemo() {
                 )}
             </ArrayField>
 
-            {/* <ArrayField field="dataC">
+            <ArrayField field="dataC">
                 {({ add, addWithInitValue, arrayFields }) => (
                     <React.Fragment>
                         <Space>
-                            <Button id='add' onClick={add} icon={<IconPlusCircle />} type="primary">Add</Button>
+                            <Button id='dataCAdd' onClick={add} icon={<IconPlusCircle />} type="primary">Add</Button>
                             <Button
-                                id='addWithInit'
-                                onClick={() => addWithInitValue({ name: `Semi New-${arrayFields.length + 1}`, role: 'Designer' })}
+                                id='dataCAddWithInit'
+                                onClick={() => addWithInitValue({ name: `DataC-${arrayFields.length + 1}`, role: 'Designer' })}
                                 icon={<IconPlusCircle />}
                                 type="primary">
                                 Add with row initValue
@@ -131,14 +132,14 @@ function InitDemo() {
                                             field={`${field}[name]`}
                                             label={`${field}.name`}
                                             style={{ width: 200 }}
-                                            initValue={'Semi DSM'}
+                                            initValue={'NameInFieldProp'}
                                         />
                                         <Form.Input
                                             id={`dataC-${i}-role`}
                                             field={`${field}[role]`}
                                             label={`${field}.role`}
                                             style={{ width: 200 }}
-                                            initValue={'Designer'}
+                                            initValue={'RoleInFieldProp'}
                                         />
                                     </Space>
                                     <Button style={{ margin: "36px 0 0 12px" }} type="danger" icon={<IconMinusCircle/>} onClick={remove}>remove this line</Button>
@@ -147,7 +148,7 @@ function InitDemo() {
                         }
                     </React.Fragment>
                 )}
-            </ArrayField>       */}
+            </ArrayField>
             <FormStateTree></FormStateTree>
         </Form>
     );

+ 1 - 0
packages/semi-ui/form/_story/ArrayField/index.js

@@ -7,3 +7,4 @@ export { default as BasicNestedDemo } from './6-nestedBasicUsage.jsx';
 export { default as ManualBatchSetDemo } from './7-manualSyncBatchSetUsage.jsx';
 export { default as ManualBatchSetAsyncDemo } from './8-manualAsyncBatchSetUsage.jsx';
 export { default as InitDemo } from './9-initUsage.jsx';
+export { default as InitCombineDemo } from './10-initCombineUsage.jsx';

+ 36 - 26
packages/semi-ui/form/arrayField.tsx

@@ -78,10 +78,14 @@ class ArrayFieldComponent extends Component<ArrayFieldProps, ArrayFieldState> {
 
     constructor(props: ArrayFieldProps, context: FormUpdaterContextType) {
         super(props, context);
-        const initValueInProps = this.props.initValue;
         const { field } = this.props;
-        const initValueInForm = context.getValue(field);
-        const initValue = initValueInProps || initValueInForm;
+        
+        const initValueInArrayFieldProps = this.props.initValue;
+        const formProps = context.getFormProps(['initValues']);
+        const initValueInFormProps = get(formProps, field);
+        const initValueInFormState = context.getValue(field);
+        // const initValue = initValueInArrayFieldProps || initValueInFormState;
+        const initValue = initValueInArrayFieldProps || initValueInFormProps || initValueInFormState;
 
         this.hasMounted = Boolean(context.getArrayField(field));
 
@@ -98,34 +102,39 @@ class ArrayFieldComponent extends Component<ArrayFieldProps, ArrayFieldState> {
         // // whether the fields inside arrayField should use props.initValue in current render process
 
         // Separate the arrays that reset and the usual add and remove modify, otherwise they will affect each other
-        // const initValueCopyForFormState = cloneDeep(initValue);
-        // const initValueCopyForReset = cloneDeep(initValue);
-        // context.registerArrayField(field, { initValue: initValueCopyForReset, forceUpdate: this.forceUpdate });
-        // context.updateStateValue(field, initValueCopyForFormState, { notNotify: true, notUpdate: true });
+        const initValueCopyForFormState = cloneDeep(initValue);
+        const initValueCopyForReset = cloneDeep(initValue);
+
+        if (!this.hasMounted) {
+            context.registerArrayField(field, { initValue: initValueCopyForReset, forceUpdate: this.forceKeysUpdate });
+            context.updateStateValue(field, initValueCopyForFormState, { notNotify: true, notUpdate: true });
+        } else {
+            context.registerArrayField(field, { forceUpdate: this.forceKeysUpdate });
+        }
     }
 
     componentDidMount() {
-        const { field } = this.props;
-        const initValueInArrayFieldProps = this.props.initValue;
-        const updater = this.context;
+        // const { field } = this.props;
+        // const initValueInArrayFieldProps = this.props.initValue;
+        // const updater = this.context;
 
-        const formProps = updater.getFormProps(['initValues']);
-        const initValueInFormProps = get(formProps, field);
+        // const formProps = updater.getFormProps(['initValues']);
+        // const initValueInFormProps = get(formProps, field);
 
-        const initValueInFormState = updater.getValue(field);
+        // const initValueInFormState = updater.getValue(field);
         
-        const initValue = initValueInArrayFieldProps || initValueInFormProps || initValueInFormState;
+        // const initValue = initValueInArrayFieldProps || initValueInFormProps || initValueInFormState;
 
-        const initValueCopyForFormState = cloneDeep(initValue);
-        const initValueCopyForReset = cloneDeep(initValue);
+        // const initValueCopyForFormState = cloneDeep(initValue);
+        // const initValueCopyForReset = cloneDeep(initValue);
 
-        // 如果首次挂载,应该使用初始值,如果不是首次挂载,例如嵌套场景下,level 1 keys变更导致的 level 2子级重新挂载,那应该直接使用formState 中的值, 且无需注册 initValue
-        if (!this.hasMounted) {
-            updater.registerArrayField(field, { initValue: initValueCopyForReset, forceUpdate: this.forceKeysUpdate });
-            updater.updateStateValue(field, initValueCopyForFormState, { notNotify: true, notUpdate: true });
-        } else {
-            updater.registerArrayField(field, { forceUpdate: this.forceKeysUpdate });
-        }
+        // // 如果首次挂载,应该使用初始值,如果不是首次挂载,例如嵌套场景下,level 1 keys变更导致的 level 2子级重新挂载,那应该直接使用formState 中的值, 且无需注册 initValue
+        // if (!this.hasMounted) {
+        //     updater.registerArrayField(field, { initValue: initValueCopyForReset, forceUpdate: this.forceKeysUpdate });
+        //     updater.updateStateValue(field, initValueCopyForFormState, { notNotify: true, notUpdate: true });
+        // } else {
+        //     updater.registerArrayField(field, { forceUpdate: this.forceKeysUpdate });
+        // }
     }
 
     componentWillUnmount() {
@@ -160,16 +169,16 @@ class ArrayFieldComponent extends Component<ArrayFieldProps, ArrayFieldState> {
         // this.shouldUseInitValue = true;
         // TODO allowEmpty 为 false 的情况下
         this.setState({ keys });
-
     }
 
     addWithInitValue(lineObject: Record<string, any>) {
         const updater = this.context;
         const { field } = this.props;
-        const newArrayFieldVal = updater.getValue(field) ? updater.getValue(field).slice() : [];
+        const oldArrayFieldVal = updater.getValue(field) ? updater.getValue(field) : [];
+        const newArrayFieldVal = oldArrayFieldVal.slice();
         newArrayFieldVal.push(lineObject);
         updater.updateStateValue(field, newArrayFieldVal, {});
-        updater.updateArrayField(field, { updateValue: newArrayFieldVal });
+        updater.updateArrayField(field, { newValue: newArrayFieldVal, oldValue: oldArrayFieldVal });
     }
 
     remove(i: number) {
@@ -211,6 +220,7 @@ class ArrayFieldComponent extends Component<ArrayFieldProps, ArrayFieldState> {
         const { addWithInitValue } = this;
         const contextVal = {
             isInArrayField: true,
+
         };
         return (
             <ArrayFieldContext.Provider value={contextVal}>

+ 8 - 8
packages/semi-ui/form/hoc/withField.tsx

@@ -28,8 +28,6 @@ const useIsomorphicEffect = typeof window !== 'undefined' ? useLayoutEffect : us
  * 1. Takes over the value and onChange of the component and synchronizes them to Form Foundation
  * 2. Insert <Label>
  * 3. Insert <ErrorMessage>
- * 4. Insert extraText
- * 5. Add A11y Aria Support
  */
 
 function withField<
@@ -101,7 +99,7 @@ function withField<
         }
 
         // To prevent user forgetting to pass the field, use undefined as the key, and updater.getValue will get the wrong value.
-        let initValueInFormOpts = typeof field !== 'undefined' ? updater.getValue(field) : undefined; // Get the init value of form from formProps.init Values Get the initial value set in the initValues of Form
+        let initValueInFormOpts = typeof field !== 'undefined' ? updater.getValue(field) : undefined; // Get the init value of form from formP rops.init Values Get the initial value set in the initValues of Form
         let initVal = typeof initValue !== 'undefined' ? initValue : initValueInFormOpts;
 
         // use arrayFieldState to fix issue 615
@@ -109,11 +107,13 @@ function withField<
         try {
             arrayFieldState = useArrayFieldState();
             if (arrayFieldState) {
-                // initVal =
-                //     arrayFieldState.shouldUseInitValue && typeof initValue !== 'undefined'
-                //         ? initValue
-                //         : initValueInFormOpts;
-                initVal = typeof initValue !== 'undefined' ? initValue : initValueInFormOpts;
+                if (arrayFieldState.shouldUseInitValue && typeof initValue !== 'undefined') {
+                    initVal = initValue;
+                    debugger;
+                } else {
+                    initVal = initValueInFormOpts;
+                    debugger;
+                }
             }
         } catch (err) {}