@instructure/ui-a11y-utils 8.56.0 → 8.56.2-pr-snapshot-1721749364069
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 +16 -0
- package/lib/FocusRegion.js +10 -13
- package/lib/KeyboardFocusRegion.js +21 -29
- package/lib/hasVisibleChildren.js +3 -3
- package/lib/scopeTab.js +8 -12
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [8.56.2-pr-snapshot-1721749364069](https://github.com/instructure/instructure-ui/compare/v8.56.1...v8.56.2-pr-snapshot-1721749364069) (2024-07-23)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @instructure/ui-a11y-utils
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [8.56.1](https://github.com/instructure/instructure-ui/compare/v8.56.0...v8.56.1) (2024-06-13)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @instructure/ui-a11y-utils
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
# [8.56.0](https://github.com/instructure/instructure-ui/compare/v8.55.1...v8.56.0) (2024-05-06)
|
|
7
23
|
|
|
8
24
|
**Note:** Version bump only for package @instructure/ui-a11y-utils
|
package/lib/FocusRegion.js
CHANGED
|
@@ -6,10 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.default = exports.FocusRegion = void 0;
|
|
8
8
|
var _keycode = _interopRequireDefault(require("keycode"));
|
|
9
|
-
var
|
|
10
|
-
var _addEventListener = require("@instructure/ui-dom-utils/lib/addEventListener.js");
|
|
11
|
-
var _ownerDocument2 = require("@instructure/ui-dom-utils/lib/ownerDocument.js");
|
|
12
|
-
var _findTabbable = require("@instructure/ui-dom-utils/lib/findTabbable.js");
|
|
9
|
+
var _uiDomUtils = require("@instructure/ui-dom-utils");
|
|
13
10
|
var _uid = require("@instructure/uid");
|
|
14
11
|
var _console = require("@instructure/console");
|
|
15
12
|
var _ScreenReaderFocusRegion = require("./ScreenReaderFocusRegion");
|
|
@@ -55,7 +52,7 @@ class FocusRegion {
|
|
|
55
52
|
};
|
|
56
53
|
this.captureDocumentMousedown = event => {
|
|
57
54
|
this._documentClickTarget = event.target;
|
|
58
|
-
this._contextContainsTarget = (0,
|
|
55
|
+
this._contextContainsTarget = (0, _uiDomUtils.contains)(this._contextElement, this._documentClickTarget);
|
|
59
56
|
};
|
|
60
57
|
this.handleDocumentClick = event => {
|
|
61
58
|
if (this._options.shouldCloseOnDocumentClick && event.button === 0 && event.detail > 0 &&
|
|
@@ -65,7 +62,7 @@ class FocusRegion {
|
|
|
65
62
|
}
|
|
66
63
|
};
|
|
67
64
|
this.handleFrameClick = (event, frame) => {
|
|
68
|
-
if (!(0,
|
|
65
|
+
if (!(0, _uiDomUtils.contains)(this._contextElement, frame)) {
|
|
69
66
|
// dismiss if frame is not within the region
|
|
70
67
|
this.handleDismiss(event, true);
|
|
71
68
|
}
|
|
@@ -76,7 +73,7 @@ class FocusRegion {
|
|
|
76
73
|
// If a dialog contains an <input type="file"/> element and the user opens the file picker and closes it with the
|
|
77
74
|
// escape key then Firefox passes through that event which could close the parent dialog. This code prevents that
|
|
78
75
|
// from happening (listening for a `cancel` event doesn't seem to work in firefox)
|
|
79
|
-
const activeElement = (_ownerDocument = (0,
|
|
76
|
+
const activeElement = (_ownerDocument = (0, _uiDomUtils.ownerDocument)(this._contextElement)) === null || _ownerDocument === void 0 ? void 0 : _ownerDocument.activeElement;
|
|
80
77
|
const fileInputFocused = (activeElement === null || activeElement === void 0 ? void 0 : activeElement.tagName) === 'INPUT' && activeElement.type === 'file';
|
|
81
78
|
if (fileInputFocused) {
|
|
82
79
|
;
|
|
@@ -117,28 +114,28 @@ class FocusRegion {
|
|
|
117
114
|
return this._active;
|
|
118
115
|
}
|
|
119
116
|
get keyboardFocusable() {
|
|
120
|
-
return ((0,
|
|
117
|
+
return ((0, _uiDomUtils.findTabbable)(this._contextElement) || []).length > 0;
|
|
121
118
|
}
|
|
122
119
|
activate() {
|
|
123
120
|
if (!this._active) {
|
|
124
|
-
const doc = (0,
|
|
121
|
+
const doc = (0, _uiDomUtils.ownerDocument)(this._contextElement);
|
|
125
122
|
this._keyboardFocusRegion.activate();
|
|
126
123
|
this._screenReaderFocusRegion.activate();
|
|
127
124
|
if (this._options.shouldCloseOnDocumentClick) {
|
|
128
|
-
this._listeners.push((0,
|
|
129
|
-
this._listeners.push((0,
|
|
125
|
+
this._listeners.push((0, _uiDomUtils.addEventListener)(doc, 'mousedown', this.captureDocumentMousedown));
|
|
126
|
+
this._listeners.push((0, _uiDomUtils.addEventListener)(doc, 'click', this.handleDocumentClick));
|
|
130
127
|
Array.from(doc.getElementsByTagName('iframe')).forEach(el => {
|
|
131
128
|
// listen for mouseup events on any iframes in the document
|
|
132
129
|
const frameDoc = el.contentDocument;
|
|
133
130
|
if (frameDoc) {
|
|
134
|
-
this._listeners.push((0,
|
|
131
|
+
this._listeners.push((0, _uiDomUtils.addEventListener)(frameDoc, 'mouseup', event => {
|
|
135
132
|
this.handleFrameClick(event, el);
|
|
136
133
|
}));
|
|
137
134
|
}
|
|
138
135
|
});
|
|
139
136
|
}
|
|
140
137
|
if (this._options.shouldCloseOnEscape) {
|
|
141
|
-
this._listeners.push((0,
|
|
138
|
+
this._listeners.push((0, _uiDomUtils.addEventListener)(doc, 'keyup', this.handleKeyUp));
|
|
142
139
|
}
|
|
143
140
|
this._active = true;
|
|
144
141
|
}
|
|
@@ -5,15 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.default = exports.KeyboardFocusRegion = void 0;
|
|
8
|
-
var
|
|
9
|
-
var _findTabbable = require("@instructure/ui-dom-utils/lib/findTabbable.js");
|
|
10
|
-
var _findFocusable = require("@instructure/ui-dom-utils/lib/findFocusable.js");
|
|
11
|
-
var _ownerWindow = require("@instructure/ui-dom-utils/lib/ownerWindow.js");
|
|
12
|
-
var _getActiveElement = require("@instructure/ui-dom-utils/lib/getActiveElement.js");
|
|
13
|
-
var _addEventListener = require("@instructure/ui-dom-utils/lib/addEventListener.js");
|
|
14
|
-
var _ownerDocument = require("@instructure/ui-dom-utils/lib/ownerDocument.js");
|
|
15
|
-
var _containsActiveElement = require("@instructure/ui-dom-utils/lib/containsActiveElement.js");
|
|
16
|
-
var _requestAnimationFrame = require("@instructure/ui-dom-utils/lib/requestAnimationFrame.js");
|
|
8
|
+
var _uiDomUtils = require("@instructure/ui-dom-utils");
|
|
17
9
|
var _console = require("@instructure/console");
|
|
18
10
|
var _keycode = _interopRequireDefault(require("keycode"));
|
|
19
11
|
var _scopeTab = require("./scopeTab");
|
|
@@ -77,8 +69,8 @@ class KeyboardFocusRegion {
|
|
|
77
69
|
// the element outside of a setTimeout. Side-effect of this implementation
|
|
78
70
|
// is that the document.body gets focus, and then we focus our element right
|
|
79
71
|
// after, seems fine.
|
|
80
|
-
this._raf.push((0,
|
|
81
|
-
if ((0,
|
|
72
|
+
this._raf.push((0, _uiDomUtils.requestAnimationFrame)(() => {
|
|
73
|
+
if ((0, _uiDomUtils.containsActiveElement)(this._contextElement)) {
|
|
82
74
|
return;
|
|
83
75
|
}
|
|
84
76
|
this.focusDefaultElement();
|
|
@@ -97,28 +89,28 @@ class KeyboardFocusRegion {
|
|
|
97
89
|
(_this$_options$onBlur2 = (_this$_options2 = this._options).onBlur) === null || _this$_options$onBlur2 === void 0 ? void 0 : _this$_options$onBlur2.call(_this$_options2, event);
|
|
98
90
|
}
|
|
99
91
|
};
|
|
100
|
-
this._contextElement = (0,
|
|
92
|
+
this._contextElement = (0, _uiDomUtils.findDOMNode)(element);
|
|
101
93
|
this._options = options || {
|
|
102
94
|
shouldContainFocus: true,
|
|
103
95
|
shouldReturnFocus: true,
|
|
104
96
|
defaultFocusElement: null
|
|
105
97
|
};
|
|
106
98
|
if (this._options.shouldReturnFocus) {
|
|
107
|
-
this._focusLaterElement = (0,
|
|
99
|
+
this._focusLaterElement = (0, _uiDomUtils.getActiveElement)(this.doc);
|
|
108
100
|
}
|
|
109
101
|
}
|
|
110
102
|
get focused() {
|
|
111
|
-
return (0,
|
|
103
|
+
return (0, _uiDomUtils.containsActiveElement)(this._contextElement);
|
|
112
104
|
}
|
|
113
105
|
get shouldContainFocus() {
|
|
114
106
|
const shouldContainFocus = this._options.shouldContainFocus;
|
|
115
107
|
return shouldContainFocus === true || Array.isArray(shouldContainFocus) && shouldContainFocus.includes('keyboard');
|
|
116
108
|
}
|
|
117
109
|
get focusable() {
|
|
118
|
-
return (0,
|
|
110
|
+
return (0, _uiDomUtils.findFocusable)(this._contextElement, () => true, true) || [];
|
|
119
111
|
}
|
|
120
112
|
get tabbable() {
|
|
121
|
-
return (0,
|
|
113
|
+
return (0, _uiDomUtils.findTabbable)(this._contextElement) || [];
|
|
122
114
|
}
|
|
123
115
|
get firstTabbable() {
|
|
124
116
|
return this.tabbable[0];
|
|
@@ -133,14 +125,14 @@ class KeyboardFocusRegion {
|
|
|
133
125
|
return this.focusable.pop();
|
|
134
126
|
}
|
|
135
127
|
get doc() {
|
|
136
|
-
return (0,
|
|
128
|
+
return (0, _uiDomUtils.ownerDocument)(this._contextElement);
|
|
137
129
|
}
|
|
138
130
|
get win() {
|
|
139
|
-
return (0,
|
|
131
|
+
return (0, _uiDomUtils.ownerWindow)(this._contextElement);
|
|
140
132
|
}
|
|
141
133
|
get defaultFocusElement() {
|
|
142
134
|
const defaultFocusElement = this._options.defaultFocusElement;
|
|
143
|
-
const element = (0,
|
|
135
|
+
const element = (0, _uiDomUtils.findDOMNode)(typeof defaultFocusElement === 'function' ? defaultFocusElement() : defaultFocusElement);
|
|
144
136
|
if (element && this._contextElement && this._contextElement.contains(element)) {
|
|
145
137
|
return element;
|
|
146
138
|
}
|
|
@@ -153,7 +145,7 @@ class KeyboardFocusRegion {
|
|
|
153
145
|
return null;
|
|
154
146
|
}
|
|
155
147
|
updateElement(element) {
|
|
156
|
-
this._contextElement = (0,
|
|
148
|
+
this._contextElement = (0, _uiDomUtils.findDOMNode)(element);
|
|
157
149
|
}
|
|
158
150
|
focusDefaultElement() {
|
|
159
151
|
if (this.defaultFocusElement) {
|
|
@@ -167,7 +159,7 @@ class KeyboardFocusRegion {
|
|
|
167
159
|
} else {
|
|
168
160
|
if (this.shouldContainFocus) {
|
|
169
161
|
// Blur the active element to place focus on the document body
|
|
170
|
-
(0,
|
|
162
|
+
(0, _uiDomUtils.getActiveElement)(this.doc) && (0, _uiDomUtils.getActiveElement)(this.doc).blur();
|
|
171
163
|
(0, _console.logError)(true, `
|
|
172
164
|
[KeyboardFocusRegion] No \`defaultFocusElement\` was provided and
|
|
173
165
|
\`shouldContainFocus\` was set to \`true\` or \`keyboard\`. Focus has
|
|
@@ -192,7 +184,7 @@ class KeyboardFocusRegion {
|
|
|
192
184
|
if (!isHiddenOutside) {
|
|
193
185
|
focusElement.focus();
|
|
194
186
|
} else {
|
|
195
|
-
this._raf.push((0,
|
|
187
|
+
this._raf.push((0, _uiDomUtils.requestAnimationFrame)(() => {
|
|
196
188
|
this.tryFocusOnPositionedElement(positionContainer, focusElement, tries - 1);
|
|
197
189
|
}));
|
|
198
190
|
}
|
|
@@ -201,7 +193,7 @@ class KeyboardFocusRegion {
|
|
|
201
193
|
if (this.focused) {
|
|
202
194
|
return;
|
|
203
195
|
}
|
|
204
|
-
this._raf.push((0,
|
|
196
|
+
this._raf.push((0, _uiDomUtils.requestAnimationFrame)(() => {
|
|
205
197
|
this.focusDefaultElement();
|
|
206
198
|
}));
|
|
207
199
|
}
|
|
@@ -225,14 +217,14 @@ class KeyboardFocusRegion {
|
|
|
225
217
|
if (!this._active) {
|
|
226
218
|
if (defaultFocusElement || shouldContainFocus) {
|
|
227
219
|
if (shouldContainFocus) {
|
|
228
|
-
this._listeners.push((0,
|
|
220
|
+
this._listeners.push((0, _uiDomUtils.addEventListener)(this.doc, 'keydown', this.handleKeyDown));
|
|
229
221
|
} else {
|
|
230
|
-
this._listeners.push((0,
|
|
231
|
-
this._listeners.push((0,
|
|
222
|
+
this._listeners.push((0, _uiDomUtils.addEventListener)(this.firstTabbable || defaultFocusElement, 'keydown', this.handleFirstTabbableKeyDown));
|
|
223
|
+
this._listeners.push((0, _uiDomUtils.addEventListener)(this.lastTabbable || defaultFocusElement, 'keydown', this.handleLastTabbableKeyDown));
|
|
232
224
|
}
|
|
233
|
-
this._listeners.push((0,
|
|
234
|
-
this._listeners.push((0,
|
|
235
|
-
this._listeners.push((0,
|
|
225
|
+
this._listeners.push((0, _uiDomUtils.addEventListener)(this.doc, 'click', this.handleClick, true));
|
|
226
|
+
this._listeners.push((0, _uiDomUtils.addEventListener)(this.win, 'blur', this.handleWindowBlur, false));
|
|
227
|
+
this._listeners.push((0, _uiDomUtils.addEventListener)(this.doc, 'focus', this.handleFocus, true));
|
|
236
228
|
this._active = true;
|
|
237
229
|
}
|
|
238
230
|
}
|
|
@@ -7,8 +7,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.default = void 0;
|
|
8
8
|
exports.hasVisibleChildren = hasVisibleChildren;
|
|
9
9
|
var _react = _interopRequireDefault(require("react"));
|
|
10
|
-
var
|
|
11
|
-
var
|
|
10
|
+
var _uiReactUtils = require("@instructure/ui-react-utils");
|
|
11
|
+
var _uiA11yContent = require("@instructure/ui-a11y-content");
|
|
12
12
|
/*
|
|
13
13
|
* The MIT License (MIT)
|
|
14
14
|
*
|
|
@@ -36,7 +36,7 @@ var _ScreenReaderContent = require("@instructure/ui-a11y-content/lib/ScreenReade
|
|
|
36
36
|
function hasVisibleChildren(children) {
|
|
37
37
|
let visible = false;
|
|
38
38
|
_react.default.Children.forEach(children, child => {
|
|
39
|
-
if (child && !(0,
|
|
39
|
+
if (child && !(0, _uiReactUtils.matchComponentTypes)(child, [_uiA11yContent.ScreenReaderContent])) {
|
|
40
40
|
visible = true;
|
|
41
41
|
}
|
|
42
42
|
});
|
package/lib/scopeTab.js
CHANGED
|
@@ -5,11 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
exports.scopeTab = scopeTab;
|
|
8
|
-
var
|
|
9
|
-
var _findTabbable = require("@instructure/ui-dom-utils/lib/findTabbable.js");
|
|
10
|
-
var _isActiveElement = require("@instructure/ui-dom-utils/lib/isActiveElement.js");
|
|
11
|
-
var _containsActiveElement = require("@instructure/ui-dom-utils/lib/containsActiveElement.js");
|
|
12
|
-
var _getActiveElement = require("@instructure/ui-dom-utils/lib/getActiveElement.js");
|
|
8
|
+
var _uiDomUtils = require("@instructure/ui-dom-utils");
|
|
13
9
|
/*
|
|
14
10
|
* The MIT License (MIT)
|
|
15
11
|
*
|
|
@@ -35,8 +31,8 @@ var _getActiveElement = require("@instructure/ui-dom-utils/lib/getActiveElement.
|
|
|
35
31
|
*/
|
|
36
32
|
|
|
37
33
|
function scopeTab(element, event, onLeavingFinalTabbable) {
|
|
38
|
-
const node = (0,
|
|
39
|
-
const tabbable = (0,
|
|
34
|
+
const node = (0, _uiDomUtils.findDOMNode)(element);
|
|
35
|
+
const tabbable = (0, _uiDomUtils.findTabbable)(node);
|
|
40
36
|
if (!tabbable.length) {
|
|
41
37
|
event.preventDefault();
|
|
42
38
|
return;
|
|
@@ -44,18 +40,18 @@ function scopeTab(element, event, onLeavingFinalTabbable) {
|
|
|
44
40
|
|
|
45
41
|
// Account for a changing tabindex of the active element
|
|
46
42
|
// (a case that happens with Menu for KO a11y)
|
|
47
|
-
if ((0,
|
|
48
|
-
const activeElement = (0,
|
|
43
|
+
if ((0, _uiDomUtils.containsActiveElement)(element)) {
|
|
44
|
+
const activeElement = (0, _uiDomUtils.getActiveElement)();
|
|
49
45
|
if (activeElement && tabbable.indexOf(activeElement) === -1) {
|
|
50
46
|
tabbable.push(activeElement);
|
|
51
47
|
}
|
|
52
48
|
}
|
|
53
49
|
const finalTabbable = tabbable[event.shiftKey ? 0 : tabbable.length - 1];
|
|
54
|
-
const leavingFinalTabbable = (0,
|
|
50
|
+
const leavingFinalTabbable = (0, _uiDomUtils.isActiveElement)(finalTabbable) ||
|
|
55
51
|
// handle immediate shift+tab after opening with mouse
|
|
56
|
-
(0,
|
|
52
|
+
(0, _uiDomUtils.isActiveElement)(node) ||
|
|
57
53
|
// already left final tabbable
|
|
58
|
-
!(0,
|
|
54
|
+
!(0, _uiDomUtils.containsActiveElement)(element);
|
|
59
55
|
if (!leavingFinalTabbable) return;
|
|
60
56
|
if (typeof onLeavingFinalTabbable === 'function') {
|
|
61
57
|
onLeavingFinalTabbable();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-a11y-utils",
|
|
3
|
-
"version": "8.56.
|
|
3
|
+
"version": "8.56.2-pr-snapshot-1721749364069",
|
|
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.23.2",
|
|
26
|
-
"@instructure/console": "8.56.
|
|
27
|
-
"@instructure/ui-a11y-content": "8.56.
|
|
28
|
-
"@instructure/ui-dom-utils": "8.56.
|
|
29
|
-
"@instructure/ui-react-utils": "8.56.
|
|
30
|
-
"@instructure/ui-testable": "8.56.
|
|
31
|
-
"@instructure/uid": "8.56.
|
|
26
|
+
"@instructure/console": "8.56.2-pr-snapshot-1721749364069",
|
|
27
|
+
"@instructure/ui-a11y-content": "8.56.2-pr-snapshot-1721749364069",
|
|
28
|
+
"@instructure/ui-dom-utils": "8.56.2-pr-snapshot-1721749364069",
|
|
29
|
+
"@instructure/ui-react-utils": "8.56.2-pr-snapshot-1721749364069",
|
|
30
|
+
"@instructure/ui-testable": "8.56.2-pr-snapshot-1721749364069",
|
|
31
|
+
"@instructure/uid": "8.56.2-pr-snapshot-1721749364069",
|
|
32
32
|
"keycode": "^2.2.1",
|
|
33
33
|
"prop-types": "^15.8.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@instructure/ui-babel-preset": "8.56.
|
|
37
|
-
"@instructure/ui-color-utils": "8.56.
|
|
38
|
-
"@instructure/ui-test-utils": "8.56.
|
|
36
|
+
"@instructure/ui-babel-preset": "8.56.2-pr-snapshot-1721749364069",
|
|
37
|
+
"@instructure/ui-color-utils": "8.56.2-pr-snapshot-1721749364069",
|
|
38
|
+
"@instructure/ui-test-utils": "8.56.2-pr-snapshot-1721749364069"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"react": ">=16.8 <=18"
|