@@ -64,7 +64,28 @@ const ModalWithAdjacentModal = () => {
6464 ) ;
6565} ;
6666
67+ const MultipleOpenModals = ( ) => {
68+ const [ isFirstOpen , setIsFirstOpen ] = useState ( true ) ;
69+ const [ isSecondOpen , setIsSecondOpen ] = useState ( false ) ;
70+
71+ return (
72+ < >
73+ < aside > Aside sibling</ aside >
74+ < Modal isOpen = { isFirstOpen } appendTo = { target } onClose = { ( ) => setIsFirstOpen ( false ) } aria-label = "First modal" >
75+ < button onClick = { ( ) => setIsSecondOpen ( true ) } > Open second modal</ button >
76+ </ Modal >
77+ < Modal isOpen = { isSecondOpen } appendTo = { target } onClose = { ( ) => setIsSecondOpen ( false ) } aria-label = "Second modal" >
78+ Second modal content
79+ </ Modal >
80+ </ >
81+ ) ;
82+ } ;
83+
6784describe ( 'Modal' , ( ) => {
85+ beforeEach ( ( ) => {
86+ Modal . openModalStack = [ ] ;
87+ } ) ;
88+
6889 test ( 'Modal creates a container element once for div' , ( ) => {
6990 render ( < Modal { ...props } /> ) ;
7091 expect ( document . createElement ) . toHaveBeenCalledWith ( 'div' ) ;
@@ -181,4 +202,67 @@ describe('Modal', () => {
181202 'pf-v6-l-bullseye'
182203 ) ;
183204 } ) ;
205+
206+ test ( 'backdropOpen class remains when closing one of multiple open modals' , async ( ) => {
207+ const user = userEvent . setup ( ) ;
208+
209+ render ( < MultipleOpenModals /> , { container : document . body . appendChild ( target ) } ) ;
210+
211+ await user . click ( screen . getByRole ( 'button' , { name : 'Open second modal' } ) ) ;
212+
213+ expect ( target ) . toHaveClass ( css ( styles . backdropOpen ) ) ;
214+
215+ const closeButtons = screen . getAllByRole ( 'button' , { name : 'Close' , hidden : true } ) ;
216+ await user . click ( closeButtons [ closeButtons . length - 1 ] ) ;
217+
218+ expect ( target ) . toHaveClass ( css ( styles . backdropOpen ) ) ;
219+ } ) ;
220+
221+ test ( 'backdropOpen class is removed when all modals are closed' , async ( ) => {
222+ const user = userEvent . setup ( ) ;
223+
224+ render ( < MultipleOpenModals /> , { container : document . body . appendChild ( target ) } ) ;
225+
226+ await user . click ( screen . getByRole ( 'button' , { name : 'Open second modal' } ) ) ;
227+
228+ const closeButtons = screen . getAllByRole ( 'button' , { name : 'Close' , hidden : true } ) ;
229+ await user . click ( closeButtons [ closeButtons . length - 1 ] ) ;
230+ await user . click ( screen . getByRole ( 'button' , { name : 'Close' } ) ) ;
231+
232+ expect ( target ) . not . toHaveClass ( css ( styles . backdropOpen ) ) ;
233+ } ) ;
234+
235+ test ( 'only the most recent modal does not have aria-hidden when multiple modals are open' , async ( ) => {
236+ const user = userEvent . setup ( ) ;
237+
238+ render ( < MultipleOpenModals /> , { container : document . body . appendChild ( target ) } ) ;
239+
240+ const firstBackdrop = screen . getByLabelText ( 'First modal' ) . closest ( '[class*="backdrop"]' ) ;
241+
242+ await user . click ( screen . getByRole ( 'button' , { name : 'Open second modal' } ) ) ;
243+
244+ const secondBackdrop = screen . getByLabelText ( 'Second modal' ) . closest ( '[class*="backdrop"]' ) ;
245+
246+ expect ( firstBackdrop ) . toHaveAttribute ( 'aria-hidden' , 'true' ) ;
247+ expect ( secondBackdrop ) . not . toHaveAttribute ( 'aria-hidden' ) ;
248+ } ) ;
249+
250+ test ( 'closing the active modal reveals the previous modal' , async ( ) => {
251+ const user = userEvent . setup ( ) ;
252+
253+ render ( < MultipleOpenModals /> , { container : document . body . appendChild ( target ) } ) ;
254+
255+ await user . click ( screen . getByRole ( 'button' , { name : 'Open second modal' } ) ) ;
256+
257+ const firstBackdrop = screen
258+ . getByLabelText ( 'First modal' , { selector : '[role="dialog"]' } )
259+ . closest ( '[class*="backdrop"]' ) ;
260+
261+ expect ( firstBackdrop ) . toHaveAttribute ( 'aria-hidden' , 'true' ) ;
262+
263+ const closeButtons = screen . getAllByRole ( 'button' , { name : 'Close' , hidden : true } ) ;
264+ await user . click ( closeButtons [ closeButtons . length - 1 ] ) ;
265+
266+ expect ( firstBackdrop ) . not . toHaveAttribute ( 'aria-hidden' ) ;
267+ } ) ;
184268} ) ;
0 commit comments