{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "form", "title": "Form", "description": "Form components with React Hook Form and Zod integration.", "dependencies": [ "radix-ui", "react-hook-form" ], "registryDependencies": [ "https://ds.formance.com/r/label.json" ], "files": [ { "path": "registry/default/ui/form.tsx", "content": "'use client';\n\nimport { Label as LabelPrimitive, Slot as SlotPrimitive } from 'radix-ui';\n\nimport * as React from 'react';\nimport {\n Controller,\n FormProvider,\n useFormContext,\n useFormState,\n type ControllerProps,\n type FieldPath,\n type FieldValues,\n} from 'react-hook-form';\n\nimport { Label } from '@/registry/default/ui/label';\nimport { cn } from '@/lib/utils';\n\n// Temporary any\n// TODO find a better way to type this one\n// Current github issue\nconst Form: any = FormProvider;\n\ntype FormFieldContextValue<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath = FieldPath,\n> = {\n name: TName;\n};\n\nconst FormFieldContext = React.createContext(\n {} as FormFieldContextValue\n);\n\nconst FormField = <\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath = FieldPath,\n>({\n ...props\n}: ControllerProps) => {\n const fieldContext = React.useMemo(\n () => ({ name: props.name }),\n [props.name]\n );\n\n return (\n \n \n \n );\n};\n\nconst useFormField = () => {\n const fieldContext = React.useContext(FormFieldContext);\n const itemContext = React.useContext(FormItemContext);\n const { getFieldState } = useFormContext();\n const formState = useFormState({ name: fieldContext.name });\n const fieldState = getFieldState(fieldContext.name, formState);\n\n if (!fieldContext) {\n throw new Error('useFormField should be used within ');\n }\n\n const { id } = itemContext;\n\n return {\n id,\n name: fieldContext.name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n ...fieldState,\n };\n};\n\ntype FormItemContextValue = {\n id: string;\n};\n\nconst FormItemContext = React.createContext(\n {} as FormItemContextValue\n);\n\nfunction FormItem({ className, ...props }: React.ComponentProps<'div'>) {\n const id = React.useId();\n const itemContext = React.useMemo(() => ({ id }), [id]);\n\n return (\n \n \n \n );\n}\n\nfunction FormLabel({\n className,\n ...props\n}: React.ComponentProps) {\n const { error, formItemId } = useFormField();\n\n return (\n \n );\n}\n\nfunction FormControl({\n ...props\n}: React.ComponentProps) {\n const { error, formItemId, formDescriptionId, formMessageId } =\n useFormField();\n\n return (\n \n );\n}\n\nfunction FormDescription({ className, ...props }: React.ComponentProps<'p'>) {\n const { formDescriptionId } = useFormField();\n\n return (\n \n );\n}\n\nfunction FormMessage({ className, ...props }: React.ComponentProps<'p'>) {\n const { error, formMessageId } = useFormField();\n const body = error ? String(error?.message ?? '') : props.children;\n\n if (!body) {\n return null;\n }\n\n return (\n \n {body}\n

\n );\n}\n\nexport {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n useFormField,\n};\n", "type": "registry:ui" } ], "type": "registry:ui" }