{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "form",
  "title": "Form",
  "description": "Components and utilities that help you compose forms with react-hook-form.",
  "dependencies": [
    "react-hook-form"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "@tetra-ui/label"
  ],
  "files": [
    {
      "path": "ui/form.tsx",
      "content": "import {\n  Children,\n  cloneElement,\n  createContext,\n  useContext,\n  useMemo,\n} from \"react\";\nimport type { FieldErrors, FieldPath } from \"react-hook-form\";\nimport { get } from \"react-hook-form\";\nimport { Text, type TextProps, View } from \"react-native\";\nimport { cn } from \"../lib/utils\";\nimport { Label, type LabelProps } from \"./label\";\n\n// Types\ntype FieldStateProps = {\n  invalid?: boolean;\n  disabled?: boolean;\n};\n\ntype InternalFieldContextType = FieldStateProps & {\n  errorMessage?: string;\n};\n\nexport type FieldProps = InternalFieldContextType & {\n  children: React.ReactNode;\n};\n\ntype FieldControlProps = {\n  children: React.ReactElement<FieldStateProps>;\n};\n\n// Context\nconst FieldContext = createContext<InternalFieldContextType | null>(null);\n\nconst useFieldContext = () => {\n  const context = useContext(FieldContext);\n  if (!context) {\n    throw new Error(\"useFieldContext must be used within a Field component\");\n  }\n  return context;\n};\n\n// Components\nexport const Field = ({\n  errorMessage,\n  invalid,\n  disabled,\n  children,\n}: FieldProps) => {\n  const ctx = useMemo(\n    () => ({ disabled, errorMessage, invalid }),\n    [errorMessage, disabled, invalid]\n  );\n\n  return (\n    <FieldContext.Provider value={ctx}>\n      <View className=\"flex flex-col gap-2\">{children}</View>\n    </FieldContext.Provider>\n  );\n};\n\nexport const FieldLabel = ({ className, ...props }: LabelProps) => {\n  const { disabled, invalid } = useFieldContext();\n\n  return (\n    <Label\n      {...props}\n      className={cn(\n        {\n          \"text-destructive\": invalid,\n          \"text-muted-foreground\": disabled,\n        },\n        className\n      )}\n    />\n  );\n};\n\nexport const FieldControl = ({ children }: FieldControlProps) => {\n  const { disabled, invalid } = useFieldContext();\n  const child = Children.only(children);\n\n  if (!child) {\n    if (__DEV__) {\n      throw new Error(\n        \"FieldControl expects a single React element as children\"\n      );\n    }\n\n    return null;\n  }\n\n  return cloneElement(child, {\n    disabled,\n    invalid,\n  });\n};\n\nexport const FieldDescription = ({ className, ...props }: TextProps) => {\n  const { errorMessage } = useFieldContext();\n\n  if (errorMessage) {\n    return null;\n  }\n\n  return (\n    <Text\n      {...props}\n      className={cn(\"text-muted-foreground text-sm\", className)}\n    />\n  );\n};\n\nexport const FieldErrorMessage = ({\n  className,\n  ...props\n}: Omit<TextProps, \"children\">) => {\n  const { errorMessage } = useFieldContext();\n\n  if (!errorMessage) {\n    return null;\n  }\n\n  return (\n    <Text\n      {...props}\n      accessibilityRole=\"alert\"\n      className={cn(\"font-medium text-destructive text-sm\", className)}\n    >\n      {errorMessage}\n    </Text>\n  );\n};\n\n// Utils\ntype FieldValuesFromFieldErrors<TFieldErrors> =\n  TFieldErrors extends FieldErrors<infer TFieldValues> ? TFieldValues : never;\n\n// biome-ignore lint/suspicious/noExplicitAny: ignore any\nexport function validateField<TFieldErrors extends FieldErrors<any>>(\n  errors: TFieldErrors,\n  fieldPath: FieldPath<FieldValuesFromFieldErrors<TFieldErrors>>\n) {\n  const error = get(errors, fieldPath);\n\n  if (!error) {\n    return {};\n  }\n\n  return {\n    errorMessage: error.message as string | undefined,\n    invalid: true,\n  } as const;\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}
