'use client' import { type SyntheticEvent, useMemo, useState } from 'react' import { Button, ComboBox, Input, Label, ListBox, ListBoxItem, Popover, useFilter, } from 'react-aria-components' import { useController } from 'react-hook-form' import { MaterialIcon } from '../../Icons/MaterialIcon' import { Typography } from '../../Typography' import { ErrorMessage } from '../ErrorMessage' import styles from './country.module.css' import type { CountryProps } from './country' const prioCountryCode = ['DE', 'DK', 'FI', 'NO', 'SE'] export default function CountryCombobox({ // hack used since chrome does not respect autocomplete="off" autoComplete = 'nope', className = '', errorMessage, label, lang = 'en', countries, name = 'country', readOnly = false, registerOptions = {}, }: CountryProps) { const { startsWith } = useFilter({ sensitivity: 'base' }) const [filterValue, setFilterValue] = useState('') const { field, formState, fieldState } = useController({ name, rules: registerOptions, }) const items = useMemo(() => { function mapCountry(country: (typeof countries)[number]) { return { value: country.code, label: country.displayName || country.name, } } const collator = new Intl.Collator(lang) const prioCountries = countries .filter((c) => prioCountryCode.includes(c.code)) .map(mapCountry) .filter((item) => startsWith(item.label, filterValue)) .sort((a, b) => collator.compare(a.label, b.label)) const restCountries = countries .filter((c) => !prioCountryCode.includes(c.code)) .map(mapCountry) .filter((item) => startsWith(item.label, filterValue)) .sort((a, b) => collator.compare(a.label, b.label)) return [...prioCountries, ...restCountries] }, [filterValue, lang, startsWith, countries]) function handleOnInput(evt: SyntheticEvent) { setFilterValue(evt.currentTarget.value) const isAutoCompleteEvent = !('inputType' in evt.nativeEvent) if (isAutoCompleteEvent) { const { value } = evt.currentTarget const cc = countries.find((c) => c.name === value || c.code === value) if (cc) { field.onChange(cc.code) } } } return (
field.onChange(c ?? '')} selectedKey={field.value} menuTrigger="focus" > {items.map((item) => ( {({ isSelected }) => ( {item.label} )} ))}
) }