Skip to content

Commit

Permalink
Merge branch 'field-array-watch-bug'
Browse files Browse the repository at this point in the history
  • Loading branch information
nikhilag committed Mar 1, 2024
2 parents 9876146 + ceb32ce commit c71f7d0
Show file tree
Hide file tree
Showing 4 changed files with 540 additions and 141 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-recoil-form",
"version": "0.7.8",
"version": "0.8.0",
"license": "MIT",
"author": "Wit By Bit",
"main": "dist/index.js",
Expand Down Expand Up @@ -49,9 +49,9 @@
"recoil": "0.7.7",
"storybook": "7.0.6",
"tslib": "^2.4.0",
"tsup": "^6.7.0",
"tsup": "^8.0.2",
"typescript": "4.7.4",
"vite": "^4.3.9"
"vite": "^4.5.2"
},
"lint-staged": {
"*": "prettier --ignore-unknown --write"
Expand Down
3 changes: 1 addition & 2 deletions src/FormProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -838,8 +838,7 @@ export function useFieldArray(props: IFieldArrayProps) {
skipUnregister,
} as Partial<IFieldArrayAtomValue>)
);
// Values are only initialized for fields or field arrays without ancestors
if (!ancestors?.length && initialValue?.length) {
if (initialValue?.length) {
setFieldArrayDataAndExtraInfo(
formId,
{ name, ancestors: ancestors ?? [] },
Expand Down
213 changes: 111 additions & 102 deletions src/stories/repros/FieldArrayWatchRepro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { shuffle } from 'lodash';
import * as React from 'react';
import {
useFieldArray,
useFieldArrayColumnWatch,
useFieldWatch,
useForm,
withFormProvider,
} from '../../FormProvider';
Expand Down Expand Up @@ -44,11 +44,6 @@ function FieldArrayWatchRepro() {
name: 'filters',
});

const watchValues = useFieldArrayColumnWatch({
fieldArrayName: 'filters',
fieldNames: ['type'],
}).values;

function reorder() {
const values = getFieldArrayValue();

Expand All @@ -63,49 +58,7 @@ function FieldArrayWatchRepro() {
<div>
<div>
{fieldArrayProps.rowIds.map((r, idx) => {
const type = watchValues?.[idx]?.type;
if (type === 'group') {
return (
<FieldGroup
ancestors={[{ name: 'filters', rowId: r }]}
onRemove={() => remove(idx)}
/>
);
} else
return (
<div className="flex gap-3" key={r}>
<React.Fragment>
<div className="px-2">
<InputField
ancestors={[{ name: 'filters', rowId: r }]}
name="name"
type="text"
// validate={(value) => (!value ? `Value missing` : '')}
/>
</div>
<div className="px-2">
<InputField
ancestors={[{ name: 'filters', rowId: r }]}
name="age"
type="number"
// validate={(value) => (!value ? `Value missing` : '')}
/>
</div>
<div className="px-2">
<div className="flex gap-2 mt-6">
<Button
small
color="red"
type="button"
onClick={() => remove(idx)}
>
Remove
</Button>
</div>
</div>
</React.Fragment>
</div>
);
return <FilterFieldArrayRow ancestors={[{ name: 'filters', rowId: r }]} idx={idx} remove={remove}/>;
})}
</div>

Expand Down Expand Up @@ -157,6 +110,55 @@ function FieldArrayWatchRepro() {
);
}

function FilterFieldArrayRow(props: {
ancestors: { name: string; rowId: number }[];
remove: any;
idx: number;
}) {
const { ancestors, idx, remove } = props;
const {values} = useFieldWatch({
fieldNames: [{ancestors, name: 'type'}],
})

if (values.type === 'group') {
return <FieldGroup ancestors={ancestors} onRemove={() => remove(idx)} />;
} else
return (
<div className="flex gap-3" key={idx}>
<React.Fragment>
<div className="px-2">
<InputField
ancestors={ancestors}
name="name"
type="text"
// validate={(value) => (!value ? `Value missing` : '')}
/>
</div>
<div className="px-2">
<InputField
ancestors={ancestors}
name="age"
type="number"
// validate={(value) => (!value ? `Value missing` : '')}
/>
</div>
<div className="px-2">
<div className="flex gap-2 mt-6">
<Button
small
color="red"
type="button"
onClick={() => remove(idx)}
>
Remove
</Button>
</div>
</div>
</React.Fragment>
</div>
);
}

export default withFormProvider(FieldArrayWatchRepro);

const FieldGroup = ({ ancestors, onRemove }: any) => {
Expand All @@ -167,67 +169,17 @@ const FieldGroup = ({ ancestors, onRemove }: any) => {
ancestors,
});

const watchValues = useFieldArrayColumnWatch({
ancestors,
fieldArrayName: fieldArrName,
fieldNames: ['name', 'age', 'type'],
}).values;

return (
<div className="border p-4 rounded m-4">
{fieldArrayProps.rowIds.map((r, idx) => {
const groupAncestors = (ancestors ?? [])?.concat([
{ name: fieldArrName, rowId: r },
]);

if (watchValues?.[idx]?.type === 'group') {
if (groupAncestors?.length < 3) {
return (
<FieldGroup
ancestors={groupAncestors}
onRemove={() => remove(idx)}
/>
);
}
return null;
}

return (
<div className="flex gap-3" key={r}>
<React.Fragment>
<div className="px-2">
<InputField
ancestors={groupAncestors}
name="name"
type="text"
// validate={(value) => (!value ? `Value missing` : '')}
/>
</div>
<div className="px-2">
<InputField
ancestors={groupAncestors}
name="age"
type="number"
// validate={(value) => (!value ? `Value missing` : '')}
/>
</div>
<div className="px-2">
<div className="flex gap-2 mt-6">
<Button
small
color="red"
type="button"
onClick={() => remove(idx)}
>
Remove
</Button>
</div>
</div>
</React.Fragment>
</div>
);
return <NestedFilterFieldRow ancestors={groupAncestors} idx={idx} remove={remove} key={r}/>
})}



<div className="flex gap-4">
<Button small type="button" onClick={() => append()}>
Add Filter
Expand All @@ -251,3 +203,60 @@ const FieldGroup = ({ ancestors, onRemove }: any) => {
</div>
);
};

function NestedFilterFieldRow(props: {
ancestors: { name: string; rowId: number }[];
remove: any;
idx: number;
}) {
const { ancestors, idx, remove } = props;
const {values} = useFieldWatch({
fieldNames: [{ancestors, name: 'type'}],
});
if (values?.type === 'group') {
if (ancestors?.length < 3) {
return (
<FieldGroup
ancestors={ancestors}
onRemove={() => remove(idx)}
/>
);
}
return null;
}

return (
<div className="flex gap-3" key={idx}>
<React.Fragment>
<div className="px-2">
<InputField
ancestors={ancestors}
name="name"
type="text"
// validate={(value) => (!value ? `Value missing` : '')}
/>
</div>
<div className="px-2">
<InputField
ancestors={ancestors}
name="age"
type="number"
// validate={(value) => (!value ? `Value missing` : '')}
/>
</div>
<div className="px-2">
<div className="flex gap-2 mt-6">
<Button
small
color="red"
type="button"
onClick={() => remove(idx)}
>
Remove
</Button>
</div>
</div>
</React.Fragment>
</div>
);
}
Loading

0 comments on commit c71f7d0

Please sign in to comment.