@y14e/portal 1.0.1 → 1.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/dist/index.cjs CHANGED
@@ -91,22 +91,25 @@ function isFocusable(element) {
91
91
  return true;
92
92
  }
93
93
  function getRelativeFocusable(container, offset, options) {
94
- const {
95
- anchor = getActiveElement(),
96
- composed = false,
97
- filter,
98
- include,
99
- wrap = false
100
- } = options;
101
- const focusables = getFocusables(container, { composed, filter, include });
102
- const { length } = focusables;
103
- if (!length) {
104
- return null;
94
+ let anchor = options.anchor ?? getActiveElement();
95
+ const { composed = false, filter, include, wrap = false } = options;
96
+ if (!(anchor instanceof Element)) {
97
+ const active = getActiveElement();
98
+ if (active instanceof Element) {
99
+ console.warn("Invalid anchor element. Fallback: active element.");
100
+ anchor = active;
101
+ } else {
102
+ console.warn("Invalid anchor element");
103
+ return null;
104
+ }
105
105
  }
106
- if (!anchor || !containsComposed(container, anchor)) {
106
+ if (!containsComposed(container, anchor)) {
107
+ console.warn("Mismatch elements");
107
108
  return null;
108
109
  }
109
- if (!(anchor instanceof Element)) {
110
+ const focusables = getFocusables(container, { composed, filter, include });
111
+ const { length } = focusables;
112
+ if (!length) {
110
113
  return null;
111
114
  }
112
115
  const currentIndex = focusables.indexOf(anchor);
@@ -272,6 +275,9 @@ function createPortal(host, container = document.body) {
272
275
  console.warn("Invalid container element. Fallback: <body> element.");
273
276
  container = document.body;
274
277
  }
278
+ if (!containsComposed2(container, host)) {
279
+ throw new Error("Mismatch elements");
280
+ }
275
281
  const portal = new Portal(host, container);
276
282
  return () => portal.destroy();
277
283
  }
@@ -404,6 +410,16 @@ var Portal = class {
404
410
  focusable && focus(focusable);
405
411
  }
406
412
  };
413
+ function containsComposed2(container, element) {
414
+ let current = element;
415
+ while (current) {
416
+ if (current === container) {
417
+ return true;
418
+ }
419
+ current = current instanceof ShadowRoot ? current.mode === "open" ? current.host : null : current.parentNode;
420
+ }
421
+ return false;
422
+ }
407
423
  function focus(element) {
408
424
  "focus" in element && typeof element.focus === "function" && element.focus();
409
425
  }
@@ -419,7 +435,7 @@ function getActiveElement2() {
419
435
  * Lightweight DOM portal (teleport) utility with fully focus management.
420
436
  * Designed for accessible dialogs, menus, overlays, popovers.
421
437
  *
422
- * @version 1.0.1
438
+ * @version 1.0.2
423
439
  * @author Yusuke Kamiyamane
424
440
  * @license MIT
425
441
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -433,7 +449,7 @@ power-focusable/dist/index.js:
433
449
  * High-precision focus management utility with full composed tree support.
434
450
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
435
451
  *
436
- * @version 4.1.2
452
+ * @version 4.1.3
437
453
  * @author Yusuke Kamiyamane
438
454
  * @license MIT
439
455
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.cts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Lightweight DOM portal (teleport) utility with fully focus management.
4
4
  * Designed for accessible dialogs, menus, overlays, popovers.
5
5
  *
6
- * @version 1.0.1
6
+ * @version 1.0.2
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Lightweight DOM portal (teleport) utility with fully focus management.
4
4
  * Designed for accessible dialogs, menus, overlays, popovers.
5
5
  *
6
- * @version 1.0.1
6
+ * @version 1.0.2
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -89,22 +89,25 @@ function isFocusable(element) {
89
89
  return true;
90
90
  }
91
91
  function getRelativeFocusable(container, offset, options) {
92
- const {
93
- anchor = getActiveElement(),
94
- composed = false,
95
- filter,
96
- include,
97
- wrap = false
98
- } = options;
99
- const focusables = getFocusables(container, { composed, filter, include });
100
- const { length } = focusables;
101
- if (!length) {
102
- return null;
92
+ let anchor = options.anchor ?? getActiveElement();
93
+ const { composed = false, filter, include, wrap = false } = options;
94
+ if (!(anchor instanceof Element)) {
95
+ const active = getActiveElement();
96
+ if (active instanceof Element) {
97
+ console.warn("Invalid anchor element. Fallback: active element.");
98
+ anchor = active;
99
+ } else {
100
+ console.warn("Invalid anchor element");
101
+ return null;
102
+ }
103
103
  }
104
- if (!anchor || !containsComposed(container, anchor)) {
104
+ if (!containsComposed(container, anchor)) {
105
+ console.warn("Mismatch elements");
105
106
  return null;
106
107
  }
107
- if (!(anchor instanceof Element)) {
108
+ const focusables = getFocusables(container, { composed, filter, include });
109
+ const { length } = focusables;
110
+ if (!length) {
108
111
  return null;
109
112
  }
110
113
  const currentIndex = focusables.indexOf(anchor);
@@ -270,6 +273,9 @@ function createPortal(host, container = document.body) {
270
273
  console.warn("Invalid container element. Fallback: <body> element.");
271
274
  container = document.body;
272
275
  }
276
+ if (!containsComposed2(container, host)) {
277
+ throw new Error("Mismatch elements");
278
+ }
273
279
  const portal = new Portal(host, container);
274
280
  return () => portal.destroy();
275
281
  }
@@ -402,6 +408,16 @@ var Portal = class {
402
408
  focusable && focus(focusable);
403
409
  }
404
410
  };
411
+ function containsComposed2(container, element) {
412
+ let current = element;
413
+ while (current) {
414
+ if (current === container) {
415
+ return true;
416
+ }
417
+ current = current instanceof ShadowRoot ? current.mode === "open" ? current.host : null : current.parentNode;
418
+ }
419
+ return false;
420
+ }
405
421
  function focus(element) {
406
422
  "focus" in element && typeof element.focus === "function" && element.focus();
407
423
  }
@@ -417,7 +433,7 @@ function getActiveElement2() {
417
433
  * Lightweight DOM portal (teleport) utility with fully focus management.
418
434
  * Designed for accessible dialogs, menus, overlays, popovers.
419
435
  *
420
- * @version 1.0.1
436
+ * @version 1.0.2
421
437
  * @author Yusuke Kamiyamane
422
438
  * @license MIT
423
439
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -431,7 +447,7 @@ power-focusable/dist/index.js:
431
447
  * High-precision focus management utility with full composed tree support.
432
448
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
433
449
  *
434
- * @version 4.1.2
450
+ * @version 4.1.3
435
451
  * @author Yusuke Kamiyamane
436
452
  * @license MIT
437
453
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/portal",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Lightweight DOM portal (teleport) utility with fully focus management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -48,7 +48,7 @@
48
48
  "homepage": "https://github.com/y14e/portal#readme",
49
49
  "devDependencies": {
50
50
  "bun-types": "latest",
51
- "power-focusable": "^4.1.2",
51
+ "power-focusable": "^4.1.3",
52
52
  "tsup": "^8.0.0",
53
53
  "typescript": "^5.6.0"
54
54
  },