{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "form",
  "title": "Form",
  "description": "Form from the Get IT Done design system.",
  "dependencies": [
    "@radix-ui/react-label@^2.1.17",
    "@radix-ui/react-slot@^1.5.0",
    "react-hook-form@^7.47.0"
  ],
  "registryDependencies": [
    "https://zero-design.itdone.de/r/label.json",
    "https://zero-design.itdone.de/r/utils.json",
    "https://zero-design.itdone.de/r/theme.json"
  ],
  "files": [
    {
      "path": "registry/ui/form.tsx",
      "content": "'use client';\n\nimport * as LabelPrimitive from '@radix-ui/react-label';\nimport { Slot } from '@radix-ui/react-slot';\nimport * as React from 'react';\nimport { Controller, ControllerProps, FieldPath, FieldValues, FormProvider, useFormContext } 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> = {\n  name: TName;\n};\n\nconst FormFieldContext = React.createContext<FormFieldContextValue>({} as FormFieldContextValue);\n\nconst FormField = <\n  TFieldValues extends FieldValues = FieldValues,\n  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n  ...props\n}: ControllerProps<TFieldValues, TName>) => {\n  return (\n    <FormFieldContext.Provider value={{ name: props.name }}>\n      <Controller {...props} />\n    </FormFieldContext.Provider>\n  );\n};\n\nconst useFormField = () => {\n  const fieldContext = React.useContext(FormFieldContext);\n  const itemContext = React.useContext(FormItemContext);\n  const { getFieldState, formState } = useFormContext();\n\n  const fieldState = getFieldState(fieldContext.name, formState);\n\n  if (!fieldContext) {\n    throw new Error('useFormField should be used within <FormField>');\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<FormItemContextValue>({} as FormItemContextValue);\n\nconst FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => {\n    const id = React.useId();\n\n    return (\n      <FormItemContext.Provider value={{ id }}>\n        <div ref={ref} {...props} />\n      </FormItemContext.Provider>\n    );\n  },\n);\nFormItem.displayName = 'FormItem';\n\nconst FormLabel = React.forwardRef<\n  React.ElementRef<typeof LabelPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & { clamp?: Boolean }\n>(({ className, clamp = false, ...props }, ref) => {\n  const { error, formItemId } = useFormField();\n\n  return (\n    <Label\n      ref={ref}\n      className={cn(\n        error && 'text-text-destructive',\n        '[&_.typography-button]:!typography-input-label',\n        { 'text-clamp': clamp },\n        { 'leading-clamp': clamp },\n        className,\n      )}\n      htmlFor={formItemId}\n      {...props}\n    />\n  );\n});\nFormLabel.displayName = 'FormLabel';\n\nconst FormControl = React.forwardRef<React.ElementRef<typeof Slot>, React.ComponentPropsWithoutRef<typeof Slot>>(\n  ({ ...props }, ref) => {\n    const { error, formItemId, formDescriptionId, formMessageId } = useFormField();\n\n    return (\n      <Slot\n        ref={ref}\n        id={formItemId}\n        aria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}\n        aria-invalid={!!error}\n        {...props}\n      />\n    );\n  },\n);\nFormControl.displayName = 'FormControl';\n\nconst FormDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(\n  ({ className, ...props }, ref) => {\n    const { formDescriptionId } = useFormField();\n\n    return <p ref={ref} id={formDescriptionId} className={cn('text-sm text-text-subtle', className)} {...props} />;\n  },\n);\nFormDescription.displayName = 'FormDescription';\n\nconst FormMessage = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(\n  ({ className, children, ...props }, ref) => {\n    const { error, formMessageId } = useFormField();\n    const body = error ? String(error?.message) : children;\n\n    if (!body) {\n      return null;\n    }\n\n    // The element only exists while there is something to say, so a validation error is announced once when it is inserted (role alert, WCAG 4.1.3). Re-renders with the same text do not announce again. Plain helper children carry no role.\n    return (\n      <p\n        ref={ref}\n        id={formMessageId}\n        role={error ? 'alert' : undefined}\n        className={cn('text-sm text-text-destructive', className)}\n        {...props}\n      >\n        {body}\n      </p>\n    );\n  },\n);\nFormMessage.displayName = 'FormMessage';\n\nexport { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useFormField };\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}