focus-trap-react 8.7.1 → 8.9.0
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 +29 -0
- package/README.md +5 -2
- package/dist/focus-trap-react.js +54 -11
- package/package.json +25 -25
- package/src/focus-trap-react.js +49 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 8.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 83097a5: Delay trap creation until it should be active. This is a change in behavior, however it should not break existing behavior. The delay now allows you to set `active=false` until you have the `focusTrapOptions` set correctly. [#539](https://github.com/focus-trap/focus-trap-react/issues/539)
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 16d1ae1: Fix bug where global document was being accessed instead of first checking for `focusTrapOptions.document` option. [#539](https://github.com/focus-trap/focus-trap-react/issues/539)
|
|
12
|
+
|
|
13
|
+
## 8.8.2
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 08a9449: Use `preventScroll` option on deactivation if returning focus.
|
|
18
|
+
|
|
19
|
+
## 8.8.1
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- a2806a0: Fix SSR issues when accessing `document` object (#482)
|
|
24
|
+
|
|
25
|
+
## 8.8.0
|
|
26
|
+
|
|
27
|
+
### Minor Changes
|
|
28
|
+
|
|
29
|
+
- c8e46c2: Support new `document` option introduced in focus-trap v6.7.0 (#460)
|
|
30
|
+
- 5ee587c: Bump focus-trap dependency to v6.7.1
|
|
31
|
+
|
|
3
32
|
## 8.7.1
|
|
4
33
|
|
|
5
34
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# focus-trap-react [](https://github.com/focus-trap/focus-trap-react/actions?query=workflow:CI+branch:master) [](https://codecov.io/gh/focus-trap/focus-trap-react) [](./LICENSE)
|
|
2
2
|
|
|
3
3
|
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
|
4
|
-
[](#contributors)
|
|
5
5
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
|
6
6
|
|
|
7
7
|
A React component that traps focus.
|
|
@@ -191,19 +191,22 @@ In alphabetical order:
|
|
|
191
191
|
<td align="center"><a href="https://github.com/features/security"><img src="https://avatars1.githubusercontent.com/u/27347476?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dependabot</b></sub></a><br /><a href="#maintenance-dependabot" title="Maintenance">🚧</a></td>
|
|
192
192
|
</tr>
|
|
193
193
|
<tr>
|
|
194
|
+
<td align="center"><a href="https://github.com/jhnns"><img src="https://avatars.githubusercontent.com/u/781746?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Johannes Ewald</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap-react/commits?author=jhnns" title="Code">💻</a></td>
|
|
194
195
|
<td align="center"><a href="http://josuzuki.me"><img src="https://avatars1.githubusercontent.com/u/9583920?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jonathan Suzuki</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap-react/issues?q=author%3AJoSuzuki" title="Bug reports">🐛</a></td>
|
|
195
196
|
<td align="center"><a href="http://kathleenmcmahon.dev/"><img src="https://avatars1.githubusercontent.com/u/11621935?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kathleen McMahon</b></sub></a><br /><a href="#maintenance-resource11" title="Maintenance">🚧</a></td>
|
|
196
197
|
<td align="center"><a href="https://marais.io/"><img src="https://avatars2.githubusercontent.com/u/599459?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Marais Rossouw</b></sub></a><br /><a href="#infra-maraisr" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
|
197
198
|
<td align="center"><a href="https://github.com/liunate"><img src="https://avatars2.githubusercontent.com/u/38996291?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nate Liu</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap-react/commits?author=liunate" title="Tests">⚠️</a></td>
|
|
198
199
|
<td align="center"><a href="https://www.linkedin.com/in/rivajunior/"><img src="https://avatars1.githubusercontent.com/u/11370172?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Rivaldo Junior</b></sub></a><br /><a href="#maintenance-rivajunior" title="Maintenance">🚧</a></td>
|
|
199
200
|
<td align="center"><a href="https://scottrippey.github.io/"><img src="https://avatars3.githubusercontent.com/u/430608?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Scott Rippey</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap-react/commits?author=scottrippey" title="Code">💻</a> <a href="https://github.com/focus-trap/focus-trap-react/issues?q=author%3Ascottrippey" title="Bug reports">🐛</a></td>
|
|
200
|
-
<td align="center"><a href="https://seanmcp.com/"><img src="https://avatars1.githubusercontent.com/u/6360367?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sean McPherson</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap-react/commits?author=SeanMcP" title="Code">💻</a></td>
|
|
201
201
|
</tr>
|
|
202
202
|
<tr>
|
|
203
|
+
<td align="center"><a href="https://seanmcp.com/"><img src="https://avatars1.githubusercontent.com/u/6360367?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sean McPherson</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap-react/commits?author=SeanMcP" title="Code">💻</a></td>
|
|
203
204
|
<td align="center"><a href="https://recollectr.io"><img src="https://avatars2.githubusercontent.com/u/6835891?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Slapbox</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap-react/commits?author=Slapbox" title="Documentation">📖</a></td>
|
|
204
205
|
<td align="center"><a href="https://stefancameron.com/"><img src="https://avatars3.githubusercontent.com/u/2855350?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Stefan Cameron</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap-react/commits?author=stefcameron" title="Code">💻</a> <a href="https://github.com/focus-trap/focus-trap-react/issues?q=author%3Astefcameron" title="Bug reports">🐛</a> <a href="#infra-stefcameron" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/focus-trap/focus-trap-react/commits?author=stefcameron" title="Tests">⚠️</a> <a href="https://github.com/focus-trap/focus-trap-react/commits?author=stefcameron" title="Documentation">📖</a> <a href="#maintenance-stefcameron" title="Maintenance">🚧</a></td>
|
|
205
206
|
<td align="center"><a href="http://tylerhawkins.info/201R/"><img src="https://avatars0.githubusercontent.com/u/13806458?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tyler Hawkins</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap-react/commits?author=thawkin3" title="Documentation">📖</a> <a href="#example-thawkin3" title="Examples">💡</a> <a href="https://github.com/focus-trap/focus-trap-react/commits?author=thawkin3" title="Tests">⚠️</a> <a href="#tool-thawkin3" title="Tools">🔧</a></td>
|
|
207
|
+
<td align="center"><a href="https://github.com/wandroll"><img src="https://avatars.githubusercontent.com/u/4492317?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Wandrille Verlut</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap-react/commits?author=wandroll" title="Code">💻</a> <a href="https://github.com/focus-trap/focus-trap-react/commits?author=wandroll" title="Tests">⚠️</a></td>
|
|
206
208
|
<td align="center"><a href="https://github.com/krikienoid"><img src="https://avatars3.githubusercontent.com/u/8528227?v=4?s=100" width="100px;" alt=""/><br /><sub><b>krikienoid</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap-react/issues?q=author%3Akrikienoid" title="Bug reports">🐛</a></td>
|
|
209
|
+
<td align="center"><a href="https://github.com/syntactic-salt"><img src="https://avatars.githubusercontent.com/u/9385662?v=4?s=100" width="100px;" alt=""/><br /><sub><b>syntactic-salt</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap-react/issues?q=author%3Asyntactic-salt" title="Bug reports">🐛</a></td>
|
|
207
210
|
</tr>
|
|
208
211
|
</table>
|
|
209
212
|
|
package/dist/focus-trap-react.js
CHANGED
|
@@ -14,7 +14,7 @@ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || func
|
|
|
14
14
|
|
|
15
15
|
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
16
16
|
|
|
17
|
-
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
|
|
17
|
+
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
|
|
18
18
|
|
|
19
19
|
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
20
20
|
|
|
@@ -86,10 +86,23 @@ var FocusTrap = /*#__PURE__*/function (_React$Component) {
|
|
|
86
86
|
_this.updatePreviousElement();
|
|
87
87
|
|
|
88
88
|
return _this;
|
|
89
|
-
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Gets the configured document.
|
|
92
|
+
* @returns {Document|undefined} Configured document, falling back to the main
|
|
93
|
+
* document, if it exists. During SSR, `undefined` is returned since the
|
|
94
|
+
* document doesn't exist.
|
|
95
|
+
*/
|
|
90
96
|
|
|
91
97
|
|
|
92
98
|
_createClass(FocusTrap, [{
|
|
99
|
+
key: "getDocument",
|
|
100
|
+
value: function getDocument() {
|
|
101
|
+
// SSR: careful to check if `document` exists before accessing it as a variable
|
|
102
|
+
return this.props.focusTrapOptions.document || (typeof document !== 'undefined' ? document : undefined);
|
|
103
|
+
} // TODO: Need more test coverage for this function
|
|
104
|
+
|
|
105
|
+
}, {
|
|
93
106
|
key: "getNodeForOption",
|
|
94
107
|
value: function getNodeForOption(optionName) {
|
|
95
108
|
var optionValue = this.tailoredFocusTrapOptions[optionName];
|
|
@@ -101,7 +114,9 @@ var FocusTrap = /*#__PURE__*/function (_React$Component) {
|
|
|
101
114
|
var node = optionValue;
|
|
102
115
|
|
|
103
116
|
if (typeof optionValue === 'string') {
|
|
104
|
-
|
|
117
|
+
var _this$getDocument;
|
|
118
|
+
|
|
119
|
+
node = (_this$getDocument = this.getDocument()) === null || _this$getDocument === void 0 ? void 0 : _this$getDocument.querySelector(optionValue);
|
|
105
120
|
|
|
106
121
|
if (!node) {
|
|
107
122
|
throw new Error("`".concat(optionName, "` refers to no known node"));
|
|
@@ -129,8 +144,10 @@ var FocusTrap = /*#__PURE__*/function (_React$Component) {
|
|
|
129
144
|
}, {
|
|
130
145
|
key: "updatePreviousElement",
|
|
131
146
|
value: function updatePreviousElement() {
|
|
132
|
-
|
|
133
|
-
|
|
147
|
+
var currentDocument = this.getDocument();
|
|
148
|
+
|
|
149
|
+
if (currentDocument) {
|
|
150
|
+
this.previouslyFocusedElement = currentDocument.activeElement;
|
|
134
151
|
}
|
|
135
152
|
}
|
|
136
153
|
}, {
|
|
@@ -138,7 +155,10 @@ var FocusTrap = /*#__PURE__*/function (_React$Component) {
|
|
|
138
155
|
value: function deactivateTrap() {
|
|
139
156
|
var _this2 = this;
|
|
140
157
|
|
|
141
|
-
var
|
|
158
|
+
var _this$tailoredFocusTr = this.tailoredFocusTrapOptions,
|
|
159
|
+
checkCanReturnFocus = _this$tailoredFocusTr.checkCanReturnFocus,
|
|
160
|
+
_this$tailoredFocusTr2 = _this$tailoredFocusTr.preventScroll,
|
|
161
|
+
preventScroll = _this$tailoredFocusTr2 === void 0 ? false : _this$tailoredFocusTr2;
|
|
142
162
|
|
|
143
163
|
if (this.focusTrap) {
|
|
144
164
|
// NOTE: we never let the trap return the focus since we do that ourselves
|
|
@@ -154,7 +174,9 @@ var FocusTrap = /*#__PURE__*/function (_React$Component) {
|
|
|
154
174
|
|
|
155
175
|
if (canReturnFocus) {
|
|
156
176
|
/** Returns focus to the element that had focus when the trap was activated. */
|
|
157
|
-
returnFocusNode.focus(
|
|
177
|
+
returnFocusNode.focus({
|
|
178
|
+
preventScroll: preventScroll
|
|
179
|
+
});
|
|
158
180
|
}
|
|
159
181
|
|
|
160
182
|
if (_this2.onPostDeactivate) {
|
|
@@ -196,7 +218,14 @@ var FocusTrap = /*#__PURE__*/function (_React$Component) {
|
|
|
196
218
|
}, {
|
|
197
219
|
key: "componentDidMount",
|
|
198
220
|
value: function componentDidMount() {
|
|
199
|
-
this.
|
|
221
|
+
if (this.props.active) {
|
|
222
|
+
this.setupFocusTrap();
|
|
223
|
+
} // else, wait for later activation in case the `focusTrapOptions` will be updated
|
|
224
|
+
// again before the trap is activated (e.g. if waiting to know what the document
|
|
225
|
+
// object will be, so the Trap must be rendered, but the consumer is waiting to
|
|
226
|
+
// activate until they have obtained the document from a ref)
|
|
227
|
+
// @see https://github.com/focus-trap/focus-trap-react/issues/539
|
|
228
|
+
|
|
200
229
|
}
|
|
201
230
|
}, {
|
|
202
231
|
key: "componentDidUpdate",
|
|
@@ -228,9 +257,22 @@ var FocusTrap = /*#__PURE__*/function (_React$Component) {
|
|
|
228
257
|
if (hasUnpaused) {
|
|
229
258
|
this.focusTrap.unpause();
|
|
230
259
|
}
|
|
231
|
-
} else
|
|
232
|
-
|
|
233
|
-
|
|
260
|
+
} else {
|
|
261
|
+
// NOTE: if we're in `componentDidUpdate` and we don't have a trap yet,
|
|
262
|
+
// it either means it shouldn't be active, or it should be but none of
|
|
263
|
+
// of given `containerElements` were present in the DOM the last time
|
|
264
|
+
// we tried to create the trap
|
|
265
|
+
if (prevProps.containerElements !== this.props.containerElements) {
|
|
266
|
+
this.focusTrapElements = this.props.containerElements;
|
|
267
|
+
} // don't create the trap unless it should be active in case the consumer
|
|
268
|
+
// is still updating `focusTrapOptions`
|
|
269
|
+
// @see https://github.com/focus-trap/focus-trap-react/issues/539
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
if (this.props.active) {
|
|
273
|
+
this.updatePreviousElement();
|
|
274
|
+
this.setupFocusTrap();
|
|
275
|
+
}
|
|
234
276
|
}
|
|
235
277
|
}
|
|
236
278
|
}, {
|
|
@@ -283,6 +325,7 @@ FocusTrap.propTypes = {
|
|
|
283
325
|
active: PropTypes.bool,
|
|
284
326
|
paused: PropTypes.bool,
|
|
285
327
|
focusTrapOptions: PropTypes.shape({
|
|
328
|
+
document: PropTypes.object,
|
|
286
329
|
onActivate: PropTypes.func,
|
|
287
330
|
onPostActivate: PropTypes.func,
|
|
288
331
|
checkCanFocusTrap: PropTypes.func,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "focus-trap-react",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.9.0",
|
|
4
4
|
"description": "A React component that traps focus.",
|
|
5
5
|
"main": "dist/focus-trap-react.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -55,43 +55,43 @@
|
|
|
55
55
|
},
|
|
56
56
|
"homepage": "https://github.com/focus-trap/focus-trap-react#readme",
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@babel/cli": "^7.
|
|
59
|
-
"@babel/core": "^7.
|
|
60
|
-
"@babel/
|
|
61
|
-
"@babel/
|
|
62
|
-
"@babel/preset-
|
|
63
|
-
"@
|
|
64
|
-
"@
|
|
65
|
-
"@testing-library/
|
|
66
|
-
"@testing-library/
|
|
67
|
-
"@testing-library/
|
|
68
|
-
"@testing-library/
|
|
69
|
-
"@
|
|
58
|
+
"@babel/cli": "^7.16.0",
|
|
59
|
+
"@babel/core": "^7.16.0",
|
|
60
|
+
"@babel/eslint-parser": "^7.16.3",
|
|
61
|
+
"@babel/plugin-proposal-class-properties": "^7.16.0",
|
|
62
|
+
"@babel/preset-env": "^7.16.4",
|
|
63
|
+
"@babel/preset-react": "^7.16.0",
|
|
64
|
+
"@changesets/cli": "^2.18.1",
|
|
65
|
+
"@testing-library/cypress": "^8.0.2",
|
|
66
|
+
"@testing-library/dom": "^8.11.1",
|
|
67
|
+
"@testing-library/jest-dom": "^5.16.1",
|
|
68
|
+
"@testing-library/react": "^12.1.2",
|
|
69
|
+
"@testing-library/user-event": "^13.5.0",
|
|
70
|
+
"@types/jquery": "^3.5.9",
|
|
70
71
|
"all-contributors-cli": "^6.20.0",
|
|
71
|
-
"babel-
|
|
72
|
-
"babel-jest": "^27.0.6",
|
|
72
|
+
"babel-jest": "^27.4.2",
|
|
73
73
|
"babelify": "^10.0.0",
|
|
74
74
|
"browserify": "^17.0.0",
|
|
75
75
|
"budo": "^11.6.4",
|
|
76
|
-
"cypress": "^
|
|
76
|
+
"cypress": "^9.1.1",
|
|
77
77
|
"cypress-plugin-tab": "^1.0.5",
|
|
78
|
-
"eslint": "^
|
|
78
|
+
"eslint": "^8.4.1",
|
|
79
79
|
"eslint-config-prettier": "^8.3.0",
|
|
80
|
-
"eslint-plugin-cypress": "^2.
|
|
81
|
-
"eslint-plugin-react": "^7.
|
|
82
|
-
"jest": "^27.
|
|
83
|
-
"jest-watch-typeahead": "^0.
|
|
80
|
+
"eslint-plugin-cypress": "^2.12.1",
|
|
81
|
+
"eslint-plugin-react": "^7.27.1",
|
|
82
|
+
"jest": "^27.4.3",
|
|
83
|
+
"jest-watch-typeahead": "^1.0.0",
|
|
84
84
|
"onchange": "^7.1.0",
|
|
85
|
-
"prettier": "^2.
|
|
85
|
+
"prettier": "^2.5.1",
|
|
86
86
|
"prop-types": "^15.7.2",
|
|
87
87
|
"react": "^17.0.2",
|
|
88
88
|
"react-dom": "^17.0.2",
|
|
89
89
|
"regenerator-runtime": "^0.13.9",
|
|
90
|
-
"start-server-and-test": "^1.
|
|
91
|
-
"typescript": "^4.
|
|
90
|
+
"start-server-and-test": "^1.14.0",
|
|
91
|
+
"typescript": "^4.5.2"
|
|
92
92
|
},
|
|
93
93
|
"dependencies": {
|
|
94
|
-
"focus-trap": "^6.
|
|
94
|
+
"focus-trap": "^6.7.1"
|
|
95
95
|
},
|
|
96
96
|
"peerDependencies": {
|
|
97
97
|
"prop-types": "^15.7.2",
|
package/src/focus-trap-react.js
CHANGED
|
@@ -53,6 +53,20 @@ class FocusTrap extends React.Component {
|
|
|
53
53
|
this.updatePreviousElement();
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Gets the configured document.
|
|
58
|
+
* @returns {Document|undefined} Configured document, falling back to the main
|
|
59
|
+
* document, if it exists. During SSR, `undefined` is returned since the
|
|
60
|
+
* document doesn't exist.
|
|
61
|
+
*/
|
|
62
|
+
getDocument() {
|
|
63
|
+
// SSR: careful to check if `document` exists before accessing it as a variable
|
|
64
|
+
return (
|
|
65
|
+
this.props.focusTrapOptions.document ||
|
|
66
|
+
(typeof document !== 'undefined' ? document : undefined)
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
56
70
|
// TODO: Need more test coverage for this function
|
|
57
71
|
getNodeForOption(optionName) {
|
|
58
72
|
const optionValue = this.tailoredFocusTrapOptions[optionName];
|
|
@@ -63,7 +77,7 @@ class FocusTrap extends React.Component {
|
|
|
63
77
|
let node = optionValue;
|
|
64
78
|
|
|
65
79
|
if (typeof optionValue === 'string') {
|
|
66
|
-
node =
|
|
80
|
+
node = this.getDocument()?.querySelector(optionValue);
|
|
67
81
|
if (!node) {
|
|
68
82
|
throw new Error(`\`${optionName}\` refers to no known node`);
|
|
69
83
|
}
|
|
@@ -87,13 +101,15 @@ class FocusTrap extends React.Component {
|
|
|
87
101
|
|
|
88
102
|
/** Update the previously focused element with the currently focused element. */
|
|
89
103
|
updatePreviousElement() {
|
|
90
|
-
|
|
91
|
-
|
|
104
|
+
const currentDocument = this.getDocument();
|
|
105
|
+
if (currentDocument) {
|
|
106
|
+
this.previouslyFocusedElement = currentDocument.activeElement;
|
|
92
107
|
}
|
|
93
108
|
}
|
|
94
109
|
|
|
95
110
|
deactivateTrap() {
|
|
96
|
-
const { checkCanReturnFocus } =
|
|
111
|
+
const { checkCanReturnFocus, preventScroll = false } =
|
|
112
|
+
this.tailoredFocusTrapOptions;
|
|
97
113
|
|
|
98
114
|
if (this.focusTrap) {
|
|
99
115
|
// NOTE: we never let the trap return the focus since we do that ourselves
|
|
@@ -107,7 +123,9 @@ class FocusTrap extends React.Component {
|
|
|
107
123
|
|
|
108
124
|
if (canReturnFocus) {
|
|
109
125
|
/** Returns focus to the element that had focus when the trap was activated. */
|
|
110
|
-
returnFocusNode.focus(
|
|
126
|
+
returnFocusNode.focus({
|
|
127
|
+
preventScroll,
|
|
128
|
+
});
|
|
111
129
|
}
|
|
112
130
|
|
|
113
131
|
if (this.onPostDeactivate) {
|
|
@@ -154,7 +172,14 @@ class FocusTrap extends React.Component {
|
|
|
154
172
|
}
|
|
155
173
|
|
|
156
174
|
componentDidMount() {
|
|
157
|
-
this.
|
|
175
|
+
if (this.props.active) {
|
|
176
|
+
this.setupFocusTrap();
|
|
177
|
+
}
|
|
178
|
+
// else, wait for later activation in case the `focusTrapOptions` will be updated
|
|
179
|
+
// again before the trap is activated (e.g. if waiting to know what the document
|
|
180
|
+
// object will be, so the Trap must be rendered, but the consumer is waiting to
|
|
181
|
+
// activate until they have obtained the document from a ref)
|
|
182
|
+
// @see https://github.com/focus-trap/focus-trap-react/issues/539
|
|
158
183
|
}
|
|
159
184
|
|
|
160
185
|
componentDidUpdate(prevProps) {
|
|
@@ -185,9 +210,23 @@ class FocusTrap extends React.Component {
|
|
|
185
210
|
if (hasUnpaused) {
|
|
186
211
|
this.focusTrap.unpause();
|
|
187
212
|
}
|
|
188
|
-
} else
|
|
189
|
-
|
|
190
|
-
|
|
213
|
+
} else {
|
|
214
|
+
// NOTE: if we're in `componentDidUpdate` and we don't have a trap yet,
|
|
215
|
+
// it either means it shouldn't be active, or it should be but none of
|
|
216
|
+
// of given `containerElements` were present in the DOM the last time
|
|
217
|
+
// we tried to create the trap
|
|
218
|
+
|
|
219
|
+
if (prevProps.containerElements !== this.props.containerElements) {
|
|
220
|
+
this.focusTrapElements = this.props.containerElements;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// don't create the trap unless it should be active in case the consumer
|
|
224
|
+
// is still updating `focusTrapOptions`
|
|
225
|
+
// @see https://github.com/focus-trap/focus-trap-react/issues/539
|
|
226
|
+
if (this.props.active) {
|
|
227
|
+
this.updatePreviousElement();
|
|
228
|
+
this.setupFocusTrap();
|
|
229
|
+
}
|
|
191
230
|
}
|
|
192
231
|
}
|
|
193
232
|
|
|
@@ -241,6 +280,7 @@ FocusTrap.propTypes = {
|
|
|
241
280
|
active: PropTypes.bool,
|
|
242
281
|
paused: PropTypes.bool,
|
|
243
282
|
focusTrapOptions: PropTypes.shape({
|
|
283
|
+
document: PropTypes.object,
|
|
244
284
|
onActivate: PropTypes.func,
|
|
245
285
|
onPostActivate: PropTypes.func,
|
|
246
286
|
checkCanFocusTrap: PropTypes.func,
|