import React, { useState, useEffect } from 'react'; import { Menu, Button, ScrollArea, ActionIcon } from '@mantine/core'; import { useTranslation } from 'react-i18next'; import { supportedLanguages } from '../../i18n'; import LanguageIcon from '@mui/icons-material/Language'; import styles from './LanguageSelector.module.css'; interface LanguageSelectorProps { position?: React.ComponentProps['position']; offset?: number; compact?: boolean; // icon-only trigger } const LanguageSelector = ({ position = 'bottom-start', offset = 8, compact = false }: LanguageSelectorProps) => { const { i18n } = useTranslation(); const [opened, setOpened] = useState(false); const [animationTriggered, setAnimationTriggered] = useState(false); const [isChanging, setIsChanging] = useState(false); const [pendingLanguage, setPendingLanguage] = useState(null); const [rippleEffect, setRippleEffect] = useState<{x: number, y: number, key: number} | null>(null); const languageOptions = Object.entries(supportedLanguages) .sort(([, nameA], [, nameB]) => nameA.localeCompare(nameB)) .map(([code, name]) => ({ value: code, label: name, })); const handleLanguageChange = (value: string, event: React.MouseEvent) => { // Create ripple effect at click position (only for button mode) if (!compact) { const rect = (event.currentTarget as HTMLElement).getBoundingClientRect(); const x = event.clientX - rect.left; const y = event.clientY - rect.top; setRippleEffect({ x, y, key: Date.now() }); } // Start transition animation setIsChanging(true); setPendingLanguage(value); // Simulate processing time for smooth transition setTimeout(() => { i18n.changeLanguage(value); setTimeout(() => { setIsChanging(false); setPendingLanguage(null); setOpened(false); // Clear ripple effect setTimeout(() => setRippleEffect(null), 100); }, 300); }, 200); }; const currentLanguage = supportedLanguages[i18n.language as keyof typeof supportedLanguages] || supportedLanguages['en-GB']; // Trigger animation when dropdown opens useEffect(() => { if (opened) { setAnimationTriggered(false); // Small delay to ensure DOM is ready setTimeout(() => setAnimationTriggered(true), 50); } }, [opened]); return ( <> {compact ? ( language ) : ( )}
{languageOptions.map((option, index) => (
))}
); }; export default LanguageSelector;