@y14e/tabs 2.0.3 → 2.0.5
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 +4 -4
- package/dist/index.bundle.cjs +59 -53
- package/dist/index.bundle.js +59 -53
- package/dist/index.cjs +38 -38
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +38 -38
- package/package.json +2 -2
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
|
|
13
|
+
import Tabs from '@y14e/tabs';
|
|
14
14
|
|
|
15
15
|
// CDNs
|
|
16
|
-
import Tabs from 'https://esm.sh/@y14e/tabs@2.0.
|
|
16
|
+
import Tabs from 'https://esm.sh/@y14e/tabs@2.0.5';
|
|
17
17
|
// or
|
|
18
|
-
import Tabs from 'https://cdn.jsdelivr.net/npm/@y14e/tabs@2.0.
|
|
18
|
+
import Tabs from 'https://cdn.jsdelivr.net/npm/@y14e/tabs@2.0.5/+esm';
|
|
19
19
|
// or
|
|
20
|
-
import Tabs from 'https://esm.unpkg.com/@y14e/tabs@2.0.
|
|
20
|
+
import Tabs from 'https://esm.unpkg.com/@y14e/tabs@2.0.5';
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
## Usage
|
package/dist/index.bundle.cjs
CHANGED
|
@@ -343,8 +343,14 @@ function createRovingTabIndex(container, options = {}) {
|
|
|
343
343
|
return () => {
|
|
344
344
|
};
|
|
345
345
|
}
|
|
346
|
-
|
|
347
|
-
|
|
346
|
+
try {
|
|
347
|
+
const roving = new RovingTabIndex(container, options);
|
|
348
|
+
return () => roving.destroy();
|
|
349
|
+
} catch (error) {
|
|
350
|
+
error instanceof Error && console.warn(error.message || error);
|
|
351
|
+
return () => {
|
|
352
|
+
};
|
|
353
|
+
}
|
|
348
354
|
}
|
|
349
355
|
var RovingTabIndex = class _RovingTabIndex {
|
|
350
356
|
static #initialized = /* @__PURE__ */ new Set();
|
|
@@ -420,28 +426,28 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
420
426
|
this.#focusablesByFirstChar.clear();
|
|
421
427
|
}
|
|
422
428
|
#initialize() {
|
|
423
|
-
this.#update(
|
|
429
|
+
this.#update(getActiveElement());
|
|
424
430
|
if (!(this.#container instanceof HTMLElement)) {
|
|
425
431
|
return;
|
|
426
432
|
}
|
|
427
433
|
this.#controller = new AbortController();
|
|
428
434
|
const { signal } = this.#controller;
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
});
|
|
433
|
-
this.#container.addEventListener("keydown", this.#onKeyDown, {
|
|
434
|
-
capture: true,
|
|
435
|
-
signal
|
|
436
|
-
});
|
|
435
|
+
document.addEventListener("focusin", this.#onFocusIn, { signal });
|
|
436
|
+
this.#settings.noMemory && document.addEventListener("focusout", this.#onFocusOut, { signal });
|
|
437
|
+
this.#container.addEventListener("keydown", this.#onKeyDown, { signal });
|
|
437
438
|
}
|
|
438
439
|
#onFocusIn = (event) => {
|
|
439
440
|
const { target } = event;
|
|
440
441
|
if (!(target instanceof Element)) {
|
|
441
442
|
return;
|
|
442
443
|
}
|
|
443
|
-
const
|
|
444
|
-
this.#settings.noMemory && !
|
|
444
|
+
const isFocusable2 = this.#focusables.has(target);
|
|
445
|
+
this.#settings.noMemory && !isFocusable2 ? this.#update() : isFocusable2 && this.#update(target);
|
|
446
|
+
};
|
|
447
|
+
#onFocusOut = (event) => {
|
|
448
|
+
if (!event.relatedTarget) {
|
|
449
|
+
this.#update();
|
|
450
|
+
}
|
|
445
451
|
};
|
|
446
452
|
#onKeyDown = (event) => {
|
|
447
453
|
const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
|
|
@@ -684,7 +690,7 @@ var Tabs = class _Tabs {
|
|
|
684
690
|
if (!panel) {
|
|
685
691
|
return;
|
|
686
692
|
}
|
|
687
|
-
const binding = createBinding(tabsByIndex, panel);
|
|
693
|
+
const binding = this.#createBinding(tabsByIndex, panel);
|
|
688
694
|
this.#bindings.set(tab, binding);
|
|
689
695
|
i < length && this.#bindings.set(panel, binding);
|
|
690
696
|
});
|
|
@@ -731,14 +737,14 @@ var Tabs = class _Tabs {
|
|
|
731
737
|
}
|
|
732
738
|
style2.setProperty("inline-size", "100%");
|
|
733
739
|
style2.setProperty("position", "absolute");
|
|
734
|
-
p === panel && !hasFocusable(p) ? p.setAttribute("tabindex", "0") : p.removeAttribute("tabindex");
|
|
740
|
+
p === panel && !this.#hasFocusable(p) ? p.setAttribute("tabindex", "0") : p.removeAttribute("tabindex");
|
|
735
741
|
});
|
|
736
742
|
this.#panelElements.forEach((p, i) => {
|
|
737
743
|
if (p === panel) {
|
|
738
744
|
p.removeAttribute("hidden");
|
|
739
745
|
} else {
|
|
740
746
|
const tab2 = this.#tabElements[i];
|
|
741
|
-
tab2 && p.setAttribute("hidden",
|
|
747
|
+
tab2 && p.setAttribute("hidden", this.#isFocusable(tab2) ? "until-found" : "");
|
|
742
748
|
}
|
|
743
749
|
});
|
|
744
750
|
this.#animation?.cancel();
|
|
@@ -771,7 +777,7 @@ var Tabs = class _Tabs {
|
|
|
771
777
|
"finish",
|
|
772
778
|
() => {
|
|
773
779
|
if (this.#animation === animation) {
|
|
774
|
-
this.#
|
|
780
|
+
this.#onContentAnimationFinish();
|
|
775
781
|
cleanup();
|
|
776
782
|
}
|
|
777
783
|
},
|
|
@@ -848,7 +854,7 @@ var Tabs = class _Tabs {
|
|
|
848
854
|
this.#panelElements.forEach((panel) => {
|
|
849
855
|
this.#bindings.get(panel)?.animation?.cancel();
|
|
850
856
|
});
|
|
851
|
-
this.#
|
|
857
|
+
this.#onContentAnimationFinish();
|
|
852
858
|
this.#animationController?.abort();
|
|
853
859
|
this.#animationController = null;
|
|
854
860
|
restoreAttributes([
|
|
@@ -906,7 +912,7 @@ var Tabs = class _Tabs {
|
|
|
906
912
|
tab.id ||= `tabs-tab-${id}`;
|
|
907
913
|
}
|
|
908
914
|
tab.setAttribute("role", "tab");
|
|
909
|
-
!
|
|
915
|
+
!this.#isFocusable(tab) && tab.style.setProperty("pointer-events", "none");
|
|
910
916
|
addTokenToAttribute(panel, "aria-labelledby", tab.id);
|
|
911
917
|
tab.addEventListener("click", this.#onTabClick, { signal });
|
|
912
918
|
tab.addEventListener("focus", this.#onTabFocus, { signal });
|
|
@@ -921,7 +927,7 @@ var Tabs = class _Tabs {
|
|
|
921
927
|
});
|
|
922
928
|
this.#panelElements.forEach((panel) => {
|
|
923
929
|
panel.setAttribute("role", "tabpanel");
|
|
924
|
-
!panel.hasAttribute("hidden") && !hasFocusable(panel) && panel.setAttribute("tabindex", "0");
|
|
930
|
+
!panel.hasAttribute("hidden") && !this.#hasFocusable(panel) && panel.setAttribute("tabindex", "0");
|
|
925
931
|
panel.addEventListener("beforematch", this.#onPanelBeforeMatch, {
|
|
926
932
|
signal
|
|
927
933
|
});
|
|
@@ -957,6 +963,23 @@ var Tabs = class _Tabs {
|
|
|
957
963
|
!this.#settings.manual && tab.click();
|
|
958
964
|
this.#isAvoidedTab(tab) && tab.blur();
|
|
959
965
|
};
|
|
966
|
+
#onContentAnimationFinish() {
|
|
967
|
+
["block-size", "overflow", "position"].forEach((name) => {
|
|
968
|
+
this.#contentElement?.style.removeProperty(name);
|
|
969
|
+
});
|
|
970
|
+
this.#panelElements.forEach((panel) => {
|
|
971
|
+
[
|
|
972
|
+
"content-visibility",
|
|
973
|
+
"display",
|
|
974
|
+
"inline-size",
|
|
975
|
+
"opacity",
|
|
976
|
+
"position"
|
|
977
|
+
].forEach((name) => {
|
|
978
|
+
panel.style.removeProperty(name);
|
|
979
|
+
});
|
|
980
|
+
});
|
|
981
|
+
this.#rootElement.removeAttribute("data-tabs-animating");
|
|
982
|
+
}
|
|
960
983
|
#onPanelBeforeMatch = (event) => {
|
|
961
984
|
const panel = event.currentTarget;
|
|
962
985
|
if (!(panel instanceof HTMLElement)) {
|
|
@@ -965,6 +988,16 @@ var Tabs = class _Tabs {
|
|
|
965
988
|
const tab = this.#bindings.get(panel)?.tabs[0];
|
|
966
989
|
tab && this.activate(tab, true);
|
|
967
990
|
};
|
|
991
|
+
#createBinding(tabs, panel) {
|
|
992
|
+
return { tabs, panel, animation: null };
|
|
993
|
+
}
|
|
994
|
+
#hasFocusable(container) {
|
|
995
|
+
return !![
|
|
996
|
+
...container.querySelectorAll(
|
|
997
|
+
`:is(a[href], area[href], button, embed, iframe, input:not([type="hidden" i]), object, select, details > summary:first-of-type, textarea, [contenteditable]:not([contenteditable="false" i]), [controls], [tabindex]):not(:disabled, [hidden], [inert], [tabindex="-1"])`
|
|
998
|
+
)
|
|
999
|
+
].filter((element) => element.checkVisibility()).length;
|
|
1000
|
+
}
|
|
968
1001
|
#isAvoidedTab(tab) {
|
|
969
1002
|
const binding = this.#bindings.get(tab);
|
|
970
1003
|
if (!binding) {
|
|
@@ -972,6 +1005,9 @@ var Tabs = class _Tabs {
|
|
|
972
1005
|
}
|
|
973
1006
|
return this.#settings.avoidDuplicates && binding.tabs.indexOf(tab) > 0;
|
|
974
1007
|
}
|
|
1008
|
+
#isFocusable(element) {
|
|
1009
|
+
return !element.hasAttribute("disabled");
|
|
1010
|
+
}
|
|
975
1011
|
#mergeOptions(target, source) {
|
|
976
1012
|
return {
|
|
977
1013
|
...target,
|
|
@@ -992,23 +1028,6 @@ var Tabs = class _Tabs {
|
|
|
992
1028
|
}
|
|
993
1029
|
};
|
|
994
1030
|
}
|
|
995
|
-
#onAnimationFinish() {
|
|
996
|
-
["block-size", "overflow", "position"].forEach((name) => {
|
|
997
|
-
this.#contentElement?.style.removeProperty(name);
|
|
998
|
-
});
|
|
999
|
-
this.#panelElements.forEach((panel) => {
|
|
1000
|
-
[
|
|
1001
|
-
"content-visibility",
|
|
1002
|
-
"display",
|
|
1003
|
-
"inline-size",
|
|
1004
|
-
"opacity",
|
|
1005
|
-
"position"
|
|
1006
|
-
].forEach((name) => {
|
|
1007
|
-
panel.style.removeProperty(name);
|
|
1008
|
-
});
|
|
1009
|
-
});
|
|
1010
|
-
this.#rootElement.removeAttribute("data-tabs-animating");
|
|
1011
|
-
}
|
|
1012
1031
|
};
|
|
1013
1032
|
var TabsIndicator = class {
|
|
1014
1033
|
#rootElement;
|
|
@@ -1078,24 +1097,11 @@ var TabsIndicator = class {
|
|
|
1078
1097
|
this.#listElement = null;
|
|
1079
1098
|
}
|
|
1080
1099
|
};
|
|
1081
|
-
function createBinding(tabs, panel) {
|
|
1082
|
-
return { tabs, panel, animation: null };
|
|
1083
|
-
}
|
|
1084
|
-
function hasFocusable(container) {
|
|
1085
|
-
return !![
|
|
1086
|
-
...container.querySelectorAll(
|
|
1087
|
-
`:is(a[href], area[href], button, embed, iframe, input:not([type="hidden" i]), object, select, details > summary:first-of-type, textarea, [contenteditable]:not([contenteditable="false" i]), [controls], [tabindex]):not(:disabled, [hidden], [inert], [tabindex="-1"])`
|
|
1088
|
-
)
|
|
1089
|
-
].filter((element) => element.checkVisibility()).length;
|
|
1090
|
-
}
|
|
1091
|
-
function isFocusable2(element) {
|
|
1092
|
-
return !element.hasAttribute("disabled");
|
|
1093
|
-
}
|
|
1094
1100
|
/**
|
|
1095
1101
|
* Tabs
|
|
1096
1102
|
* WAI-ARIA compliant tabs pattern implementation in TypeScript.
|
|
1097
1103
|
*
|
|
1098
|
-
* @version 2.0.
|
|
1104
|
+
* @version 2.0.5
|
|
1099
1105
|
* @author Yusuke Kamiyamane
|
|
1100
1106
|
* @license MIT
|
|
1101
1107
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -1120,7 +1126,7 @@ power-focusable/dist/index.js:
|
|
|
1120
1126
|
* High-precision focus management utility with full composed tree support.
|
|
1121
1127
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
1122
1128
|
*
|
|
1123
|
-
* @version 4.3.
|
|
1129
|
+
* @version 4.3.5
|
|
1124
1130
|
* @author Yusuke Kamiyamane
|
|
1125
1131
|
* @license MIT
|
|
1126
1132
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -1144,7 +1150,7 @@ power-focusable/dist/index.js:
|
|
|
1144
1150
|
* Lightweight roving tabindex utility with fully focus management.
|
|
1145
1151
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
1146
1152
|
*
|
|
1147
|
-
* @version 3.
|
|
1153
|
+
* @version 3.1.2
|
|
1148
1154
|
* @author Yusuke Kamiyamane
|
|
1149
1155
|
* @license MIT
|
|
1150
1156
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.bundle.js
CHANGED
|
@@ -341,8 +341,14 @@ function createRovingTabIndex(container, options = {}) {
|
|
|
341
341
|
return () => {
|
|
342
342
|
};
|
|
343
343
|
}
|
|
344
|
-
|
|
345
|
-
|
|
344
|
+
try {
|
|
345
|
+
const roving = new RovingTabIndex(container, options);
|
|
346
|
+
return () => roving.destroy();
|
|
347
|
+
} catch (error) {
|
|
348
|
+
error instanceof Error && console.warn(error.message || error);
|
|
349
|
+
return () => {
|
|
350
|
+
};
|
|
351
|
+
}
|
|
346
352
|
}
|
|
347
353
|
var RovingTabIndex = class _RovingTabIndex {
|
|
348
354
|
static #initialized = /* @__PURE__ */ new Set();
|
|
@@ -418,28 +424,28 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
418
424
|
this.#focusablesByFirstChar.clear();
|
|
419
425
|
}
|
|
420
426
|
#initialize() {
|
|
421
|
-
this.#update(
|
|
427
|
+
this.#update(getActiveElement());
|
|
422
428
|
if (!(this.#container instanceof HTMLElement)) {
|
|
423
429
|
return;
|
|
424
430
|
}
|
|
425
431
|
this.#controller = new AbortController();
|
|
426
432
|
const { signal } = this.#controller;
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
});
|
|
431
|
-
this.#container.addEventListener("keydown", this.#onKeyDown, {
|
|
432
|
-
capture: true,
|
|
433
|
-
signal
|
|
434
|
-
});
|
|
433
|
+
document.addEventListener("focusin", this.#onFocusIn, { signal });
|
|
434
|
+
this.#settings.noMemory && document.addEventListener("focusout", this.#onFocusOut, { signal });
|
|
435
|
+
this.#container.addEventListener("keydown", this.#onKeyDown, { signal });
|
|
435
436
|
}
|
|
436
437
|
#onFocusIn = (event) => {
|
|
437
438
|
const { target } = event;
|
|
438
439
|
if (!(target instanceof Element)) {
|
|
439
440
|
return;
|
|
440
441
|
}
|
|
441
|
-
const
|
|
442
|
-
this.#settings.noMemory && !
|
|
442
|
+
const isFocusable2 = this.#focusables.has(target);
|
|
443
|
+
this.#settings.noMemory && !isFocusable2 ? this.#update() : isFocusable2 && this.#update(target);
|
|
444
|
+
};
|
|
445
|
+
#onFocusOut = (event) => {
|
|
446
|
+
if (!event.relatedTarget) {
|
|
447
|
+
this.#update();
|
|
448
|
+
}
|
|
443
449
|
};
|
|
444
450
|
#onKeyDown = (event) => {
|
|
445
451
|
const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
|
|
@@ -682,7 +688,7 @@ var Tabs = class _Tabs {
|
|
|
682
688
|
if (!panel) {
|
|
683
689
|
return;
|
|
684
690
|
}
|
|
685
|
-
const binding = createBinding(tabsByIndex, panel);
|
|
691
|
+
const binding = this.#createBinding(tabsByIndex, panel);
|
|
686
692
|
this.#bindings.set(tab, binding);
|
|
687
693
|
i < length && this.#bindings.set(panel, binding);
|
|
688
694
|
});
|
|
@@ -729,14 +735,14 @@ var Tabs = class _Tabs {
|
|
|
729
735
|
}
|
|
730
736
|
style2.setProperty("inline-size", "100%");
|
|
731
737
|
style2.setProperty("position", "absolute");
|
|
732
|
-
p === panel && !hasFocusable(p) ? p.setAttribute("tabindex", "0") : p.removeAttribute("tabindex");
|
|
738
|
+
p === panel && !this.#hasFocusable(p) ? p.setAttribute("tabindex", "0") : p.removeAttribute("tabindex");
|
|
733
739
|
});
|
|
734
740
|
this.#panelElements.forEach((p, i) => {
|
|
735
741
|
if (p === panel) {
|
|
736
742
|
p.removeAttribute("hidden");
|
|
737
743
|
} else {
|
|
738
744
|
const tab2 = this.#tabElements[i];
|
|
739
|
-
tab2 && p.setAttribute("hidden",
|
|
745
|
+
tab2 && p.setAttribute("hidden", this.#isFocusable(tab2) ? "until-found" : "");
|
|
740
746
|
}
|
|
741
747
|
});
|
|
742
748
|
this.#animation?.cancel();
|
|
@@ -769,7 +775,7 @@ var Tabs = class _Tabs {
|
|
|
769
775
|
"finish",
|
|
770
776
|
() => {
|
|
771
777
|
if (this.#animation === animation) {
|
|
772
|
-
this.#
|
|
778
|
+
this.#onContentAnimationFinish();
|
|
773
779
|
cleanup();
|
|
774
780
|
}
|
|
775
781
|
},
|
|
@@ -846,7 +852,7 @@ var Tabs = class _Tabs {
|
|
|
846
852
|
this.#panelElements.forEach((panel) => {
|
|
847
853
|
this.#bindings.get(panel)?.animation?.cancel();
|
|
848
854
|
});
|
|
849
|
-
this.#
|
|
855
|
+
this.#onContentAnimationFinish();
|
|
850
856
|
this.#animationController?.abort();
|
|
851
857
|
this.#animationController = null;
|
|
852
858
|
restoreAttributes([
|
|
@@ -904,7 +910,7 @@ var Tabs = class _Tabs {
|
|
|
904
910
|
tab.id ||= `tabs-tab-${id}`;
|
|
905
911
|
}
|
|
906
912
|
tab.setAttribute("role", "tab");
|
|
907
|
-
!
|
|
913
|
+
!this.#isFocusable(tab) && tab.style.setProperty("pointer-events", "none");
|
|
908
914
|
addTokenToAttribute(panel, "aria-labelledby", tab.id);
|
|
909
915
|
tab.addEventListener("click", this.#onTabClick, { signal });
|
|
910
916
|
tab.addEventListener("focus", this.#onTabFocus, { signal });
|
|
@@ -919,7 +925,7 @@ var Tabs = class _Tabs {
|
|
|
919
925
|
});
|
|
920
926
|
this.#panelElements.forEach((panel) => {
|
|
921
927
|
panel.setAttribute("role", "tabpanel");
|
|
922
|
-
!panel.hasAttribute("hidden") && !hasFocusable(panel) && panel.setAttribute("tabindex", "0");
|
|
928
|
+
!panel.hasAttribute("hidden") && !this.#hasFocusable(panel) && panel.setAttribute("tabindex", "0");
|
|
923
929
|
panel.addEventListener("beforematch", this.#onPanelBeforeMatch, {
|
|
924
930
|
signal
|
|
925
931
|
});
|
|
@@ -955,6 +961,23 @@ var Tabs = class _Tabs {
|
|
|
955
961
|
!this.#settings.manual && tab.click();
|
|
956
962
|
this.#isAvoidedTab(tab) && tab.blur();
|
|
957
963
|
};
|
|
964
|
+
#onContentAnimationFinish() {
|
|
965
|
+
["block-size", "overflow", "position"].forEach((name) => {
|
|
966
|
+
this.#contentElement?.style.removeProperty(name);
|
|
967
|
+
});
|
|
968
|
+
this.#panelElements.forEach((panel) => {
|
|
969
|
+
[
|
|
970
|
+
"content-visibility",
|
|
971
|
+
"display",
|
|
972
|
+
"inline-size",
|
|
973
|
+
"opacity",
|
|
974
|
+
"position"
|
|
975
|
+
].forEach((name) => {
|
|
976
|
+
panel.style.removeProperty(name);
|
|
977
|
+
});
|
|
978
|
+
});
|
|
979
|
+
this.#rootElement.removeAttribute("data-tabs-animating");
|
|
980
|
+
}
|
|
958
981
|
#onPanelBeforeMatch = (event) => {
|
|
959
982
|
const panel = event.currentTarget;
|
|
960
983
|
if (!(panel instanceof HTMLElement)) {
|
|
@@ -963,6 +986,16 @@ var Tabs = class _Tabs {
|
|
|
963
986
|
const tab = this.#bindings.get(panel)?.tabs[0];
|
|
964
987
|
tab && this.activate(tab, true);
|
|
965
988
|
};
|
|
989
|
+
#createBinding(tabs, panel) {
|
|
990
|
+
return { tabs, panel, animation: null };
|
|
991
|
+
}
|
|
992
|
+
#hasFocusable(container) {
|
|
993
|
+
return !![
|
|
994
|
+
...container.querySelectorAll(
|
|
995
|
+
`:is(a[href], area[href], button, embed, iframe, input:not([type="hidden" i]), object, select, details > summary:first-of-type, textarea, [contenteditable]:not([contenteditable="false" i]), [controls], [tabindex]):not(:disabled, [hidden], [inert], [tabindex="-1"])`
|
|
996
|
+
)
|
|
997
|
+
].filter((element) => element.checkVisibility()).length;
|
|
998
|
+
}
|
|
966
999
|
#isAvoidedTab(tab) {
|
|
967
1000
|
const binding = this.#bindings.get(tab);
|
|
968
1001
|
if (!binding) {
|
|
@@ -970,6 +1003,9 @@ var Tabs = class _Tabs {
|
|
|
970
1003
|
}
|
|
971
1004
|
return this.#settings.avoidDuplicates && binding.tabs.indexOf(tab) > 0;
|
|
972
1005
|
}
|
|
1006
|
+
#isFocusable(element) {
|
|
1007
|
+
return !element.hasAttribute("disabled");
|
|
1008
|
+
}
|
|
973
1009
|
#mergeOptions(target, source) {
|
|
974
1010
|
return {
|
|
975
1011
|
...target,
|
|
@@ -990,23 +1026,6 @@ var Tabs = class _Tabs {
|
|
|
990
1026
|
}
|
|
991
1027
|
};
|
|
992
1028
|
}
|
|
993
|
-
#onAnimationFinish() {
|
|
994
|
-
["block-size", "overflow", "position"].forEach((name) => {
|
|
995
|
-
this.#contentElement?.style.removeProperty(name);
|
|
996
|
-
});
|
|
997
|
-
this.#panelElements.forEach((panel) => {
|
|
998
|
-
[
|
|
999
|
-
"content-visibility",
|
|
1000
|
-
"display",
|
|
1001
|
-
"inline-size",
|
|
1002
|
-
"opacity",
|
|
1003
|
-
"position"
|
|
1004
|
-
].forEach((name) => {
|
|
1005
|
-
panel.style.removeProperty(name);
|
|
1006
|
-
});
|
|
1007
|
-
});
|
|
1008
|
-
this.#rootElement.removeAttribute("data-tabs-animating");
|
|
1009
|
-
}
|
|
1010
1029
|
};
|
|
1011
1030
|
var TabsIndicator = class {
|
|
1012
1031
|
#rootElement;
|
|
@@ -1076,24 +1095,11 @@ var TabsIndicator = class {
|
|
|
1076
1095
|
this.#listElement = null;
|
|
1077
1096
|
}
|
|
1078
1097
|
};
|
|
1079
|
-
function createBinding(tabs, panel) {
|
|
1080
|
-
return { tabs, panel, animation: null };
|
|
1081
|
-
}
|
|
1082
|
-
function hasFocusable(container) {
|
|
1083
|
-
return !![
|
|
1084
|
-
...container.querySelectorAll(
|
|
1085
|
-
`:is(a[href], area[href], button, embed, iframe, input:not([type="hidden" i]), object, select, details > summary:first-of-type, textarea, [contenteditable]:not([contenteditable="false" i]), [controls], [tabindex]):not(:disabled, [hidden], [inert], [tabindex="-1"])`
|
|
1086
|
-
)
|
|
1087
|
-
].filter((element) => element.checkVisibility()).length;
|
|
1088
|
-
}
|
|
1089
|
-
function isFocusable2(element) {
|
|
1090
|
-
return !element.hasAttribute("disabled");
|
|
1091
|
-
}
|
|
1092
1098
|
/**
|
|
1093
1099
|
* Tabs
|
|
1094
1100
|
* WAI-ARIA compliant tabs pattern implementation in TypeScript.
|
|
1095
1101
|
*
|
|
1096
|
-
* @version 2.0.
|
|
1102
|
+
* @version 2.0.5
|
|
1097
1103
|
* @author Yusuke Kamiyamane
|
|
1098
1104
|
* @license MIT
|
|
1099
1105
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -1118,7 +1124,7 @@ power-focusable/dist/index.js:
|
|
|
1118
1124
|
* High-precision focus management utility with full composed tree support.
|
|
1119
1125
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
1120
1126
|
*
|
|
1121
|
-
* @version 4.3.
|
|
1127
|
+
* @version 4.3.5
|
|
1122
1128
|
* @author Yusuke Kamiyamane
|
|
1123
1129
|
* @license MIT
|
|
1124
1130
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -1142,7 +1148,7 @@ power-focusable/dist/index.js:
|
|
|
1142
1148
|
* Lightweight roving tabindex utility with fully focus management.
|
|
1143
1149
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
1144
1150
|
*
|
|
1145
|
-
* @version 3.
|
|
1151
|
+
* @version 3.1.2
|
|
1146
1152
|
* @author Yusuke Kamiyamane
|
|
1147
1153
|
* @license MIT
|
|
1148
1154
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.cjs
CHANGED
|
@@ -116,7 +116,7 @@ var Tabs = class _Tabs {
|
|
|
116
116
|
if (!panel) {
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
119
|
-
const binding = createBinding(tabsByIndex, panel);
|
|
119
|
+
const binding = this.#createBinding(tabsByIndex, panel);
|
|
120
120
|
this.#bindings.set(tab, binding);
|
|
121
121
|
i < length && this.#bindings.set(panel, binding);
|
|
122
122
|
});
|
|
@@ -163,14 +163,14 @@ var Tabs = class _Tabs {
|
|
|
163
163
|
}
|
|
164
164
|
style2.setProperty("inline-size", "100%");
|
|
165
165
|
style2.setProperty("position", "absolute");
|
|
166
|
-
p === panel && !hasFocusable(p) ? p.setAttribute("tabindex", "0") : p.removeAttribute("tabindex");
|
|
166
|
+
p === panel && !this.#hasFocusable(p) ? p.setAttribute("tabindex", "0") : p.removeAttribute("tabindex");
|
|
167
167
|
});
|
|
168
168
|
this.#panelElements.forEach((p, i) => {
|
|
169
169
|
if (p === panel) {
|
|
170
170
|
p.removeAttribute("hidden");
|
|
171
171
|
} else {
|
|
172
172
|
const tab2 = this.#tabElements[i];
|
|
173
|
-
tab2 && p.setAttribute("hidden", isFocusable(tab2) ? "until-found" : "");
|
|
173
|
+
tab2 && p.setAttribute("hidden", this.#isFocusable(tab2) ? "until-found" : "");
|
|
174
174
|
}
|
|
175
175
|
});
|
|
176
176
|
this.#animation?.cancel();
|
|
@@ -203,7 +203,7 @@ var Tabs = class _Tabs {
|
|
|
203
203
|
"finish",
|
|
204
204
|
() => {
|
|
205
205
|
if (this.#animation === animation) {
|
|
206
|
-
this.#
|
|
206
|
+
this.#onContentAnimationFinish();
|
|
207
207
|
cleanup();
|
|
208
208
|
}
|
|
209
209
|
},
|
|
@@ -280,7 +280,7 @@ var Tabs = class _Tabs {
|
|
|
280
280
|
this.#panelElements.forEach((panel) => {
|
|
281
281
|
this.#bindings.get(panel)?.animation?.cancel();
|
|
282
282
|
});
|
|
283
|
-
this.#
|
|
283
|
+
this.#onContentAnimationFinish();
|
|
284
284
|
this.#animationController?.abort();
|
|
285
285
|
this.#animationController = null;
|
|
286
286
|
attributesUtils.restoreAttributes([
|
|
@@ -338,7 +338,7 @@ var Tabs = class _Tabs {
|
|
|
338
338
|
tab.id ||= `tabs-tab-${id}`;
|
|
339
339
|
}
|
|
340
340
|
tab.setAttribute("role", "tab");
|
|
341
|
-
!isFocusable(tab) && tab.style.setProperty("pointer-events", "none");
|
|
341
|
+
!this.#isFocusable(tab) && tab.style.setProperty("pointer-events", "none");
|
|
342
342
|
attributesUtils.addTokenToAttribute(panel, "aria-labelledby", tab.id);
|
|
343
343
|
tab.addEventListener("click", this.#onTabClick, { signal });
|
|
344
344
|
tab.addEventListener("focus", this.#onTabFocus, { signal });
|
|
@@ -353,7 +353,7 @@ var Tabs = class _Tabs {
|
|
|
353
353
|
});
|
|
354
354
|
this.#panelElements.forEach((panel) => {
|
|
355
355
|
panel.setAttribute("role", "tabpanel");
|
|
356
|
-
!panel.hasAttribute("hidden") && !hasFocusable(panel) && panel.setAttribute("tabindex", "0");
|
|
356
|
+
!panel.hasAttribute("hidden") && !this.#hasFocusable(panel) && panel.setAttribute("tabindex", "0");
|
|
357
357
|
panel.addEventListener("beforematch", this.#onPanelBeforeMatch, {
|
|
358
358
|
signal
|
|
359
359
|
});
|
|
@@ -389,6 +389,23 @@ var Tabs = class _Tabs {
|
|
|
389
389
|
!this.#settings.manual && tab.click();
|
|
390
390
|
this.#isAvoidedTab(tab) && tab.blur();
|
|
391
391
|
};
|
|
392
|
+
#onContentAnimationFinish() {
|
|
393
|
+
["block-size", "overflow", "position"].forEach((name) => {
|
|
394
|
+
this.#contentElement?.style.removeProperty(name);
|
|
395
|
+
});
|
|
396
|
+
this.#panelElements.forEach((panel) => {
|
|
397
|
+
[
|
|
398
|
+
"content-visibility",
|
|
399
|
+
"display",
|
|
400
|
+
"inline-size",
|
|
401
|
+
"opacity",
|
|
402
|
+
"position"
|
|
403
|
+
].forEach((name) => {
|
|
404
|
+
panel.style.removeProperty(name);
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
this.#rootElement.removeAttribute("data-tabs-animating");
|
|
408
|
+
}
|
|
392
409
|
#onPanelBeforeMatch = (event) => {
|
|
393
410
|
const panel = event.currentTarget;
|
|
394
411
|
if (!(panel instanceof HTMLElement)) {
|
|
@@ -397,6 +414,16 @@ var Tabs = class _Tabs {
|
|
|
397
414
|
const tab = this.#bindings.get(panel)?.tabs[0];
|
|
398
415
|
tab && this.activate(tab, true);
|
|
399
416
|
};
|
|
417
|
+
#createBinding(tabs, panel) {
|
|
418
|
+
return { tabs, panel, animation: null };
|
|
419
|
+
}
|
|
420
|
+
#hasFocusable(container) {
|
|
421
|
+
return !![
|
|
422
|
+
...container.querySelectorAll(
|
|
423
|
+
`:is(a[href], area[href], button, embed, iframe, input:not([type="hidden" i]), object, select, details > summary:first-of-type, textarea, [contenteditable]:not([contenteditable="false" i]), [controls], [tabindex]):not(:disabled, [hidden], [inert], [tabindex="-1"])`
|
|
424
|
+
)
|
|
425
|
+
].filter((element) => element.checkVisibility()).length;
|
|
426
|
+
}
|
|
400
427
|
#isAvoidedTab(tab) {
|
|
401
428
|
const binding = this.#bindings.get(tab);
|
|
402
429
|
if (!binding) {
|
|
@@ -404,6 +431,9 @@ var Tabs = class _Tabs {
|
|
|
404
431
|
}
|
|
405
432
|
return this.#settings.avoidDuplicates && binding.tabs.indexOf(tab) > 0;
|
|
406
433
|
}
|
|
434
|
+
#isFocusable(element) {
|
|
435
|
+
return !element.hasAttribute("disabled");
|
|
436
|
+
}
|
|
407
437
|
#mergeOptions(target, source) {
|
|
408
438
|
return {
|
|
409
439
|
...target,
|
|
@@ -424,23 +454,6 @@ var Tabs = class _Tabs {
|
|
|
424
454
|
}
|
|
425
455
|
};
|
|
426
456
|
}
|
|
427
|
-
#onAnimationFinish() {
|
|
428
|
-
["block-size", "overflow", "position"].forEach((name) => {
|
|
429
|
-
this.#contentElement?.style.removeProperty(name);
|
|
430
|
-
});
|
|
431
|
-
this.#panelElements.forEach((panel) => {
|
|
432
|
-
[
|
|
433
|
-
"content-visibility",
|
|
434
|
-
"display",
|
|
435
|
-
"inline-size",
|
|
436
|
-
"opacity",
|
|
437
|
-
"position"
|
|
438
|
-
].forEach((name) => {
|
|
439
|
-
panel.style.removeProperty(name);
|
|
440
|
-
});
|
|
441
|
-
});
|
|
442
|
-
this.#rootElement.removeAttribute("data-tabs-animating");
|
|
443
|
-
}
|
|
444
457
|
};
|
|
445
458
|
var TabsIndicator = class {
|
|
446
459
|
#rootElement;
|
|
@@ -510,24 +523,11 @@ var TabsIndicator = class {
|
|
|
510
523
|
this.#listElement = null;
|
|
511
524
|
}
|
|
512
525
|
};
|
|
513
|
-
function createBinding(tabs, panel) {
|
|
514
|
-
return { tabs, panel, animation: null };
|
|
515
|
-
}
|
|
516
|
-
function hasFocusable(container) {
|
|
517
|
-
return !![
|
|
518
|
-
...container.querySelectorAll(
|
|
519
|
-
`:is(a[href], area[href], button, embed, iframe, input:not([type="hidden" i]), object, select, details > summary:first-of-type, textarea, [contenteditable]:not([contenteditable="false" i]), [controls], [tabindex]):not(:disabled, [hidden], [inert], [tabindex="-1"])`
|
|
520
|
-
)
|
|
521
|
-
].filter((element) => element.checkVisibility()).length;
|
|
522
|
-
}
|
|
523
|
-
function isFocusable(element) {
|
|
524
|
-
return !element.hasAttribute("disabled");
|
|
525
|
-
}
|
|
526
526
|
/**
|
|
527
527
|
* Tabs
|
|
528
528
|
* WAI-ARIA compliant tabs pattern implementation in TypeScript.
|
|
529
529
|
*
|
|
530
|
-
* @version 2.0.
|
|
530
|
+
* @version 2.0.5
|
|
531
531
|
* @author Yusuke Kamiyamane
|
|
532
532
|
* @license MIT
|
|
533
533
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -110,7 +110,7 @@ var Tabs = class _Tabs {
|
|
|
110
110
|
if (!panel) {
|
|
111
111
|
return;
|
|
112
112
|
}
|
|
113
|
-
const binding = createBinding(tabsByIndex, panel);
|
|
113
|
+
const binding = this.#createBinding(tabsByIndex, panel);
|
|
114
114
|
this.#bindings.set(tab, binding);
|
|
115
115
|
i < length && this.#bindings.set(panel, binding);
|
|
116
116
|
});
|
|
@@ -157,14 +157,14 @@ var Tabs = class _Tabs {
|
|
|
157
157
|
}
|
|
158
158
|
style2.setProperty("inline-size", "100%");
|
|
159
159
|
style2.setProperty("position", "absolute");
|
|
160
|
-
p === panel && !hasFocusable(p) ? p.setAttribute("tabindex", "0") : p.removeAttribute("tabindex");
|
|
160
|
+
p === panel && !this.#hasFocusable(p) ? p.setAttribute("tabindex", "0") : p.removeAttribute("tabindex");
|
|
161
161
|
});
|
|
162
162
|
this.#panelElements.forEach((p, i) => {
|
|
163
163
|
if (p === panel) {
|
|
164
164
|
p.removeAttribute("hidden");
|
|
165
165
|
} else {
|
|
166
166
|
const tab2 = this.#tabElements[i];
|
|
167
|
-
tab2 && p.setAttribute("hidden", isFocusable(tab2) ? "until-found" : "");
|
|
167
|
+
tab2 && p.setAttribute("hidden", this.#isFocusable(tab2) ? "until-found" : "");
|
|
168
168
|
}
|
|
169
169
|
});
|
|
170
170
|
this.#animation?.cancel();
|
|
@@ -197,7 +197,7 @@ var Tabs = class _Tabs {
|
|
|
197
197
|
"finish",
|
|
198
198
|
() => {
|
|
199
199
|
if (this.#animation === animation) {
|
|
200
|
-
this.#
|
|
200
|
+
this.#onContentAnimationFinish();
|
|
201
201
|
cleanup();
|
|
202
202
|
}
|
|
203
203
|
},
|
|
@@ -274,7 +274,7 @@ var Tabs = class _Tabs {
|
|
|
274
274
|
this.#panelElements.forEach((panel) => {
|
|
275
275
|
this.#bindings.get(panel)?.animation?.cancel();
|
|
276
276
|
});
|
|
277
|
-
this.#
|
|
277
|
+
this.#onContentAnimationFinish();
|
|
278
278
|
this.#animationController?.abort();
|
|
279
279
|
this.#animationController = null;
|
|
280
280
|
restoreAttributes([
|
|
@@ -332,7 +332,7 @@ var Tabs = class _Tabs {
|
|
|
332
332
|
tab.id ||= `tabs-tab-${id}`;
|
|
333
333
|
}
|
|
334
334
|
tab.setAttribute("role", "tab");
|
|
335
|
-
!isFocusable(tab) && tab.style.setProperty("pointer-events", "none");
|
|
335
|
+
!this.#isFocusable(tab) && tab.style.setProperty("pointer-events", "none");
|
|
336
336
|
addTokenToAttribute(panel, "aria-labelledby", tab.id);
|
|
337
337
|
tab.addEventListener("click", this.#onTabClick, { signal });
|
|
338
338
|
tab.addEventListener("focus", this.#onTabFocus, { signal });
|
|
@@ -347,7 +347,7 @@ var Tabs = class _Tabs {
|
|
|
347
347
|
});
|
|
348
348
|
this.#panelElements.forEach((panel) => {
|
|
349
349
|
panel.setAttribute("role", "tabpanel");
|
|
350
|
-
!panel.hasAttribute("hidden") && !hasFocusable(panel) && panel.setAttribute("tabindex", "0");
|
|
350
|
+
!panel.hasAttribute("hidden") && !this.#hasFocusable(panel) && panel.setAttribute("tabindex", "0");
|
|
351
351
|
panel.addEventListener("beforematch", this.#onPanelBeforeMatch, {
|
|
352
352
|
signal
|
|
353
353
|
});
|
|
@@ -383,6 +383,23 @@ var Tabs = class _Tabs {
|
|
|
383
383
|
!this.#settings.manual && tab.click();
|
|
384
384
|
this.#isAvoidedTab(tab) && tab.blur();
|
|
385
385
|
};
|
|
386
|
+
#onContentAnimationFinish() {
|
|
387
|
+
["block-size", "overflow", "position"].forEach((name) => {
|
|
388
|
+
this.#contentElement?.style.removeProperty(name);
|
|
389
|
+
});
|
|
390
|
+
this.#panelElements.forEach((panel) => {
|
|
391
|
+
[
|
|
392
|
+
"content-visibility",
|
|
393
|
+
"display",
|
|
394
|
+
"inline-size",
|
|
395
|
+
"opacity",
|
|
396
|
+
"position"
|
|
397
|
+
].forEach((name) => {
|
|
398
|
+
panel.style.removeProperty(name);
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
this.#rootElement.removeAttribute("data-tabs-animating");
|
|
402
|
+
}
|
|
386
403
|
#onPanelBeforeMatch = (event) => {
|
|
387
404
|
const panel = event.currentTarget;
|
|
388
405
|
if (!(panel instanceof HTMLElement)) {
|
|
@@ -391,6 +408,16 @@ var Tabs = class _Tabs {
|
|
|
391
408
|
const tab = this.#bindings.get(panel)?.tabs[0];
|
|
392
409
|
tab && this.activate(tab, true);
|
|
393
410
|
};
|
|
411
|
+
#createBinding(tabs, panel) {
|
|
412
|
+
return { tabs, panel, animation: null };
|
|
413
|
+
}
|
|
414
|
+
#hasFocusable(container) {
|
|
415
|
+
return !![
|
|
416
|
+
...container.querySelectorAll(
|
|
417
|
+
`:is(a[href], area[href], button, embed, iframe, input:not([type="hidden" i]), object, select, details > summary:first-of-type, textarea, [contenteditable]:not([contenteditable="false" i]), [controls], [tabindex]):not(:disabled, [hidden], [inert], [tabindex="-1"])`
|
|
418
|
+
)
|
|
419
|
+
].filter((element) => element.checkVisibility()).length;
|
|
420
|
+
}
|
|
394
421
|
#isAvoidedTab(tab) {
|
|
395
422
|
const binding = this.#bindings.get(tab);
|
|
396
423
|
if (!binding) {
|
|
@@ -398,6 +425,9 @@ var Tabs = class _Tabs {
|
|
|
398
425
|
}
|
|
399
426
|
return this.#settings.avoidDuplicates && binding.tabs.indexOf(tab) > 0;
|
|
400
427
|
}
|
|
428
|
+
#isFocusable(element) {
|
|
429
|
+
return !element.hasAttribute("disabled");
|
|
430
|
+
}
|
|
401
431
|
#mergeOptions(target, source) {
|
|
402
432
|
return {
|
|
403
433
|
...target,
|
|
@@ -418,23 +448,6 @@ var Tabs = class _Tabs {
|
|
|
418
448
|
}
|
|
419
449
|
};
|
|
420
450
|
}
|
|
421
|
-
#onAnimationFinish() {
|
|
422
|
-
["block-size", "overflow", "position"].forEach((name) => {
|
|
423
|
-
this.#contentElement?.style.removeProperty(name);
|
|
424
|
-
});
|
|
425
|
-
this.#panelElements.forEach((panel) => {
|
|
426
|
-
[
|
|
427
|
-
"content-visibility",
|
|
428
|
-
"display",
|
|
429
|
-
"inline-size",
|
|
430
|
-
"opacity",
|
|
431
|
-
"position"
|
|
432
|
-
].forEach((name) => {
|
|
433
|
-
panel.style.removeProperty(name);
|
|
434
|
-
});
|
|
435
|
-
});
|
|
436
|
-
this.#rootElement.removeAttribute("data-tabs-animating");
|
|
437
|
-
}
|
|
438
451
|
};
|
|
439
452
|
var TabsIndicator = class {
|
|
440
453
|
#rootElement;
|
|
@@ -504,24 +517,11 @@ var TabsIndicator = class {
|
|
|
504
517
|
this.#listElement = null;
|
|
505
518
|
}
|
|
506
519
|
};
|
|
507
|
-
function createBinding(tabs, panel) {
|
|
508
|
-
return { tabs, panel, animation: null };
|
|
509
|
-
}
|
|
510
|
-
function hasFocusable(container) {
|
|
511
|
-
return !![
|
|
512
|
-
...container.querySelectorAll(
|
|
513
|
-
`:is(a[href], area[href], button, embed, iframe, input:not([type="hidden" i]), object, select, details > summary:first-of-type, textarea, [contenteditable]:not([contenteditable="false" i]), [controls], [tabindex]):not(:disabled, [hidden], [inert], [tabindex="-1"])`
|
|
514
|
-
)
|
|
515
|
-
].filter((element) => element.checkVisibility()).length;
|
|
516
|
-
}
|
|
517
|
-
function isFocusable(element) {
|
|
518
|
-
return !element.hasAttribute("disabled");
|
|
519
|
-
}
|
|
520
520
|
/**
|
|
521
521
|
* Tabs
|
|
522
522
|
* WAI-ARIA compliant tabs pattern implementation in TypeScript.
|
|
523
523
|
*
|
|
524
|
-
* @version 2.0.
|
|
524
|
+
* @version 2.0.5
|
|
525
525
|
* @author Yusuke Kamiyamane
|
|
526
526
|
* @license MIT
|
|
527
527
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@y14e/tabs",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"description": "WAI-ARIA compliant tabs pattern implementation in TypeScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -53,6 +53,6 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@y14e/attributes-utils": "^1.1.2",
|
|
55
55
|
"@y14e/button": "^1.0.6",
|
|
56
|
-
"@y14e/roving-tabindex": "^3.
|
|
56
|
+
"@y14e/roving-tabindex": "^3.1.2"
|
|
57
57
|
}
|
|
58
58
|
}
|