Add feature to close the language switching dropdown when the user clicks outside of it

This commit is contained in:
2026-05-21 23:28:42 +02:00
parent 258a4025bc
commit 006bb5136e
@@ -22,6 +22,7 @@ import { loadLanguage, LANGUAGES_RTL } from '@/i18n';
const { t, locale } = useI18n(); const { t, locale } = useI18n();
const isOpen = ref(false); const isOpen = ref(false);
const languageDropdown = ref(null);
const languages = [ const languages = [
{ code: 'en', flag: '🇬🇧' }, { code: 'en', flag: '🇬🇧' },
@@ -41,24 +42,37 @@ async function selectLanguage(code) {
localStorage.setItem('locale', code); localStorage.setItem('locale', code);
document.documentElement.lang = code; document.documentElement.lang = code;
document.documentElement.dir = LANGUAGES_RTL.includes(code) ? 'rtl' : 'ltr'; document.documentElement.dir = LANGUAGES_RTL.includes(code) ? 'rtl' : 'ltr';
close();
};
const close = function () {
document.removeEventListener('click', closeWrapperOnClickOutsite);
isOpen.value = false; isOpen.value = false;
} };
function toggle() { const closeWrapperOnClickOutsite = function (e) {
isOpen.value = !isOpen.value; if (languageDropdown.value) {
} if (!languageDropdown.value.contains(e.target)) {
close();
};
};
};
function closeOnBlur() { const open = function () {
// A short delay so that the click on the option can be registered if (!isOpen.value) {
setTimeout(() => { isOpen.value = false; }, 150); isOpen.value = true;
} setTimeout(() => {
document.addEventListener('click', closeWrapperOnClickOutsite);
}, 0);
};
};
</script> </script>
<template> <template>
<div class="language-switch" @blur="closeOnBlur" tabindex="-1"> <div class="language-switch" tabindex="-1">
<button <button
class="language-button button" class="language-button button"
@click="toggle" @click="open"
:aria-expanded="isOpen" :aria-expanded="isOpen"
aria-haspopup="listbox" aria-haspopup="listbox"
> >
@@ -67,7 +81,7 @@ function closeOnBlur() {
<span class="chevron" :class="{ open: isOpen }"></span> <span class="chevron" :class="{ open: isOpen }"></span>
</button> </button>
<ul v-if="isOpen" 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 languages"
:key="lang.code" :key="lang.code"