import type { ReactNode } from 'react' import { EmptyState, SearchInput, cn } from '@/components/ui' import { Loader2 } from 'lucide-react' import { getHighlightedParts } from './search-model' export interface SearchItem { id: string title: string subtitle?: string description?: string meta?: ReactNode disabled?: boolean } export interface InlineSearchProps { query: string onQueryChange: (query: string) => void items: T[] onSelect: (item: T) => void placeholder?: string label?: string loading?: boolean error?: string | null emptyTitle?: string className?: string } /** A small, controlled search input and result list for one page section. */ export function InlineSearch({ query, onQueryChange, items, onSelect, placeholder = 'Search...', label, loading = false, error = null, emptyTitle = 'No matches', className, }: InlineSearchProps) { return (
{label && } onQueryChange(event.target.value)} onClear={() => onQueryChange('')} placeholder={placeholder} aria-label={label ?? placeholder} /> {loading ? (
Searching...
) : error ? (

{error}

) : items.length === 0 ? ( ) : (
    {items.map((item) => (
  • ))}
)}
) } function HighlightedText({ text, query }: { text: string; query: string }) { return getHighlightedParts(text, query).map((part, index) => part.match ? {part.text} : {part.text}, ) }