"use client";
import { Form } from "@/components/ui/form";
import type React from "react";
import { useEffect } from "react";
import { type DefaultValues, type FormState, useForm } from "react-hook-form";
import type { z } from "zod";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { zodResolver } from "@hookform/resolvers/zod";
import AutoFormObject from "@/components/auto-form/fields/object";
import type { Dependency, FieldConfig } from "@/components/auto-form/types";
import {
type ZodObjectOrWrapped,
getDefaultValues,
getObjectFormSchema,
} from "@/components/auto-form/utils";
export function AutoFormSubmit({
children,
className,
disabled,
}: {
children?: React.ReactNode;
className?: string;
disabled?: boolean;
}) {
return (
);
}
function AutoForm({
formSchema,
values: valuesProp,
onValuesChange: onValuesChangeProp,
onParsedValuesChange,
onSubmit: onSubmitProp,
fieldConfig,
children,
className,
dependencies,
}: {
formSchema: SchemaType;
values?: Partial>;
onValuesChange?: (values: Partial>) => void;
onParsedValuesChange?: (values: Partial>) => void;
onSubmit?: (values: z.infer) => void;
fieldConfig?: FieldConfig>;
children?:
| React.ReactNode
| ((formState: FormState>) => React.ReactNode);
className?: string;
dependencies?: Dependency>[];
}) {
const objectFormSchema = getObjectFormSchema(formSchema);
const defaultValues: DefaultValues> | null =
getDefaultValues(objectFormSchema, fieldConfig);
const form = useForm>({
resolver: zodResolver(formSchema),
defaultValues: defaultValues ?? undefined,
values: valuesProp,
});
function onSubmit(values: z.infer) {
const parsedValues = formSchema.safeParse(values);
if (parsedValues.success) {
onSubmitProp?.(parsedValues.data);
}
}
const values = form.watch();
// valuesString is needed because form.watch() returns a new object every time
const valuesString = JSON.stringify(values);
// biome-ignore lint/correctness/useExhaustiveDependencies:
useEffect(() => {
onValuesChangeProp?.(values);
const parsedValues = formSchema.safeParse(values);
if (parsedValues.success) {
onParsedValuesChange?.(parsedValues.data);
}
}, [valuesString]);
const renderChildren =
typeof children === "function"
? children(form.formState as FormState>)
: children;
return (
);
}
export default AutoForm;