import { useRef } from 'react'; import { createPortal } from 'react-dom'; import type React from 'react'; import type { SearchResult } from '../../hooks/useLocationSearch'; import { useDropdownPosition } from '../../hooks/useDropdownPosition'; import { SearchIcon } from './icons/SearchIcon'; import { MapPinIcon } from './icons/MapPinIcon'; interface SearchHook { query: string; results: SearchResult[]; activeIndex: number; setActiveIndex: (idx: number) => void; open: boolean; setOpen: (open: boolean) => void; handleInputChange: (value: string) => void; handleKeyDown: (e: React.KeyboardEvent, onSelect: (result: SearchResult) => void) => void; } interface PlaceSearchInputProps { search: SearchHook; onSelect: (result: SearchResult) => void; loading?: boolean; placeholder?: string; size?: 'sm' | 'xs'; inputClassName?: string; inputRef?: React.Ref; onInputChange?: () => void; portal?: boolean; } export function PlaceSearchInput({ search, onSelect, loading, placeholder, size = 'sm', inputClassName, inputRef, onInputChange, portal, }: PlaceSearchInputProps) { const sm = size === 'sm'; const iconSize = sm ? 'w-4 h-4' : 'w-3 h-3'; const spinnerSize = sm ? 'w-4 h-4' : 'w-3 h-3'; const wrapperRef = useRef(null); const dropdownPos = useDropdownPosition(wrapperRef, portal ? search.open : false); const showDropdown = search.open && search.results.length > 0; const dropdown = showDropdown && (
{search.results.map((result, idx) => ( ))}
); return (
{ search.handleInputChange(e.target.value); onInputChange?.(); }} onFocus={() => { if (search.results.length > 0) search.setOpen(true); }} onKeyDown={(e) => search.handleKeyDown(e, onSelect)} placeholder={placeholder} className={inputClassName} /> {loading && (
)} {showDropdown && (portal ? ( createPortal(dropdown, document.body) ) : (
{dropdown}
))}
); }