Skip to content

Commit

Permalink
Add focus trap to Modals
Browse files Browse the repository at this point in the history
Fixes #2663
  • Loading branch information
davwheat committed Aug 12, 2021
1 parent cdf18c9 commit 33105cd
Showing 1 changed file with 19 additions and 0 deletions.
19 changes: 19 additions & 0 deletions js/src/common/components/ModalManager.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import Component from '../Component';
import { createFocusTrap } from '../utils/focusTrap';

/**
* The `ModalManager` component manages a modal dialog. Only one modal dialog
* can be shown at once; loading a new component into the ModalManager will
* overwrite the previous one.
*/
export default class ModalManager extends Component {
/**
* @type {import('../utils/focusTrap').FocusTrap | undefined}
*/
focusTrap;

view() {
const modal = this.attrs.state.modal;

Expand All @@ -23,13 +29,22 @@ export default class ModalManager extends Component {
);
}

/**
* @param {import('mithril').VnodeDOM<{}, this>} vnode
*/
oncreate(vnode) {
super.oncreate(vnode);

// Ensure the modal state is notified about a closed modal, even when the
// DOM-based Bootstrap JavaScript code triggered the closing of the modal,
// e.g. via ESC key or a click on the modal backdrop.
this.$().on('hidden.bs.modal', this.attrs.state.close.bind(this.attrs.state));

this.focusTrap = createFocusTrap(this.element);
}

onupdate(vnode) {
super.onupdate(vnode);
}

animateShow(readyCallback) {
Expand All @@ -50,9 +65,13 @@ export default class ModalManager extends Component {
keyboard: dismissible,
})
.modal('show');

if (this.focusTrap) this.focusTrap.activate();
}

animateHide() {
this.$().modal('hide');

if (this.focusTrap) this.focusTrap.deactivate();
}
}

0 comments on commit 33105cd

Please sign in to comment.