Compare commits

...

1 Commits

Author SHA1 Message Date
Cyril 829ef7ed1b ️(a11y) improve settings dialog screen reader support
Add aria labels, initial focus and accessible heading to dialog
2026-02-24 15:45:32 +01:00
3 changed files with 44 additions and 24 deletions
@@ -21,7 +21,7 @@ import { AudioTab } from './tabs/AudioTab'
import { VideoTab } from './tabs/VideoTab'
import { TranscriptionTab } from './tabs/TranscriptionTab'
import { ShortcutTab } from './tabs/ShortcutTab'
import { useRef } from 'react'
import { useEffect, useRef } from 'react'
import { useMediaQuery } from '@/features/rooms/livekit/hooks/useMediaQuery'
import { SettingsDialogExtendedKey } from '@/features/settings/type'
import { useIsAdminOrOwner } from '@/features/rooms/livekit/hooks/useIsAdminOrOwner'
@@ -68,6 +68,17 @@ export const SettingsDialogExtended = (props: SettingsDialogExtended) => {
const isAdminOrOwner = useIsAdminOrOwner()
useEffect(() => {
if (!props.isOpen) return
const timer = setTimeout(() => {
const selectedTab = dialogEl.current?.querySelector(
'[role="tab"][data-selected]'
) as HTMLElement | null
selectedTab?.focus()
}, 200)
return () => clearTimeout(timer)
}, [props.isOpen])
return (
<Dialog innerRef={dialogEl} {...props} role="dialog" type="flex">
<Tabs
@@ -83,46 +94,53 @@ export const SettingsDialogExtended = (props: SettingsDialogExtended) => {
paddingRight: !isWideScreen ? '1rem' : undefined,
}}
>
{isWideScreen && (
<Heading slot="title" level={1} className={text({ variant: 'h1' })}>
{t('dialog.heading')}
</Heading>
)}
<TabList border={false}>
<Tab icon highlight id={SettingsDialogExtendedKey.ACCOUNT}>
<RiAccountCircleLine />
<Heading
slot="title"
level={1}
className={
isWideScreen ? text({ variant: 'h1' }) : 'sr-only'
}
>
{t('dialog.heading')}
</Heading>
<TabList
border={false}
aria-label={t('dialog.tablistLabel')}
>
<Tab icon highlight id={SettingsDialogExtendedKey.ACCOUNT} aria-label={t(`tabs.${SettingsDialogExtendedKey.ACCOUNT}`)}>
<RiAccountCircleLine aria-hidden="true" />
{isWideScreen && t(`tabs.${SettingsDialogExtendedKey.ACCOUNT}`)}
</Tab>
<Tab icon highlight id={SettingsDialogExtendedKey.AUDIO}>
<RiSpeakerLine />
<Tab icon highlight id={SettingsDialogExtendedKey.AUDIO} aria-label={t(`tabs.${SettingsDialogExtendedKey.AUDIO}`)}>
<RiSpeakerLine aria-hidden="true" />
{isWideScreen && t(`tabs.${SettingsDialogExtendedKey.AUDIO}`)}
</Tab>
<Tab icon highlight id={SettingsDialogExtendedKey.VIDEO}>
<RiVideoOnLine />
<Tab icon highlight id={SettingsDialogExtendedKey.VIDEO} aria-label={t(`tabs.${SettingsDialogExtendedKey.VIDEO}`)}>
<RiVideoOnLine aria-hidden="true" />
{isWideScreen && t(`tabs.${SettingsDialogExtendedKey.VIDEO}`)}
</Tab>
<Tab icon highlight id={SettingsDialogExtendedKey.GENERAL}>
<RiSettings3Line />
<Tab icon highlight id={SettingsDialogExtendedKey.GENERAL} aria-label={t(`tabs.${SettingsDialogExtendedKey.GENERAL}`)}>
<RiSettings3Line aria-hidden="true" />
{isWideScreen && t(`tabs.${SettingsDialogExtendedKey.GENERAL}`)}
</Tab>
<Tab icon highlight id={SettingsDialogExtendedKey.NOTIFICATIONS}>
<RiNotification3Line />
<Tab icon highlight id={SettingsDialogExtendedKey.NOTIFICATIONS} aria-label={t(`tabs.${SettingsDialogExtendedKey.NOTIFICATIONS}`)}>
<RiNotification3Line aria-hidden="true" />
{isWideScreen &&
t(`tabs.${SettingsDialogExtendedKey.NOTIFICATIONS}`)}
</Tab>
<Tab icon highlight id={SettingsDialogExtendedKey.SHORTCUTS}>
<RiKeyboardBoxLine />
<Tab icon highlight id={SettingsDialogExtendedKey.SHORTCUTS} aria-label={t(`tabs.${SettingsDialogExtendedKey.SHORTCUTS}`)}>
<RiKeyboardBoxLine aria-hidden="true" />
{isWideScreen && t(`tabs.${SettingsDialogExtendedKey.SHORTCUTS}`)}
</Tab>
{isAdminOrOwner && (
<Tab icon highlight id={SettingsDialogExtendedKey.TRANSCRIPTION}>
<Tab icon highlight id={SettingsDialogExtendedKey.TRANSCRIPTION} aria-label={t(`tabs.${SettingsDialogExtendedKey.TRANSCRIPTION}`)}>
<Icon type="symbols" name="speech_to_text" />
{isWideScreen &&
t(`tabs.${SettingsDialogExtendedKey.TRANSCRIPTION}`)}
</Tab>
)}
<Tab icon highlight id={SettingsDialogExtendedKey.ACCESSIBILITY}>
<RiEyeLine />
<Tab icon highlight id={SettingsDialogExtendedKey.ACCESSIBILITY} aria-label={t(`tabs.${SettingsDialogExtendedKey.ACCESSIBILITY}`)}>
<RiEyeLine aria-hidden="true" />
{isWideScreen &&
t(`tabs.${SettingsDialogExtendedKey.ACCESSIBILITY}`)}
</Tab>
+2 -1
View File
@@ -106,7 +106,8 @@
"columnShortcut": "Shortcut"
},
"dialog": {
"heading": "Settings"
"heading": "Settings",
"tablistLabel": "Sections"
},
"language": {
"heading": "Language",
+2 -1
View File
@@ -106,7 +106,8 @@
"columnShortcut": "Raccourci"
},
"dialog": {
"heading": "Paramètres"
"heading": "Paramètres",
"tablistLabel": "Sections"
},
"language": {
"heading": "Langue",