@@ -129,6 +129,71 @@ describe("Modal", () => {
129129 expect ( mockOnClose ) . toHaveBeenCalled ( ) ;
130130 } ) ;
131131
132+ it ( "traps focus inside the modal when opened" , ( ) => {
133+ const { getByLabelText } = render (
134+ < >
135+ < button type = "button" > Focusable outside</ button >
136+ < Modal id = { id } show closeButtonAriaLabel = { closeButtonAriaLabel } >
137+ { childrenContent }
138+ </ Modal >
139+ </ >
140+ ) ;
141+ const closeButton = getByLabelText ( closeButtonAriaLabel ) ;
142+ expect ( closeButton ) . toHaveFocus ( ) ;
143+
144+ userEvent . tab ( ) ;
145+ expect ( closeButton ) . toHaveFocus ( ) ;
146+ } ) ;
147+
148+ it ( "releases focus lock inside the modal when closed" , ( ) => {
149+ const { rerender, getByLabelText, getByText } = render (
150+ < >
151+ < button type = "button" > Focusable outside 1</ button >
152+ < button type = "button" > Focusable outside 2</ button >
153+ < Modal id = { id } show closeButtonAriaLabel = { closeButtonAriaLabel } >
154+ { childrenContent }
155+ </ Modal >
156+ </ >
157+ ) ;
158+ const closeButton = getByLabelText ( closeButtonAriaLabel ) ;
159+ expect ( closeButton ) . toHaveFocus ( ) ;
160+
161+ rerender (
162+ < >
163+ < button type = "button" > Focusable outside 1</ button >
164+ < button type = "button" > Focusable outside 2</ button >
165+ < Modal id = { id } show = { false } closeButtonAriaLabel = { closeButtonAriaLabel } >
166+ { childrenContent }
167+ </ Modal >
168+ </ >
169+ ) ;
170+
171+ userEvent . tab ( ) ;
172+ expect ( getByText ( "Focusable outside 1" ) ) . toHaveFocus ( ) ;
173+ userEvent . tab ( ) ;
174+ expect ( getByText ( "Focusable outside 2" ) ) . toHaveFocus ( ) ;
175+ } ) ;
176+
177+ it ( "traps and moves focus between modal elements" , ( ) => {
178+ const { getByLabelText, getByText } = render (
179+ < Modal id = { id } show closeButtonAriaLabel = { closeButtonAriaLabel } >
180+ < button type = "button" > Focusable 1</ button >
181+ < button type = "button" > Focusable 2</ button >
182+ </ Modal >
183+ ) ;
184+ const closeButton = getByLabelText ( closeButtonAriaLabel ) ;
185+ expect ( closeButton ) . toHaveFocus ( ) ;
186+
187+ userEvent . tab ( ) ;
188+ expect ( getByText ( "Focusable 1" ) ) . toHaveFocus ( ) ;
189+
190+ userEvent . tab ( ) ;
191+ expect ( getByText ( "Focusable 2" ) ) . toHaveFocus ( ) ;
192+
193+ userEvent . tab ( ) ;
194+ expect ( closeButton ) . toHaveFocus ( ) ;
195+ } ) ;
196+
132197 it . todo ( "renders the correct aria-labelledby" ) ;
133198
134199 it . todo ( "renders the correct aria-describedby" ) ;
0 commit comments