{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "search-field",
  "title": "Search Field",
  "description": "A search input with a leading icon, a clear button and an Enter-to-search callback.",
  "dependencies": [
    "lucide-react"
  ],
  "files": [
    {
      "path": "registry/tealmac/search-field.tsx",
      "content": "// Adapted from Ballmac UI (https://github.com/vamsiy78/ballmac-ui), MIT License, Copyright (c) 2026 Ballmac.\n\"use client\"\n\nimport * as React from \"react\"\nimport { Search, X } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype SearchFieldProps = Omit<\n  React.ComponentProps<\"input\">,\n  \"type\" | \"value\" | \"defaultValue\" | \"onChange\"\n> & {\n  /** Controlled search query. */\n  value?: string\n  /** Initial query when uncontrolled. */\n  defaultValue?: string\n  /** Called whenever the query changes or clears. */\n  onValueChange?: (value: string) => void\n  /** Called when Enter submits the query. */\n  onSearch?: (value: string) => void\n  /** Accessible name of the search field. */\n  label?: string\n}\nfunction SearchField({\n  value,\n  defaultValue = \"\",\n  onValueChange,\n  onSearch,\n  label,\n  className,\n  disabled,\n  onKeyDown,\n  ...props\n}: SearchFieldProps) {\n  label ??= \"Search\"\n  const [internal, setInternal] = React.useState(defaultValue)\n  const current = value ?? internal\n  const inputRef = React.useRef<HTMLInputElement>(null)\n  function commit(next: string) {\n    if (value === undefined) setInternal(next)\n    onValueChange?.(next)\n  }\n  return (\n    <div\n      data-slot=\"search-field\"\n      className={cn(\n        \"border-input bg-background focus-within:border-ring focus-within:ring-ring/50 flex h-9 w-full min-w-0 items-center gap-2 rounded-md border px-3 shadow-xs transition-[border-color,box-shadow] duration-150 focus-within:ring-[3px] motion-reduce:transition-none\",\n        className\n      )}\n    >\n      <Search\n        aria-hidden=\"true\"\n        className=\"text-muted-foreground size-4 shrink-0\"\n      />\n      <input\n        ref={inputRef}\n        data-slot=\"search-field-input\"\n        type=\"search\"\n        aria-label={label}\n        disabled={disabled}\n        value={current}\n        onChange={(event) => commit(event.currentTarget.value)}\n        onKeyDown={(event) => {\n          onKeyDown?.(event)\n          if (!event.defaultPrevented && event.key === \"Enter\")\n            onSearch?.(current)\n        }}\n        className=\"text-foreground placeholder:text-muted-foreground h-full min-w-0 flex-1 bg-transparent text-sm outline-none disabled:opacity-50 [&::-webkit-search-cancel-button]:hidden\"\n        {...props}\n      />\n      {current && (\n        <button\n          type=\"button\"\n          aria-label=\"Clear search\"\n          disabled={disabled}\n          onClick={() => {\n            commit(\"\")\n            inputRef.current?.focus()\n          }}\n          className=\"text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:ring-ring/50 flex size-7 shrink-0 items-center justify-center rounded-md outline-none focus-visible:ring-[3px] disabled:opacity-50\"\n        >\n          <X aria-hidden=\"true\" className=\"size-4\" />\n        </button>\n      )}\n    </div>\n  )\n}\nexport { SearchField, type SearchFieldProps }\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}