import { useMemo } from "react"; import { UseCountriesOptions, CountryType } from "hooks"; export function getFlagEmoji(countryCode: string) { const codePoints = countryCode .toUpperCase() .split("") // eslint-disable-next-line @typescript-eslint/no-explicit-any .map((char) => 127397 + char.charCodeAt(undefined as any)); return String.fromCodePoint(...codePoints); } /* * @param code The `code` to provide depends on the `type` passed to display name during creation: * - If the type is `"region"`, code should be either an [ISO-3166 two letters region code](https://www.iso.org/iso-3166-country-codes.html), * or a [three digits UN M49 Geographic Regions](https://unstats.un.org/unsd/methodology/m49/). * - If the type is `"script"`, code should be an [ISO-15924 four letters script code](https://unicode.org/iso15924/iso15924-codes.html). * - If the type is `"language"`, code should be a `languageCode` ["-" `scriptCode`] ["-" `regionCode` ] *("-" `variant` ) * subsequence of the unicode_language_id grammar in [UTS 35's Unicode Language and Locale Identifiers grammar](https://unicode.org/reports/tr35/#Unicode_language_identifier). * `languageCode` is either a two letters ISO 639-1 language code or a three letters ISO 639-2 language code. * - If the type is `"currency"`, code should be a [3-letter ISO 4217 currency code](https://www.iso.org/iso-4217-currency-codes.html). */ export function getCountries(lang = "en") { const A = 65; const Z = 90; const countryName = new Intl.DisplayNames([lang], { type: "region" }); const countries: CountryType[] = []; for (let i = A; i <= Z; i += 1) { for (let j = A; j <= Z; j += 1) { const code = String.fromCharCode(i) + String.fromCharCode(j); const name = countryName.of(code) as string; const correctCountry = code !== name; const alreadyExist = countries.some((country) => country.name === name); if (correctCountry && !alreadyExist) { countries.push({ code, name, emoji: getFlagEmoji(code), }); } } } return countries; } let cachedCountries: CountryType[] = []; /** * * @kind 03-Countries */ export const useCountries = (options: UseCountriesOptions) => { const { language } = options || {}; const countries = useMemo(() => { if (!cachedCountries.length) { cachedCountries = getCountries(language); } return cachedCountries; }, [language]); return countries; };