mirror of
https://github.com/suitenumerique/meet.git
synced 2026-07-27 12:19:10 +00:00
♿️(frontend) improve accessibility and navigation for reaction toolbar
Refine keyboard behavior so left and right arrow keys no longer control toolbar navigation, allowing users to directly tab into individual reaction buttons for faster and more intuitive access. Remove the reaction toolbar from accessibility tree to avoid unnecessary focus and announcements, keeping assistive technology focused on the actual reaction controls. This ensures the UX centers on reaction actions rather than auxiliary navigation elements. Also, not related to this topic, I've reworked the scroll viewport styles.
This commit is contained in:
committed by
aleb_the_flash
parent
318447f2b3
commit
eb74feaa0d
+48
-34
@@ -8,10 +8,11 @@ import {
|
||||
import { styled } from '@/styled-system/jsx'
|
||||
import { useReactionsToolbar } from '../../hooks/useReactionsToolbar'
|
||||
import { useIsMobile } from '@/utils/useIsMobile'
|
||||
import { css } from '@/styled-system/css'
|
||||
import { useSize } from '@/features/rooms/livekit/hooks/useResizeObserver'
|
||||
import { RiArrowLeftSLine, RiArrowRightSLine } from '@remixicon/react'
|
||||
import { Button } from '@/primitives'
|
||||
import { ReactionsKeyboardNavigation } from './ReactionsKeyboardNavigation'
|
||||
import { FocusScope } from '@react-aria/focus'
|
||||
|
||||
import { CONTROL_BAR_REGION_ID } from '@/features/layout/components/ControlBarRegion'
|
||||
import { REACTIONS_TOGGLE_ID } from '../ReactionsToggle'
|
||||
@@ -42,18 +43,20 @@ const StyledContainer = styled('div', {
|
||||
},
|
||||
})
|
||||
|
||||
const scrollViewport = css({
|
||||
display: 'flex',
|
||||
gap: '0.2rem',
|
||||
overflowX: 'auto',
|
||||
padding: '0.19rem',
|
||||
scrollBehavior: 'smooth',
|
||||
minWidth: 0,
|
||||
flex: '1 1 auto',
|
||||
scrollbarWidth: 'none',
|
||||
'&::-webkit-scrollbar': { display: 'none' },
|
||||
'& > *': {
|
||||
flexShrink: 0,
|
||||
const StyledScrollViewport = styled('div', {
|
||||
base: {
|
||||
display: 'flex',
|
||||
gap: '0.2rem',
|
||||
overflowX: 'auto',
|
||||
padding: '0.19rem',
|
||||
scrollBehavior: 'smooth',
|
||||
minWidth: 0,
|
||||
flex: '1 1 auto',
|
||||
scrollbarWidth: 'none',
|
||||
'&::-webkit-scrollbar': { display: 'none' },
|
||||
'& > *': {
|
||||
flexShrink: 0,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -182,29 +185,40 @@ export const ReactionButtonsContainer = ({
|
||||
}
|
||||
>
|
||||
{overflowing && (
|
||||
<Button
|
||||
onPress={() => scrollBy(-SCROLL_AMOUNT)}
|
||||
variant="primaryTextDark"
|
||||
size="sm"
|
||||
isDisabled={atStart}
|
||||
round
|
||||
>
|
||||
<RiArrowLeftSLine />
|
||||
</Button>
|
||||
<div aria-hidden="true">
|
||||
<Button
|
||||
onPress={() => scrollBy(-SCROLL_AMOUNT)}
|
||||
variant="primaryTextDark"
|
||||
size="sm"
|
||||
isDisabled={atStart}
|
||||
round
|
||||
excludeFromTabOrder
|
||||
>
|
||||
<RiArrowLeftSLine />
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
<div ref={scrollRef} className={scrollViewport} onScroll={updateArrows}>
|
||||
{children}
|
||||
</div>
|
||||
{/* eslint-disable-next-line jsx-a11y/no-autofocus*/}
|
||||
<FocusScope autoFocus>
|
||||
<ReactionsKeyboardNavigation>
|
||||
<StyledScrollViewport ref={scrollRef} onScroll={updateArrows}>
|
||||
{children}
|
||||
</StyledScrollViewport>
|
||||
</ReactionsKeyboardNavigation>
|
||||
</FocusScope>
|
||||
{overflowing && (
|
||||
<Button
|
||||
onPress={() => scrollBy(SCROLL_AMOUNT)}
|
||||
variant="primaryTextDark"
|
||||
size="sm"
|
||||
isDisabled={atEnd}
|
||||
round
|
||||
>
|
||||
<RiArrowRightSLine />
|
||||
</Button>
|
||||
<div aria-hidden="true">
|
||||
<Button
|
||||
onPress={() => scrollBy(SCROLL_AMOUNT)}
|
||||
variant="primaryTextDark"
|
||||
size="sm"
|
||||
isDisabled={atEnd}
|
||||
round
|
||||
excludeFromTabOrder
|
||||
>
|
||||
<RiArrowRightSLine />
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</StyledContainer>
|
||||
)
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { FocusScope } from '@react-aria/focus'
|
||||
import { useReactionsToolbar } from '../../hooks/useReactionsToolbar'
|
||||
import { ReactionButton } from './ReactionButton'
|
||||
import { Emoji } from '../../types'
|
||||
import { styled } from '@/styled-system/jsx'
|
||||
import { useDelayUnmount } from '@/hooks/useDelayUnmount'
|
||||
import { ReactionsKeyboardNavigation } from './ReactionsKeyboardNavigation'
|
||||
import { ReactionButtonsContainer } from './ReactionButtonsContainer'
|
||||
|
||||
const Container = styled('div', {
|
||||
@@ -27,16 +25,11 @@ export const ReactionsToolbar = () => {
|
||||
|
||||
return (
|
||||
<Container>
|
||||
{/* eslint-disable-next-line jsx-a11y/no-autofocus*/}
|
||||
<FocusScope autoFocus>
|
||||
<ReactionsKeyboardNavigation>
|
||||
<ReactionButtonsContainer>
|
||||
{Object.values(Emoji).map((emoji) => (
|
||||
<ReactionButton key={emoji} emoji={emoji} />
|
||||
))}
|
||||
</ReactionButtonsContainer>
|
||||
</ReactionsKeyboardNavigation>
|
||||
</FocusScope>
|
||||
<ReactionButtonsContainer>
|
||||
{Object.values(Emoji).map((emoji) => (
|
||||
<ReactionButton key={emoji} emoji={emoji} />
|
||||
))}
|
||||
</ReactionButtonsContainer>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user