@y14e/disclosure 2.1.2 → 2.1.4

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
@@ -13,11 +13,11 @@ npm i @y14e/disclosure
13
13
  import { Disclosure } from '@y14e/disclosure';
14
14
 
15
15
  // CDNs
16
- import { Disclosure } from 'https://esm.sh/@y14e/disclosure@2.1.2';
16
+ import { Disclosure } from 'https://esm.sh/@y14e/disclosure@<x.x.x>';
17
17
  // or
18
- import { Disclosure } from 'https://cdn.jsdelivr.net/npm/@y14e/disclosure@2.1.2/+esm';
18
+ import { Disclosure } from 'https://cdn.jsdelivr.net/npm/@y14e/disclosure@<x.x.x>/+esm';
19
19
  // or
20
- import { Disclosure } from 'https://esm.unpkg.com/@y14e/disclosure@2.1.2';
20
+ import { Disclosure } from 'https://esm.unpkg.com/@y14e/disclosure@<x.x.x>';
21
21
  ```
22
22
 
23
23
  ## Usage
@@ -10,16 +10,16 @@ function addAttributeToken(element, name, token, options = {}) {
10
10
  const value = element.getAttribute(name)?.trim();
11
11
  const { caseInsensitive, parse, serialize } = resolveOptions(options);
12
12
  const tokens = value ? parse(value).filter(Boolean) : [];
13
- if (caseInsensitive) {
14
- const lower = token.toLowerCase();
15
- if (tokens.every((t) => t.toLowerCase() !== lower)) {
16
- tokens.push(token);
17
- element.setAttribute(name, serialize(tokens));
18
- }
19
- } else {
13
+ if (!caseInsensitive) {
20
14
  const set = new Set(tokens);
21
15
  set.add(token);
22
16
  element.setAttribute(name, serialize([...set]));
17
+ return;
18
+ }
19
+ const lower = token.toLowerCase();
20
+ if (tokens.every((t) => t.toLowerCase() !== lower)) {
21
+ tokens.push(token);
22
+ element.setAttribute(name, serialize(tokens));
23
23
  }
24
24
  }
25
25
  var snapshots = /* @__PURE__ */ new WeakMap();
@@ -109,7 +109,16 @@ function getFocusables(container = document.body, options = {}) {
109
109
  skipVisibilityCheck
110
110
  } = resolveOptions2(options);
111
111
  const candidates = [];
112
- if (composed || include) {
112
+ if (!composed && !include) {
113
+ for (const match of container.querySelectorAll(
114
+ !skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR : FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX
115
+ )) {
116
+ match && isFocusable(match, {
117
+ skipNegativeTabIndexCheck,
118
+ skipVisibilityCheck
119
+ }) && candidates.push(match);
120
+ }
121
+ } else {
113
122
  let traverse2 = function(node) {
114
123
  if (isFocusable(node, {
115
124
  skipNegativeTabIndexCheck,
@@ -117,23 +126,16 @@ function getFocusables(container = document.body, options = {}) {
117
126
  }) || include?.(node)) {
118
127
  candidates.push(node);
119
128
  }
120
- (composed ? getComposedChildren(node) : [...node.children]).map(traverse2);
129
+ (!composed ? [...node.children] : getComposedChildren(node)).map(
130
+ traverse2
131
+ );
121
132
  };
122
- (composed ? getComposedChildren(container) : [...container.children]).map(
133
+ (!composed ? [...container.children] : getComposedChildren(container)).map(
123
134
  traverse2
124
135
  );
125
- } else {
126
- for (const match of container.querySelectorAll(
127
- skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX : FOCUSABLE_SELECTOR
128
- )) {
129
- match && isFocusable(match, {
130
- skipNegativeTabIndexCheck,
131
- skipVisibilityCheck
132
- }) && candidates.push(match);
133
- }
134
136
  }
135
137
  return normalizeRadioGroup(
136
- sortByTabIndex(filter ? candidates.filter(filter) : candidates)
138
+ sortByTabIndex(!filter ? candidates : candidates.filter(filter))
137
139
  );
138
140
  }
139
141
  function isFocusable(element, options = {}) {
@@ -149,7 +151,7 @@ function isFocusable(element, options = {}) {
149
151
  return false;
150
152
  }
151
153
  if (!element.matches(
152
- skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX : FOCUSABLE_SELECTOR
154
+ !skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR : FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX
153
155
  )) {
154
156
  return false;
155
157
  }
@@ -280,8 +282,7 @@ function isDisabled(element) {
280
282
  return "disabled" in element && !!element.disabled;
281
283
  }
282
284
  function isFormControl(element) {
283
- const name = element.tagName;
284
- return name === "BUTTON" || name === "INPUT" || name === "SELECT" || name === "TEXTAREA";
285
+ return ["BUTTON", "INPUT", "SELECT", "TEXTAREA"].includes(element.tagName);
285
286
  }
286
287
  function isInert(element) {
287
288
  return "inert" in element && !!element.inert;
@@ -353,8 +354,8 @@ function createRovingTabIndex(container, options = {}) {
353
354
  return () => {
354
355
  };
355
356
  }
356
- const rovingTabIndex = new RovingTabIndex(container, options);
357
- return () => rovingTabIndex.destroy();
357
+ const instance = new RovingTabIndex(container, options);
358
+ return () => instance.destroy();
358
359
  }
359
360
  var RovingTabIndex = class _RovingTabIndex {
360
361
  static #initialized = /* @__PURE__ */ new Set();
@@ -387,32 +388,24 @@ var RovingTabIndex = class _RovingTabIndex {
387
388
  }
388
389
  #initialize() {
389
390
  this.#update(getActiveElement());
391
+ const container = this.#container;
390
392
  this.#controller = new AbortController();
391
393
  const { signal } = this.#controller;
392
- this.#container.addEventListener("focusin", this.#onFocusIn, { signal });
393
- this.#settings.noMemory && this.#container.addEventListener("focusout", this.#onFocusOut, {
394
+ container.addEventListener("focusin", this.#onFocusIn, { signal });
395
+ this.#settings.noMemory && container.addEventListener("focusout", this.#onFocusOut, {
394
396
  signal
395
397
  });
396
- this.#container.addEventListener("keydown", this.#onKeyDown, { signal });
398
+ container.addEventListener("keydown", this.#onKeyDown, { signal });
397
399
  }
398
400
  #onFocusIn = (event) => {
399
- if (!(event instanceof FocusEvent)) {
400
- return;
401
- }
402
401
  const { target } = event;
403
402
  target instanceof Element && this.#update(target);
404
403
  };
405
404
  #onFocusOut = (event) => {
406
- if (!(event instanceof FocusEvent)) {
407
- return;
408
- }
409
405
  const target = event.relatedTarget;
410
406
  (!(target instanceof Element) || !this.#focusables.has(target)) && this.#update();
411
407
  };
412
408
  #onKeyDown = (event) => {
413
- if (!(event instanceof KeyboardEvent)) {
414
- return;
415
- }
416
409
  const { direction, typeahead, wrap = false } = this.#settings;
417
410
  const isGrid = direction === "grid";
418
411
  const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
@@ -452,9 +445,9 @@ var RovingTabIndex = class _RovingTabIndex {
452
445
  if (isGrid && !ctrlKey) {
453
446
  const cell = this.#getCellsOfActiveRow().at(rawIndex);
454
447
  newIndex = cell ? candidates.indexOf(cell) : activeIndex;
455
- } else {
456
- newIndex = rawIndex;
448
+ break;
457
449
  }
450
+ newIndex = rawIndex;
458
451
  break;
459
452
  }
460
453
  case "ArrowLeft":
@@ -464,14 +457,14 @@ var RovingTabIndex = class _RovingTabIndex {
464
457
  if (["ArrowUp", "ArrowDown"].includes(key) && isGrid) {
465
458
  const cell = this.#getNextCell(key, wrap);
466
459
  newIndex = cell ? candidates.indexOf(cell) : activeIndex;
467
- } else {
468
- if (isGrid) {
469
- target = this.#getCellsOfActiveRow();
470
- }
471
- const isPrevious = ["ArrowLeft", "ArrowUp"].includes(key);
472
- const rawIndex = (isGrid ? target.indexOf(active) : activeIndex) + (isPrevious ? -1 : 1);
473
- newIndex = isPrevious ? wrap ? rawIndex : Math.max(rawIndex, 0) : wrap ? rawIndex % target.length : Math.min(rawIndex, target.length - 1);
460
+ break;
461
+ }
462
+ if (isGrid) {
463
+ target = this.#getCellsOfActiveRow();
474
464
  }
465
+ const isPrevious = ["ArrowLeft", "ArrowUp"].includes(key);
466
+ const rawIndex = (isGrid ? target.indexOf(active) : activeIndex) + (isPrevious ? -1 : 1);
467
+ newIndex = isPrevious ? !wrap ? Math.max(rawIndex, 0) : rawIndex : !wrap ? Math.min(rawIndex, target.length - 1) : rawIndex % target.length;
475
468
  break;
476
469
  }
477
470
  default: {
@@ -491,16 +484,17 @@ var RovingTabIndex = class _RovingTabIndex {
491
484
  #update(active) {
492
485
  const current = new Set(this.#getFocusables());
493
486
  for (const focusable of this.#focusables) {
494
- if (!current.has(focusable)) {
495
- _RovingTabIndex.#initialized.delete(focusable);
496
- restoreAttributes(focusable);
497
- this.#focusables.delete(focusable);
498
- for (const [key, focusables] of this.#focusablesByFirstChar) {
499
- const index = focusables.indexOf(focusable);
500
- if (index >= 0) {
501
- focusables.splice(index, 1);
502
- !focusables.length && this.#focusablesByFirstChar.delete(key);
503
- }
487
+ if (current.has(focusable)) {
488
+ continue;
489
+ }
490
+ _RovingTabIndex.#initialized.delete(focusable);
491
+ restoreAttributes(focusable);
492
+ this.#focusables.delete(focusable);
493
+ for (const [key, focusables] of this.#focusablesByFirstChar) {
494
+ const index = focusables.indexOf(focusable);
495
+ if (index >= 0) {
496
+ focusables.splice(index, 1);
497
+ !focusables.length && this.#focusablesByFirstChar.delete(key);
504
498
  }
505
499
  }
506
500
  }
@@ -544,11 +538,11 @@ var RovingTabIndex = class _RovingTabIndex {
544
538
  for (const focusable of this.#focusables) {
545
539
  focusable.setAttribute("tabindex", focusable === active ? "0" : "-1");
546
540
  }
547
- } else {
548
- [...this.#focusables].forEach((focusable, i) => {
549
- focusable.setAttribute("tabindex", i || noStart ? "-1" : "0");
550
- });
541
+ return;
551
542
  }
543
+ [...this.#focusables].forEach((focusable, i) => {
544
+ focusable.setAttribute("tabindex", !i && !noStart ? "0" : "-1");
545
+ });
552
546
  }
553
547
  }
554
548
  #createSelectorFilter() {
@@ -556,11 +550,8 @@ var RovingTabIndex = class _RovingTabIndex {
556
550
  return (element) => !selector || [...this.#container.querySelectorAll(selector)].includes(element);
557
551
  }
558
552
  #getCellCoords(cell) {
559
- const { height, left, top, width } = cell.getBoundingClientRect();
560
- return {
561
- x: left + width / 2,
562
- y: top + height / 2
563
- };
553
+ const { left, top, width, height } = cell.getBoundingClientRect();
554
+ return { x: left + width / 2, y: top + height / 2 };
564
555
  }
565
556
  #getCellsOfActiveRow() {
566
557
  const active = getActiveElement();
@@ -635,7 +626,9 @@ var RovingTabIndex = class _RovingTabIndex {
635
626
  typeahead = false,
636
627
  wrap = false
637
628
  } = options;
638
- direction = direction.toLowerCase();
629
+ if (typeof direction === "string") {
630
+ direction = direction.toLowerCase();
631
+ }
639
632
  if (!DIRECTIONS.includes(direction)) {
640
633
  console.warn("Invalid direction option. Fallback: 'both'.");
641
634
  direction = "both";
@@ -979,44 +972,5 @@ function waitAnimationFinish(animation) {
979
972
  (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
980
973
  );
981
974
  }
982
- /*! Bundled license information:
983
-
984
- @y14e/attribute-utils/dist/index.js:
985
- (**
986
- * Attribute Utils
987
- *
988
- * @version 2.0.12
989
- * @author Yusuke Kamiyamane
990
- * @license MIT
991
- * @copyright Copyright (c) Yusuke Kamiyamane
992
- * @see {@link https://github.com/y14e/attribute-utils}
993
- *)
994
-
995
- power-focusable/dist/index.js:
996
- (**
997
- * Power Focusable
998
- * High-precision focus management utility with full composed tree support.
999
- * Handles complex focus rules including tabindex ordering, radio groups, inert.
1000
- *
1001
- * @version 4.4.3
1002
- * @author Yusuke Kamiyamane
1003
- * @license MIT
1004
- * @copyright Copyright (c) Yusuke Kamiyamane
1005
- * @see {@link https://github.com/y14e/power-focusable}
1006
- *)
1007
-
1008
- @y14e/roving-tabindex/dist/index.js:
1009
- (**
1010
- * Roving Tabindex
1011
- * Lightweight roving tabindex utility with fully focus management.
1012
- * Designed for accessible menus, tabs, toolbars, and composite widgets.
1013
- *
1014
- * @version 3.3.2
1015
- * @author Yusuke Kamiyamane
1016
- * @license MIT
1017
- * @copyright Copyright (c) Yusuke Kamiyamane
1018
- * @see {@link https://github.com/y14e/roving-tabindex}
1019
- *)
1020
- */
1021
975
 
1022
976
  exports.Disclosure = Disclosure;
@@ -8,16 +8,16 @@ function addAttributeToken(element, name, token, options = {}) {
8
8
  const value = element.getAttribute(name)?.trim();
9
9
  const { caseInsensitive, parse, serialize } = resolveOptions(options);
10
10
  const tokens = value ? parse(value).filter(Boolean) : [];
11
- if (caseInsensitive) {
12
- const lower = token.toLowerCase();
13
- if (tokens.every((t) => t.toLowerCase() !== lower)) {
14
- tokens.push(token);
15
- element.setAttribute(name, serialize(tokens));
16
- }
17
- } else {
11
+ if (!caseInsensitive) {
18
12
  const set = new Set(tokens);
19
13
  set.add(token);
20
14
  element.setAttribute(name, serialize([...set]));
15
+ return;
16
+ }
17
+ const lower = token.toLowerCase();
18
+ if (tokens.every((t) => t.toLowerCase() !== lower)) {
19
+ tokens.push(token);
20
+ element.setAttribute(name, serialize(tokens));
21
21
  }
22
22
  }
23
23
  var snapshots = /* @__PURE__ */ new WeakMap();
@@ -107,7 +107,16 @@ function getFocusables(container = document.body, options = {}) {
107
107
  skipVisibilityCheck
108
108
  } = resolveOptions2(options);
109
109
  const candidates = [];
110
- if (composed || include) {
110
+ if (!composed && !include) {
111
+ for (const match of container.querySelectorAll(
112
+ !skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR : FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX
113
+ )) {
114
+ match && isFocusable(match, {
115
+ skipNegativeTabIndexCheck,
116
+ skipVisibilityCheck
117
+ }) && candidates.push(match);
118
+ }
119
+ } else {
111
120
  let traverse2 = function(node) {
112
121
  if (isFocusable(node, {
113
122
  skipNegativeTabIndexCheck,
@@ -115,23 +124,16 @@ function getFocusables(container = document.body, options = {}) {
115
124
  }) || include?.(node)) {
116
125
  candidates.push(node);
117
126
  }
118
- (composed ? getComposedChildren(node) : [...node.children]).map(traverse2);
127
+ (!composed ? [...node.children] : getComposedChildren(node)).map(
128
+ traverse2
129
+ );
119
130
  };
120
- (composed ? getComposedChildren(container) : [...container.children]).map(
131
+ (!composed ? [...container.children] : getComposedChildren(container)).map(
121
132
  traverse2
122
133
  );
123
- } else {
124
- for (const match of container.querySelectorAll(
125
- skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX : FOCUSABLE_SELECTOR
126
- )) {
127
- match && isFocusable(match, {
128
- skipNegativeTabIndexCheck,
129
- skipVisibilityCheck
130
- }) && candidates.push(match);
131
- }
132
134
  }
133
135
  return normalizeRadioGroup(
134
- sortByTabIndex(filter ? candidates.filter(filter) : candidates)
136
+ sortByTabIndex(!filter ? candidates : candidates.filter(filter))
135
137
  );
136
138
  }
137
139
  function isFocusable(element, options = {}) {
@@ -147,7 +149,7 @@ function isFocusable(element, options = {}) {
147
149
  return false;
148
150
  }
149
151
  if (!element.matches(
150
- skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX : FOCUSABLE_SELECTOR
152
+ !skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR : FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX
151
153
  )) {
152
154
  return false;
153
155
  }
@@ -278,8 +280,7 @@ function isDisabled(element) {
278
280
  return "disabled" in element && !!element.disabled;
279
281
  }
280
282
  function isFormControl(element) {
281
- const name = element.tagName;
282
- return name === "BUTTON" || name === "INPUT" || name === "SELECT" || name === "TEXTAREA";
283
+ return ["BUTTON", "INPUT", "SELECT", "TEXTAREA"].includes(element.tagName);
283
284
  }
284
285
  function isInert(element) {
285
286
  return "inert" in element && !!element.inert;
@@ -351,8 +352,8 @@ function createRovingTabIndex(container, options = {}) {
351
352
  return () => {
352
353
  };
353
354
  }
354
- const rovingTabIndex = new RovingTabIndex(container, options);
355
- return () => rovingTabIndex.destroy();
355
+ const instance = new RovingTabIndex(container, options);
356
+ return () => instance.destroy();
356
357
  }
357
358
  var RovingTabIndex = class _RovingTabIndex {
358
359
  static #initialized = /* @__PURE__ */ new Set();
@@ -385,32 +386,24 @@ var RovingTabIndex = class _RovingTabIndex {
385
386
  }
386
387
  #initialize() {
387
388
  this.#update(getActiveElement());
389
+ const container = this.#container;
388
390
  this.#controller = new AbortController();
389
391
  const { signal } = this.#controller;
390
- this.#container.addEventListener("focusin", this.#onFocusIn, { signal });
391
- this.#settings.noMemory && this.#container.addEventListener("focusout", this.#onFocusOut, {
392
+ container.addEventListener("focusin", this.#onFocusIn, { signal });
393
+ this.#settings.noMemory && container.addEventListener("focusout", this.#onFocusOut, {
392
394
  signal
393
395
  });
394
- this.#container.addEventListener("keydown", this.#onKeyDown, { signal });
396
+ container.addEventListener("keydown", this.#onKeyDown, { signal });
395
397
  }
396
398
  #onFocusIn = (event) => {
397
- if (!(event instanceof FocusEvent)) {
398
- return;
399
- }
400
399
  const { target } = event;
401
400
  target instanceof Element && this.#update(target);
402
401
  };
403
402
  #onFocusOut = (event) => {
404
- if (!(event instanceof FocusEvent)) {
405
- return;
406
- }
407
403
  const target = event.relatedTarget;
408
404
  (!(target instanceof Element) || !this.#focusables.has(target)) && this.#update();
409
405
  };
410
406
  #onKeyDown = (event) => {
411
- if (!(event instanceof KeyboardEvent)) {
412
- return;
413
- }
414
407
  const { direction, typeahead, wrap = false } = this.#settings;
415
408
  const isGrid = direction === "grid";
416
409
  const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
@@ -450,9 +443,9 @@ var RovingTabIndex = class _RovingTabIndex {
450
443
  if (isGrid && !ctrlKey) {
451
444
  const cell = this.#getCellsOfActiveRow().at(rawIndex);
452
445
  newIndex = cell ? candidates.indexOf(cell) : activeIndex;
453
- } else {
454
- newIndex = rawIndex;
446
+ break;
455
447
  }
448
+ newIndex = rawIndex;
456
449
  break;
457
450
  }
458
451
  case "ArrowLeft":
@@ -462,14 +455,14 @@ var RovingTabIndex = class _RovingTabIndex {
462
455
  if (["ArrowUp", "ArrowDown"].includes(key) && isGrid) {
463
456
  const cell = this.#getNextCell(key, wrap);
464
457
  newIndex = cell ? candidates.indexOf(cell) : activeIndex;
465
- } else {
466
- if (isGrid) {
467
- target = this.#getCellsOfActiveRow();
468
- }
469
- const isPrevious = ["ArrowLeft", "ArrowUp"].includes(key);
470
- const rawIndex = (isGrid ? target.indexOf(active) : activeIndex) + (isPrevious ? -1 : 1);
471
- newIndex = isPrevious ? wrap ? rawIndex : Math.max(rawIndex, 0) : wrap ? rawIndex % target.length : Math.min(rawIndex, target.length - 1);
458
+ break;
459
+ }
460
+ if (isGrid) {
461
+ target = this.#getCellsOfActiveRow();
472
462
  }
463
+ const isPrevious = ["ArrowLeft", "ArrowUp"].includes(key);
464
+ const rawIndex = (isGrid ? target.indexOf(active) : activeIndex) + (isPrevious ? -1 : 1);
465
+ newIndex = isPrevious ? !wrap ? Math.max(rawIndex, 0) : rawIndex : !wrap ? Math.min(rawIndex, target.length - 1) : rawIndex % target.length;
473
466
  break;
474
467
  }
475
468
  default: {
@@ -489,16 +482,17 @@ var RovingTabIndex = class _RovingTabIndex {
489
482
  #update(active) {
490
483
  const current = new Set(this.#getFocusables());
491
484
  for (const focusable of this.#focusables) {
492
- if (!current.has(focusable)) {
493
- _RovingTabIndex.#initialized.delete(focusable);
494
- restoreAttributes(focusable);
495
- this.#focusables.delete(focusable);
496
- for (const [key, focusables] of this.#focusablesByFirstChar) {
497
- const index = focusables.indexOf(focusable);
498
- if (index >= 0) {
499
- focusables.splice(index, 1);
500
- !focusables.length && this.#focusablesByFirstChar.delete(key);
501
- }
485
+ if (current.has(focusable)) {
486
+ continue;
487
+ }
488
+ _RovingTabIndex.#initialized.delete(focusable);
489
+ restoreAttributes(focusable);
490
+ this.#focusables.delete(focusable);
491
+ for (const [key, focusables] of this.#focusablesByFirstChar) {
492
+ const index = focusables.indexOf(focusable);
493
+ if (index >= 0) {
494
+ focusables.splice(index, 1);
495
+ !focusables.length && this.#focusablesByFirstChar.delete(key);
502
496
  }
503
497
  }
504
498
  }
@@ -542,11 +536,11 @@ var RovingTabIndex = class _RovingTabIndex {
542
536
  for (const focusable of this.#focusables) {
543
537
  focusable.setAttribute("tabindex", focusable === active ? "0" : "-1");
544
538
  }
545
- } else {
546
- [...this.#focusables].forEach((focusable, i) => {
547
- focusable.setAttribute("tabindex", i || noStart ? "-1" : "0");
548
- });
539
+ return;
549
540
  }
541
+ [...this.#focusables].forEach((focusable, i) => {
542
+ focusable.setAttribute("tabindex", !i && !noStart ? "0" : "-1");
543
+ });
550
544
  }
551
545
  }
552
546
  #createSelectorFilter() {
@@ -554,11 +548,8 @@ var RovingTabIndex = class _RovingTabIndex {
554
548
  return (element) => !selector || [...this.#container.querySelectorAll(selector)].includes(element);
555
549
  }
556
550
  #getCellCoords(cell) {
557
- const { height, left, top, width } = cell.getBoundingClientRect();
558
- return {
559
- x: left + width / 2,
560
- y: top + height / 2
561
- };
551
+ const { left, top, width, height } = cell.getBoundingClientRect();
552
+ return { x: left + width / 2, y: top + height / 2 };
562
553
  }
563
554
  #getCellsOfActiveRow() {
564
555
  const active = getActiveElement();
@@ -633,7 +624,9 @@ var RovingTabIndex = class _RovingTabIndex {
633
624
  typeahead = false,
634
625
  wrap = false
635
626
  } = options;
636
- direction = direction.toLowerCase();
627
+ if (typeof direction === "string") {
628
+ direction = direction.toLowerCase();
629
+ }
637
630
  if (!DIRECTIONS.includes(direction)) {
638
631
  console.warn("Invalid direction option. Fallback: 'both'.");
639
632
  direction = "both";
@@ -977,44 +970,5 @@ function waitAnimationFinish(animation) {
977
970
  (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
978
971
  );
979
972
  }
980
- /*! Bundled license information:
981
-
982
- @y14e/attribute-utils/dist/index.js:
983
- (**
984
- * Attribute Utils
985
- *
986
- * @version 2.0.12
987
- * @author Yusuke Kamiyamane
988
- * @license MIT
989
- * @copyright Copyright (c) Yusuke Kamiyamane
990
- * @see {@link https://github.com/y14e/attribute-utils}
991
- *)
992
-
993
- power-focusable/dist/index.js:
994
- (**
995
- * Power Focusable
996
- * High-precision focus management utility with full composed tree support.
997
- * Handles complex focus rules including tabindex ordering, radio groups, inert.
998
- *
999
- * @version 4.4.3
1000
- * @author Yusuke Kamiyamane
1001
- * @license MIT
1002
- * @copyright Copyright (c) Yusuke Kamiyamane
1003
- * @see {@link https://github.com/y14e/power-focusable}
1004
- *)
1005
-
1006
- @y14e/roving-tabindex/dist/index.js:
1007
- (**
1008
- * Roving Tabindex
1009
- * Lightweight roving tabindex utility with fully focus management.
1010
- * Designed for accessible menus, tabs, toolbars, and composite widgets.
1011
- *
1012
- * @version 3.3.2
1013
- * @author Yusuke Kamiyamane
1014
- * @license MIT
1015
- * @copyright Copyright (c) Yusuke Kamiyamane
1016
- * @see {@link https://github.com/y14e/roving-tabindex}
1017
- *)
1018
- */
1019
973
 
1020
974
  export { Disclosure };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/disclosure",
3
- "version": "2.1.2",
3
+ "version": "2.1.4",
4
4
  "description": "WAI-ARIA compliant disclosure pattern implementation in TypeScript",
5
5
  "keywords": [
6
6
  "a11y",
@@ -42,6 +42,10 @@
42
42
  "lint": "tsc --noEmit",
43
43
  "prepublishOnly": "npm run build"
44
44
  },
45
+ "dependencies": {
46
+ "@y14e/attribute-utils": "^2.0.15",
47
+ "@y14e/roving-tabindex": "^3.3.8"
48
+ },
45
49
  "devDependencies": {
46
50
  "bun-types": "latest",
47
51
  "tsup": "^8.0.0",
@@ -52,9 +56,5 @@
52
56
  },
53
57
  "allowScripts": {
54
58
  "esbuild": true
55
- },
56
- "dependencies": {
57
- "@y14e/attribute-utils": "^2.0.12",
58
- "@y14e/roving-tabindex": "^3.3.2"
59
59
  }
60
60
  }