Skip to content

Commit a802ef2

Browse files
Gregor WoiwodeGregOnNet
authored andcommitted
fix(modal): deactivate focus-trap before close
1 parent d969c3d commit a802ef2

File tree

2 files changed

+26
-29
lines changed

2 files changed

+26
-29
lines changed

packages/kit-headless/src/components/modal/modal-portal.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,23 @@ export const ModalPortal = component$(
3333
}
3434
});
3535

36-
useVisibleTask$(function setupFocusTrap({ track, cleanup }) {
36+
useVisibleTask$(function toggleFocusTrap({ track, cleanup }) {
3737
const isOpen = track(() => modalContext.showSig.value);
3838
const modal = refSig.value;
39-
let focusTrap: FocusTrap | null = null;
4039

4140
if (!modal) return;
4241

42+
let focusTrap: FocusTrap | null = createFocusTrap(modal, {
43+
escapeDeactivates: false,
44+
});
45+
4346
if (isOpen) {
44-
focusTrap = createFocusTrap(modal, { escapeDeactivates: false });
4547
focusTrap.activate();
48+
} else {
49+
focusTrap.deactivate();
4650
}
4751

4852
cleanup(() => {
49-
focusTrap?.deactivate();
5053
focusTrap = null;
5154
});
5255
});

packages/kit-headless/src/components/modal/modal.spec.tsx

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,51 @@
1-
import { component$, useSignal } from '@builder.io/qwik';
1+
import { component$ } from '@builder.io/qwik';
22
import { mount } from 'cypress-ct-qwik';
3+
import { Modal } from './modal';
4+
import { ModalClose } from './modal-close';
35
import { ModalContent } from './modal-content';
46
import { ModalFooter } from './modal-footer';
57
import { ModalHeader } from './modal-header';
6-
import { ModalRoot } from './modal';
8+
import { ModalPortal } from './modal-portal';
9+
import { ModalTrigger } from './modal-trigger';
710

811
/**
912
* SUT - System under test
1013
* Reference: https://en.wikipedia.org/wiki/System_under_test
1114
*/
1215
const Sut = component$(() => {
13-
const openSig = useSignal(false);
1416
return (
15-
<>
16-
<button onClick$={() => (openSig.value = true)}>Open Dialog</button>
17-
18-
<ModalRoot show={openSig}>
17+
<Modal>
18+
<ModalTrigger>
19+
<button data-test="modal-trigger">Open Modal</button>
20+
</ModalTrigger>
21+
<ModalPortal>
1922
<ModalHeader>
20-
<h2>Hello 👋</h2>
23+
<h2 data-test="modal-header">Hello 👋</h2>
2124
</ModalHeader>
2225
<ModalContent>I am a simple Modal</ModalContent>
2326
<ModalFooter>
24-
<button
25-
data-test="dialog-close-button"
26-
onClick$={() => (openSig.value = false)}
27-
>
28-
Close Dialog
29-
</button>
27+
<ModalClose>
28+
<button data-test="modal-close-button">Close Modal</button>
29+
</ModalClose>
3030
</ModalFooter>
31-
</ModalRoot>
32-
</>
31+
</ModalPortal>
32+
</Modal>
3333
);
3434
});
3535

3636
describe('Modal', () => {
3737
it('renders an opened Modal', () => {
3838
mount(<Sut />);
3939

40-
cy.get('button')
41-
.contains(/Open Modal/i)
42-
.click();
40+
cy.get('[data-test=modal-trigger]').click();
4341

4442
cy.get('[data-test=modal-header]').should('be.visible').should('contain', 'Hello 👋');
4543
});
4644

4745
it('closes on button-click', () => {
4846
mount(<Sut />);
4947

50-
cy.get('button')
51-
.contains(/Open Modal/i)
52-
.click();
48+
cy.get('[data-test=modal-trigger]').click();
5349

5450
cy.get('[data-test=modal-close-button]').click();
5551

@@ -59,9 +55,7 @@ describe('Modal', () => {
5955
it('closes on backdrop-click', () => {
6056
mount(<Sut />);
6157

62-
cy.get('button')
63-
.contains(/Open Modal/i)
64-
.click();
58+
cy.get('[data-test=modal-trigger]').click();
6559

6660
cy.get('body').click('top');
6761

0 commit comments

Comments
 (0)