@y14e/portal 1.2.32 → 1.3.0
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 +13 -4
- package/dist/index.bundle.cjs +14 -5
- package/dist/index.bundle.js +14 -5
- package/dist/index.cjs +14 -5
- package/dist/index.d.cts +6 -3
- package/dist/index.d.ts +6 -3
- package/dist/index.js +14 -5
- package/package.json +1 -1
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.
|
|
16
|
+
import { createPortal } from 'https://esm.sh/@y14e/portal@1.3.0';
|
|
17
17
|
// or
|
|
18
|
-
import { createPortal } from 'https://cdn.jsdelivr.net/npm/@y14e/portal@1.
|
|
18
|
+
import { createPortal } from 'https://cdn.jsdelivr.net/npm/@y14e/portal@1.3.0/+esm';
|
|
19
19
|
// or
|
|
20
|
-
import { createPortal } from 'https://esm.unpkg.com/@y14e/portal@1.
|
|
20
|
+
import { createPortal } from 'https://esm.unpkg.com/@y14e/portal@1.3.0';
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
## 📦 APIs
|
|
@@ -27,11 +27,20 @@ import { createPortal } from 'https://esm.unpkg.com/@y14e/portal@1.2.32';
|
|
|
27
27
|
Creates a portal and preserves keyboard focus order between the original DOM and the portal.
|
|
28
28
|
|
|
29
29
|
```ts
|
|
30
|
-
const cleanup = createPortal(host, container);
|
|
30
|
+
const cleanup = createPortal(host, container, options);
|
|
31
31
|
// => () => void
|
|
32
32
|
//
|
|
33
33
|
// host: Element
|
|
34
34
|
// container (optional): Element (default: <body>)
|
|
35
|
+
// options (optional): PortalOptions
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 🪄 Options
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
interface PortalOptions {
|
|
42
|
+
noInlineStyle: boolean; // default: false
|
|
43
|
+
}
|
|
35
44
|
```
|
|
36
45
|
|
|
37
46
|
## Demo
|
package/dist/index.bundle.cjs
CHANGED
|
@@ -394,7 +394,7 @@ function isUngroupedRadio(element) {
|
|
|
394
394
|
|
|
395
395
|
// src/index.ts
|
|
396
396
|
var VISUALLY_HIDDEN_CSS = `border: 0; clip: rect(0, 0, 0, 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; user-select: none; white-space: nowrap; width: 1px;`;
|
|
397
|
-
function createPortal(host, container = document.body) {
|
|
397
|
+
function createPortal(host, container = document.body, options = {}) {
|
|
398
398
|
if (!(host instanceof Element)) {
|
|
399
399
|
console.warn("Invalid host element");
|
|
400
400
|
return () => {
|
|
@@ -410,24 +410,31 @@ function createPortal(host, container = document.body) {
|
|
|
410
410
|
return () => {
|
|
411
411
|
};
|
|
412
412
|
}
|
|
413
|
-
const portal = new Portal(host, container);
|
|
413
|
+
const portal = new Portal(host, container, options);
|
|
414
414
|
return () => portal.destroy();
|
|
415
415
|
}
|
|
416
416
|
var Portal = class {
|
|
417
417
|
#host;
|
|
418
418
|
#container;
|
|
419
|
+
#settings;
|
|
419
420
|
#entranceSentinel;
|
|
420
421
|
#exitSentinel;
|
|
421
422
|
#focusables = /* @__PURE__ */ new Set();
|
|
422
423
|
#controller = null;
|
|
423
424
|
#isDestroyed = false;
|
|
424
|
-
constructor(host, container) {
|
|
425
|
+
constructor(host, container, options = {}) {
|
|
425
426
|
this.#host = host;
|
|
426
427
|
if (!(container instanceof Element)) {
|
|
427
428
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
428
429
|
container = document.body;
|
|
429
430
|
}
|
|
430
431
|
this.#container = container;
|
|
432
|
+
let { noInlineStyle = false } = options;
|
|
433
|
+
if (typeof noInlineStyle !== "boolean") {
|
|
434
|
+
console.warn("Invalid noInlineStyle option. Fallback: false.");
|
|
435
|
+
noInlineStyle = false;
|
|
436
|
+
}
|
|
437
|
+
this.#settings = { noInlineStyle };
|
|
431
438
|
this.#entranceSentinel = this.#createSentinel();
|
|
432
439
|
this.#exitSentinel = this.#createSentinel();
|
|
433
440
|
this.#initialize();
|
|
@@ -532,7 +539,9 @@ var Portal = class {
|
|
|
532
539
|
sentinel.setAttribute("aria-hidden", "true");
|
|
533
540
|
sentinel.setAttribute("data-portal-sentinel", "");
|
|
534
541
|
sentinel.setAttribute("tabindex", "0");
|
|
535
|
-
|
|
542
|
+
if (!this.#settings.noInlineStyle) {
|
|
543
|
+
sentinel.style.cssText += VISUALLY_HIDDEN_CSS;
|
|
544
|
+
}
|
|
536
545
|
return sentinel;
|
|
537
546
|
}
|
|
538
547
|
#focusSentinel(isPrevious) {
|
|
@@ -568,7 +577,7 @@ function containsComposed2(container, element) {
|
|
|
568
577
|
* Lightweight DOM portal (teleport) utility with fully focus management.
|
|
569
578
|
* Designed for accessible dialogs, menus, overlays, popovers.
|
|
570
579
|
*
|
|
571
|
-
* @version 1.
|
|
580
|
+
* @version 1.3.0
|
|
572
581
|
* @author Yusuke Kamiyamane
|
|
573
582
|
* @license MIT
|
|
574
583
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.bundle.js
CHANGED
|
@@ -392,7 +392,7 @@ function isUngroupedRadio(element) {
|
|
|
392
392
|
|
|
393
393
|
// src/index.ts
|
|
394
394
|
var VISUALLY_HIDDEN_CSS = `border: 0; clip: rect(0, 0, 0, 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; user-select: none; white-space: nowrap; width: 1px;`;
|
|
395
|
-
function createPortal(host, container = document.body) {
|
|
395
|
+
function createPortal(host, container = document.body, options = {}) {
|
|
396
396
|
if (!(host instanceof Element)) {
|
|
397
397
|
console.warn("Invalid host element");
|
|
398
398
|
return () => {
|
|
@@ -408,24 +408,31 @@ function createPortal(host, container = document.body) {
|
|
|
408
408
|
return () => {
|
|
409
409
|
};
|
|
410
410
|
}
|
|
411
|
-
const portal = new Portal(host, container);
|
|
411
|
+
const portal = new Portal(host, container, options);
|
|
412
412
|
return () => portal.destroy();
|
|
413
413
|
}
|
|
414
414
|
var Portal = class {
|
|
415
415
|
#host;
|
|
416
416
|
#container;
|
|
417
|
+
#settings;
|
|
417
418
|
#entranceSentinel;
|
|
418
419
|
#exitSentinel;
|
|
419
420
|
#focusables = /* @__PURE__ */ new Set();
|
|
420
421
|
#controller = null;
|
|
421
422
|
#isDestroyed = false;
|
|
422
|
-
constructor(host, container) {
|
|
423
|
+
constructor(host, container, options = {}) {
|
|
423
424
|
this.#host = host;
|
|
424
425
|
if (!(container instanceof Element)) {
|
|
425
426
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
426
427
|
container = document.body;
|
|
427
428
|
}
|
|
428
429
|
this.#container = container;
|
|
430
|
+
let { noInlineStyle = false } = options;
|
|
431
|
+
if (typeof noInlineStyle !== "boolean") {
|
|
432
|
+
console.warn("Invalid noInlineStyle option. Fallback: false.");
|
|
433
|
+
noInlineStyle = false;
|
|
434
|
+
}
|
|
435
|
+
this.#settings = { noInlineStyle };
|
|
429
436
|
this.#entranceSentinel = this.#createSentinel();
|
|
430
437
|
this.#exitSentinel = this.#createSentinel();
|
|
431
438
|
this.#initialize();
|
|
@@ -530,7 +537,9 @@ var Portal = class {
|
|
|
530
537
|
sentinel.setAttribute("aria-hidden", "true");
|
|
531
538
|
sentinel.setAttribute("data-portal-sentinel", "");
|
|
532
539
|
sentinel.setAttribute("tabindex", "0");
|
|
533
|
-
|
|
540
|
+
if (!this.#settings.noInlineStyle) {
|
|
541
|
+
sentinel.style.cssText += VISUALLY_HIDDEN_CSS;
|
|
542
|
+
}
|
|
534
543
|
return sentinel;
|
|
535
544
|
}
|
|
536
545
|
#focusSentinel(isPrevious) {
|
|
@@ -566,7 +575,7 @@ function containsComposed2(container, element) {
|
|
|
566
575
|
* Lightweight DOM portal (teleport) utility with fully focus management.
|
|
567
576
|
* Designed for accessible dialogs, menus, overlays, popovers.
|
|
568
577
|
*
|
|
569
|
-
* @version 1.
|
|
578
|
+
* @version 1.3.0
|
|
570
579
|
* @author Yusuke Kamiyamane
|
|
571
580
|
* @license MIT
|
|
572
581
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.cjs
CHANGED
|
@@ -5,7 +5,7 @@ var powerFocusable = require('power-focusable');
|
|
|
5
5
|
|
|
6
6
|
// src/index.ts
|
|
7
7
|
var VISUALLY_HIDDEN_CSS = `border: 0; clip: rect(0, 0, 0, 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; user-select: none; white-space: nowrap; width: 1px;`;
|
|
8
|
-
function createPortal(host, container = document.body) {
|
|
8
|
+
function createPortal(host, container = document.body, options = {}) {
|
|
9
9
|
if (!(host instanceof Element)) {
|
|
10
10
|
console.warn("Invalid host element");
|
|
11
11
|
return () => {
|
|
@@ -21,24 +21,31 @@ function createPortal(host, container = document.body) {
|
|
|
21
21
|
return () => {
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
-
const portal = new Portal(host, container);
|
|
24
|
+
const portal = new Portal(host, container, options);
|
|
25
25
|
return () => portal.destroy();
|
|
26
26
|
}
|
|
27
27
|
var Portal = class {
|
|
28
28
|
#host;
|
|
29
29
|
#container;
|
|
30
|
+
#settings;
|
|
30
31
|
#entranceSentinel;
|
|
31
32
|
#exitSentinel;
|
|
32
33
|
#focusables = /* @__PURE__ */ new Set();
|
|
33
34
|
#controller = null;
|
|
34
35
|
#isDestroyed = false;
|
|
35
|
-
constructor(host, container) {
|
|
36
|
+
constructor(host, container, options = {}) {
|
|
36
37
|
this.#host = host;
|
|
37
38
|
if (!(container instanceof Element)) {
|
|
38
39
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
39
40
|
container = document.body;
|
|
40
41
|
}
|
|
41
42
|
this.#container = container;
|
|
43
|
+
let { noInlineStyle = false } = options;
|
|
44
|
+
if (typeof noInlineStyle !== "boolean") {
|
|
45
|
+
console.warn("Invalid noInlineStyle option. Fallback: false.");
|
|
46
|
+
noInlineStyle = false;
|
|
47
|
+
}
|
|
48
|
+
this.#settings = { noInlineStyle };
|
|
42
49
|
this.#entranceSentinel = this.#createSentinel();
|
|
43
50
|
this.#exitSentinel = this.#createSentinel();
|
|
44
51
|
this.#initialize();
|
|
@@ -143,7 +150,9 @@ var Portal = class {
|
|
|
143
150
|
sentinel.setAttribute("aria-hidden", "true");
|
|
144
151
|
sentinel.setAttribute("data-portal-sentinel", "");
|
|
145
152
|
sentinel.setAttribute("tabindex", "0");
|
|
146
|
-
|
|
153
|
+
if (!this.#settings.noInlineStyle) {
|
|
154
|
+
sentinel.style.cssText += VISUALLY_HIDDEN_CSS;
|
|
155
|
+
}
|
|
147
156
|
return sentinel;
|
|
148
157
|
}
|
|
149
158
|
#focusSentinel(isPrevious) {
|
|
@@ -179,7 +188,7 @@ function containsComposed(container, element) {
|
|
|
179
188
|
* Lightweight DOM portal (teleport) utility with fully focus management.
|
|
180
189
|
* Designed for accessible dialogs, menus, overlays, popovers.
|
|
181
190
|
*
|
|
182
|
-
* @version 1.
|
|
191
|
+
* @version 1.3.0
|
|
183
192
|
* @author Yusuke Kamiyamane
|
|
184
193
|
* @license MIT
|
|
185
194
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.d.cts
CHANGED
|
@@ -3,12 +3,15 @@
|
|
|
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.
|
|
6
|
+
* @version 1.3.0
|
|
7
7
|
* @author Yusuke Kamiyamane
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
10
10
|
* @see {@link https://github.com/y14e/portal}
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
interface PortalOptions {
|
|
13
|
+
noInlineStyle: boolean;
|
|
14
|
+
}
|
|
15
|
+
declare function createPortal(host: Element, container?: HTMLElement, options?: Partial<PortalOptions>): () => void;
|
|
13
16
|
|
|
14
|
-
export { createPortal };
|
|
17
|
+
export { type PortalOptions, createPortal };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,12 +3,15 @@
|
|
|
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.
|
|
6
|
+
* @version 1.3.0
|
|
7
7
|
* @author Yusuke Kamiyamane
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
10
10
|
* @see {@link https://github.com/y14e/portal}
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
interface PortalOptions {
|
|
13
|
+
noInlineStyle: boolean;
|
|
14
|
+
}
|
|
15
|
+
declare function createPortal(host: Element, container?: HTMLElement, options?: Partial<PortalOptions>): () => void;
|
|
13
16
|
|
|
14
|
-
export { createPortal };
|
|
17
|
+
export { type PortalOptions, createPortal };
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { focusElement, getActiveElement, getFocusables, getPreviousFocusable, ge
|
|
|
3
3
|
|
|
4
4
|
// src/index.ts
|
|
5
5
|
var VISUALLY_HIDDEN_CSS = `border: 0; clip: rect(0, 0, 0, 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; user-select: none; white-space: nowrap; width: 1px;`;
|
|
6
|
-
function createPortal(host, container = document.body) {
|
|
6
|
+
function createPortal(host, container = document.body, options = {}) {
|
|
7
7
|
if (!(host instanceof Element)) {
|
|
8
8
|
console.warn("Invalid host element");
|
|
9
9
|
return () => {
|
|
@@ -19,24 +19,31 @@ function createPortal(host, container = document.body) {
|
|
|
19
19
|
return () => {
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
|
-
const portal = new Portal(host, container);
|
|
22
|
+
const portal = new Portal(host, container, options);
|
|
23
23
|
return () => portal.destroy();
|
|
24
24
|
}
|
|
25
25
|
var Portal = class {
|
|
26
26
|
#host;
|
|
27
27
|
#container;
|
|
28
|
+
#settings;
|
|
28
29
|
#entranceSentinel;
|
|
29
30
|
#exitSentinel;
|
|
30
31
|
#focusables = /* @__PURE__ */ new Set();
|
|
31
32
|
#controller = null;
|
|
32
33
|
#isDestroyed = false;
|
|
33
|
-
constructor(host, container) {
|
|
34
|
+
constructor(host, container, options = {}) {
|
|
34
35
|
this.#host = host;
|
|
35
36
|
if (!(container instanceof Element)) {
|
|
36
37
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
37
38
|
container = document.body;
|
|
38
39
|
}
|
|
39
40
|
this.#container = container;
|
|
41
|
+
let { noInlineStyle = false } = options;
|
|
42
|
+
if (typeof noInlineStyle !== "boolean") {
|
|
43
|
+
console.warn("Invalid noInlineStyle option. Fallback: false.");
|
|
44
|
+
noInlineStyle = false;
|
|
45
|
+
}
|
|
46
|
+
this.#settings = { noInlineStyle };
|
|
40
47
|
this.#entranceSentinel = this.#createSentinel();
|
|
41
48
|
this.#exitSentinel = this.#createSentinel();
|
|
42
49
|
this.#initialize();
|
|
@@ -141,7 +148,9 @@ var Portal = class {
|
|
|
141
148
|
sentinel.setAttribute("aria-hidden", "true");
|
|
142
149
|
sentinel.setAttribute("data-portal-sentinel", "");
|
|
143
150
|
sentinel.setAttribute("tabindex", "0");
|
|
144
|
-
|
|
151
|
+
if (!this.#settings.noInlineStyle) {
|
|
152
|
+
sentinel.style.cssText += VISUALLY_HIDDEN_CSS;
|
|
153
|
+
}
|
|
145
154
|
return sentinel;
|
|
146
155
|
}
|
|
147
156
|
#focusSentinel(isPrevious) {
|
|
@@ -177,7 +186,7 @@ function containsComposed(container, element) {
|
|
|
177
186
|
* Lightweight DOM portal (teleport) utility with fully focus management.
|
|
178
187
|
* Designed for accessible dialogs, menus, overlays, popovers.
|
|
179
188
|
*
|
|
180
|
-
* @version 1.
|
|
189
|
+
* @version 1.3.0
|
|
181
190
|
* @author Yusuke Kamiyamane
|
|
182
191
|
* @license MIT
|
|
183
192
|
* @copyright Copyright (c) Yusuke Kamiyamane
|