// Copyright 2024 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React, { useState, useCallback, useMemo } from 'react'; import Fuse from 'fuse.js'; import type { LocalizerType } from '../types/Util'; import type { CountryDataType } from '../util/getCountryData'; import { Modal } from './Modal'; import { SearchInput } from './SearchInput'; export type PropsType = Readonly<{ i18n: LocalizerType; onChange: (region: string) => void; value: string; defaultRegion: string; countries: ReadonlyArray; }>; export function CountryCodeSelect({ i18n, onChange, value, defaultRegion, countries, }: PropsType): JSX.Element { const index = useMemo(() => { return new Fuse(countries, { keys: [ { name: 'displayName', weight: 1, }, { name: 'code', weight: 0.5, }, ], threshold: 0.1, }); }, [countries]); const [isModalOpen, setIsModalOpen] = useState(false); const [searchTerm, setSearchTerm] = useState(''); const selectedCountry = useMemo(() => { return countries.find(({ region }) => region === value); }, [countries, value]); const defaultCode = useMemo(() => { return countries.find(({ region }) => region === defaultRegion)?.code ?? ''; }, [countries, defaultRegion]); const filteredCountries = useMemo(() => { if (!searchTerm) { return countries; } return index.search(searchTerm).map(({ item }) => item); }, [countries, index, searchTerm]); const onShowModal = useCallback((ev: React.MouseEvent) => { ev.preventDefault(); setIsModalOpen(true); }, []); const onCloseModal = useCallback(() => { setIsModalOpen(false); setSearchTerm(''); }, []); const onSearchTermChange = useCallback( (ev: React.ChangeEvent) => { setSearchTerm(ev.target.value); }, [] ); const onCountryClick = useCallback( (region: string) => { onCloseModal(); onChange(region); }, [onChange, onCloseModal] ); const modal = (
{filteredCountries.map(({ displayName, region, code }) => { return ( ); })}
); return ( <> {isModalOpen ? modal : null} ); } type CountryButtonPropsType = Readonly<{ region: string; displayName: string; code: string; onClick: (region: string) => void; }>; function CountryButton({ region, displayName, code, onClick, }: CountryButtonPropsType): JSX.Element { const onButtonClick = useCallback( (ev: React.MouseEvent) => { ev.preventDefault(); onClick(region); }, [region, onClick] ); return ( ); }