{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "field-input",
  "type": "registry:ui",
  "title": "Field Input",
  "description": "A field input component",
  "files": [
    {
      "path": "src/registry/ui/field-input.tsx",
      "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { type VariantProps, cva } from \"class-variance-authority\";\nimport { EyeIcon, EyeOffIcon } from \"lucide-react\";\nimport * as React from \"react\";\n\nexport const containerVariants = cva(\n  cn(\n    \"flex w-full px-2.5 relative rounded-lg\",\n    \"text-base cursor-text\",\n    \"data-[is-invalid=true]:border-destructive\",\n    \"data-[disabled=true]:opacity-70 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:hover:border-input\",\n    \"hover:border-ring focus-within:border-ring\",\n    \"transition-all duration-200\",\n  ),\n  {\n    variants: {\n      variant: {\n        default: \"bg-muted border-2 border-input\",\n        faded: cn(\n          \"bg-muted border-2 border-muted\",\n          \"hover:bg-accent hover:border-accent\",\n          \"focus-within:bg-accent focus-within:border-accent\",\n          \"data-[disabled=true]:hover:bg-muted data-[disabled=true]:hover:border-muted\",\n        ),\n        bordered: \"border-2 border-input\",\n        underline: \"border-b-2 border-input rounded-none\",\n      },\n      size: {\n        sm: \"h-12 py-1.5\",\n        md: \"h-14 py-2\",\n        lg: \"h-16 py-2\",\n      },\n    },\n    compoundVariants: [\n      {\n        variant: \"underline\",\n        size: \"sm\",\n        className: \"px-1 h-11\",\n      },\n      {\n        variant: \"underline\",\n        size: \"md\",\n        className: \"px-1 h-13\",\n      },\n      {\n        variant: \"underline\",\n        size: \"lg\",\n        className: \"px-1 h-14\",\n      },\n    ],\n    defaultVariants: {\n      variant: \"default\",\n      size: \"md\",\n    },\n  },\n);\n\nconst inputVariants = cva(\n  cn(\n    \"w-full outline-hidden\",\n    \"disabled:cursor-not-allowed\",\n    \"bg-transparent\",\n    \"[&:-webkit-autofill]:bg-transparent\",\n    \"[&:-webkit-autofill:hover]:bg-transparent\",\n    \"[&:-webkit-autofill:focus]:bg-transparent\",\n    \"[&:-webkit-autofill:active]:bg-transparent\",\n    \"[&:-webkit-autofill]:[transition-delay:9999s]\",\n  ),\n  {\n    variants: {\n      size: {\n        sm: \"text-sm\",\n        md: \"text-sm\",\n        lg: \"text-md\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  },\n);\n\nconst labelVariants = cva(\n  cn(\n    \"absolute left-0 top-1/2 -translate-y-1/2 origin-top-left pointer-events-none\",\n    \"text-accent-foreground/70\",\n    \"transition-all duration-200\",\n    \"group-data-[is-invalid=true]:text-destructive\",\n  ),\n  {\n    variants: {\n      size: {\n        sm: \"text-sm group-focus-within:scale-85 group-focus-within:-translate-y-4.5 group-data-[zoom-out=true]:scale-85 group-data-[zoom-out=true]:-translate-y-4.5\",\n        md: \"text-sm group-focus-within:scale-85 group-focus-within:-translate-y-5 group-data-[zoom-out=true]:scale-85 group-data-[zoom-out=true]:-translate-y-5\",\n        lg: \"text-md group-focus-within:scale-85 group-focus-within:-translate-y-6 group-data-[zoom-out=true]:scale-85 group-data-[zoom-out=true]:-translate-y-6\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  },\n);\n\ninterface FieldInputProps\n  extends Omit<React.ComponentProps<\"input\">, \"size\">,\n    VariantProps<typeof containerVariants> {\n  id: string;\n  label: string;\n  inputClassName?: string;\n  startContent?: React.ReactNode;\n  endContent?: React.ReactNode;\n}\n\nconst FieldInput = React.forwardRef<HTMLInputElement, FieldInputProps>(\n  (\n    {\n      className,\n      inputClassName,\n      type,\n      placeholder,\n      value,\n      defaultValue,\n      variant,\n      size,\n      label,\n      \"aria-invalid\": ariaInvalid,\n      disabled,\n      startContent,\n      endContent,\n      ...props\n    },\n    ref,\n  ) => {\n    const [showPassword, setShowPassword] = React.useState(false);\n    const [uncontrolledValue, setUncontrolledValue] = React.useState(\n      defaultValue || \"\",\n    );\n    const inputRef = React.useRef<HTMLInputElement>(null);\n    React.useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(\n      ref,\n      () => inputRef.current,\n    );\n\n    const isControlled = value !== undefined;\n    const currentValue = isControlled ? value : uncontrolledValue;\n    const zoomOut =\n      Boolean(currentValue) || !!placeholder || !!startContent || !!endContent;\n\n    const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n      if (!isControlled) {\n        setUncontrolledValue(e.target.value);\n      }\n      props.onChange?.(e);\n    };\n\n    const endContentRender = () => {\n      if (endContent) {\n        return endContent;\n      }\n\n      if (type === \"password\") {\n        return (\n          <button\n            aria-label=\"Change password visibility\"\n            type=\"button\"\n            className=\"cursor-pointer\"\n            onClick={() => setShowPassword(!showPassword)}\n          >\n            {!showPassword ? <EyeOffIcon size={20} /> : <EyeIcon size={20} />}\n          </button>\n        );\n      }\n\n      return null;\n    };\n\n    return (\n      <div\n        className={cn(\n          containerVariants({ variant, size }),\n          \"group flex items-center justify-center gap-1.5\",\n          className,\n        )}\n        data-is-invalid={ariaInvalid?.toString()}\n        data-disabled={disabled?.toString()}\n        data-zoom-out={zoomOut.toString()}\n        onClick={() => {\n          if (!disabled && inputRef.current) {\n            inputRef.current.focus();\n          }\n        }}\n      >\n        <div className=\"inline-flex w-full items-end gap-1.5 h-full relative\">\n          {startContent && startContent}\n          <input\n            type={\n              type === \"password\" && endContent === undefined && showPassword\n                ? \"text\"\n                : type\n            }\n            ref={inputRef}\n            className={cn(inputVariants({ size }), inputClassName)}\n            disabled={disabled}\n            placeholder={placeholder}\n            {...(isControlled ? { value: currentValue } : { defaultValue })}\n            {...props}\n            onChange={handleChange}\n          />\n          {endContentRender()}\n          <label htmlFor={props.id} className={cn(labelVariants({ size }))}>\n            {label}\n          </label>\n        </div>\n      </div>\n    );\n  },\n);\n\nFieldInput.displayName = \"FieldInput\";\n\nexport { FieldInput, type FieldInputProps };\n",
      "type": "registry:ui",
      "target": "components/wed/field-input.tsx"
    }
  ]
}