@@ -14,7 +14,6 @@ import { getEmojiLabel } from '@/features/rooms/livekit/utils/reactionUtils'
1414import { useRegisterKeyboardShortcut } from '@/features/shortcuts/useRegisterKeyboardShortcut'
1515import {
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