@@ -116,6 +116,95 @@ describe('BoundingBoxHighlightNav', () => {
116116 } ) ;
117117 } ) ;
118118
119+ describe ( 'keyboard navigation' , ( ) => {
120+ test ( 'should call onPrev when ArrowLeft is pressed' , ( ) => {
121+ const onPrev = jest . fn ( ) ;
122+ renderNav ( { currentIndex : 1 , onPrev } ) ;
123+
124+ fireEvent . keyDown ( document , { key : 'ArrowLeft' } ) ;
125+
126+ expect ( onPrev ) . toHaveBeenCalledTimes ( 1 ) ;
127+ } ) ;
128+
129+ test ( 'should call onNext when ArrowRight is pressed' , ( ) => {
130+ const onNext = jest . fn ( ) ;
131+ renderNav ( { currentIndex : 1 , onNext } ) ;
132+
133+ fireEvent . keyDown ( document , { key : 'ArrowRight' } ) ;
134+
135+ expect ( onNext ) . toHaveBeenCalledTimes ( 1 ) ;
136+ } ) ;
137+
138+ test ( 'should not call onPrev when ArrowLeft is pressed and at first item' , ( ) => {
139+ const onPrev = jest . fn ( ) ;
140+ renderNav ( { currentIndex : 0 , onPrev } ) ;
141+
142+ fireEvent . keyDown ( document , { key : 'ArrowLeft' } ) ;
143+
144+ expect ( onPrev ) . not . toHaveBeenCalled ( ) ;
145+ } ) ;
146+
147+ test ( 'should not call onNext when ArrowRight is pressed and at last item' , ( ) => {
148+ const onNext = jest . fn ( ) ;
149+ renderNav ( { currentIndex : 4 , total : 5 , onNext } ) ;
150+
151+ fireEvent . keyDown ( document , { key : 'ArrowRight' } ) ;
152+
153+ expect ( onNext ) . not . toHaveBeenCalled ( ) ;
154+ } ) ;
155+
156+ test ( 'should stop propagation for ArrowLeft even when prev is disabled' , ( ) => {
157+ renderNav ( { currentIndex : 0 } ) ;
158+ const event = new KeyboardEvent ( 'keydown' , { key : 'ArrowLeft' , bubbles : true } ) ;
159+ jest . spyOn ( event , 'stopPropagation' ) ;
160+
161+ document . dispatchEvent ( event ) ;
162+
163+ expect ( event . stopPropagation ) . toHaveBeenCalled ( ) ;
164+ } ) ;
165+
166+ test ( 'should stop propagation for ArrowRight even when next is disabled' , ( ) => {
167+ renderNav ( { currentIndex : 4 , total : 5 } ) ;
168+ const event = new KeyboardEvent ( 'keydown' , { key : 'ArrowRight' , bubbles : true } ) ;
169+ jest . spyOn ( event , 'stopPropagation' ) ;
170+
171+ document . dispatchEvent ( event ) ;
172+
173+ expect ( event . stopPropagation ) . toHaveBeenCalled ( ) ;
174+ } ) ;
175+
176+ test ( 'should not stop propagation for non-arrow keys' , ( ) => {
177+ renderNav ( { currentIndex : 1 } ) ;
178+ const event = new KeyboardEvent ( 'keydown' , { key : 'Enter' , bubbles : true } ) ;
179+ jest . spyOn ( event , 'stopPropagation' ) ;
180+
181+ document . dispatchEvent ( event ) ;
182+
183+ expect ( event . stopPropagation ) . not . toHaveBeenCalled ( ) ;
184+ } ) ;
185+
186+ test ( 'should not call callbacks for non-arrow keys' , ( ) => {
187+ const onPrev = jest . fn ( ) ;
188+ const onNext = jest . fn ( ) ;
189+ renderNav ( { currentIndex : 1 , onPrev, onNext } ) ;
190+
191+ fireEvent . keyDown ( document , { key : 'Enter' } ) ;
192+
193+ expect ( onPrev ) . not . toHaveBeenCalled ( ) ;
194+ expect ( onNext ) . not . toHaveBeenCalled ( ) ;
195+ } ) ;
196+
197+ test ( 'should remove keydown listener on unmount' , ( ) => {
198+ const onPrev = jest . fn ( ) ;
199+ const { unmount } = renderNav ( { currentIndex : 1 , onPrev } ) ;
200+
201+ unmount ( ) ;
202+ fireEvent . keyDown ( document , { key : 'ArrowLeft' } ) ;
203+
204+ expect ( onPrev ) . not . toHaveBeenCalled ( ) ;
205+ } ) ;
206+ } ) ;
207+
119208 describe ( 'accessibility' , ( ) => {
120209 test ( 'should have aria-label on prev button' , ( ) => {
121210 renderNav ( ) ;
0 commit comments