Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | 72x 22x 22x 2x 22x 22x 1x 1x 1x | import { useEffect } from "react";
import { FieldValues, useFieldArray } from "react-hook-form";
import { FieldArrayProps } from "shared-types";
import { Plus, Trash2 } from "lucide-react";
import { Button } from "../Inputs";
import { slotInitializer } from "./utils";
import { Field } from "./Field";
import { cn } from "@/utils";
export const RHFFieldArray = <TFields extends FieldValues>(props: FieldArrayProps<TFields>) => {
const fieldArr = useFieldArray<any>({
control: props.control,
name: props.name,
shouldUnregister: true,
});
const onAppend = () => {
fieldArr.append(props.fields.reduce(slotInitializer(), {}) as never);
};
useEffect(() => {
if (fieldArr.fields.length) return;
fieldArr.append(props.fields.reduce(slotInitializer(), {}) as never, {
shouldFocus: false,
});
}, [fieldArr, props.fields]);
return (
<div className={"flex flex-col gap-6 w-full"}>
{fieldArr.fields.map((FLD, index) => {
return (
<div className={cn("flex flex-row gap-6", props.fieldArrayClassName)} key={FLD.id}>
{props.fields.map((SLOT, i) => {
return <Field key={`${SLOT.name}-${i}`} {...props} index={index} SLOT={SLOT} />;
})}
{/* FieldArray Removal */}
{index >= 1 && !props.removeText && (
<Trash2
className="self-end mb-2 cursor-pointer stroke-primary"
data-testid={`removeRowButton-${index}`}
onClick={() => fieldArr.remove(index)}
/>
)}
{/* FieldGroup Removal */}
{index >= 1 && props.removeText && (
<Button
className="self-end m-2 mr-0"
variant={"destructive"}
data-testid={`removeGroupButton-${index}`}
onClick={() => {
fieldArr.remove(index);
}}
>
{props.removeText ?? "Remove Group"}
</Button>
)}
{props.divider && <div className="w-full border-slate-300 border-b-[1px]" />}
</div>
);
})}
{props.lastDivider && (
<div className={cn("w-full border-slate-300 border-b-[1px]", props.lastDivider)} />
)}
<div className={cn("flex items-center", props.appendClassName)}>
<Button
type="button"
size="sm"
onClick={onAppend}
data-testid={`appendRowButton-${props.name}`}
variant={props.appendVariant ?? "outline"}
>
<Plus className="h-5 w-5 mr-2" />
{props.appendText || "New Row"}
</Button>
</div>
</div>
);
};
|