{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "beam-search",
  "title": "Beam Search Bar",
  "description": "A search bar whose bottom edge lights up with a traveling beam while it has focus.",
  "dependencies": [
    "border-beam",
    "lucide-react"
  ],
  "registryDependencies": [
    "@spectrumui/use-surface-theme"
  ],
  "files": [
    {
      "path": "components/spectrumui/beam-search.tsx",
      "content": "/**\n * Spectrum UI — BeamSearch\n *\n * A search bar whose bottom edge lights up with a traveling beam while it has\n * focus, using the `line` preset of `border-beam` (Jakub Antalík, MIT,\n * https://libraries.dev/beam). The beam fades in on focus and out on blur via\n * the library's `active` prop, so idle bars stay quiet. Controlled or\n * uncontrolled value, Escape clears, and class-based dark/light detection.\n *\n * Dependencies: border-beam, lucide-react, @/lib/utils\n *\n * @example\n * <BeamSearch placeholder=\"Search components…\" onChange={setQuery} />\n */\n\n'use client';\n\nimport * as React from 'react';\nimport { BorderBeam, type BorderBeamColorVariant } from 'border-beam';\nimport { Search, X } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\nimport { useSurfaceTheme, type SurfaceTheme } from '@/components/spectrumui/use-surface-theme';\n\nexport interface BeamSearchProps {\n  value?: string;\n  defaultValue?: string;\n  onChange?: (value: string) => void;\n  /** Fires on Enter with the current value */\n  onSubmit?: (value: string) => void;\n  placeholder?: string;\n  /** Keep the beam running even without focus. Default false */\n  alwaysOn?: boolean;\n  /** Palette: \"colorful\" | \"ocean\" | \"sunset\" | \"mono\". Default \"colorful\" */\n  colorVariant?: BorderBeamColorVariant;\n  /** \"auto\" follows a `.dark`/`.light` class on <html>, then the OS. Default \"auto\" */\n  theme?: SurfaceTheme;\n  /** Right-hand slot, e.g. a keyboard hint */\n  trailing?: React.ReactNode;\n  className?: string;\n}\n\nexport function BeamSearch({\n  value,\n  defaultValue = '',\n  onChange,\n  onSubmit,\n  placeholder = 'Search…',\n  alwaysOn = false,\n  colorVariant = 'colorful',\n  theme = 'auto',\n  trailing,\n  className,\n}: BeamSearchProps) {\n  const resolved = useSurfaceTheme(theme);\n  const [inner, setInner] = React.useState(defaultValue);\n  const [focused, setFocused] = React.useState(false);\n  const inputRef = React.useRef<HTMLInputElement>(null);\n  const current = value ?? inner;\n\n  const update = (next: string) => {\n    if (value === undefined) setInner(next);\n    onChange?.(next);\n  };\n\n  return (\n    <BorderBeam\n      size=\"line\"\n      colorVariant={colorVariant}\n      theme={resolved}\n      active={alwaysOn || focused}\n      className={cn('w-full', className)}\n    >\n      <label\n        className={cn(\n          'flex h-12 w-full items-center gap-3 rounded-xl border border-black/10 bg-white px-3.5 transition-colors dark:border-white/12 dark:bg-neutral-950',\n          focused && 'border-black/20 dark:border-white/20',\n        )}\n      >\n        <Search className=\"size-4 shrink-0 text-neutral-400\" aria-hidden />\n        <input\n          ref={inputRef}\n          type=\"search\"\n          value={current}\n          placeholder={placeholder}\n          onChange={(event) => update(event.target.value)}\n          onFocus={() => setFocused(true)}\n          onBlur={() => setFocused(false)}\n          onKeyDown={(event) => {\n            if (event.key === 'Enter') onSubmit?.(current);\n            if (event.key === 'Escape') update('');\n          }}\n          className=\"min-w-0 flex-1 bg-transparent text-[15px] text-neutral-900 outline-hidden placeholder:text-neutral-400 dark:text-neutral-100 dark:placeholder:text-neutral-500 [&::-webkit-search-cancel-button]:hidden\"\n        />\n        {current ? (\n          <button\n            type=\"button\"\n            aria-label=\"Clear\"\n            onMouseDown={(event) => event.preventDefault()}\n            onClick={() => {\n              update('');\n              inputRef.current?.focus();\n            }}\n            className=\"flex size-6 items-center justify-center rounded-full text-neutral-400 transition-colors hover:bg-black/5 hover:text-neutral-700 dark:hover:bg-white/8 dark:hover:text-neutral-200\"\n          >\n            <X className=\"size-3.5\" />\n          </button>\n        ) : (\n          trailing\n        )}\n      </label>\n    </BorderBeam>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/spectrumui/beam-search.tsx"
    }
  ],
  "type": "registry:component"
}
