@y14e/tabs 1.5.5 → 1.5.7

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
@@ -10,14 +10,14 @@ npm i @y14e/tabs
10
10
 
11
11
  ```ts
12
12
  // npm
13
- import Tabs from '@y14e/tabs@1.5.5';
13
+ import Tabs from '@y14e/tabs@1.5.7';
14
14
 
15
15
  // CDNs
16
- import Tabs from 'https://esm.sh/@y14e/tabs@1.5.5';
16
+ import Tabs from 'https://esm.sh/@y14e/tabs@1.5.7';
17
17
  // or
18
- import Tabs from 'https://cdn.jsdelivr.net/npm/@y14e/tabs@1.5.5/+esm';
18
+ import Tabs from 'https://cdn.jsdelivr.net/npm/@y14e/tabs@1.5.7/+esm';
19
19
  // or
20
- import Tabs from 'https://esm.unpkg.com/@y14e/tabs@1.5.5';
20
+ import Tabs from 'https://esm.unpkg.com/@y14e/tabs@1.5.7';
21
21
  ```
22
22
 
23
23
  ## Usage
package/dist/index.cjs CHANGED
@@ -13,11 +13,10 @@ function addTokenToAttribute(element, attribute, token, options = {}) {
13
13
  const tokens = value ? parse(value).filter(Boolean) : [];
14
14
  if (caseInsensitive) {
15
15
  const lower = token.toLowerCase();
16
- if (tokens.some((token2) => token2.toLowerCase() === lower)) {
17
- return;
16
+ if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
17
+ tokens.push(token);
18
+ element.setAttribute(attribute, serialize(tokens));
18
19
  }
19
- tokens.push(token);
20
- element.setAttribute(attribute, serialize(tokens));
21
20
  return;
22
21
  }
23
22
  const set = new Set(tokens);
@@ -119,11 +118,10 @@ function addTokenToAttribute2(element, attribute, token, options = {}) {
119
118
  const tokens = value ? parse(value).filter(Boolean) : [];
120
119
  if (caseInsensitive) {
121
120
  const lower = token.toLowerCase();
122
- if (tokens.some((token2) => token2.toLowerCase() === lower)) {
123
- return;
121
+ if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
122
+ tokens.push(token);
123
+ element.setAttribute(attribute, serialize(tokens));
124
124
  }
125
- tokens.push(token);
126
- element.setAttribute(attribute, serialize(tokens));
127
125
  return;
128
126
  }
129
127
  const set = new Set(tokens);
@@ -402,6 +400,8 @@ function createRovingTabIndex(container, options = {}) {
402
400
  let {
403
401
  direction,
404
402
  navigationOnly = false,
403
+ noMemory = false,
404
+ noStart = false,
405
405
  selector,
406
406
  typeahead = false,
407
407
  wrap = false
@@ -414,6 +414,14 @@ function createRovingTabIndex(container, options = {}) {
414
414
  console.warn("Invalid navigationOnly option. Fallback: false.");
415
415
  navigationOnly = false;
416
416
  }
417
+ if (typeof noMemory !== "boolean") {
418
+ console.warn("Invalid noMemory option. Fallback: false.");
419
+ noMemory = false;
420
+ }
421
+ if (typeof noStart !== "boolean") {
422
+ console.warn("Invalid noStart option. Fallback: false.");
423
+ noStart = false;
424
+ }
417
425
  if (typeof selector !== "undefined" && (typeof selector !== "string" || !selector.trim())) {
418
426
  console.warn(
419
427
  "Invalid selector. Fallback: all focusable elements (undefined)."
@@ -428,13 +436,9 @@ function createRovingTabIndex(container, options = {}) {
428
436
  console.warn("Invalid wrap option. Fallback: false.");
429
437
  wrap = false;
430
438
  }
431
- const settings = { navigationOnly, typeahead, wrap };
432
- if (direction) {
433
- Object.assign(settings, { direction });
434
- }
435
- if (selector) {
436
- Object.assign(settings, { selector });
437
- }
439
+ const settings = { navigationOnly, noMemory, noStart, typeahead, wrap };
440
+ direction && Object.assign(settings, { direction });
441
+ selector && Object.assign(settings, { selector });
438
442
  const roving = new RovingTabIndex(container, settings);
439
443
  return () => roving.destroy();
440
444
  }
@@ -467,12 +471,29 @@ var RovingTabIndex = class {
467
471
  #initialize() {
468
472
  this.#update(document.activeElement);
469
473
  this.#controller = new AbortController();
474
+ const { signal } = this.#controller;
475
+ document.addEventListener("focusin", this.#onFocusIn, {
476
+ capture: true,
477
+ signal
478
+ });
470
479
  document.addEventListener("keydown", this.#onKeyDown, {
471
480
  capture: true,
472
- signal: this.#controller.signal
481
+ signal
473
482
  });
474
483
  this.#container.setAttribute("data-roving-tabindex-initialized", "");
475
484
  }
485
+ #onFocusIn = (event) => {
486
+ const { target } = event;
487
+ if (!(target instanceof Element)) {
488
+ return;
489
+ }
490
+ const isFocusable22 = this.#focusables.has(target);
491
+ if (this.#options.noMemory && !isFocusable22) {
492
+ this.#update(null);
493
+ return;
494
+ }
495
+ isFocusable22 && this.#update(target);
496
+ };
476
497
  #onKeyDown = (event) => {
477
498
  if (!event.composedPath().includes(this.#container)) {
478
499
  return;
@@ -534,11 +555,7 @@ var RovingTabIndex = class {
534
555
  }
535
556
  }
536
557
  const focusable = target.at(newIndex);
537
- if (!focusable) {
538
- return;
539
- }
540
- this.#update(focusable);
541
- focusElement(focusable);
558
+ focusable && focusElement(focusable);
542
559
  };
543
560
  #update(active) {
544
561
  const current = new Set(this.#getFocusables());
@@ -553,7 +570,7 @@ var RovingTabIndex = class {
553
570
  index >= 0 && focusables.splice(index, 1);
554
571
  });
555
572
  }
556
- const { navigationOnly } = this.#options;
573
+ const { navigationOnly, noStart, typeahead } = this.#options;
557
574
  for (const focusable of current) {
558
575
  if (this.#focusables.has(focusable)) {
559
576
  continue;
@@ -563,7 +580,7 @@ var RovingTabIndex = class {
563
580
  saveAttributes2([focusable], ["tabindex"]);
564
581
  focusable.setAttribute("tabindex", "-1");
565
582
  }
566
- if (!this.#options.typeahead) {
583
+ if (!typeahead) {
567
584
  continue;
568
585
  }
569
586
  const value = focusable.ariaKeyShortcuts?.trim();
@@ -594,7 +611,7 @@ var RovingTabIndex = class {
594
611
  return;
595
612
  }
596
613
  [...this.#focusables].forEach((focusable, i) => {
597
- focusable.setAttribute("tabindex", i ? "-1" : "0");
614
+ focusable.setAttribute("tabindex", i || noStart ? "-1" : "0");
598
615
  });
599
616
  }
600
617
  #createSelectorFilter() {
@@ -605,7 +622,8 @@ var RovingTabIndex = class {
605
622
  return getFocusables(this.#container, {
606
623
  composed: true,
607
624
  filter: this.#selectorFilter,
608
- skipNegativeTabIndexCheck: !this.#options.navigationOnly
625
+ skipNegativeTabIndexCheck: !this.#options.navigationOnly,
626
+ skipVisibilityCheck: true
609
627
  });
610
628
  }
611
629
  };
@@ -659,6 +677,7 @@ var Tabs = class _Tabs {
659
677
  #animationController = null;
660
678
  #cleanupsRovingTabIndex = [];
661
679
  #animation = null;
680
+ #animationId = 0;
662
681
  #buttons = [];
663
682
  #indicators = [];
664
683
  #isDestroyed = false;
@@ -761,14 +780,14 @@ var Tabs = class _Tabs {
761
780
  const { style } = this.#contentElement;
762
781
  style.setProperty("overflow", "clip");
763
782
  style.setProperty("position", "relative");
764
- const { fade, crossFade } = this.#settings.animation.content;
783
+ const { crossFade, fade } = this.#settings.animation.content;
765
784
  const panel = this.#bindings.get(tab)?.panel;
766
785
  if (!panel) {
767
786
  return;
768
787
  }
769
788
  this.#panelElements.forEach((p) => {
770
789
  const { style: style2 } = p;
771
- if (fade || crossFade) {
790
+ if (crossFade || fade) {
772
791
  style2.setProperty("content-visibility", "visible");
773
792
  style2.setProperty("display", "block");
774
793
  style2.setProperty("opacity", p.hidden ? "0" : "1");
@@ -788,6 +807,7 @@ var Tabs = class _Tabs {
788
807
  p.setAttribute("hidden", isFocusable2(tab2) ? "until-found" : "");
789
808
  }
790
809
  });
810
+ const animationId = ++this.#animationId;
791
811
  this.#animation?.cancel();
792
812
  const { duration, easing } = this.#settings.animation.content;
793
813
  this.#animation = this.#contentElement.animate(
@@ -803,7 +823,9 @@ var Tabs = class _Tabs {
803
823
  }
804
824
  );
805
825
  const cleanup = () => {
806
- this.#animation = null;
826
+ if (animationId === this.#animationId) {
827
+ this.#animation = null;
828
+ }
807
829
  };
808
830
  this.#animationController = new AbortController();
809
831
  const { signal } = this.#animationController;
@@ -814,8 +836,10 @@ var Tabs = class _Tabs {
814
836
  this.#animation.addEventListener(
815
837
  "finish",
816
838
  () => {
817
- this.#onAnimationFinish();
818
- cleanup();
839
+ if (animationId === this.#animationId) {
840
+ this.#onAnimationFinish();
841
+ cleanup();
842
+ }
819
843
  },
820
844
  {
821
845
  once: true,
@@ -835,7 +859,7 @@ var Tabs = class _Tabs {
835
859
  opacity: fade ? isSelected ? [opacity, opacity, "1"] : [opacity, "0", "0"] : isSelected ? [opacity, "1"] : [opacity, "0"]
836
860
  },
837
861
  {
838
- duration: isMatch || !(fade || crossFade) ? 0 : this.#settings.animation.content.duration,
862
+ duration: isMatch || !(crossFade || fade) ? 0 : this.#settings.animation.content.duration,
839
863
  easing: "ease"
840
864
  }
841
865
  );
@@ -888,10 +912,7 @@ var Tabs = class _Tabs {
888
912
  );
889
913
  }
890
914
  this.#panelElements.forEach((panel) => {
891
- const animation = this.#bindings.get(panel)?.animation;
892
- if (animation) {
893
- animation.cancel();
894
- }
915
+ this.#bindings.get(panel)?.animation?.cancel();
895
916
  });
896
917
  this.#onAnimationFinish();
897
918
  this.#animationController?.abort();
@@ -973,11 +994,9 @@ var Tabs = class _Tabs {
973
994
  });
974
995
  const options = { selector: this.#settings.selector.tab, wrap: true };
975
996
  this.#listElements.forEach((list) => {
976
- if (list.ariaOrientation !== "undefined") {
977
- Object.assign(options, {
978
- direction: this.#settings.vertical ? "vertical" : "horizontal"
979
- });
980
- }
997
+ list.ariaOrientation !== "undefined" && Object.assign(options, {
998
+ direction: this.#settings.vertical ? "vertical" : "horizontal"
999
+ });
981
1000
  this.#cleanupsRovingTabIndex.push(createRovingTabIndex(list, options));
982
1001
  list.querySelectorAll(this.#settings.selector.tab).forEach((tab) => {
983
1002
  tab.setAttribute(
@@ -1145,7 +1164,7 @@ function isFocusable2(element) {
1145
1164
  * Tabs
1146
1165
  * WAI-ARIA compliant tabs pattern implementation in TypeScript.
1147
1166
  *
1148
- * @version 1.5.5
1167
+ * @version 1.5.7
1149
1168
  * @author Yusuke Kamiyamane
1150
1169
  * @license MIT
1151
1170
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1157,7 +1176,7 @@ function isFocusable2(element) {
1157
1176
  (**
1158
1177
  * Attributes Utils
1159
1178
  *
1160
- * @version 1.1.0
1179
+ * @version 1.1.1
1161
1180
  * @author Yusuke Kamiyamane
1162
1181
  * @license MIT
1163
1182
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1181,7 +1200,7 @@ function isFocusable2(element) {
1181
1200
  * Lightweight roving tabindex utility with fully focus management.
1182
1201
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
1183
1202
  *
1184
- * @version 2.0.4
1203
+ * @version 2.2.0
1185
1204
  * @author Yusuke Kamiyamane
1186
1205
  * @license MIT
1187
1206
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1193,7 +1212,7 @@ function isFocusable2(element) {
1193
1212
  (**
1194
1213
  * Attributes Utils
1195
1214
  *
1196
- * @version 1.1.0
1215
+ * @version 1.1.1
1197
1216
  * @author Yusuke Kamiyamane
1198
1217
  * @license MIT
1199
1218
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1206,7 +1225,7 @@ function isFocusable2(element) {
1206
1225
  * High-precision focus management utility with full composed tree support.
1207
1226
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
1208
1227
  *
1209
- * @version 4.3.1
1228
+ * @version 4.3.2
1210
1229
  * @author Yusuke Kamiyamane
1211
1230
  * @license MIT
1212
1231
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.cts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Tabs
3
3
  * WAI-ARIA compliant tabs pattern implementation in TypeScript.
4
4
  *
5
- * @version 1.5.5
5
+ * @version 1.5.7
6
6
  * @author Yusuke Kamiyamane
7
7
  * @license MIT
8
8
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Tabs
3
3
  * WAI-ARIA compliant tabs pattern implementation in TypeScript.
4
4
  *
5
- * @version 1.5.5
5
+ * @version 1.5.7
6
6
  * @author Yusuke Kamiyamane
7
7
  * @license MIT
8
8
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -11,11 +11,10 @@ function addTokenToAttribute(element, attribute, token, options = {}) {
11
11
  const tokens = value ? parse(value).filter(Boolean) : [];
12
12
  if (caseInsensitive) {
13
13
  const lower = token.toLowerCase();
14
- if (tokens.some((token2) => token2.toLowerCase() === lower)) {
15
- return;
14
+ if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
15
+ tokens.push(token);
16
+ element.setAttribute(attribute, serialize(tokens));
16
17
  }
17
- tokens.push(token);
18
- element.setAttribute(attribute, serialize(tokens));
19
18
  return;
20
19
  }
21
20
  const set = new Set(tokens);
@@ -117,11 +116,10 @@ function addTokenToAttribute2(element, attribute, token, options = {}) {
117
116
  const tokens = value ? parse(value).filter(Boolean) : [];
118
117
  if (caseInsensitive) {
119
118
  const lower = token.toLowerCase();
120
- if (tokens.some((token2) => token2.toLowerCase() === lower)) {
121
- return;
119
+ if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
120
+ tokens.push(token);
121
+ element.setAttribute(attribute, serialize(tokens));
122
122
  }
123
- tokens.push(token);
124
- element.setAttribute(attribute, serialize(tokens));
125
123
  return;
126
124
  }
127
125
  const set = new Set(tokens);
@@ -400,6 +398,8 @@ function createRovingTabIndex(container, options = {}) {
400
398
  let {
401
399
  direction,
402
400
  navigationOnly = false,
401
+ noMemory = false,
402
+ noStart = false,
403
403
  selector,
404
404
  typeahead = false,
405
405
  wrap = false
@@ -412,6 +412,14 @@ function createRovingTabIndex(container, options = {}) {
412
412
  console.warn("Invalid navigationOnly option. Fallback: false.");
413
413
  navigationOnly = false;
414
414
  }
415
+ if (typeof noMemory !== "boolean") {
416
+ console.warn("Invalid noMemory option. Fallback: false.");
417
+ noMemory = false;
418
+ }
419
+ if (typeof noStart !== "boolean") {
420
+ console.warn("Invalid noStart option. Fallback: false.");
421
+ noStart = false;
422
+ }
415
423
  if (typeof selector !== "undefined" && (typeof selector !== "string" || !selector.trim())) {
416
424
  console.warn(
417
425
  "Invalid selector. Fallback: all focusable elements (undefined)."
@@ -426,13 +434,9 @@ function createRovingTabIndex(container, options = {}) {
426
434
  console.warn("Invalid wrap option. Fallback: false.");
427
435
  wrap = false;
428
436
  }
429
- const settings = { navigationOnly, typeahead, wrap };
430
- if (direction) {
431
- Object.assign(settings, { direction });
432
- }
433
- if (selector) {
434
- Object.assign(settings, { selector });
435
- }
437
+ const settings = { navigationOnly, noMemory, noStart, typeahead, wrap };
438
+ direction && Object.assign(settings, { direction });
439
+ selector && Object.assign(settings, { selector });
436
440
  const roving = new RovingTabIndex(container, settings);
437
441
  return () => roving.destroy();
438
442
  }
@@ -465,12 +469,29 @@ var RovingTabIndex = class {
465
469
  #initialize() {
466
470
  this.#update(document.activeElement);
467
471
  this.#controller = new AbortController();
472
+ const { signal } = this.#controller;
473
+ document.addEventListener("focusin", this.#onFocusIn, {
474
+ capture: true,
475
+ signal
476
+ });
468
477
  document.addEventListener("keydown", this.#onKeyDown, {
469
478
  capture: true,
470
- signal: this.#controller.signal
479
+ signal
471
480
  });
472
481
  this.#container.setAttribute("data-roving-tabindex-initialized", "");
473
482
  }
483
+ #onFocusIn = (event) => {
484
+ const { target } = event;
485
+ if (!(target instanceof Element)) {
486
+ return;
487
+ }
488
+ const isFocusable22 = this.#focusables.has(target);
489
+ if (this.#options.noMemory && !isFocusable22) {
490
+ this.#update(null);
491
+ return;
492
+ }
493
+ isFocusable22 && this.#update(target);
494
+ };
474
495
  #onKeyDown = (event) => {
475
496
  if (!event.composedPath().includes(this.#container)) {
476
497
  return;
@@ -532,11 +553,7 @@ var RovingTabIndex = class {
532
553
  }
533
554
  }
534
555
  const focusable = target.at(newIndex);
535
- if (!focusable) {
536
- return;
537
- }
538
- this.#update(focusable);
539
- focusElement(focusable);
556
+ focusable && focusElement(focusable);
540
557
  };
541
558
  #update(active) {
542
559
  const current = new Set(this.#getFocusables());
@@ -551,7 +568,7 @@ var RovingTabIndex = class {
551
568
  index >= 0 && focusables.splice(index, 1);
552
569
  });
553
570
  }
554
- const { navigationOnly } = this.#options;
571
+ const { navigationOnly, noStart, typeahead } = this.#options;
555
572
  for (const focusable of current) {
556
573
  if (this.#focusables.has(focusable)) {
557
574
  continue;
@@ -561,7 +578,7 @@ var RovingTabIndex = class {
561
578
  saveAttributes2([focusable], ["tabindex"]);
562
579
  focusable.setAttribute("tabindex", "-1");
563
580
  }
564
- if (!this.#options.typeahead) {
581
+ if (!typeahead) {
565
582
  continue;
566
583
  }
567
584
  const value = focusable.ariaKeyShortcuts?.trim();
@@ -592,7 +609,7 @@ var RovingTabIndex = class {
592
609
  return;
593
610
  }
594
611
  [...this.#focusables].forEach((focusable, i) => {
595
- focusable.setAttribute("tabindex", i ? "-1" : "0");
612
+ focusable.setAttribute("tabindex", i || noStart ? "-1" : "0");
596
613
  });
597
614
  }
598
615
  #createSelectorFilter() {
@@ -603,7 +620,8 @@ var RovingTabIndex = class {
603
620
  return getFocusables(this.#container, {
604
621
  composed: true,
605
622
  filter: this.#selectorFilter,
606
- skipNegativeTabIndexCheck: !this.#options.navigationOnly
623
+ skipNegativeTabIndexCheck: !this.#options.navigationOnly,
624
+ skipVisibilityCheck: true
607
625
  });
608
626
  }
609
627
  };
@@ -657,6 +675,7 @@ var Tabs = class _Tabs {
657
675
  #animationController = null;
658
676
  #cleanupsRovingTabIndex = [];
659
677
  #animation = null;
678
+ #animationId = 0;
660
679
  #buttons = [];
661
680
  #indicators = [];
662
681
  #isDestroyed = false;
@@ -759,14 +778,14 @@ var Tabs = class _Tabs {
759
778
  const { style } = this.#contentElement;
760
779
  style.setProperty("overflow", "clip");
761
780
  style.setProperty("position", "relative");
762
- const { fade, crossFade } = this.#settings.animation.content;
781
+ const { crossFade, fade } = this.#settings.animation.content;
763
782
  const panel = this.#bindings.get(tab)?.panel;
764
783
  if (!panel) {
765
784
  return;
766
785
  }
767
786
  this.#panelElements.forEach((p) => {
768
787
  const { style: style2 } = p;
769
- if (fade || crossFade) {
788
+ if (crossFade || fade) {
770
789
  style2.setProperty("content-visibility", "visible");
771
790
  style2.setProperty("display", "block");
772
791
  style2.setProperty("opacity", p.hidden ? "0" : "1");
@@ -786,6 +805,7 @@ var Tabs = class _Tabs {
786
805
  p.setAttribute("hidden", isFocusable2(tab2) ? "until-found" : "");
787
806
  }
788
807
  });
808
+ const animationId = ++this.#animationId;
789
809
  this.#animation?.cancel();
790
810
  const { duration, easing } = this.#settings.animation.content;
791
811
  this.#animation = this.#contentElement.animate(
@@ -801,7 +821,9 @@ var Tabs = class _Tabs {
801
821
  }
802
822
  );
803
823
  const cleanup = () => {
804
- this.#animation = null;
824
+ if (animationId === this.#animationId) {
825
+ this.#animation = null;
826
+ }
805
827
  };
806
828
  this.#animationController = new AbortController();
807
829
  const { signal } = this.#animationController;
@@ -812,8 +834,10 @@ var Tabs = class _Tabs {
812
834
  this.#animation.addEventListener(
813
835
  "finish",
814
836
  () => {
815
- this.#onAnimationFinish();
816
- cleanup();
837
+ if (animationId === this.#animationId) {
838
+ this.#onAnimationFinish();
839
+ cleanup();
840
+ }
817
841
  },
818
842
  {
819
843
  once: true,
@@ -833,7 +857,7 @@ var Tabs = class _Tabs {
833
857
  opacity: fade ? isSelected ? [opacity, opacity, "1"] : [opacity, "0", "0"] : isSelected ? [opacity, "1"] : [opacity, "0"]
834
858
  },
835
859
  {
836
- duration: isMatch || !(fade || crossFade) ? 0 : this.#settings.animation.content.duration,
860
+ duration: isMatch || !(crossFade || fade) ? 0 : this.#settings.animation.content.duration,
837
861
  easing: "ease"
838
862
  }
839
863
  );
@@ -886,10 +910,7 @@ var Tabs = class _Tabs {
886
910
  );
887
911
  }
888
912
  this.#panelElements.forEach((panel) => {
889
- const animation = this.#bindings.get(panel)?.animation;
890
- if (animation) {
891
- animation.cancel();
892
- }
913
+ this.#bindings.get(panel)?.animation?.cancel();
893
914
  });
894
915
  this.#onAnimationFinish();
895
916
  this.#animationController?.abort();
@@ -971,11 +992,9 @@ var Tabs = class _Tabs {
971
992
  });
972
993
  const options = { selector: this.#settings.selector.tab, wrap: true };
973
994
  this.#listElements.forEach((list) => {
974
- if (list.ariaOrientation !== "undefined") {
975
- Object.assign(options, {
976
- direction: this.#settings.vertical ? "vertical" : "horizontal"
977
- });
978
- }
995
+ list.ariaOrientation !== "undefined" && Object.assign(options, {
996
+ direction: this.#settings.vertical ? "vertical" : "horizontal"
997
+ });
979
998
  this.#cleanupsRovingTabIndex.push(createRovingTabIndex(list, options));
980
999
  list.querySelectorAll(this.#settings.selector.tab).forEach((tab) => {
981
1000
  tab.setAttribute(
@@ -1143,7 +1162,7 @@ function isFocusable2(element) {
1143
1162
  * Tabs
1144
1163
  * WAI-ARIA compliant tabs pattern implementation in TypeScript.
1145
1164
  *
1146
- * @version 1.5.5
1165
+ * @version 1.5.7
1147
1166
  * @author Yusuke Kamiyamane
1148
1167
  * @license MIT
1149
1168
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1155,7 +1174,7 @@ function isFocusable2(element) {
1155
1174
  (**
1156
1175
  * Attributes Utils
1157
1176
  *
1158
- * @version 1.1.0
1177
+ * @version 1.1.1
1159
1178
  * @author Yusuke Kamiyamane
1160
1179
  * @license MIT
1161
1180
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1179,7 +1198,7 @@ function isFocusable2(element) {
1179
1198
  * Lightweight roving tabindex utility with fully focus management.
1180
1199
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
1181
1200
  *
1182
- * @version 2.0.4
1201
+ * @version 2.2.0
1183
1202
  * @author Yusuke Kamiyamane
1184
1203
  * @license MIT
1185
1204
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1191,7 +1210,7 @@ function isFocusable2(element) {
1191
1210
  (**
1192
1211
  * Attributes Utils
1193
1212
  *
1194
- * @version 1.1.0
1213
+ * @version 1.1.1
1195
1214
  * @author Yusuke Kamiyamane
1196
1215
  * @license MIT
1197
1216
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1204,7 +1223,7 @@ function isFocusable2(element) {
1204
1223
  * High-precision focus management utility with full composed tree support.
1205
1224
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
1206
1225
  *
1207
- * @version 4.3.1
1226
+ * @version 4.3.2
1208
1227
  * @author Yusuke Kamiyamane
1209
1228
  * @license MIT
1210
1229
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/tabs",
3
- "version": "1.5.5",
3
+ "version": "1.5.7",
4
4
  "description": "WAI-ARIA compliant tabs pattern implementation in TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -42,9 +42,9 @@
42
42
  },
43
43
  "homepage": "https://github.com/y14e/tabs#readme",
44
44
  "devDependencies": {
45
- "@y14e/attributes-utils": "^1.1.0",
45
+ "@y14e/attributes-utils": "^1.1.1",
46
46
  "@y14e/button": "^1.0.0",
47
- "@y14e/roving-tabindex": "^2.0.4",
47
+ "@y14e/roving-tabindex": "^2.2.0",
48
48
  "bun-types": "latest",
49
49
  "tsup": "^8.0.0",
50
50
  "typescript": "^5.6.0",