{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "input",
  "title": "Input",
  "description": "A styled text input.",
  "dependencies": [
    "@base-ui/react",
    "lucide-react"
  ],
  "registryDependencies": [
    "https://ui.ask.mir-ai.it/r/utils.json"
  ],
  "files": [
    {
      "path": "src/registry/ask-ui/components/ui/input/input.tsx",
      "content": "import * as React from \"react\";\nimport { Input as InputPrimitive } from \"@base-ui/react/input\";\nimport { XIcon } from \"lucide-react\";\n\nimport { cn } from \"@/registry/ask-ui/lib/utils\";\n\nconst pickerIndicator =\n  \"[&::-webkit-calendar-picker-indicator]:cursor-pointer [&::-webkit-calendar-picker-indicator]:opacity-60 [&::-webkit-calendar-picker-indicator]:hover:opacity-100\";\n\n// The empty-state \"dd/mm/yyyy\"-style segments aren't a real `::placeholder`\n// (that pseudo-element doesn't apply to date/time inputs) — they're the\n// `::-webkit-datetime-edit` fields, which inherit the input's own text\n// color by default, rendering noticeably darker than every other input's\n// placeholder. `:placeholder-shown` does NOT match these types in Chrome\n// (verified directly — it stays `false` even with a `placeholder` attribute\n// set), so this relies on the `data-empty` attribute the component itself\n// tracks and sets below instead.\nconst datetimeEditPlaceholder =\n  \"data-empty:[&::-webkit-datetime-edit]:text-muted-foreground\";\n\nconst customSearchClearButton =\n  \"[&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none\";\n\n// Lightly styles native date/time picker indicators and color swatches without\n// removing their built-in functionality. None of these have a Figma reference\n// yet, see ROADMAP.md.\nconst typeClasses: Partial<Record<React.HTMLInputTypeAttribute, string>> = {\n  date: cn(pickerIndicator, datetimeEditPlaceholder),\n  time: cn(pickerIndicator, datetimeEditPlaceholder),\n  \"datetime-local\": cn(pickerIndicator, datetimeEditPlaceholder),\n  month: cn(pickerIndicator, datetimeEditPlaceholder),\n  week: cn(pickerIndicator, datetimeEditPlaceholder),\n  color: \"p-1\",\n};\n\nconst nativeValueSetter =\n  typeof window !== \"undefined\"\n    ? Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, \"value\")\n        ?.set\n    : undefined;\n\nexport interface InputProps\n  extends Omit<\n    InputPrimitive.Props,\n    \"className\" | \"ref\" | \"render\"\n  > {\n  className?: string;\n  ref?: React.Ref<HTMLInputElement>;\n  /**\n   * Shows a clear (\"x\") button once the input has a value, for text-like\n   * types. Clicking it empties the input and refocuses it, and fires\n   * `onChange` like a normal edit — works for both controlled and\n   * uncontrolled usage.\n   */\n  clearable?: boolean;\n}\n\n/**\n * A styled text input. Height, padding and font size match the Figma spec\n * (44px, text-base at every breakpoint) rather than shadcn's stock, denser\n * defaults.\n */\nfunction Input({\n  className,\n  type = \"text\",\n  clearable = false,\n  value,\n  defaultValue,\n  disabled,\n  onChange,\n  ref,\n  ...props\n}: InputProps) {\n  const inputRef = React.useRef<HTMLInputElement>(null);\n  const setInputRef = React.useCallback(\n    (node: HTMLInputElement | null) => {\n      inputRef.current = node;\n\n      if (typeof ref === \"function\") {\n        ref(node);\n      } else if (ref) {\n        ref.current = node;\n      }\n    },\n    [ref]\n  );\n  // Tracks the value only for uncontrolled usage; when `value` is passed,\n  // it's the source of truth directly, so no effect/sync is needed.\n  const [uncontrolledHasValue, setUncontrolledHasValue] = React.useState(() =>\n    String(defaultValue ?? \"\").length > 0\n  );\n  const hasValue =\n    value !== undefined ? String(value).length > 0 : uncontrolledHasValue;\n\n  React.useEffect(() => {\n    const inputElement = inputRef.current;\n    const form = inputElement?.form;\n\n    if (!clearable || value !== undefined || !inputElement || !form) {\n      return;\n    }\n\n    let resetTimer: ReturnType<typeof setTimeout> | undefined;\n\n    const handleReset = () => {\n      // A reset event fires before every browser has applied the form's\n      // default values. Read the input in the next task, once that native\n      // reset action has completed.\n      resetTimer = setTimeout(() => {\n        setUncontrolledHasValue(inputElement.value.length > 0);\n      }, 0);\n    };\n\n    form.addEventListener(\"reset\", handleReset);\n    return () => {\n      form.removeEventListener(\"reset\", handleReset);\n      clearTimeout(resetTimer);\n    };\n  }, [clearable, value]);\n\n  const input = (\n    <InputPrimitive\n      ref={setInputRef}\n      type={type}\n      data-slot=\"input\"\n      data-empty={hasValue ? undefined : true}\n      value={value}\n      defaultValue={defaultValue}\n      disabled={disabled}\n      className={cn(\n        \"h-11 w-full min-w-0 rounded-md border border-input bg-background px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40\",\n        typeClasses[type],\n        clearable && type === \"search\" && customSearchClearButton,\n        clearable && \"pr-9\",\n        className\n      )}\n      onChange={(e) => {\n        setUncontrolledHasValue(e.target.value.length > 0);\n        onChange?.(e);\n      }}\n      {...props}\n    />\n  );\n\n  if (!clearable) {\n    return input;\n  }\n\n  return (\n    <div className=\"relative\">\n      {input}\n      {hasValue && !disabled && (\n        <button\n          type=\"button\"\n          aria-label=\"Clear\"\n          data-slot=\"input-clear\"\n          className=\"absolute inset-y-0 right-0 flex items-center pr-3 text-muted-foreground outline-none hover:text-foreground focus-visible:text-foreground\"\n          onClick={() => {\n            const el = inputRef.current;\n            if (!el) return;\n            nativeValueSetter?.call(el, \"\");\n            el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n            el.focus();\n          }}\n        >\n          <XIcon className=\"size-4\" />\n        </button>\n      )}\n    </div>\n  );\n}\n\nexport { Input };\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}