diff --git a/package.json b/package.json index b7cb35fb..821dea4d 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@vercel/speed-insights": "^1.3.1", "axios": "^1.7.2", "countries-list": "^3.1.1", + "country-flag-emoji-polyfill": "^0.1.8", "date-fns": "^2.30.0", "date-fns-tz": "^2.0.0", "export-to-csv": "^1.3.0", diff --git a/public/fonts/TwemojiCountryFlags.woff2 b/public/fonts/TwemojiCountryFlags.woff2 new file mode 100644 index 00000000..b9d6ea84 Binary files /dev/null and b/public/fonts/TwemojiCountryFlags.woff2 differ diff --git a/src/app/Theme.ts b/src/app/Theme.ts index e111e18e..977ea7a6 100644 --- a/src/app/Theme.ts +++ b/src/app/Theme.ts @@ -56,7 +56,10 @@ export enum ThemeModeEnum { } export const fontFamily = { - primary: 'var(--font-mulish)', + // "Twemoji Country Flags" is loaded via a polyfill (polyfillCountryFlagEmojis in providers.tsx) + // and uses unicode-range: U+1F1E6-1F1FF, so it only applies to flag emoji code points + // and does not affect any other text rendering. + primary: '"Twemoji Country Flags", var(--font-mulish)', secondary: 'var(--font-ibm-plex-mono)', }; diff --git a/src/app/providers.tsx b/src/app/providers.tsx index b3cf8808..f66ccc6a 100644 --- a/src/app/providers.tsx +++ b/src/app/providers.tsx @@ -8,6 +8,7 @@ import { type RemoteConfigValues } from './interface/RemoteConfig'; // Look into this provider and see if it's client blocking. Niche provider might be able to isolate for single use import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { polyfillCountryFlagEmojis } from 'country-flag-emoji-polyfill'; interface ProvidersProps { children: React.ReactNode; @@ -19,6 +20,15 @@ export function Providers({ children, remoteConfig, }: ProvidersProps): React.ReactElement { + // Polyfill country flag emojis for browsers that don't support them natively + // (e.g. Microsoft Edge / Chrome on Windows) + React.useEffect(() => { + polyfillCountryFlagEmojis( + 'Twemoji Country Flags', + '/fonts/TwemojiCountryFlags.woff2', + ); + }, []); + // Start MSW in mock mode to intercept API calls client-side React.useEffect(() => { if (process.env.NEXT_PUBLIC_API_MOCKING === 'enabled') { diff --git a/yarn.lock b/yarn.lock index 66e2aff6..99277cd1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4994,6 +4994,11 @@ countries-list@^3.1.1: resolved "https://registry.yarnpkg.com/countries-list/-/countries-list-3.2.2.tgz#34ded4d3c8ebe715306cb5658c34f73a0c8f01cb" integrity sha512-ABJ/RWQBrPWy+hRuZoW+0ooK8p65Eo3WmUZwHm6v4wmfSPznNAKzjy3+UUYrJK2v3182BVsgWxdB6ROidj39kw== +country-flag-emoji-polyfill@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/country-flag-emoji-polyfill/-/country-flag-emoji-polyfill-0.1.8.tgz#d2cfb23dd2f949b80d83eb9822b613bf62957173" + integrity sha512-Mbah52sADS3gshUYhK5142gtUuJpHYOXlXtLFI3Ly4RqgkmPMvhX9kMZSTqDM8P7UqtSW99eHKFphhQSGXA3Cg== + crc-32@^1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff"