focus-trap-react 8.8.1 → 8.9.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 CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## 8.9.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 83e283c: Update focus-trap to v6.7.3 for bug fix related to elements with a negative `tabindex`.
8
+
9
+ ## 8.9.1
10
+
11
+ ### Patch Changes
12
+
13
+ - 3eb9421: Bump focus-trap to v6.7.2 for bug fix.
14
+
15
+ ## 8.9.0
16
+
17
+ ### Minor Changes
18
+
19
+ - 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)
20
+
21
+ ### Patch Changes
22
+
23
+ - 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)
24
+
25
+ ## 8.8.2
26
+
27
+ ### Patch Changes
28
+
29
+ - 08a9449: Use `preventScroll` option on deactivation if returning focus.
30
+
3
31
  ## 8.8.1
4
32
 
5
33
  ### Patch Changes
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # focus-trap-react [![CI](https://github.com/focus-trap/focus-trap-react/workflows/CI/badge.svg?branch=master&event=push)](https://github.com/focus-trap/focus-trap-react/actions?query=workflow:CI+branch:master) [![Codecov](https://img.shields.io/codecov/c/github/focus-trap/focus-trap-react)](https://codecov.io/gh/focus-trap/focus-trap-react) [![license](https://badgen.now.sh/badge/license/MIT)](./LICENSE)
2
2
 
3
3
  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
4
- [![All Contributors](https://img.shields.io/badge/all_contributors-20-orange.svg?style=flat-square)](#contributors)
4
+ [![All Contributors](https://img.shields.io/badge/all_contributors-22-orange.svg?style=flat-square)](#contributors)
5
5
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
6
6
 
7
7
  A React component that traps focus.
@@ -191,20 +191,24 @@ 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>
197
+ <td align="center"><a href="https://github.com/LoganDark"><img src="https://avatars.githubusercontent.com/u/4723091?v=4?s=100" width="100px;" alt=""/><br /><sub><b>LoganDark</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap-react/issues?q=author%3ALoganDark" title="Bug reports">🐛</a></td>
196
198
  <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
199
  <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
200
  <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
- <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://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>
204
+ <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
205
  <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
206
  <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
207
  <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>
206
208
  <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>
207
209
  <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>
210
+ </tr>
211
+ <tr>
208
212
  <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>
209
213
  </tr>
210
214
  </table>
@@ -1,14 +1,14 @@
1
1
  "use strict";
2
2
 
3
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
3
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
4
4
 
5
5
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6
6
 
7
7
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
8
8
 
9
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
9
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
10
10
 
11
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
11
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
12
12
 
13
13
  function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
14
14
 
@@ -86,10 +86,23 @@ var FocusTrap = /*#__PURE__*/function (_React$Component) {
86
86
  _this.updatePreviousElement();
87
87
 
88
88
  return _this;
89
- } // TODO: Need more test coverage for this function
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
- node = document.querySelector(optionValue);
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,7 @@ var FocusTrap = /*#__PURE__*/function (_React$Component) {
129
144
  }, {
130
145
  key: "updatePreviousElement",
131
146
  value: function updatePreviousElement() {
132
- // SSR: careful to check if `document` exists before accessing it as a variable
133
- var currentDocument = this.props.focusTrapOptions.document || (typeof document !== 'undefined' ? document : undefined);
147
+ var currentDocument = this.getDocument();
134
148
 
135
149
  if (currentDocument) {
136
150
  this.previouslyFocusedElement = currentDocument.activeElement;
@@ -141,7 +155,10 @@ var FocusTrap = /*#__PURE__*/function (_React$Component) {
141
155
  value: function deactivateTrap() {
142
156
  var _this2 = this;
143
157
 
144
- var checkCanReturnFocus = this.tailoredFocusTrapOptions.checkCanReturnFocus;
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;
145
162
 
146
163
  if (this.focusTrap) {
147
164
  // NOTE: we never let the trap return the focus since we do that ourselves
@@ -157,7 +174,9 @@ var FocusTrap = /*#__PURE__*/function (_React$Component) {
157
174
 
158
175
  if (canReturnFocus) {
159
176
  /** Returns focus to the element that had focus when the trap was activated. */
160
- returnFocusNode.focus();
177
+ returnFocusNode.focus({
178
+ preventScroll: preventScroll
179
+ });
161
180
  }
162
181
 
163
182
  if (_this2.onPostDeactivate) {
@@ -199,7 +218,14 @@ var FocusTrap = /*#__PURE__*/function (_React$Component) {
199
218
  }, {
200
219
  key: "componentDidMount",
201
220
  value: function componentDidMount() {
202
- this.setupFocusTrap();
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
+
203
229
  }
204
230
  }, {
205
231
  key: "componentDidUpdate",
@@ -231,9 +257,22 @@ var FocusTrap = /*#__PURE__*/function (_React$Component) {
231
257
  if (hasUnpaused) {
232
258
  this.focusTrap.unpause();
233
259
  }
234
- } else if (prevProps.containerElements !== this.props.containerElements) {
235
- this.focusTrapElements = this.props.containerElements;
236
- this.setupFocusTrap();
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
+ }
237
276
  }
238
277
  }
239
278
  }, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "focus-trap-react",
3
- "version": "8.8.1",
3
+ "version": "8.9.2",
4
4
  "description": "A React component that traps focus.",
5
5
  "main": "dist/focus-trap-react.js",
6
6
  "types": "index.d.ts",
@@ -55,46 +55,46 @@
55
55
  },
56
56
  "homepage": "https://github.com/focus-trap/focus-trap-react#readme",
57
57
  "devDependencies": {
58
- "@babel/cli": "^7.15.7",
59
- "@babel/core": "^7.15.5",
60
- "@babel/plugin-proposal-class-properties": "^7.12.13",
61
- "@babel/preset-env": "^7.15.6",
62
- "@babel/preset-react": "^7.14.5",
63
- "@changesets/cli": "^2.17.0",
64
- "@testing-library/cypress": "^8.0.1",
65
- "@testing-library/dom": "^8.5.0",
66
- "@testing-library/jest-dom": "^5.14.1",
67
- "@testing-library/react": "^12.1.0",
68
- "@testing-library/user-event": "^13.2.1",
69
- "@types/jquery": "^3.5.6",
58
+ "@babel/cli": "^7.17.0",
59
+ "@babel/core": "^7.17.2",
60
+ "@babel/eslint-parser": "^7.17.0",
61
+ "@babel/plugin-proposal-class-properties": "^7.16.5",
62
+ "@babel/preset-env": "^7.16.11",
63
+ "@babel/preset-react": "^7.16.7",
64
+ "@changesets/cli": "^2.20.0",
65
+ "@testing-library/cypress": "^8.0.2",
66
+ "@testing-library/dom": "^8.11.3",
67
+ "@testing-library/jest-dom": "^5.16.2",
68
+ "@testing-library/react": "^12.1.2",
69
+ "@testing-library/user-event": "^13.5.0",
70
+ "@types/jquery": "^3.5.13",
70
71
  "all-contributors-cli": "^6.20.0",
71
- "babel-eslint": "^10.1.0",
72
- "babel-jest": "^27.2.1",
72
+ "babel-jest": "^27.5.1",
73
73
  "babelify": "^10.0.0",
74
74
  "browserify": "^17.0.0",
75
75
  "budo": "^11.6.4",
76
- "cypress": "^8.4.1",
76
+ "cypress": "^9.4.1",
77
77
  "cypress-plugin-tab": "^1.0.5",
78
- "eslint": "^7.32.0",
78
+ "eslint": "^8.8.0",
79
79
  "eslint-config-prettier": "^8.3.0",
80
80
  "eslint-plugin-cypress": "^2.12.1",
81
- "eslint-plugin-react": "^7.26.0",
82
- "jest": "^27.2.1",
83
- "jest-watch-typeahead": "^0.6.4",
81
+ "eslint-plugin-react": "^7.28.0",
82
+ "jest": "^27.5.1",
83
+ "jest-watch-typeahead": "^1.0.0",
84
84
  "onchange": "^7.1.0",
85
- "prettier": "^2.4.1",
86
- "prop-types": "^15.7.2",
85
+ "prettier": "^2.5.1",
86
+ "prop-types": "^15.8.1",
87
87
  "react": "^17.0.2",
88
88
  "react-dom": "^17.0.2",
89
89
  "regenerator-runtime": "^0.13.9",
90
90
  "start-server-and-test": "^1.14.0",
91
- "typescript": "^4.4.3"
91
+ "typescript": "^4.5.5"
92
92
  },
93
93
  "dependencies": {
94
- "focus-trap": "^6.7.1"
94
+ "focus-trap": "^6.7.3"
95
95
  },
96
96
  "peerDependencies": {
97
- "prop-types": "^15.7.2",
97
+ "prop-types": "^15.8.1",
98
98
  "react": ">=16.0.0",
99
99
  "react-dom": ">=16.0.0"
100
100
  }
@@ -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 = document.querySelector(optionValue);
80
+ node = this.getDocument()?.querySelector(optionValue);
67
81
  if (!node) {
68
82
  throw new Error(`\`${optionName}\` refers to no known node`);
69
83
  }
@@ -87,17 +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
- // SSR: careful to check if `document` exists before accessing it as a variable
91
- const currentDocument =
92
- this.props.focusTrapOptions.document ||
93
- (typeof document !== 'undefined' ? document : undefined);
104
+ const currentDocument = this.getDocument();
94
105
  if (currentDocument) {
95
106
  this.previouslyFocusedElement = currentDocument.activeElement;
96
107
  }
97
108
  }
98
109
 
99
110
  deactivateTrap() {
100
- const { checkCanReturnFocus } = this.tailoredFocusTrapOptions;
111
+ const { checkCanReturnFocus, preventScroll = false } =
112
+ this.tailoredFocusTrapOptions;
101
113
 
102
114
  if (this.focusTrap) {
103
115
  // NOTE: we never let the trap return the focus since we do that ourselves
@@ -111,7 +123,9 @@ class FocusTrap extends React.Component {
111
123
 
112
124
  if (canReturnFocus) {
113
125
  /** Returns focus to the element that had focus when the trap was activated. */
114
- returnFocusNode.focus();
126
+ returnFocusNode.focus({
127
+ preventScroll,
128
+ });
115
129
  }
116
130
 
117
131
  if (this.onPostDeactivate) {
@@ -158,7 +172,14 @@ class FocusTrap extends React.Component {
158
172
  }
159
173
 
160
174
  componentDidMount() {
161
- this.setupFocusTrap();
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
162
183
  }
163
184
 
164
185
  componentDidUpdate(prevProps) {
@@ -189,9 +210,23 @@ class FocusTrap extends React.Component {
189
210
  if (hasUnpaused) {
190
211
  this.focusTrap.unpause();
191
212
  }
192
- } else if (prevProps.containerElements !== this.props.containerElements) {
193
- this.focusTrapElements = this.props.containerElements;
194
- this.setupFocusTrap();
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
+ }
195
230
  }
196
231
  }
197
232