import { useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Languages, Globe, ChevronDown } from 'lucide-react'
import {
SUPPORTED_LANGUAGES,
changeAppLanguage,
normalizeAppLanguage,
type AppLanguage
} from '../utils/i18nLanguages.js'
function FlagIcon({ lang, className, style }: { lang: string; className?: string; style?: React.CSSProperties }) {
const baseStyle = {
display: 'inline-block',
verticalAlign: 'middle',
borderRadius: '2px',
overflow: 'hidden',
border: '1px solid rgba(255, 255, 255, 0.15)',
boxSizing: 'border-box' as const,
...style
}
switch (lang) {
case 'de':
return (
)
case 'en':
return (
)
case 'da':
return (
)
case 'sv':
return (
)
case 'nb':
return (
)
case 'fr':
return (
)
case 'es':
return (
)
default:
return null
}
}
interface LanguageDropdownProps {
variant?: 'icon' | 'text' | 'secondary-button'
align?: 'left' | 'right'
}
export default function LanguageDropdown({
variant = 'icon',
align = 'right'
}: LanguageDropdownProps) {
const { t, i18n } = useTranslation()
const [isOpen, setIsOpen] = useState(false)
const rootRef = useRef(null)
const activeLang = normalizeAppLanguage(i18n.language)
useEffect(() => {
if (!isOpen) return
const closeOnOutsideClick = (event: MouseEvent) => {
if (rootRef.current && !rootRef.current.contains(event.target as Node)) {
setIsOpen(false)
}
}
const closeOnEscape = (event: KeyboardEvent) => {
if (event.key === 'Escape') setIsOpen(false)
}
document.addEventListener('mousedown', closeOnOutsideClick)
document.addEventListener('keydown', closeOnEscape)
return () => {
document.removeEventListener('mousedown', closeOnOutsideClick)
document.removeEventListener('keydown', closeOnEscape)
}
}, [isOpen])
const selectLanguage = (lang: AppLanguage) => {
changeAppLanguage(i18n, lang)
setIsOpen(false)
}
// Trigger button content based on variant
const renderTriggerContent = () => {
const name = t(`languages.${activeLang}`)
if (variant === 'icon') {
return (
)
}
if (variant === 'secondary-button') {
return (
<>
{name}
>
)
}
// Default or "text" variant (used in footer)
return (
<>
{name}
>
)
}
const triggerClass =
variant === 'icon'
? 'btn-icon'
: variant === 'secondary-button'
? 'btn secondary compact'
: 'btn-icon-text'
return (
{isOpen && (
{SUPPORTED_LANGUAGES.map((lang) => {
const isSelected = lang === activeLang
return (
- selectLanguage(lang)}
>
{t(`languages.${lang}`)}
)
})}
)}
)
}