focus-trap 7.5.4 β 7.6.1
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 +12 -0
- package/README.md +24 -6
- package/dist/focus-trap.esm.js +112 -70
- package/dist/focus-trap.esm.js.map +1 -1
- package/dist/focus-trap.esm.min.js +2 -2
- package/dist/focus-trap.esm.min.js.map +1 -1
- package/dist/focus-trap.js +112 -72
- package/dist/focus-trap.js.map +1 -1
- package/dist/focus-trap.min.js +2 -2
- package/dist/focus-trap.min.js.map +1 -1
- package/dist/focus-trap.umd.js +112 -72
- package/dist/focus-trap.umd.js.map +1 -1
- package/dist/focus-trap.umd.min.js +2 -2
- package/dist/focus-trap.umd.min.js.map +1 -1
- package/index.js +52 -20
- package/package.json +22 -23
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 7.6.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- fc5910d: Fix fallbackFocus not used when initialFocus is selector to non-existent node ([#1218](https://github.com/focus-trap/focus-trap/issues/1218))
|
|
8
|
+
|
|
9
|
+
## 7.6.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 8aeacee: Move `Escape` key handler to target phase to allow more control in `escapeDeactivates` ([#1247](https://github.com/focus-trap/focus-trap/issues/1247))
|
|
14
|
+
|
|
3
15
|
## 7.5.4
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# focus-trap [](https://github.com/focus-trap/focus-trap/actions?query=workflow:CI+branch:master) [](./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
|
Trap focus within a DOM node.
|
|
@@ -101,9 +101,12 @@ Returns a new focus trap on `element` (one or more "containers" of tabbable node
|
|
|
101
101
|
- **onDeactivate** `{() => void}`: A function that will be called **before** returning focus to the node that had focus prior to activation (or configured with the `setReturnFocus` option) upon deactivation.
|
|
102
102
|
- **onPostDeactivate** `{() => void}`: A function that will be called after the trap is deactivated, after `onDeactivate`. If the `returnFocus` deactivation option was set, it will be called **after** returning focus to the node that had focus prior to activation (or configured with the `setReturnFocus` option) upon deactivation; otherwise, it will be called after deactivation completes.
|
|
103
103
|
- **checkCanReturnFocus** `{(trigger: HTMLElement | SVGElement) => Promise<void>}`: An animated trigger button will have a small delay between when `onDeactivate` is called and when the focus is able to be sent back to the trigger. `checkCanReturnFocus` expects a promise to be returned. When that promise settles (resolves or rejects), focus will be sent to to the node that had focus prior to the activation of the trap (or the node configured in the `setReturnFocus` option).
|
|
104
|
-
- **initialFocus** `{HTMLElement | SVGElement | string | false | undefined | (() => HTMLElement | SVGElement | string | false | undefined)}`: By default, when a focus trap is activated the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus. Can be a DOM node, or a selector string (which will be passed to `document.querySelector()` to find the DOM node), or a function that returns any of these. You can also set this option to `false` (or to a function that returns `false`) to prevent any initial focus at all when the trap activates.
|
|
104
|
+
- **initialFocus** `{HTMLElement | SVGElement | string | false | undefined | (() => HTMLElement | SVGElement | string | false | undefined)}`: By default (when `undefined` or the function returns `undefined`), when a focus trap is activated, the active element will receive focus if it's in the trap, otherwise, the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus. Can be a DOM node, or a selector string (which will be passed to `document.querySelector()` to find the DOM node), or a function that returns any of these. You can also set this option to `false` (or to a function that returns `false`) to prevent any initial focus at all when the trap activates.
|
|
105
105
|
- π¬ Setting this option to `false` (or a function that returns `false`) will prevent the `fallbackFocus` option from being used.
|
|
106
|
-
-
|
|
106
|
+
- π¬ If the option resolves to a non-focusable node (e.g. one that exists, but is hidden), the default behavior will be used (as though the option weren't set at all).
|
|
107
|
+
- π¬ If the option resolves to a non-existent node, an exception will be thrown.
|
|
108
|
+
- π¬ If the option resolves to a valid selector string (directly set, or returned from a function), but the selector doesn't match a node, the trap will fall back to the `fallbackFocus` node option. If that option also fails to yield a node, an exception will be thrown.
|
|
109
|
+
- π¬ If the option resolves to `undefined` (i.e. not set or function returns `undefined`), the default behavior will be used.
|
|
107
110
|
- β οΈ See warning below about **Shadow DOM** and selector strings.
|
|
108
111
|
- **fallbackFocus** `{HTMLElement | SVGElement | string | () => HTMLElement | SVGElement | string}`: By default, an error will be thrown if the focus trap contains no elements in its tab order. With this option you can specify a fallback element to programmatically receive focus if no other tabbable elements are found. For example, you may want a popover's `<div>` to receive focus if the popover's content includes no tabbable elements. *Make sure the fallback element has a negative `tabindex` so it can be programmatically focused.* The option value can be a DOM node, a selector string (which will be passed to `document.querySelector()` to find the DOM node), or a function that returns any of these.
|
|
109
112
|
- π¬ If `initialFocus` is `false` (or a function that returns `false`), this function will not be called when the trap is activated, and no element will be initially focused. This function may still be called while the trap is active if things change such that there are no longer any tabbable nodes in the trap.
|
|
@@ -348,6 +351,18 @@ You will hit this error if your trap does not have (or no longer has) any [tabba
|
|
|
348
351
|
|
|
349
352
|
This often happens when traps are related to elements that appear and disappear dynamically. Typically, the error will fire either as the element is being shown (because the trap gets created before the trapped children have been inserted into the DOM), or as it's being hidden (because the trapped children are destroyed before the trap is either destroyed or disabled).
|
|
350
353
|
|
|
354
|
+
### First element in trap is unreachable with the TAB key
|
|
355
|
+
|
|
356
|
+
If you create a trap and try to use the TAB key to set focus to the first element in your trap, the first element seems unreachable because focus keeps skipping over it for some reason.
|
|
357
|
+
|
|
358
|
+
This can happen in projects where the Angular-related [zone.js](https://www.npmjs.com/package/zone.js) module is being used because Zone can interfere with Focus-trap's ability to control where focus goes when it _leaves an edge node_ (that is, a node that is on the edge of a container in which it is trapping focus).
|
|
359
|
+
|
|
360
|
+
What is actually happening is that Focus-trap is correctly wrapping focus around to that first element (or last element, if going in reverse with SHIFT+TAB, and you're seeing that get skipped) and setting focus to it, but because of Zone's interference (in which Focus-trap's call to `preventDefault()` on the focus event triggered by the TAB key press is rendered ineffective), once Focus-trap is done handling the event, the browser hasn't received the signal that its default behavior should be prevented, and so it proceeds to move focus to the _next_ element -- effectively "skipping" over the element to which Focus-trap set focus, making it seem "unreachable".
|
|
361
|
+
|
|
362
|
+
Unfortunately, there's no good workaround to this issue from Focus-trap's perspective. The issue was [reported to Angular](https://github.com/angular/angular/issues/45020) (not by Focus-trap) and [has a PR](https://github.com/angular/angular/pull/49477) (also not by Focus-trap) for a fix.
|
|
363
|
+
|
|
364
|
+
This was originally investigated in [#1165](https://github.com/focus-trap/focus-trap/issues/1165) if you want to go deeper.
|
|
365
|
+
|
|
351
366
|
# Contributing
|
|
352
367
|
|
|
353
368
|
See [CONTRIBUTING](CONTRIBUTING.md).
|
|
@@ -371,34 +386,37 @@ In alphabetical order:
|
|
|
371
386
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/features/security"><img src="https://avatars1.githubusercontent.com/u/27347476?v=4?s=100" width="100px;" alt="Dependabot"/><br /><sub><b>Dependabot</b></sub></a><br /><a href="#maintenance-dependabot" title="Maintenance">π§</a></td>
|
|
372
387
|
</tr>
|
|
373
388
|
<tr>
|
|
389
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jcfranco"><img src="https://avatars.githubusercontent.com/u/197440?v=4?s=100" width="100px;" alt="JC Franco"/><br /><sub><b>JC Franco</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/commits?author=jcfranco" title="Code">π»</a></td>
|
|
374
390
|
<td align="center" valign="top" width="14.28%"><a href="https://www.schilljs.com/"><img src="https://avatars.githubusercontent.com/u/213943?v=4?s=100" width="100px;" alt="Joas Schilling"/><br /><sub><b>Joas Schilling</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/pulls?q=is%3Apr+reviewed-by%3Anickvergessen" title="Reviewed Pull Requests">π</a></td>
|
|
375
391
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/skjnldsv"><img src="https://avatars.githubusercontent.com/u/14975046?v=4?s=100" width="100px;" alt="John MolakvoΓ¦"/><br /><sub><b>John MolakvoΓ¦</b></sub></a><br /><a href="#ideas-skjnldsv" title="Ideas, Planning, & Feedback">π€</a></td>
|
|
376
392
|
<td align="center" valign="top" width="14.28%"><a href="http://reload.dk"><img src="https://avatars.githubusercontent.com/u/73966?v=4?s=100" width="100px;" alt="Kasper GarnΓ¦s"/><br /><sub><b>Kasper GarnΓ¦s</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/commits?author=kasperg" title="Documentation">π</a> <a href="https://github.com/focus-trap/focus-trap/issues?q=author%3Akasperg" title="Bug reports">π</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=kasperg" title="Code">π»</a></td>
|
|
377
393
|
<td align="center" valign="top" width="14.28%"><a href="http://blogs.esri.com/esri/arcgis/"><img src="https://avatars.githubusercontent.com/u/1231455?v=4?s=100" width="100px;" alt="Matt Driscoll"/><br /><sub><b>Matt Driscoll</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/issues?q=author%3Adriskull" title="Bug reports">π</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=driskull" title="Code">π»</a> <a href="#tutorial-driskull" title="Tutorials">β
</a></td>
|
|
378
394
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/msev"><img src="https://avatars.githubusercontent.com/u/1529562?v=4?s=100" width="100px;" alt="Maxime"/><br /><sub><b>Maxime</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/issues?q=author%3Amsev" title="Bug reports">π</a></td>
|
|
379
395
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/michael-ar"><img src="https://avatars3.githubusercontent.com/u/18557997?v=4?s=100" width="100px;" alt="Michael Reynolds"/><br /><sub><b>Michael Reynolds</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/issues?q=author%3Amichael-ar" title="Bug reports">π</a></td>
|
|
380
|
-
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liunate"><img src="https://avatars2.githubusercontent.com/u/38996291?v=4?s=100" width="100px;" alt="Nate Liu"/><br /><sub><b>Nate Liu</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/commits?author=liunate" title="Tests">β οΈ</a></td>
|
|
381
396
|
</tr>
|
|
382
397
|
<tr>
|
|
398
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liunate"><img src="https://avatars2.githubusercontent.com/u/38996291?v=4?s=100" width="100px;" alt="Nate Liu"/><br /><sub><b>Nate Liu</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/commits?author=liunate" title="Tests">β οΈ</a></td>
|
|
383
399
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/far-fetched"><img src="https://avatars.githubusercontent.com/u/11621383?v=4?s=100" width="100px;" alt="Piotr Panek"/><br /><sub><b>Piotr Panek</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/issues?q=author%3Afar-fetched" title="Bug reports">π</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=far-fetched" title="Documentation">π</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=far-fetched" title="Code">π»</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=far-fetched" title="Tests">β οΈ</a></td>
|
|
384
400
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/randypuro"><img src="https://avatars2.githubusercontent.com/u/2579?v=4?s=100" width="100px;" alt="Randy Puro"/><br /><sub><b>Randy Puro</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/issues?q=author%3Arandypuro" title="Bug reports">π</a></td>
|
|
385
401
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sadick254"><img src="https://avatars2.githubusercontent.com/u/5238135?v=4?s=100" width="100px;" alt="Sadick"/><br /><sub><b>Sadick</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/commits?author=sadick254" title="Code">π»</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=sadick254" title="Tests">β οΈ</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=sadick254" title="Documentation">π</a></td>
|
|
386
402
|
<td align="center" valign="top" width="14.28%"><a href="https://scottblinch.me/"><img src="https://avatars2.githubusercontent.com/u/4682114?v=4?s=100" width="100px;" alt="Scott Blinch"/><br /><sub><b>Scott Blinch</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/commits?author=scottblinch" title="Documentation">π</a></td>
|
|
387
403
|
<td align="center" valign="top" width="14.28%"><a href="https://seanmcp.com/"><img src="https://avatars1.githubusercontent.com/u/6360367?v=4?s=100" width="100px;" alt="Sean McPherson"/><br /><sub><b>Sean McPherson</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/commits?author=SeanMcP" title="Code">π»</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=SeanMcP" title="Documentation">π</a></td>
|
|
388
404
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/skriems"><img src="https://avatars.githubusercontent.com/u/15573317?v=4?s=100" width="100px;" alt="Sebastian Kriems"/><br /><sub><b>Sebastian Kriems</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/issues?q=author%3Askriems" title="Bug reports">π</a></td>
|
|
389
|
-
<td align="center" valign="top" width="14.28%"><a href="https://recollectr.io"><img src="https://avatars2.githubusercontent.com/u/6835891?v=4?s=100" width="100px;" alt="Slapbox"/><br /><sub><b>Slapbox</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/issues?q=author%3ASlapbox" title="Bug reports">π</a></td>
|
|
390
405
|
</tr>
|
|
391
406
|
<tr>
|
|
407
|
+
<td align="center" valign="top" width="14.28%"><a href="https://recollectr.io"><img src="https://avatars2.githubusercontent.com/u/6835891?v=4?s=100" width="100px;" alt="Slapbox"/><br /><sub><b>Slapbox</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/issues?q=author%3ASlapbox" title="Bug reports">π</a></td>
|
|
392
408
|
<td align="center" valign="top" width="14.28%"><a href="https://stefancameron.com/"><img src="https://avatars3.githubusercontent.com/u/2855350?v=4?s=100" width="100px;" alt="Stefan Cameron"/><br /><sub><b>Stefan Cameron</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/commits?author=stefcameron" title="Code">π»</a> <a href="https://github.com/focus-trap/focus-trap/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/commits?author=stefcameron" title="Tests">β οΈ</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=stefcameron" title="Documentation">π</a> <a href="#maintenance-stefcameron" title="Maintenance">π§</a></td>
|
|
393
409
|
<td align="center" valign="top" width="14.28%"><a href="http://tylerhawkins.info/201R/"><img src="https://avatars0.githubusercontent.com/u/13806458?v=4?s=100" width="100px;" alt="Tyler Hawkins"/><br /><sub><b>Tyler Hawkins</b></sub></a><br /><a href="#tool-thawkin3" title="Tools">π§</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=thawkin3" title="Tests">β οΈ</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=thawkin3" title="Documentation">π</a></td>
|
|
394
410
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/vasiliki-b"><img src="https://avatars.githubusercontent.com/u/98032598?v=4?s=100" width="100px;" alt="Vasiliki Boutas"/><br /><sub><b>Vasiliki Boutas</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/issues?q=author%3Avasiliki-b" title="Bug reports">π</a></td>
|
|
395
411
|
<td align="center" valign="top" width="14.28%"><a href="https://vinicius73.dev/"><img src="https://avatars.githubusercontent.com/u/1561347?v=4?s=100" width="100px;" alt="Vinicius Reis"/><br /><sub><b>Vinicius Reis</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/commits?author=vinicius73" title="Code">π»</a> <a href="#ideas-vinicius73" title="Ideas, Planning, & Feedback">π€</a></td>
|
|
396
412
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/wandroll"><img src="https://avatars.githubusercontent.com/u/4492317?v=4?s=100" width="100px;" alt="Wandrille Verlut"/><br /><sub><b>Wandrille Verlut</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/commits?author=wandroll" title="Code">π»</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=wandroll" title="Tests">β οΈ</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=wandroll" title="Documentation">π</a> <a href="#tool-wandroll" title="Tools">π§</a></td>
|
|
397
413
|
<td align="center" valign="top" width="14.28%"><a href="http://willmruzek.com/"><img src="https://avatars.githubusercontent.com/u/108522?v=4?s=100" width="100px;" alt="Will Mruzek"/><br /><sub><b>Will Mruzek</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/commits?author=mruzekw" title="Code">π»</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=mruzekw" title="Documentation">π</a> <a href="#example-mruzekw" title="Examples">π‘</a> <a href="https://github.com/focus-trap/focus-trap/commits?author=mruzekw" title="Tests">β οΈ</a> <a href="#question-mruzekw" title="Answering Questions">π¬</a></td>
|
|
398
|
-
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zioth"><img src="https://avatars3.githubusercontent.com/u/945603?v=4?s=100" width="100px;" alt="Zioth"/><br /><sub><b>Zioth</b></sub></a><br /><a href="#ideas-zioth" title="Ideas, Planning, & Feedback">π€</a> <a href="https://github.com/focus-trap/focus-trap/issues?q=author%3Azioth" title="Bug reports">π</a></td>
|
|
399
414
|
</tr>
|
|
400
415
|
<tr>
|
|
416
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zioth"><img src="https://avatars3.githubusercontent.com/u/945603?v=4?s=100" width="100px;" alt="Zioth"/><br /><sub><b>Zioth</b></sub></a><br /><a href="#ideas-zioth" title="Ideas, Planning, & Feedback">π€</a> <a href="https://github.com/focus-trap/focus-trap/issues?q=author%3Azioth" title="Bug reports">π</a></td>
|
|
417
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/glushkova91"><img src="https://avatars.githubusercontent.com/u/13402897?v=4?s=100" width="100px;" alt="glushkova91"/><br /><sub><b>glushkova91</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/commits?author=glushkova91" title="Documentation">π</a></td>
|
|
401
418
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jpveooys"><img src="https://avatars.githubusercontent.com/u/66470099?v=4?s=100" width="100px;" alt="jpveooys"/><br /><sub><b>jpveooys</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/issues?q=author%3Ajpveooys" title="Bug reports">π</a></td>
|
|
419
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/konradr33"><img src="https://avatars.githubusercontent.com/u/32595283?v=4?s=100" width="100px;" alt="konradr33"/><br /><sub><b>konradr33</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/issues?q=author%3Akonradr33" title="Bug reports">π</a></td>
|
|
402
420
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/simonxabris"><img src="https://avatars.githubusercontent.com/u/27497229?v=4?s=100" width="100px;" alt="Γbris Simon"/><br /><sub><b>Γbris Simon</b></sub></a><br /><a href="https://github.com/focus-trap/focus-trap/commits?author=simonxabris" title="Code">π»</a> <a href="https://github.com/focus-trap/focus-trap/issues?q=author%3Asimonxabris" title="Bug reports">π</a></td>
|
|
403
421
|
</tr>
|
|
404
422
|
</tbody>
|
package/dist/focus-trap.esm.js
CHANGED
|
@@ -1,9 +1,31 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* focus-trap 7.
|
|
2
|
+
* focus-trap 7.6.1
|
|
3
3
|
* @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE
|
|
4
4
|
*/
|
|
5
5
|
import { isFocusable, tabbable, focusable, isTabbable, getTabIndex } from 'tabbable';
|
|
6
6
|
|
|
7
|
+
function _arrayLikeToArray(r, a) {
|
|
8
|
+
(null == a || a > r.length) && (a = r.length);
|
|
9
|
+
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
10
|
+
return n;
|
|
11
|
+
}
|
|
12
|
+
function _arrayWithoutHoles(r) {
|
|
13
|
+
if (Array.isArray(r)) return _arrayLikeToArray(r);
|
|
14
|
+
}
|
|
15
|
+
function _defineProperty(e, r, t) {
|
|
16
|
+
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
17
|
+
value: t,
|
|
18
|
+
enumerable: !0,
|
|
19
|
+
configurable: !0,
|
|
20
|
+
writable: !0
|
|
21
|
+
}) : e[r] = t, e;
|
|
22
|
+
}
|
|
23
|
+
function _iterableToArray(r) {
|
|
24
|
+
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
|
|
25
|
+
}
|
|
26
|
+
function _nonIterableSpread() {
|
|
27
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
28
|
+
}
|
|
7
29
|
function ownKeys(e, r) {
|
|
8
30
|
var t = Object.keys(e);
|
|
9
31
|
if (Object.getOwnPropertySymbols) {
|
|
@@ -25,33 +47,29 @@ function _objectSpread2(e) {
|
|
|
25
47
|
}
|
|
26
48
|
return e;
|
|
27
49
|
}
|
|
28
|
-
function
|
|
29
|
-
|
|
30
|
-
if (key in obj) {
|
|
31
|
-
Object.defineProperty(obj, key, {
|
|
32
|
-
value: value,
|
|
33
|
-
enumerable: true,
|
|
34
|
-
configurable: true,
|
|
35
|
-
writable: true
|
|
36
|
-
});
|
|
37
|
-
} else {
|
|
38
|
-
obj[key] = value;
|
|
39
|
-
}
|
|
40
|
-
return obj;
|
|
50
|
+
function _toConsumableArray(r) {
|
|
51
|
+
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
|
|
41
52
|
}
|
|
42
|
-
function _toPrimitive(
|
|
43
|
-
if (
|
|
44
|
-
var
|
|
45
|
-
if (
|
|
46
|
-
var
|
|
47
|
-
if (
|
|
53
|
+
function _toPrimitive(t, r) {
|
|
54
|
+
if ("object" != typeof t || !t) return t;
|
|
55
|
+
var e = t[Symbol.toPrimitive];
|
|
56
|
+
if (void 0 !== e) {
|
|
57
|
+
var i = e.call(t, r || "default");
|
|
58
|
+
if ("object" != typeof i) return i;
|
|
48
59
|
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
49
60
|
}
|
|
50
|
-
return (
|
|
61
|
+
return ("string" === r ? String : Number)(t);
|
|
51
62
|
}
|
|
52
|
-
function _toPropertyKey(
|
|
53
|
-
var
|
|
54
|
-
return
|
|
63
|
+
function _toPropertyKey(t) {
|
|
64
|
+
var i = _toPrimitive(t, "string");
|
|
65
|
+
return "symbol" == typeof i ? i : i + "";
|
|
66
|
+
}
|
|
67
|
+
function _unsupportedIterableToArray(r, a) {
|
|
68
|
+
if (r) {
|
|
69
|
+
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
70
|
+
var t = {}.toString.call(r).slice(8, -1);
|
|
71
|
+
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
|
72
|
+
}
|
|
55
73
|
}
|
|
56
74
|
|
|
57
75
|
var activeFocusTraps = {
|
|
@@ -113,10 +131,8 @@ var findIndex = function findIndex(arr, fn) {
|
|
|
113
131
|
idx = i;
|
|
114
132
|
return false; // break
|
|
115
133
|
}
|
|
116
|
-
|
|
117
134
|
return true; // next
|
|
118
135
|
});
|
|
119
|
-
|
|
120
136
|
return idx;
|
|
121
137
|
};
|
|
122
138
|
|
|
@@ -229,7 +245,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
229
245
|
return state.containerGroups.findIndex(function (_ref) {
|
|
230
246
|
var container = _ref.container,
|
|
231
247
|
tabbableNodes = _ref.tabbableNodes;
|
|
232
|
-
return container.contains(element) || (
|
|
248
|
+
return container.contains(element) || (// fall back to explicit tabbable search which will take into consideration any
|
|
233
249
|
// web components if the `tabbableOptions.getShadowRoot` option was used for
|
|
234
250
|
// the trap, enabling shadow DOM support in tabbable (`Node.contains()` doesn't
|
|
235
251
|
// look inside web components even if open)
|
|
@@ -245,25 +261,31 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
245
261
|
* (if a node is explicitly NOT given), or a function that returns any of these
|
|
246
262
|
* values.
|
|
247
263
|
* @param {string} optionName
|
|
248
|
-
* @
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
264
|
+
* @param {Object} options
|
|
265
|
+
* @param {boolean} [options.hasFallback] True if the option could be a selector string
|
|
266
|
+
* and the option allows for a fallback scenario in the case where the selector is
|
|
267
|
+
* valid but does not match a node (i.e. the queried node doesn't exist in the DOM).
|
|
268
|
+
* @param {Array} [options.params] Params to pass to the option if it's a function.
|
|
269
|
+
* @returns {undefined | null | false | HTMLElement | SVGElement} Returns
|
|
270
|
+
* `undefined` if the option is not specified; `null` if the option didn't resolve
|
|
271
|
+
* to a node but `options.hasFallback=true`, `false` if the option resolved to `false`
|
|
272
|
+
* (node explicitly not given); otherwise, the resolved DOM node.
|
|
252
273
|
* @throws {Error} If the option is set, not `false`, and is not, or does not
|
|
253
|
-
* resolve to a node.
|
|
274
|
+
* resolve to a node, unless the option is a selector string and `options.hasFallback=true`.
|
|
254
275
|
*/
|
|
255
276
|
var getNodeForOption = function getNodeForOption(optionName) {
|
|
277
|
+
var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
278
|
+
_ref2$hasFallback = _ref2.hasFallback,
|
|
279
|
+
hasFallback = _ref2$hasFallback === void 0 ? false : _ref2$hasFallback,
|
|
280
|
+
_ref2$params = _ref2.params,
|
|
281
|
+
params = _ref2$params === void 0 ? [] : _ref2$params;
|
|
256
282
|
var optionValue = config[optionName];
|
|
257
283
|
if (typeof optionValue === 'function') {
|
|
258
|
-
|
|
259
|
-
params[_key2 - 1] = arguments[_key2];
|
|
260
|
-
}
|
|
261
|
-
optionValue = optionValue.apply(void 0, params);
|
|
284
|
+
optionValue = optionValue.apply(void 0, _toConsumableArray(params));
|
|
262
285
|
}
|
|
263
286
|
if (optionValue === true) {
|
|
264
287
|
optionValue = undefined; // use default value
|
|
265
288
|
}
|
|
266
|
-
|
|
267
289
|
if (!optionValue) {
|
|
268
290
|
if (optionValue === undefined || optionValue === false) {
|
|
269
291
|
return optionValue;
|
|
@@ -275,21 +297,31 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
275
297
|
var node = optionValue; // could be HTMLElement, SVGElement, or non-empty string at this point
|
|
276
298
|
|
|
277
299
|
if (typeof optionValue === 'string') {
|
|
278
|
-
|
|
300
|
+
try {
|
|
301
|
+
node = doc.querySelector(optionValue); // resolve to node, or null if fails
|
|
302
|
+
} catch (err) {
|
|
303
|
+
throw new Error("`".concat(optionName, "` appears to be an invalid selector; error=\"").concat(err.message, "\""));
|
|
304
|
+
}
|
|
279
305
|
if (!node) {
|
|
280
|
-
|
|
306
|
+
if (!hasFallback) {
|
|
307
|
+
throw new Error("`".concat(optionName, "` as selector refers to no known node"));
|
|
308
|
+
}
|
|
309
|
+
// else, `node` MUST be `null` because that's what `Document.querySelector()` returns
|
|
310
|
+
// if the selector is valid but doesn't match anything
|
|
281
311
|
}
|
|
282
312
|
}
|
|
283
313
|
return node;
|
|
284
314
|
};
|
|
285
315
|
var getInitialFocusNode = function getInitialFocusNode() {
|
|
286
|
-
var node = getNodeForOption('initialFocus'
|
|
316
|
+
var node = getNodeForOption('initialFocus', {
|
|
317
|
+
hasFallback: true
|
|
318
|
+
});
|
|
287
319
|
|
|
288
320
|
// false explicitly indicates we want no initialFocus at all
|
|
289
321
|
if (node === false) {
|
|
290
322
|
return false;
|
|
291
323
|
}
|
|
292
|
-
if (node === undefined || !isFocusable(node, config.tabbableOptions)) {
|
|
324
|
+
if (node === undefined || node && !isFocusable(node, config.tabbableOptions)) {
|
|
293
325
|
// option not specified nor focusable: use fallback options
|
|
294
326
|
if (findContainerIndex(doc.activeElement) >= 0) {
|
|
295
327
|
node = doc.activeElement;
|
|
@@ -300,6 +332,10 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
300
332
|
// NOTE: `fallbackFocus` option function cannot return `false` (not supported)
|
|
301
333
|
node = firstTabbableNode || getNodeForOption('fallbackFocus');
|
|
302
334
|
}
|
|
335
|
+
} else if (node === null) {
|
|
336
|
+
// option is a VALID selector string that doesn't yield a node: use the `fallbackFocus`
|
|
337
|
+
// option instead of the default behavior when the option isn't specified at all
|
|
338
|
+
node = getNodeForOption('fallbackFocus');
|
|
303
339
|
}
|
|
304
340
|
if (!node) {
|
|
305
341
|
throw new Error('Your focus-trap needs to have at least one focusable element');
|
|
@@ -409,25 +445,25 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
409
445
|
*
|
|
410
446
|
* @returns {HTMLElement} The element that currently has the focus
|
|
411
447
|
**/
|
|
412
|
-
var
|
|
448
|
+
var _getActiveElement = function getActiveElement(el) {
|
|
413
449
|
var activeElement = el.activeElement;
|
|
414
450
|
if (!activeElement) {
|
|
415
451
|
return;
|
|
416
452
|
}
|
|
417
453
|
if (activeElement.shadowRoot && activeElement.shadowRoot.activeElement !== null) {
|
|
418
|
-
return
|
|
454
|
+
return _getActiveElement(activeElement.shadowRoot);
|
|
419
455
|
}
|
|
420
456
|
return activeElement;
|
|
421
457
|
};
|
|
422
|
-
var
|
|
458
|
+
var _tryFocus = function tryFocus(node) {
|
|
423
459
|
if (node === false) {
|
|
424
460
|
return;
|
|
425
461
|
}
|
|
426
|
-
if (node ===
|
|
462
|
+
if (node === _getActiveElement(document)) {
|
|
427
463
|
return;
|
|
428
464
|
}
|
|
429
465
|
if (!node || !node.focus) {
|
|
430
|
-
|
|
466
|
+
_tryFocus(getInitialFocusNode());
|
|
431
467
|
return;
|
|
432
468
|
}
|
|
433
469
|
node.focus({
|
|
@@ -440,7 +476,9 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
440
476
|
}
|
|
441
477
|
};
|
|
442
478
|
var getReturnFocusNode = function getReturnFocusNode(previousActiveElement) {
|
|
443
|
-
var node = getNodeForOption('setReturnFocus',
|
|
479
|
+
var node = getNodeForOption('setReturnFocus', {
|
|
480
|
+
params: [previousActiveElement]
|
|
481
|
+
});
|
|
444
482
|
return node ? node : node === false ? false : previousActiveElement;
|
|
445
483
|
};
|
|
446
484
|
|
|
@@ -455,11 +493,11 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
455
493
|
* @returns {Node|undefined} The next node, or `undefined` if a next node couldn't be
|
|
456
494
|
* determined given the current state of the trap.
|
|
457
495
|
*/
|
|
458
|
-
var findNextNavNode = function findNextNavNode(
|
|
459
|
-
var target =
|
|
460
|
-
event =
|
|
461
|
-
|
|
462
|
-
isBackward =
|
|
496
|
+
var findNextNavNode = function findNextNavNode(_ref3) {
|
|
497
|
+
var target = _ref3.target,
|
|
498
|
+
event = _ref3.event,
|
|
499
|
+
_ref3$isBackward = _ref3.isBackward,
|
|
500
|
+
isBackward = _ref3$isBackward === void 0 ? false : _ref3$isBackward;
|
|
463
501
|
target = target || getActualTarget(event);
|
|
464
502
|
updateTabbableNodes();
|
|
465
503
|
var destinationNode = null;
|
|
@@ -483,8 +521,8 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
483
521
|
// REVERSE
|
|
484
522
|
|
|
485
523
|
// is the target the first tabbable node in a group?
|
|
486
|
-
var startOfGroupIndex = findIndex(state.tabbableGroups, function (
|
|
487
|
-
var firstTabbableNode =
|
|
524
|
+
var startOfGroupIndex = findIndex(state.tabbableGroups, function (_ref4) {
|
|
525
|
+
var firstTabbableNode = _ref4.firstTabbableNode;
|
|
488
526
|
return target === firstTabbableNode;
|
|
489
527
|
});
|
|
490
528
|
if (startOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target, false))) {
|
|
@@ -512,8 +550,8 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
512
550
|
// FORWARD
|
|
513
551
|
|
|
514
552
|
// is the target the last tabbable node in a group?
|
|
515
|
-
var lastOfGroupIndex = findIndex(state.tabbableGroups, function (
|
|
516
|
-
var lastTabbableNode =
|
|
553
|
+
var lastOfGroupIndex = findIndex(state.tabbableGroups, function (_ref5) {
|
|
554
|
+
var lastTabbableNode = _ref5.lastTabbableNode;
|
|
517
555
|
return target === lastTabbableNode;
|
|
518
556
|
});
|
|
519
557
|
if (lastOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target))) {
|
|
@@ -671,9 +709,9 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
671
709
|
});
|
|
672
710
|
}
|
|
673
711
|
if (nextNode) {
|
|
674
|
-
|
|
712
|
+
_tryFocus(nextNode);
|
|
675
713
|
} else {
|
|
676
|
-
|
|
714
|
+
_tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());
|
|
677
715
|
}
|
|
678
716
|
}
|
|
679
717
|
state.recentNavEvent = undefined; // clear
|
|
@@ -698,19 +736,21 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
698
736
|
// to where it normally would
|
|
699
737
|
event.preventDefault();
|
|
700
738
|
}
|
|
701
|
-
|
|
739
|
+
_tryFocus(destinationNode);
|
|
702
740
|
}
|
|
703
741
|
// else, let the browser take care of [shift+]tab and move the focus
|
|
704
742
|
};
|
|
743
|
+
var checkTabKey = function checkTabKey(event) {
|
|
744
|
+
if (config.isKeyForward(event) || config.isKeyBackward(event)) {
|
|
745
|
+
checkKeyNav(event, config.isKeyBackward(event));
|
|
746
|
+
}
|
|
747
|
+
};
|
|
705
748
|
|
|
706
|
-
|
|
749
|
+
// we use a different event phase for the Escape key to allow canceling the event and checking for this in escapeDeactivates
|
|
750
|
+
var checkEscapeKey = function checkEscapeKey(event) {
|
|
707
751
|
if (isEscapeEvent(event) && valueOrHandler(config.escapeDeactivates, event) !== false) {
|
|
708
752
|
event.preventDefault();
|
|
709
753
|
trap.deactivate();
|
|
710
|
-
return;
|
|
711
|
-
}
|
|
712
|
-
if (config.isKeyForward(event) || config.isKeyBackward(event)) {
|
|
713
|
-
checkKeyNav(event, config.isKeyBackward(event));
|
|
714
754
|
}
|
|
715
755
|
};
|
|
716
756
|
var checkClick = function checkClick(e) {
|
|
@@ -743,8 +783,8 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
743
783
|
// Delay ensures that the focused element doesn't capture the event
|
|
744
784
|
// that caused the focus trap activation.
|
|
745
785
|
state.delayInitialFocusTimer = config.delayInitialFocus ? delay(function () {
|
|
746
|
-
|
|
747
|
-
}) :
|
|
786
|
+
_tryFocus(getInitialFocusNode());
|
|
787
|
+
}) : _tryFocus(getInitialFocusNode());
|
|
748
788
|
doc.addEventListener('focusin', checkFocusIn, true);
|
|
749
789
|
doc.addEventListener('mousedown', checkPointerDown, {
|
|
750
790
|
capture: true,
|
|
@@ -758,10 +798,11 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
758
798
|
capture: true,
|
|
759
799
|
passive: false
|
|
760
800
|
});
|
|
761
|
-
doc.addEventListener('keydown',
|
|
801
|
+
doc.addEventListener('keydown', checkTabKey, {
|
|
762
802
|
capture: true,
|
|
763
803
|
passive: false
|
|
764
804
|
});
|
|
805
|
+
doc.addEventListener('keydown', checkEscapeKey);
|
|
765
806
|
return trap;
|
|
766
807
|
};
|
|
767
808
|
var removeListeners = function removeListeners() {
|
|
@@ -772,7 +813,8 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
772
813
|
doc.removeEventListener('mousedown', checkPointerDown, true);
|
|
773
814
|
doc.removeEventListener('touchstart', checkPointerDown, true);
|
|
774
815
|
doc.removeEventListener('click', checkClick, true);
|
|
775
|
-
doc.removeEventListener('keydown',
|
|
816
|
+
doc.removeEventListener('keydown', checkTabKey, true);
|
|
817
|
+
doc.removeEventListener('keydown', checkEscapeKey);
|
|
776
818
|
return trap;
|
|
777
819
|
};
|
|
778
820
|
|
|
@@ -791,7 +833,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
791
833
|
// If the currently focused is removed then browsers will move focus to the
|
|
792
834
|
// <body> element. If this happens, try to move focus back into the trap.
|
|
793
835
|
if (isFocusedNodeRemoved) {
|
|
794
|
-
|
|
836
|
+
_tryFocus(getInitialFocusNode());
|
|
795
837
|
}
|
|
796
838
|
};
|
|
797
839
|
|
|
@@ -877,7 +919,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
|
877
919
|
var finishDeactivation = function finishDeactivation() {
|
|
878
920
|
delay(function () {
|
|
879
921
|
if (returnFocus) {
|
|
880
|
-
|
|
922
|
+
_tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
|
|
881
923
|
}
|
|
882
924
|
onPostDeactivate === null || onPostDeactivate === void 0 || onPostDeactivate();
|
|
883
925
|
});
|