import {flip, offset, shift, useFloating} from '@floating-ui/react' import {Popover, PopoverButton, PopoverPanel} from '@headlessui/react' import {ChevronDownIcon} from '@heroicons/react/24/solid' import clsx from 'clsx' import {useState} from 'react' import {Input} from './input' export type Suggestion = { id: string label: string icon?: React.ReactNode } export function SearchableSelect(props: { value: string onChange: (value: string) => void suggestions: Suggestion[] placeholder?: string parentClassName?: string className?: string allowCustom?: boolean }) { const {value, onChange, suggestions, placeholder, parentClassName, className, allowCustom} = props const [query, setQuery] = useState('') const {refs, floatingStyles} = useFloating({ placement: 'bottom-start', middleware: [offset(4), flip(), shift({padding: 8})], }) const filteredSuggestions = suggestions.filter((s) => s.label.toLowerCase().includes(query.toLowerCase()), ) const showCustom = allowCustom && query.length > 0 && filteredSuggestions.length === 0 const currentSuggestion = suggestions.find((s) => s.id === value) return ( {({close}) => ( <> {currentSuggestion?.label || value || placeholder || 'Select...'}
setQuery(e.target.value)} placeholder="Search..." className="mb-2 w-full" />
{filteredSuggestions.map((suggestion) => ( ))} {showCustom && ( )}
)}
) }