47 lines
1.4 KiB
Vue
47 lines
1.4 KiB
Vue
<script setup lang="ts">
|
|
import { Globe2, ChevronDown } from "lucide-vue-next";
|
|
const { locale, setLocale } = useI18n();
|
|
const open = ref(false);
|
|
const root = ref<HTMLElement>();
|
|
const languages = [
|
|
{ code: "en", name: "English" },
|
|
{ code: "ru", name: "Русский" },
|
|
{ code: "es", name: "Español" },
|
|
] as const;
|
|
function outside(e: PointerEvent) {
|
|
if (!root.value?.contains(e.target as Node)) open.value = false;
|
|
}
|
|
onMounted(() => document.addEventListener("pointerdown", outside));
|
|
onBeforeUnmount(() => document.removeEventListener("pointerdown", outside));
|
|
</script>
|
|
<template>
|
|
<div ref="root" class="language" @keydown.esc="open = false">
|
|
<GlassButton
|
|
:aria-label="$t('general.language')"
|
|
:aria-expanded="open"
|
|
aria-controls="language-options"
|
|
@click="open = !open"
|
|
><Globe2 :size="17" /><span>{{ locale.toUpperCase() }}</span
|
|
><ChevronDown :size="14"
|
|
/></GlassButton>
|
|
<GlassCard
|
|
v-if="open"
|
|
id="language-options"
|
|
class="language-menu"
|
|
role="group"
|
|
:aria-label="$t('general.language')"
|
|
><button
|
|
v-for="lang in languages"
|
|
:key="lang.code"
|
|
:aria-pressed="locale === lang.code"
|
|
@click="
|
|
setLocale(lang.code);
|
|
open = false;
|
|
"
|
|
>
|
|
{{ lang.name }}<span v-if="locale === lang.code">✓</span>
|
|
</button></GlassCard
|
|
>
|
|
</div>
|
|
</template>
|