️(frontend) announce selected state to SR in select and menu list

Add visually hidden "selected" text for screen readers.
This commit is contained in:
Cyril
2026-03-04 14:56:07 +01:00
committed by aleb_the_flash
parent 9c009839f0
commit 3d7aec2b4a
7 changed files with 31 additions and 3 deletions

View File

@@ -12,6 +12,7 @@ and this project adheres to
- 🩹(frontend) remove incorrect reference to ProConnect on the prejoin #1080
- ✨(frontend) add Ctrl+Shift+/ to open shortcuts settings #1050
- ♿(frontend) announce selected state to screen readers #1081
### Changed

View File

@@ -25,6 +25,7 @@
"heading": "Überprüfen Sie Ihren Meeting-Code",
"body": "Stellen Sie sicher, dass Sie den richtigen Meeting-Code in der URL eingegeben haben. Beispiel:"
},
"selected": "ausgewählt",
"submit": "OK",
"footer": {
"links": {

View File

@@ -25,6 +25,7 @@
"heading": "Verify your meeting code",
"body": "Check that you have entered the correct meeting code in the URL. Example:"
},
"selected": "selected",
"submit": "OK",
"footer": {
"links": {

View File

@@ -25,6 +25,7 @@
"heading": "Vérifier votre code de réunion",
"body": "Vérifiez que vous avez saisi le code de réunion correct dans l'URL. Exemple :"
},
"selected": "sélectionné",
"submit": "OK",
"footer": {
"links": {

View File

@@ -24,6 +24,7 @@
"notFound": {
"heading": "Pagina niet gevonden"
},
"selected": "geselecteerd",
"submit": "OK",
"footer": {
"links": {

View File

@@ -1,5 +1,7 @@
import { ReactNode } from 'react'
import { Menu, MenuProps, MenuItem } from 'react-aria-components'
import { useTranslation } from 'react-i18next'
import { VisuallyHidden } from '@/styled-system/jsx'
import { menuRecipe } from '@/primitives/menuRecipe.ts'
import type { RecipeVariantProps } from '@/styled-system/types'
@@ -19,6 +21,7 @@ export const MenuList = <T extends string | number = string>({
} & MenuProps<unknown> &
RecipeVariantProps<typeof menuRecipe>) => {
const [variantProps] = menuRecipe.splitVariantProps(menuProps)
const { t } = useTranslation('global')
const classes = menuRecipe({
extraPadding: true,
variant: variant,
@@ -39,11 +42,19 @@ export const MenuList = <T extends string | number = string>({
className={classes.item}
key={value}
id={value as string}
textValue={typeof label === 'string' ? label : undefined}
onAction={() => {
onAction(value as T)
}}
>
{label}
{({ isSelected }) => (
<>
{label}
{isSelected && (
<VisuallyHidden>, {t('selected')}</VisuallyHidden>
)}
</>
)}
</MenuItem>
)
})}

View File

@@ -1,5 +1,5 @@
import { type ReactNode } from 'react'
import { styled } from '@/styled-system/jsx'
import { styled, VisuallyHidden } from '@/styled-system/jsx'
import { RemixiconComponentType, RiArrowDropDownLine } from '@remixicon/react'
import {
Button,
@@ -9,6 +9,7 @@ import {
SelectProps as RACSelectProps,
SelectValue,
} from 'react-aria-components'
import { useTranslation } from 'react-i18next'
import { Box } from './Box'
import { StyledPopover } from './Popover'
import { menuRecipe } from '@/primitives/menuRecipe.ts'
@@ -110,6 +111,7 @@ export const Select = <T extends string | number>({
...props
}: SelectProps<T>) => {
const IconComponent = iconComponent
const { t } = useTranslation('global')
return (
<RACSelect {...props}>
{label}
@@ -138,8 +140,18 @@ export const Select = <T extends string | number>({
}
id={item.value}
key={item.value}
textValue={
typeof item.label === 'string' ? item.label : undefined
}
>
{item.label}
{({ isSelected }) => (
<>
{item.label}
{isSelected && (
<VisuallyHidden>, {t('selected')}</VisuallyHidden>
)}
</>
)}
</ListBoxItem>
))}
</ListBox>