@y14e/portal 1.2.21 → 1.2.23

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
@@ -10,14 +10,14 @@ npm i @y14e/portal
10
10
 
11
11
  ```ts
12
12
  // npm
13
- import { createPortal } from '@y14e/portal@1.2.21';
13
+ import { createPortal } from '@y14e/portal@1.2.23';
14
14
 
15
15
  // CDNs
16
- import { createPortal } from 'https://esm.sh/@y14e/portal@1.2.21';
16
+ import { createPortal } from 'https://esm.sh/@y14e/portal@1.2.23';
17
17
  // or
18
- import { createPortal } from 'https://cdn.jsdelivr.net/npm/@y14e/portal@1.2.21/+esm';
18
+ import { createPortal } from 'https://cdn.jsdelivr.net/npm/@y14e/portal@1.2.23/+esm';
19
19
  // or
20
- import { createPortal } from 'https://esm.unpkg.com/@y14e/portal@1.2.21';
20
+ import { createPortal } from 'https://esm.unpkg.com/@y14e/portal@1.2.23';
21
21
  ```
22
22
 
23
23
  ## 📦 APIs
@@ -388,6 +388,7 @@ var Portal = class {
388
388
  #exitSentinel;
389
389
  #focusables = /* @__PURE__ */ new Set();
390
390
  #controller = null;
391
+ #timer;
391
392
  #isDestroyed = false;
392
393
  constructor(host, container) {
393
394
  this.#host = host;
@@ -407,6 +408,10 @@ var Portal = class {
407
408
  this.#isDestroyed = true;
408
409
  this.#controller?.abort();
409
410
  this.#controller = null;
411
+ if (this.#timer !== void 0) {
412
+ cancelAnimationFrame(this.#timer);
413
+ this.#timer = void 0;
414
+ }
410
415
  restoreAttributes([...this.#focusables]);
411
416
  this.#focusables.clear();
412
417
  this.#exitSentinel.after(this.#host);
@@ -433,12 +438,12 @@ var Portal = class {
433
438
  }
434
439
  #onFocusIn = (event) => {
435
440
  const current = event.target;
436
- const before = event.relatedTarget;
437
- if (!(before instanceof Element)) {
441
+ const previous = event.relatedTarget;
442
+ if (!(previous instanceof Element)) {
438
443
  return;
439
444
  }
440
445
  if (current === this.#entranceSentinel) {
441
- if (this.#host.contains(before)) {
446
+ if (this.#host.contains(previous)) {
442
447
  this.#moveFocus("previous");
443
448
  return;
444
449
  }
@@ -454,7 +459,7 @@ var Portal = class {
454
459
  next && focusElement(next);
455
460
  }
456
461
  } else if (current === this.#exitSentinel) {
457
- if (this.#host.contains(before)) {
462
+ if (this.#host.contains(previous)) {
458
463
  this.#moveFocus("next");
459
464
  return;
460
465
  }
@@ -463,11 +468,11 @@ var Portal = class {
463
468
  if (last) {
464
469
  focusElement(last);
465
470
  } else {
466
- const previous = getPreviousFocusable(document.body, {
471
+ const previous2 = getPreviousFocusable(document.body, {
467
472
  anchor: this.#entranceSentinel,
468
473
  composed: true
469
474
  });
470
- previous && focusElement(previous);
475
+ previous2 && focusElement(previous2);
471
476
  }
472
477
  }
473
478
  };
@@ -525,7 +530,10 @@ var Portal = class {
525
530
  return sentinel;
526
531
  }
527
532
  #focusSentinel(isPrevious) {
528
- (isPrevious ? this.#entranceSentinel : this.#exitSentinel).focus();
533
+ this.#timer && cancelAnimationFrame(this.#timer);
534
+ this.#timer = requestAnimationFrame(
535
+ () => (isPrevious ? this.#entranceSentinel : this.#exitSentinel).focus()
536
+ );
529
537
  }
530
538
  #getFocusables() {
531
539
  return getFocusables(this.#host, {
@@ -557,7 +565,7 @@ function containsComposed2(container, element) {
557
565
  * Lightweight DOM portal (teleport) utility with fully focus management.
558
566
  * Designed for accessible dialogs, menus, overlays, popovers.
559
567
  *
560
- * @version 1.2.21
568
+ * @version 1.2.23
561
569
  * @author Yusuke Kamiyamane
562
570
  * @license MIT
563
571
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -386,6 +386,7 @@ var Portal = class {
386
386
  #exitSentinel;
387
387
  #focusables = /* @__PURE__ */ new Set();
388
388
  #controller = null;
389
+ #timer;
389
390
  #isDestroyed = false;
390
391
  constructor(host, container) {
391
392
  this.#host = host;
@@ -405,6 +406,10 @@ var Portal = class {
405
406
  this.#isDestroyed = true;
406
407
  this.#controller?.abort();
407
408
  this.#controller = null;
409
+ if (this.#timer !== void 0) {
410
+ cancelAnimationFrame(this.#timer);
411
+ this.#timer = void 0;
412
+ }
408
413
  restoreAttributes([...this.#focusables]);
409
414
  this.#focusables.clear();
410
415
  this.#exitSentinel.after(this.#host);
@@ -431,12 +436,12 @@ var Portal = class {
431
436
  }
432
437
  #onFocusIn = (event) => {
433
438
  const current = event.target;
434
- const before = event.relatedTarget;
435
- if (!(before instanceof Element)) {
439
+ const previous = event.relatedTarget;
440
+ if (!(previous instanceof Element)) {
436
441
  return;
437
442
  }
438
443
  if (current === this.#entranceSentinel) {
439
- if (this.#host.contains(before)) {
444
+ if (this.#host.contains(previous)) {
440
445
  this.#moveFocus("previous");
441
446
  return;
442
447
  }
@@ -452,7 +457,7 @@ var Portal = class {
452
457
  next && focusElement(next);
453
458
  }
454
459
  } else if (current === this.#exitSentinel) {
455
- if (this.#host.contains(before)) {
460
+ if (this.#host.contains(previous)) {
456
461
  this.#moveFocus("next");
457
462
  return;
458
463
  }
@@ -461,11 +466,11 @@ var Portal = class {
461
466
  if (last) {
462
467
  focusElement(last);
463
468
  } else {
464
- const previous = getPreviousFocusable(document.body, {
469
+ const previous2 = getPreviousFocusable(document.body, {
465
470
  anchor: this.#entranceSentinel,
466
471
  composed: true
467
472
  });
468
- previous && focusElement(previous);
473
+ previous2 && focusElement(previous2);
469
474
  }
470
475
  }
471
476
  };
@@ -523,7 +528,10 @@ var Portal = class {
523
528
  return sentinel;
524
529
  }
525
530
  #focusSentinel(isPrevious) {
526
- (isPrevious ? this.#entranceSentinel : this.#exitSentinel).focus();
531
+ this.#timer && cancelAnimationFrame(this.#timer);
532
+ this.#timer = requestAnimationFrame(
533
+ () => (isPrevious ? this.#entranceSentinel : this.#exitSentinel).focus()
534
+ );
527
535
  }
528
536
  #getFocusables() {
529
537
  return getFocusables(this.#host, {
@@ -555,7 +563,7 @@ function containsComposed2(container, element) {
555
563
  * Lightweight DOM portal (teleport) utility with fully focus management.
556
564
  * Designed for accessible dialogs, menus, overlays, popovers.
557
565
  *
558
- * @version 1.2.21
566
+ * @version 1.2.23
559
567
  * @author Yusuke Kamiyamane
560
568
  * @license MIT
561
569
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.cjs CHANGED
@@ -31,6 +31,7 @@ var Portal = class {
31
31
  #exitSentinel;
32
32
  #focusables = /* @__PURE__ */ new Set();
33
33
  #controller = null;
34
+ #timer;
34
35
  #isDestroyed = false;
35
36
  constructor(host, container) {
36
37
  this.#host = host;
@@ -50,6 +51,10 @@ var Portal = class {
50
51
  this.#isDestroyed = true;
51
52
  this.#controller?.abort();
52
53
  this.#controller = null;
54
+ if (this.#timer !== void 0) {
55
+ cancelAnimationFrame(this.#timer);
56
+ this.#timer = void 0;
57
+ }
53
58
  attributesUtils.restoreAttributes([...this.#focusables]);
54
59
  this.#focusables.clear();
55
60
  this.#exitSentinel.after(this.#host);
@@ -76,12 +81,12 @@ var Portal = class {
76
81
  }
77
82
  #onFocusIn = (event) => {
78
83
  const current = event.target;
79
- const before = event.relatedTarget;
80
- if (!(before instanceof Element)) {
84
+ const previous = event.relatedTarget;
85
+ if (!(previous instanceof Element)) {
81
86
  return;
82
87
  }
83
88
  if (current === this.#entranceSentinel) {
84
- if (this.#host.contains(before)) {
89
+ if (this.#host.contains(previous)) {
85
90
  this.#moveFocus("previous");
86
91
  return;
87
92
  }
@@ -97,7 +102,7 @@ var Portal = class {
97
102
  next && powerFocusable.focusElement(next);
98
103
  }
99
104
  } else if (current === this.#exitSentinel) {
100
- if (this.#host.contains(before)) {
105
+ if (this.#host.contains(previous)) {
101
106
  this.#moveFocus("next");
102
107
  return;
103
108
  }
@@ -106,11 +111,11 @@ var Portal = class {
106
111
  if (last) {
107
112
  powerFocusable.focusElement(last);
108
113
  } else {
109
- const previous = powerFocusable.getPreviousFocusable(document.body, {
114
+ const previous2 = powerFocusable.getPreviousFocusable(document.body, {
110
115
  anchor: this.#entranceSentinel,
111
116
  composed: true
112
117
  });
113
- previous && powerFocusable.focusElement(previous);
118
+ previous2 && powerFocusable.focusElement(previous2);
114
119
  }
115
120
  }
116
121
  };
@@ -168,7 +173,10 @@ var Portal = class {
168
173
  return sentinel;
169
174
  }
170
175
  #focusSentinel(isPrevious) {
171
- (isPrevious ? this.#entranceSentinel : this.#exitSentinel).focus();
176
+ this.#timer && cancelAnimationFrame(this.#timer);
177
+ this.#timer = requestAnimationFrame(
178
+ () => (isPrevious ? this.#entranceSentinel : this.#exitSentinel).focus()
179
+ );
172
180
  }
173
181
  #getFocusables() {
174
182
  return powerFocusable.getFocusables(this.#host, {
@@ -200,7 +208,7 @@ function containsComposed(container, element) {
200
208
  * Lightweight DOM portal (teleport) utility with fully focus management.
201
209
  * Designed for accessible dialogs, menus, overlays, popovers.
202
210
  *
203
- * @version 1.2.21
211
+ * @version 1.2.23
204
212
  * @author Yusuke Kamiyamane
205
213
  * @license MIT
206
214
  * @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.21
6
+ * @version 1.2.23
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.21
6
+ * @version 1.2.23
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -29,6 +29,7 @@ var Portal = class {
29
29
  #exitSentinel;
30
30
  #focusables = /* @__PURE__ */ new Set();
31
31
  #controller = null;
32
+ #timer;
32
33
  #isDestroyed = false;
33
34
  constructor(host, container) {
34
35
  this.#host = host;
@@ -48,6 +49,10 @@ var Portal = class {
48
49
  this.#isDestroyed = true;
49
50
  this.#controller?.abort();
50
51
  this.#controller = null;
52
+ if (this.#timer !== void 0) {
53
+ cancelAnimationFrame(this.#timer);
54
+ this.#timer = void 0;
55
+ }
51
56
  restoreAttributes([...this.#focusables]);
52
57
  this.#focusables.clear();
53
58
  this.#exitSentinel.after(this.#host);
@@ -74,12 +79,12 @@ var Portal = class {
74
79
  }
75
80
  #onFocusIn = (event) => {
76
81
  const current = event.target;
77
- const before = event.relatedTarget;
78
- if (!(before instanceof Element)) {
82
+ const previous = event.relatedTarget;
83
+ if (!(previous instanceof Element)) {
79
84
  return;
80
85
  }
81
86
  if (current === this.#entranceSentinel) {
82
- if (this.#host.contains(before)) {
87
+ if (this.#host.contains(previous)) {
83
88
  this.#moveFocus("previous");
84
89
  return;
85
90
  }
@@ -95,7 +100,7 @@ var Portal = class {
95
100
  next && focusElement(next);
96
101
  }
97
102
  } else if (current === this.#exitSentinel) {
98
- if (this.#host.contains(before)) {
103
+ if (this.#host.contains(previous)) {
99
104
  this.#moveFocus("next");
100
105
  return;
101
106
  }
@@ -104,11 +109,11 @@ var Portal = class {
104
109
  if (last) {
105
110
  focusElement(last);
106
111
  } else {
107
- const previous = getPreviousFocusable(document.body, {
112
+ const previous2 = getPreviousFocusable(document.body, {
108
113
  anchor: this.#entranceSentinel,
109
114
  composed: true
110
115
  });
111
- previous && focusElement(previous);
116
+ previous2 && focusElement(previous2);
112
117
  }
113
118
  }
114
119
  };
@@ -166,7 +171,10 @@ var Portal = class {
166
171
  return sentinel;
167
172
  }
168
173
  #focusSentinel(isPrevious) {
169
- (isPrevious ? this.#entranceSentinel : this.#exitSentinel).focus();
174
+ this.#timer && cancelAnimationFrame(this.#timer);
175
+ this.#timer = requestAnimationFrame(
176
+ () => (isPrevious ? this.#entranceSentinel : this.#exitSentinel).focus()
177
+ );
170
178
  }
171
179
  #getFocusables() {
172
180
  return getFocusables(this.#host, {
@@ -198,7 +206,7 @@ function containsComposed(container, element) {
198
206
  * Lightweight DOM portal (teleport) utility with fully focus management.
199
207
  * Designed for accessible dialogs, menus, overlays, popovers.
200
208
  *
201
- * @version 1.2.21
209
+ * @version 1.2.23
202
210
  * @author Yusuke Kamiyamane
203
211
  * @license MIT
204
212
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/portal",
3
- "version": "1.2.21",
3
+ "version": "1.2.23",
4
4
  "description": "Lightweight DOM portal (teleport) utility with fully focus management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",