import { useRef } from 'react'; import { createPortal } from 'react-dom'; import { useTranslation } from 'react-i18next'; 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'; import { HouseIcon } from './icons/HouseIcon'; interface SearchHook { query: string; results: SearchResult[]; activeIndex: number; setActiveIndex: (idx: number) => void; open: boolean; searching?: boolean; handleInputChange: (value: string) => void; handleKeyDown: (e: React.KeyboardEvent, onSelect: (result: SearchResult) => void) => void; showEmptySearches: () => void; } interface PlaceSearchInputProps { search: SearchHook; onSelect: (result: SearchResult) => void; loading?: boolean; placeholder?: string; ariaLabel?: string; name?: string; size?: 'sm' | 'xs'; inputClassName?: string; inputRef?: React.Ref; onInputChange?: () => void; portal?: boolean; } export function PlaceSearchInput({ search, onSelect, loading, placeholder, ariaLabel, name, size = 'sm', inputClassName, inputRef, onInputChange, portal, }: PlaceSearchInputProps) { const { t } = useTranslation(); 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 showEmptyResults = search.open && !search.searching && search.query.trim().length >= 2 && search.results.length === 0; const showDropdown = search.open && (search.results.length > 0 || showEmptyResults); const showSpinner = loading || search.searching; const dropdown = showDropdown && (
{showEmptyResults ? (
{t('locationSearch.noResults')}
) : ( search.results.map((result, idx) => ( )) )}
); return (
{ search.handleInputChange(e.target.value); onInputChange?.(); }} onFocus={() => { search.showEmptySearches(); }} onKeyDown={(e) => search.handleKeyDown(e, onSelect)} aria-label={ariaLabel ?? placeholder} placeholder={placeholder} className={inputClassName} /> {showSpinner && (
)} {showDropdown && (portal ? ( createPortal(dropdown, document.body) ) : (
{dropdown}
))}
); }