@y14e/accordion 1.3.2 → 1.4.0
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 +97 -40
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +97 -40
- package/package.json +3 -2
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(" ");
|
|
@@ -105,7 +161,12 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
105
161
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
106
162
|
container = document.body;
|
|
107
163
|
}
|
|
108
|
-
let {
|
|
164
|
+
let {
|
|
165
|
+
composed = false,
|
|
166
|
+
filter,
|
|
167
|
+
include,
|
|
168
|
+
skipVisibilityCheck = false
|
|
169
|
+
} = options;
|
|
109
170
|
if (typeof composed !== "boolean") {
|
|
110
171
|
console.warn("Invalid composed option. Fallback: false.");
|
|
111
172
|
composed = false;
|
|
@@ -126,7 +187,7 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
126
187
|
if (composed || include) {
|
|
127
188
|
let traverse2 = function(node) {
|
|
128
189
|
if (node instanceof Element) {
|
|
129
|
-
if (isFocusable(node) || include?.(node)) {
|
|
190
|
+
if (isFocusable(node, { skipVisibilityCheck }) || include?.(node)) {
|
|
130
191
|
elements[elements.length] = node;
|
|
131
192
|
}
|
|
132
193
|
}
|
|
@@ -147,7 +208,7 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
147
208
|
if (!(candidate instanceof Element)) {
|
|
148
209
|
continue;
|
|
149
210
|
}
|
|
150
|
-
if (isFocusable(candidate)) {
|
|
211
|
+
if (isFocusable(candidate, { skipVisibilityCheck })) {
|
|
151
212
|
elements[elements.length] = candidate;
|
|
152
213
|
}
|
|
153
214
|
}
|
|
@@ -155,11 +216,16 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
155
216
|
const unfiltered = normalizeRadioGroup(sortByTabIndex(elements));
|
|
156
217
|
return filter ? unfiltered.filter(filter) : unfiltered;
|
|
157
218
|
}
|
|
158
|
-
function isFocusable(element) {
|
|
219
|
+
function isFocusable(element, options = {}) {
|
|
159
220
|
if (!(element instanceof Element)) {
|
|
160
221
|
console.warn("Invalid element");
|
|
161
222
|
return false;
|
|
162
223
|
}
|
|
224
|
+
let { skipVisibilityCheck = false } = options;
|
|
225
|
+
if (typeof skipVisibilityCheck !== "boolean") {
|
|
226
|
+
console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
|
|
227
|
+
skipVisibilityCheck = false;
|
|
228
|
+
}
|
|
163
229
|
if (element.hasAttribute("hidden") || isInert(element)) {
|
|
164
230
|
return false;
|
|
165
231
|
}
|
|
@@ -172,7 +238,7 @@ function isFocusable(element) {
|
|
|
172
238
|
if (isDisabledDeep(element)) {
|
|
173
239
|
return false;
|
|
174
240
|
}
|
|
175
|
-
if (!element.checkVisibility({
|
|
241
|
+
if (!skipVisibilityCheck && !element.checkVisibility({
|
|
176
242
|
contentVisibilityAuto: true,
|
|
177
243
|
opacityProperty: true,
|
|
178
244
|
visibilityProperty: true
|
|
@@ -406,7 +472,7 @@ var RovingTabIndex = class {
|
|
|
406
472
|
return;
|
|
407
473
|
}
|
|
408
474
|
}
|
|
409
|
-
const active =
|
|
475
|
+
const active = getActiveElement2();
|
|
410
476
|
if (!(active instanceof HTMLElement)) {
|
|
411
477
|
return;
|
|
412
478
|
}
|
|
@@ -457,7 +523,8 @@ var RovingTabIndex = class {
|
|
|
457
523
|
...this.#getFocusables(),
|
|
458
524
|
...getFocusables(this.#container, {
|
|
459
525
|
composed: true,
|
|
460
|
-
filter: this.#selectorFilter
|
|
526
|
+
filter: this.#selectorFilter,
|
|
527
|
+
skipVisibilityCheck: true
|
|
461
528
|
})
|
|
462
529
|
]);
|
|
463
530
|
for (const focusable of this.#focusables) {
|
|
@@ -523,14 +590,15 @@ var RovingTabIndex = class {
|
|
|
523
590
|
return getFocusables(this.#container, {
|
|
524
591
|
composed: true,
|
|
525
592
|
filter: this.#selectorFilter,
|
|
526
|
-
include: (element) => this.#focusables.has(element)
|
|
593
|
+
include: (element) => this.#focusables.has(element),
|
|
594
|
+
skipVisibilityCheck: true
|
|
527
595
|
});
|
|
528
596
|
}
|
|
529
597
|
};
|
|
530
598
|
function focusElement(element) {
|
|
531
599
|
"focus" in element && typeof element.focus === "function" && element.focus();
|
|
532
600
|
}
|
|
533
|
-
function
|
|
601
|
+
function getActiveElement2() {
|
|
534
602
|
let current = document.activeElement;
|
|
535
603
|
while (current?.shadowRoot?.activeElement) {
|
|
536
604
|
current = current.shadowRoot.activeElement;
|
|
@@ -556,6 +624,7 @@ var Accordion = class _Accordion {
|
|
|
556
624
|
#eventController = null;
|
|
557
625
|
#animationController = null;
|
|
558
626
|
#cleanupRovingTabIndex = null;
|
|
627
|
+
#buttons = [];
|
|
559
628
|
#isDestroyed = false;
|
|
560
629
|
constructor(root, options = {}) {
|
|
561
630
|
if (!(root instanceof HTMLElement)) {
|
|
@@ -629,6 +698,10 @@ var Accordion = class _Accordion {
|
|
|
629
698
|
this.#eventController = null;
|
|
630
699
|
this.#cleanupRovingTabIndex?.();
|
|
631
700
|
this.#cleanupRovingTabIndex = null;
|
|
701
|
+
this.#buttons.forEach((button) => {
|
|
702
|
+
button.destroy();
|
|
703
|
+
});
|
|
704
|
+
this.#buttons.length = 0;
|
|
632
705
|
!force && await this.#waitAnimationsFinish();
|
|
633
706
|
this.#contentElements.forEach((content) => {
|
|
634
707
|
force && this.#bindings.get(content)?.animation?.finish();
|
|
@@ -671,12 +744,12 @@ var Accordion = class _Accordion {
|
|
|
671
744
|
trigger2.style.setProperty("pointer-events", "none");
|
|
672
745
|
}
|
|
673
746
|
trigger2.addEventListener("click", this.#onTriggerClick, { signal });
|
|
674
|
-
trigger2.addEventListener("keydown", this.#onTriggerKeyDown, { signal });
|
|
675
747
|
addTokenToAttribute(content2, "aria-labelledby", trigger2.id);
|
|
676
748
|
content2.setAttribute("role", "region");
|
|
677
749
|
content2.addEventListener("beforematch", this.#onContentBeforeMatch, {
|
|
678
750
|
signal
|
|
679
751
|
});
|
|
752
|
+
this.#buttons.push(new Button(trigger2));
|
|
680
753
|
});
|
|
681
754
|
const { trigger, content } = this.#settings.selector;
|
|
682
755
|
this.#cleanupRovingTabIndex = createRovingTabIndex(this.#rootElement, {
|
|
@@ -695,26 +768,6 @@ var Accordion = class _Accordion {
|
|
|
695
768
|
}
|
|
696
769
|
this.#toggle(trigger, trigger.ariaExpanded === "false");
|
|
697
770
|
};
|
|
698
|
-
#onTriggerKeyDown = (event) => {
|
|
699
|
-
const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
|
|
700
|
-
if (altKey || ctrlKey || metaKey || shiftKey) {
|
|
701
|
-
return;
|
|
702
|
-
}
|
|
703
|
-
if (!["Enter", " "].includes(key)) {
|
|
704
|
-
return;
|
|
705
|
-
}
|
|
706
|
-
const active = getActiveElement2();
|
|
707
|
-
if (!(active instanceof HTMLElement)) {
|
|
708
|
-
return;
|
|
709
|
-
}
|
|
710
|
-
event.preventDefault();
|
|
711
|
-
switch (key) {
|
|
712
|
-
case "Enter":
|
|
713
|
-
case " ":
|
|
714
|
-
active.click();
|
|
715
|
-
return;
|
|
716
|
-
}
|
|
717
|
-
};
|
|
718
771
|
#onContentBeforeMatch = (event) => {
|
|
719
772
|
const content = event.currentTarget;
|
|
720
773
|
if (!(content instanceof HTMLElement)) {
|
|
@@ -811,13 +864,6 @@ var Accordion = class _Accordion {
|
|
|
811
864
|
function createBinding(trigger, content) {
|
|
812
865
|
return { trigger, content, animation: null };
|
|
813
866
|
}
|
|
814
|
-
function getActiveElement2() {
|
|
815
|
-
let current = document.activeElement;
|
|
816
|
-
while (current?.shadowRoot?.activeElement) {
|
|
817
|
-
current = current.shadowRoot.activeElement;
|
|
818
|
-
}
|
|
819
|
-
return current;
|
|
820
|
-
}
|
|
821
867
|
function isFocusable2(element) {
|
|
822
868
|
return !element.hasAttribute("disabled") && element.tabIndex >= 0;
|
|
823
869
|
}
|
|
@@ -834,7 +880,7 @@ function waitAnimationFinish(animation) {
|
|
|
834
880
|
* Accordion
|
|
835
881
|
* WAI-ARIA compliant accordion pattern implementation in TypeScript.
|
|
836
882
|
*
|
|
837
|
-
* @version 1.
|
|
883
|
+
* @version 1.4.0
|
|
838
884
|
* @author Yusuke Kamiyamane
|
|
839
885
|
* @license MIT
|
|
840
886
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -853,13 +899,24 @@ function waitAnimationFinish(animation) {
|
|
|
853
899
|
* @see {@link https://github.com/y14e/attributes-utils}
|
|
854
900
|
*)
|
|
855
901
|
|
|
902
|
+
@y14e/button/dist/index.js:
|
|
903
|
+
(**
|
|
904
|
+
* Button
|
|
905
|
+
*
|
|
906
|
+
* @version 1.0.0
|
|
907
|
+
* @author Yusuke Kamiyamane
|
|
908
|
+
* @license MIT
|
|
909
|
+
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
910
|
+
* @see {@link https://github.com/y14e/button}
|
|
911
|
+
*)
|
|
912
|
+
|
|
856
913
|
@y14e/roving-tabindex/dist/index.js:
|
|
857
914
|
(**
|
|
858
915
|
* Roving Tabindex
|
|
859
916
|
* Lightweight roving tabindex utility with fully focus management.
|
|
860
917
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
861
918
|
*
|
|
862
|
-
* @version 1.3.
|
|
919
|
+
* @version 1.3.1
|
|
863
920
|
* @author Yusuke Kamiyamane
|
|
864
921
|
* @license MIT
|
|
865
922
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -884,7 +941,7 @@ function waitAnimationFinish(animation) {
|
|
|
884
941
|
* High-precision focus management utility with full composed tree support.
|
|
885
942
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
886
943
|
*
|
|
887
|
-
* @version 4.
|
|
944
|
+
* @version 4.2.0
|
|
888
945
|
* @author Yusuke Kamiyamane
|
|
889
946
|
* @license MIT
|
|
890
947
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
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(" ");
|
|
@@ -103,7 +159,12 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
103
159
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
104
160
|
container = document.body;
|
|
105
161
|
}
|
|
106
|
-
let {
|
|
162
|
+
let {
|
|
163
|
+
composed = false,
|
|
164
|
+
filter,
|
|
165
|
+
include,
|
|
166
|
+
skipVisibilityCheck = false
|
|
167
|
+
} = options;
|
|
107
168
|
if (typeof composed !== "boolean") {
|
|
108
169
|
console.warn("Invalid composed option. Fallback: false.");
|
|
109
170
|
composed = false;
|
|
@@ -124,7 +185,7 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
124
185
|
if (composed || include) {
|
|
125
186
|
let traverse2 = function(node) {
|
|
126
187
|
if (node instanceof Element) {
|
|
127
|
-
if (isFocusable(node) || include?.(node)) {
|
|
188
|
+
if (isFocusable(node, { skipVisibilityCheck }) || include?.(node)) {
|
|
128
189
|
elements[elements.length] = node;
|
|
129
190
|
}
|
|
130
191
|
}
|
|
@@ -145,7 +206,7 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
145
206
|
if (!(candidate instanceof Element)) {
|
|
146
207
|
continue;
|
|
147
208
|
}
|
|
148
|
-
if (isFocusable(candidate)) {
|
|
209
|
+
if (isFocusable(candidate, { skipVisibilityCheck })) {
|
|
149
210
|
elements[elements.length] = candidate;
|
|
150
211
|
}
|
|
151
212
|
}
|
|
@@ -153,11 +214,16 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
153
214
|
const unfiltered = normalizeRadioGroup(sortByTabIndex(elements));
|
|
154
215
|
return filter ? unfiltered.filter(filter) : unfiltered;
|
|
155
216
|
}
|
|
156
|
-
function isFocusable(element) {
|
|
217
|
+
function isFocusable(element, options = {}) {
|
|
157
218
|
if (!(element instanceof Element)) {
|
|
158
219
|
console.warn("Invalid element");
|
|
159
220
|
return false;
|
|
160
221
|
}
|
|
222
|
+
let { skipVisibilityCheck = false } = options;
|
|
223
|
+
if (typeof skipVisibilityCheck !== "boolean") {
|
|
224
|
+
console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
|
|
225
|
+
skipVisibilityCheck = false;
|
|
226
|
+
}
|
|
161
227
|
if (element.hasAttribute("hidden") || isInert(element)) {
|
|
162
228
|
return false;
|
|
163
229
|
}
|
|
@@ -170,7 +236,7 @@ function isFocusable(element) {
|
|
|
170
236
|
if (isDisabledDeep(element)) {
|
|
171
237
|
return false;
|
|
172
238
|
}
|
|
173
|
-
if (!element.checkVisibility({
|
|
239
|
+
if (!skipVisibilityCheck && !element.checkVisibility({
|
|
174
240
|
contentVisibilityAuto: true,
|
|
175
241
|
opacityProperty: true,
|
|
176
242
|
visibilityProperty: true
|
|
@@ -404,7 +470,7 @@ var RovingTabIndex = class {
|
|
|
404
470
|
return;
|
|
405
471
|
}
|
|
406
472
|
}
|
|
407
|
-
const active =
|
|
473
|
+
const active = getActiveElement2();
|
|
408
474
|
if (!(active instanceof HTMLElement)) {
|
|
409
475
|
return;
|
|
410
476
|
}
|
|
@@ -455,7 +521,8 @@ var RovingTabIndex = class {
|
|
|
455
521
|
...this.#getFocusables(),
|
|
456
522
|
...getFocusables(this.#container, {
|
|
457
523
|
composed: true,
|
|
458
|
-
filter: this.#selectorFilter
|
|
524
|
+
filter: this.#selectorFilter,
|
|
525
|
+
skipVisibilityCheck: true
|
|
459
526
|
})
|
|
460
527
|
]);
|
|
461
528
|
for (const focusable of this.#focusables) {
|
|
@@ -521,14 +588,15 @@ var RovingTabIndex = class {
|
|
|
521
588
|
return getFocusables(this.#container, {
|
|
522
589
|
composed: true,
|
|
523
590
|
filter: this.#selectorFilter,
|
|
524
|
-
include: (element) => this.#focusables.has(element)
|
|
591
|
+
include: (element) => this.#focusables.has(element),
|
|
592
|
+
skipVisibilityCheck: true
|
|
525
593
|
});
|
|
526
594
|
}
|
|
527
595
|
};
|
|
528
596
|
function focusElement(element) {
|
|
529
597
|
"focus" in element && typeof element.focus === "function" && element.focus();
|
|
530
598
|
}
|
|
531
|
-
function
|
|
599
|
+
function getActiveElement2() {
|
|
532
600
|
let current = document.activeElement;
|
|
533
601
|
while (current?.shadowRoot?.activeElement) {
|
|
534
602
|
current = current.shadowRoot.activeElement;
|
|
@@ -554,6 +622,7 @@ var Accordion = class _Accordion {
|
|
|
554
622
|
#eventController = null;
|
|
555
623
|
#animationController = null;
|
|
556
624
|
#cleanupRovingTabIndex = null;
|
|
625
|
+
#buttons = [];
|
|
557
626
|
#isDestroyed = false;
|
|
558
627
|
constructor(root, options = {}) {
|
|
559
628
|
if (!(root instanceof HTMLElement)) {
|
|
@@ -627,6 +696,10 @@ var Accordion = class _Accordion {
|
|
|
627
696
|
this.#eventController = null;
|
|
628
697
|
this.#cleanupRovingTabIndex?.();
|
|
629
698
|
this.#cleanupRovingTabIndex = null;
|
|
699
|
+
this.#buttons.forEach((button) => {
|
|
700
|
+
button.destroy();
|
|
701
|
+
});
|
|
702
|
+
this.#buttons.length = 0;
|
|
630
703
|
!force && await this.#waitAnimationsFinish();
|
|
631
704
|
this.#contentElements.forEach((content) => {
|
|
632
705
|
force && this.#bindings.get(content)?.animation?.finish();
|
|
@@ -669,12 +742,12 @@ var Accordion = class _Accordion {
|
|
|
669
742
|
trigger2.style.setProperty("pointer-events", "none");
|
|
670
743
|
}
|
|
671
744
|
trigger2.addEventListener("click", this.#onTriggerClick, { signal });
|
|
672
|
-
trigger2.addEventListener("keydown", this.#onTriggerKeyDown, { signal });
|
|
673
745
|
addTokenToAttribute(content2, "aria-labelledby", trigger2.id);
|
|
674
746
|
content2.setAttribute("role", "region");
|
|
675
747
|
content2.addEventListener("beforematch", this.#onContentBeforeMatch, {
|
|
676
748
|
signal
|
|
677
749
|
});
|
|
750
|
+
this.#buttons.push(new Button(trigger2));
|
|
678
751
|
});
|
|
679
752
|
const { trigger, content } = this.#settings.selector;
|
|
680
753
|
this.#cleanupRovingTabIndex = createRovingTabIndex(this.#rootElement, {
|
|
@@ -693,26 +766,6 @@ var Accordion = class _Accordion {
|
|
|
693
766
|
}
|
|
694
767
|
this.#toggle(trigger, trigger.ariaExpanded === "false");
|
|
695
768
|
};
|
|
696
|
-
#onTriggerKeyDown = (event) => {
|
|
697
|
-
const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
|
|
698
|
-
if (altKey || ctrlKey || metaKey || shiftKey) {
|
|
699
|
-
return;
|
|
700
|
-
}
|
|
701
|
-
if (!["Enter", " "].includes(key)) {
|
|
702
|
-
return;
|
|
703
|
-
}
|
|
704
|
-
const active = getActiveElement2();
|
|
705
|
-
if (!(active instanceof HTMLElement)) {
|
|
706
|
-
return;
|
|
707
|
-
}
|
|
708
|
-
event.preventDefault();
|
|
709
|
-
switch (key) {
|
|
710
|
-
case "Enter":
|
|
711
|
-
case " ":
|
|
712
|
-
active.click();
|
|
713
|
-
return;
|
|
714
|
-
}
|
|
715
|
-
};
|
|
716
769
|
#onContentBeforeMatch = (event) => {
|
|
717
770
|
const content = event.currentTarget;
|
|
718
771
|
if (!(content instanceof HTMLElement)) {
|
|
@@ -809,13 +862,6 @@ var Accordion = class _Accordion {
|
|
|
809
862
|
function createBinding(trigger, content) {
|
|
810
863
|
return { trigger, content, animation: null };
|
|
811
864
|
}
|
|
812
|
-
function getActiveElement2() {
|
|
813
|
-
let current = document.activeElement;
|
|
814
|
-
while (current?.shadowRoot?.activeElement) {
|
|
815
|
-
current = current.shadowRoot.activeElement;
|
|
816
|
-
}
|
|
817
|
-
return current;
|
|
818
|
-
}
|
|
819
865
|
function isFocusable2(element) {
|
|
820
866
|
return !element.hasAttribute("disabled") && element.tabIndex >= 0;
|
|
821
867
|
}
|
|
@@ -832,7 +878,7 @@ function waitAnimationFinish(animation) {
|
|
|
832
878
|
* Accordion
|
|
833
879
|
* WAI-ARIA compliant accordion pattern implementation in TypeScript.
|
|
834
880
|
*
|
|
835
|
-
* @version 1.
|
|
881
|
+
* @version 1.4.0
|
|
836
882
|
* @author Yusuke Kamiyamane
|
|
837
883
|
* @license MIT
|
|
838
884
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -851,13 +897,24 @@ function waitAnimationFinish(animation) {
|
|
|
851
897
|
* @see {@link https://github.com/y14e/attributes-utils}
|
|
852
898
|
*)
|
|
853
899
|
|
|
900
|
+
@y14e/button/dist/index.js:
|
|
901
|
+
(**
|
|
902
|
+
* Button
|
|
903
|
+
*
|
|
904
|
+
* @version 1.0.0
|
|
905
|
+
* @author Yusuke Kamiyamane
|
|
906
|
+
* @license MIT
|
|
907
|
+
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
908
|
+
* @see {@link https://github.com/y14e/button}
|
|
909
|
+
*)
|
|
910
|
+
|
|
854
911
|
@y14e/roving-tabindex/dist/index.js:
|
|
855
912
|
(**
|
|
856
913
|
* Roving Tabindex
|
|
857
914
|
* Lightweight roving tabindex utility with fully focus management.
|
|
858
915
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
859
916
|
*
|
|
860
|
-
* @version 1.3.
|
|
917
|
+
* @version 1.3.1
|
|
861
918
|
* @author Yusuke Kamiyamane
|
|
862
919
|
* @license MIT
|
|
863
920
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -882,7 +939,7 @@ function waitAnimationFinish(animation) {
|
|
|
882
939
|
* High-precision focus management utility with full composed tree support.
|
|
883
940
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
884
941
|
*
|
|
885
|
-
* @version 4.
|
|
942
|
+
* @version 4.2.0
|
|
886
943
|
* @author Yusuke Kamiyamane
|
|
887
944
|
* @license MIT
|
|
888
945
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@y14e/accordion",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "WAI-ARIA compliant accordion pattern implementation in TypeScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
"homepage": "https://github.com/y14e/accordion#readme",
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@y14e/attributes-utils": "^1.0.5",
|
|
47
|
-
"@y14e/
|
|
47
|
+
"@y14e/button": "^1.0.0",
|
|
48
|
+
"@y14e/roving-tabindex": "^1.3.1",
|
|
48
49
|
"bun-types": "latest",
|
|
49
50
|
"tsup": "^8.0.0",
|
|
50
51
|
"typescript": "^5.6.0",
|