{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "input",
  "title": "Input",
  "description": "The text field foundation with adornments, size variants, and animated focus ring.",
  "dependencies": [],
  "files": [
    {
      "path": "components/ui/input.tsx",
      "type": "registry:ui",
      "content": "'use client'\n\nimport { forwardRef, useId, type InputHTMLAttributes, type ReactNode } from 'react'\nimport { AnimatePresence, motion, useReducedMotion } from 'motion/react'\nimport { cn } from '@/lib/utils'\nimport { playHoverSound } from '@/lib/sound'\nimport { springs } from '@/lib/motion-tokens'\n\nconst sizeClasses = {\n  sm: 'h-9 text-xs',\n  md: 'h-11 text-sm',\n} as const\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {\n  size?: 'sm' | 'md'\n  startAdornment?: ReactNode\n  endAdornment?: ReactNode\n  label?: string\n  error?: string\n  containerClassName?: string\n}\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n  (\n    {\n      size = 'md',\n      startAdornment,\n      endAdornment,\n      label,\n      error,\n      containerClassName,\n      className,\n      id: idProp,\n      disabled,\n      required,\n      'aria-invalid': ariaInvalid,\n      'aria-describedby': ariaDescribedBy,\n      ...props\n    },\n    ref,\n  ) => {\n    const reactId = useId()\n    const id = idProp ?? reactId\n    const errorId = error ? `${id}-error` : undefined\n    const reduceMotion = useReducedMotion()\n\n    return (\n      <div className={cn('flex flex-col gap-1.5', containerClassName)}>\n        {label && (\n          <label htmlFor={id} className=\"text-sm font-medium text-(--color-fg)\">\n            {label}\n            {required && <span className=\"ms-1 text-(--color-error)\">*</span>}\n          </label>\n        )}\n        <div\n          onMouseEnter={() => !disabled && playHoverSound()}\n          className={cn(\n            'relative flex items-center gap-1.5 rounded-lg squircle-corners border bg-(--color-bg) px-3.5',\n            'transition-[border-color,box-shadow] duration-(--motion-dur-fast) ease-(--motion-ease-out) motion-reduce:transition-none',\n            sizeClasses[size],\n            error\n              ? 'border-(--color-error) ring-1 ring-(--color-error)/20'\n              : 'border-(--color-border) hover:border-(--color-border-strong) focus-within:border-(--color-accent) focus-within:ring-2 focus-within:ring-(--color-accent)/20',\n            disabled && 'cursor-not-allowed opacity-50',\n          )}\n        >\n          {startAdornment && (\n            <span className=\"shrink-0 text-(--color-muted)\" aria-hidden=\"true\">\n              {startAdornment}\n            </span>\n          )}\n          <input\n            ref={ref}\n            id={id}\n            disabled={disabled}\n            required={required}\n            aria-invalid={ariaInvalid || !!error || undefined}\n            aria-describedby={ariaDescribedBy || errorId}\n            className={cn(\n              'flex-1 bg-transparent text-(--color-fg) outline-none placeholder:text-(--color-muted)',\n              disabled && 'cursor-not-allowed',\n              className,\n            )}\n            {...props}\n          />\n          {endAdornment && (\n            <span className=\"shrink-0 text-(--color-muted)\" aria-hidden=\"true\">\n              {endAdornment}\n            </span>\n          )}\n        </div>\n        <AnimatePresence>\n          {error && (\n            <motion.p\n              key=\"error\"\n              id={errorId}\n              role=\"alert\"\n              initial={reduceMotion ? false : { opacity: 0, y: 6 }}\n              animate={{ opacity: 1, y: 0 }}\n              exit={reduceMotion ? undefined : { opacity: 0, y: 6 }}\n              transition={reduceMotion ? { duration: 0 } : springs.settle}\n              className=\"text-xs text-(--color-error)\"\n            >\n              {error}\n            </motion.p>\n          )}\n        </AnimatePresence>\n      </div>\n    )\n  },\n)\nInput.displayName = 'Input'\n\nexport function InputPreview() {\n  return (\n    <div className=\"flex h-full w-full items-center justify-center p-6\">\n      <div className=\"w-72 space-y-4\">\n        <Input label=\"Email\" placeholder=\"you@example.com\" />\n        <Input\n          label=\"Password\"\n          type=\"password\"\n          placeholder=\"Enter password\"\n          error=\"Password is required\"\n        />\n        <Input\n          label=\"Search\"\n          size=\"sm\"\n          placeholder=\"Search…\"\n          startAdornment={\n            <svg\n              width=\"16\"\n              height=\"16\"\n              viewBox=\"0 0 16 16\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth=\"1.5\"\n            >\n              <circle cx=\"7\" cy=\"7\" r=\"5\" />\n              <path d=\"M11 11l3.5 3.5\" />\n            </svg>\n          }\n        />\n      </div>\n    </div>\n  )\n}\n"
    }
  ],
  "type": "registry:ui"
}
