@y14e/portal 1.2.25 → 1.2.27

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/README.md CHANGED
@@ -13,11 +13,11 @@ npm i @y14e/portal
13
13
  import { createPortal } from '@y14e/portal';
14
14
 
15
15
  // CDNs
16
- import { createPortal } from 'https://esm.sh/@y14e/portal@1.2.25';
16
+ import { createPortal } from 'https://esm.sh/@y14e/portal@1.2.27';
17
17
  // or
18
- import { createPortal } from 'https://cdn.jsdelivr.net/npm/@y14e/portal@1.2.25/+esm';
18
+ import { createPortal } from 'https://cdn.jsdelivr.net/npm/@y14e/portal@1.2.27/+esm';
19
19
  // or
20
- import { createPortal } from 'https://esm.unpkg.com/@y14e/portal@1.2.25';
20
+ import { createPortal } from 'https://esm.unpkg.com/@y14e/portal@1.2.27';
21
21
  ```
22
22
 
23
23
  ## 📦 APIs
@@ -426,17 +426,22 @@ var Portal = class {
426
426
  this.#update();
427
427
  this.#controller = new AbortController();
428
428
  const { signal } = this.#controller;
429
- document.addEventListener("focusin", this.#onFocusIn, { signal });
430
- document.addEventListener("keydown", this.#onKeyDown, { signal });
429
+ [this.#entranceSentinel, this.#exitSentinel].forEach((sentinel) => {
430
+ sentinel.addEventListener("focus", this.#onFocus, { signal });
431
+ });
432
+ if (!(this.#host instanceof HTMLElement)) {
433
+ return;
434
+ }
435
+ this.#host.addEventListener("keydown", this.#onKeyDown, { signal });
431
436
  this.#host.setAttribute("data-portaled", "");
432
437
  }
433
- #onFocusIn = (event) => {
434
- const current = event.target;
438
+ #onFocus = (event) => {
439
+ const sentinel = event.target;
435
440
  const previous = event.relatedTarget;
436
441
  if (!(previous instanceof Element)) {
437
442
  return;
438
443
  }
439
- if (current === this.#entranceSentinel) {
444
+ if (sentinel === this.#entranceSentinel) {
440
445
  if (this.#host.contains(previous)) {
441
446
  this.#moveFocus("previous");
442
447
  return;
@@ -452,7 +457,7 @@ var Portal = class {
452
457
  });
453
458
  next && focusElement(next);
454
459
  }
455
- } else if (current === this.#exitSentinel) {
460
+ } else {
456
461
  if (this.#host.contains(previous)) {
457
462
  this.#moveFocus("next");
458
463
  return;
@@ -479,9 +484,6 @@ var Portal = class {
479
484
  if (!(active instanceof Element)) {
480
485
  return;
481
486
  }
482
- if (!this.#host.contains(active)) {
483
- return;
484
- }
485
487
  this.#update();
486
488
  const focusables = this.#getFocusables();
487
489
  if (focusables.length) {
@@ -524,10 +526,13 @@ var Portal = class {
524
526
  return sentinel;
525
527
  }
526
528
  #focusSentinel(isPrevious) {
527
- this.#timer && cancelAnimationFrame(this.#timer);
528
- this.#timer = requestAnimationFrame(
529
- () => (isPrevious ? this.#entranceSentinel : this.#exitSentinel).focus()
530
- );
529
+ const sentinel = isPrevious ? this.#entranceSentinel : this.#exitSentinel;
530
+ if (isPrevious) {
531
+ sentinel.focus();
532
+ } else {
533
+ this.#timer && cancelAnimationFrame(this.#timer);
534
+ this.#timer = requestAnimationFrame(() => sentinel.focus());
535
+ }
531
536
  }
532
537
  #getFocusables() {
533
538
  return getFocusables(this.#host, {
@@ -559,7 +564,7 @@ function containsComposed2(container, element) {
559
564
  * Lightweight DOM portal (teleport) utility with fully focus management.
560
565
  * Designed for accessible dialogs, menus, overlays, popovers.
561
566
  *
562
- * @version 1.2.25
567
+ * @version 1.2.27
563
568
  * @author Yusuke Kamiyamane
564
569
  * @license MIT
565
570
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -584,7 +589,7 @@ power-focusable/dist/index.js:
584
589
  * High-precision focus management utility with full composed tree support.
585
590
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
586
591
  *
587
- * @version 4.3.3
592
+ * @version 4.3.6
588
593
  * @author Yusuke Kamiyamane
589
594
  * @license MIT
590
595
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -424,17 +424,22 @@ var Portal = class {
424
424
  this.#update();
425
425
  this.#controller = new AbortController();
426
426
  const { signal } = this.#controller;
427
- document.addEventListener("focusin", this.#onFocusIn, { signal });
428
- document.addEventListener("keydown", this.#onKeyDown, { signal });
427
+ [this.#entranceSentinel, this.#exitSentinel].forEach((sentinel) => {
428
+ sentinel.addEventListener("focus", this.#onFocus, { signal });
429
+ });
430
+ if (!(this.#host instanceof HTMLElement)) {
431
+ return;
432
+ }
433
+ this.#host.addEventListener("keydown", this.#onKeyDown, { signal });
429
434
  this.#host.setAttribute("data-portaled", "");
430
435
  }
431
- #onFocusIn = (event) => {
432
- const current = event.target;
436
+ #onFocus = (event) => {
437
+ const sentinel = event.target;
433
438
  const previous = event.relatedTarget;
434
439
  if (!(previous instanceof Element)) {
435
440
  return;
436
441
  }
437
- if (current === this.#entranceSentinel) {
442
+ if (sentinel === this.#entranceSentinel) {
438
443
  if (this.#host.contains(previous)) {
439
444
  this.#moveFocus("previous");
440
445
  return;
@@ -450,7 +455,7 @@ var Portal = class {
450
455
  });
451
456
  next && focusElement(next);
452
457
  }
453
- } else if (current === this.#exitSentinel) {
458
+ } else {
454
459
  if (this.#host.contains(previous)) {
455
460
  this.#moveFocus("next");
456
461
  return;
@@ -477,9 +482,6 @@ var Portal = class {
477
482
  if (!(active instanceof Element)) {
478
483
  return;
479
484
  }
480
- if (!this.#host.contains(active)) {
481
- return;
482
- }
483
485
  this.#update();
484
486
  const focusables = this.#getFocusables();
485
487
  if (focusables.length) {
@@ -522,10 +524,13 @@ var Portal = class {
522
524
  return sentinel;
523
525
  }
524
526
  #focusSentinel(isPrevious) {
525
- this.#timer && cancelAnimationFrame(this.#timer);
526
- this.#timer = requestAnimationFrame(
527
- () => (isPrevious ? this.#entranceSentinel : this.#exitSentinel).focus()
528
- );
527
+ const sentinel = isPrevious ? this.#entranceSentinel : this.#exitSentinel;
528
+ if (isPrevious) {
529
+ sentinel.focus();
530
+ } else {
531
+ this.#timer && cancelAnimationFrame(this.#timer);
532
+ this.#timer = requestAnimationFrame(() => sentinel.focus());
533
+ }
529
534
  }
530
535
  #getFocusables() {
531
536
  return getFocusables(this.#host, {
@@ -557,7 +562,7 @@ function containsComposed2(container, element) {
557
562
  * Lightweight DOM portal (teleport) utility with fully focus management.
558
563
  * Designed for accessible dialogs, menus, overlays, popovers.
559
564
  *
560
- * @version 1.2.25
565
+ * @version 1.2.27
561
566
  * @author Yusuke Kamiyamane
562
567
  * @license MIT
563
568
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -582,7 +587,7 @@ power-focusable/dist/index.js:
582
587
  * High-precision focus management utility with full composed tree support.
583
588
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
584
589
  *
585
- * @version 4.3.3
590
+ * @version 4.3.6
586
591
  * @author Yusuke Kamiyamane
587
592
  * @license MIT
588
593
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.cjs CHANGED
@@ -69,17 +69,22 @@ var Portal = class {
69
69
  this.#update();
70
70
  this.#controller = new AbortController();
71
71
  const { signal } = this.#controller;
72
- document.addEventListener("focusin", this.#onFocusIn, { signal });
73
- document.addEventListener("keydown", this.#onKeyDown, { signal });
72
+ [this.#entranceSentinel, this.#exitSentinel].forEach((sentinel) => {
73
+ sentinel.addEventListener("focus", this.#onFocus, { signal });
74
+ });
75
+ if (!(this.#host instanceof HTMLElement)) {
76
+ return;
77
+ }
78
+ this.#host.addEventListener("keydown", this.#onKeyDown, { signal });
74
79
  this.#host.setAttribute("data-portaled", "");
75
80
  }
76
- #onFocusIn = (event) => {
77
- const current = event.target;
81
+ #onFocus = (event) => {
82
+ const sentinel = event.target;
78
83
  const previous = event.relatedTarget;
79
84
  if (!(previous instanceof Element)) {
80
85
  return;
81
86
  }
82
- if (current === this.#entranceSentinel) {
87
+ if (sentinel === this.#entranceSentinel) {
83
88
  if (this.#host.contains(previous)) {
84
89
  this.#moveFocus("previous");
85
90
  return;
@@ -95,7 +100,7 @@ var Portal = class {
95
100
  });
96
101
  next && powerFocusable.focusElement(next);
97
102
  }
98
- } else if (current === this.#exitSentinel) {
103
+ } else {
99
104
  if (this.#host.contains(previous)) {
100
105
  this.#moveFocus("next");
101
106
  return;
@@ -122,9 +127,6 @@ var Portal = class {
122
127
  if (!(active instanceof Element)) {
123
128
  return;
124
129
  }
125
- if (!this.#host.contains(active)) {
126
- return;
127
- }
128
130
  this.#update();
129
131
  const focusables = this.#getFocusables();
130
132
  if (focusables.length) {
@@ -167,10 +169,13 @@ var Portal = class {
167
169
  return sentinel;
168
170
  }
169
171
  #focusSentinel(isPrevious) {
170
- this.#timer && cancelAnimationFrame(this.#timer);
171
- this.#timer = requestAnimationFrame(
172
- () => (isPrevious ? this.#entranceSentinel : this.#exitSentinel).focus()
173
- );
172
+ const sentinel = isPrevious ? this.#entranceSentinel : this.#exitSentinel;
173
+ if (isPrevious) {
174
+ sentinel.focus();
175
+ } else {
176
+ this.#timer && cancelAnimationFrame(this.#timer);
177
+ this.#timer = requestAnimationFrame(() => sentinel.focus());
178
+ }
174
179
  }
175
180
  #getFocusables() {
176
181
  return powerFocusable.getFocusables(this.#host, {
@@ -202,7 +207,7 @@ function containsComposed(container, element) {
202
207
  * Lightweight DOM portal (teleport) utility with fully focus management.
203
208
  * Designed for accessible dialogs, menus, overlays, popovers.
204
209
  *
205
- * @version 1.2.25
210
+ * @version 1.2.27
206
211
  * @author Yusuke Kamiyamane
207
212
  * @license MIT
208
213
  * @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.25
6
+ * @version 1.2.27
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.25
6
+ * @version 1.2.27
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -67,17 +67,22 @@ var Portal = class {
67
67
  this.#update();
68
68
  this.#controller = new AbortController();
69
69
  const { signal } = this.#controller;
70
- document.addEventListener("focusin", this.#onFocusIn, { signal });
71
- document.addEventListener("keydown", this.#onKeyDown, { signal });
70
+ [this.#entranceSentinel, this.#exitSentinel].forEach((sentinel) => {
71
+ sentinel.addEventListener("focus", this.#onFocus, { signal });
72
+ });
73
+ if (!(this.#host instanceof HTMLElement)) {
74
+ return;
75
+ }
76
+ this.#host.addEventListener("keydown", this.#onKeyDown, { signal });
72
77
  this.#host.setAttribute("data-portaled", "");
73
78
  }
74
- #onFocusIn = (event) => {
75
- const current = event.target;
79
+ #onFocus = (event) => {
80
+ const sentinel = event.target;
76
81
  const previous = event.relatedTarget;
77
82
  if (!(previous instanceof Element)) {
78
83
  return;
79
84
  }
80
- if (current === this.#entranceSentinel) {
85
+ if (sentinel === this.#entranceSentinel) {
81
86
  if (this.#host.contains(previous)) {
82
87
  this.#moveFocus("previous");
83
88
  return;
@@ -93,7 +98,7 @@ var Portal = class {
93
98
  });
94
99
  next && focusElement(next);
95
100
  }
96
- } else if (current === this.#exitSentinel) {
101
+ } else {
97
102
  if (this.#host.contains(previous)) {
98
103
  this.#moveFocus("next");
99
104
  return;
@@ -120,9 +125,6 @@ var Portal = class {
120
125
  if (!(active instanceof Element)) {
121
126
  return;
122
127
  }
123
- if (!this.#host.contains(active)) {
124
- return;
125
- }
126
128
  this.#update();
127
129
  const focusables = this.#getFocusables();
128
130
  if (focusables.length) {
@@ -165,10 +167,13 @@ var Portal = class {
165
167
  return sentinel;
166
168
  }
167
169
  #focusSentinel(isPrevious) {
168
- this.#timer && cancelAnimationFrame(this.#timer);
169
- this.#timer = requestAnimationFrame(
170
- () => (isPrevious ? this.#entranceSentinel : this.#exitSentinel).focus()
171
- );
170
+ const sentinel = isPrevious ? this.#entranceSentinel : this.#exitSentinel;
171
+ if (isPrevious) {
172
+ sentinel.focus();
173
+ } else {
174
+ this.#timer && cancelAnimationFrame(this.#timer);
175
+ this.#timer = requestAnimationFrame(() => sentinel.focus());
176
+ }
172
177
  }
173
178
  #getFocusables() {
174
179
  return getFocusables(this.#host, {
@@ -200,7 +205,7 @@ function containsComposed(container, element) {
200
205
  * Lightweight DOM portal (teleport) utility with fully focus management.
201
206
  * Designed for accessible dialogs, menus, overlays, popovers.
202
207
  *
203
- * @version 1.2.25
208
+ * @version 1.2.27
204
209
  * @author Yusuke Kamiyamane
205
210
  * @license MIT
206
211
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/portal",
3
- "version": "1.2.25",
3
+ "version": "1.2.27",
4
4
  "description": "Lightweight DOM portal (teleport) utility with fully focus management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -56,6 +56,6 @@
56
56
  },
57
57
  "dependencies": {
58
58
  "@y14e/attributes-utils": "^1.1.2",
59
- "power-focusable": "^4.3.4"
59
+ "power-focusable": "^4.3.6"
60
60
  }
61
61
  }