49 lines
1.8 KiB
TypeScript
49 lines
1.8 KiB
TypeScript
import { useEffect, useRef, useState } from "react";
|
|
import { Check } from "lucide-react";
|
|
import { usePlatformLanguage } from "../i18n/LanguageContext";
|
|
|
|
export default function LanguageMenu() {
|
|
const { language, selectableLanguages, setLanguage } = usePlatformLanguage();
|
|
const [open, setOpen] = useState(false);
|
|
const menuRef = useRef<HTMLDivElement>(null);
|
|
|
|
useEffect(() => {
|
|
function onPointerDown(event: MouseEvent) {
|
|
const target = event.target as Node;
|
|
if (menuRef.current && !menuRef.current.contains(target)) setOpen(false);
|
|
}
|
|
window.addEventListener("mousedown", onPointerDown);
|
|
return () => window.removeEventListener("mousedown", onPointerDown);
|
|
}, []);
|
|
|
|
if (selectableLanguages.length <= 1) return null;
|
|
|
|
function selectLanguage(code: string) {
|
|
setLanguage(code);
|
|
setOpen(false);
|
|
}
|
|
|
|
return (
|
|
<div className="context-menu-wrap language-menu-wrap" ref={menuRef}>
|
|
<button className="titlebar-link language-menu-button" onClick={() => setOpen(!open)} aria-haspopup="menu" aria-expanded={open}>
|
|
<span className="language-menu-code">{language.toUpperCase()}</span>
|
|
<span className="tenant-caret">▾</span>
|
|
</button>
|
|
{open && (
|
|
<div className="dropdown-menu language-menu" role="menu">
|
|
{selectableLanguages.map((item) => {
|
|
const active = item.code === language;
|
|
return (
|
|
<button key={item.code} className={`dropdown-item ${active ? "active" : ""}`} onClick={() => selectLanguage(item.code)} role="menuitem">
|
|
<span className="language-option-code">{item.code.toUpperCase()}</span>
|
|
<span>{item.nativeLabel || item.label}</span>
|
|
{active && <Check size={16} />}
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|