Skip to content

Commit cda4500

Browse files
authored
refactor: add focus trap to modal component (#12)
1 parent 3bf6705 commit cda4500

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

resources/assets/js/modal.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ import {
44
clearAllBodyScrollLocks,
55
} from "body-scroll-lock";
66

7+
import { createFocusTrap } from "focus-trap";
8+
79
const Modal = {
810
previousPaddingRight: undefined,
911
previousNavPaddingRight: undefined,
12+
trappedElement: null,
1013

1114
defaultSettings: {
1215
reserveScrollBarGap: true,
@@ -26,7 +29,7 @@ const Modal = {
2629
reserveScrollBarGap: !!settings.reserveScrollBarGap,
2730
});
2831

29-
scrollable.focus();
32+
this.trapFocus(scrollable);
3033
},
3134

3235
onModalClosed(scrollable, settings = Modal.defaultSettings) {
@@ -40,11 +43,32 @@ const Modal = {
4043

4144
enableBodyScroll(scrollable);
4245

46+
this.releaseTrappedFocus();
47+
4348
if (!document.querySelectorAll("[data-modal]").length) {
4449
clearAllBodyScrollLocks();
4550
}
4651
},
4752

53+
trapFocus(el) {
54+
let trap = createFocusTrap(el, {
55+
escapeDeactivates: false,
56+
allowOutsideClick: true,
57+
});
58+
59+
this.trappedElement = trap.activate();
60+
},
61+
62+
releaseTrappedFocus() {
63+
let trap = this.trappedElement;
64+
65+
if (trap) {
66+
trap.deactivate();
67+
}
68+
69+
this.trappedElement = null;
70+
},
71+
4872
alpine(
4973
extraData = {},
5074
modalName = "",

usage/ui.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,11 @@ window.initClipboard = () => {
9292

9393
### Modals
9494

95-
1. Install `body-scroll-lock`
95+
1. Install `body-scroll-lock` and `focus-trap`
9696

9797
```bash
9898
yarn add body-scroll-lock
99+
yarn add focus-trap
99100
```
100101

101102
2. Import the modal script in your `resources/js/app.js` file

0 commit comments

Comments
 (0)