@y14e/portal 0.0.4 → 0.1.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 CHANGED
@@ -30,15 +30,9 @@ import { createPortal } from 'https://unpkg.com/@y14e/portal/dist/index.js';
30
30
  Creates a portal and preserves keyboard focus order between the original DOM and the portal.
31
31
 
32
32
  ```ts
33
- const portal = createPortal(source, container);
34
- // => { element: Element; cleanup: () => void }
33
+ const cleanup = createPortal(source, target);
34
+ // => () => void
35
35
  //
36
36
  // source: Element
37
- // container (optional): Element (default: <body>)
38
-
39
- // Element
40
- console.log(portal.element);
41
-
42
- // Cleanup
43
- portal.cleanup();
37
+ // target (optional): Element (default: <body>)
44
38
  ```
package/dist/index.cjs CHANGED
@@ -254,35 +254,28 @@ function isUngroupedRadio(element) {
254
254
 
255
255
  // src/index.ts
256
256
  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;`;
257
- function createPortal(source, container = document.body) {
257
+ function createPortal(source, target = document.body) {
258
258
  if (!(source instanceof Element)) {
259
259
  throw new Error("Invalid source element");
260
260
  }
261
- if (!(container instanceof Element)) {
262
- console.warn("Invalid container element. Fallback: <body> element.");
263
- container = document.body;
261
+ if (!(target instanceof Element)) {
262
+ console.warn("Invalid target element. Fallback: <body> element.");
263
+ target = document.body;
264
264
  }
265
- const portal = new Portal(source, container);
266
- return {
267
- element: portal.getElement(),
268
- cleanup: () => portal.destroy()
269
- };
265
+ const portal = new Portal(source, target);
266
+ return () => portal.destroy();
270
267
  }
271
268
  var Portal = class {
272
269
  #source;
273
- #container;
274
270
  #target;
275
271
  #entranceSentinel;
276
272
  #exitSentinel;
277
273
  #tabIndexes = /* @__PURE__ */ new WeakMap();
278
274
  #controller = null;
279
275
  #isDestroyed = false;
280
- constructor(source, container) {
276
+ constructor(source, target) {
281
277
  this.#source = source;
282
- this.#container = container;
283
- this.#target = document.createElement("div");
284
- this.#target.setAttribute("data-portal", "");
285
- this.#target.setAttribute("tabindex", "-1");
278
+ this.#target = target;
286
279
  this.#entranceSentinel = this.#createSentinel();
287
280
  this.#exitSentinel = this.#createSentinel();
288
281
  this.#initialize();
@@ -306,18 +299,14 @@ var Portal = class {
306
299
  }
307
300
  });
308
301
  this.#exitSentinel.after(this.#source);
309
- this.#target.remove();
310
302
  this.#entranceSentinel.remove();
311
303
  this.#exitSentinel.remove();
312
- }
313
- getElement() {
314
- return this.#target;
304
+ this.#source.removeAttribute("data-portal");
315
305
  }
316
306
  #initialize() {
317
307
  this.#source.before(this.#entranceSentinel);
318
308
  this.#entranceSentinel.after(this.#exitSentinel);
319
309
  this.#target.append(this.#source);
320
- this.#container.append(this.#target);
321
310
  this.#getFocusables().forEach((focusable) => {
322
311
  const index = focusable.getAttribute("tabindex")?.trim();
323
312
  this.#tabIndexes.set(focusable, index === null ? null : Number(index));
@@ -333,6 +322,7 @@ var Portal = class {
333
322
  capture: true,
334
323
  signal
335
324
  });
325
+ this.#source.setAttribute("data-portal", "");
336
326
  }
337
327
  #onFocusIn = (event) => {
338
328
  const current = event.target;
@@ -420,7 +410,7 @@ function getActiveElement2() {
420
410
  * Lightweight DOM portal (teleport) utility with fully focus management.
421
411
  * Designed for accessible dialogs, menus, overlays, popovers.
422
412
  *
423
- * @version 0.0.4
413
+ * @version 0.1.0
424
414
  * @author Yusuke Kamiyamane
425
415
  * @license MIT
426
416
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.cts CHANGED
@@ -3,21 +3,17 @@
3
3
  * Lightweight DOM portal (teleport) utility with fully focus management.
4
4
  * Designed for accessible dialogs, menus, overlays, popovers.
5
5
  *
6
- * @version 0.0.4
6
+ * @version 0.1.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
- declare function createPortal(source: Element, container?: HTMLElement): {
13
- element: Element;
14
- cleanup: () => void;
15
- };
12
+ declare function createPortal(source: Element, target?: HTMLElement): () => void;
16
13
  declare class Portal {
17
14
  #private;
18
- constructor(source: Element, container: Element);
15
+ constructor(source: Element, target: Element);
19
16
  destroy(): void;
20
- getElement(): HTMLElement;
21
17
  }
22
18
 
23
19
  export { Portal, createPortal };
package/dist/index.d.ts CHANGED
@@ -3,21 +3,17 @@
3
3
  * Lightweight DOM portal (teleport) utility with fully focus management.
4
4
  * Designed for accessible dialogs, menus, overlays, popovers.
5
5
  *
6
- * @version 0.0.4
6
+ * @version 0.1.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
- declare function createPortal(source: Element, container?: HTMLElement): {
13
- element: Element;
14
- cleanup: () => void;
15
- };
12
+ declare function createPortal(source: Element, target?: HTMLElement): () => void;
16
13
  declare class Portal {
17
14
  #private;
18
- constructor(source: Element, container: Element);
15
+ constructor(source: Element, target: Element);
19
16
  destroy(): void;
20
- getElement(): HTMLElement;
21
17
  }
22
18
 
23
19
  export { Portal, createPortal };
package/dist/index.js CHANGED
@@ -252,35 +252,28 @@ function isUngroupedRadio(element) {
252
252
 
253
253
  // src/index.ts
254
254
  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;`;
255
- function createPortal(source, container = document.body) {
255
+ function createPortal(source, target = document.body) {
256
256
  if (!(source instanceof Element)) {
257
257
  throw new Error("Invalid source element");
258
258
  }
259
- if (!(container instanceof Element)) {
260
- console.warn("Invalid container element. Fallback: <body> element.");
261
- container = document.body;
259
+ if (!(target instanceof Element)) {
260
+ console.warn("Invalid target element. Fallback: <body> element.");
261
+ target = document.body;
262
262
  }
263
- const portal = new Portal(source, container);
264
- return {
265
- element: portal.getElement(),
266
- cleanup: () => portal.destroy()
267
- };
263
+ const portal = new Portal(source, target);
264
+ return () => portal.destroy();
268
265
  }
269
266
  var Portal = class {
270
267
  #source;
271
- #container;
272
268
  #target;
273
269
  #entranceSentinel;
274
270
  #exitSentinel;
275
271
  #tabIndexes = /* @__PURE__ */ new WeakMap();
276
272
  #controller = null;
277
273
  #isDestroyed = false;
278
- constructor(source, container) {
274
+ constructor(source, target) {
279
275
  this.#source = source;
280
- this.#container = container;
281
- this.#target = document.createElement("div");
282
- this.#target.setAttribute("data-portal", "");
283
- this.#target.setAttribute("tabindex", "-1");
276
+ this.#target = target;
284
277
  this.#entranceSentinel = this.#createSentinel();
285
278
  this.#exitSentinel = this.#createSentinel();
286
279
  this.#initialize();
@@ -304,18 +297,14 @@ var Portal = class {
304
297
  }
305
298
  });
306
299
  this.#exitSentinel.after(this.#source);
307
- this.#target.remove();
308
300
  this.#entranceSentinel.remove();
309
301
  this.#exitSentinel.remove();
310
- }
311
- getElement() {
312
- return this.#target;
302
+ this.#source.removeAttribute("data-portal");
313
303
  }
314
304
  #initialize() {
315
305
  this.#source.before(this.#entranceSentinel);
316
306
  this.#entranceSentinel.after(this.#exitSentinel);
317
307
  this.#target.append(this.#source);
318
- this.#container.append(this.#target);
319
308
  this.#getFocusables().forEach((focusable) => {
320
309
  const index = focusable.getAttribute("tabindex")?.trim();
321
310
  this.#tabIndexes.set(focusable, index === null ? null : Number(index));
@@ -331,6 +320,7 @@ var Portal = class {
331
320
  capture: true,
332
321
  signal
333
322
  });
323
+ this.#source.setAttribute("data-portal", "");
334
324
  }
335
325
  #onFocusIn = (event) => {
336
326
  const current = event.target;
@@ -418,7 +408,7 @@ function getActiveElement2() {
418
408
  * Lightweight DOM portal (teleport) utility with fully focus management.
419
409
  * Designed for accessible dialogs, menus, overlays, popovers.
420
410
  *
421
- * @version 0.0.4
411
+ * @version 0.1.0
422
412
  * @author Yusuke Kamiyamane
423
413
  * @license MIT
424
414
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/portal",
3
- "version": "0.0.4",
3
+ "version": "0.1.0",
4
4
  "description": "Lightweight DOM portal (teleport) utility with fully focus management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",