{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "input",
  "type": "registry:ui",
  "title": "Input",
  "description": "Native <input> with shadcn styling, sized for htmx live-validation patterns. Ships in five flavours.",
  "files": [
    {
      "path": "registry/ui/input.tsx",
      "type": "registry:ui",
      "target": "components/ui/input.tsx",
      "content": "/** @jsxImportSource hono/jsx */\nimport { cn, type ClassValue } from \"@/registry/lib/cn\"\n\n// Native <input> with shadcn styling. Source of truth:\n//   repos/shadcn-ui/apps/v4/registry/new-york-v4/ui/input.tsx\n//\n// We render a real <input> so every native behaviour is preserved:\n// constraint validation (required, pattern, min/max), client-side autofill,\n// browser autocomplete, and the input-mode keyboards on mobile.\n\nexport type InputType =\n  | \"text\"\n  | \"password\"\n  | \"email\"\n  | \"number\"\n  | \"search\"\n  | \"tel\"\n  | \"url\"\n  | \"date\"\n  | \"time\"\n  | \"datetime-local\"\n  | \"month\"\n  | \"week\"\n  | \"color\"\n  | \"file\"\n  | \"hidden\"\n\nconst base =\n  \"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none \" +\n  \"selection:bg-primary selection:text-primary-foreground \" +\n  \"file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground \" +\n  \"placeholder:text-muted-foreground \" +\n  \"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 \" +\n  \"md:text-sm dark:bg-input/30 \" +\n  \"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 \" +\n  \"aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 \" +\n  // htmx-request: dim while a request triggered by/targeting this input is\n  // in flight (e.g. live-validation patterns).\n  \"[&.htmx-request]:opacity-70\"\n\nexport function inputClasses(opts?: { class?: ClassValue }): string {\n  return cn(base, opts?.class)\n}\n\ntype InputProps = {\n  type?: InputType\n  class?: ClassValue\n  id?: string\n  name?: string\n  value?: string | number\n  defaultValue?: string | number\n  placeholder?: string\n  required?: boolean\n  disabled?: boolean\n  readonly?: boolean\n\n  // String/numeric constraints. The browser enforces these natively when the\n  // input is inside a <form> that submits.\n  minLength?: number\n  maxLength?: number\n  min?: number | string\n  max?: number | string\n  step?: number | string\n  pattern?: string\n\n  // Mobile UX: hint to the OS keyboard layout (numeric, decimal, email, …)\n  // and the Enter key label (done, search, send, …).\n  inputmode?: \"none\" | \"text\" | \"decimal\" | \"numeric\" | \"tel\" | \"search\" | \"email\" | \"url\"\n  enterkeyhint?: \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"search\" | \"send\"\n\n  // Submits the text directionality (ltr/rtl) as a separate form field\n  // named by this attribute's value. Critical for multilingual forms — the\n  // server can preserve the writer's intent even if it doesn't speak the\n  // language. Valid for text/search/url/tel/email.\n  // See repos/mdn/files/en-us/web/html/reference/elements/input/index.md:357\n  dirname?: string\n\n  // type=\"file\" only — request the OS camera with a specific facing mode.\n  capture?: \"user\" | \"environment\" | boolean\n\n  // Mobile keyboard capitalisation. iOS/Safari honour this aggressively;\n  // most useful as \"off\" for email/password/url where auto-caps is wrong.\n  autocapitalize?: \"off\" | \"none\" | \"on\" | \"sentences\" | \"words\" | \"characters\"\n\n  // Spellcheck hint (enumerated global attribute). Set \"false\" for fields\n  // holding PII, codes, usernames, or tokens — spellcheck content may be\n  // sent to a third party (\"spell-jacking\").\n  // See repos/mdn/files/en-us/web/html/reference/global_attributes/spellcheck/index.md\n  spellcheck?: boolean\n\n  // Autocorrect hint (enumerated global attribute, on/off). Disable for\n  // names, usernames, addresses, or coupon/API codes where OS autocorrect\n  // is harmful. password/email/url are always \"off\" per spec.\n  // See repos/mdn/files/en-us/web/html/reference/global_attributes/autocorrect/index.md\n  autocorrect?: \"on\" | \"off\"\n\n  // Visible width in characters for text/email/password/tel/url. Mostly\n  // superseded by CSS but useful for graceful fallback rendering.\n  size?: number\n\n  // Autofill / completion.\n  autocomplete?: string\n  autofocus?: boolean\n  list?: string\n\n  // For type=\"file\".\n  accept?: string\n  multiple?: boolean\n\n  // ARIA\n  ariaLabel?: string\n  ariaLabelledby?: string\n  ariaDescribedby?: string\n  ariaInvalid?: boolean | \"grammar\" | \"spelling\"\n  ariaRequired?: boolean\n\n  // Form metadata\n  form?: string\n\n  // htmx v4 attributes (subset). htmx fires hx-* on the trigger event, default\n  // for an input is \"change\" (or \"input\" for type=search). Use hx-trigger to\n  // override, e.g. hx-trigger=\"input changed delay:300ms\".\n  // See repos/htmx/www/src/content/reference/01-attributes/.\n  \"hx-get\"?: string\n  \"hx-post\"?: string\n  \"hx-put\"?: string\n  \"hx-patch\"?: string\n  \"hx-target\"?: string\n  \"hx-swap\"?: string\n  \"hx-trigger\"?: string\n  \"hx-indicator\"?: string\n  \"hx-vals\"?: string\n  \"hx-include\"?: string\n  \"hx-disable\"?: string\n}\n\nexport function Input(props: InputProps) {\n  const {\n    type = \"text\",\n    class: className,\n    ariaLabel,\n    ariaLabelledby,\n    ariaDescribedby,\n    ariaInvalid,\n    ariaRequired,\n    ...rest\n  } = props\n\n  return (\n    <input\n      type={type}\n      class={inputClasses({ class: className })}\n      aria-label={ariaLabel}\n      aria-labelledby={ariaLabelledby}\n      aria-describedby={ariaDescribedby}\n      aria-invalid={ariaInvalid === undefined ? undefined : String(ariaInvalid)}\n      aria-required={ariaRequired === undefined ? undefined : String(ariaRequired)}\n      data-slot=\"input\"\n      {...rest}\n    />\n  )\n}\n"
    },
    {
      "path": "registry/jinja2/input.html",
      "type": "registry:file",
      "target": "templates/components/input.html",
      "content": "{# Input macro — shadcn-htmx, htmx v4 + Tailwind v4.\n   Mirrors registry/ui/input.tsx for Python/Flask/FastAPI/Django/Jinja2.\n\n   Usage:\n       {% from \"components/input.html\" import input %}\n       {{ input(name=\"email\", type=\"email\", placeholder=\"you@example.com\") }}\n       {{ input(name=\"q\", type=\"search\",\n                hx_get=\"/search\", hx_target=\"#results\",\n                hx_trigger=\"input changed delay:300ms\") }}\n\n   All hx-* attributes are passed through via **attrs (underscores become\n   dashes, so `hx_get=\"/search\"` emits `hx-get=\"/search\"`).\n   See repos/htmx/www/src/content/reference/01-attributes/. #}\n\n{% macro input(\n    type=\"text\",\n    id=none,\n    name=none,\n    value=none,\n    placeholder=none,\n    required=false,\n    disabled=false,\n    readonly=false,\n    minlength=none,\n    maxlength=none,\n    min=none,\n    max=none,\n    step=none,\n    pattern=none,\n    inputmode=none,\n    enterkeyhint=none,\n    autocomplete=none,\n    autocapitalize=none,\n    spellcheck=none,\n    autocorrect=none,\n    autofocus=false,\n    list=none,\n    accept=none,\n    capture=none,\n    multiple=false,\n    size=none,\n    dirname=none,\n    form=none,\n    aria_label=none,\n    aria_labelledby=none,\n    aria_describedby=none,\n    aria_invalid=none,\n    aria_required=none,\n    extra_class=\"\",\n    **attrs\n) %}\n{%- set base -%}\nflex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground 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 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&.htmx-request]:opacity-70\n{%- endset -%}\n<input type=\"{{ type }}\"\n       class=\"{{ base }} {{ extra_class }}\"\n       {%- if id %} id=\"{{ id }}\"{% endif %}\n       {%- if name %} name=\"{{ name }}\"{% endif %}\n       {%- if value is not none %} value=\"{{ value }}\"{% endif %}\n       {%- if placeholder %} placeholder=\"{{ placeholder }}\"{% endif %}\n       {%- if required %} required{% endif %}\n       {%- if disabled %} disabled{% endif %}\n       {%- if readonly %} readonly{% endif %}\n       {%- if minlength is not none %} minlength=\"{{ minlength }}\"{% endif %}\n       {%- if maxlength is not none %} maxlength=\"{{ maxlength }}\"{% endif %}\n       {%- if min is not none %} min=\"{{ min }}\"{% endif %}\n       {%- if max is not none %} max=\"{{ max }}\"{% endif %}\n       {%- if step is not none %} step=\"{{ step }}\"{% endif %}\n       {%- if pattern %} pattern=\"{{ pattern }}\"{% endif %}\n       {%- if inputmode %} inputmode=\"{{ inputmode }}\"{% endif %}\n       {%- if enterkeyhint %} enterkeyhint=\"{{ enterkeyhint }}\"{% endif %}\n       {%- if autocomplete %} autocomplete=\"{{ autocomplete }}\"{% endif %}\n       {%- if autocapitalize %} autocapitalize=\"{{ autocapitalize }}\"{% endif %}\n       {# spellcheck/autocorrect: enumerated global attrs — see repos/mdn/files/en-us/web/html/reference/global_attributes/spellcheck/index.md #}\n       {%- if spellcheck is not none %} spellcheck=\"{{ 'true' if spellcheck else 'false' }}\"{% endif %}\n       {%- if autocorrect %} autocorrect=\"{{ autocorrect }}\"{% endif %}\n       {%- if autofocus %} autofocus{% endif %}\n       {%- if list %} list=\"{{ list }}\"{% endif %}\n       {%- if accept %} accept=\"{{ accept }}\"{% endif %}\n       {%- if capture is not none %} capture{% if capture is string %}=\"{{ capture }}\"{% endif %}{% endif %}\n       {%- if multiple %} multiple{% endif %}\n       {%- if size is not none %} size=\"{{ size }}\"{% endif %}\n       {%- if dirname %} dirname=\"{{ dirname }}\"{% endif %}\n       {%- if form %} form=\"{{ form }}\"{% endif %}\n       {%- if aria_label %} aria-label=\"{{ aria_label }}\"{% endif %}\n       {%- if aria_labelledby %} aria-labelledby=\"{{ aria_labelledby }}\"{% endif %}\n       {%- if aria_describedby %} aria-describedby=\"{{ aria_describedby }}\"{% endif %}\n       {%- if aria_invalid is not none %} aria-invalid=\"{{ aria_invalid|string|lower }}\"{% endif %}\n       {%- if aria_required is not none %} aria-required=\"{{ aria_required|string|lower }}\"{% endif %}\n       data-slot=\"input\"\n       {%- for k, v in attrs.items() %} {{ k|replace('_', '-') }}=\"{{ v }}\"{% endfor -%}\n>\n{% endmacro %}\n"
    },
    {
      "path": "registry/go-templates/input.tmpl",
      "type": "registry:file",
      "target": "components/input.tmpl",
      "content": "{{/*\n  Input template — shadcn-htmx, htmx v4 + Tailwind v4.\n  Mirrors registry/ui/input.tsx for Go projects using html/template.\n\n  Usage in your code:\n\n      type InputArgs struct {\n          Type        string // text | password | email | number | search | tel | url | date | …\n          ID          string\n          Name        string\n          Value       string\n          Placeholder string\n          Required    bool\n          Disabled    bool\n          Readonly    bool\n\n          // Validation\n          MinLength int\n          MaxLength int\n          Min       string\n          Max       string\n          Step      string\n          Pattern   string\n\n          // Mobile UX\n          InputMode      string // none | text | decimal | numeric | tel | search | email | url\n          EnterKeyHint   string // enter | done | go | next | previous | search | send\n          Autocapitalize string // off | none | on | sentences | words | characters\n          Spellcheck     *bool  // tri-state spellcheck hint (enumerated global attr)\n          Autocorrect    string // \"\" | on | off  (enumerated global attr)\n\n          // Autofill / completion\n          Autocomplete string\n          Autofocus    bool\n          List         string // datalist id\n\n          // type=\"file\"\n          Accept   string\n          Multiple bool\n          Capture  string // \"\" | \"user\" | \"environment\" | \"true\"\n\n          // Display / form behaviour\n          Size    string // visible width in characters\n          Dirname string // submits text directionality as a separate field\n\n          // Form metadata\n          Form string\n\n          // ARIA\n          AriaLabel       string\n          AriaLabelledby  string\n          AriaDescribedby string\n          AriaInvalid     string // \"true\" | \"false\" | \"grammar\" | \"spelling\"\n          AriaRequired    string // \"true\" | \"false\"\n\n          // Everything else (hx-get, hx-target, hx-trigger, …)\n          Attrs map[string]string\n      }\n\n      tpl.ExecuteTemplate(w, \"input\", InputArgs{\n          Type: \"email\", Name: \"email\",\n          Placeholder: \"you@example.com\",\n          Required: true,\n      })\n\n  See repos/mdn/files/en-us/web/html/reference/elements/input/ for native\n  attribute semantics.\n*/}}\n\n{{define \"input\"}}\n{{- $type := or .Type \"text\" -}}\n{{- $base := \"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground 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 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&.htmx-request]:opacity-70\" -}}\n<input type=\"{{$type}}\"\n       class=\"{{$base}}\"\n       {{- if .ID}} id=\"{{.ID}}\"{{end}}\n       {{- if .Name}} name=\"{{.Name}}\"{{end}}\n       {{- if .Value}} value=\"{{.Value}}\"{{end}}\n       {{- if .Placeholder}} placeholder=\"{{.Placeholder}}\"{{end}}\n       {{- if .Required}} required{{end}}\n       {{- if .Disabled}} disabled{{end}}\n       {{- if .Readonly}} readonly{{end}}\n       {{- if .MinLength}} minlength=\"{{.MinLength}}\"{{end}}\n       {{- if .MaxLength}} maxlength=\"{{.MaxLength}}\"{{end}}\n       {{- if .Min}} min=\"{{.Min}}\"{{end}}\n       {{- if .Max}} max=\"{{.Max}}\"{{end}}\n       {{- if .Step}} step=\"{{.Step}}\"{{end}}\n       {{- if .Pattern}} pattern=\"{{.Pattern}}\"{{end}}\n       {{- if .InputMode}} inputmode=\"{{.InputMode}}\"{{end}}\n       {{- if .EnterKeyHint}} enterkeyhint=\"{{.EnterKeyHint}}\"{{end}}\n       {{- if .Autocomplete}} autocomplete=\"{{.Autocomplete}}\"{{end}}\n       {{- if .Autocapitalize}} autocapitalize=\"{{.Autocapitalize}}\"{{end}}\n       {{- /* spellcheck/autocorrect: enumerated global attrs — repos/mdn/files/en-us/web/html/reference/global_attributes/spellcheck/index.md */ -}}\n       {{- if .Spellcheck}} spellcheck=\"{{if deref .Spellcheck}}true{{else}}false{{end}}\"{{end}}\n       {{- if .Autocorrect}} autocorrect=\"{{.Autocorrect}}\"{{end}}\n       {{- if .Autofocus}} autofocus{{end}}\n       {{- if .List}} list=\"{{.List}}\"{{end}}\n       {{- if .Accept}} accept=\"{{.Accept}}\"{{end}}\n       {{- if .Capture}} capture{{if ne .Capture \"true\"}}=\"{{.Capture}}\"{{end}}{{end}}\n       {{- if .Multiple}} multiple{{end}}\n       {{- if .Size}} size=\"{{.Size}}\"{{end}}\n       {{- if .Dirname}} dirname=\"{{.Dirname}}\"{{end}}\n       {{- if .Form}} form=\"{{.Form}}\"{{end}}\n       {{- if .AriaLabel}} aria-label=\"{{.AriaLabel}}\"{{end}}\n       {{- if .AriaLabelledby}} aria-labelledby=\"{{.AriaLabelledby}}\"{{end}}\n       {{- if .AriaDescribedby}} aria-describedby=\"{{.AriaDescribedby}}\"{{end}}\n       {{- if .AriaInvalid}} aria-invalid=\"{{.AriaInvalid}}\"{{end}}\n       {{- if .AriaRequired}} aria-required=\"{{.AriaRequired}}\"{{end}}\n       data-slot=\"input\"\n       {{- range $k, $v := .Attrs}} {{$k}}=\"{{$v}}\"{{end -}}\n>\n{{end}}\n"
    },
    {
      "path": "registry/phoenix/input.ex",
      "type": "registry:file",
      "target": "lib/my_app_web/components/input.ex",
      "content": "defmodule ShadcnHtmx.Components.Input do\n  @moduledoc \"\"\"\n  Input — shadcn-htmx, htmx v4 + Tailwind v4 for Phoenix.\n\n  Mirrors registry/ui/input.tsx. Works with plain HEEx and LiveView forms;\n  htmx attributes and any other input attribute pass through via `:rest`.\n\n  ## Examples\n\n      <.input type=\"email\" name=\"email\" placeholder=\"you@example.com\" required />\n      <.input type=\"search\" name=\"q\"\n              hx-get=\"/search\" hx-target=\"#results\"\n              hx-trigger=\"input changed delay:300ms\" />\n\n  See repos/mdn/files/en-us/web/html/reference/elements/input/ for native\n  attribute semantics.\n  \"\"\"\n\n  use Phoenix.Component\n\n  @base \"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs \" <>\n          \"transition-[color,box-shadow] outline-none \" <>\n          \"selection:bg-primary selection:text-primary-foreground \" <>\n          \"file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground \" <>\n          \"placeholder:text-muted-foreground \" <>\n          \"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 \" <>\n          \"md:text-sm dark:bg-input/30 \" <>\n          \"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 \" <>\n          \"aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 \" <>\n          \"[&.htmx-request]:opacity-70\"\n\n  attr :type, :string,\n    default: \"text\",\n    values:\n      ~w(text password email number search tel url date time datetime-local month week color file hidden)\n\n  attr :class, :string, default: nil\n\n  attr :rest, :global,\n    include:\n      ~w(hx-get hx-post hx-put hx-patch hx-delete hx-target hx-swap hx-trigger hx-indicator hx-vals hx-include hx-disable\n         id name value placeholder required disabled readonly\n         minlength maxlength min max step pattern\n         inputmode enterkeyhint autocomplete autocapitalize autofocus list accept capture multiple size dirname form\n         spellcheck autocorrect\n         aria-label aria-labelledby aria-describedby aria-invalid aria-required)\n\n  def input(assigns) do\n    assigns = assign(assigns, :base_class, @base)\n\n    ~H\"\"\"\n    <input\n      type={@type}\n      class={[@base_class, @class]}\n      data-slot=\"input\"\n      {@rest}\n    />\n    \"\"\"\n  end\nend\n"
    },
    {
      "path": "registry/html/input.html",
      "type": "registry:file",
      "target": "snippets/input.html",
      "content": "<!--\n  shadcn-htmx — raw HTML input snippets.\n\n  Mirrors registry/ui/input.tsx. Drop these onto any page that loads Tailwind\n  CSS v4 and the shadcn theme variables (background, foreground, input, ring,\n  destructive, primary). See app/styles/input.css for the variable defaults.\n\n  BASE (shared by every input):\n    flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent\n    px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none\n    selection:bg-primary selection:text-primary-foreground\n    file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm\n    file:font-medium file:text-foreground\n    placeholder:text-muted-foreground\n    disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\n    md:text-sm dark:bg-input/30\n    focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\n    aria-invalid:border-destructive aria-invalid:ring-destructive/20\n    dark:aria-invalid:ring-destructive/40\n    [&.htmx-request]:opacity-70\n-->\n\n<!-- ─── Common types ────────────────────────────────────────────────── -->\n\n<!-- Email — browser validates locally; required signals the constraint -->\n<input type=\"email\" name=\"email\" placeholder=\"you@example.com\" required autocomplete=\"email\" data-slot=\"input\"\n  class=\"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40\">\n\n<!-- Password — autocomplete=\"current-password\" / \"new-password\" -->\n<input type=\"password\" name=\"password\" autocomplete=\"current-password\" data-slot=\"input\"\n  class=\"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\">\n\n<!-- Number — inputmode=\"decimal\" hints the OS keyboard -->\n<input type=\"number\" name=\"amount\" min=\"0\" step=\"0.01\" inputmode=\"decimal\" data-slot=\"input\"\n  class=\"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\">\n\n<!-- Search — pair with hx-get for live-search -->\n<input type=\"search\" name=\"q\" placeholder=\"Search…\" autocomplete=\"off\" data-slot=\"input\"\n  hx-get=\"/search\" hx-target=\"#results\" hx-trigger=\"input changed delay:300ms\"\n  class=\"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [&.htmx-request]:opacity-70\">\n\n<!-- ─── States ──────────────────────────────────────────────────────── -->\n\n<!-- Invalid — pair with an error message via aria-describedby -->\n<div>\n  <input type=\"email\" name=\"email\" aria-invalid=\"true\" aria-describedby=\"email-error\"\n         placeholder=\"you@example.com\" data-slot=\"input\"\n    class=\"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40\">\n  <p id=\"email-error\" class=\"mt-1 text-sm text-destructive\">Enter a valid email address.</p>\n</div>\n\n<!-- Disabled — also removes from tab order -->\n<input type=\"text\" disabled value=\"Read-only after save\" data-slot=\"input\"\n  class=\"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30\">\n\n<!-- Readonly — value is selectable + focusable, but not editable -->\n<input type=\"text\" readonly value=\"https://example.com/abc-123\" data-slot=\"input\"\n  class=\"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\">\n\n<!-- ─── File ────────────────────────────────────────────────────────── -->\n<input type=\"file\" name=\"avatar\" accept=\"image/*\" data-slot=\"input\"\n  class=\"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 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 md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\">\n\n<!-- ─── Sensitive / no-correction ───────────────────────────────────── -->\n<!-- spellcheck=\"false\" + autocorrect=\"off\": codes, usernames, tokens, API keys.\n     spellcheck content may be sent to a third party (\"spell-jacking\"); both are\n     enumerated global attributes (MDN global_attributes/spellcheck, /autocorrect). -->\n<input type=\"text\" name=\"coupon\" placeholder=\"Coupon code\" spellcheck=\"false\" autocorrect=\"off\" autocapitalize=\"characters\" data-slot=\"input\"\n  class=\"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\">\n"
    }
  ]
}
