@y14e/portal 0.0.2 → 0.0.3

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
@@ -18,7 +18,7 @@ import { createPortal } from '@y14e/portal';
18
18
  // CDNs
19
19
  import { createPortal } from 'https://esm.sh/@y14e/portal'
20
20
  // or
21
- import { createPortal } from 'https://cdn.jsdelivr.net/npm/@y14e/portal/dist/index.js';
21
+ import { createPortal } from 'https://cdn.jsdelivr.net/npm/@y14e/portal/+esm';
22
22
  // or
23
23
  import { createPortal } from 'https://unpkg.com/@y14e/portal/dist/index.js';
24
24
  ```
package/dist/index.cjs CHANGED
@@ -273,6 +273,7 @@ var Portal = class {
273
273
  #portal;
274
274
  #entranceSentinel;
275
275
  #exitSentinel;
276
+ #focusables = [];
276
277
  #tabIndexes = /* @__PURE__ */ new WeakMap();
277
278
  #controller = null;
278
279
  #isDestroyed = false;
@@ -284,6 +285,7 @@ var Portal = class {
284
285
  this.#portal.setAttribute("tabindex", "-1");
285
286
  this.#entranceSentinel = this.#createSentinel();
286
287
  this.#exitSentinel = this.#createSentinel();
288
+ this.#focusables = getFocusables(this.#source, { composed: true });
287
289
  this.#initialize();
288
290
  }
289
291
  destroy() {
@@ -293,7 +295,7 @@ var Portal = class {
293
295
  this.#isDestroyed = true;
294
296
  this.#controller?.abort();
295
297
  this.#controller = null;
296
- this.#getFocusables().forEach((focusable) => {
298
+ this.#focusables.forEach((focusable) => {
297
299
  const index = this.#tabIndexes.get(focusable);
298
300
  if (index === null) {
299
301
  focusable.removeAttribute("tabindex");
@@ -301,6 +303,7 @@ var Portal = class {
301
303
  focusable.setAttribute("tabindex", String(index));
302
304
  }
303
305
  });
306
+ this.#focusables.length = 0;
304
307
  this.#exitSentinel.after(this.#source);
305
308
  this.#portal.remove();
306
309
  this.#entranceSentinel.remove();
@@ -314,13 +317,11 @@ var Portal = class {
314
317
  this.#entranceSentinel.after(this.#exitSentinel);
315
318
  this.#portal.append(this.#source);
316
319
  this.#container.append(this.#portal);
317
- getFocusables(this.#source, { composed: true }).forEach(
318
- (focusable) => {
319
- const index = focusable.getAttribute("tabindex")?.trim();
320
- this.#tabIndexes.set(focusable, index === null ? null : Number(index));
321
- focusable.setAttribute("tabindex", "-1");
322
- }
323
- );
320
+ this.#focusables.forEach((focusable) => {
321
+ const index = focusable.getAttribute("tabindex")?.trim();
322
+ this.#tabIndexes.set(focusable, index === null ? null : Number(index));
323
+ focusable.setAttribute("tabindex", "-1");
324
+ });
324
325
  this.#controller = new AbortController();
325
326
  const { signal } = this.#controller;
326
327
  document.addEventListener("focusin", this.#onFocusIn, {
@@ -338,19 +339,18 @@ var Portal = class {
338
339
  if (!(before instanceof Element)) {
339
340
  return;
340
341
  }
341
- const focusables = this.#getFocusables();
342
342
  if (current === this.#entranceSentinel) {
343
343
  if (this.#source.contains(before)) {
344
344
  this.#focusOutside("backward");
345
345
  } else {
346
- const first = focusables[0];
346
+ const first = this.#focusables[0];
347
347
  first && focus(first);
348
348
  }
349
349
  } else if (current === this.#exitSentinel) {
350
350
  if (this.#source.contains(before)) {
351
351
  this.#focusOutside("forward");
352
352
  } else {
353
- const last = focusables.at(-1);
353
+ const last = this.#focusables.at(-1);
354
354
  last && focus(last);
355
355
  }
356
356
  }
@@ -366,17 +366,16 @@ var Portal = class {
366
366
  if (!this.#source.contains(active)) {
367
367
  return;
368
368
  }
369
- const focusables = this.#getFocusables();
370
- if (!focusables.length) {
369
+ if (!this.#focusables.length) {
371
370
  event.preventDefault();
372
371
  (event.shiftKey ? this.#entranceSentinel : this.#exitSentinel).focus();
373
372
  }
374
- const index = focusables.indexOf(active);
373
+ const index = this.#focusables.indexOf(active);
375
374
  if (index === -1) {
376
375
  return;
377
376
  }
378
377
  event.preventDefault();
379
- const focusable = focusables[index + (event.shiftKey ? -1 : 1)];
378
+ const focusable = this.#focusables[index + (event.shiftKey ? -1 : 1)];
380
379
  if (focusable) {
381
380
  focus(focusable);
382
381
  } else {
@@ -398,9 +397,6 @@ var Portal = class {
398
397
  const focusable = direction === "backward" ? getPreviousFocusable(document.body, options) : getNextFocusable(document.body, options);
399
398
  focusable && focus(focusable);
400
399
  }
401
- #getFocusables() {
402
- return getFocusables(this.#source, { composed: true });
403
- }
404
400
  };
405
401
  function focus(element) {
406
402
  "focus" in element && typeof element.focus === "function" && element.focus();
@@ -417,7 +413,7 @@ function getActiveElement2() {
417
413
  * Lightweight DOM portal (teleport) utility with fully focus management.
418
414
  * Designed for accessible dialogs, menus, overlays, popovers, and etc.
419
415
  *
420
- * @version 0.0.2
416
+ * @version 0.0.3
421
417
  * @author Yusuke Kamiyamane
422
418
  * @license MIT
423
419
  * @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, and etc.
5
5
  *
6
- * @version 0.0.2
6
+ * @version 0.0.3
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, and etc.
5
5
  *
6
- * @version 0.0.2
6
+ * @version 0.0.3
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -271,6 +271,7 @@ var Portal = class {
271
271
  #portal;
272
272
  #entranceSentinel;
273
273
  #exitSentinel;
274
+ #focusables = [];
274
275
  #tabIndexes = /* @__PURE__ */ new WeakMap();
275
276
  #controller = null;
276
277
  #isDestroyed = false;
@@ -282,6 +283,7 @@ var Portal = class {
282
283
  this.#portal.setAttribute("tabindex", "-1");
283
284
  this.#entranceSentinel = this.#createSentinel();
284
285
  this.#exitSentinel = this.#createSentinel();
286
+ this.#focusables = getFocusables(this.#source, { composed: true });
285
287
  this.#initialize();
286
288
  }
287
289
  destroy() {
@@ -291,7 +293,7 @@ var Portal = class {
291
293
  this.#isDestroyed = true;
292
294
  this.#controller?.abort();
293
295
  this.#controller = null;
294
- this.#getFocusables().forEach((focusable) => {
296
+ this.#focusables.forEach((focusable) => {
295
297
  const index = this.#tabIndexes.get(focusable);
296
298
  if (index === null) {
297
299
  focusable.removeAttribute("tabindex");
@@ -299,6 +301,7 @@ var Portal = class {
299
301
  focusable.setAttribute("tabindex", String(index));
300
302
  }
301
303
  });
304
+ this.#focusables.length = 0;
302
305
  this.#exitSentinel.after(this.#source);
303
306
  this.#portal.remove();
304
307
  this.#entranceSentinel.remove();
@@ -312,13 +315,11 @@ var Portal = class {
312
315
  this.#entranceSentinel.after(this.#exitSentinel);
313
316
  this.#portal.append(this.#source);
314
317
  this.#container.append(this.#portal);
315
- getFocusables(this.#source, { composed: true }).forEach(
316
- (focusable) => {
317
- const index = focusable.getAttribute("tabindex")?.trim();
318
- this.#tabIndexes.set(focusable, index === null ? null : Number(index));
319
- focusable.setAttribute("tabindex", "-1");
320
- }
321
- );
318
+ this.#focusables.forEach((focusable) => {
319
+ const index = focusable.getAttribute("tabindex")?.trim();
320
+ this.#tabIndexes.set(focusable, index === null ? null : Number(index));
321
+ focusable.setAttribute("tabindex", "-1");
322
+ });
322
323
  this.#controller = new AbortController();
323
324
  const { signal } = this.#controller;
324
325
  document.addEventListener("focusin", this.#onFocusIn, {
@@ -336,19 +337,18 @@ var Portal = class {
336
337
  if (!(before instanceof Element)) {
337
338
  return;
338
339
  }
339
- const focusables = this.#getFocusables();
340
340
  if (current === this.#entranceSentinel) {
341
341
  if (this.#source.contains(before)) {
342
342
  this.#focusOutside("backward");
343
343
  } else {
344
- const first = focusables[0];
344
+ const first = this.#focusables[0];
345
345
  first && focus(first);
346
346
  }
347
347
  } else if (current === this.#exitSentinel) {
348
348
  if (this.#source.contains(before)) {
349
349
  this.#focusOutside("forward");
350
350
  } else {
351
- const last = focusables.at(-1);
351
+ const last = this.#focusables.at(-1);
352
352
  last && focus(last);
353
353
  }
354
354
  }
@@ -364,17 +364,16 @@ var Portal = class {
364
364
  if (!this.#source.contains(active)) {
365
365
  return;
366
366
  }
367
- const focusables = this.#getFocusables();
368
- if (!focusables.length) {
367
+ if (!this.#focusables.length) {
369
368
  event.preventDefault();
370
369
  (event.shiftKey ? this.#entranceSentinel : this.#exitSentinel).focus();
371
370
  }
372
- const index = focusables.indexOf(active);
371
+ const index = this.#focusables.indexOf(active);
373
372
  if (index === -1) {
374
373
  return;
375
374
  }
376
375
  event.preventDefault();
377
- const focusable = focusables[index + (event.shiftKey ? -1 : 1)];
376
+ const focusable = this.#focusables[index + (event.shiftKey ? -1 : 1)];
378
377
  if (focusable) {
379
378
  focus(focusable);
380
379
  } else {
@@ -396,9 +395,6 @@ var Portal = class {
396
395
  const focusable = direction === "backward" ? getPreviousFocusable(document.body, options) : getNextFocusable(document.body, options);
397
396
  focusable && focus(focusable);
398
397
  }
399
- #getFocusables() {
400
- return getFocusables(this.#source, { composed: true });
401
- }
402
398
  };
403
399
  function focus(element) {
404
400
  "focus" in element && typeof element.focus === "function" && element.focus();
@@ -415,7 +411,7 @@ function getActiveElement2() {
415
411
  * Lightweight DOM portal (teleport) utility with fully focus management.
416
412
  * Designed for accessible dialogs, menus, overlays, popovers, and etc.
417
413
  *
418
- * @version 0.0.2
414
+ * @version 0.0.3
419
415
  * @author Yusuke Kamiyamane
420
416
  * @license MIT
421
417
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/portal",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Lightweight DOM portal (teleport) utility with fully focus management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",