@y14e/tabs 1.4.1 → 1.5.1

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/dist/index.cjs CHANGED
@@ -50,6 +50,62 @@ function saveAttributes(elements, attributes) {
50
50
  });
51
51
  }
52
52
 
53
+ // node_modules/@y14e/button/dist/index.js
54
+ var Button = class {
55
+ #element;
56
+ #controller = null;
57
+ #isDestroyed = false;
58
+ constructor(element) {
59
+ if (!(element instanceof HTMLElement)) {
60
+ throw new TypeError("Invalid element");
61
+ }
62
+ if (element.hasAttribute("data-button-initialized")) {
63
+ console.warn("Already initialized");
64
+ return;
65
+ }
66
+ this.#element = element;
67
+ this.#initialize();
68
+ }
69
+ destroy() {
70
+ if (this.#isDestroyed) {
71
+ return;
72
+ }
73
+ this.#isDestroyed = true;
74
+ this.#controller?.abort();
75
+ this.#controller = null;
76
+ this.#element.removeAttribute("data-button-initialized");
77
+ }
78
+ #initialize() {
79
+ this.#controller = new AbortController();
80
+ this.#element.addEventListener("keydown", this.#onKeyDown, {
81
+ signal: this.#controller.signal
82
+ });
83
+ this.#element.setAttribute("data-button-initialized", "");
84
+ }
85
+ #onKeyDown = (event) => {
86
+ const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
87
+ if (altKey || ctrlKey || metaKey || shiftKey) {
88
+ return;
89
+ }
90
+ if (!["Enter", " "].includes(key)) {
91
+ return;
92
+ }
93
+ const active = getActiveElement();
94
+ if (!(active instanceof HTMLElement)) {
95
+ return;
96
+ }
97
+ event.preventDefault();
98
+ active.click();
99
+ };
100
+ };
101
+ function getActiveElement() {
102
+ let current = document.activeElement;
103
+ while (current?.shadowRoot?.activeElement) {
104
+ current = current.shadowRoot.activeElement;
105
+ }
106
+ return current;
107
+ }
108
+
53
109
  // node_modules/@y14e/roving-tabindex/dist/index.js
54
110
  var defaultParser2 = (value) => value.split(/\s+/);
55
111
  var defaultSerializer2 = (tokens) => tokens.join(" ");
@@ -127,6 +183,10 @@ function getFocusables(container = document.body, options = {}) {
127
183
  );
128
184
  include = void 0;
129
185
  }
186
+ if (typeof skipVisibilityCheck !== "boolean") {
187
+ console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
188
+ skipVisibilityCheck = false;
189
+ }
130
190
  const elements = [];
131
191
  if (composed || include) {
132
192
  let traverse2 = function(node) {
@@ -326,6 +386,7 @@ function createRovingTabIndex(container, options = {}) {
326
386
  direction,
327
387
  navigationOnly = false,
328
388
  selector,
389
+ skipVisibilityCheck = false,
329
390
  typeahead = false,
330
391
  wrap = false
331
392
  } = options;
@@ -343,6 +404,10 @@ function createRovingTabIndex(container, options = {}) {
343
404
  );
344
405
  selector = void 0;
345
406
  }
407
+ if (typeof skipVisibilityCheck !== "boolean") {
408
+ console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
409
+ skipVisibilityCheck = false;
410
+ }
346
411
  if (typeof typeahead !== "boolean") {
347
412
  console.warn("Invalid typeahead option. Fallback: false.");
348
413
  typeahead = false;
@@ -355,6 +420,7 @@ function createRovingTabIndex(container, options = {}) {
355
420
  direction,
356
421
  navigationOnly,
357
422
  selector,
423
+ skipVisibilityCheck,
358
424
  typeahead,
359
425
  wrap
360
426
  });
@@ -416,7 +482,7 @@ var RovingTabIndex = class {
416
482
  return;
417
483
  }
418
484
  }
419
- const active = getActiveElement();
485
+ const active = getActiveElement2();
420
486
  if (!(active instanceof HTMLElement)) {
421
487
  return;
422
488
  }
@@ -468,7 +534,7 @@ var RovingTabIndex = class {
468
534
  ...getFocusables(this.#container, {
469
535
  composed: true,
470
536
  filter: this.#selectorFilter,
471
- skipVisibilityCheck: true
537
+ skipVisibilityCheck: !!this.#options.skipVisibilityCheck
472
538
  })
473
539
  ]);
474
540
  for (const focusable of this.#focusables) {
@@ -535,14 +601,14 @@ var RovingTabIndex = class {
535
601
  composed: true,
536
602
  filter: this.#selectorFilter,
537
603
  include: (element) => this.#focusables.has(element),
538
- skipVisibilityCheck: true
604
+ skipVisibilityCheck: !!this.#options.skipVisibilityCheck
539
605
  });
540
606
  }
541
607
  };
542
608
  function focusElement(element) {
543
609
  "focus" in element && typeof element.focus === "function" && element.focus();
544
610
  }
545
- function getActiveElement() {
611
+ function getActiveElement2() {
546
612
  let current = document.activeElement;
547
613
  while (current?.shadowRoot?.activeElement) {
548
614
  current = current.shadowRoot.activeElement;
@@ -589,6 +655,7 @@ var Tabs = class _Tabs {
589
655
  #animationController = null;
590
656
  #cleanupsRovingTabIndex = [];
591
657
  #animation = null;
658
+ #buttons = [];
592
659
  #indicators = [];
593
660
  #isDestroyed = false;
594
661
  constructor(root, options = {}) {
@@ -791,6 +858,10 @@ var Tabs = class _Tabs {
791
858
  cleanup();
792
859
  });
793
860
  this.#cleanupsRovingTabIndex.length = 0;
861
+ this.#buttons.forEach((button) => {
862
+ button.destroy();
863
+ });
864
+ this.#buttons.length = 0;
794
865
  this.#indicators.forEach((indicator) => {
795
866
  indicator.destroy(force);
796
867
  });
@@ -876,7 +947,7 @@ var Tabs = class _Tabs {
876
947
  addTokenToAttribute(panel, "aria-labelledby", tab.id);
877
948
  tab.addEventListener("click", this.#onTabClick, { signal });
878
949
  tab.addEventListener("focus", this.#onTabFocus, { signal });
879
- tab.addEventListener("keydown", this.#onTabKeyDown, { signal });
950
+ this.#buttons.push(new Button(tab));
880
951
  });
881
952
  saveAttributes(this.#indicatorElements, ["style"]);
882
953
  this.#indicatorElements.forEach((indicator) => {
@@ -898,6 +969,7 @@ var Tabs = class _Tabs {
898
969
  createRovingTabIndex(list, {
899
970
  direction: list.ariaOrientation === "undefined" ? void 0 : this.#settings.vertical ? "vertical" : "horizontal",
900
971
  selector: this.#settings.selector.tab,
972
+ skipVisibilityCheck: true,
901
973
  wrap: true
902
974
  })
903
975
  );
@@ -926,21 +998,6 @@ var Tabs = class _Tabs {
926
998
  !this.#settings.manual && tab.click();
927
999
  this.#isAvoidedTab(tab) && tab.blur();
928
1000
  };
929
- #onTabKeyDown = (event) => {
930
- const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
931
- if (altKey || ctrlKey || metaKey || shiftKey) {
932
- return;
933
- }
934
- if (!["Enter", " "].includes(key)) {
935
- return;
936
- }
937
- const active = getActiveElement2();
938
- if (!(active instanceof HTMLElement)) {
939
- return;
940
- }
941
- event.preventDefault();
942
- active.click();
943
- };
944
1001
  #onPanelBeforeMatch = (event) => {
945
1002
  const panel = event.currentTarget;
946
1003
  if (!(panel instanceof HTMLElement)) {
@@ -1069,13 +1126,6 @@ var TabsIndicator = class {
1069
1126
  function createBinding(tabs, panel) {
1070
1127
  return { tabs, panel, animation: null };
1071
1128
  }
1072
- function getActiveElement2() {
1073
- let current = document.activeElement;
1074
- while (current?.shadowRoot?.activeElement) {
1075
- current = current.shadowRoot.activeElement;
1076
- }
1077
- return current;
1078
- }
1079
1129
  function hasFocusable(container) {
1080
1130
  return !![
1081
1131
  ...container.querySelectorAll(
@@ -1090,7 +1140,7 @@ function isFocusable2(element) {
1090
1140
  * Tabs
1091
1141
  * WAI-ARIA compliant tabs pattern implementation in TypeScript.
1092
1142
  *
1093
- * @version 1.4.1
1143
+ * @version 1.5.1
1094
1144
  * @author Yusuke Kamiyamane
1095
1145
  * @license MIT
1096
1146
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1109,13 +1159,24 @@ function isFocusable2(element) {
1109
1159
  * @see {@link https://github.com/y14e/attributes-utils}
1110
1160
  *)
1111
1161
 
1162
+ @y14e/button/dist/index.js:
1163
+ (**
1164
+ * Button
1165
+ *
1166
+ * @version 1.0.0
1167
+ * @author Yusuke Kamiyamane
1168
+ * @license MIT
1169
+ * @copyright Copyright (c) Yusuke Kamiyamane
1170
+ * @see {@link https://github.com/y14e/button}
1171
+ *)
1172
+
1112
1173
  @y14e/roving-tabindex/dist/index.js:
1113
1174
  (**
1114
1175
  * Roving Tabindex
1115
1176
  * Lightweight roving tabindex utility with fully focus management.
1116
1177
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
1117
1178
  *
1118
- * @version 1.3.1
1179
+ * @version 1.3.2
1119
1180
  * @author Yusuke Kamiyamane
1120
1181
  * @license MIT
1121
1182
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1140,7 +1201,7 @@ function isFocusable2(element) {
1140
1201
  * High-precision focus management utility with full composed tree support.
1141
1202
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
1142
1203
  *
1143
- * @version 4.2.0
1204
+ * @version 4.2.1
1144
1205
  * @author Yusuke Kamiyamane
1145
1206
  * @license MIT
1146
1207
  * @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.4.1
5
+ * @version 1.5.1
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.4.1
5
+ * @version 1.5.1
6
6
  * @author Yusuke Kamiyamane
7
7
  * @license MIT
8
8
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -48,6 +48,62 @@ function saveAttributes(elements, attributes) {
48
48
  });
49
49
  }
50
50
 
51
+ // node_modules/@y14e/button/dist/index.js
52
+ var Button = class {
53
+ #element;
54
+ #controller = null;
55
+ #isDestroyed = false;
56
+ constructor(element) {
57
+ if (!(element instanceof HTMLElement)) {
58
+ throw new TypeError("Invalid element");
59
+ }
60
+ if (element.hasAttribute("data-button-initialized")) {
61
+ console.warn("Already initialized");
62
+ return;
63
+ }
64
+ this.#element = element;
65
+ this.#initialize();
66
+ }
67
+ destroy() {
68
+ if (this.#isDestroyed) {
69
+ return;
70
+ }
71
+ this.#isDestroyed = true;
72
+ this.#controller?.abort();
73
+ this.#controller = null;
74
+ this.#element.removeAttribute("data-button-initialized");
75
+ }
76
+ #initialize() {
77
+ this.#controller = new AbortController();
78
+ this.#element.addEventListener("keydown", this.#onKeyDown, {
79
+ signal: this.#controller.signal
80
+ });
81
+ this.#element.setAttribute("data-button-initialized", "");
82
+ }
83
+ #onKeyDown = (event) => {
84
+ const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
85
+ if (altKey || ctrlKey || metaKey || shiftKey) {
86
+ return;
87
+ }
88
+ if (!["Enter", " "].includes(key)) {
89
+ return;
90
+ }
91
+ const active = getActiveElement();
92
+ if (!(active instanceof HTMLElement)) {
93
+ return;
94
+ }
95
+ event.preventDefault();
96
+ active.click();
97
+ };
98
+ };
99
+ function getActiveElement() {
100
+ let current = document.activeElement;
101
+ while (current?.shadowRoot?.activeElement) {
102
+ current = current.shadowRoot.activeElement;
103
+ }
104
+ return current;
105
+ }
106
+
51
107
  // node_modules/@y14e/roving-tabindex/dist/index.js
52
108
  var defaultParser2 = (value) => value.split(/\s+/);
53
109
  var defaultSerializer2 = (tokens) => tokens.join(" ");
@@ -125,6 +181,10 @@ function getFocusables(container = document.body, options = {}) {
125
181
  );
126
182
  include = void 0;
127
183
  }
184
+ if (typeof skipVisibilityCheck !== "boolean") {
185
+ console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
186
+ skipVisibilityCheck = false;
187
+ }
128
188
  const elements = [];
129
189
  if (composed || include) {
130
190
  let traverse2 = function(node) {
@@ -324,6 +384,7 @@ function createRovingTabIndex(container, options = {}) {
324
384
  direction,
325
385
  navigationOnly = false,
326
386
  selector,
387
+ skipVisibilityCheck = false,
327
388
  typeahead = false,
328
389
  wrap = false
329
390
  } = options;
@@ -341,6 +402,10 @@ function createRovingTabIndex(container, options = {}) {
341
402
  );
342
403
  selector = void 0;
343
404
  }
405
+ if (typeof skipVisibilityCheck !== "boolean") {
406
+ console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
407
+ skipVisibilityCheck = false;
408
+ }
344
409
  if (typeof typeahead !== "boolean") {
345
410
  console.warn("Invalid typeahead option. Fallback: false.");
346
411
  typeahead = false;
@@ -353,6 +418,7 @@ function createRovingTabIndex(container, options = {}) {
353
418
  direction,
354
419
  navigationOnly,
355
420
  selector,
421
+ skipVisibilityCheck,
356
422
  typeahead,
357
423
  wrap
358
424
  });
@@ -414,7 +480,7 @@ var RovingTabIndex = class {
414
480
  return;
415
481
  }
416
482
  }
417
- const active = getActiveElement();
483
+ const active = getActiveElement2();
418
484
  if (!(active instanceof HTMLElement)) {
419
485
  return;
420
486
  }
@@ -466,7 +532,7 @@ var RovingTabIndex = class {
466
532
  ...getFocusables(this.#container, {
467
533
  composed: true,
468
534
  filter: this.#selectorFilter,
469
- skipVisibilityCheck: true
535
+ skipVisibilityCheck: !!this.#options.skipVisibilityCheck
470
536
  })
471
537
  ]);
472
538
  for (const focusable of this.#focusables) {
@@ -533,14 +599,14 @@ var RovingTabIndex = class {
533
599
  composed: true,
534
600
  filter: this.#selectorFilter,
535
601
  include: (element) => this.#focusables.has(element),
536
- skipVisibilityCheck: true
602
+ skipVisibilityCheck: !!this.#options.skipVisibilityCheck
537
603
  });
538
604
  }
539
605
  };
540
606
  function focusElement(element) {
541
607
  "focus" in element && typeof element.focus === "function" && element.focus();
542
608
  }
543
- function getActiveElement() {
609
+ function getActiveElement2() {
544
610
  let current = document.activeElement;
545
611
  while (current?.shadowRoot?.activeElement) {
546
612
  current = current.shadowRoot.activeElement;
@@ -587,6 +653,7 @@ var Tabs = class _Tabs {
587
653
  #animationController = null;
588
654
  #cleanupsRovingTabIndex = [];
589
655
  #animation = null;
656
+ #buttons = [];
590
657
  #indicators = [];
591
658
  #isDestroyed = false;
592
659
  constructor(root, options = {}) {
@@ -789,6 +856,10 @@ var Tabs = class _Tabs {
789
856
  cleanup();
790
857
  });
791
858
  this.#cleanupsRovingTabIndex.length = 0;
859
+ this.#buttons.forEach((button) => {
860
+ button.destroy();
861
+ });
862
+ this.#buttons.length = 0;
792
863
  this.#indicators.forEach((indicator) => {
793
864
  indicator.destroy(force);
794
865
  });
@@ -874,7 +945,7 @@ var Tabs = class _Tabs {
874
945
  addTokenToAttribute(panel, "aria-labelledby", tab.id);
875
946
  tab.addEventListener("click", this.#onTabClick, { signal });
876
947
  tab.addEventListener("focus", this.#onTabFocus, { signal });
877
- tab.addEventListener("keydown", this.#onTabKeyDown, { signal });
948
+ this.#buttons.push(new Button(tab));
878
949
  });
879
950
  saveAttributes(this.#indicatorElements, ["style"]);
880
951
  this.#indicatorElements.forEach((indicator) => {
@@ -896,6 +967,7 @@ var Tabs = class _Tabs {
896
967
  createRovingTabIndex(list, {
897
968
  direction: list.ariaOrientation === "undefined" ? void 0 : this.#settings.vertical ? "vertical" : "horizontal",
898
969
  selector: this.#settings.selector.tab,
970
+ skipVisibilityCheck: true,
899
971
  wrap: true
900
972
  })
901
973
  );
@@ -924,21 +996,6 @@ var Tabs = class _Tabs {
924
996
  !this.#settings.manual && tab.click();
925
997
  this.#isAvoidedTab(tab) && tab.blur();
926
998
  };
927
- #onTabKeyDown = (event) => {
928
- const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
929
- if (altKey || ctrlKey || metaKey || shiftKey) {
930
- return;
931
- }
932
- if (!["Enter", " "].includes(key)) {
933
- return;
934
- }
935
- const active = getActiveElement2();
936
- if (!(active instanceof HTMLElement)) {
937
- return;
938
- }
939
- event.preventDefault();
940
- active.click();
941
- };
942
999
  #onPanelBeforeMatch = (event) => {
943
1000
  const panel = event.currentTarget;
944
1001
  if (!(panel instanceof HTMLElement)) {
@@ -1067,13 +1124,6 @@ var TabsIndicator = class {
1067
1124
  function createBinding(tabs, panel) {
1068
1125
  return { tabs, panel, animation: null };
1069
1126
  }
1070
- function getActiveElement2() {
1071
- let current = document.activeElement;
1072
- while (current?.shadowRoot?.activeElement) {
1073
- current = current.shadowRoot.activeElement;
1074
- }
1075
- return current;
1076
- }
1077
1127
  function hasFocusable(container) {
1078
1128
  return !![
1079
1129
  ...container.querySelectorAll(
@@ -1088,7 +1138,7 @@ function isFocusable2(element) {
1088
1138
  * Tabs
1089
1139
  * WAI-ARIA compliant tabs pattern implementation in TypeScript.
1090
1140
  *
1091
- * @version 1.4.1
1141
+ * @version 1.5.1
1092
1142
  * @author Yusuke Kamiyamane
1093
1143
  * @license MIT
1094
1144
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1107,13 +1157,24 @@ function isFocusable2(element) {
1107
1157
  * @see {@link https://github.com/y14e/attributes-utils}
1108
1158
  *)
1109
1159
 
1160
+ @y14e/button/dist/index.js:
1161
+ (**
1162
+ * Button
1163
+ *
1164
+ * @version 1.0.0
1165
+ * @author Yusuke Kamiyamane
1166
+ * @license MIT
1167
+ * @copyright Copyright (c) Yusuke Kamiyamane
1168
+ * @see {@link https://github.com/y14e/button}
1169
+ *)
1170
+
1110
1171
  @y14e/roving-tabindex/dist/index.js:
1111
1172
  (**
1112
1173
  * Roving Tabindex
1113
1174
  * Lightweight roving tabindex utility with fully focus management.
1114
1175
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
1115
1176
  *
1116
- * @version 1.3.1
1177
+ * @version 1.3.2
1117
1178
  * @author Yusuke Kamiyamane
1118
1179
  * @license MIT
1119
1180
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1138,7 +1199,7 @@ function isFocusable2(element) {
1138
1199
  * High-precision focus management utility with full composed tree support.
1139
1200
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
1140
1201
  *
1141
- * @version 4.2.0
1202
+ * @version 4.2.1
1142
1203
  * @author Yusuke Kamiyamane
1143
1204
  * @license MIT
1144
1205
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/tabs",
3
- "version": "1.4.1",
3
+ "version": "1.5.1",
4
4
  "description": "WAI-ARIA compliant tabs pattern implementation in TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -43,7 +43,8 @@
43
43
  "homepage": "https://github.com/y14e/tabs#readme",
44
44
  "devDependencies": {
45
45
  "@y14e/attributes-utils": "^1.0.5",
46
- "@y14e/roving-tabindex": "^1.3.1",
46
+ "@y14e/button": "^1.0.0",
47
+ "@y14e/roving-tabindex": "^1.3.2",
47
48
  "bun-types": "latest",
48
49
  "tsup": "^8.0.0",
49
50
  "typescript": "^5.6.0",