UNPKG

3.31 kBJavaScriptView Raw
1'use strict';
2
3exports.__esModule = true;
4
5var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
6
7var _ariaUtils = require('./aria-utils');
8
9var _ariaUtils2 = _interopRequireDefault(_ariaUtils);
10
11function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
13/**
14 * @constructor
15 * @desc Dialog object providing modal focus management.
16 *
17 * Assumptions: The element serving as the dialog container is present in the
18 * DOM and hidden. The dialog container has role='dialog'.
19 *
20 * @param dialogId
21 * The ID of the element serving as the dialog container.
22 * @param focusAfterClosed
23 * Either the DOM node or the ID of the DOM node to focus when the
24 * dialog closes.
25 * @param focusFirst
26 * Optional parameter containing either the DOM node or the ID of the
27 * DOM node to focus when the dialog opens. If not specified, the
28 * first focusable element in the dialog will receive focus.
29 */
30var aria = aria || {};
31var tabEvent;
32
33aria.Dialog = function (dialog, focusAfterClosed, focusFirst) {
34 var _this = this;
35
36 this.dialogNode = dialog;
37 if (this.dialogNode === null || this.dialogNode.getAttribute('role') !== 'dialog') {
38 throw new Error('Dialog() requires a DOM element with ARIA role of dialog.');
39 }
40
41 if (typeof focusAfterClosed === 'string') {
42 this.focusAfterClosed = document.getElementById(focusAfterClosed);
43 } else if ((typeof focusAfterClosed === 'undefined' ? 'undefined' : _typeof(focusAfterClosed)) === 'object') {
44 this.focusAfterClosed = focusAfterClosed;
45 } else {
46 this.focusAfterClosed = null;
47 }
48
49 if (typeof focusFirst === 'string') {
50 this.focusFirst = document.getElementById(focusFirst);
51 } else if ((typeof focusFirst === 'undefined' ? 'undefined' : _typeof(focusFirst)) === 'object') {
52 this.focusFirst = focusFirst;
53 } else {
54 this.focusFirst = null;
55 }
56
57 if (this.focusFirst) {
58 this.focusFirst.focus();
59 } else {
60 _ariaUtils2.default.focusFirstDescendant(this.dialogNode);
61 }
62
63 this.lastFocus = document.activeElement;
64 tabEvent = function tabEvent(e) {
65 _this.trapFocus(e);
66 };
67 this.addListeners();
68};
69
70aria.Dialog.prototype.addListeners = function () {
71 document.addEventListener('focus', tabEvent, true);
72};
73
74aria.Dialog.prototype.removeListeners = function () {
75 document.removeEventListener('focus', tabEvent, true);
76};
77
78aria.Dialog.prototype.closeDialog = function () {
79 var _this2 = this;
80
81 this.removeListeners();
82 if (this.focusAfterClosed) {
83 setTimeout(function () {
84 _this2.focusAfterClosed.focus();
85 });
86 }
87};
88
89aria.Dialog.prototype.trapFocus = function (event) {
90 if (_ariaUtils2.default.IgnoreUtilFocusChanges) {
91 return;
92 }
93 if (this.dialogNode.contains(event.target)) {
94 this.lastFocus = event.target;
95 } else {
96 _ariaUtils2.default.focusFirstDescendant(this.dialogNode);
97 if (this.lastFocus === document.activeElement) {
98 _ariaUtils2.default.focusLastDescendant(this.dialogNode);
99 }
100 this.lastFocus = document.activeElement;
101 }
102};
103
104exports.default = aria.Dialog;
\No newline at end of file