Add more Languages and switch button #70

Merged
jakob.scheid merged 22 commits from feature/add-languages into main 2026-05-22 17:19:25 +02:00
8 changed files with 46 additions and 61 deletions
Showing only changes of commit abbfd0ad9d - Show all commits
@@ -15,28 +15,15 @@ limitations under the License.
--> -->
<script setup> <script setup>
import { ref, computed } from 'vue'; import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { loadLanguage, LANGUAGES_RTL } from '@/i18n'; import { loadLanguage, LANGUAGES_RTL, SUPPORTED_LANGUAGES } from '@/i18n';
const { t, locale } = useI18n(); const { t, locale } = useI18n();
const isOpen = ref(false); const isOpen = ref(false);
const languageDropdown = ref(null); const languageDropdown = ref(null);
const languages = [
{ code: 'en', flag: '🇬🇧' },
{ code: 'de', flag: '🇩🇪' },
{ code: 'fr', flag: '🇫🇷' },
{ code: 'es', flag: '🇪🇸' },
{ code: 'it', flag: '🇮🇹' },
{ code: 'pt', flag: '🇵🇹' },
];
const currentLanguage = computed(
() => languages.find(l => l.code === locale.value) ?? languages[0]
);
async function selectLanguage(code) { async function selectLanguage(code) {
await loadLanguage(code); await loadLanguage(code);
localStorage.setItem('locale', code); localStorage.setItem('locale', code);
@@ -76,22 +63,20 @@ const open = function () {
:aria-expanded="isOpen" :aria-expanded="isOpen"
aria-haspopup="listbox" aria-haspopup="listbox"
> >
<span class="flag">{{ currentLanguage.flag }}</span> <span class="lang-code">{{ t(`preferences.locale.languages.${locale}`) }}</span>
<span class="lang-code">{{ currentLanguage.code.toUpperCase() }}</span>
<span class="chevron" :class="{ open: isOpen }"></span> <span class="chevron" :class="{ open: isOpen }"></span>
</button> </button>
<ul v-if="isOpen" ref="languageDropdown" class="language-dropdown" role="listbox"> <ul v-if="isOpen" ref="languageDropdown" class="language-dropdown" role="listbox">
<li <li
v-for="lang in languages" v-for="lang in SUPPORTED_LANGUAGES"
:key="lang.code" :key="lang"
role="option" role="option"
:aria-selected="lang.code === locale" :aria-selected="lang === locale"
:class="{ active: lang.code === locale }" :class="{ active: lang === locale }"
@click="selectLanguage(lang.code)" @click="selectLanguage(lang)"
> >
<span class="flag">{{ lang.flag }}</span> <span class="lang-label">{{ t(`preferences.locale.languages.${lang}`) }}</span>
<span class="lang-label">{{ t(`preferences.locale.languages.${lang.code}`) }}</span>
</li> </li>
</ul> </ul>
</div> </div>
1
+1 -1
View File
@@ -23,7 +23,7 @@ export const fallbackLocale = 'en';
export const LANGUAGES_RTL = [ export const LANGUAGES_RTL = [
jakob.scheid marked this conversation as resolved Outdated
Outdated
Review

Not all of these languages are supported.

Not all of these languages are supported.
'ar' 'ar'
]; ];
const SUPPORTED_LANGUAGES = [ export const SUPPORTED_LANGUAGES = [
'en', 'en',
'de', 'de',
'fr', 'fr',
+6 -6
View File
@@ -27,12 +27,12 @@
}, },
"locale": { "locale": {
"languages": { "languages": {
"en": "English", "en": "🇬🇧 English",
"de": "Deutsch", "de": "🇩🇪 Deutsch",
"fr": "Français", "fr": "🇫🇷 Français",
"es": "Español", "es": "🇪🇸 Español",
"it": "Italiano", "it": "🇮🇹 Italiano",
"pt": "Português" "pt": "🇵🇹 Português"
} }
} }
}, },
+6 -6
View File
@@ -27,12 +27,12 @@
}, },
"locale": { "locale": {
"languages": { "languages": {
"en": "English", "en": "🇬🇧 English",
"de": "Deutsch", "de": "🇩🇪 Deutsch",
"fr": "Français", "fr": "🇫🇷 Français",
"es": "Español", "es": "🇪🇸 Español",
"it": "Italiano", "it": "🇮🇹 Italiano",
"pt": "Português" "pt": "🇵🇹 Português"
} }
} }
}, },
+6 -6
View File
@@ -27,12 +27,12 @@
}, },
"locale": { "locale": {
"languages": { "languages": {
"en": "English", "en": "🇬🇧 English",
"de": "Deutsch", "de": "🇩🇪 Deutsch",
"fr": "Français", "fr": "🇫🇷 Français",
"es": "Español", "es": "🇪🇸 Español",
"it": "Italiano", "it": "🇮🇹 Italiano",
"pt": "Português" "pt": "🇵🇹 Português"
} }
} }
}, },
+6 -6
View File
@@ -27,12 +27,12 @@
}, },
"locale": { "locale": {
"languages": { "languages": {
"en": "English", "en": "🇬🇧 English",
"de": "Deutsch", "de": "🇩🇪 Deutsch",
"fr": "Français", "fr": "🇫🇷 Français",
"es": "Español", "es": "🇪🇸 Español",
"it": "Italiano", "it": "🇮🇹 Italiano",
"pt": "Português" "pt": "🇵🇹 Português"
} }
} }
}, },
+6 -6
View File
@@ -27,12 +27,12 @@
}, },
"locale": { "locale": {
"languages": { "languages": {
"en": "English", "en": "🇬🇧 English",
"de": "Deutsch", "de": "🇩🇪 Deutsch",
"fr": "Français", "fr": "🇫🇷 Français",
"es": "Español", "es": "🇪🇸 Español",
"it": "Italiano", "it": "🇮🇹 Italiano",
"pt": "Português" "pt": "🇵🇹 Português"
} }
} }
}, },
+6 -6
View File
@@ -27,12 +27,12 @@
}, },
"locale": { "locale": {
"languages": { "languages": {
"en": "English", "en": "🇬🇧 English",
"de": "Deutsch", "de": "🇩🇪 Deutsch",
"fr": "Français", "fr": "🇫🇷 Français",
"es": "Español", "es": "🇪🇸 Español",
"it": "Italiano", "it": "🇮🇹 Italiano",
"pt": "Português" "pt": "🇵🇹 Português"
} }
} }
}, },