diff --git a/frontend/src/components/shared/LanguageSelector.tsx b/frontend/src/components/shared/LanguageSelector.tsx index f2fddf212..2ec563a72 100644 --- a/frontend/src/components/shared/LanguageSelector.tsx +++ b/frontend/src/components/shared/LanguageSelector.tsx @@ -5,20 +5,141 @@ import { supportedLanguages } from '../../i18n'; import LocalIcon from './LocalIcon'; import styles from './LanguageSelector.module.css'; +// Types interface LanguageSelectorProps { position?: React.ComponentProps['position']; offset?: number; compact?: boolean; // icon-only trigger } -const LanguageSelector = ({ position = 'bottom-start', offset = 8, compact = false }: LanguageSelectorProps) => { +interface LanguageOption { + value: string; + label: string; +} + +interface RippleEffect { + x: number; + y: number; + key: number; +} + +// Sub-components +interface LanguageItemProps { + option: LanguageOption; + index: number; + animationTriggered: boolean; + isSelected: boolean; + onClick: (event: React.MouseEvent) => void; + rippleEffect?: RippleEffect | null; + pendingLanguage: string | null; + compact: boolean; +} + +const LanguageItem: React.FC = ({ + option, + index, + animationTriggered, + isSelected, + onClick, + rippleEffect, + pendingLanguage, + compact +}) => { + return ( +
+ +
+ ); +}; + +const RippleStyles: React.FC = () => ( + +); + +// Main component +const LanguageSelector: React.FC = ({ position = 'bottom-start', offset = 8, compact = false }) => { const { i18n } = useTranslation(); const [opened, setOpened] = useState(false); const [animationTriggered, setAnimationTriggered] = useState(false); const [pendingLanguage, setPendingLanguage] = useState(null); - const [rippleEffect, setRippleEffect] = useState<{x: number, y: number, key: number} | null>(null); + const [rippleEffect, setRippleEffect] = useState(null); - const languageOptions = Object.entries(supportedLanguages) + const languageOptions: LanguageOption[] = Object.entries(supportedLanguages) .sort(([, nameA], [, nameB]) => nameA.localeCompare(nameB)) .map(([code, name]) => ({ value: code, @@ -65,15 +186,7 @@ const LanguageSelector = ({ position = 'bottom-start', offset = 8, compact = fal return ( <> - + - - {compact ? ( - + {compact ? ( + - - - ) : ( - - )} - + }} + > + + + ) : ( + + )} + - - -
- {languageOptions.map((option, index) => ( -
- -
- ))} -
-
-
+ rippleEffect={rippleEffect} + pendingLanguage={pendingLanguage} + compact={compact} + /> + ))} + + +
); }; export default LanguageSelector; +export type { LanguageSelectorProps, LanguageOption, RippleEffect }; \ No newline at end of file