@y14e/accordion 1.4.16 → 1.4.18

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@1.4.16';
13
+ import Accordion from '@y14e/accordion';
14
14
 
15
15
  // CDNs
16
- import Accordion from 'https://esm.sh/@y14e/accordion@1.4.16';
16
+ import Accordion from 'https://esm.sh/@y14e/accordion@1.4.18';
17
17
  // or
18
- import Accordion from 'https://cdn.jsdelivr.net/npm/@y14e/accordion@1.4.16/+esm';
18
+ import Accordion from 'https://cdn.jsdelivr.net/npm/@y14e/accordion@1.4.18/+esm';
19
19
  // or
20
- import Accordion from 'https://esm.unpkg.com/@y14e/accordion@1.4.16';
20
+ import Accordion from 'https://esm.unpkg.com/@y14e/accordion@1.4.18';
21
21
  ```
22
22
 
23
23
  ## Usage
@@ -343,8 +343,14 @@ function createRovingTabIndex(container, options = {}) {
343
343
  return () => {
344
344
  };
345
345
  }
346
- const roving = new RovingTabIndex(container, options);
347
- return () => roving.destroy();
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(document.activeElement);
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
- this.#container.addEventListener("focusin", this.#onFocusIn, {
430
- capture: true,
431
- signal
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 isFocusable3 = this.#focusables.has(target);
444
- this.#settings.noMemory && !isFocusable3 ? this.#update(null) : isFocusable3 && this.#update(target);
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;
@@ -633,7 +639,7 @@ var Accordion = class _Accordion {
633
639
  if (!content2) {
634
640
  return;
635
641
  }
636
- const binding = createBinding(trigger2, content2);
642
+ const binding = this.#createBinding(trigger2, content2);
637
643
  this.#bindings.set(trigger2, binding);
638
644
  this.#bindings.set(content2, binding);
639
645
  });
@@ -665,7 +671,7 @@ var Accordion = class _Accordion {
665
671
  !force && await this.#waitAnimationsFinish();
666
672
  this.#contentElements.forEach((content) => {
667
673
  force && this.#bindings.get(content)?.animation?.finish();
668
- this.#onAnimationFinish(content);
674
+ this.#onContentAnimationFinish(content);
669
675
  });
670
676
  this.#animationController?.abort();
671
677
  this.#animationController = null;
@@ -708,7 +714,7 @@ var Accordion = class _Accordion {
708
714
  String(trigger2.ariaExpanded === "true")
709
715
  );
710
716
  trigger2.id ||= `accordion-trigger-${id}`;
711
- if (!isFocusable2(trigger2)) {
717
+ if (!this.#isFocusable(trigger2)) {
712
718
  trigger2.setAttribute("aria-disabled", "true");
713
719
  trigger2.setAttribute("tabindex", "-1");
714
720
  trigger2.style.setProperty("pointer-events", "none");
@@ -738,6 +744,16 @@ var Accordion = class _Accordion {
738
744
  }
739
745
  this.#toggle(trigger, trigger.ariaExpanded === "false");
740
746
  };
747
+ #onContentAnimationFinish(content) {
748
+ const trigger = this.#bindings.get(content)?.trigger;
749
+ if (!trigger) {
750
+ return;
751
+ }
752
+ trigger.ariaExpanded === "false" && content.setAttribute("hidden", "until-found");
753
+ ["block-size", "overflow"].forEach((name) => {
754
+ content.style.removeProperty(name);
755
+ });
756
+ }
741
757
  #onContentBeforeMatch = (event) => {
742
758
  const content = event.currentTarget;
743
759
  if (!(content instanceof HTMLElement)) {
@@ -755,10 +771,10 @@ var Accordion = class _Accordion {
755
771
  }
756
772
  const name = trigger.getAttribute("data-accordion-name");
757
773
  if (name && isOpen) {
758
- const opened = this.#triggerElements.find(
774
+ const open = this.#triggerElements.find(
759
775
  (t) => t !== trigger && t.getAttribute("data-accordion-name") === name && t.ariaExpanded === "true"
760
776
  );
761
- opened && this.#toggle(opened, false, isMatch);
777
+ open && this.#toggle(open, false, isMatch);
762
778
  }
763
779
  trigger.setAttribute(
764
780
  "aria-label",
@@ -797,31 +813,25 @@ var Accordion = class _Accordion {
797
813
  "finish",
798
814
  () => {
799
815
  if (binding?.animation === animation) {
800
- this.#onAnimationFinish(content);
816
+ this.#onContentAnimationFinish(content);
801
817
  cleanup();
802
818
  }
803
819
  },
804
820
  { once: true, signal }
805
821
  );
806
822
  }
823
+ #createBinding(trigger, content) {
824
+ return { trigger, content, animation: null };
825
+ }
826
+ #isFocusable(element) {
827
+ return !element.hasAttribute("disabled") && element.tabIndex >= 0;
828
+ }
807
829
  #mergeOptions(target, source) {
808
830
  return {
809
831
  animation: { ...target.animation, ...source.animation ?? {} },
810
832
  selector: { ...target.selector, ...source.selector ?? {} }
811
833
  };
812
834
  }
813
- #onAnimationFinish(content) {
814
- const trigger = this.#bindings.get(content)?.trigger;
815
- if (!trigger) {
816
- return;
817
- }
818
- if (trigger.ariaExpanded === "false") {
819
- content.setAttribute("hidden", "until-found");
820
- }
821
- ["block-size", "overflow"].forEach((name) => {
822
- content.style.removeProperty(name);
823
- });
824
- }
825
835
  async #waitAnimationsFinish() {
826
836
  const promises = [];
827
837
  this.#contentElements.forEach((content) => {
@@ -831,26 +841,16 @@ var Accordion = class _Accordion {
831
841
  await Promise.allSettled(promises);
832
842
  }
833
843
  };
834
- function createBinding(trigger, content) {
835
- return { trigger, content, animation: null };
836
- }
837
- function isFocusable2(element) {
838
- return !element.hasAttribute("disabled") && element.tabIndex >= 0;
839
- }
840
844
  function waitAnimationFinish(animation) {
841
- if (["idle", "finished"].includes(animation.playState)) {
842
- return Promise.resolve();
843
- } else {
844
- return new Promise(
845
- (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
846
- );
847
- }
845
+ return ["idle", "finished"].includes(animation.playState) ? Promise.resolve() : new Promise(
846
+ (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
847
+ );
848
848
  }
849
849
  /**
850
850
  * Accordion
851
851
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
852
852
  *
853
- * @version 1.4.16
853
+ * @version 1.4.18
854
854
  * @author Yusuke Kamiyamane
855
855
  * @license MIT
856
856
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -875,7 +875,7 @@ power-focusable/dist/index.js:
875
875
  * High-precision focus management utility with full composed tree support.
876
876
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
877
877
  *
878
- * @version 4.3.3
878
+ * @version 4.3.5
879
879
  * @author Yusuke Kamiyamane
880
880
  * @license MIT
881
881
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -899,7 +899,7 @@ power-focusable/dist/index.js:
899
899
  * Lightweight roving tabindex utility with fully focus management.
900
900
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
901
901
  *
902
- * @version 3.0.12
902
+ * @version 3.1.2
903
903
  * @author Yusuke Kamiyamane
904
904
  * @license MIT
905
905
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -341,8 +341,14 @@ function createRovingTabIndex(container, options = {}) {
341
341
  return () => {
342
342
  };
343
343
  }
344
- const roving = new RovingTabIndex(container, options);
345
- return () => roving.destroy();
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(document.activeElement);
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
- this.#container.addEventListener("focusin", this.#onFocusIn, {
428
- capture: true,
429
- signal
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 isFocusable3 = this.#focusables.has(target);
442
- this.#settings.noMemory && !isFocusable3 ? this.#update(null) : isFocusable3 && this.#update(target);
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;
@@ -631,7 +637,7 @@ var Accordion = class _Accordion {
631
637
  if (!content2) {
632
638
  return;
633
639
  }
634
- const binding = createBinding(trigger2, content2);
640
+ const binding = this.#createBinding(trigger2, content2);
635
641
  this.#bindings.set(trigger2, binding);
636
642
  this.#bindings.set(content2, binding);
637
643
  });
@@ -663,7 +669,7 @@ var Accordion = class _Accordion {
663
669
  !force && await this.#waitAnimationsFinish();
664
670
  this.#contentElements.forEach((content) => {
665
671
  force && this.#bindings.get(content)?.animation?.finish();
666
- this.#onAnimationFinish(content);
672
+ this.#onContentAnimationFinish(content);
667
673
  });
668
674
  this.#animationController?.abort();
669
675
  this.#animationController = null;
@@ -706,7 +712,7 @@ var Accordion = class _Accordion {
706
712
  String(trigger2.ariaExpanded === "true")
707
713
  );
708
714
  trigger2.id ||= `accordion-trigger-${id}`;
709
- if (!isFocusable2(trigger2)) {
715
+ if (!this.#isFocusable(trigger2)) {
710
716
  trigger2.setAttribute("aria-disabled", "true");
711
717
  trigger2.setAttribute("tabindex", "-1");
712
718
  trigger2.style.setProperty("pointer-events", "none");
@@ -736,6 +742,16 @@ var Accordion = class _Accordion {
736
742
  }
737
743
  this.#toggle(trigger, trigger.ariaExpanded === "false");
738
744
  };
745
+ #onContentAnimationFinish(content) {
746
+ const trigger = this.#bindings.get(content)?.trigger;
747
+ if (!trigger) {
748
+ return;
749
+ }
750
+ trigger.ariaExpanded === "false" && content.setAttribute("hidden", "until-found");
751
+ ["block-size", "overflow"].forEach((name) => {
752
+ content.style.removeProperty(name);
753
+ });
754
+ }
739
755
  #onContentBeforeMatch = (event) => {
740
756
  const content = event.currentTarget;
741
757
  if (!(content instanceof HTMLElement)) {
@@ -753,10 +769,10 @@ var Accordion = class _Accordion {
753
769
  }
754
770
  const name = trigger.getAttribute("data-accordion-name");
755
771
  if (name && isOpen) {
756
- const opened = this.#triggerElements.find(
772
+ const open = this.#triggerElements.find(
757
773
  (t) => t !== trigger && t.getAttribute("data-accordion-name") === name && t.ariaExpanded === "true"
758
774
  );
759
- opened && this.#toggle(opened, false, isMatch);
775
+ open && this.#toggle(open, false, isMatch);
760
776
  }
761
777
  trigger.setAttribute(
762
778
  "aria-label",
@@ -795,31 +811,25 @@ var Accordion = class _Accordion {
795
811
  "finish",
796
812
  () => {
797
813
  if (binding?.animation === animation) {
798
- this.#onAnimationFinish(content);
814
+ this.#onContentAnimationFinish(content);
799
815
  cleanup();
800
816
  }
801
817
  },
802
818
  { once: true, signal }
803
819
  );
804
820
  }
821
+ #createBinding(trigger, content) {
822
+ return { trigger, content, animation: null };
823
+ }
824
+ #isFocusable(element) {
825
+ return !element.hasAttribute("disabled") && element.tabIndex >= 0;
826
+ }
805
827
  #mergeOptions(target, source) {
806
828
  return {
807
829
  animation: { ...target.animation, ...source.animation ?? {} },
808
830
  selector: { ...target.selector, ...source.selector ?? {} }
809
831
  };
810
832
  }
811
- #onAnimationFinish(content) {
812
- const trigger = this.#bindings.get(content)?.trigger;
813
- if (!trigger) {
814
- return;
815
- }
816
- if (trigger.ariaExpanded === "false") {
817
- content.setAttribute("hidden", "until-found");
818
- }
819
- ["block-size", "overflow"].forEach((name) => {
820
- content.style.removeProperty(name);
821
- });
822
- }
823
833
  async #waitAnimationsFinish() {
824
834
  const promises = [];
825
835
  this.#contentElements.forEach((content) => {
@@ -829,26 +839,16 @@ var Accordion = class _Accordion {
829
839
  await Promise.allSettled(promises);
830
840
  }
831
841
  };
832
- function createBinding(trigger, content) {
833
- return { trigger, content, animation: null };
834
- }
835
- function isFocusable2(element) {
836
- return !element.hasAttribute("disabled") && element.tabIndex >= 0;
837
- }
838
842
  function waitAnimationFinish(animation) {
839
- if (["idle", "finished"].includes(animation.playState)) {
840
- return Promise.resolve();
841
- } else {
842
- return new Promise(
843
- (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
844
- );
845
- }
843
+ return ["idle", "finished"].includes(animation.playState) ? Promise.resolve() : new Promise(
844
+ (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
845
+ );
846
846
  }
847
847
  /**
848
848
  * Accordion
849
849
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
850
850
  *
851
- * @version 1.4.16
851
+ * @version 1.4.18
852
852
  * @author Yusuke Kamiyamane
853
853
  * @license MIT
854
854
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -873,7 +873,7 @@ power-focusable/dist/index.js:
873
873
  * High-precision focus management utility with full composed tree support.
874
874
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
875
875
  *
876
- * @version 4.3.3
876
+ * @version 4.3.5
877
877
  * @author Yusuke Kamiyamane
878
878
  * @license MIT
879
879
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -897,7 +897,7 @@ power-focusable/dist/index.js:
897
897
  * Lightweight roving tabindex utility with fully focus management.
898
898
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
899
899
  *
900
- * @version 3.0.12
900
+ * @version 3.1.2
901
901
  * @author Yusuke Kamiyamane
902
902
  * @license MIT
903
903
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.cjs CHANGED
@@ -65,7 +65,7 @@ var Accordion = class _Accordion {
65
65
  if (!content2) {
66
66
  return;
67
67
  }
68
- const binding = createBinding(trigger2, content2);
68
+ const binding = this.#createBinding(trigger2, content2);
69
69
  this.#bindings.set(trigger2, binding);
70
70
  this.#bindings.set(content2, binding);
71
71
  });
@@ -97,7 +97,7 @@ var Accordion = class _Accordion {
97
97
  !force && await this.#waitAnimationsFinish();
98
98
  this.#contentElements.forEach((content) => {
99
99
  force && this.#bindings.get(content)?.animation?.finish();
100
- this.#onAnimationFinish(content);
100
+ this.#onContentAnimationFinish(content);
101
101
  });
102
102
  this.#animationController?.abort();
103
103
  this.#animationController = null;
@@ -140,7 +140,7 @@ var Accordion = class _Accordion {
140
140
  String(trigger2.ariaExpanded === "true")
141
141
  );
142
142
  trigger2.id ||= `accordion-trigger-${id}`;
143
- if (!isFocusable(trigger2)) {
143
+ if (!this.#isFocusable(trigger2)) {
144
144
  trigger2.setAttribute("aria-disabled", "true");
145
145
  trigger2.setAttribute("tabindex", "-1");
146
146
  trigger2.style.setProperty("pointer-events", "none");
@@ -170,6 +170,16 @@ var Accordion = class _Accordion {
170
170
  }
171
171
  this.#toggle(trigger, trigger.ariaExpanded === "false");
172
172
  };
173
+ #onContentAnimationFinish(content) {
174
+ const trigger = this.#bindings.get(content)?.trigger;
175
+ if (!trigger) {
176
+ return;
177
+ }
178
+ trigger.ariaExpanded === "false" && content.setAttribute("hidden", "until-found");
179
+ ["block-size", "overflow"].forEach((name) => {
180
+ content.style.removeProperty(name);
181
+ });
182
+ }
173
183
  #onContentBeforeMatch = (event) => {
174
184
  const content = event.currentTarget;
175
185
  if (!(content instanceof HTMLElement)) {
@@ -187,10 +197,10 @@ var Accordion = class _Accordion {
187
197
  }
188
198
  const name = trigger.getAttribute("data-accordion-name");
189
199
  if (name && isOpen) {
190
- const opened = this.#triggerElements.find(
200
+ const open = this.#triggerElements.find(
191
201
  (t) => t !== trigger && t.getAttribute("data-accordion-name") === name && t.ariaExpanded === "true"
192
202
  );
193
- opened && this.#toggle(opened, false, isMatch);
203
+ open && this.#toggle(open, false, isMatch);
194
204
  }
195
205
  trigger.setAttribute(
196
206
  "aria-label",
@@ -229,31 +239,25 @@ var Accordion = class _Accordion {
229
239
  "finish",
230
240
  () => {
231
241
  if (binding?.animation === animation) {
232
- this.#onAnimationFinish(content);
242
+ this.#onContentAnimationFinish(content);
233
243
  cleanup();
234
244
  }
235
245
  },
236
246
  { once: true, signal }
237
247
  );
238
248
  }
249
+ #createBinding(trigger, content) {
250
+ return { trigger, content, animation: null };
251
+ }
252
+ #isFocusable(element) {
253
+ return !element.hasAttribute("disabled") && element.tabIndex >= 0;
254
+ }
239
255
  #mergeOptions(target, source) {
240
256
  return {
241
257
  animation: { ...target.animation, ...source.animation ?? {} },
242
258
  selector: { ...target.selector, ...source.selector ?? {} }
243
259
  };
244
260
  }
245
- #onAnimationFinish(content) {
246
- const trigger = this.#bindings.get(content)?.trigger;
247
- if (!trigger) {
248
- return;
249
- }
250
- if (trigger.ariaExpanded === "false") {
251
- content.setAttribute("hidden", "until-found");
252
- }
253
- ["block-size", "overflow"].forEach((name) => {
254
- content.style.removeProperty(name);
255
- });
256
- }
257
261
  async #waitAnimationsFinish() {
258
262
  const promises = [];
259
263
  this.#contentElements.forEach((content) => {
@@ -263,26 +267,16 @@ var Accordion = class _Accordion {
263
267
  await Promise.allSettled(promises);
264
268
  }
265
269
  };
266
- function createBinding(trigger, content) {
267
- return { trigger, content, animation: null };
268
- }
269
- function isFocusable(element) {
270
- return !element.hasAttribute("disabled") && element.tabIndex >= 0;
271
- }
272
270
  function waitAnimationFinish(animation) {
273
- if (["idle", "finished"].includes(animation.playState)) {
274
- return Promise.resolve();
275
- } else {
276
- return new Promise(
277
- (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
278
- );
279
- }
271
+ return ["idle", "finished"].includes(animation.playState) ? Promise.resolve() : new Promise(
272
+ (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
273
+ );
280
274
  }
281
275
  /**
282
276
  * Accordion
283
277
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
284
278
  *
285
- * @version 1.4.16
279
+ * @version 1.4.18
286
280
  * @author Yusuke Kamiyamane
287
281
  * @license MIT
288
282
  * @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.4.16
5
+ * @version 1.4.18
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.4.16
5
+ * @version 1.4.18
6
6
  * @author Yusuke Kamiyamane
7
7
  * @license MIT
8
8
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -59,7 +59,7 @@ var Accordion = class _Accordion {
59
59
  if (!content2) {
60
60
  return;
61
61
  }
62
- const binding = createBinding(trigger2, content2);
62
+ const binding = this.#createBinding(trigger2, content2);
63
63
  this.#bindings.set(trigger2, binding);
64
64
  this.#bindings.set(content2, binding);
65
65
  });
@@ -91,7 +91,7 @@ var Accordion = class _Accordion {
91
91
  !force && await this.#waitAnimationsFinish();
92
92
  this.#contentElements.forEach((content) => {
93
93
  force && this.#bindings.get(content)?.animation?.finish();
94
- this.#onAnimationFinish(content);
94
+ this.#onContentAnimationFinish(content);
95
95
  });
96
96
  this.#animationController?.abort();
97
97
  this.#animationController = null;
@@ -134,7 +134,7 @@ var Accordion = class _Accordion {
134
134
  String(trigger2.ariaExpanded === "true")
135
135
  );
136
136
  trigger2.id ||= `accordion-trigger-${id}`;
137
- if (!isFocusable(trigger2)) {
137
+ if (!this.#isFocusable(trigger2)) {
138
138
  trigger2.setAttribute("aria-disabled", "true");
139
139
  trigger2.setAttribute("tabindex", "-1");
140
140
  trigger2.style.setProperty("pointer-events", "none");
@@ -164,6 +164,16 @@ var Accordion = class _Accordion {
164
164
  }
165
165
  this.#toggle(trigger, trigger.ariaExpanded === "false");
166
166
  };
167
+ #onContentAnimationFinish(content) {
168
+ const trigger = this.#bindings.get(content)?.trigger;
169
+ if (!trigger) {
170
+ return;
171
+ }
172
+ trigger.ariaExpanded === "false" && content.setAttribute("hidden", "until-found");
173
+ ["block-size", "overflow"].forEach((name) => {
174
+ content.style.removeProperty(name);
175
+ });
176
+ }
167
177
  #onContentBeforeMatch = (event) => {
168
178
  const content = event.currentTarget;
169
179
  if (!(content instanceof HTMLElement)) {
@@ -181,10 +191,10 @@ var Accordion = class _Accordion {
181
191
  }
182
192
  const name = trigger.getAttribute("data-accordion-name");
183
193
  if (name && isOpen) {
184
- const opened = this.#triggerElements.find(
194
+ const open = this.#triggerElements.find(
185
195
  (t) => t !== trigger && t.getAttribute("data-accordion-name") === name && t.ariaExpanded === "true"
186
196
  );
187
- opened && this.#toggle(opened, false, isMatch);
197
+ open && this.#toggle(open, false, isMatch);
188
198
  }
189
199
  trigger.setAttribute(
190
200
  "aria-label",
@@ -223,31 +233,25 @@ var Accordion = class _Accordion {
223
233
  "finish",
224
234
  () => {
225
235
  if (binding?.animation === animation) {
226
- this.#onAnimationFinish(content);
236
+ this.#onContentAnimationFinish(content);
227
237
  cleanup();
228
238
  }
229
239
  },
230
240
  { once: true, signal }
231
241
  );
232
242
  }
243
+ #createBinding(trigger, content) {
244
+ return { trigger, content, animation: null };
245
+ }
246
+ #isFocusable(element) {
247
+ return !element.hasAttribute("disabled") && element.tabIndex >= 0;
248
+ }
233
249
  #mergeOptions(target, source) {
234
250
  return {
235
251
  animation: { ...target.animation, ...source.animation ?? {} },
236
252
  selector: { ...target.selector, ...source.selector ?? {} }
237
253
  };
238
254
  }
239
- #onAnimationFinish(content) {
240
- const trigger = this.#bindings.get(content)?.trigger;
241
- if (!trigger) {
242
- return;
243
- }
244
- if (trigger.ariaExpanded === "false") {
245
- content.setAttribute("hidden", "until-found");
246
- }
247
- ["block-size", "overflow"].forEach((name) => {
248
- content.style.removeProperty(name);
249
- });
250
- }
251
255
  async #waitAnimationsFinish() {
252
256
  const promises = [];
253
257
  this.#contentElements.forEach((content) => {
@@ -257,26 +261,16 @@ var Accordion = class _Accordion {
257
261
  await Promise.allSettled(promises);
258
262
  }
259
263
  };
260
- function createBinding(trigger, content) {
261
- return { trigger, content, animation: null };
262
- }
263
- function isFocusable(element) {
264
- return !element.hasAttribute("disabled") && element.tabIndex >= 0;
265
- }
266
264
  function waitAnimationFinish(animation) {
267
- if (["idle", "finished"].includes(animation.playState)) {
268
- return Promise.resolve();
269
- } else {
270
- return new Promise(
271
- (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
272
- );
273
- }
265
+ return ["idle", "finished"].includes(animation.playState) ? Promise.resolve() : new Promise(
266
+ (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
267
+ );
274
268
  }
275
269
  /**
276
270
  * Accordion
277
271
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
278
272
  *
279
- * @version 1.4.16
273
+ * @version 1.4.18
280
274
  * @author Yusuke Kamiyamane
281
275
  * @license MIT
282
276
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/accordion",
3
- "version": "1.4.16",
3
+ "version": "1.4.18",
4
4
  "description": "WAI-ARIA compliant accordion pattern implementation in TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -54,6 +54,6 @@
54
54
  "dependencies": {
55
55
  "@y14e/attributes-utils": "^1.1.2",
56
56
  "@y14e/button": "^1.0.6",
57
- "@y14e/roving-tabindex": "^3.0.12"
57
+ "@y14e/roving-tabindex": "^3.1.2"
58
58
  }
59
59
  }