@instructure/ui-a11y-utils 8.33.2-snapshot-0 → 8.33.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -5
- package/es/FocusRegion.js +6 -40
- package/es/FocusRegionManager.js +10 -33
- package/es/KeyboardFocusRegion.js +4 -53
- package/es/ScreenReaderFocusRegion.js +1 -36
- package/es/hasVisibleChildren.js +1 -2
- package/es/index.js +1 -0
- package/es/scopeTab.js +8 -12
- package/lib/FocusRegion.js +6 -50
- package/lib/FocusRegionManager.js +10 -38
- package/lib/KeyboardFocusRegion.js +4 -66
- package/lib/ScreenReaderFocusRegion.js +1 -37
- package/lib/hasVisibleChildren.js +1 -8
- package/lib/index.js +0 -6
- package/lib/scopeTab.js +8 -17
- package/package.json +10 -10
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -1,36 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
-
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
7
|
exports.default = exports.KeyboardFocusRegion = void 0;
|
|
9
|
-
|
|
10
8
|
var _findDOMNode = require("@instructure/ui-dom-utils/lib/findDOMNode.js");
|
|
11
|
-
|
|
12
9
|
var _findTabbable = require("@instructure/ui-dom-utils/lib/findTabbable.js");
|
|
13
|
-
|
|
14
10
|
var _findFocusable = require("@instructure/ui-dom-utils/lib/findFocusable.js");
|
|
15
|
-
|
|
16
11
|
var _ownerWindow = require("@instructure/ui-dom-utils/lib/ownerWindow.js");
|
|
17
|
-
|
|
18
12
|
var _getActiveElement = require("@instructure/ui-dom-utils/lib/getActiveElement.js");
|
|
19
|
-
|
|
20
13
|
var _addEventListener = require("@instructure/ui-dom-utils/lib/addEventListener.js");
|
|
21
|
-
|
|
22
14
|
var _ownerDocument = require("@instructure/ui-dom-utils/lib/ownerDocument.js");
|
|
23
|
-
|
|
24
15
|
var _containsActiveElement = require("@instructure/ui-dom-utils/lib/containsActiveElement.js");
|
|
25
|
-
|
|
26
16
|
var _requestAnimationFrame = require("@instructure/ui-dom-utils/lib/requestAnimationFrame.js");
|
|
27
|
-
|
|
28
17
|
var _console = require("@instructure/console");
|
|
29
|
-
|
|
30
18
|
var _keycode = _interopRequireDefault(require("keycode"));
|
|
31
|
-
|
|
32
19
|
var _scopeTab = require("./scopeTab");
|
|
33
|
-
|
|
34
20
|
/*
|
|
35
21
|
* The MIT License (MIT)
|
|
36
22
|
*
|
|
@@ -54,6 +40,7 @@ var _scopeTab = require("./scopeTab");
|
|
|
54
40
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
55
41
|
* SOFTWARE.
|
|
56
42
|
*/
|
|
43
|
+
|
|
57
44
|
class KeyboardFocusRegion {
|
|
58
45
|
constructor(element, options) {
|
|
59
46
|
this._options = void 0;
|
|
@@ -64,141 +51,110 @@ class KeyboardFocusRegion {
|
|
|
64
51
|
this._active = false;
|
|
65
52
|
this._wasDocumentClick = void 0;
|
|
66
53
|
this._contextElement = void 0;
|
|
67
|
-
|
|
68
54
|
this.handleKeyDown = event => {
|
|
69
55
|
if (event.keyCode === _keycode.default.codes.tab) {
|
|
70
56
|
(0, _scopeTab.scopeTab)(this._contextElement, event);
|
|
71
57
|
}
|
|
72
58
|
};
|
|
73
|
-
|
|
74
59
|
this.handleClick = () => {
|
|
75
60
|
this._wasDocumentClick = true;
|
|
76
61
|
};
|
|
77
|
-
|
|
78
62
|
this.handleWindowBlur = () => {
|
|
79
63
|
if (this._wasDocumentClick) {
|
|
80
64
|
this._wasDocumentClick = false;
|
|
81
65
|
return;
|
|
82
66
|
}
|
|
83
|
-
|
|
84
67
|
this._needToFocus = true;
|
|
85
68
|
};
|
|
86
|
-
|
|
87
69
|
this.handleFocus = () => {
|
|
88
70
|
if (this._needToFocus) {
|
|
89
71
|
this._needToFocus = false;
|
|
90
|
-
|
|
91
72
|
if (!this._contextElement) {
|
|
92
73
|
return;
|
|
93
|
-
}
|
|
74
|
+
}
|
|
75
|
+
// need to see how jQuery shims document.on('focusin') so we don't need the
|
|
94
76
|
// setTimeout, firefox doesn't support focusin, if it did, we could focus
|
|
95
77
|
// the element outside of a setTimeout. Side-effect of this implementation
|
|
96
78
|
// is that the document.body gets focus, and then we focus our element right
|
|
97
79
|
// after, seems fine.
|
|
98
|
-
|
|
99
|
-
|
|
100
80
|
this._raf.push((0, _requestAnimationFrame.requestAnimationFrame)(() => {
|
|
101
81
|
if ((0, _containsActiveElement.containsActiveElement)(this._contextElement)) {
|
|
102
82
|
return;
|
|
103
83
|
}
|
|
104
|
-
|
|
105
84
|
this.focusDefaultElement();
|
|
106
85
|
}));
|
|
107
86
|
}
|
|
108
87
|
};
|
|
109
|
-
|
|
110
88
|
this.handleFirstTabbableKeyDown = event => {
|
|
111
89
|
if (event.keyCode === _keycode.default.codes.tab && event.shiftKey) {
|
|
112
90
|
var _this$_options$onBlur, _this$_options;
|
|
113
|
-
|
|
114
91
|
(_this$_options$onBlur = (_this$_options = this._options).onBlur) === null || _this$_options$onBlur === void 0 ? void 0 : _this$_options$onBlur.call(_this$_options, event);
|
|
115
92
|
}
|
|
116
93
|
};
|
|
117
|
-
|
|
118
94
|
this.handleLastTabbableKeyDown = event => {
|
|
119
95
|
if (event.keyCode === _keycode.default.codes.tab && !event.shiftKey) {
|
|
120
96
|
var _this$_options$onBlur2, _this$_options2;
|
|
121
|
-
|
|
122
97
|
(_this$_options$onBlur2 = (_this$_options2 = this._options).onBlur) === null || _this$_options$onBlur2 === void 0 ? void 0 : _this$_options$onBlur2.call(_this$_options2, event);
|
|
123
98
|
}
|
|
124
99
|
};
|
|
125
|
-
|
|
126
100
|
this._contextElement = (0, _findDOMNode.findDOMNode)(element);
|
|
127
101
|
this._options = options || {
|
|
128
102
|
shouldContainFocus: true,
|
|
129
103
|
shouldReturnFocus: true,
|
|
130
104
|
defaultFocusElement: null
|
|
131
105
|
};
|
|
132
|
-
|
|
133
106
|
if (this._options.shouldReturnFocus) {
|
|
134
107
|
this._focusLaterElement = (0, _getActiveElement.getActiveElement)(this.doc);
|
|
135
108
|
}
|
|
136
109
|
}
|
|
137
|
-
|
|
138
110
|
get focused() {
|
|
139
111
|
return (0, _containsActiveElement.containsActiveElement)(this._contextElement);
|
|
140
112
|
}
|
|
141
|
-
|
|
142
113
|
get shouldContainFocus() {
|
|
143
114
|
const shouldContainFocus = this._options.shouldContainFocus;
|
|
144
115
|
return shouldContainFocus === true || Array.isArray(shouldContainFocus) && shouldContainFocus.includes('keyboard');
|
|
145
116
|
}
|
|
146
|
-
|
|
147
117
|
get focusable() {
|
|
148
118
|
return (0, _findFocusable.findFocusable)(this._contextElement, () => true, true) || [];
|
|
149
119
|
}
|
|
150
|
-
|
|
151
120
|
get tabbable() {
|
|
152
121
|
return (0, _findTabbable.findTabbable)(this._contextElement) || [];
|
|
153
122
|
}
|
|
154
|
-
|
|
155
123
|
get firstTabbable() {
|
|
156
124
|
return this.tabbable[0];
|
|
157
125
|
}
|
|
158
|
-
|
|
159
126
|
get lastTabbable() {
|
|
160
127
|
return this.tabbable.pop();
|
|
161
128
|
}
|
|
162
|
-
|
|
163
129
|
get firstFocusable() {
|
|
164
130
|
return this.focusable[0];
|
|
165
131
|
}
|
|
166
|
-
|
|
167
132
|
get lastFocusable() {
|
|
168
133
|
return this.focusable.pop();
|
|
169
134
|
}
|
|
170
|
-
|
|
171
135
|
get doc() {
|
|
172
136
|
return (0, _ownerDocument.ownerDocument)(this._contextElement);
|
|
173
137
|
}
|
|
174
|
-
|
|
175
138
|
get win() {
|
|
176
139
|
return (0, _ownerWindow.ownerWindow)(this._contextElement);
|
|
177
140
|
}
|
|
178
|
-
|
|
179
141
|
get defaultFocusElement() {
|
|
180
142
|
const defaultFocusElement = this._options.defaultFocusElement;
|
|
181
143
|
const element = (0, _findDOMNode.findDOMNode)(typeof defaultFocusElement === 'function' ? defaultFocusElement() : defaultFocusElement);
|
|
182
|
-
|
|
183
144
|
if (element && this._contextElement && this._contextElement.contains(element)) {
|
|
184
145
|
return element;
|
|
185
146
|
}
|
|
186
|
-
|
|
187
147
|
if (this.firstTabbable) {
|
|
188
148
|
return this.firstTabbable;
|
|
189
149
|
}
|
|
190
|
-
|
|
191
150
|
if (this._contextElement && this.focusable.includes(this._contextElement)) {
|
|
192
151
|
return this._contextElement;
|
|
193
152
|
}
|
|
194
|
-
|
|
195
153
|
return null;
|
|
196
154
|
}
|
|
197
|
-
|
|
198
155
|
updateElement(element) {
|
|
199
156
|
this._contextElement = (0, _findDOMNode.findDOMNode)(element);
|
|
200
157
|
}
|
|
201
|
-
|
|
202
158
|
focusDefaultElement() {
|
|
203
159
|
if (this.defaultFocusElement) {
|
|
204
160
|
;
|
|
@@ -214,22 +170,18 @@ class KeyboardFocusRegion {
|
|
|
214
170
|
}
|
|
215
171
|
}
|
|
216
172
|
}
|
|
217
|
-
|
|
218
173
|
focus() {
|
|
219
174
|
if (this.focused) {
|
|
220
175
|
return;
|
|
221
176
|
}
|
|
222
|
-
|
|
223
177
|
this._raf.push((0, _requestAnimationFrame.requestAnimationFrame)(() => {
|
|
224
178
|
this.focusDefaultElement();
|
|
225
179
|
}));
|
|
226
180
|
}
|
|
227
|
-
|
|
228
181
|
blur() {
|
|
229
182
|
if (this._options.shouldReturnFocus && this._focusLaterElement) {
|
|
230
183
|
try {
|
|
231
184
|
;
|
|
232
|
-
|
|
233
185
|
this._focusLaterElement.focus();
|
|
234
186
|
} catch (e) {
|
|
235
187
|
(0, _console.logError)(false, `
|
|
@@ -237,53 +189,39 @@ class KeyboardFocusRegion {
|
|
|
237
189
|
but it is not in the DOM anymore: ${e}
|
|
238
190
|
`);
|
|
239
191
|
}
|
|
240
|
-
|
|
241
192
|
this._focusLaterElement = null;
|
|
242
193
|
}
|
|
243
194
|
}
|
|
244
|
-
|
|
245
195
|
activate() {
|
|
246
196
|
const defaultFocusElement = this.defaultFocusElement,
|
|
247
|
-
|
|
248
|
-
|
|
197
|
+
shouldContainFocus = this.shouldContainFocus;
|
|
249
198
|
if (!this._active) {
|
|
250
199
|
if (defaultFocusElement || shouldContainFocus) {
|
|
251
200
|
if (shouldContainFocus) {
|
|
252
201
|
this._listeners.push((0, _addEventListener.addEventListener)(this.doc, 'keydown', this.handleKeyDown));
|
|
253
202
|
} else {
|
|
254
203
|
this._listeners.push((0, _addEventListener.addEventListener)(this.firstTabbable || defaultFocusElement, 'keydown', this.handleFirstTabbableKeyDown));
|
|
255
|
-
|
|
256
204
|
this._listeners.push((0, _addEventListener.addEventListener)(this.lastTabbable || defaultFocusElement, 'keydown', this.handleLastTabbableKeyDown));
|
|
257
205
|
}
|
|
258
|
-
|
|
259
206
|
this._listeners.push((0, _addEventListener.addEventListener)(this.doc, 'click', this.handleClick, true));
|
|
260
|
-
|
|
261
207
|
this._listeners.push((0, _addEventListener.addEventListener)(this.win, 'blur', this.handleWindowBlur, false));
|
|
262
|
-
|
|
263
208
|
this._listeners.push((0, _addEventListener.addEventListener)(this.doc, 'focus', this.handleFocus, true));
|
|
264
|
-
|
|
265
209
|
this._active = true;
|
|
266
210
|
}
|
|
267
211
|
}
|
|
268
212
|
}
|
|
269
|
-
|
|
270
213
|
deactivate() {
|
|
271
214
|
if (this._active) {
|
|
272
215
|
this._listeners.forEach(listener => {
|
|
273
216
|
listener.remove();
|
|
274
217
|
});
|
|
275
|
-
|
|
276
218
|
this._listeners = [];
|
|
277
|
-
|
|
278
219
|
this._raf.forEach(request => request.cancel());
|
|
279
|
-
|
|
280
220
|
this._raf = [];
|
|
281
221
|
this._active = false;
|
|
282
222
|
}
|
|
283
223
|
}
|
|
284
|
-
|
|
285
224
|
}
|
|
286
|
-
|
|
287
225
|
exports.KeyboardFocusRegion = KeyboardFocusRegion;
|
|
288
226
|
var _default = KeyboardFocusRegion;
|
|
289
227
|
exports.default = _default;
|
|
@@ -4,9 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = exports.ScreenReaderFocusRegion = void 0;
|
|
7
|
-
|
|
8
7
|
var _console = require("@instructure/console");
|
|
9
|
-
|
|
10
8
|
/*
|
|
11
9
|
* The MIT License (MIT)
|
|
12
10
|
*
|
|
@@ -30,6 +28,7 @@ var _console = require("@instructure/console");
|
|
|
30
28
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
31
29
|
* SOFTWARE.
|
|
32
30
|
*/
|
|
31
|
+
|
|
33
32
|
class ScreenReaderFocusRegion {
|
|
34
33
|
constructor(element) {
|
|
35
34
|
let options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {
|
|
@@ -43,7 +42,6 @@ class ScreenReaderFocusRegion {
|
|
|
43
42
|
this._options = void 0;
|
|
44
43
|
this._observer = null;
|
|
45
44
|
this._attributes = [];
|
|
46
|
-
|
|
47
45
|
this.handleDOMMutation = records => {
|
|
48
46
|
records.forEach(record => {
|
|
49
47
|
const addedNodes = Array.from(record.addedNodes);
|
|
@@ -55,7 +53,6 @@ class ScreenReaderFocusRegion {
|
|
|
55
53
|
if (removedNode.tagName.toLowerCase() !== 'iframe') {
|
|
56
54
|
this.restoreNode(removedNode);
|
|
57
55
|
}
|
|
58
|
-
|
|
59
56
|
const iframeBodies = this.parseIframeBodies(removedNode);
|
|
60
57
|
iframeBodies.forEach(iframeBody => {
|
|
61
58
|
this.restoreNode(iframeBody);
|
|
@@ -63,17 +60,14 @@ class ScreenReaderFocusRegion {
|
|
|
63
60
|
});
|
|
64
61
|
});
|
|
65
62
|
};
|
|
66
|
-
|
|
67
63
|
const liveRegion = typeof options.liveRegion === 'function' ? options.liveRegion() : options.liveRegion;
|
|
68
64
|
this._liveRegion = Array.isArray(liveRegion) ? liveRegion : [liveRegion];
|
|
69
65
|
this._contextElement = element;
|
|
70
66
|
this._options = options;
|
|
71
67
|
}
|
|
72
|
-
|
|
73
68
|
updateElement(element) {
|
|
74
69
|
this._contextElement = element;
|
|
75
70
|
}
|
|
76
|
-
|
|
77
71
|
muteNode(node) {
|
|
78
72
|
if (node && node.tagName.toLowerCase() !== 'script') {
|
|
79
73
|
// When we are trapping screen reader focus on an element that
|
|
@@ -86,31 +80,24 @@ class ScreenReaderFocusRegion {
|
|
|
86
80
|
['role', 'aria-label', 'aria-hidden' // this should never happen right?
|
|
87
81
|
].forEach(attribute => {
|
|
88
82
|
const value = node.getAttribute(attribute);
|
|
89
|
-
|
|
90
83
|
if (value !== null) {
|
|
91
84
|
this._attributes.push([node, attribute, value]);
|
|
92
|
-
|
|
93
85
|
node.removeAttribute(attribute);
|
|
94
86
|
}
|
|
95
87
|
});
|
|
96
|
-
|
|
97
88
|
this._observer.observe(node, {
|
|
98
89
|
childList: true
|
|
99
90
|
});
|
|
100
91
|
}
|
|
101
92
|
}
|
|
102
|
-
|
|
103
93
|
hideNodes(nodes) {
|
|
104
94
|
nodes.forEach(node => {
|
|
105
95
|
var _node$getAttribute;
|
|
106
|
-
|
|
107
96
|
const ariaLive = typeof node.getAttribute === 'function' && ((_node$getAttribute = node.getAttribute('aria-live')) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.toLowerCase());
|
|
108
|
-
|
|
109
97
|
if (node && node.nodeType === 1 && node.tagName.toLowerCase() !== 'script' && ariaLive !== 'assertive' && ariaLive !== 'polite' && this._parents.indexOf(node) === -1 && this._nodes.indexOf(node) === -1 && this._liveRegion.indexOf(node) === -1 && !this._contextElement.contains(node)) {
|
|
110
98
|
if (node.tagName.toLowerCase() !== 'iframe') {
|
|
111
99
|
this.hideNode(node);
|
|
112
100
|
}
|
|
113
|
-
|
|
114
101
|
const iframeBodies = this.parseIframeBodies(node);
|
|
115
102
|
iframeBodies.forEach(iframeBody => {
|
|
116
103
|
this.hideNode(iframeBody);
|
|
@@ -118,29 +105,22 @@ class ScreenReaderFocusRegion {
|
|
|
118
105
|
}
|
|
119
106
|
});
|
|
120
107
|
}
|
|
121
|
-
|
|
122
108
|
hideNode(node) {
|
|
123
109
|
if (node.getAttribute('aria-hidden') !== 'true') {
|
|
124
110
|
node.setAttribute('aria-hidden', 'true');
|
|
125
|
-
|
|
126
111
|
this._nodes.push(node);
|
|
127
112
|
}
|
|
128
113
|
}
|
|
129
|
-
|
|
130
114
|
restoreNode(removedNode) {
|
|
131
115
|
const index = this._nodes.indexOf(removedNode);
|
|
132
|
-
|
|
133
116
|
if (index >= 0) {
|
|
134
117
|
removedNode.removeAttribute('aria-hidden');
|
|
135
|
-
|
|
136
118
|
this._nodes.splice(index, 1);
|
|
137
119
|
}
|
|
138
120
|
}
|
|
139
|
-
|
|
140
121
|
parseIframeBodies(node) {
|
|
141
122
|
if (!node) return [];
|
|
142
123
|
let iframes = [];
|
|
143
|
-
|
|
144
124
|
if (node.tagName.toLowerCase() === 'iframe') {
|
|
145
125
|
iframes.push(node);
|
|
146
126
|
} else {
|
|
@@ -148,38 +128,29 @@ class ScreenReaderFocusRegion {
|
|
|
148
128
|
iframes = Array.from(node.getElementsByTagName('iframe'));
|
|
149
129
|
}
|
|
150
130
|
}
|
|
151
|
-
|
|
152
131
|
return iframes.map(iframe => {
|
|
153
132
|
let body = null;
|
|
154
|
-
|
|
155
133
|
try {
|
|
156
134
|
body = iframe.contentDocument.body;
|
|
157
135
|
} catch (e) {
|
|
158
136
|
(0, _console.logWarn)(false, `[ui-a11y] could not find a document for iframe: ${e} ${iframe}`);
|
|
159
137
|
}
|
|
160
|
-
|
|
161
138
|
return body;
|
|
162
139
|
}).filter(body => body !== null);
|
|
163
140
|
}
|
|
164
|
-
|
|
165
141
|
activate() {
|
|
166
142
|
if (!this._options.shouldContainFocus) {
|
|
167
143
|
return;
|
|
168
144
|
}
|
|
169
|
-
|
|
170
145
|
this._observer = new MutationObserver(this.handleDOMMutation);
|
|
171
146
|
let node = this._contextElement;
|
|
172
|
-
|
|
173
147
|
while (node && node.nodeType === Node.ELEMENT_NODE && node.tagName.toLowerCase() !== 'body') {
|
|
174
148
|
const parent = node.parentElement;
|
|
175
|
-
|
|
176
149
|
if (parent) {
|
|
177
150
|
this._parents.push(parent);
|
|
178
|
-
|
|
179
151
|
this.muteNode(parent);
|
|
180
152
|
this.hideNodes(Array.prototype.slice.call(parent.childNodes));
|
|
181
153
|
}
|
|
182
|
-
|
|
183
154
|
node = node.parentNode; // should never be null, will default to doc element
|
|
184
155
|
}
|
|
185
156
|
}
|
|
@@ -187,26 +158,19 @@ class ScreenReaderFocusRegion {
|
|
|
187
158
|
deactivate() {
|
|
188
159
|
if (this._observer) {
|
|
189
160
|
this._observer.disconnect();
|
|
190
|
-
|
|
191
161
|
this._observer = null;
|
|
192
162
|
}
|
|
193
|
-
|
|
194
163
|
this._nodes.forEach(node => {
|
|
195
164
|
node.removeAttribute('aria-hidden');
|
|
196
165
|
});
|
|
197
|
-
|
|
198
166
|
this._nodes = [];
|
|
199
|
-
|
|
200
167
|
this._attributes.forEach(attribute => {
|
|
201
168
|
attribute[0].setAttribute(attribute[1], attribute[2] || '');
|
|
202
169
|
});
|
|
203
|
-
|
|
204
170
|
this._attributes = [];
|
|
205
171
|
this._parents = [];
|
|
206
172
|
}
|
|
207
|
-
|
|
208
173
|
}
|
|
209
|
-
|
|
210
174
|
exports.ScreenReaderFocusRegion = ScreenReaderFocusRegion;
|
|
211
175
|
var _default = ScreenReaderFocusRegion;
|
|
212
176
|
exports.default = _default;
|
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
-
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
7
|
exports.default = void 0;
|
|
9
8
|
exports.hasVisibleChildren = hasVisibleChildren;
|
|
10
|
-
|
|
11
9
|
var _react = _interopRequireDefault(require("react"));
|
|
12
|
-
|
|
13
10
|
var _matchComponentTypes = require("@instructure/ui-react-utils/lib/matchComponentTypes.js");
|
|
14
|
-
|
|
15
11
|
var _ScreenReaderContent = require("@instructure/ui-a11y-content/lib/ScreenReaderContent");
|
|
16
|
-
|
|
17
12
|
/*
|
|
18
13
|
* The MIT License (MIT)
|
|
19
14
|
*
|
|
@@ -37,17 +32,15 @@ var _ScreenReaderContent = require("@instructure/ui-a11y-content/lib/ScreenReade
|
|
|
37
32
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
38
33
|
* SOFTWARE.
|
|
39
34
|
*/
|
|
35
|
+
|
|
40
36
|
function hasVisibleChildren(children) {
|
|
41
37
|
let visible = false;
|
|
42
|
-
|
|
43
38
|
_react.default.Children.forEach(children, child => {
|
|
44
39
|
if (child && !(0, _matchComponentTypes.matchComponentTypes)(child, [_ScreenReaderContent.ScreenReaderContent])) {
|
|
45
40
|
visible = true;
|
|
46
41
|
}
|
|
47
42
|
});
|
|
48
|
-
|
|
49
43
|
return visible;
|
|
50
44
|
}
|
|
51
|
-
|
|
52
45
|
var _default = hasVisibleChildren;
|
|
53
46
|
exports.default = _default;
|
package/lib/index.js
CHANGED
|
@@ -39,15 +39,9 @@ Object.defineProperty(exports, "scopeTab", {
|
|
|
39
39
|
return _scopeTab.scopeTab;
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
|
-
|
|
43
42
|
var _FocusRegion = require("./FocusRegion");
|
|
44
|
-
|
|
45
43
|
var _FocusRegionManager = require("./FocusRegionManager");
|
|
46
|
-
|
|
47
44
|
var _hasVisibleChildren = require("./hasVisibleChildren");
|
|
48
|
-
|
|
49
45
|
var _KeyboardFocusRegion = require("./KeyboardFocusRegion");
|
|
50
|
-
|
|
51
46
|
var _scopeTab = require("./scopeTab");
|
|
52
|
-
|
|
53
47
|
var _ScreenReaderFocusRegion = require("./ScreenReaderFocusRegion");
|
package/lib/scopeTab.js
CHANGED
|
@@ -5,17 +5,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
exports.scopeTab = scopeTab;
|
|
8
|
-
|
|
9
8
|
var _findDOMNode = require("@instructure/ui-dom-utils/lib/findDOMNode.js");
|
|
10
|
-
|
|
11
9
|
var _findTabbable = require("@instructure/ui-dom-utils/lib/findTabbable.js");
|
|
12
|
-
|
|
13
10
|
var _isActiveElement = require("@instructure/ui-dom-utils/lib/isActiveElement.js");
|
|
14
|
-
|
|
15
11
|
var _containsActiveElement = require("@instructure/ui-dom-utils/lib/containsActiveElement.js");
|
|
16
|
-
|
|
17
12
|
var _getActiveElement = require("@instructure/ui-dom-utils/lib/getActiveElement.js");
|
|
18
|
-
|
|
19
13
|
/*
|
|
20
14
|
* The MIT License (MIT)
|
|
21
15
|
*
|
|
@@ -39,40 +33,37 @@ var _getActiveElement = require("@instructure/ui-dom-utils/lib/getActiveElement.
|
|
|
39
33
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
40
34
|
* SOFTWARE.
|
|
41
35
|
*/
|
|
36
|
+
|
|
42
37
|
function scopeTab(element, event, onLeavingFinalTabbable) {
|
|
43
38
|
const node = (0, _findDOMNode.findDOMNode)(element);
|
|
44
39
|
const tabbable = (0, _findTabbable.findTabbable)(node);
|
|
45
|
-
|
|
46
40
|
if (!tabbable.length) {
|
|
47
41
|
event.preventDefault();
|
|
48
42
|
return;
|
|
49
|
-
}
|
|
50
|
-
// (a case that happens with Menu for KO a11y)
|
|
51
|
-
|
|
43
|
+
}
|
|
52
44
|
|
|
45
|
+
// Account for a changing tabindex of the active element
|
|
46
|
+
// (a case that happens with Menu for KO a11y)
|
|
53
47
|
if ((0, _containsActiveElement.containsActiveElement)(element)) {
|
|
54
48
|
const activeElement = (0, _getActiveElement.getActiveElement)();
|
|
55
|
-
|
|
56
49
|
if (activeElement && tabbable.indexOf(activeElement) === -1) {
|
|
57
50
|
tabbable.push(activeElement);
|
|
58
51
|
}
|
|
59
52
|
}
|
|
60
|
-
|
|
61
53
|
const finalTabbable = tabbable[event.shiftKey ? 0 : tabbable.length - 1];
|
|
62
|
-
const leavingFinalTabbable = (0, _isActiveElement.isActiveElement)(finalTabbable) ||
|
|
63
|
-
|
|
54
|
+
const leavingFinalTabbable = (0, _isActiveElement.isActiveElement)(finalTabbable) ||
|
|
55
|
+
// handle immediate shift+tab after opening with mouse
|
|
56
|
+
(0, _isActiveElement.isActiveElement)(node) ||
|
|
57
|
+
// already left final tabbable
|
|
64
58
|
!(0, _containsActiveElement.containsActiveElement)(element);
|
|
65
59
|
if (!leavingFinalTabbable) return;
|
|
66
|
-
|
|
67
60
|
if (typeof onLeavingFinalTabbable === 'function') {
|
|
68
61
|
onLeavingFinalTabbable();
|
|
69
62
|
return;
|
|
70
63
|
}
|
|
71
|
-
|
|
72
64
|
event.preventDefault();
|
|
73
65
|
const target = tabbable[event.shiftKey ? tabbable.length - 1 : 0];
|
|
74
66
|
target.focus();
|
|
75
67
|
}
|
|
76
|
-
|
|
77
68
|
var _default = scopeTab;
|
|
78
69
|
exports.default = _default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-a11y-utils",
|
|
3
|
-
"version": "8.33.2
|
|
3
|
+
"version": "8.33.2",
|
|
4
4
|
"description": "A collection of utilities for managing focus and screen reader behavior",
|
|
5
5
|
"author": "Instructure, Inc. Engineering and Product Design",
|
|
6
6
|
"module": "./es/index.js",
|
|
@@ -23,19 +23,19 @@
|
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@babel/runtime": "^7.13.10",
|
|
26
|
-
"@instructure/console": "8.33.2
|
|
27
|
-
"@instructure/ui-a11y-content": "8.33.2
|
|
28
|
-
"@instructure/ui-dom-utils": "8.33.2
|
|
29
|
-
"@instructure/ui-react-utils": "8.33.2
|
|
30
|
-
"@instructure/ui-testable": "8.33.2
|
|
31
|
-
"@instructure/uid": "8.33.2
|
|
26
|
+
"@instructure/console": "8.33.2",
|
|
27
|
+
"@instructure/ui-a11y-content": "8.33.2",
|
|
28
|
+
"@instructure/ui-dom-utils": "8.33.2",
|
|
29
|
+
"@instructure/ui-react-utils": "8.33.2",
|
|
30
|
+
"@instructure/ui-testable": "8.33.2",
|
|
31
|
+
"@instructure/uid": "8.33.2",
|
|
32
32
|
"keycode": "^2",
|
|
33
33
|
"prop-types": "^15"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@instructure/ui-babel-preset": "8.33.2
|
|
37
|
-
"@instructure/ui-color-utils": "8.33.2
|
|
38
|
-
"@instructure/ui-test-utils": "8.33.2
|
|
36
|
+
"@instructure/ui-babel-preset": "8.33.2",
|
|
37
|
+
"@instructure/ui-color-utils": "8.33.2",
|
|
38
|
+
"@instructure/ui-test-utils": "8.33.2"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"react": ">=16.8 <=18"
|