@y14e/accordion 2.0.4 → 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 +7 -7
- package/dist/index.bundle.cjs +19 -13
- package/dist/index.bundle.js +19 -13
- package/dist/index.cjs +33 -7
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +14 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -13,11 +13,11 @@ npm i @y14e/accordion
|
|
|
13
13
|
import Accordion from "@y14e/accordion";
|
|
14
14
|
|
|
15
15
|
// CDNs
|
|
16
|
-
import Accordion from "https://esm.sh/@y14e/accordion@2.0.
|
|
16
|
+
import Accordion from "https://esm.sh/@y14e/accordion@2.0.5";
|
|
17
17
|
// or
|
|
18
|
-
import Accordion from "https://cdn.jsdelivr.net/npm/@y14e/accordion@2.0.
|
|
18
|
+
import Accordion from "https://cdn.jsdelivr.net/npm/@y14e/accordion@2.0.5/+esm";
|
|
19
19
|
// or
|
|
20
|
-
import Accordion from "https://esm.unpkg.com/@y14e/accordion@2.0.
|
|
20
|
+
import Accordion from "https://esm.unpkg.com/@y14e/accordion@2.0.5";
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
## Usage
|
|
@@ -35,13 +35,13 @@ new Accordion(root, options);
|
|
|
35
35
|
```ts
|
|
36
36
|
interface AccordionOptions {
|
|
37
37
|
animation: {
|
|
38
|
-
duration: number;
|
|
39
|
-
easing: string;
|
|
38
|
+
duration: number; // ms (default: 300)
|
|
39
|
+
easing: string; // <easing-function> (default: 'ease')
|
|
40
40
|
};
|
|
41
41
|
collapsible: boolean; // default: true
|
|
42
42
|
selector: {
|
|
43
|
-
content: string;
|
|
44
|
-
trigger: string;
|
|
43
|
+
content: string; // default: '[data-accordion-content]'
|
|
44
|
+
trigger: string; // default: '[data-accordion-trigger]'
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
```
|
package/dist/index.bundle.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
// node_modules/@y14e/
|
|
3
|
+
// node_modules/@y14e/attribute-util/dist/index.js
|
|
4
4
|
var DEFAULT_PARSER = (value) => value.split(/\s+/);
|
|
5
5
|
var DEFAULT_SERIALIZER = (tokens) => tokens.join(" ");
|
|
6
6
|
function addAttributeToken(element, name, token, options = {}) {
|
|
@@ -49,7 +49,6 @@ function saveAttributes(element_or_elements, name_or_names) {
|
|
|
49
49
|
});
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
|
-
var addTokenToAttribute = addAttributeToken;
|
|
53
52
|
|
|
54
53
|
// node_modules/power-focusable/dist/index.js
|
|
55
54
|
var FOCUSABLE_SELECTOR = `: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"])`;
|
|
@@ -369,10 +368,10 @@ var Button = class {
|
|
|
369
368
|
};
|
|
370
369
|
};
|
|
371
370
|
|
|
372
|
-
// node_modules/@y14e/
|
|
371
|
+
// node_modules/@y14e/attributes-utils/dist/index.js
|
|
373
372
|
var DEFAULT_PARSER2 = (value) => value.split(/\s+/);
|
|
374
373
|
var DEFAULT_SERIALIZER2 = (tokens) => tokens.join(" ");
|
|
375
|
-
function
|
|
374
|
+
function addTokenToAttribute(element, name, token, options = {}) {
|
|
376
375
|
const value = element.getAttribute(name)?.trim();
|
|
377
376
|
const {
|
|
378
377
|
caseInsensitive = false,
|
|
@@ -651,7 +650,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
651
650
|
if (char) {
|
|
652
651
|
keys.add(char);
|
|
653
652
|
saveAttributes2(focusable, "aria-keyshortcuts");
|
|
654
|
-
|
|
653
|
+
addTokenToAttribute(focusable, "aria-keyshortcuts", char, {
|
|
655
654
|
caseInsensitive: true
|
|
656
655
|
});
|
|
657
656
|
}
|
|
@@ -781,7 +780,10 @@ var Accordion = class _Accordion {
|
|
|
781
780
|
});
|
|
782
781
|
this.#animationController?.abort();
|
|
783
782
|
this.#animationController = null;
|
|
784
|
-
restoreAttributes([
|
|
783
|
+
restoreAttributes([
|
|
784
|
+
...this.#triggerElements,
|
|
785
|
+
...this.#contentElements
|
|
786
|
+
]);
|
|
785
787
|
this.#triggerElements.length = 0;
|
|
786
788
|
this.#contentElements.length = 0;
|
|
787
789
|
this.#rootElement.removeAttribute("data-accordion-initialized");
|
|
@@ -804,7 +806,11 @@ var Accordion = class _Accordion {
|
|
|
804
806
|
"style",
|
|
805
807
|
"tabindex"
|
|
806
808
|
]);
|
|
807
|
-
saveAttributes(this.#contentElements, [
|
|
809
|
+
saveAttributes(this.#contentElements, [
|
|
810
|
+
"aria-labelledby",
|
|
811
|
+
"id",
|
|
812
|
+
"role"
|
|
813
|
+
]);
|
|
808
814
|
this.#eventController = new AbortController();
|
|
809
815
|
const { signal } = this.#eventController;
|
|
810
816
|
this.#triggerElements.forEach((trigger2, i) => {
|
|
@@ -814,7 +820,7 @@ var Accordion = class _Accordion {
|
|
|
814
820
|
return;
|
|
815
821
|
}
|
|
816
822
|
content2.id ||= `accordion-content-${id}`;
|
|
817
|
-
|
|
823
|
+
addAttributeToken(trigger2, "aria-controls", content2.id);
|
|
818
824
|
trigger2.setAttribute(
|
|
819
825
|
"aria-expanded",
|
|
820
826
|
String(trigger2.ariaExpanded === "true")
|
|
@@ -826,7 +832,7 @@ var Accordion = class _Accordion {
|
|
|
826
832
|
trigger2.style.setProperty("pointer-events", "none");
|
|
827
833
|
}
|
|
828
834
|
trigger2.addEventListener("click", this.#onTriggerClick, { signal });
|
|
829
|
-
|
|
835
|
+
addAttributeToken(content2, "aria-labelledby", trigger2.id);
|
|
830
836
|
content2.setAttribute("role", "region");
|
|
831
837
|
content2.addEventListener("beforematch", this.#onContentBeforeMatch, {
|
|
832
838
|
signal
|
|
@@ -961,7 +967,7 @@ function waitAnimationFinish(animation) {
|
|
|
961
967
|
* Accordion
|
|
962
968
|
* WAI-ARIA compliant accordion pattern implementation in TypeScript.
|
|
963
969
|
*
|
|
964
|
-
* @version 2.0.
|
|
970
|
+
* @version 2.0.5
|
|
965
971
|
* @author Yusuke Kamiyamane
|
|
966
972
|
* @license MIT
|
|
967
973
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -969,15 +975,15 @@ function waitAnimationFinish(animation) {
|
|
|
969
975
|
*/
|
|
970
976
|
/*! Bundled license information:
|
|
971
977
|
|
|
972
|
-
@y14e/
|
|
978
|
+
@y14e/attribute-util/dist/index.js:
|
|
973
979
|
(**
|
|
974
|
-
*
|
|
980
|
+
* Attribute Util
|
|
975
981
|
*
|
|
976
982
|
* @version 2.0.0
|
|
977
983
|
* @author Yusuke Kamiyamane
|
|
978
984
|
* @license MIT
|
|
979
985
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
980
|
-
* @see {@link https://github.com/y14e/
|
|
986
|
+
* @see {@link https://github.com/y14e/attribute-util}
|
|
981
987
|
*)
|
|
982
988
|
|
|
983
989
|
power-focusable/dist/index.js:
|
package/dist/index.bundle.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// node_modules/@y14e/
|
|
1
|
+
// node_modules/@y14e/attribute-util/dist/index.js
|
|
2
2
|
var DEFAULT_PARSER = (value) => value.split(/\s+/);
|
|
3
3
|
var DEFAULT_SERIALIZER = (tokens) => tokens.join(" ");
|
|
4
4
|
function addAttributeToken(element, name, token, options = {}) {
|
|
@@ -47,7 +47,6 @@ function saveAttributes(element_or_elements, name_or_names) {
|
|
|
47
47
|
});
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
-
var addTokenToAttribute = addAttributeToken;
|
|
51
50
|
|
|
52
51
|
// node_modules/power-focusable/dist/index.js
|
|
53
52
|
var FOCUSABLE_SELECTOR = `: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"])`;
|
|
@@ -367,10 +366,10 @@ var Button = class {
|
|
|
367
366
|
};
|
|
368
367
|
};
|
|
369
368
|
|
|
370
|
-
// node_modules/@y14e/
|
|
369
|
+
// node_modules/@y14e/attributes-utils/dist/index.js
|
|
371
370
|
var DEFAULT_PARSER2 = (value) => value.split(/\s+/);
|
|
372
371
|
var DEFAULT_SERIALIZER2 = (tokens) => tokens.join(" ");
|
|
373
|
-
function
|
|
372
|
+
function addTokenToAttribute(element, name, token, options = {}) {
|
|
374
373
|
const value = element.getAttribute(name)?.trim();
|
|
375
374
|
const {
|
|
376
375
|
caseInsensitive = false,
|
|
@@ -649,7 +648,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
649
648
|
if (char) {
|
|
650
649
|
keys.add(char);
|
|
651
650
|
saveAttributes2(focusable, "aria-keyshortcuts");
|
|
652
|
-
|
|
651
|
+
addTokenToAttribute(focusable, "aria-keyshortcuts", char, {
|
|
653
652
|
caseInsensitive: true
|
|
654
653
|
});
|
|
655
654
|
}
|
|
@@ -779,7 +778,10 @@ var Accordion = class _Accordion {
|
|
|
779
778
|
});
|
|
780
779
|
this.#animationController?.abort();
|
|
781
780
|
this.#animationController = null;
|
|
782
|
-
restoreAttributes([
|
|
781
|
+
restoreAttributes([
|
|
782
|
+
...this.#triggerElements,
|
|
783
|
+
...this.#contentElements
|
|
784
|
+
]);
|
|
783
785
|
this.#triggerElements.length = 0;
|
|
784
786
|
this.#contentElements.length = 0;
|
|
785
787
|
this.#rootElement.removeAttribute("data-accordion-initialized");
|
|
@@ -802,7 +804,11 @@ var Accordion = class _Accordion {
|
|
|
802
804
|
"style",
|
|
803
805
|
"tabindex"
|
|
804
806
|
]);
|
|
805
|
-
saveAttributes(this.#contentElements, [
|
|
807
|
+
saveAttributes(this.#contentElements, [
|
|
808
|
+
"aria-labelledby",
|
|
809
|
+
"id",
|
|
810
|
+
"role"
|
|
811
|
+
]);
|
|
806
812
|
this.#eventController = new AbortController();
|
|
807
813
|
const { signal } = this.#eventController;
|
|
808
814
|
this.#triggerElements.forEach((trigger2, i) => {
|
|
@@ -812,7 +818,7 @@ var Accordion = class _Accordion {
|
|
|
812
818
|
return;
|
|
813
819
|
}
|
|
814
820
|
content2.id ||= `accordion-content-${id}`;
|
|
815
|
-
|
|
821
|
+
addAttributeToken(trigger2, "aria-controls", content2.id);
|
|
816
822
|
trigger2.setAttribute(
|
|
817
823
|
"aria-expanded",
|
|
818
824
|
String(trigger2.ariaExpanded === "true")
|
|
@@ -824,7 +830,7 @@ var Accordion = class _Accordion {
|
|
|
824
830
|
trigger2.style.setProperty("pointer-events", "none");
|
|
825
831
|
}
|
|
826
832
|
trigger2.addEventListener("click", this.#onTriggerClick, { signal });
|
|
827
|
-
|
|
833
|
+
addAttributeToken(content2, "aria-labelledby", trigger2.id);
|
|
828
834
|
content2.setAttribute("role", "region");
|
|
829
835
|
content2.addEventListener("beforematch", this.#onContentBeforeMatch, {
|
|
830
836
|
signal
|
|
@@ -959,7 +965,7 @@ function waitAnimationFinish(animation) {
|
|
|
959
965
|
* Accordion
|
|
960
966
|
* WAI-ARIA compliant accordion pattern implementation in TypeScript.
|
|
961
967
|
*
|
|
962
|
-
* @version 2.0.
|
|
968
|
+
* @version 2.0.5
|
|
963
969
|
* @author Yusuke Kamiyamane
|
|
964
970
|
* @license MIT
|
|
965
971
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -967,15 +973,15 @@ function waitAnimationFinish(animation) {
|
|
|
967
973
|
*/
|
|
968
974
|
/*! Bundled license information:
|
|
969
975
|
|
|
970
|
-
@y14e/
|
|
976
|
+
@y14e/attribute-util/dist/index.js:
|
|
971
977
|
(**
|
|
972
|
-
*
|
|
978
|
+
* Attribute Util
|
|
973
979
|
*
|
|
974
980
|
* @version 2.0.0
|
|
975
981
|
* @author Yusuke Kamiyamane
|
|
976
982
|
* @license MIT
|
|
977
983
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
978
|
-
* @see {@link https://github.com/y14e/
|
|
984
|
+
* @see {@link https://github.com/y14e/attribute-util}
|
|
979
985
|
*)
|
|
980
986
|
|
|
981
987
|
power-focusable/dist/index.js:
|
package/dist/index.cjs
CHANGED
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var util = require('@y14e/attribute-util');
|
|
4
4
|
var Button = require('@y14e/button');
|
|
5
5
|
var rovingTabindex = require('@y14e/roving-tabindex');
|
|
6
6
|
|
|
7
7
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
8
|
|
|
9
|
+
function _interopNamespace(e) {
|
|
10
|
+
if (e && e.__esModule) return e;
|
|
11
|
+
var n = Object.create(null);
|
|
12
|
+
if (e) {
|
|
13
|
+
Object.keys(e).forEach(function (k) {
|
|
14
|
+
if (k !== 'default') {
|
|
15
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
16
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return e[k]; }
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
n.default = e;
|
|
24
|
+
return Object.freeze(n);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var util__namespace = /*#__PURE__*/_interopNamespace(util);
|
|
9
28
|
var Button__default = /*#__PURE__*/_interopDefault(Button);
|
|
10
29
|
|
|
11
30
|
// src/index.ts
|
|
@@ -102,7 +121,10 @@ var Accordion = class _Accordion {
|
|
|
102
121
|
});
|
|
103
122
|
this.#animationController?.abort();
|
|
104
123
|
this.#animationController = null;
|
|
105
|
-
|
|
124
|
+
util__namespace.restoreAttributes([
|
|
125
|
+
...this.#triggerElements,
|
|
126
|
+
...this.#contentElements
|
|
127
|
+
]);
|
|
106
128
|
this.#triggerElements.length = 0;
|
|
107
129
|
this.#contentElements.length = 0;
|
|
108
130
|
this.#rootElement.removeAttribute("data-accordion-initialized");
|
|
@@ -118,14 +140,18 @@ var Accordion = class _Accordion {
|
|
|
118
140
|
this.#toggle(trigger, true);
|
|
119
141
|
}
|
|
120
142
|
#initialize() {
|
|
121
|
-
|
|
143
|
+
util__namespace.saveAttributes(this.#triggerElements, [
|
|
122
144
|
"aria-controls",
|
|
123
145
|
"aria-disabled",
|
|
124
146
|
"id",
|
|
125
147
|
"style",
|
|
126
148
|
"tabindex"
|
|
127
149
|
]);
|
|
128
|
-
|
|
150
|
+
util__namespace.saveAttributes(this.#contentElements, [
|
|
151
|
+
"aria-labelledby",
|
|
152
|
+
"id",
|
|
153
|
+
"role"
|
|
154
|
+
]);
|
|
129
155
|
this.#eventController = new AbortController();
|
|
130
156
|
const { signal } = this.#eventController;
|
|
131
157
|
this.#triggerElements.forEach((trigger2, i) => {
|
|
@@ -135,7 +161,7 @@ var Accordion = class _Accordion {
|
|
|
135
161
|
return;
|
|
136
162
|
}
|
|
137
163
|
content2.id ||= `accordion-content-${id}`;
|
|
138
|
-
|
|
164
|
+
util__namespace.addAttributeToken(trigger2, "aria-controls", content2.id);
|
|
139
165
|
trigger2.setAttribute(
|
|
140
166
|
"aria-expanded",
|
|
141
167
|
String(trigger2.ariaExpanded === "true")
|
|
@@ -147,7 +173,7 @@ var Accordion = class _Accordion {
|
|
|
147
173
|
trigger2.style.setProperty("pointer-events", "none");
|
|
148
174
|
}
|
|
149
175
|
trigger2.addEventListener("click", this.#onTriggerClick, { signal });
|
|
150
|
-
|
|
176
|
+
util__namespace.addAttributeToken(content2, "aria-labelledby", trigger2.id);
|
|
151
177
|
content2.setAttribute("role", "region");
|
|
152
178
|
content2.addEventListener("beforematch", this.#onContentBeforeMatch, {
|
|
153
179
|
signal
|
|
@@ -282,7 +308,7 @@ function waitAnimationFinish(animation) {
|
|
|
282
308
|
* Accordion
|
|
283
309
|
* WAI-ARIA compliant accordion pattern implementation in TypeScript.
|
|
284
310
|
*
|
|
285
|
-
* @version 2.0.
|
|
311
|
+
* @version 2.0.5
|
|
286
312
|
* @author Yusuke Kamiyamane
|
|
287
313
|
* @license MIT
|
|
288
314
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as util from '@y14e/attribute-util';
|
|
2
2
|
import Button from '@y14e/button';
|
|
3
3
|
import { createRovingTabIndex } from '@y14e/roving-tabindex';
|
|
4
4
|
|
|
@@ -96,7 +96,10 @@ var Accordion = class _Accordion {
|
|
|
96
96
|
});
|
|
97
97
|
this.#animationController?.abort();
|
|
98
98
|
this.#animationController = null;
|
|
99
|
-
restoreAttributes([
|
|
99
|
+
util.restoreAttributes([
|
|
100
|
+
...this.#triggerElements,
|
|
101
|
+
...this.#contentElements
|
|
102
|
+
]);
|
|
100
103
|
this.#triggerElements.length = 0;
|
|
101
104
|
this.#contentElements.length = 0;
|
|
102
105
|
this.#rootElement.removeAttribute("data-accordion-initialized");
|
|
@@ -112,14 +115,18 @@ var Accordion = class _Accordion {
|
|
|
112
115
|
this.#toggle(trigger, true);
|
|
113
116
|
}
|
|
114
117
|
#initialize() {
|
|
115
|
-
saveAttributes(this.#triggerElements, [
|
|
118
|
+
util.saveAttributes(this.#triggerElements, [
|
|
116
119
|
"aria-controls",
|
|
117
120
|
"aria-disabled",
|
|
118
121
|
"id",
|
|
119
122
|
"style",
|
|
120
123
|
"tabindex"
|
|
121
124
|
]);
|
|
122
|
-
saveAttributes(this.#contentElements, [
|
|
125
|
+
util.saveAttributes(this.#contentElements, [
|
|
126
|
+
"aria-labelledby",
|
|
127
|
+
"id",
|
|
128
|
+
"role"
|
|
129
|
+
]);
|
|
123
130
|
this.#eventController = new AbortController();
|
|
124
131
|
const { signal } = this.#eventController;
|
|
125
132
|
this.#triggerElements.forEach((trigger2, i) => {
|
|
@@ -129,7 +136,7 @@ var Accordion = class _Accordion {
|
|
|
129
136
|
return;
|
|
130
137
|
}
|
|
131
138
|
content2.id ||= `accordion-content-${id}`;
|
|
132
|
-
|
|
139
|
+
util.addAttributeToken(trigger2, "aria-controls", content2.id);
|
|
133
140
|
trigger2.setAttribute(
|
|
134
141
|
"aria-expanded",
|
|
135
142
|
String(trigger2.ariaExpanded === "true")
|
|
@@ -141,7 +148,7 @@ var Accordion = class _Accordion {
|
|
|
141
148
|
trigger2.style.setProperty("pointer-events", "none");
|
|
142
149
|
}
|
|
143
150
|
trigger2.addEventListener("click", this.#onTriggerClick, { signal });
|
|
144
|
-
|
|
151
|
+
util.addAttributeToken(content2, "aria-labelledby", trigger2.id);
|
|
145
152
|
content2.setAttribute("role", "region");
|
|
146
153
|
content2.addEventListener("beforematch", this.#onContentBeforeMatch, {
|
|
147
154
|
signal
|
|
@@ -276,7 +283,7 @@ function waitAnimationFinish(animation) {
|
|
|
276
283
|
* Accordion
|
|
277
284
|
* WAI-ARIA compliant accordion pattern implementation in TypeScript.
|
|
278
285
|
*
|
|
279
|
-
* @version 2.0.
|
|
286
|
+
* @version 2.0.5
|
|
280
287
|
* @author Yusuke Kamiyamane
|
|
281
288
|
* @license MIT
|
|
282
289
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@y14e/accordion",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"description": "WAI-ARIA compliant accordion pattern implementation in TypeScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"node": ">=18"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@y14e/
|
|
54
|
+
"@y14e/attribute-util": "^2.0.0",
|
|
55
55
|
"@y14e/button": "^1.0.6",
|
|
56
56
|
"@y14e/roving-tabindex": "^3.1.20"
|
|
57
57
|
}
|