File size: 1,712 Bytes
494c9e4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | import * as d3 from 'd3';
import { getCurrentLanguage, setLanguage, type Language } from '../lang/i18n-lite';
import { tr } from '../lang/i18n-lite';
import { createSettingsDropdown } from './settingsDropdown';
export type LanguageManagerOptions = {
onLanguageChange?: () => void;
};
export type LanguageManager = {
dispose: () => void;
};
const languageOptions: Array<{ lang: Language; label: string }> = [
{ lang: 'en', label: 'English' },
{ lang: 'zh', label: 'Chinese' },
];
export function initLanguageManager(options: LanguageManagerOptions = {}, containerSelector: string = '#language_toggle'): LanguageManager {
const { onLanguageChange } = options;
const container = d3.select(containerSelector);
const selectLang = (lang: Language) => {
setLanguage(lang);
dropdown.updateCurrent(lang);
onLanguageChange?.();
location.reload();
};
const dropdown = createSettingsDropdown<Language>({
container,
classPrefix: 'language',
options: languageOptions.map(({ lang, label }) => ({ value: lang, html: `<span>${tr(label)}</span>` })),
dataAttr: 'data-lang',
bodyClickNamespace: 'language-dropdown',
onSelect: selectLang,
});
const storageListener = (event: StorageEvent) => {
if (event.key !== 'app_language') return;
if (event.newValue === 'en' || event.newValue === 'zh') location.reload();
};
dropdown.updateCurrent(getCurrentLanguage());
window.addEventListener('storage', storageListener);
return {
dispose: () => {
window.removeEventListener('storage', storageListener);
dropdown.dispose();
},
};
}
|