{
  "name": "search-input",
  "type": "registry:ui",
  "dependencies": [
    "lucide-react",
    "react"
  ],
  "registryDependencies": [
    "input",
    "popover"
  ],
  "files": [
    {
      "path": "./items/components/search-input/component.tsx",
      "type": "registry:ui",
      "target": "./components/ui/shuip/search-input.tsx",
      "content": "'use client';\n\nimport { Search } from 'lucide-react';\nimport * as React from 'react';\nimport { Input } from '@/components/ui/input';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\nimport { cn } from '@/lib/utils';\n\nfunction isEditableTarget(target: EventTarget | null): boolean {\n  if (!(target instanceof HTMLElement)) return false;\n  const tag = target.tagName;\n  return tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || target.isContentEditable;\n}\n\nexport interface SearchInputProps extends Omit<React.ComponentProps<'input'>, 'onChange'> {\n  onChange: (value: string) => void;\n  debounceMs?: number;\n  hotkey?: string | false;\n  hotkeyTooltip?: string;\n}\n\nexport function SearchInput({\n  value,\n  onChange,\n  placeholder = 'Search…',\n  debounceMs = 250,\n  hotkey = '/',\n  hotkeyTooltip,\n  autoFocus,\n  className,\n  ...props\n}: SearchInputProps) {\n  const inputRef = React.useRef<HTMLInputElement>(null);\n  const timer = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n  const [text, setText] = React.useState(typeof value === 'string' ? value : '');\n  const [prevValue, setPrevValue] = React.useState(value);\n  const [focused, setFocused] = React.useState(false);\n  const [hintOpen, setHintOpen] = React.useState(false);\n\n  if (prevValue !== value) {\n    setPrevValue(value);\n    if (typeof value === 'string') setText(value);\n  }\n\n  const resolvedTooltip = hotkeyTooltip ?? (hotkey ? `Press ${hotkey} to search` : undefined);\n\n  React.useEffect(\n    () => () => {\n      if (timer.current) clearTimeout(timer.current);\n    },\n    [],\n  );\n\n  React.useEffect(() => {\n    if (!hotkey) return;\n    function onKey(e: KeyboardEvent) {\n      if (e.key !== hotkey || e.metaKey || e.ctrlKey || e.altKey) return;\n      if (isEditableTarget(e.target)) return;\n      e.preventDefault();\n      inputRef.current?.focus();\n    }\n    document.addEventListener('keydown', onKey);\n    return () => document.removeEventListener('keydown', onKey);\n  }, [hotkey]);\n\n  function handleChange(next: string) {\n    setText(next);\n    if (timer.current) clearTimeout(timer.current);\n    if (debounceMs <= 0) {\n      onChange(next);\n      return;\n    }\n    timer.current = setTimeout(() => onChange(next), debounceMs);\n  }\n\n  const showHotkeyBadge = Boolean(hotkey) && !focused && text.length === 0;\n\n  return (\n    <div className={cn('relative', className)}>\n      <Search aria-hidden className='absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground' />\n      <Input\n        {...props}\n        ref={inputRef}\n        type='search'\n        placeholder={placeholder}\n        value={text}\n        onChange={(e) => handleChange(e.target.value)}\n        onFocus={() => setFocused(true)}\n        onBlur={() => setFocused(false)}\n        autoFocus={autoFocus}\n        className={cn('h-9 pl-9', showHotkeyBadge && 'pr-9')}\n      />\n      {showHotkeyBadge && (\n        <Popover open={hintOpen} onOpenChange={setHintOpen}>\n          <PopoverTrigger\n            type='button'\n            aria-label={resolvedTooltip}\n            onClick={() => inputRef.current?.focus()}\n            onMouseEnter={() => setHintOpen(true)}\n            onMouseLeave={() => setHintOpen(false)}\n            className='absolute right-2 top-1/2 -translate-y-1/2 inline-flex h-5 min-w-5 items-center justify-center rounded border border-border bg-muted px-1.5 font-mono text-xs font-medium text-muted-foreground transition-colors hover:text-foreground'\n          >\n            {hotkey}\n          </PopoverTrigger>\n          <PopoverContent\n            side='top'\n            align='end'\n            sideOffset={8}\n            onOpenAutoFocus={(e) => e.preventDefault()}\n            className='w-auto p-2 text-xs text-muted-foreground'\n          >\n            {resolvedTooltip}\n          </PopoverContent>\n        </Popover>\n      )}\n    </div>\n  );\n}\n"
    }
  ],
  "$schema": "https://ui.shadcn.com/schema/registry-item.json"
}
