{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "form",
  "title": "Form",
  "description": "Accessible react-hook-form bindings for labels, controls and validation messages.",
  "dependencies": [
    "@radix-ui/react-label",
    "@radix-ui/react-slot",
    "react-hook-form"
  ],
  "registryDependencies": [
    "@rivelle/utils",
    "@rivelle/label"
  ],
  "files": [
    {
      "path": "registry/nova/ui/form.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport {\n  Controller,\n  FormProvider,\n  useFormContext,\n  type ControllerProps,\n  type FieldPath,\n  type FieldValues,\n} from \"react-hook-form\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Label } from \"@/components/ui/label\";\n\nconst Form = FormProvider;\n\ntype FormFieldContextValue<\n  TFieldValues extends FieldValues = FieldValues,\n  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = { name: TName };\nconst FormFieldContext = React.createContext<FormFieldContextValue>(\n  {} as FormFieldContextValue,\n);\n\nfunction FormField<\n  TFieldValues extends FieldValues = FieldValues,\n  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>(props: ControllerProps<TFieldValues, TName>) {\n  return (\n    <FormFieldContext.Provider value={{ name: props.name }}>\n      <Controller {...props} />\n    </FormFieldContext.Provider>\n  );\n}\n\nconst FormItemContext = React.createContext<{ id: string }>({ id: \"\" });\n\nfunction FormItem({ className, ...props }: React.ComponentProps<\"div\">) {\n  const id = React.useId();\n  return (\n    <FormItemContext.Provider value={{ id }}>\n      <div\n        data-slot=\"form-item\"\n        className={cn(\"grid gap-2\", className)}\n        {...props}\n      />\n    </FormItemContext.Provider>\n  );\n}\n\nfunction useFormField() {\n  const fieldContext = React.useContext(FormFieldContext);\n  const itemContext = React.useContext(FormItemContext);\n  const { getFieldState, formState } = useFormContext();\n  if (!fieldContext.name)\n    throw new Error(\"useFormField must be used within <FormField>\");\n  const fieldState = getFieldState(fieldContext.name, formState);\n  return {\n    id: itemContext.id,\n    name: fieldContext.name,\n    formItemId: `${itemContext.id}-form-item`,\n    formDescriptionId: `${itemContext.id}-form-item-description`,\n    formMessageId: `${itemContext.id}-form-item-message`,\n    ...fieldState,\n  };\n}\n\nfunction FormLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n  const { error, formItemId } = useFormField();\n  return (\n    <Label\n      data-slot=\"form-label\"\n      data-error={!!error}\n      className={cn(\"data-[error=true]:text-destructive\", className)}\n      htmlFor={formItemId}\n      {...props}\n    />\n  );\n}\n\nfunction FormControl(props: React.ComponentProps<typeof Slot>) {\n  const { error, formItemId, formDescriptionId, formMessageId } =\n    useFormField();\n  return (\n    <Slot\n      data-slot=\"form-control\"\n      id={formItemId}\n      aria-describedby={\n        !error ? formDescriptionId : `${formDescriptionId} ${formMessageId}`\n      }\n      aria-invalid={!!error}\n      {...props}\n    />\n  );\n}\n\nfunction FormDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n  const { formDescriptionId } = useFormField();\n  return (\n    <p\n      data-slot=\"form-description\"\n      id={formDescriptionId}\n      className={cn(\"text-xs leading-relaxed text-muted-foreground\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction FormMessage({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<\"p\">) {\n  const { error, formMessageId } = useFormField();\n  const body = error ? String(error.message ?? \"\") : children;\n  if (!body) return null;\n  return (\n    <p\n      data-slot=\"form-message\"\n      id={formMessageId}\n      className={cn(\"text-xs font-medium text-destructive\", className)}\n      {...props}\n    >\n      {body}\n    </p>\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"
}