@y14e/portal 1.2.4 → 1.2.6

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
@@ -3,10 +3,10 @@
3
3
  // node_modules/@y14e/attributes-utils/dist/index.js
4
4
  var snapshots = /* @__PURE__ */ new WeakMap();
5
5
  function restoreAttributes(elements) {
6
- elements.forEach((element) => {
6
+ for (const element of elements) {
7
7
  const snapshot = snapshots.get(element);
8
8
  if (!snapshot) {
9
- return;
9
+ continue;
10
10
  }
11
11
  for (const [attribute, value] of snapshot.entries()) {
12
12
  if (value === null) {
@@ -16,7 +16,7 @@ function restoreAttributes(elements) {
16
16
  }
17
17
  }
18
18
  snapshots.delete(element);
19
- });
19
+ }
20
20
  }
21
21
  function saveAttributes(elements, attributes) {
22
22
  elements.forEach((element) => {
@@ -38,14 +38,17 @@ function getFocusables(container = document.body, options = {}) {
38
38
  console.warn("Invalid container element. Fallback: <body> element.");
39
39
  container = document.body;
40
40
  }
41
- const { composed = false } = options;
42
- let { filter, include } = options;
43
- if (filter && typeof filter !== "function") {
44
- console.warn("Invalid filter function");
41
+ let { composed = false, filter, include } = options;
42
+ if (typeof composed !== "boolean") {
43
+ console.warn("Invalid composed. Fallback: false.");
44
+ composed = false;
45
+ }
46
+ if (typeof filter !== "undefined" && typeof filter !== "function") {
47
+ console.warn("Invalid filter. Fallback: no filter function (undefined).");
45
48
  filter = void 0;
46
49
  }
47
- if (include && typeof include !== "function") {
48
- console.warn("Invalid include function");
50
+ if (typeof include !== "undefined" && typeof include !== "function") {
51
+ console.warn("Invalid include. Fallback: no include function (undefined).");
49
52
  include = void 0;
50
53
  }
51
54
  const elements = [];
@@ -82,17 +85,9 @@ function getFocusables(container = document.body, options = {}) {
82
85
  return filter ? unfiltered.filter(filter) : unfiltered;
83
86
  }
84
87
  function getNextFocusable(container = document.body, options = {}) {
85
- if (!(container instanceof Element)) {
86
- console.warn("Invalid container element. Fallback: <body> element.");
87
- container = document.body;
88
- }
89
88
  return getRelativeFocusable(container, 1, options);
90
89
  }
91
90
  function getPreviousFocusable(container = document.body, options = {}) {
92
- if (!(container instanceof Element)) {
93
- console.warn("Invalid container element. Fallback: <body> element.");
94
- container = document.body;
95
- }
96
91
  return getRelativeFocusable(container, -1, options);
97
92
  }
98
93
  function isFocusable(element) {
@@ -122,8 +117,17 @@ function isFocusable(element) {
122
117
  return true;
123
118
  }
124
119
  function getRelativeFocusable(container, offset, options) {
125
- let anchor = options.anchor ?? getActiveElement();
126
- const { composed = false, filter, include, wrap = false } = options;
120
+ if (!(container instanceof Element)) {
121
+ console.warn("Invalid container element. Fallback: <body> element.");
122
+ container = document.body;
123
+ }
124
+ let {
125
+ anchor = getActiveElement(),
126
+ composed = false,
127
+ filter,
128
+ include,
129
+ wrap = false
130
+ } = options;
127
131
  if (!(anchor instanceof Element)) {
128
132
  const active = getActiveElement();
129
133
  if (active instanceof Element) {
@@ -138,6 +142,22 @@ function getRelativeFocusable(container, offset, options) {
138
142
  console.warn("Anchor (active) element not within container");
139
143
  return null;
140
144
  }
145
+ if (typeof composed !== "boolean") {
146
+ console.warn("Invalid composed. Fallback: false.");
147
+ composed = false;
148
+ }
149
+ if (typeof filter !== "undefined" && typeof filter !== "function") {
150
+ console.warn("Invalid filter. Fallback: no filter function (undefined).");
151
+ filter = void 0;
152
+ }
153
+ if (typeof include !== "undefined" && typeof include !== "function") {
154
+ console.warn("Invalid include. Fallback: no include function (undefined).");
155
+ include = void 0;
156
+ }
157
+ if (typeof wrap !== "boolean") {
158
+ console.warn("Invalid wrap. Fallback: false.");
159
+ wrap = false;
160
+ }
141
161
  const focusables = getFocusables(container, { composed, filter, include });
142
162
  const { length } = focusables;
143
163
  if (!length) {
@@ -416,34 +436,30 @@ var Portal = class {
416
436
  }
417
437
  event.preventDefault();
418
438
  const focusable = focusables[index + (shiftKey ? -1 : 1)];
419
- if (focusable) {
420
- focusElement(focusable);
421
- } else {
422
- this.#focusSentinel(shiftKey);
423
- }
439
+ focusable ? focusElement(focusable) : this.#focusSentinel(shiftKey);
424
440
  };
425
441
  #update() {
426
442
  const current = /* @__PURE__ */ new Set([
427
443
  ...this.#getFocusables(),
428
444
  ...getFocusables(this.#host, { composed: true })
429
445
  ]);
430
- this.#focusables.forEach((focusable) => {
446
+ for (const focusable of this.#focusables) {
431
447
  if (current.has(focusable)) {
432
- return;
448
+ continue;
433
449
  }
434
450
  if (focusable.isConnected) {
435
451
  restoreAttributes([focusable]);
436
452
  }
437
453
  this.#focusables.delete(focusable);
438
- });
439
- current.forEach((c) => {
454
+ }
455
+ for (const c of current) {
440
456
  if (this.#focusables.has(c)) {
441
- return;
457
+ continue;
442
458
  }
443
459
  this.#focusables.add(c);
444
460
  saveAttributes([c], ["tabindex"]);
445
461
  c.setAttribute("tabindex", "-1");
446
- });
462
+ }
447
463
  }
448
464
  #createSentinel() {
449
465
  const sentinel = document.createElement("span");
@@ -498,7 +514,7 @@ function getActiveElement2() {
498
514
  * Lightweight DOM portal (teleport) utility with fully focus management.
499
515
  * Designed for accessible dialogs, menus, overlays, popovers.
500
516
  *
501
- * @version 1.2.4
517
+ * @version 1.2.6
502
518
  * @author Yusuke Kamiyamane
503
519
  * @license MIT
504
520
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -510,7 +526,7 @@ function getActiveElement2() {
510
526
  (**
511
527
  * Attributes Utils
512
528
  *
513
- * @version 1.0.0
529
+ * @version 1.0.2
514
530
  * @author Yusuke Kamiyamane
515
531
  * @license MIT
516
532
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -523,7 +539,7 @@ power-focusable/dist/index.js:
523
539
  * High-precision focus management utility with full composed tree support.
524
540
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
525
541
  *
526
- * @version 4.1.5
542
+ * @version 4.1.7
527
543
  * @author Yusuke Kamiyamane
528
544
  * @license MIT
529
545
  * @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.2.4
6
+ * @version 1.2.6
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.2.4
6
+ * @version 1.2.6
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  // node_modules/@y14e/attributes-utils/dist/index.js
2
2
  var snapshots = /* @__PURE__ */ new WeakMap();
3
3
  function restoreAttributes(elements) {
4
- elements.forEach((element) => {
4
+ for (const element of elements) {
5
5
  const snapshot = snapshots.get(element);
6
6
  if (!snapshot) {
7
- return;
7
+ continue;
8
8
  }
9
9
  for (const [attribute, value] of snapshot.entries()) {
10
10
  if (value === null) {
@@ -14,7 +14,7 @@ function restoreAttributes(elements) {
14
14
  }
15
15
  }
16
16
  snapshots.delete(element);
17
- });
17
+ }
18
18
  }
19
19
  function saveAttributes(elements, attributes) {
20
20
  elements.forEach((element) => {
@@ -36,14 +36,17 @@ function getFocusables(container = document.body, options = {}) {
36
36
  console.warn("Invalid container element. Fallback: <body> element.");
37
37
  container = document.body;
38
38
  }
39
- const { composed = false } = options;
40
- let { filter, include } = options;
41
- if (filter && typeof filter !== "function") {
42
- console.warn("Invalid filter function");
39
+ let { composed = false, filter, include } = options;
40
+ if (typeof composed !== "boolean") {
41
+ console.warn("Invalid composed. Fallback: false.");
42
+ composed = false;
43
+ }
44
+ if (typeof filter !== "undefined" && typeof filter !== "function") {
45
+ console.warn("Invalid filter. Fallback: no filter function (undefined).");
43
46
  filter = void 0;
44
47
  }
45
- if (include && typeof include !== "function") {
46
- console.warn("Invalid include function");
48
+ if (typeof include !== "undefined" && typeof include !== "function") {
49
+ console.warn("Invalid include. Fallback: no include function (undefined).");
47
50
  include = void 0;
48
51
  }
49
52
  const elements = [];
@@ -80,17 +83,9 @@ function getFocusables(container = document.body, options = {}) {
80
83
  return filter ? unfiltered.filter(filter) : unfiltered;
81
84
  }
82
85
  function getNextFocusable(container = document.body, options = {}) {
83
- if (!(container instanceof Element)) {
84
- console.warn("Invalid container element. Fallback: <body> element.");
85
- container = document.body;
86
- }
87
86
  return getRelativeFocusable(container, 1, options);
88
87
  }
89
88
  function getPreviousFocusable(container = document.body, options = {}) {
90
- if (!(container instanceof Element)) {
91
- console.warn("Invalid container element. Fallback: <body> element.");
92
- container = document.body;
93
- }
94
89
  return getRelativeFocusable(container, -1, options);
95
90
  }
96
91
  function isFocusable(element) {
@@ -120,8 +115,17 @@ function isFocusable(element) {
120
115
  return true;
121
116
  }
122
117
  function getRelativeFocusable(container, offset, options) {
123
- let anchor = options.anchor ?? getActiveElement();
124
- const { composed = false, filter, include, wrap = false } = options;
118
+ if (!(container instanceof Element)) {
119
+ console.warn("Invalid container element. Fallback: <body> element.");
120
+ container = document.body;
121
+ }
122
+ let {
123
+ anchor = getActiveElement(),
124
+ composed = false,
125
+ filter,
126
+ include,
127
+ wrap = false
128
+ } = options;
125
129
  if (!(anchor instanceof Element)) {
126
130
  const active = getActiveElement();
127
131
  if (active instanceof Element) {
@@ -136,6 +140,22 @@ function getRelativeFocusable(container, offset, options) {
136
140
  console.warn("Anchor (active) element not within container");
137
141
  return null;
138
142
  }
143
+ if (typeof composed !== "boolean") {
144
+ console.warn("Invalid composed. Fallback: false.");
145
+ composed = false;
146
+ }
147
+ if (typeof filter !== "undefined" && typeof filter !== "function") {
148
+ console.warn("Invalid filter. Fallback: no filter function (undefined).");
149
+ filter = void 0;
150
+ }
151
+ if (typeof include !== "undefined" && typeof include !== "function") {
152
+ console.warn("Invalid include. Fallback: no include function (undefined).");
153
+ include = void 0;
154
+ }
155
+ if (typeof wrap !== "boolean") {
156
+ console.warn("Invalid wrap. Fallback: false.");
157
+ wrap = false;
158
+ }
139
159
  const focusables = getFocusables(container, { composed, filter, include });
140
160
  const { length } = focusables;
141
161
  if (!length) {
@@ -414,34 +434,30 @@ var Portal = class {
414
434
  }
415
435
  event.preventDefault();
416
436
  const focusable = focusables[index + (shiftKey ? -1 : 1)];
417
- if (focusable) {
418
- focusElement(focusable);
419
- } else {
420
- this.#focusSentinel(shiftKey);
421
- }
437
+ focusable ? focusElement(focusable) : this.#focusSentinel(shiftKey);
422
438
  };
423
439
  #update() {
424
440
  const current = /* @__PURE__ */ new Set([
425
441
  ...this.#getFocusables(),
426
442
  ...getFocusables(this.#host, { composed: true })
427
443
  ]);
428
- this.#focusables.forEach((focusable) => {
444
+ for (const focusable of this.#focusables) {
429
445
  if (current.has(focusable)) {
430
- return;
446
+ continue;
431
447
  }
432
448
  if (focusable.isConnected) {
433
449
  restoreAttributes([focusable]);
434
450
  }
435
451
  this.#focusables.delete(focusable);
436
- });
437
- current.forEach((c) => {
452
+ }
453
+ for (const c of current) {
438
454
  if (this.#focusables.has(c)) {
439
- return;
455
+ continue;
440
456
  }
441
457
  this.#focusables.add(c);
442
458
  saveAttributes([c], ["tabindex"]);
443
459
  c.setAttribute("tabindex", "-1");
444
- });
460
+ }
445
461
  }
446
462
  #createSentinel() {
447
463
  const sentinel = document.createElement("span");
@@ -496,7 +512,7 @@ function getActiveElement2() {
496
512
  * Lightweight DOM portal (teleport) utility with fully focus management.
497
513
  * Designed for accessible dialogs, menus, overlays, popovers.
498
514
  *
499
- * @version 1.2.4
515
+ * @version 1.2.6
500
516
  * @author Yusuke Kamiyamane
501
517
  * @license MIT
502
518
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -508,7 +524,7 @@ function getActiveElement2() {
508
524
  (**
509
525
  * Attributes Utils
510
526
  *
511
- * @version 1.0.0
527
+ * @version 1.0.2
512
528
  * @author Yusuke Kamiyamane
513
529
  * @license MIT
514
530
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -521,7 +537,7 @@ power-focusable/dist/index.js:
521
537
  * High-precision focus management utility with full composed tree support.
522
538
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
523
539
  *
524
- * @version 4.1.5
540
+ * @version 4.1.7
525
541
  * @author Yusuke Kamiyamane
526
542
  * @license MIT
527
543
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/portal",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "description": "Lightweight DOM portal (teleport) utility with fully focus management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -47,9 +47,9 @@
47
47
  },
48
48
  "homepage": "https://github.com/y14e/portal#readme",
49
49
  "devDependencies": {
50
- "@y14e/attributes-utils": "^1.0.0",
50
+ "@y14e/attributes-utils": "^1.0.2",
51
51
  "bun-types": "latest",
52
- "power-focusable": "^4.1.5",
52
+ "power-focusable": "^4.1.7",
53
53
  "tsup": "^8.0.0",
54
54
  "typescript": "^5.6.0"
55
55
  },