Skip to content

Commit f40ca27

Browse files
committed
fixup! ♻️(frontend) use react aria toolbar for arrow key navigation
1 parent abc50f8 commit f40ca27

File tree

1 file changed

+32
-10
lines changed

1 file changed

+32
-10
lines changed

src/frontend/src/features/rooms/livekit/components/controls/ReactionsToggle.tsx

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { getEmojiLabel } from '@/features/rooms/livekit/utils/reactionUtils'
1414
import { useRegisterKeyboardShortcut } from '@/features/shortcuts/useRegisterKeyboardShortcut'
1515
import {
1616
Popover as RACPopover,
17-
Dialog,
1817
DialogTrigger,
1918
Toolbar,
2019
} from 'react-aria-components'
@@ -79,10 +78,34 @@ export const ReactionsToggle = () => {
7978
}, ANIMATION_DURATION)
8079
}
8180

82-
const closeOnTab = (e: React.KeyboardEvent) => {
81+
const handleToolbarKeyDown = (e: React.KeyboardEvent) => {
8382
if (e.key === 'Tab') {
8483
e.preventDefault()
85-
setIsOpen(false)
84+
document.getElementById('reaction-toggle')?.focus()
85+
return
86+
}
87+
88+
const buttons = Array.from(
89+
(e.currentTarget as HTMLElement).querySelectorAll<HTMLElement>(
90+
'[role="toolbar"] button'
91+
)
92+
)
93+
if (buttons.length === 0) return
94+
95+
if (
96+
e.key === 'ArrowRight' &&
97+
document.activeElement === buttons[buttons.length - 1]
98+
) {
99+
e.preventDefault()
100+
e.stopPropagation()
101+
buttons[0].focus()
102+
} else if (
103+
e.key === 'ArrowLeft' &&
104+
document.activeElement === buttons[0]
105+
) {
106+
e.preventDefault()
107+
e.stopPropagation()
108+
buttons[buttons.length - 1].focus()
86109
}
87110
}
88111

@@ -97,6 +120,7 @@ export const ReactionsToggle = () => {
97120
<div className={css({ position: 'relative' })}>
98121
<DialogTrigger isOpen={isOpen} onOpenChange={setIsOpen}>
99122
<ToggleButton
123+
id="reaction-toggle"
100124
square
101125
variant="primaryDark"
102126
aria-label={t('button')}
@@ -123,10 +147,9 @@ export const ReactionsToggle = () => {
123147
},
124148
})}
125149
>
126-
<Dialog className={css({ outline: 'none' })}>
127-
{/* eslint-disable-next-line jsx-a11y/no-autofocus -- FocusScope autoFocus is programmatic focus for overlays, not the HTML autofocus attribute */}
128-
<FocusScope autoFocus restoreFocus>
129-
<div onKeyDownCapture={closeOnTab}>
150+
{/* eslint-disable-next-line jsx-a11y/no-autofocus -- FocusScope autoFocus is programmatic focus for overlays, not the HTML autofocus attribute */}
151+
<FocusScope autoFocus restoreFocus>
152+
<div onKeyDownCapture={handleToolbarKeyDown}>
130153
<Toolbar
131154
orientation="horizontal"
132155
aria-label={t('button')}
@@ -158,9 +181,8 @@ export const ReactionsToggle = () => {
158181
</Button>
159182
))}
160183
</Toolbar>
161-
</div>
162-
</FocusScope>
163-
</Dialog>
184+
</div>
185+
</FocusScope>
164186
</RACPopover>
165187
</DialogTrigger>
166188
</div>

0 commit comments

Comments
 (0)