@blocdigital/usetoplayerelement 0.0.2 → 0.0.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.
@@ -4,16 +4,16 @@ exports.default = useTopLayerElements;
4
4
  const react_1 = require("react");
5
5
  const topLayerElements = new Set();
6
6
  // Custom event to notify elements when they are added/removed from the top layer
7
- const topLayerEvent = (inTopLayer) => new CustomEvent("topLayer", { bubbles: true, detail: { inTopLayer } });
8
- if (typeof document !== "undefined") {
7
+ const topLayerEvent = (inTopLayer) => new CustomEvent('topLayer', { bubbles: true, detail: { inTopLayer } });
8
+ if (typeof document !== 'undefined') {
9
9
  // Listen for elements being added/removed from the top layer
10
- document.addEventListener("toggle", ({ target }) => {
10
+ document.addEventListener('toggle', ({ target }) => {
11
11
  if (!target)
12
12
  return;
13
13
  const el = target;
14
- if (!(el instanceof HTMLDialogElement || el.hasAttribute("popover")))
14
+ if (!(el instanceof HTMLDialogElement || el.hasAttribute('popover')))
15
15
  return;
16
- if (el.matches(":modal, :popover-open") && document.contains(el)) {
16
+ if (el.matches(':modal, :popover-open') && document.contains(el)) {
17
17
  topLayerElements.add(el);
18
18
  el.dispatchEvent(topLayerEvent(true));
19
19
  }
@@ -24,7 +24,7 @@ if (typeof document !== "undefined") {
24
24
  }, { capture: true });
25
25
  // MutationObserver for automatic cleanup
26
26
  const observer = new MutationObserver((mutations) => {
27
- const nodes = mutations.flatMap(({ removedNodes }) => [...removedNodes]);
27
+ const nodes = mutations.flatMap(({ removedNodes }) => Array.from(removedNodes).filter((node) => node instanceof HTMLElement));
28
28
  for (const node of nodes)
29
29
  if (topLayerElements.delete(node))
30
30
  document.dispatchEvent(topLayerEvent(false));
@@ -33,22 +33,18 @@ if (typeof document !== "undefined") {
33
33
  }
34
34
  function useTopLayerElements() {
35
35
  const ref = (0, react_1.useRef)(null);
36
- const [topLayerList, setTopLayerList] = (0, react_1.useState)([
37
- ...topLayerElements,
38
- ]);
36
+ const [topLayerList, setTopLayerList] = (0, react_1.useState)([...topLayerElements]);
39
37
  const derivedState = (0, react_1.useMemo)(() => {
40
38
  const topElement = topLayerList.length ? topLayerList.at(-1) || null : null;
41
- const topDialog = topLayerList.findLast((el) => el.tagName === "DIALOG") || null;
39
+ const topDialog = topLayerList.findLast((el) => el.tagName === 'DIALOG') || null;
42
40
  const isTopElement = ref.current ? topElement === ref.current : false;
43
- const isInTopLayer = ref.current
44
- ? topLayerList.includes(ref.current)
45
- : false;
41
+ const isInTopLayer = ref.current ? topLayerList.includes(ref.current) : false;
46
42
  return { topElement, topDialog, isTopElement, isInTopLayer };
47
43
  }, [topLayerList]);
48
44
  // Listen for top layer changes
49
45
  (0, react_1.useEffect)(() => {
50
46
  const ac = new AbortController();
51
- document.addEventListener("topLayer", () => setTopLayerList([...topLayerElements]), { signal: ac.signal });
47
+ document.addEventListener('topLayer', () => setTopLayerList([...topLayerElements]), { signal: ac.signal });
52
48
  return () => ac.abort();
53
49
  }, []);
54
50
  return (0, react_1.useMemo)(() => ({ ref, ...derivedState, topLayerList }), [derivedState, topLayerList]);
@@ -1,16 +1,16 @@
1
- import { useEffect, useMemo, useRef, useState } from "react";
1
+ import { useEffect, useMemo, useRef, useState } from 'react';
2
2
  const topLayerElements = new Set();
3
3
  // Custom event to notify elements when they are added/removed from the top layer
4
- const topLayerEvent = (inTopLayer) => new CustomEvent("topLayer", { bubbles: true, detail: { inTopLayer } });
5
- if (typeof document !== "undefined") {
4
+ const topLayerEvent = (inTopLayer) => new CustomEvent('topLayer', { bubbles: true, detail: { inTopLayer } });
5
+ if (typeof document !== 'undefined') {
6
6
  // Listen for elements being added/removed from the top layer
7
- document.addEventListener("toggle", ({ target }) => {
7
+ document.addEventListener('toggle', ({ target }) => {
8
8
  if (!target)
9
9
  return;
10
10
  const el = target;
11
- if (!(el instanceof HTMLDialogElement || el.hasAttribute("popover")))
11
+ if (!(el instanceof HTMLDialogElement || el.hasAttribute('popover')))
12
12
  return;
13
- if (el.matches(":modal, :popover-open") && document.contains(el)) {
13
+ if (el.matches(':modal, :popover-open') && document.contains(el)) {
14
14
  topLayerElements.add(el);
15
15
  el.dispatchEvent(topLayerEvent(true));
16
16
  }
@@ -21,7 +21,7 @@ if (typeof document !== "undefined") {
21
21
  }, { capture: true });
22
22
  // MutationObserver for automatic cleanup
23
23
  const observer = new MutationObserver((mutations) => {
24
- const nodes = mutations.flatMap(({ removedNodes }) => [...removedNodes]);
24
+ const nodes = mutations.flatMap(({ removedNodes }) => Array.from(removedNodes).filter((node) => node instanceof HTMLElement));
25
25
  for (const node of nodes)
26
26
  if (topLayerElements.delete(node))
27
27
  document.dispatchEvent(topLayerEvent(false));
@@ -30,22 +30,18 @@ if (typeof document !== "undefined") {
30
30
  }
31
31
  export default function useTopLayerElements() {
32
32
  const ref = useRef(null);
33
- const [topLayerList, setTopLayerList] = useState([
34
- ...topLayerElements,
35
- ]);
33
+ const [topLayerList, setTopLayerList] = useState([...topLayerElements]);
36
34
  const derivedState = useMemo(() => {
37
35
  const topElement = topLayerList.length ? topLayerList.at(-1) || null : null;
38
- const topDialog = topLayerList.findLast((el) => el.tagName === "DIALOG") || null;
36
+ const topDialog = topLayerList.findLast((el) => el.tagName === 'DIALOG') || null;
39
37
  const isTopElement = ref.current ? topElement === ref.current : false;
40
- const isInTopLayer = ref.current
41
- ? topLayerList.includes(ref.current)
42
- : false;
38
+ const isInTopLayer = ref.current ? topLayerList.includes(ref.current) : false;
43
39
  return { topElement, topDialog, isTopElement, isInTopLayer };
44
40
  }, [topLayerList]);
45
41
  // Listen for top layer changes
46
42
  useEffect(() => {
47
43
  const ac = new AbortController();
48
- document.addEventListener("topLayer", () => setTopLayerList([...topLayerElements]), { signal: ac.signal });
44
+ document.addEventListener('topLayer', () => setTopLayerList([...topLayerElements]), { signal: ac.signal });
49
45
  return () => ac.abort();
50
46
  }, []);
51
47
  return useMemo(() => ({ ref, ...derivedState, topLayerList }), [derivedState, topLayerList]);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@blocdigital/usetoplayerelement",
3
3
  "type": "module",
4
- "version": "0.0.2",
4
+ "version": "0.0.3",
5
5
  "description": "React hook for monitoring the top layer",
6
6
  "author": "Bloc Digital <web@bloc.digital>",
7
7
  "license": "MIT",
@@ -49,33 +49,29 @@
49
49
  "preview": "vite preview",
50
50
  "test": "jest"
51
51
  },
52
- "dependencies": {
53
- "react": "^19.0.0",
54
- "react-dom": "^19.0.0"
55
- },
56
52
  "devDependencies": {
57
- "@babel/core": "^7.26.9",
58
- "@babel/preset-env": "^7.26.9",
59
- "@babel/preset-typescript": "^7.26.0",
60
- "@testing-library/react": "^16.2.0",
61
- "@types/jest": "^29.5.14",
62
- "@types/react": "^19.0.10",
63
- "@types/react-dom": "^19.0.4",
64
- "@typescript-eslint/eslint-plugin": "^8.25.0",
65
- "@typescript-eslint/parser": "^8.25.0",
66
- "@vitejs/plugin-react-swc": "^3.8.0",
67
- "babel-jest": "^29.7.0",
68
- "eslint": "^9.21.0",
69
- "eslint-config-prettier": "^10.0.2",
70
- "eslint-plugin-prettier": "^5.2.3",
71
- "eslint-plugin-react-hooks": "^5.1.0",
72
- "eslint-plugin-react-refresh": "^0.4.19",
73
- "globals": "^16.0.0",
74
- "jest": "^29.7.0",
75
- "jest-environment-jsdom": "^29.7.0",
76
- "prettier": "^3.5.2",
77
- "typescript": "^5.7.3",
78
- "vite": "^6.2.0"
53
+ "@babel/core": "^7.28.0",
54
+ "@babel/preset-env": "^7.28.0",
55
+ "@babel/preset-typescript": "^7.27.1",
56
+ "@testing-library/react": "^16.3.0",
57
+ "@types/jest": "^30.0.0",
58
+ "@types/react": "^19.1.8",
59
+ "@types/react-dom": "^19.1.6",
60
+ "@typescript-eslint/eslint-plugin": "^8.35.1",
61
+ "@typescript-eslint/parser": "^8.35.1",
62
+ "@vitejs/plugin-react-swc": "^3.10.2",
63
+ "babel-jest": "^30.0.4",
64
+ "eslint": "^9.30.1",
65
+ "eslint-config-prettier": "^10.1.5",
66
+ "eslint-plugin-prettier": "^5.5.1",
67
+ "eslint-plugin-react-hooks": "^5.2.0",
68
+ "eslint-plugin-react-refresh": "^0.4.20",
69
+ "globals": "^16.3.0",
70
+ "jest": "^30.0.4",
71
+ "jest-environment-jsdom": "^30.0.4",
72
+ "prettier": "^3.6.2",
73
+ "typescript": "^5.8.3",
74
+ "vite": "^7.0.2"
79
75
  },
80
76
  "bugs": {
81
77
  "url": "https://github.com/bloc-digital/usetoplayerelement/issues"