import { Combobox, ComboboxCancel, ComboboxGroup, ComboboxGroupLabel, ComboboxItem, ComboboxItemValue, ComboboxPopover, ComboboxProvider, } from '@ariakit/react' import { ComponentType, ForwardedRef, forwardRef, startTransition, useState } from 'react' import './Autocomplete.css' import { Icon } from './Icon' import { Spinner } from './Spinner' export type DropdownOption = { label: string value: string group?: string } type AutocompleteProps = { customUI?: React.ReactNode groups?: string[] groupsToIcon?: { [key: string]: ComponentType<{ className?: string }> } groupsToLabel?: { [key: string]: string } isLoading: boolean options: DropdownOption[] onChange: (value: string) => void onInputChange: (value: string) => void } const DEFAULT_GROUP = 'autocomplete-default' const Autocomplete = forwardRef(function Autocomplete( { customUI, groups = [DEFAULT_GROUP], groupsToIcon, groupsToLabel, isLoading, options, onInputChange, onChange, }: AutocompleteProps, ref: ForwardedRef ) { const [open, setOpen] = useState(false) const [value, setValue] = useState('') const renderedGroups = groups.map((group) => { const filteredOptions = options.filter( ({ group: optionGroup }) => optionGroup === group || group === DEFAULT_GROUP ) if (filteredOptions.length === 0) return null return ( {groupsToLabel?.[group] && ( {groupsToLabel[group]} )} {filteredOptions.map(({ label, value }) => { const Icon = groupsToIcon?.[group] return ( {Icon && } ) })} ) }) return ( defaultSelectedValue="" open={open} setOpen={setOpen} resetValueOnHide includesBaseElement={false} setValue={(newValue) => { startTransition(() => setValue(newValue)) onInputChange(newValue) }} setSelectedValue={(newValue) => onChange(newValue)} >
{isLoading ? ( ) : ( )} {value && } {value && ( {customUI} {options.length === 0 && No results found.} {options.length !== 0 && renderedGroups} )}
) }) export { Autocomplete }