Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
1import { zodResolver } from "@hookform/resolvers/zod";
2import type { ComponentProps } from "react";
3import type {
4 FieldValues,
5 SubmitHandler,
6 UseFormProps,
7 UseFormReturn
8} from "react-hook-form";
9import { FormProvider, useForm, useFormContext } from "react-hook-form";
10import type { TypeOf, ZodSchema, ZodType } from "zod";
11import cn from "@/helpers/cn";
12import { H6 } from "./Typography";
13
14interface UseZodFormProps<T extends ZodSchema<FieldValues>>
15 extends UseFormProps<TypeOf<T>> {
16 schema: T;
17}
18
19export const useZodForm = <T extends ZodType<any>>({
20 schema,
21 ...formConfig
22}: UseZodFormProps<T>) => {
23 return useForm<TypeOf<T>>({
24 ...formConfig,
25 resolver: (zodResolver as any)(schema) as any
26 });
27};
28
29interface FieldErrorProps {
30 name?: string;
31}
32
33export const FieldError = ({ name }: FieldErrorProps) => {
34 const {
35 formState: { errors }
36 } = useFormContext();
37
38 if (!name) {
39 return null;
40 }
41
42 const error = errors[name];
43
44 if (!error) {
45 return null;
46 }
47
48 return <H6 className="mt-2 text-red-500">{error.message as string}</H6>;
49};
50
51interface FormProps<T extends FieldValues = Record<string, unknown>>
52 extends Omit<ComponentProps<"form">, "onSubmit"> {
53 className?: string;
54 form: UseFormReturn<T, any, any>;
55 onSubmit: SubmitHandler<T>;
56}
57
58export const Form = <T extends FieldValues>({
59 children,
60 className = "",
61 form,
62 onSubmit
63}: FormProps<T>) => {
64 return (
65 <FormProvider {...form}>
66 <form onSubmit={form.handleSubmit(onSubmit)}>
67 <fieldset
68 className={cn("flex flex-col", className)}
69 disabled={form.formState.isSubmitting}
70 >
71 {children}
72 </fieldset>
73 </form>
74 </FormProvider>
75 );
76};