import React, { useState, useRef, useEffect, useMemo } from 'react'; import { useFormikContext } from 'formik'; import { useTranslation } from 'react-i18next'; import { Search } from '@carbon/react'; import { useAddressHierarchy } from './address-hierarchy.resource'; import styles from './address-search.scss'; interface AddressSearchComponentProps { addressLayout: Array; } const AddressSearchComponent: React.FC = ({ addressLayout }) => { const { t } = useTranslation(); const separator = ' > '; const searchBox = useRef(null); const wrapper = useRef(null); const [searchString, setSearchString] = useState(''); const { addresses, isLoading, error } = useAddressHierarchy(searchString, separator); const addressOptions: Array = useMemo(() => { const options: Set = new Set(); addresses.forEach((address) => { const values = address.split(separator); values.forEach((val, index) => { if (val.toLowerCase().includes(searchString.toLowerCase())) { options.add(values.slice(0, index + 1).join(separator)); } }); }); return [...options]; }, [addresses, searchString]); const { setFieldValue } = useFormikContext(); const handleInputChange = (e) => { setSearchString(e.target.value); }; const handleChange = (address) => { if (address) { const values = address.split(separator); addressLayout.map(({ name }, index) => { setFieldValue(`address.${name}`, values?.[index] ?? ''); }); setSearchString(''); } }; const handleClickOutsideComponent = (e) => { if (wrapper.current && !wrapper.current.contains(e.target)) { setSearchString(''); } }; useEffect(() => { document.addEventListener('mousedown', handleClickOutsideComponent); return () => { document.removeEventListener('mousedown', handleClickOutsideComponent); }; }, [wrapper]); return (
{ if (e.key === 'Enter') { e.preventDefault(); } }} labelText={t('searchAddress', 'Search address')} placeholder={t('searchAddress', 'Search address')} ref={searchBox} value={searchString} /> {searchString && (
    {isLoading ? (
  • {t('searching', 'Searching...')}
  • ) : error ? (
  • {t('errorFetchingAddresses', 'Error fetching address results')}
  • ) : addressOptions.length > 0 ? ( addressOptions.map((address) => (
  • handleChange(address)}> {address}
  • )) ) : (
  • {t('noAddressResults', 'No matching addresses found')}
  • )}
)}
); }; export default AddressSearchComponent;