@@ -409,7 +409,7 @@ describe('Menu', () => {
409
409
expect ( triggerItem ) . toHaveAttribute ( 'data-open' , 'true' ) ;
410
410
let submenu = getAllByRole ( 'menu' ) [ 1 ] ;
411
411
expect ( submenu ) . toBeInTheDocument ( ) ;
412
-
412
+
413
413
let submenuPopover = submenu . closest ( '.react-aria-Popover' ) ;
414
414
expect ( submenuPopover ) . toBeInTheDocument ( ) ;
415
415
expect ( submenuPopover ) . toHaveAttribute ( 'data-trigger' , 'SubmenuTrigger' ) ;
@@ -482,7 +482,7 @@ describe('Menu', () => {
482
482
expect ( triggerItem ) . toHaveAttribute ( 'data-open' , 'true' ) ;
483
483
let submenu = getAllByRole ( 'menu' ) [ 1 ] ;
484
484
expect ( submenu ) . toBeInTheDocument ( ) ;
485
-
485
+
486
486
let submenuPopover = submenu . closest ( '.react-aria-Popover' ) ;
487
487
expect ( submenuPopover ) . toBeInTheDocument ( ) ;
488
488
expect ( submenuPopover ) . toHaveAttribute ( 'data-trigger' , 'SubmenuTrigger' ) ;
@@ -513,7 +513,7 @@ describe('Menu', () => {
513
513
expect ( nestedSubmenu ) . not . toBeInTheDocument ( ) ;
514
514
expect ( submenu ) . not . toBeInTheDocument ( ) ;
515
515
} ) ;
516
- it ( 'should close all submenus if underlay is clicked ' , async ( ) => {
516
+ it ( 'should close all submenus if interacting outside root submenu ' , async ( ) => {
517
517
let onAction = jest . fn ( ) ;
518
518
let { getByRole, getAllByRole, getByTestId} = render (
519
519
< MenuTrigger >
@@ -575,7 +575,7 @@ describe('Menu', () => {
575
575
expect ( triggerItem ) . toHaveAttribute ( 'data-open' , 'true' ) ;
576
576
let submenu = getAllByRole ( 'menu' ) [ 1 ] ;
577
577
expect ( submenu ) . toBeInTheDocument ( ) ;
578
-
578
+
579
579
let submenuPopover = submenu . closest ( '.react-aria-Popover' ) ;
580
580
expect ( submenuPopover ) . toBeInTheDocument ( ) ;
581
581
expect ( submenuPopover ) . toHaveAttribute ( 'data-trigger' , 'SubmenuTrigger' ) ;
@@ -603,7 +603,7 @@ describe('Menu', () => {
603
603
let underlay = getByTestId ( 'underlay' ) ;
604
604
expect ( underlay ) . toBeInTheDocument ( ) ;
605
605
expect ( underlay ) . toHaveAttribute ( 'aria-hidden' , 'true' ) ;
606
- await user . click ( underlay ) ;
606
+ await user . click ( document . body ) ;
607
607
expect ( nestedSubmenu ) . not . toBeInTheDocument ( ) ;
608
608
expect ( submenu ) . not . toBeInTheDocument ( ) ;
609
609
expect ( menu ) . not . toBeInTheDocument ( ) ;
@@ -662,7 +662,7 @@ describe('Menu', () => {
662
662
expect ( triggerItem ) . toHaveAttribute ( 'data-open' , 'true' ) ;
663
663
let submenu = getAllByRole ( 'menu' ) [ 1 ] ;
664
664
expect ( submenu ) . toBeInTheDocument ( ) ;
665
-
665
+
666
666
let submenuItems = within ( submenu ) . getAllByRole ( 'menuitem' ) ;
667
667
expect ( submenuItems ) . toHaveLength ( 3 ) ;
668
668
@@ -673,7 +673,7 @@ describe('Menu', () => {
673
673
fireEvent . keyDown ( document . activeElement , { key : 'Escape' } ) ;
674
674
fireEvent . keyUp ( document . activeElement , { key : 'Escape' } ) ;
675
675
act ( ( ) => { jest . runAllTimers ( ) ; } ) ;
676
-
676
+
677
677
expect ( submenu ) . not . toBeInTheDocument ( ) ;
678
678
expect ( menu ) . not . toBeInTheDocument ( ) ;
679
679
expect ( document . activeElement ) . toBe ( button ) ;
@@ -740,7 +740,7 @@ describe('Menu', () => {
740
740
expect ( triggerItem ) . toHaveAttribute ( 'data-open' , 'true' ) ;
741
741
let submenu = getAllByRole ( 'menu' ) [ 1 ] ;
742
742
expect ( submenu ) . toBeInTheDocument ( ) ;
743
-
743
+
744
744
let submenuItems = within ( submenu ) . getAllByRole ( 'menuitem' ) ;
745
745
expect ( submenuItems ) . toHaveLength ( 3 ) ;
746
746
@@ -760,11 +760,78 @@ describe('Menu', () => {
760
760
fireEvent . keyDown ( document . activeElement , { key : 'Escape' } ) ;
761
761
fireEvent . keyUp ( document . activeElement , { key : 'Escape' } ) ;
762
762
act ( ( ) => { jest . runAllTimers ( ) ; } ) ;
763
-
763
+
764
764
expect ( nestedSubmenu ) . not . toBeInTheDocument ( ) ;
765
765
expect ( submenu ) . not . toBeInTheDocument ( ) ;
766
766
expect ( menu ) . not . toBeInTheDocument ( ) ;
767
767
expect ( document . activeElement ) . toBe ( button ) ;
768
768
} ) ;
769
+ it ( 'should not close the menu when clicking on a element within the submenu tree' , async ( ) => {
770
+ let onAction = jest . fn ( ) ;
771
+ let { getByRole, getAllByRole, queryAllByRole} = render (
772
+ < MenuTrigger >
773
+ < Button aria-label = "Menu" > ☰</ Button >
774
+ < Popover >
775
+ < Menu onAction = { onAction } >
776
+ < MenuItem id = "open" > Open</ MenuItem >
777
+ < MenuItem id = "rename" > Rename…</ MenuItem >
778
+ < MenuItem id = "duplicate" > Duplicate</ MenuItem >
779
+ < SubmenuTrigger >
780
+ < MenuItem id = "share" > Share…</ MenuItem >
781
+ < Popover >
782
+ < Menu onAction = { onAction } >
783
+ < SubmenuTrigger >
784
+ < MenuItem id = "email" > Email…</ MenuItem >
785
+ < Popover >
786
+ < Menu onAction = { onAction } >
787
+ < MenuItem id = "work" > Work</ MenuItem >
788
+ < MenuItem id = "personal" > Personal</ MenuItem >
789
+ </ Menu >
790
+ </ Popover >
791
+ </ SubmenuTrigger >
792
+ < MenuItem id = "sms" > SMS</ MenuItem >
793
+ < MenuItem id = "twitter" > Twitter</ MenuItem >
794
+ </ Menu >
795
+ </ Popover >
796
+ </ SubmenuTrigger >
797
+ < MenuItem id = "delete" > Delete…</ MenuItem >
798
+ </ Menu >
799
+ </ Popover >
800
+ </ MenuTrigger >
801
+ ) ;
802
+
803
+ let button = getByRole ( 'button' ) ;
804
+ expect ( button ) . not . toHaveAttribute ( 'data-pressed' ) ;
805
+
806
+ await user . click ( button ) ;
807
+ expect ( button ) . toHaveAttribute ( 'data-pressed' ) ;
808
+
809
+ let menu = getAllByRole ( 'menu' ) [ 0 ] ;
810
+ expect ( getAllByRole ( 'menuitem' ) ) . toHaveLength ( 5 ) ;
811
+
812
+ let popover = menu . closest ( '.react-aria-Popover' ) ;
813
+ expect ( popover ) . toBeInTheDocument ( ) ;
814
+
815
+ let triggerItem = getAllByRole ( 'menuitem' ) [ 3 ] ;
816
+
817
+ // Open the submenu
818
+ await user . pointer ( { target : triggerItem } ) ;
819
+ act ( ( ) => { jest . runAllTimers ( ) ; } ) ;
820
+ let submenu = getAllByRole ( 'menu' ) [ 1 ] ;
821
+ expect ( submenu ) . toBeInTheDocument ( ) ;
822
+
823
+ let nestedTriggerItem = getAllByRole ( 'menuitem' ) [ 5 ] ;
824
+
825
+ // Click a nested submenu item trigger
826
+ await user . click ( nestedTriggerItem ) ;
827
+ act ( ( ) => { jest . runAllTimers ( ) ; } ) ;
828
+ let menus = getAllByRole ( 'menu' , { hidden : true } ) ;
829
+ expect ( menus ) . toHaveLength ( 3 ) ;
830
+
831
+ await user . click ( getAllByRole ( 'menuitem' ) [ 6 ] ) ;
832
+ menus = queryAllByRole ( 'menu' , { hidden : true } ) ;
833
+ expect ( menus ) . toHaveLength ( 0 ) ;
834
+ expect ( menu ) . not . toBeInTheDocument ( ) ;
835
+ } ) ;
769
836
} ) ;
770
837
} ) ;
0 commit comments