@y14e/portal 1.2.8 → 1.2.9
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 +4 -7
- package/dist/index.cjs +70 -20
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +70 -20
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Lightweight DOM portal (teleport) utility with fully focus management. Designed for accessible dialogs, menus, overlays, popovers.
|
|
4
4
|
|
|
5
|
-
> [!NOTE]
|
|
6
|
-
> Focus traversal works across portals using invisible sentinels and composed-tree-aware focus detection powered by [Power Focusable](https://github.com/y14e/power-focusable).
|
|
7
|
-
|
|
8
5
|
## Install
|
|
9
6
|
|
|
10
7
|
```bash
|
|
@@ -13,14 +10,14 @@ npm i @y14e/portal
|
|
|
13
10
|
|
|
14
11
|
```ts
|
|
15
12
|
// npm
|
|
16
|
-
import { createPortal } from '@y14e/portal';
|
|
13
|
+
import { createPortal } from '@y14e/portal@1.2.9';
|
|
17
14
|
|
|
18
15
|
// CDNs
|
|
19
|
-
import { createPortal } from 'https://esm.sh/@y14e/portal'
|
|
16
|
+
import { createPortal } from 'https://esm.sh/@y14e/portal@1.2.9';
|
|
20
17
|
// or
|
|
21
|
-
import { createPortal } from 'https://cdn.jsdelivr.net/npm/@y14e/portal/+esm';
|
|
18
|
+
import { createPortal } from 'https://cdn.jsdelivr.net/npm/@y14e/portal@1.2.9/+esm';
|
|
22
19
|
// or
|
|
23
|
-
import { createPortal } from 'https://unpkg.com/@y14e/portal
|
|
20
|
+
import { createPortal } from 'https://esm.unpkg.com/@y14e/portal@1.2.9';
|
|
24
21
|
```
|
|
25
22
|
|
|
26
23
|
## 📦 APIs
|
package/dist/index.cjs
CHANGED
|
@@ -34,7 +34,13 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
34
34
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
35
35
|
container = document.body;
|
|
36
36
|
}
|
|
37
|
-
let {
|
|
37
|
+
let {
|
|
38
|
+
composed = false,
|
|
39
|
+
filter,
|
|
40
|
+
include,
|
|
41
|
+
skipNegativeTabIndexCheck = false,
|
|
42
|
+
skipVisibilityCheck = false
|
|
43
|
+
} = options;
|
|
38
44
|
if (typeof composed !== "boolean") {
|
|
39
45
|
console.warn("Invalid composed option. Fallback: false.");
|
|
40
46
|
composed = false;
|
|
@@ -51,11 +57,22 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
51
57
|
);
|
|
52
58
|
include = void 0;
|
|
53
59
|
}
|
|
60
|
+
if (typeof skipNegativeTabIndexCheck !== "boolean") {
|
|
61
|
+
console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
|
|
62
|
+
skipNegativeTabIndexCheck = false;
|
|
63
|
+
}
|
|
64
|
+
if (typeof skipVisibilityCheck !== "boolean") {
|
|
65
|
+
console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
|
|
66
|
+
skipVisibilityCheck = false;
|
|
67
|
+
}
|
|
54
68
|
const elements = [];
|
|
55
69
|
if (composed || include) {
|
|
56
70
|
let traverse2 = function(node) {
|
|
57
71
|
if (node instanceof Element) {
|
|
58
|
-
if (isFocusable(node
|
|
72
|
+
if (isFocusable(node, {
|
|
73
|
+
skipNegativeTabIndexCheck,
|
|
74
|
+
skipVisibilityCheck
|
|
75
|
+
}) || include?.(node)) {
|
|
59
76
|
elements[elements.length] = node;
|
|
60
77
|
}
|
|
61
78
|
}
|
|
@@ -76,7 +93,10 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
76
93
|
if (!(candidate instanceof Element)) {
|
|
77
94
|
continue;
|
|
78
95
|
}
|
|
79
|
-
if (isFocusable(candidate
|
|
96
|
+
if (isFocusable(candidate, {
|
|
97
|
+
skipNegativeTabIndexCheck,
|
|
98
|
+
skipVisibilityCheck
|
|
99
|
+
})) {
|
|
80
100
|
elements[elements.length] = candidate;
|
|
81
101
|
}
|
|
82
102
|
}
|
|
@@ -90,24 +110,35 @@ function getNextFocusable(container = document.body, options = {}) {
|
|
|
90
110
|
function getPreviousFocusable(container = document.body, options = {}) {
|
|
91
111
|
return getRelativeFocusable(container, -1, options);
|
|
92
112
|
}
|
|
93
|
-
function isFocusable(element) {
|
|
113
|
+
function isFocusable(element, options = {}) {
|
|
94
114
|
if (!(element instanceof Element)) {
|
|
95
115
|
console.warn("Invalid element");
|
|
96
116
|
return false;
|
|
97
117
|
}
|
|
118
|
+
let { skipNegativeTabIndexCheck = false, skipVisibilityCheck = false } = options;
|
|
119
|
+
if (typeof skipNegativeTabIndexCheck !== "boolean") {
|
|
120
|
+
console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
|
|
121
|
+
skipNegativeTabIndexCheck = false;
|
|
122
|
+
}
|
|
123
|
+
if (typeof skipVisibilityCheck !== "boolean") {
|
|
124
|
+
console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
|
|
125
|
+
skipVisibilityCheck = false;
|
|
126
|
+
}
|
|
98
127
|
if (element.hasAttribute("hidden") || isInert(element)) {
|
|
99
128
|
return false;
|
|
100
129
|
}
|
|
101
|
-
if (getTabIndex(element) < 0) {
|
|
130
|
+
if (!skipNegativeTabIndexCheck && getTabIndex(element) < 0) {
|
|
102
131
|
return false;
|
|
103
132
|
}
|
|
104
|
-
if (!element.matches(
|
|
133
|
+
if (!element.matches(
|
|
134
|
+
skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR.replace(/(,\s*)?\[tabindex="-1"\]/g, "") : FOCUSABLE_SELECTOR
|
|
135
|
+
)) {
|
|
105
136
|
return false;
|
|
106
137
|
}
|
|
107
138
|
if (isDisabledDeep(element)) {
|
|
108
139
|
return false;
|
|
109
140
|
}
|
|
110
|
-
if (!element.checkVisibility({
|
|
141
|
+
if (!skipVisibilityCheck && !element.checkVisibility({
|
|
111
142
|
contentVisibilityAuto: true,
|
|
112
143
|
opacityProperty: true,
|
|
113
144
|
visibilityProperty: true
|
|
@@ -126,6 +157,8 @@ function getRelativeFocusable(container, offset, options) {
|
|
|
126
157
|
composed = false,
|
|
127
158
|
filter,
|
|
128
159
|
include,
|
|
160
|
+
skipNegativeTabIndexCheck = false,
|
|
161
|
+
skipVisibilityCheck = false,
|
|
129
162
|
wrap = false
|
|
130
163
|
} = options;
|
|
131
164
|
if (!(anchor instanceof Element)) {
|
|
@@ -158,11 +191,26 @@ function getRelativeFocusable(container, offset, options) {
|
|
|
158
191
|
);
|
|
159
192
|
include = void 0;
|
|
160
193
|
}
|
|
194
|
+
if (typeof skipNegativeTabIndexCheck !== "boolean") {
|
|
195
|
+
console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
|
|
196
|
+
skipNegativeTabIndexCheck = false;
|
|
197
|
+
}
|
|
198
|
+
if (typeof skipVisibilityCheck !== "boolean") {
|
|
199
|
+
console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
|
|
200
|
+
skipVisibilityCheck = false;
|
|
201
|
+
}
|
|
161
202
|
if (typeof wrap !== "boolean") {
|
|
162
203
|
console.warn("Invalid wrap option. Fallback: false.");
|
|
163
204
|
wrap = false;
|
|
164
205
|
}
|
|
165
|
-
const
|
|
206
|
+
const settings = { composed, skipNegativeTabIndexCheck, skipVisibilityCheck };
|
|
207
|
+
if (filter !== void 0) {
|
|
208
|
+
Object.assign(settings, { filter });
|
|
209
|
+
}
|
|
210
|
+
if (include !== void 0) {
|
|
211
|
+
Object.assign(settings, { include });
|
|
212
|
+
}
|
|
213
|
+
const focusables = getFocusables(container, settings);
|
|
166
214
|
const { length } = focusables;
|
|
167
215
|
if (!length) {
|
|
168
216
|
return null;
|
|
@@ -400,19 +448,21 @@ var Portal = class {
|
|
|
400
448
|
if (current === this.#entranceSentinel) {
|
|
401
449
|
if (this.#host.contains(before)) {
|
|
402
450
|
this.#moveFocus("previous");
|
|
403
|
-
|
|
404
|
-
this.#update();
|
|
405
|
-
const first = [...this.#focusables][0];
|
|
406
|
-
first && focusElement(first);
|
|
451
|
+
return;
|
|
407
452
|
}
|
|
408
|
-
|
|
453
|
+
this.#update();
|
|
454
|
+
const first = [...this.#focusables][0];
|
|
455
|
+
first && focusElement(first);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
if (current === this.#exitSentinel) {
|
|
409
459
|
if (this.#host.contains(before)) {
|
|
410
460
|
this.#moveFocus("next");
|
|
411
|
-
|
|
412
|
-
this.#update();
|
|
413
|
-
const last = [...this.#focusables].at(-1);
|
|
414
|
-
last && focusElement(last);
|
|
461
|
+
return;
|
|
415
462
|
}
|
|
463
|
+
this.#update();
|
|
464
|
+
const last = [...this.#focusables].at(-1);
|
|
465
|
+
last && focusElement(last);
|
|
416
466
|
}
|
|
417
467
|
};
|
|
418
468
|
#onKeyDown = (event) => {
|
|
@@ -516,7 +566,7 @@ function getActiveElement2() {
|
|
|
516
566
|
* Lightweight DOM portal (teleport) utility with fully focus management.
|
|
517
567
|
* Designed for accessible dialogs, menus, overlays, popovers.
|
|
518
568
|
*
|
|
519
|
-
* @version 1.2.
|
|
569
|
+
* @version 1.2.9
|
|
520
570
|
* @author Yusuke Kamiyamane
|
|
521
571
|
* @license MIT
|
|
522
572
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -528,7 +578,7 @@ function getActiveElement2() {
|
|
|
528
578
|
(**
|
|
529
579
|
* Attributes Utils
|
|
530
580
|
*
|
|
531
|
-
* @version 1.0
|
|
581
|
+
* @version 1.1.0
|
|
532
582
|
* @author Yusuke Kamiyamane
|
|
533
583
|
* @license MIT
|
|
534
584
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -541,7 +591,7 @@ power-focusable/dist/index.js:
|
|
|
541
591
|
* High-precision focus management utility with full composed tree support.
|
|
542
592
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
543
593
|
*
|
|
544
|
-
* @version 4.1
|
|
594
|
+
* @version 4.3.1
|
|
545
595
|
* @author Yusuke Kamiyamane
|
|
546
596
|
* @license MIT
|
|
547
597
|
* @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.
|
|
6
|
+
* @version 1.2.9
|
|
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.
|
|
6
|
+
* @version 1.2.9
|
|
7
7
|
* @author Yusuke Kamiyamane
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.js
CHANGED
|
@@ -32,7 +32,13 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
32
32
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
33
33
|
container = document.body;
|
|
34
34
|
}
|
|
35
|
-
let {
|
|
35
|
+
let {
|
|
36
|
+
composed = false,
|
|
37
|
+
filter,
|
|
38
|
+
include,
|
|
39
|
+
skipNegativeTabIndexCheck = false,
|
|
40
|
+
skipVisibilityCheck = false
|
|
41
|
+
} = options;
|
|
36
42
|
if (typeof composed !== "boolean") {
|
|
37
43
|
console.warn("Invalid composed option. Fallback: false.");
|
|
38
44
|
composed = false;
|
|
@@ -49,11 +55,22 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
49
55
|
);
|
|
50
56
|
include = void 0;
|
|
51
57
|
}
|
|
58
|
+
if (typeof skipNegativeTabIndexCheck !== "boolean") {
|
|
59
|
+
console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
|
|
60
|
+
skipNegativeTabIndexCheck = false;
|
|
61
|
+
}
|
|
62
|
+
if (typeof skipVisibilityCheck !== "boolean") {
|
|
63
|
+
console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
|
|
64
|
+
skipVisibilityCheck = false;
|
|
65
|
+
}
|
|
52
66
|
const elements = [];
|
|
53
67
|
if (composed || include) {
|
|
54
68
|
let traverse2 = function(node) {
|
|
55
69
|
if (node instanceof Element) {
|
|
56
|
-
if (isFocusable(node
|
|
70
|
+
if (isFocusable(node, {
|
|
71
|
+
skipNegativeTabIndexCheck,
|
|
72
|
+
skipVisibilityCheck
|
|
73
|
+
}) || include?.(node)) {
|
|
57
74
|
elements[elements.length] = node;
|
|
58
75
|
}
|
|
59
76
|
}
|
|
@@ -74,7 +91,10 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
74
91
|
if (!(candidate instanceof Element)) {
|
|
75
92
|
continue;
|
|
76
93
|
}
|
|
77
|
-
if (isFocusable(candidate
|
|
94
|
+
if (isFocusable(candidate, {
|
|
95
|
+
skipNegativeTabIndexCheck,
|
|
96
|
+
skipVisibilityCheck
|
|
97
|
+
})) {
|
|
78
98
|
elements[elements.length] = candidate;
|
|
79
99
|
}
|
|
80
100
|
}
|
|
@@ -88,24 +108,35 @@ function getNextFocusable(container = document.body, options = {}) {
|
|
|
88
108
|
function getPreviousFocusable(container = document.body, options = {}) {
|
|
89
109
|
return getRelativeFocusable(container, -1, options);
|
|
90
110
|
}
|
|
91
|
-
function isFocusable(element) {
|
|
111
|
+
function isFocusable(element, options = {}) {
|
|
92
112
|
if (!(element instanceof Element)) {
|
|
93
113
|
console.warn("Invalid element");
|
|
94
114
|
return false;
|
|
95
115
|
}
|
|
116
|
+
let { skipNegativeTabIndexCheck = false, skipVisibilityCheck = false } = options;
|
|
117
|
+
if (typeof skipNegativeTabIndexCheck !== "boolean") {
|
|
118
|
+
console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
|
|
119
|
+
skipNegativeTabIndexCheck = false;
|
|
120
|
+
}
|
|
121
|
+
if (typeof skipVisibilityCheck !== "boolean") {
|
|
122
|
+
console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
|
|
123
|
+
skipVisibilityCheck = false;
|
|
124
|
+
}
|
|
96
125
|
if (element.hasAttribute("hidden") || isInert(element)) {
|
|
97
126
|
return false;
|
|
98
127
|
}
|
|
99
|
-
if (getTabIndex(element) < 0) {
|
|
128
|
+
if (!skipNegativeTabIndexCheck && getTabIndex(element) < 0) {
|
|
100
129
|
return false;
|
|
101
130
|
}
|
|
102
|
-
if (!element.matches(
|
|
131
|
+
if (!element.matches(
|
|
132
|
+
skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR.replace(/(,\s*)?\[tabindex="-1"\]/g, "") : FOCUSABLE_SELECTOR
|
|
133
|
+
)) {
|
|
103
134
|
return false;
|
|
104
135
|
}
|
|
105
136
|
if (isDisabledDeep(element)) {
|
|
106
137
|
return false;
|
|
107
138
|
}
|
|
108
|
-
if (!element.checkVisibility({
|
|
139
|
+
if (!skipVisibilityCheck && !element.checkVisibility({
|
|
109
140
|
contentVisibilityAuto: true,
|
|
110
141
|
opacityProperty: true,
|
|
111
142
|
visibilityProperty: true
|
|
@@ -124,6 +155,8 @@ function getRelativeFocusable(container, offset, options) {
|
|
|
124
155
|
composed = false,
|
|
125
156
|
filter,
|
|
126
157
|
include,
|
|
158
|
+
skipNegativeTabIndexCheck = false,
|
|
159
|
+
skipVisibilityCheck = false,
|
|
127
160
|
wrap = false
|
|
128
161
|
} = options;
|
|
129
162
|
if (!(anchor instanceof Element)) {
|
|
@@ -156,11 +189,26 @@ function getRelativeFocusable(container, offset, options) {
|
|
|
156
189
|
);
|
|
157
190
|
include = void 0;
|
|
158
191
|
}
|
|
192
|
+
if (typeof skipNegativeTabIndexCheck !== "boolean") {
|
|
193
|
+
console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
|
|
194
|
+
skipNegativeTabIndexCheck = false;
|
|
195
|
+
}
|
|
196
|
+
if (typeof skipVisibilityCheck !== "boolean") {
|
|
197
|
+
console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
|
|
198
|
+
skipVisibilityCheck = false;
|
|
199
|
+
}
|
|
159
200
|
if (typeof wrap !== "boolean") {
|
|
160
201
|
console.warn("Invalid wrap option. Fallback: false.");
|
|
161
202
|
wrap = false;
|
|
162
203
|
}
|
|
163
|
-
const
|
|
204
|
+
const settings = { composed, skipNegativeTabIndexCheck, skipVisibilityCheck };
|
|
205
|
+
if (filter !== void 0) {
|
|
206
|
+
Object.assign(settings, { filter });
|
|
207
|
+
}
|
|
208
|
+
if (include !== void 0) {
|
|
209
|
+
Object.assign(settings, { include });
|
|
210
|
+
}
|
|
211
|
+
const focusables = getFocusables(container, settings);
|
|
164
212
|
const { length } = focusables;
|
|
165
213
|
if (!length) {
|
|
166
214
|
return null;
|
|
@@ -398,19 +446,21 @@ var Portal = class {
|
|
|
398
446
|
if (current === this.#entranceSentinel) {
|
|
399
447
|
if (this.#host.contains(before)) {
|
|
400
448
|
this.#moveFocus("previous");
|
|
401
|
-
|
|
402
|
-
this.#update();
|
|
403
|
-
const first = [...this.#focusables][0];
|
|
404
|
-
first && focusElement(first);
|
|
449
|
+
return;
|
|
405
450
|
}
|
|
406
|
-
|
|
451
|
+
this.#update();
|
|
452
|
+
const first = [...this.#focusables][0];
|
|
453
|
+
first && focusElement(first);
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
if (current === this.#exitSentinel) {
|
|
407
457
|
if (this.#host.contains(before)) {
|
|
408
458
|
this.#moveFocus("next");
|
|
409
|
-
|
|
410
|
-
this.#update();
|
|
411
|
-
const last = [...this.#focusables].at(-1);
|
|
412
|
-
last && focusElement(last);
|
|
459
|
+
return;
|
|
413
460
|
}
|
|
461
|
+
this.#update();
|
|
462
|
+
const last = [...this.#focusables].at(-1);
|
|
463
|
+
last && focusElement(last);
|
|
414
464
|
}
|
|
415
465
|
};
|
|
416
466
|
#onKeyDown = (event) => {
|
|
@@ -514,7 +564,7 @@ function getActiveElement2() {
|
|
|
514
564
|
* Lightweight DOM portal (teleport) utility with fully focus management.
|
|
515
565
|
* Designed for accessible dialogs, menus, overlays, popovers.
|
|
516
566
|
*
|
|
517
|
-
* @version 1.2.
|
|
567
|
+
* @version 1.2.9
|
|
518
568
|
* @author Yusuke Kamiyamane
|
|
519
569
|
* @license MIT
|
|
520
570
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -526,7 +576,7 @@ function getActiveElement2() {
|
|
|
526
576
|
(**
|
|
527
577
|
* Attributes Utils
|
|
528
578
|
*
|
|
529
|
-
* @version 1.0
|
|
579
|
+
* @version 1.1.0
|
|
530
580
|
* @author Yusuke Kamiyamane
|
|
531
581
|
* @license MIT
|
|
532
582
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -539,7 +589,7 @@ power-focusable/dist/index.js:
|
|
|
539
589
|
* High-precision focus management utility with full composed tree support.
|
|
540
590
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
541
591
|
*
|
|
542
|
-
* @version 4.1
|
|
592
|
+
* @version 4.3.1
|
|
543
593
|
* @author Yusuke Kamiyamane
|
|
544
594
|
* @license MIT
|
|
545
595
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@y14e/portal",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.9",
|
|
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
|
|
50
|
+
"@y14e/attributes-utils": "^1.1.0",
|
|
51
51
|
"bun-types": "latest",
|
|
52
|
-
"power-focusable": "^4.1
|
|
52
|
+
"power-focusable": "^4.3.1",
|
|
53
53
|
"tsup": "^8.0.0",
|
|
54
54
|
"typescript": "^5.6.0"
|
|
55
55
|
},
|