{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "field",
  "title": "Field",
  "description": "Layout wrapper pairing a label, control, description, and error message.",
  "dependencies": [
    "@vllnt/ui@^0.2.1"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/field/field.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@vllnt/ui\";\nimport { Label } from \"@vllnt/ui\";\n\ntype FieldContextValue = {\n  descriptionId: string;\n  errorId: string;\n  id: string;\n  invalid: boolean;\n};\n\nconst FieldContext = React.createContext<FieldContextValue | null>(null);\n\nfunction useFieldContext(): FieldContextValue {\n  const context = React.use(FieldContext);\n  if (!context) {\n    throw new Error(\"Field subcomponents must be used within a Field\");\n  }\n  return context;\n}\n\nconst fieldVariants = cva(\"flex\", {\n  defaultVariants: {\n    orientation: \"vertical\",\n  },\n  variants: {\n    orientation: {\n      horizontal: \"flex-row items-center gap-3\",\n      vertical: \"flex-col gap-1.5\",\n    },\n  },\n});\n\n/** Groups a label, control, description, and error message for one input. */\nexport type FieldProps = {\n  children: React.ReactNode;\n  className?: string;\n  invalid?: boolean;\n} & VariantProps<typeof fieldVariants>;\n\nconst Field = ({\n  children,\n  className,\n  invalid = false,\n  orientation,\n  ref,\n}: FieldProps & { ref?: React.Ref<HTMLDivElement> }) => {\n  const id = React.useId();\n  const value = React.useMemo<FieldContextValue>(\n    () => ({\n      descriptionId: `${id}-description`,\n      errorId: `${id}-error`,\n      id: `${id}-control`,\n      invalid,\n    }),\n    [id, invalid],\n  );\n\n  return (\n    <FieldContext.Provider value={value}>\n      <div\n        className={cn(fieldVariants({ orientation }), className)}\n        data-slot=\"field\"\n        ref={ref}\n      >\n        {children}\n      </div>\n    </FieldContext.Provider>\n  );\n};\nField.displayName = \"Field\";\n\n/** Label wired to the field control through htmlFor. */\nexport type FieldLabelProps = React.ComponentPropsWithoutRef<typeof Label>;\n\nconst FieldLabel = ({\n  className,\n  ref,\n  ...props\n}: FieldLabelProps & { ref?: React.Ref<React.ComponentRef<typeof Label>> }) => {\n  const { id, invalid } = useFieldContext();\n\n  return (\n    <Label\n      className={cn(invalid && \"text-destructive\", className)}\n      htmlFor={id}\n      ref={ref}\n      {...props}\n    />\n  );\n};\nFieldLabel.displayName = \"FieldLabel\";\n\n/** Wraps the control and injects id plus aria wiring from the Field. */\nexport type FieldControlProps = {\n  children: React.ReactNode;\n};\n\nconst FieldControl = ({\n  children,\n  ref,\n}: FieldControlProps & { ref?: React.Ref<HTMLElement> }) => {\n  const { descriptionId, errorId, id, invalid } = useFieldContext();\n  const describedBy =\n    [descriptionId, invalid ? errorId : null].filter(Boolean).join(\" \") ||\n    undefined;\n\n  return (\n    <Slot\n      aria-describedby={describedBy}\n      aria-invalid={invalid || undefined}\n      id={id}\n      ref={ref}\n    >\n      {children}\n    </Slot>\n  );\n};\nFieldControl.displayName = \"FieldControl\";\n\n/** Helper text describing the field, announced to assistive tech. */\nexport type FieldDescriptionProps = React.ComponentPropsWithoutRef<\"p\">;\n\nconst FieldDescription = ({\n  className,\n  ref,\n  ...props\n}: FieldDescriptionProps & { ref?: React.Ref<HTMLParagraphElement> }) => {\n  const { descriptionId } = useFieldContext();\n\n  return (\n    <p\n      className={cn(\"text-sm text-muted-foreground\", className)}\n      id={descriptionId}\n      ref={ref}\n      {...props}\n    />\n  );\n};\nFieldDescription.displayName = \"FieldDescription\";\n\n/** Validation message that renders when children are present. */\nexport type FieldErrorProps = React.ComponentPropsWithoutRef<\"p\">;\n\nconst FieldError = ({\n  children,\n  className,\n  ref,\n  ...props\n}: FieldErrorProps & { ref?: React.Ref<HTMLParagraphElement> }) => {\n  const { errorId } = useFieldContext();\n\n  if (!children) {\n    return null;\n  }\n\n  return (\n    <p\n      className={cn(\"text-sm font-medium text-destructive\", className)}\n      id={errorId}\n      ref={ref}\n      role=\"alert\"\n      {...props}\n    >\n      {children}\n    </p>\n  );\n};\nFieldError.displayName = \"FieldError\";\n\nexport {\n  Field,\n  FieldControl,\n  FieldDescription,\n  FieldError,\n  FieldLabel,\n  fieldVariants,\n};\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component",
  "version": "0.2.1",
  "stability": "stable"
}
