@y14e/accordion 1.3.3 → 1.4.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/README.md CHANGED
@@ -10,14 +10,14 @@ npm i @y14e/accordion
10
10
 
11
11
  ```ts
12
12
  // npm
13
- import Accordion from '@y14e/accordion';
13
+ import Accordion from '@y14e/accordion@1.4.1';
14
14
 
15
15
  // CDNs
16
- import Accordion from 'https://esm.sh/@y14e/accordion'
16
+ import Accordion from 'https://esm.sh/@y14e/accordion@1.4.1';
17
17
  // or
18
- import Accordion from 'https://cdn.jsdelivr.net/npm/@y14e/accordion/+esm';
18
+ import Accordion from 'https://cdn.jsdelivr.net/npm/@y14e/accordion@1.4.1/+esm';
19
19
  // or
20
- import Accordion from 'https://unpkg.com/@y14e/accordion/dist/index.js';
20
+ import Accordion from 'https://esm.unpkg.com/@y14e/accordion@1.4.1';
21
21
  ```
22
22
 
23
23
  ## Usage
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(" ");
@@ -109,6 +165,7 @@ function getFocusables(container = document.body, options = {}) {
109
165
  composed = false,
110
166
  filter,
111
167
  include,
168
+ skipNegativeTabIndexCheck = false,
112
169
  skipVisibilityCheck = false
113
170
  } = options;
114
171
  if (typeof composed !== "boolean") {
@@ -127,11 +184,22 @@ function getFocusables(container = document.body, options = {}) {
127
184
  );
128
185
  include = void 0;
129
186
  }
187
+ if (typeof skipNegativeTabIndexCheck !== "boolean") {
188
+ console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
189
+ skipNegativeTabIndexCheck = false;
190
+ }
191
+ if (typeof skipVisibilityCheck !== "boolean") {
192
+ console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
193
+ skipVisibilityCheck = false;
194
+ }
130
195
  const elements = [];
131
196
  if (composed || include) {
132
197
  let traverse2 = function(node) {
133
198
  if (node instanceof Element) {
134
- if (isFocusable(node, { skipVisibilityCheck }) || include?.(node)) {
199
+ if (isFocusable(node, {
200
+ skipNegativeTabIndexCheck,
201
+ skipVisibilityCheck
202
+ }) || include?.(node)) {
135
203
  elements[elements.length] = node;
136
204
  }
137
205
  }
@@ -152,7 +220,10 @@ function getFocusables(container = document.body, options = {}) {
152
220
  if (!(candidate instanceof Element)) {
153
221
  continue;
154
222
  }
155
- if (isFocusable(candidate, { skipVisibilityCheck })) {
223
+ if (isFocusable(candidate, {
224
+ skipNegativeTabIndexCheck,
225
+ skipVisibilityCheck
226
+ })) {
156
227
  elements[elements.length] = candidate;
157
228
  }
158
229
  }
@@ -165,7 +236,11 @@ function isFocusable(element, options = {}) {
165
236
  console.warn("Invalid element");
166
237
  return false;
167
238
  }
168
- let { skipVisibilityCheck = false } = options;
239
+ let { skipNegativeTabIndexCheck = false, skipVisibilityCheck = false } = options;
240
+ if (typeof skipNegativeTabIndexCheck !== "boolean") {
241
+ console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
242
+ skipNegativeTabIndexCheck = false;
243
+ }
169
244
  if (typeof skipVisibilityCheck !== "boolean") {
170
245
  console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
171
246
  skipVisibilityCheck = false;
@@ -173,10 +248,12 @@ function isFocusable(element, options = {}) {
173
248
  if (element.hasAttribute("hidden") || isInert(element)) {
174
249
  return false;
175
250
  }
176
- if (getTabIndex(element) < 0) {
251
+ if (!skipNegativeTabIndexCheck && getTabIndex(element) < 0) {
177
252
  return false;
178
253
  }
179
- if (!element.matches(FOCUSABLE_SELECTOR)) {
254
+ if (!element.matches(
255
+ skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR.replace(/(,\s*)?\[tabindex="-1"\]/g, "") : FOCUSABLE_SELECTOR
256
+ )) {
180
257
  return false;
181
258
  }
182
259
  if (isDisabledDeep(element)) {
@@ -351,13 +428,14 @@ function createRovingTabIndex(container, options = {}) {
351
428
  console.warn("Invalid wrap option. Fallback: false.");
352
429
  wrap = false;
353
430
  }
354
- const roving = new RovingTabIndex(container, {
355
- direction,
356
- navigationOnly,
357
- selector,
358
- typeahead,
359
- wrap
360
- });
431
+ const settings = { navigationOnly, typeahead, wrap };
432
+ if (direction !== void 0) {
433
+ Object.assign(settings, { direction });
434
+ }
435
+ if (selector !== void 0) {
436
+ Object.assign(settings, { selector });
437
+ }
438
+ const roving = new RovingTabIndex(container, settings);
361
439
  return () => roving.destroy();
362
440
  }
363
441
  var RovingTabIndex = class {
@@ -399,8 +477,8 @@ var RovingTabIndex = class {
399
477
  if (!event.composedPath().includes(this.#container)) {
400
478
  return;
401
479
  }
402
- const { key, altKey, ctrlKey, metaKey } = event;
403
- if (altKey || ctrlKey || metaKey) {
480
+ const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
481
+ if (altKey || ctrlKey || metaKey || shiftKey) {
404
482
  return;
405
483
  }
406
484
  const { direction, typeahead, wrap } = this.#options;
@@ -416,7 +494,7 @@ var RovingTabIndex = class {
416
494
  return;
417
495
  }
418
496
  }
419
- const active = getActiveElement();
497
+ const active = getActiveElement2();
420
498
  if (!(active instanceof HTMLElement)) {
421
499
  return;
422
500
  }
@@ -463,14 +541,7 @@ var RovingTabIndex = class {
463
541
  focusElement(focusable);
464
542
  };
465
543
  #update(active) {
466
- const current = /* @__PURE__ */ new Set([
467
- ...this.#getFocusables(),
468
- ...getFocusables(this.#container, {
469
- composed: true,
470
- filter: this.#selectorFilter,
471
- skipVisibilityCheck: true
472
- })
473
- ]);
544
+ const current = new Set(this.#getFocusables());
474
545
  for (const focusable of this.#focusables) {
475
546
  if (current.has(focusable)) {
476
547
  continue;
@@ -534,15 +605,14 @@ var RovingTabIndex = class {
534
605
  return getFocusables(this.#container, {
535
606
  composed: true,
536
607
  filter: this.#selectorFilter,
537
- include: (element) => this.#focusables.has(element),
538
- skipVisibilityCheck: true
608
+ skipNegativeTabIndexCheck: !this.#options.navigationOnly
539
609
  });
540
610
  }
541
611
  };
542
612
  function focusElement(element) {
543
613
  "focus" in element && typeof element.focus === "function" && element.focus();
544
614
  }
545
- function getActiveElement() {
615
+ function getActiveElement2() {
546
616
  let current = document.activeElement;
547
617
  while (current?.shadowRoot?.activeElement) {
548
618
  current = current.shadowRoot.activeElement;
@@ -568,6 +638,7 @@ var Accordion = class _Accordion {
568
638
  #eventController = null;
569
639
  #animationController = null;
570
640
  #cleanupRovingTabIndex = null;
641
+ #buttons = [];
571
642
  #isDestroyed = false;
572
643
  constructor(root, options = {}) {
573
644
  if (!(root instanceof HTMLElement)) {
@@ -641,6 +712,10 @@ var Accordion = class _Accordion {
641
712
  this.#eventController = null;
642
713
  this.#cleanupRovingTabIndex?.();
643
714
  this.#cleanupRovingTabIndex = null;
715
+ this.#buttons.forEach((button) => {
716
+ button.destroy();
717
+ });
718
+ this.#buttons.length = 0;
644
719
  !force && await this.#waitAnimationsFinish();
645
720
  this.#contentElements.forEach((content) => {
646
721
  force && this.#bindings.get(content)?.animation?.finish();
@@ -683,12 +758,12 @@ var Accordion = class _Accordion {
683
758
  trigger2.style.setProperty("pointer-events", "none");
684
759
  }
685
760
  trigger2.addEventListener("click", this.#onTriggerClick, { signal });
686
- trigger2.addEventListener("keydown", this.#onTriggerKeyDown, { signal });
687
761
  addTokenToAttribute(content2, "aria-labelledby", trigger2.id);
688
762
  content2.setAttribute("role", "region");
689
763
  content2.addEventListener("beforematch", this.#onContentBeforeMatch, {
690
764
  signal
691
765
  });
766
+ this.#buttons.push(new Button(trigger2));
692
767
  });
693
768
  const { trigger, content } = this.#settings.selector;
694
769
  this.#cleanupRovingTabIndex = createRovingTabIndex(this.#rootElement, {
@@ -707,21 +782,6 @@ var Accordion = class _Accordion {
707
782
  }
708
783
  this.#toggle(trigger, trigger.ariaExpanded === "false");
709
784
  };
710
- #onTriggerKeyDown = (event) => {
711
- const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
712
- if (altKey || ctrlKey || metaKey || shiftKey) {
713
- return;
714
- }
715
- if (!["Enter", " "].includes(key)) {
716
- return;
717
- }
718
- const active = getActiveElement2();
719
- if (!(active instanceof HTMLElement)) {
720
- return;
721
- }
722
- event.preventDefault();
723
- active.click();
724
- };
725
785
  #onContentBeforeMatch = (event) => {
726
786
  const content = event.currentTarget;
727
787
  if (!(content instanceof HTMLElement)) {
@@ -818,13 +878,6 @@ var Accordion = class _Accordion {
818
878
  function createBinding(trigger, content) {
819
879
  return { trigger, content, animation: null };
820
880
  }
821
- function getActiveElement2() {
822
- let current = document.activeElement;
823
- while (current?.shadowRoot?.activeElement) {
824
- current = current.shadowRoot.activeElement;
825
- }
826
- return current;
827
- }
828
881
  function isFocusable2(element) {
829
882
  return !element.hasAttribute("disabled") && element.tabIndex >= 0;
830
883
  }
@@ -841,7 +894,7 @@ function waitAnimationFinish(animation) {
841
894
  * Accordion
842
895
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
843
896
  *
844
- * @version 1.3.3
897
+ * @version 1.4.1
845
898
  * @author Yusuke Kamiyamane
846
899
  * @license MIT
847
900
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -853,20 +906,31 @@ function waitAnimationFinish(animation) {
853
906
  (**
854
907
  * Attributes Utils
855
908
  *
856
- * @version 1.0.5
909
+ * @version 1.1.0
857
910
  * @author Yusuke Kamiyamane
858
911
  * @license MIT
859
912
  * @copyright Copyright (c) Yusuke Kamiyamane
860
913
  * @see {@link https://github.com/y14e/attributes-utils}
861
914
  *)
862
915
 
916
+ @y14e/button/dist/index.js:
917
+ (**
918
+ * Button
919
+ *
920
+ * @version 1.0.0
921
+ * @author Yusuke Kamiyamane
922
+ * @license MIT
923
+ * @copyright Copyright (c) Yusuke Kamiyamane
924
+ * @see {@link https://github.com/y14e/button}
925
+ *)
926
+
863
927
  @y14e/roving-tabindex/dist/index.js:
864
928
  (**
865
929
  * Roving Tabindex
866
930
  * Lightweight roving tabindex utility with fully focus management.
867
931
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
868
932
  *
869
- * @version 1.3.1
933
+ * @version 2.0.3
870
934
  * @author Yusuke Kamiyamane
871
935
  * @license MIT
872
936
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -878,7 +942,7 @@ function waitAnimationFinish(animation) {
878
942
  (**
879
943
  * Attributes Utils
880
944
  *
881
- * @version 1.0.5
945
+ * @version 1.1.0
882
946
  * @author Yusuke Kamiyamane
883
947
  * @license MIT
884
948
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -891,7 +955,7 @@ function waitAnimationFinish(animation) {
891
955
  * High-precision focus management utility with full composed tree support.
892
956
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
893
957
  *
894
- * @version 4.2.0
958
+ * @version 4.3.1
895
959
  * @author Yusuke Kamiyamane
896
960
  * @license MIT
897
961
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.cts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Accordion
3
3
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
4
4
  *
5
- * @version 1.3.3
5
+ * @version 1.4.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
  * Accordion
3
3
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
4
4
  *
5
- * @version 1.3.3
5
+ * @version 1.4.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(" ");
@@ -107,6 +163,7 @@ function getFocusables(container = document.body, options = {}) {
107
163
  composed = false,
108
164
  filter,
109
165
  include,
166
+ skipNegativeTabIndexCheck = false,
110
167
  skipVisibilityCheck = false
111
168
  } = options;
112
169
  if (typeof composed !== "boolean") {
@@ -125,11 +182,22 @@ function getFocusables(container = document.body, options = {}) {
125
182
  );
126
183
  include = void 0;
127
184
  }
185
+ if (typeof skipNegativeTabIndexCheck !== "boolean") {
186
+ console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
187
+ skipNegativeTabIndexCheck = false;
188
+ }
189
+ if (typeof skipVisibilityCheck !== "boolean") {
190
+ console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
191
+ skipVisibilityCheck = false;
192
+ }
128
193
  const elements = [];
129
194
  if (composed || include) {
130
195
  let traverse2 = function(node) {
131
196
  if (node instanceof Element) {
132
- if (isFocusable(node, { skipVisibilityCheck }) || include?.(node)) {
197
+ if (isFocusable(node, {
198
+ skipNegativeTabIndexCheck,
199
+ skipVisibilityCheck
200
+ }) || include?.(node)) {
133
201
  elements[elements.length] = node;
134
202
  }
135
203
  }
@@ -150,7 +218,10 @@ function getFocusables(container = document.body, options = {}) {
150
218
  if (!(candidate instanceof Element)) {
151
219
  continue;
152
220
  }
153
- if (isFocusable(candidate, { skipVisibilityCheck })) {
221
+ if (isFocusable(candidate, {
222
+ skipNegativeTabIndexCheck,
223
+ skipVisibilityCheck
224
+ })) {
154
225
  elements[elements.length] = candidate;
155
226
  }
156
227
  }
@@ -163,7 +234,11 @@ function isFocusable(element, options = {}) {
163
234
  console.warn("Invalid element");
164
235
  return false;
165
236
  }
166
- let { skipVisibilityCheck = false } = options;
237
+ let { skipNegativeTabIndexCheck = false, skipVisibilityCheck = false } = options;
238
+ if (typeof skipNegativeTabIndexCheck !== "boolean") {
239
+ console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
240
+ skipNegativeTabIndexCheck = false;
241
+ }
167
242
  if (typeof skipVisibilityCheck !== "boolean") {
168
243
  console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
169
244
  skipVisibilityCheck = false;
@@ -171,10 +246,12 @@ function isFocusable(element, options = {}) {
171
246
  if (element.hasAttribute("hidden") || isInert(element)) {
172
247
  return false;
173
248
  }
174
- if (getTabIndex(element) < 0) {
249
+ if (!skipNegativeTabIndexCheck && getTabIndex(element) < 0) {
175
250
  return false;
176
251
  }
177
- if (!element.matches(FOCUSABLE_SELECTOR)) {
252
+ if (!element.matches(
253
+ skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR.replace(/(,\s*)?\[tabindex="-1"\]/g, "") : FOCUSABLE_SELECTOR
254
+ )) {
178
255
  return false;
179
256
  }
180
257
  if (isDisabledDeep(element)) {
@@ -349,13 +426,14 @@ function createRovingTabIndex(container, options = {}) {
349
426
  console.warn("Invalid wrap option. Fallback: false.");
350
427
  wrap = false;
351
428
  }
352
- const roving = new RovingTabIndex(container, {
353
- direction,
354
- navigationOnly,
355
- selector,
356
- typeahead,
357
- wrap
358
- });
429
+ const settings = { navigationOnly, typeahead, wrap };
430
+ if (direction !== void 0) {
431
+ Object.assign(settings, { direction });
432
+ }
433
+ if (selector !== void 0) {
434
+ Object.assign(settings, { selector });
435
+ }
436
+ const roving = new RovingTabIndex(container, settings);
359
437
  return () => roving.destroy();
360
438
  }
361
439
  var RovingTabIndex = class {
@@ -397,8 +475,8 @@ var RovingTabIndex = class {
397
475
  if (!event.composedPath().includes(this.#container)) {
398
476
  return;
399
477
  }
400
- const { key, altKey, ctrlKey, metaKey } = event;
401
- if (altKey || ctrlKey || metaKey) {
478
+ const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
479
+ if (altKey || ctrlKey || metaKey || shiftKey) {
402
480
  return;
403
481
  }
404
482
  const { direction, typeahead, wrap } = this.#options;
@@ -414,7 +492,7 @@ var RovingTabIndex = class {
414
492
  return;
415
493
  }
416
494
  }
417
- const active = getActiveElement();
495
+ const active = getActiveElement2();
418
496
  if (!(active instanceof HTMLElement)) {
419
497
  return;
420
498
  }
@@ -461,14 +539,7 @@ var RovingTabIndex = class {
461
539
  focusElement(focusable);
462
540
  };
463
541
  #update(active) {
464
- const current = /* @__PURE__ */ new Set([
465
- ...this.#getFocusables(),
466
- ...getFocusables(this.#container, {
467
- composed: true,
468
- filter: this.#selectorFilter,
469
- skipVisibilityCheck: true
470
- })
471
- ]);
542
+ const current = new Set(this.#getFocusables());
472
543
  for (const focusable of this.#focusables) {
473
544
  if (current.has(focusable)) {
474
545
  continue;
@@ -532,15 +603,14 @@ var RovingTabIndex = class {
532
603
  return getFocusables(this.#container, {
533
604
  composed: true,
534
605
  filter: this.#selectorFilter,
535
- include: (element) => this.#focusables.has(element),
536
- skipVisibilityCheck: true
606
+ skipNegativeTabIndexCheck: !this.#options.navigationOnly
537
607
  });
538
608
  }
539
609
  };
540
610
  function focusElement(element) {
541
611
  "focus" in element && typeof element.focus === "function" && element.focus();
542
612
  }
543
- function getActiveElement() {
613
+ function getActiveElement2() {
544
614
  let current = document.activeElement;
545
615
  while (current?.shadowRoot?.activeElement) {
546
616
  current = current.shadowRoot.activeElement;
@@ -566,6 +636,7 @@ var Accordion = class _Accordion {
566
636
  #eventController = null;
567
637
  #animationController = null;
568
638
  #cleanupRovingTabIndex = null;
639
+ #buttons = [];
569
640
  #isDestroyed = false;
570
641
  constructor(root, options = {}) {
571
642
  if (!(root instanceof HTMLElement)) {
@@ -639,6 +710,10 @@ var Accordion = class _Accordion {
639
710
  this.#eventController = null;
640
711
  this.#cleanupRovingTabIndex?.();
641
712
  this.#cleanupRovingTabIndex = null;
713
+ this.#buttons.forEach((button) => {
714
+ button.destroy();
715
+ });
716
+ this.#buttons.length = 0;
642
717
  !force && await this.#waitAnimationsFinish();
643
718
  this.#contentElements.forEach((content) => {
644
719
  force && this.#bindings.get(content)?.animation?.finish();
@@ -681,12 +756,12 @@ var Accordion = class _Accordion {
681
756
  trigger2.style.setProperty("pointer-events", "none");
682
757
  }
683
758
  trigger2.addEventListener("click", this.#onTriggerClick, { signal });
684
- trigger2.addEventListener("keydown", this.#onTriggerKeyDown, { signal });
685
759
  addTokenToAttribute(content2, "aria-labelledby", trigger2.id);
686
760
  content2.setAttribute("role", "region");
687
761
  content2.addEventListener("beforematch", this.#onContentBeforeMatch, {
688
762
  signal
689
763
  });
764
+ this.#buttons.push(new Button(trigger2));
690
765
  });
691
766
  const { trigger, content } = this.#settings.selector;
692
767
  this.#cleanupRovingTabIndex = createRovingTabIndex(this.#rootElement, {
@@ -705,21 +780,6 @@ var Accordion = class _Accordion {
705
780
  }
706
781
  this.#toggle(trigger, trigger.ariaExpanded === "false");
707
782
  };
708
- #onTriggerKeyDown = (event) => {
709
- const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
710
- if (altKey || ctrlKey || metaKey || shiftKey) {
711
- return;
712
- }
713
- if (!["Enter", " "].includes(key)) {
714
- return;
715
- }
716
- const active = getActiveElement2();
717
- if (!(active instanceof HTMLElement)) {
718
- return;
719
- }
720
- event.preventDefault();
721
- active.click();
722
- };
723
783
  #onContentBeforeMatch = (event) => {
724
784
  const content = event.currentTarget;
725
785
  if (!(content instanceof HTMLElement)) {
@@ -816,13 +876,6 @@ var Accordion = class _Accordion {
816
876
  function createBinding(trigger, content) {
817
877
  return { trigger, content, animation: null };
818
878
  }
819
- function getActiveElement2() {
820
- let current = document.activeElement;
821
- while (current?.shadowRoot?.activeElement) {
822
- current = current.shadowRoot.activeElement;
823
- }
824
- return current;
825
- }
826
879
  function isFocusable2(element) {
827
880
  return !element.hasAttribute("disabled") && element.tabIndex >= 0;
828
881
  }
@@ -839,7 +892,7 @@ function waitAnimationFinish(animation) {
839
892
  * Accordion
840
893
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
841
894
  *
842
- * @version 1.3.3
895
+ * @version 1.4.1
843
896
  * @author Yusuke Kamiyamane
844
897
  * @license MIT
845
898
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -851,20 +904,31 @@ function waitAnimationFinish(animation) {
851
904
  (**
852
905
  * Attributes Utils
853
906
  *
854
- * @version 1.0.5
907
+ * @version 1.1.0
855
908
  * @author Yusuke Kamiyamane
856
909
  * @license MIT
857
910
  * @copyright Copyright (c) Yusuke Kamiyamane
858
911
  * @see {@link https://github.com/y14e/attributes-utils}
859
912
  *)
860
913
 
914
+ @y14e/button/dist/index.js:
915
+ (**
916
+ * Button
917
+ *
918
+ * @version 1.0.0
919
+ * @author Yusuke Kamiyamane
920
+ * @license MIT
921
+ * @copyright Copyright (c) Yusuke Kamiyamane
922
+ * @see {@link https://github.com/y14e/button}
923
+ *)
924
+
861
925
  @y14e/roving-tabindex/dist/index.js:
862
926
  (**
863
927
  * Roving Tabindex
864
928
  * Lightweight roving tabindex utility with fully focus management.
865
929
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
866
930
  *
867
- * @version 1.3.1
931
+ * @version 2.0.3
868
932
  * @author Yusuke Kamiyamane
869
933
  * @license MIT
870
934
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -876,7 +940,7 @@ function waitAnimationFinish(animation) {
876
940
  (**
877
941
  * Attributes Utils
878
942
  *
879
- * @version 1.0.5
943
+ * @version 1.1.0
880
944
  * @author Yusuke Kamiyamane
881
945
  * @license MIT
882
946
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -889,7 +953,7 @@ function waitAnimationFinish(animation) {
889
953
  * High-precision focus management utility with full composed tree support.
890
954
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
891
955
  *
892
- * @version 4.2.0
956
+ * @version 4.3.1
893
957
  * @author Yusuke Kamiyamane
894
958
  * @license MIT
895
959
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/accordion",
3
- "version": "1.3.3",
3
+ "version": "1.4.1",
4
4
  "description": "WAI-ARIA compliant accordion pattern implementation in TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -43,8 +43,9 @@
43
43
  },
44
44
  "homepage": "https://github.com/y14e/accordion#readme",
45
45
  "devDependencies": {
46
- "@y14e/attributes-utils": "^1.0.5",
47
- "@y14e/roving-tabindex": "^1.3.1",
46
+ "@y14e/attributes-utils": "^1.1.0",
47
+ "@y14e/button": "^1.0.0",
48
+ "@y14e/roving-tabindex": "^2.0.3",
48
49
  "bun-types": "latest",
49
50
  "tsup": "^8.0.0",
50
51
  "typescript": "^5.6.0",