import type { ComponentType, SVGProps } from 'react'; import { Menu, UnstyledButton, Text, Group, rem } from '@mantine/core'; import { IconCheck, IconChevronDown, IconWorld } from '@tabler/icons-react'; import { GB, ET } from 'country-flag-icons/react/3x2'; import { useTranslation } from 'react-i18next'; interface LanguageSwitcherProps { supportedLanguages: readonly string[]; /** `icon` renders a compact flag button; `button` shows the language label. */ variant?: 'icon' | 'button'; } type FlagComponentType = ComponentType>; const LANGUAGE_CONFIG: Record< string, { Flag: FlagComponentType; nativeName: string; shortCode: string } > = { en: { Flag: GB, nativeName: 'English', shortCode: 'EN' }, am: { Flag: ET, nativeName: 'አማርኛ', shortCode: 'AM' }, }; export function LanguageSwitcher({ supportedLanguages, variant = 'icon', }: LanguageSwitcherProps) { const { t, i18n } = useTranslation(); const current = i18n.language || 'en'; const change = (lng: string) => { if (lng !== current) i18n.changeLanguage(lng); }; const currentConfig = LANGUAGE_CONFIG[current] || { Flag: null, nativeName: current.toUpperCase(), shortCode: current.toUpperCase(), }; const CurrentFlag = currentConfig.Flag; return ( { e.currentTarget.style.transform = 'translateY(-1px)'; e.currentTarget.style.boxShadow = '0 4px 12px rgba(0,0,0,0.1), 0 0 0 1px var(--mantine-primary-color-3)'; }} onMouseLeave={(e) => { e.currentTarget.style.transform = 'translateY(0)'; e.currentTarget.style.boxShadow = '0 1px 3px rgba(0,0,0,0.06), 0 0 0 1px rgba(0,0,0,0.08)'; }} > {CurrentFlag ? ( ) : ( )} {variant !== 'icon' && ( {t(`language.${current}`, currentConfig.nativeName)} )} {t('language.label', 'Language')} {supportedLanguages.map((lng) => { const config = LANGUAGE_CONFIG[lng] || { Flag: null, nativeName: lng.toUpperCase(), shortCode: lng.toUpperCase(), }; const Flag = config.Flag; const isSelected = current === lng; return ( change(lng)} leftSection={ Flag ? ( ) : ( ) } rightSection={ isSelected ? ( ) : undefined } style={{ borderRadius: rem(8), fontWeight: isSelected ? 600 : 400, backgroundColor: isSelected ? 'var(--mantine-primary-color-light)' : undefined, color: isSelected ? 'var(--mantine-primary-color-filled)' : undefined, }} > {t(`language.${lng}`, config.nativeName)} ); })} ); }