{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "input",
  "title": "Input",
  "description": "Ink-framed text input with accessible label, hint, and marker-flagged error message.",
  "registryDependencies": [
    "https://frame12.dev/r/frame12-styles.json",
    "https://frame12.dev/r/field.json"
  ],
  "files": [
    {
      "path": "ui/input.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\nimport { useFieldContext } from './field';\n\nexport type InputDensity = 'comfortable' | 'compact';\n\nexport interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n  label?: React.ReactNode;\n  hint?: React.ReactNode;\n  error?: React.ReactNode;\n  density?: InputDensity;\n  fieldClassName?: string;\n}\n\nconst useIsomorphicLayoutEffect =\n  typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(function Input(\n  {\n    id,\n    label,\n    hint,\n    error,\n    density,\n    disabled,\n    required,\n    className = '',\n    fieldClassName = '',\n    'aria-describedby': userDescribedBy,\n    'aria-invalid': userAriaInvalid,\n    ...rest\n  },\n  ref,\n) {\n  const fieldCtx = useFieldContext();\n  const autoId = React.useId().replace(/:/g, '');\n  const effectiveDensity: InputDensity = density ?? fieldCtx?.density ?? 'comfortable';\n  const isCompact = effectiveDensity === 'compact';\n  const inputId =\n    id || (!fieldCtx?.isControlGroup ? fieldCtx?.id : undefined) || `f12-input-${autoId}`;\n  const showOwnLabel = Boolean(label && (!fieldCtx?.labelId || fieldCtx?.isControlGroup));\n  const showOwnHint = Boolean(hint && !fieldCtx?.hintId);\n  const showOwnError = Boolean(error && !fieldCtx?.errorId);\n  const hintId = showOwnHint ? `${inputId}-hint` : undefined;\n  const errorId = showOwnError ? `${inputId}-error` : undefined;\n  const describedBy =\n    [userDescribedBy, fieldCtx?.describedBy, hintId, errorId].filter(Boolean).join(' ') ||\n    undefined;\n  const effectiveInvalid = error || fieldCtx?.invalid ? true : userAriaInvalid;\n  const effectiveDisabled = disabled ?? fieldCtx?.disabled;\n  const effectiveRequired = required ?? fieldCtx?.required;\n\n  const registerControlId = fieldCtx?.registerControlId;\n  useIsomorphicLayoutEffect(() => {\n    return registerControlId?.(autoId, id);\n  }, [registerControlId, autoId, id]);\n\n  const inputElement = (\n    <input\n      ref={ref}\n      id={inputId}\n      disabled={effectiveDisabled}\n      required={effectiveRequired}\n      className={`f12-input${isCompact ? ' f12-input-compact' : ''}${className ? ` ${className}` : ''}`}\n      aria-describedby={describedBy}\n      aria-invalid={effectiveInvalid}\n      {...rest}\n    />\n  );\n\n  if (fieldCtx && !showOwnLabel && !showOwnHint && !showOwnError) {\n    return inputElement;\n  }\n\n  return (\n    <div\n      className={`f12-field${isCompact ? ' f12-field-compact' : ''}${fieldClassName ? ` ${fieldClassName}` : ''}`}\n      data-density={isCompact ? 'compact' : undefined}\n      data-disabled={effectiveDisabled ? '' : undefined}\n    >\n      {showOwnLabel && (\n        <label htmlFor={inputId} className=\"f12-label\">\n          {label}\n          {effectiveRequired && (\n            <span className=\"f12-field-req\" aria-hidden=\"true\">\n              {' '}\n              *\n            </span>\n          )}\n        </label>\n      )}\n      {inputElement}\n      {showOwnHint && (\n        <p id={hintId} className=\"f12-hint\">\n          {hint}\n        </p>\n      )}\n      {showOwnError && (\n        <p id={errorId} className=\"f12-error\" role=\"alert\">\n          <span className=\"f12-error-flag\" aria-hidden=\"true\">\n            !\n          </span>\n          <span>{error}</span>\n        </p>\n      )}\n    </div>\n  );\n});\n\n(Input as unknown as { f12IsControl?: boolean }).f12IsControl = true;\n",
      "type": "registry:ui",
      "target": "components/frame12/input.tsx"
    }
  ],
  "type": "registry:ui"
}