fix: language buttons real design / conformance
This commit is contained in:
1 parent
2c8f39273c
commit
0490a4c494
23 files changed
+1408
-412
No files matched your search
@@ -0,0 +1,15 @@
|
||||
import { computed } from 'vue'
|
||||
import { locale, setLocale, type Locale } from '@/i18n'
|
||||
|
||||
export const languageOptions: { label: string; value: Locale }[] = [
|
||||
{ label: 'English', value: 'en' },
|
||||
{ label: 'Français', value: 'fr' },
|
||||
]
|
||||
|
||||
export const languageName = computed(
|
||||
() => languageOptions.find((option) => option.value === locale.value)?.label ?? 'English',
|
||||
)
|
||||
|
||||
export function chooseLanguage(value: Locale) {
|
||||
setLocale(value)
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import { onBeforeUnmount, watch, type Ref } from 'vue'
|
||||
import { t } from '@/i18n'
|
||||
import { languageOptions } from '@/composables/useLanguage'
|
||||
|
||||
export const LANGUAGE_MENU_CLASS = 'rc-language-menu'
|
||||
|
||||
function groupLabel(group: Element) {
|
||||
const id = group.getAttribute('aria-labelledby')
|
||||
return id ? document.getElementById(id)?.textContent?.trim() : undefined
|
||||
}
|
||||
|
||||
function toRadio(item: Element) {
|
||||
item.setAttribute('role', 'menuitemradio')
|
||||
const language = languageOptions.find((option) => option.label === item.textContent?.trim())
|
||||
if (language) item.setAttribute('lang', language.value)
|
||||
}
|
||||
|
||||
function radiofyAccountMenu() {
|
||||
const labels = [t('Theme'), t('Language')]
|
||||
for (const group of document.querySelectorAll('[role="menu"] [role="group"]')) {
|
||||
const label = groupLabel(group)
|
||||
if (!label || !labels.includes(label)) continue
|
||||
group.querySelectorAll('[role="menuitemcheckbox"]').forEach(toRadio)
|
||||
}
|
||||
}
|
||||
|
||||
function radiofyLanguageMenu() {
|
||||
for (const menu of document.querySelectorAll(`[role="menu"].${LANGUAGE_MENU_CLASS}`)) {
|
||||
menu.setAttribute('aria-label', t('Language'))
|
||||
menu.querySelectorAll('[role="menuitemcheckbox"]').forEach(toRadio)
|
||||
}
|
||||
}
|
||||
|
||||
function applyWhileOpen(open: Ref<boolean>, apply: () => void) {
|
||||
let observer: MutationObserver | null = null
|
||||
|
||||
function stop() {
|
||||
observer?.disconnect()
|
||||
observer = null
|
||||
}
|
||||
|
||||
watch(
|
||||
open,
|
||||
(value) => {
|
||||
stop()
|
||||
if (!value) return
|
||||
apply()
|
||||
observer = new MutationObserver(apply)
|
||||
observer.observe(document.body, { childList: true, subtree: true })
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
onBeforeUnmount(stop)
|
||||
}
|
||||
|
||||
export function useAccountMenuRadios(open: Ref<boolean>) {
|
||||
applyWhileOpen(open, radiofyAccountMenu)
|
||||
}
|
||||
|
||||
export function useLanguageMenuRadios(open: Ref<boolean>) {
|
||||
applyWhileOpen(open, radiofyLanguageMenu)
|
||||
}
|
||||
Reference in new issue
Block a user