135 lines
4.4 KiB
JavaScript
135 lines
4.4 KiB
JavaScript
// Language Selector Component with Emojis
|
|
export class LanguageSelector {
|
|
constructor(onLanguageChange) {
|
|
this.onLanguageChange = onLanguageChange;
|
|
this.currentLang = '';
|
|
this.languages = [
|
|
{ code: '', name: 'English', emoji: '🇬🇧', native: 'English' },
|
|
{ code: 'de', name: 'German', emoji: '🇩🇪', native: 'Deutsch' },
|
|
{ code: 'fr', name: 'French', emoji: '🇫🇷', native: 'Français' },
|
|
{ code: 'es', name: 'Spanish', emoji: '🇪🇸', native: 'Español' },
|
|
{ code: 'it', name: 'Italian', emoji: '🇮🇹', native: 'Italiano' },
|
|
{ code: 'pt', name: 'Portuguese', emoji: '🇵🇹', native: 'Português' },
|
|
{ code: 'ru', name: 'Russian', emoji: '🇷🇺', native: 'Русский' }
|
|
];
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
// Load saved language preference
|
|
const savedLang = localStorage.getItem('preferredLanguage') || '';
|
|
this.currentLang = savedLang;
|
|
this.createSelector();
|
|
}
|
|
|
|
createSelector() {
|
|
// Create floating language selector
|
|
const selector = document.createElement('div');
|
|
selector.className = 'language-selector';
|
|
selector.id = 'languageSelector';
|
|
|
|
const button = document.createElement('button');
|
|
button.className = 'language-selector-button';
|
|
button.setAttribute('aria-label', 'Select language');
|
|
button.setAttribute('aria-haspopup', 'true');
|
|
|
|
const currentLang = this.languages.find(lang => lang.code === this.currentLang) || this.languages[0];
|
|
button.innerHTML = `
|
|
<span class="language-emoji">${currentLang.emoji}</span>
|
|
<span class="language-name">${currentLang.native}</span>
|
|
<span class="language-arrow">▼</span>
|
|
`;
|
|
|
|
const dropdown = document.createElement('div');
|
|
dropdown.className = 'language-dropdown';
|
|
dropdown.id = 'languageDropdown';
|
|
|
|
this.languages.forEach(lang => {
|
|
const option = document.createElement('button');
|
|
option.className = `language-option ${lang.code === this.currentLang ? 'active' : ''}`;
|
|
option.dataset.code = lang.code;
|
|
option.innerHTML = `
|
|
<span class="language-emoji">${lang.emoji}</span>
|
|
<span class="language-name">${lang.native}</span>
|
|
<span class="language-name-en">${lang.name}</span>
|
|
`;
|
|
|
|
option.addEventListener('click', () => {
|
|
this.selectLanguage(lang.code);
|
|
dropdown.classList.remove('active');
|
|
});
|
|
|
|
dropdown.appendChild(option);
|
|
});
|
|
|
|
button.addEventListener('click', (e) => {
|
|
e.stopPropagation();
|
|
const isActive = dropdown.classList.contains('active');
|
|
dropdown.classList.toggle('active');
|
|
// Update arrow rotation
|
|
const arrow = button.querySelector('.language-arrow');
|
|
if (arrow) {
|
|
arrow.style.transform = isActive ? 'rotate(0deg)' : 'rotate(180deg)';
|
|
}
|
|
});
|
|
|
|
selector.appendChild(button);
|
|
selector.appendChild(dropdown);
|
|
|
|
// Store reference for arrow rotation
|
|
this.button = button;
|
|
this.dropdown = dropdown;
|
|
|
|
// Insert into content area (top right)
|
|
const content = document.getElementById('content');
|
|
if (content) {
|
|
content.insertBefore(selector, content.firstChild);
|
|
}
|
|
|
|
// Close dropdown when clicking outside
|
|
document.addEventListener('click', (e) => {
|
|
if (!selector.contains(e.target)) {
|
|
dropdown.classList.remove('active');
|
|
const arrow = button.querySelector('.language-arrow');
|
|
if (arrow) {
|
|
arrow.style.transform = 'rotate(0deg)';
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
selectLanguage(code) {
|
|
this.currentLang = code;
|
|
localStorage.setItem('preferredLanguage', code);
|
|
|
|
// Update button display
|
|
const currentLang = this.languages.find(lang => lang.code === code) || this.languages[0];
|
|
const button = document.querySelector('.language-selector-button');
|
|
if (button) {
|
|
button.innerHTML = `
|
|
<span class="language-emoji">${currentLang.emoji}</span>
|
|
<span class="language-name">${currentLang.native}</span>
|
|
<span class="language-arrow">▼</span>
|
|
`;
|
|
}
|
|
|
|
// Update active option
|
|
document.querySelectorAll('.language-option').forEach(option => {
|
|
if (option.dataset.code === code) {
|
|
option.classList.add('active');
|
|
} else {
|
|
option.classList.remove('active');
|
|
}
|
|
});
|
|
|
|
if (this.onLanguageChange) {
|
|
this.onLanguageChange(code);
|
|
}
|
|
}
|
|
|
|
getCurrentLanguage() {
|
|
return this.currentLang;
|
|
}
|
|
}
|
|
|