fix: language buttons real design / conformance

This commit is contained in:
fsylvain committed 2026-10-04 17:08:43 +02:00
1 parent 2c8f39273c
commit 0490a4c494
23 files changed
+1408 -412

No files matched your search

+53 -26
View File
@@ -1,13 +1,15 @@
<script setup lang="ts">
import { t } from '@/i18n'
import { locale, t } from '@/i18n'
import { ref } from 'vue'
import { ref, useId } from 'vue'
import type { ColorModePreference } from '@/composables/useColorMode'
import { colorModeOptions, useAccountMenu } from '@/composables/useAccountMenu'
import LanguagePicker from '@/components/LanguagePicker.vue'
import { chooseLanguage, languageOptions } from '@/composables/useLanguage'
const ITEM_SELECTOR = '[role="menuitem"], [role="menuitemcheckbox"], [role="combobox"]'
const ITEM_CLASS = 'h-12 justify-start gap-3 px-4 text-[0.9375rem] text-highlighted'
const ITEM_SELECTOR = '[role="menuitem"], [role="menuitemradio"]'
const ITEM_CLASS = 'h-12 justify-start gap-3 px-4 text-[0.9375rem] font-normal text-highlighted'
const SECTION_LABEL_CLASS =
'px-4 pt-2 pb-0.5 text-[0.6875rem] font-medium uppercase tracking-[0.04em] text-muted'
const props = defineProps<{
username: string
@@ -29,6 +31,8 @@ const {
goToProfile: navigateToProfile,
} = useAccountMenu(() => props)
const menu = ref<HTMLElement | null>(null)
const themeLabelId = useId()
const languageLabelId = useId()
function goToProfile() {
open.value = false
@@ -37,7 +41,6 @@ function goToProfile() {
function chooseColorMode(value: ColorModePreference) {
colorMode.preference = value
open.value = false
}
function logOut() {
@@ -46,7 +49,6 @@ function logOut() {
}
function moveFocus(event: KeyboardEvent) {
if ((event.target as HTMLElement).closest('[role="combobox"]')) return
const items = Array.from(menu.value?.querySelectorAll<HTMLElement>(ITEM_SELECTOR) ?? [])
if (items.length === 0) {
return
@@ -96,7 +98,7 @@ function moveFocus(event: KeyboardEvent) {
:text="initials"
:ui="{
root: 'size-9 bg-secondary-300',
fallback: 'text-[0.8125rem] font-semibold text-primary-900',
fallback: 'text-[0.8125rem] pt-0.5 font-semibold text-primary-900',
}"
/>
<div class="flex min-w-0 flex-col">
@@ -121,26 +123,51 @@ function moveFocus(event: KeyboardEvent) {
</UButton>
<USeparator class="my-1" />
<LanguagePicker mobile />
<div role="group" :aria-labelledby="themeLabelId">
<div :id="themeLabelId" :class="SECTION_LABEL_CLASS">{{ t('Theme') }}</div>
<UButton
v-for="option in colorModeOptions"
:key="option.value"
role="menuitemradio"
color="neutral"
variant="ghost"
block
:aria-checked="colorMode.preference === option.value"
:trailing-icon="
colorMode.preference === option.value ? 'i-lucide-check' : undefined
"
:class="ITEM_CLASS"
:ui="{ trailingIcon: 'ms-auto size-4.5' }"
@click="chooseColorMode(option.value)"
>
{{ option.label }}
</UButton>
</div>
<USeparator class="my-1" />
<UButton
v-for="option in colorModeOptions"
:key="option.value"
role="menuitemcheckbox"
color="neutral"
variant="ghost"
block
:aria-checked="colorMode.preference === option.value"
:trailing-icon="
colorMode.preference === option.value ? 'i-lucide-check' : undefined
"
:class="ITEM_CLASS"
:ui="{ trailingIcon: 'ms-auto size-4.5' }"
@click="chooseColorMode(option.value)"
>
{{ option.label }}
</UButton>
<div role="group" :aria-labelledby="languageLabelId">
<div :id="languageLabelId" :class="SECTION_LABEL_CLASS">
{{ t('Language') }}
</div>
<UButton
v-for="option in languageOptions"
:key="option.value"
role="menuitemradio"
color="neutral"
variant="ghost"
block
:lang="option.value"
:aria-checked="locale === option.value"
:trailing-icon="locale === option.value ? 'i-lucide-check' : undefined"
:class="ITEM_CLASS"
:ui="{ trailingIcon: 'ms-auto size-4.5' }"
@click="chooseLanguage(option.value)"
>
{{ option.label }}
</UButton>
</div>
<USeparator class="my-1" />