focus-trap 7.4.2 → 7.4.3

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/index.js CHANGED
@@ -260,8 +260,8 @@ const createFocusTrap = function (elements, userOptions) {
260
260
  return false;
261
261
  }
262
262
 
263
- if (node === undefined) {
264
- // option not specified: use fallback options
263
+ if (node === undefined || !isFocusable(node, config.tabbableOptions)) {
264
+ // option not specified nor focusable: use fallback options
265
265
  if (findContainerIndex(doc.activeElement) >= 0) {
266
266
  node = doc.activeElement;
267
267
  } else {
@@ -655,6 +655,48 @@ const createFocusTrap = function (elements, userOptions) {
655
655
  return trap;
656
656
  };
657
657
 
658
+ //
659
+ // MUTATION OBSERVER
660
+ //
661
+
662
+ const checkDomRemoval = function (mutations) {
663
+ const isFocusedNodeRemoved = mutations.some(function (mutation) {
664
+ const removedNodes = Array.from(mutation.removedNodes);
665
+ return removedNodes.some(function (node) {
666
+ return node === state.mostRecentlyFocusedNode;
667
+ });
668
+ });
669
+
670
+ // If the currently focused is removed then browsers will move focus to the
671
+ // <body> element. If this happens, try to move focus back into the trap.
672
+ if (isFocusedNodeRemoved) {
673
+ tryFocus(getInitialFocusNode());
674
+ }
675
+ };
676
+
677
+ // Use MutationObserver - if supported - to detect if focused node is removed
678
+ // from the DOM.
679
+ const mutationObserver =
680
+ typeof window !== 'undefined' && 'MutationObserver' in window
681
+ ? new MutationObserver(checkDomRemoval)
682
+ : undefined;
683
+
684
+ const updateObservedNodes = function () {
685
+ if (!mutationObserver) {
686
+ return;
687
+ }
688
+
689
+ mutationObserver.disconnect();
690
+ if (state.active && !state.paused) {
691
+ state.containers.map(function (container) {
692
+ mutationObserver.observe(container, {
693
+ subtree: true,
694
+ childList: true,
695
+ });
696
+ });
697
+ }
698
+ };
699
+
658
700
  //
659
701
  // TRAP DEFINITION
660
702
  //
@@ -692,6 +734,7 @@ const createFocusTrap = function (elements, userOptions) {
692
734
  updateTabbableNodes();
693
735
  }
694
736
  addListeners();
737
+ updateObservedNodes();
695
738
  onPostActivate?.();
696
739
  };
697
740
 
@@ -725,6 +768,7 @@ const createFocusTrap = function (elements, userOptions) {
725
768
  removeListeners();
726
769
  state.active = false;
727
770
  state.paused = false;
771
+ updateObservedNodes();
728
772
 
729
773
  activeFocusTraps.deactivateTrap(trapStack, trap);
730
774
 
@@ -771,6 +815,7 @@ const createFocusTrap = function (elements, userOptions) {
771
815
  onPause?.();
772
816
 
773
817
  removeListeners();
818
+ updateObservedNodes();
774
819
 
775
820
  onPostPause?.();
776
821
  return this;
@@ -789,6 +834,7 @@ const createFocusTrap = function (elements, userOptions) {
789
834
 
790
835
  updateTabbableNodes();
791
836
  addListeners();
837
+ updateObservedNodes();
792
838
 
793
839
  onPostUnpause?.();
794
840
  return this;
@@ -805,6 +851,8 @@ const createFocusTrap = function (elements, userOptions) {
805
851
  updateTabbableNodes();
806
852
  }
807
853
 
854
+ updateObservedNodes();
855
+
808
856
  return this;
809
857
  },
810
858
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "focus-trap",
3
- "version": "7.4.2",
3
+ "version": "7.4.3",
4
4
  "description": "Trap focus within a DOM node.",
5
5
  "main": "dist/focus-trap.js",
6
6
  "module": "dist/focus-trap.esm.js",