@@ -21,6 +21,26 @@ beforeAll(() => {
21
21
getClientRects : {
22
22
get : ( ) => ( ) => [ 42 ] ,
23
23
} ,
24
+ offsetParent : {
25
+ get ( ) {
26
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
27
+ for ( let element = this ; element ; element = element . parentNode ) {
28
+ if ( element . style ?. display ?. toLowerCase ( ) === 'none' ) {
29
+ return null
30
+ }
31
+ }
32
+
33
+ if ( this . style ?. position ?. toLowerCase ( ) === 'fixed' ) {
34
+ return null
35
+ }
36
+
37
+ if ( this . tagName . toLowerCase ( ) in [ 'html' , 'body' ] ) {
38
+ return null
39
+ }
40
+
41
+ return this . parentNode
42
+ } ,
43
+ } ,
24
44
} )
25
45
} catch {
26
46
// ignore
@@ -569,3 +589,63 @@ it('Should handle elements being reordered', async () => {
569
589
570
590
controller . abort ( )
571
591
} )
592
+
593
+ it ( 'Should ignore hidden elements if strict' , async ( ) => {
594
+ const user = userEvent . setup ( )
595
+ const { container} = render (
596
+ < div id = "focusZone" >
597
+ < button > Apple</ button >
598
+ < button style = { { visibility : 'hidden' } } > Banana</ button >
599
+ < button style = { { display : 'none' } } > Watermelon</ button >
600
+ < div style = { { visibility : 'hidden' } } >
601
+ < div >
602
+ < button > Cherry</ button >
603
+ </ div >
604
+ </ div >
605
+ < div style = { { display : 'none' } } >
606
+ < div >
607
+ < button > Peach</ button >
608
+ </ div >
609
+ </ div >
610
+ < button tabIndex = { - 1 } > Cantaloupe</ button >
611
+ </ div > ,
612
+ )
613
+ const focusZoneContainer = container . querySelector < HTMLElement > ( '#focusZone' ) !
614
+ const allButtons = focusZoneContainer . querySelectorAll ( 'button' )
615
+ const firstButton = allButtons [ 0 ]
616
+ const lastButton = allButtons [ allButtons . length - 1 ]
617
+ const controller = focusZone ( focusZoneContainer , { strict : true } )
618
+
619
+ firstButton . focus ( )
620
+ expect ( document . activeElement ) . toEqual ( firstButton )
621
+
622
+ await user . keyboard ( '{arrowdown}' )
623
+ expect ( document . activeElement ) . toEqual ( lastButton )
624
+
625
+ controller . abort ( )
626
+ } )
627
+
628
+ it ( 'Shoud move to tabbable elements if onlyTabbable' , async ( ) => {
629
+ const user = userEvent . setup ( )
630
+ const { container} = render (
631
+ < div id = "focusZone" >
632
+ < button > Apple</ button >
633
+ < button tabIndex = { - 1 } > Cherry</ button >
634
+ < button tabIndex = { 0 } > Cantaloupe</ button >
635
+ </ div > ,
636
+ )
637
+
638
+ const focusZoneContainer = container . querySelector < HTMLElement > ( '#focusZone' ) !
639
+ const allButtons = focusZoneContainer . querySelectorAll ( 'button' )
640
+ const firstButton = allButtons [ 0 ]
641
+ const lastButton = allButtons [ allButtons . length - 1 ]
642
+ const controller = focusZone ( focusZoneContainer , { onlyTabbable : true } )
643
+
644
+ firstButton . focus ( )
645
+ expect ( document . activeElement ) . toEqual ( firstButton )
646
+
647
+ await user . keyboard ( '{arrowdown}' )
648
+ expect ( document . activeElement ) . toEqual ( lastButton )
649
+
650
+ controller . abort ( )
651
+ } )
0 commit comments