mirror of
https://github.com/suitenumerique/meet.git
synced 2026-08-05 16:37:43 +00:00
♿️(a11y) improve settings dialog screen reader support
Add aria labels, initial focus and accessible heading to dialog
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -106,7 +106,8 @@
|
||||
"columnShortcut": "Shortcut"
|
||||
},
|
||||
"dialog": {
|
||||
"heading": "Settings"
|
||||
"heading": "Settings",
|
||||
"tablistLabel": "Sections"
|
||||
},
|
||||
"language": {
|
||||
"heading": "Language",
|
||||
|
||||
@@ -106,7 +106,8 @@
|
||||
"columnShortcut": "Raccourci"
|
||||
},
|
||||
"dialog": {
|
||||
"heading": "Paramètres"
|
||||
"heading": "Paramètres",
|
||||
"tablistLabel": "Sections"
|
||||
},
|
||||
"language": {
|
||||
"heading": "Langue",
|
||||
|
||||
Reference in New Issue
Block a user