focus-trap-react 9.0.1 → 9.0.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 +6 -0
- package/README.md +4 -3
- package/dist/focus-trap-react.js +23 -1
- package/package.json +13 -13
- package/src/focus-trap-react.js +22 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 9.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4d8e041: Fix an issue when running in strict mode which has React immediately unmount/remount the trap, causing it to deactivate and then have to reactivate (per existing component state) on the remount. [#720](https://github.com/focus-trap/focus-trap-react/issues/720)
|
|
8
|
+
|
|
3
9
|
## 9.0.1
|
|
4
10
|
|
|
5
11
|
### 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.
|
|
@@ -214,19 +214,20 @@ In alphabetical order:
|
|
|
214
214
|
<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>
|
|
215
215
|
<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>
|
|
216
216
|
<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>
|
|
217
|
+
<td align="center"><a href="https://www.moroshko.me"><img src="https://avatars.githubusercontent.com/u/259753?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Misha Moroshko</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap-react/issues?q=author%3Amoroshko" title="Bug reports">🐛</a></td>
|
|
217
218
|
<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>
|
|
218
|
-
<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>
|
|
219
219
|
</tr>
|
|
220
220
|
<tr>
|
|
221
|
+
<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>
|
|
221
222
|
<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>
|
|
222
223
|
<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>
|
|
223
224
|
<td align="center"><a href="http://smoores.dev"><img src="https://avatars.githubusercontent.com/u/5354254?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Shane Moore</b></sub></a><br /><a href="#platform-SMores" title="Packaging/porting to new platform">📦</a></td>
|
|
224
225
|
<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> <a href="https://github.com/focus-trap/focus-trap-react/issues?q=author%3ASlapbox" title="Bug reports">🐛</a></td>
|
|
225
226
|
<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>
|
|
226
227
|
<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>
|
|
227
|
-
<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>
|
|
228
228
|
</tr>
|
|
229
229
|
<tr>
|
|
230
|
+
<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>
|
|
230
231
|
<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>
|
|
231
232
|
<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>
|
|
232
233
|
</tr>
|
package/dist/focus-trap-react.js
CHANGED
|
@@ -299,7 +299,28 @@ var FocusTrap = /*#__PURE__*/function (_React$Component) {
|
|
|
299
299
|
}, {
|
|
300
300
|
key: "setupFocusTrap",
|
|
301
301
|
value: function setupFocusTrap() {
|
|
302
|
-
if (
|
|
302
|
+
if (this.focusTrap) {
|
|
303
|
+
// trap already exists: it's possible we're in StrictMode and we're being remounted,
|
|
304
|
+
// in which case, we will have deactivated the trap when we got unmounted (remember,
|
|
305
|
+
// StrictMode, in development, purposely unmounts and remounts components after
|
|
306
|
+
// mounting them the first time to make sure they have reusable state,
|
|
307
|
+
// @see https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state) so now
|
|
308
|
+
// we need to restore the state of the trap according to our component state
|
|
309
|
+
// NOTE: Strict mode __violates__ assumptions about the `componentWillUnmount()` API
|
|
310
|
+
// which clearly states -- even for React 18 -- that, "Once a component instance is
|
|
311
|
+
// unmounted, __it will never be mounted again.__" (emphasis ours). So when we get
|
|
312
|
+
// unmounted, we assume we're gone forever and we deactivate the trap. But then
|
|
313
|
+
// we get remounted and we're supposed to restore state. But if you had paused,
|
|
314
|
+
// we've now deactivated (we don't know we're amount to get remounted again)
|
|
315
|
+
// which means we need to reactivate and then pause. Otherwise, do nothing.
|
|
316
|
+
if (this.props.active && !this.focusTrap.active) {
|
|
317
|
+
this.focusTrap.activate();
|
|
318
|
+
|
|
319
|
+
if (this.props.paused) {
|
|
320
|
+
this.focusTrap.pause();
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
} else {
|
|
303
324
|
var nodesExist = this.focusTrapElements.some(Boolean);
|
|
304
325
|
|
|
305
326
|
if (nodesExist) {
|
|
@@ -448,6 +469,7 @@ FocusTrap.propTypes = {
|
|
|
448
469
|
})
|
|
449
470
|
}),
|
|
450
471
|
containerElements: PropTypes.arrayOf(PropTypes.instanceOf(ElementType)),
|
|
472
|
+
// DOM element ONLY
|
|
451
473
|
children: PropTypes.oneOfType([PropTypes.element, // React element
|
|
452
474
|
PropTypes.instanceOf(ElementType) // DOM element
|
|
453
475
|
]) // NOTE: _createFocusTrap is internal, for testing purposes only, so we don't
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "focus-trap-react",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.2",
|
|
4
4
|
"description": "A React component that traps focus.",
|
|
5
5
|
"main": "dist/focus-trap-react.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"index.d.ts"
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
|
-
"demo-bundle": "browserify demo/js -t babelify --extension=.jsx -o demo/demo-bundle.js",
|
|
18
|
-
"start": "yarn build && budo demo/js/index.js:demo-bundle.js --dir demo --live -- -t babelify --extension=.jsx",
|
|
17
|
+
"demo-bundle": "NODE_ENV=production browserify demo/js -t babelify --extension=.jsx -o demo/demo-bundle.js",
|
|
18
|
+
"start": "yarn build && NODE_ENV=development budo demo/js/index.js:demo-bundle.js --dir demo --live -- -t babelify --extension=.jsx",
|
|
19
19
|
"lint": "eslint \"*.js\" \"src/**/*.js\" \"test/**/*.js\" \"demo/**/*.js\" \"cypress/**/*.js\"",
|
|
20
20
|
"format": "prettier --write \"{*,src/**/*,test/**/*,demo/js/**/*,.github/workflows/*,cypress/**/*}.+(js|yml)\"",
|
|
21
21
|
"format:check": "prettier --check \"{*,src/**/*,test/**/*,demo/js/**/*,.github/workflows/*,cypress/**/*}.+(js|yml)\"",
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
"test:types": "tsc index.d.ts",
|
|
25
25
|
"test:unit": "jest",
|
|
26
26
|
"test:coverage": "jest --coverage",
|
|
27
|
-
"test:
|
|
28
|
-
"test:
|
|
29
|
-
"test:
|
|
30
|
-
"test": "yarn format:check && yarn lint && yarn test:unit && yarn test:types &&
|
|
27
|
+
"test:e2e": "ELECTRON_ENABLE_LOGGING=1 start-server-and-test start 9966 'cypress run --browser $CYPRESS_BROWSER --headless'",
|
|
28
|
+
"test:e2e:chrome": "CYPRESS_BROWSER=chrome yarn test:e2e",
|
|
29
|
+
"test:e2e:dev": "ELECTRON_ENABLE_LOGGING=1 start-server-and-test start 9966 'cypress open --browser --e2e'",
|
|
30
|
+
"test": "yarn format:check && yarn lint && yarn test:unit && yarn test:types && yarn test:e2e:chrome",
|
|
31
31
|
"prepare": "yarn build",
|
|
32
32
|
"prepublishOnly": "yarn test && yarn build",
|
|
33
33
|
"release": "yarn build && changeset publish"
|
|
@@ -58,12 +58,12 @@
|
|
|
58
58
|
"homepage": "https://github.com/focus-trap/focus-trap-react#readme",
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@babel/cli": "^7.17.10",
|
|
61
|
-
"@babel/core": "^7.18.
|
|
61
|
+
"@babel/core": "^7.18.5",
|
|
62
62
|
"@babel/eslint-parser": "^7.18.2",
|
|
63
63
|
"@babel/plugin-proposal-class-properties": "^7.17.12",
|
|
64
64
|
"@babel/preset-env": "^7.18.2",
|
|
65
65
|
"@babel/preset-react": "^7.17.12",
|
|
66
|
-
"@changesets/cli": "^2.
|
|
66
|
+
"@changesets/cli": "^2.23.0",
|
|
67
67
|
"@testing-library/cypress": "^8.0.3",
|
|
68
68
|
"@testing-library/dom": "^8.13.0",
|
|
69
69
|
"@testing-library/jest-dom": "^5.16.4",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"babelify": "^10.0.0",
|
|
76
76
|
"browserify": "^17.0.0",
|
|
77
77
|
"budo": "^11.7.0",
|
|
78
|
-
"cypress": "^
|
|
78
|
+
"cypress": "^10.1.0",
|
|
79
79
|
"cypress-plugin-tab": "^1.0.5",
|
|
80
80
|
"eslint": "^8.17.0",
|
|
81
81
|
"eslint-config-prettier": "^8.5.0",
|
|
@@ -86,10 +86,10 @@
|
|
|
86
86
|
"jest-environment-jsdom": "^28.1.1",
|
|
87
87
|
"jest-watch-typeahead": "^1.1.0",
|
|
88
88
|
"onchange": "^7.1.0",
|
|
89
|
-
"prettier": "^2.
|
|
89
|
+
"prettier": "^2.7.0",
|
|
90
90
|
"prop-types": "^15.8.1",
|
|
91
|
-
"react": "^18.
|
|
92
|
-
"react-dom": "^18.
|
|
91
|
+
"react": "^18.2.0",
|
|
92
|
+
"react-dom": "^18.2.0",
|
|
93
93
|
"regenerator-runtime": "^0.13.9",
|
|
94
94
|
"start-server-and-test": "^1.14.0",
|
|
95
95
|
"typescript": "^4.7.3"
|
package/src/focus-trap-react.js
CHANGED
|
@@ -270,7 +270,27 @@ class FocusTrap extends React.Component {
|
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
setupFocusTrap() {
|
|
273
|
-
if (
|
|
273
|
+
if (this.focusTrap) {
|
|
274
|
+
// trap already exists: it's possible we're in StrictMode and we're being remounted,
|
|
275
|
+
// in which case, we will have deactivated the trap when we got unmounted (remember,
|
|
276
|
+
// StrictMode, in development, purposely unmounts and remounts components after
|
|
277
|
+
// mounting them the first time to make sure they have reusable state,
|
|
278
|
+
// @see https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state) so now
|
|
279
|
+
// we need to restore the state of the trap according to our component state
|
|
280
|
+
// NOTE: Strict mode __violates__ assumptions about the `componentWillUnmount()` API
|
|
281
|
+
// which clearly states -- even for React 18 -- that, "Once a component instance is
|
|
282
|
+
// unmounted, __it will never be mounted again.__" (emphasis ours). So when we get
|
|
283
|
+
// unmounted, we assume we're gone forever and we deactivate the trap. But then
|
|
284
|
+
// we get remounted and we're supposed to restore state. But if you had paused,
|
|
285
|
+
// we've now deactivated (we don't know we're amount to get remounted again)
|
|
286
|
+
// which means we need to reactivate and then pause. Otherwise, do nothing.
|
|
287
|
+
if (this.props.active && !this.focusTrap.active) {
|
|
288
|
+
this.focusTrap.activate();
|
|
289
|
+
if (this.props.paused) {
|
|
290
|
+
this.focusTrap.pause();
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
} else {
|
|
274
294
|
const nodesExist = this.focusTrapElements.some(Boolean);
|
|
275
295
|
if (nodesExist) {
|
|
276
296
|
// eslint-disable-next-line react/prop-types -- _createFocusTrap is an internal prop
|
|
@@ -437,7 +457,7 @@ FocusTrap.propTypes = {
|
|
|
437
457
|
getShadowRoot: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
|
|
438
458
|
}),
|
|
439
459
|
}),
|
|
440
|
-
containerElements: PropTypes.arrayOf(PropTypes.instanceOf(ElementType)),
|
|
460
|
+
containerElements: PropTypes.arrayOf(PropTypes.instanceOf(ElementType)), // DOM element ONLY
|
|
441
461
|
children: PropTypes.oneOfType([
|
|
442
462
|
PropTypes.element, // React element
|
|
443
463
|
PropTypes.instanceOf(ElementType), // DOM element
|