initial
This commit is contained in:
134
static/components/LanguageSelector.js
Normal file
134
static/components/LanguageSelector.js
Normal file
@@ -0,0 +1,134 @@
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user