@y14e/disclosure 1.3.17 → 1.3.19

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/disclosure
10
10
 
11
11
  ```ts
12
12
  // npm
13
- import Disclosure from '@y14e/disclosure@1.3.17';
13
+ import Disclosure from '@y14e/disclosure@1.3.19';
14
14
 
15
15
  // CDNs
16
- import Disclosure from 'https://esm.sh/@y14e/disclosure@1.3.17';
16
+ import Disclosure from 'https://esm.sh/@y14e/disclosure@1.3.19';
17
17
  // or
18
- import Disclosure from 'https://cdn.jsdelivr.net/npm/@y14e/disclosure@1.3.17/+esm';
18
+ import Disclosure from 'https://cdn.jsdelivr.net/npm/@y14e/disclosure@1.3.19/+esm';
19
19
  // or
20
- import Disclosure from 'https://esm.unpkg.com/@y14e/disclosure@1.3.17';
20
+ import Disclosure from 'https://esm.unpkg.com/@y14e/disclosure@1.3.19';
21
21
  ```
22
22
 
23
23
  ## Usage
@@ -294,8 +294,14 @@ function createRovingTabIndex(container, options = {}) {
294
294
  return () => {
295
295
  };
296
296
  }
297
- const roving = new RovingTabIndex(container, options);
298
- return () => roving.destroy();
297
+ try {
298
+ const roving = new RovingTabIndex(container, options);
299
+ return () => roving.destroy();
300
+ } catch (error) {
301
+ error instanceof Error && console.warn(error.message || error);
302
+ return () => {
303
+ };
304
+ }
299
305
  }
300
306
  var RovingTabIndex = class _RovingTabIndex {
301
307
  static #initialized = /* @__PURE__ */ new Set();
@@ -371,28 +377,28 @@ var RovingTabIndex = class _RovingTabIndex {
371
377
  this.#focusablesByFirstChar.clear();
372
378
  }
373
379
  #initialize() {
374
- this.#update(document.activeElement);
380
+ this.#update(getActiveElement());
375
381
  if (!(this.#container instanceof HTMLElement)) {
376
382
  return;
377
383
  }
378
384
  this.#controller = new AbortController();
379
385
  const { signal } = this.#controller;
380
- this.#container.addEventListener("focusin", this.#onFocusIn, {
381
- capture: true,
382
- signal
383
- });
384
- this.#container.addEventListener("keydown", this.#onKeyDown, {
385
- capture: true,
386
- signal
387
- });
386
+ document.addEventListener("focusin", this.#onFocusIn, { signal });
387
+ this.#settings.noMemory && document.addEventListener("focusout", this.#onFocusOut, { signal });
388
+ this.#container.addEventListener("keydown", this.#onKeyDown, { signal });
388
389
  }
389
390
  #onFocusIn = (event) => {
390
391
  const { target } = event;
391
392
  if (!(target instanceof Element)) {
392
393
  return;
393
394
  }
394
- const isFocusable3 = this.#focusables.has(target);
395
- this.#settings.noMemory && !isFocusable3 ? this.#update(null) : isFocusable3 && this.#update(target);
395
+ const isFocusable2 = this.#focusables.has(target);
396
+ this.#settings.noMemory && !isFocusable2 ? this.#update() : isFocusable2 && this.#update(target);
397
+ };
398
+ #onFocusOut = (event) => {
399
+ if (!event.relatedTarget) {
400
+ this.#update();
401
+ }
396
402
  };
397
403
  #onKeyDown = (event) => {
398
404
  const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
@@ -591,7 +597,7 @@ var Disclosure = class _Disclosure {
591
597
  const summary = this.#summaryElements[i];
592
598
  const content = this.#contentElements[i];
593
599
  if (summary && content) {
594
- const binding = createBinding(details, summary, content);
600
+ const binding = this.#createBinding(details, summary, content);
595
601
  this.#bindings.set(details, binding);
596
602
  this.#bindings.set(summary, binding);
597
603
  this.#bindings.set(content, binding);
@@ -625,7 +631,7 @@ var Disclosure = class _Disclosure {
625
631
  !force && await this.#waitAnimationsFinish();
626
632
  this.#contentElements.forEach((content) => {
627
633
  force && this.#bindings.get(content)?.animation?.finish();
628
- this.#onAnimationFinish(content);
634
+ this.#onContentAnimationFinish(content);
629
635
  });
630
636
  this.#animationController?.abort();
631
637
  this.#animationController = null;
@@ -671,7 +677,7 @@ var Disclosure = class _Disclosure {
671
677
  if (!summary) {
672
678
  return;
673
679
  }
674
- if (!isFocusable2(summary)) {
680
+ if (!this.#isFocusable(summary)) {
675
681
  summary.setAttribute("aria-disabled", "true");
676
682
  summary.setAttribute("tabindex", "-1");
677
683
  summary.style.setProperty("pointer-events", "none");
@@ -699,6 +705,24 @@ var Disclosure = class _Disclosure {
699
705
  const { details } = binding;
700
706
  this.#toggle(details, !details.hasAttribute("data-disclosure-open"));
701
707
  };
708
+ #onContentAnimationFinish(content) {
709
+ const binding = this.#bindings.get(content);
710
+ if (!binding) {
711
+ return;
712
+ }
713
+ const details = binding.details;
714
+ if (!details) {
715
+ return;
716
+ }
717
+ const name = details.getAttribute("data-disclosure-name");
718
+ name && details.setAttribute("name", name);
719
+ if (!details.hasAttribute("data-disclosure-open")) {
720
+ details.open = false;
721
+ }
722
+ ["block-size", "overflow"].forEach((name2) => {
723
+ content.style.removeProperty(name2);
724
+ });
725
+ }
702
726
  #toggle(details, isOpen) {
703
727
  if (details.hasAttribute("data-disclosure-open") === isOpen) {
704
728
  return;
@@ -706,16 +730,16 @@ var Disclosure = class _Disclosure {
706
730
  const name = details.getAttribute("data-disclosure-name");
707
731
  if (name && isOpen) {
708
732
  details.removeAttribute("name");
709
- const opened = this.#detailsElements.find(
733
+ const open = this.#detailsElements.find(
710
734
  (d) => d.hasAttribute("data-disclosure-open") && d.getAttribute("data-disclosure-name") === name
711
735
  );
712
- opened && this.close(opened);
736
+ open && this.close(open);
713
737
  }
714
738
  const binding = this.#bindings.get(details);
715
739
  if (!binding) {
716
740
  return;
717
741
  }
718
- const { content, timer } = binding;
742
+ const { content } = binding;
719
743
  const startSize = details.open ? content.offsetHeight : 0;
720
744
  binding.animation?.cancel();
721
745
  if (isOpen) {
@@ -723,11 +747,7 @@ var Disclosure = class _Disclosure {
723
747
  }
724
748
  const endSize = isOpen ? content.scrollHeight : 0;
725
749
  binding.animation?.cancel();
726
- timer && cancelAnimationFrame(timer);
727
- binding.timer = requestAnimationFrame(() => {
728
- binding.timer = void 0;
729
- details.toggleAttribute("data-disclosure-open", isOpen);
730
- });
750
+ details.toggleAttribute("data-disclosure-open", isOpen);
731
751
  content.style.setProperty("overflow", "clip");
732
752
  const { duration, easing } = this.#settings.animation;
733
753
  const animation = content.animate(
@@ -747,36 +767,24 @@ var Disclosure = class _Disclosure {
747
767
  "finish",
748
768
  () => {
749
769
  if (binding?.animation === animation) {
750
- this.#onAnimationFinish(content);
770
+ this.#onContentAnimationFinish(content);
751
771
  cleanup();
752
772
  }
753
773
  },
754
774
  { once: true, signal }
755
775
  );
756
776
  }
777
+ #createBinding(details, summary, content) {
778
+ return { details, summary, content, animation: null };
779
+ }
780
+ #isFocusable(element) {
781
+ return element.tabIndex >= 0;
782
+ }
757
783
  #mergeOptions(target, source) {
758
784
  return {
759
785
  animation: { ...target.animation, ...source.animation ?? {} }
760
786
  };
761
787
  }
762
- #onAnimationFinish(content) {
763
- const binding = this.#bindings.get(content);
764
- if (!binding) {
765
- return;
766
- }
767
- const details = binding.details;
768
- if (!details) {
769
- return;
770
- }
771
- const name = details.getAttribute("data-disclosure-name");
772
- name && details.setAttribute("name", name);
773
- if (!details.hasAttribute("data-disclosure-open")) {
774
- details.open = false;
775
- }
776
- ["block-size", "overflow"].forEach((name2) => {
777
- content.style.removeProperty(name2);
778
- });
779
- }
780
788
  async #waitAnimationsFinish() {
781
789
  const promises = [];
782
790
  this.#contentElements.forEach((content) => {
@@ -786,27 +794,17 @@ var Disclosure = class _Disclosure {
786
794
  await Promise.allSettled(promises);
787
795
  }
788
796
  };
789
- function createBinding(details, summary, content) {
790
- return { details, summary, content, timer: void 0, animation: null };
791
- }
792
- function isFocusable2(element) {
793
- return element.tabIndex >= 0;
794
- }
795
797
  function waitAnimationFinish(animation) {
796
- if (["idle", "finished"].includes(animation.playState)) {
797
- return Promise.resolve();
798
- } else {
799
- return new Promise(
800
- (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
801
- );
802
- }
798
+ return ["idle", "finished"].includes(animation.playState) ? Promise.resolve() : new Promise(
799
+ (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
800
+ );
803
801
  }
804
802
  /**
805
803
  * Disclosure
806
804
  * WAI-ARIA compliant disclosure pattern implementation in TypeScript.
807
805
  * Using the <details> and <summary> element.
808
806
  *
809
- * @version 1.3.17
807
+ * @version 1.3.19
810
808
  * @author Yusuke Kamiyamane
811
809
  * @license MIT
812
810
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -831,7 +829,7 @@ power-focusable/dist/index.js:
831
829
  * High-precision focus management utility with full composed tree support.
832
830
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
833
831
  *
834
- * @version 4.3.3
832
+ * @version 4.3.5
835
833
  * @author Yusuke Kamiyamane
836
834
  * @license MIT
837
835
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -844,7 +842,7 @@ power-focusable/dist/index.js:
844
842
  * Lightweight roving tabindex utility with fully focus management.
845
843
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
846
844
  *
847
- * @version 3.0.12
845
+ * @version 3.1.2
848
846
  * @author Yusuke Kamiyamane
849
847
  * @license MIT
850
848
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -292,8 +292,14 @@ function createRovingTabIndex(container, options = {}) {
292
292
  return () => {
293
293
  };
294
294
  }
295
- const roving = new RovingTabIndex(container, options);
296
- return () => roving.destroy();
295
+ try {
296
+ const roving = new RovingTabIndex(container, options);
297
+ return () => roving.destroy();
298
+ } catch (error) {
299
+ error instanceof Error && console.warn(error.message || error);
300
+ return () => {
301
+ };
302
+ }
297
303
  }
298
304
  var RovingTabIndex = class _RovingTabIndex {
299
305
  static #initialized = /* @__PURE__ */ new Set();
@@ -369,28 +375,28 @@ var RovingTabIndex = class _RovingTabIndex {
369
375
  this.#focusablesByFirstChar.clear();
370
376
  }
371
377
  #initialize() {
372
- this.#update(document.activeElement);
378
+ this.#update(getActiveElement());
373
379
  if (!(this.#container instanceof HTMLElement)) {
374
380
  return;
375
381
  }
376
382
  this.#controller = new AbortController();
377
383
  const { signal } = this.#controller;
378
- this.#container.addEventListener("focusin", this.#onFocusIn, {
379
- capture: true,
380
- signal
381
- });
382
- this.#container.addEventListener("keydown", this.#onKeyDown, {
383
- capture: true,
384
- signal
385
- });
384
+ document.addEventListener("focusin", this.#onFocusIn, { signal });
385
+ this.#settings.noMemory && document.addEventListener("focusout", this.#onFocusOut, { signal });
386
+ this.#container.addEventListener("keydown", this.#onKeyDown, { signal });
386
387
  }
387
388
  #onFocusIn = (event) => {
388
389
  const { target } = event;
389
390
  if (!(target instanceof Element)) {
390
391
  return;
391
392
  }
392
- const isFocusable3 = this.#focusables.has(target);
393
- this.#settings.noMemory && !isFocusable3 ? this.#update(null) : isFocusable3 && this.#update(target);
393
+ const isFocusable2 = this.#focusables.has(target);
394
+ this.#settings.noMemory && !isFocusable2 ? this.#update() : isFocusable2 && this.#update(target);
395
+ };
396
+ #onFocusOut = (event) => {
397
+ if (!event.relatedTarget) {
398
+ this.#update();
399
+ }
394
400
  };
395
401
  #onKeyDown = (event) => {
396
402
  const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
@@ -589,7 +595,7 @@ var Disclosure = class _Disclosure {
589
595
  const summary = this.#summaryElements[i];
590
596
  const content = this.#contentElements[i];
591
597
  if (summary && content) {
592
- const binding = createBinding(details, summary, content);
598
+ const binding = this.#createBinding(details, summary, content);
593
599
  this.#bindings.set(details, binding);
594
600
  this.#bindings.set(summary, binding);
595
601
  this.#bindings.set(content, binding);
@@ -623,7 +629,7 @@ var Disclosure = class _Disclosure {
623
629
  !force && await this.#waitAnimationsFinish();
624
630
  this.#contentElements.forEach((content) => {
625
631
  force && this.#bindings.get(content)?.animation?.finish();
626
- this.#onAnimationFinish(content);
632
+ this.#onContentAnimationFinish(content);
627
633
  });
628
634
  this.#animationController?.abort();
629
635
  this.#animationController = null;
@@ -669,7 +675,7 @@ var Disclosure = class _Disclosure {
669
675
  if (!summary) {
670
676
  return;
671
677
  }
672
- if (!isFocusable2(summary)) {
678
+ if (!this.#isFocusable(summary)) {
673
679
  summary.setAttribute("aria-disabled", "true");
674
680
  summary.setAttribute("tabindex", "-1");
675
681
  summary.style.setProperty("pointer-events", "none");
@@ -697,6 +703,24 @@ var Disclosure = class _Disclosure {
697
703
  const { details } = binding;
698
704
  this.#toggle(details, !details.hasAttribute("data-disclosure-open"));
699
705
  };
706
+ #onContentAnimationFinish(content) {
707
+ const binding = this.#bindings.get(content);
708
+ if (!binding) {
709
+ return;
710
+ }
711
+ const details = binding.details;
712
+ if (!details) {
713
+ return;
714
+ }
715
+ const name = details.getAttribute("data-disclosure-name");
716
+ name && details.setAttribute("name", name);
717
+ if (!details.hasAttribute("data-disclosure-open")) {
718
+ details.open = false;
719
+ }
720
+ ["block-size", "overflow"].forEach((name2) => {
721
+ content.style.removeProperty(name2);
722
+ });
723
+ }
700
724
  #toggle(details, isOpen) {
701
725
  if (details.hasAttribute("data-disclosure-open") === isOpen) {
702
726
  return;
@@ -704,16 +728,16 @@ var Disclosure = class _Disclosure {
704
728
  const name = details.getAttribute("data-disclosure-name");
705
729
  if (name && isOpen) {
706
730
  details.removeAttribute("name");
707
- const opened = this.#detailsElements.find(
731
+ const open = this.#detailsElements.find(
708
732
  (d) => d.hasAttribute("data-disclosure-open") && d.getAttribute("data-disclosure-name") === name
709
733
  );
710
- opened && this.close(opened);
734
+ open && this.close(open);
711
735
  }
712
736
  const binding = this.#bindings.get(details);
713
737
  if (!binding) {
714
738
  return;
715
739
  }
716
- const { content, timer } = binding;
740
+ const { content } = binding;
717
741
  const startSize = details.open ? content.offsetHeight : 0;
718
742
  binding.animation?.cancel();
719
743
  if (isOpen) {
@@ -721,11 +745,7 @@ var Disclosure = class _Disclosure {
721
745
  }
722
746
  const endSize = isOpen ? content.scrollHeight : 0;
723
747
  binding.animation?.cancel();
724
- timer && cancelAnimationFrame(timer);
725
- binding.timer = requestAnimationFrame(() => {
726
- binding.timer = void 0;
727
- details.toggleAttribute("data-disclosure-open", isOpen);
728
- });
748
+ details.toggleAttribute("data-disclosure-open", isOpen);
729
749
  content.style.setProperty("overflow", "clip");
730
750
  const { duration, easing } = this.#settings.animation;
731
751
  const animation = content.animate(
@@ -745,36 +765,24 @@ var Disclosure = class _Disclosure {
745
765
  "finish",
746
766
  () => {
747
767
  if (binding?.animation === animation) {
748
- this.#onAnimationFinish(content);
768
+ this.#onContentAnimationFinish(content);
749
769
  cleanup();
750
770
  }
751
771
  },
752
772
  { once: true, signal }
753
773
  );
754
774
  }
775
+ #createBinding(details, summary, content) {
776
+ return { details, summary, content, animation: null };
777
+ }
778
+ #isFocusable(element) {
779
+ return element.tabIndex >= 0;
780
+ }
755
781
  #mergeOptions(target, source) {
756
782
  return {
757
783
  animation: { ...target.animation, ...source.animation ?? {} }
758
784
  };
759
785
  }
760
- #onAnimationFinish(content) {
761
- const binding = this.#bindings.get(content);
762
- if (!binding) {
763
- return;
764
- }
765
- const details = binding.details;
766
- if (!details) {
767
- return;
768
- }
769
- const name = details.getAttribute("data-disclosure-name");
770
- name && details.setAttribute("name", name);
771
- if (!details.hasAttribute("data-disclosure-open")) {
772
- details.open = false;
773
- }
774
- ["block-size", "overflow"].forEach((name2) => {
775
- content.style.removeProperty(name2);
776
- });
777
- }
778
786
  async #waitAnimationsFinish() {
779
787
  const promises = [];
780
788
  this.#contentElements.forEach((content) => {
@@ -784,27 +792,17 @@ var Disclosure = class _Disclosure {
784
792
  await Promise.allSettled(promises);
785
793
  }
786
794
  };
787
- function createBinding(details, summary, content) {
788
- return { details, summary, content, timer: void 0, animation: null };
789
- }
790
- function isFocusable2(element) {
791
- return element.tabIndex >= 0;
792
- }
793
795
  function waitAnimationFinish(animation) {
794
- if (["idle", "finished"].includes(animation.playState)) {
795
- return Promise.resolve();
796
- } else {
797
- return new Promise(
798
- (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
799
- );
800
- }
796
+ return ["idle", "finished"].includes(animation.playState) ? Promise.resolve() : new Promise(
797
+ (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
798
+ );
801
799
  }
802
800
  /**
803
801
  * Disclosure
804
802
  * WAI-ARIA compliant disclosure pattern implementation in TypeScript.
805
803
  * Using the <details> and <summary> element.
806
804
  *
807
- * @version 1.3.17
805
+ * @version 1.3.19
808
806
  * @author Yusuke Kamiyamane
809
807
  * @license MIT
810
808
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -829,7 +827,7 @@ power-focusable/dist/index.js:
829
827
  * High-precision focus management utility with full composed tree support.
830
828
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
831
829
  *
832
- * @version 4.3.3
830
+ * @version 4.3.5
833
831
  * @author Yusuke Kamiyamane
834
832
  * @license MIT
835
833
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -842,7 +840,7 @@ power-focusable/dist/index.js:
842
840
  * Lightweight roving tabindex utility with fully focus management.
843
841
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
844
842
  *
845
- * @version 3.0.12
843
+ * @version 3.1.2
846
844
  * @author Yusuke Kamiyamane
847
845
  * @license MIT
848
846
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.cjs CHANGED
@@ -67,7 +67,7 @@ var Disclosure = class _Disclosure {
67
67
  const summary = this.#summaryElements[i];
68
68
  const content = this.#contentElements[i];
69
69
  if (summary && content) {
70
- const binding = createBinding(details, summary, content);
70
+ const binding = this.#createBinding(details, summary, content);
71
71
  this.#bindings.set(details, binding);
72
72
  this.#bindings.set(summary, binding);
73
73
  this.#bindings.set(content, binding);
@@ -101,7 +101,7 @@ var Disclosure = class _Disclosure {
101
101
  !force && await this.#waitAnimationsFinish();
102
102
  this.#contentElements.forEach((content) => {
103
103
  force && this.#bindings.get(content)?.animation?.finish();
104
- this.#onAnimationFinish(content);
104
+ this.#onContentAnimationFinish(content);
105
105
  });
106
106
  this.#animationController?.abort();
107
107
  this.#animationController = null;
@@ -147,7 +147,7 @@ var Disclosure = class _Disclosure {
147
147
  if (!summary) {
148
148
  return;
149
149
  }
150
- if (!isFocusable(summary)) {
150
+ if (!this.#isFocusable(summary)) {
151
151
  summary.setAttribute("aria-disabled", "true");
152
152
  summary.setAttribute("tabindex", "-1");
153
153
  summary.style.setProperty("pointer-events", "none");
@@ -175,6 +175,24 @@ var Disclosure = class _Disclosure {
175
175
  const { details } = binding;
176
176
  this.#toggle(details, !details.hasAttribute("data-disclosure-open"));
177
177
  };
178
+ #onContentAnimationFinish(content) {
179
+ const binding = this.#bindings.get(content);
180
+ if (!binding) {
181
+ return;
182
+ }
183
+ const details = binding.details;
184
+ if (!details) {
185
+ return;
186
+ }
187
+ const name = details.getAttribute("data-disclosure-name");
188
+ name && details.setAttribute("name", name);
189
+ if (!details.hasAttribute("data-disclosure-open")) {
190
+ details.open = false;
191
+ }
192
+ ["block-size", "overflow"].forEach((name2) => {
193
+ content.style.removeProperty(name2);
194
+ });
195
+ }
178
196
  #toggle(details, isOpen) {
179
197
  if (details.hasAttribute("data-disclosure-open") === isOpen) {
180
198
  return;
@@ -182,16 +200,16 @@ var Disclosure = class _Disclosure {
182
200
  const name = details.getAttribute("data-disclosure-name");
183
201
  if (name && isOpen) {
184
202
  details.removeAttribute("name");
185
- const opened = this.#detailsElements.find(
203
+ const open = this.#detailsElements.find(
186
204
  (d) => d.hasAttribute("data-disclosure-open") && d.getAttribute("data-disclosure-name") === name
187
205
  );
188
- opened && this.close(opened);
206
+ open && this.close(open);
189
207
  }
190
208
  const binding = this.#bindings.get(details);
191
209
  if (!binding) {
192
210
  return;
193
211
  }
194
- const { content, timer } = binding;
212
+ const { content } = binding;
195
213
  const startSize = details.open ? content.offsetHeight : 0;
196
214
  binding.animation?.cancel();
197
215
  if (isOpen) {
@@ -199,11 +217,7 @@ var Disclosure = class _Disclosure {
199
217
  }
200
218
  const endSize = isOpen ? content.scrollHeight : 0;
201
219
  binding.animation?.cancel();
202
- timer && cancelAnimationFrame(timer);
203
- binding.timer = requestAnimationFrame(() => {
204
- binding.timer = void 0;
205
- details.toggleAttribute("data-disclosure-open", isOpen);
206
- });
220
+ details.toggleAttribute("data-disclosure-open", isOpen);
207
221
  content.style.setProperty("overflow", "clip");
208
222
  const { duration, easing } = this.#settings.animation;
209
223
  const animation = content.animate(
@@ -223,36 +237,24 @@ var Disclosure = class _Disclosure {
223
237
  "finish",
224
238
  () => {
225
239
  if (binding?.animation === animation) {
226
- this.#onAnimationFinish(content);
240
+ this.#onContentAnimationFinish(content);
227
241
  cleanup();
228
242
  }
229
243
  },
230
244
  { once: true, signal }
231
245
  );
232
246
  }
247
+ #createBinding(details, summary, content) {
248
+ return { details, summary, content, animation: null };
249
+ }
250
+ #isFocusable(element) {
251
+ return element.tabIndex >= 0;
252
+ }
233
253
  #mergeOptions(target, source) {
234
254
  return {
235
255
  animation: { ...target.animation, ...source.animation ?? {} }
236
256
  };
237
257
  }
238
- #onAnimationFinish(content) {
239
- const binding = this.#bindings.get(content);
240
- if (!binding) {
241
- return;
242
- }
243
- const details = binding.details;
244
- if (!details) {
245
- return;
246
- }
247
- const name = details.getAttribute("data-disclosure-name");
248
- name && details.setAttribute("name", name);
249
- if (!details.hasAttribute("data-disclosure-open")) {
250
- details.open = false;
251
- }
252
- ["block-size", "overflow"].forEach((name2) => {
253
- content.style.removeProperty(name2);
254
- });
255
- }
256
258
  async #waitAnimationsFinish() {
257
259
  const promises = [];
258
260
  this.#contentElements.forEach((content) => {
@@ -262,27 +264,17 @@ var Disclosure = class _Disclosure {
262
264
  await Promise.allSettled(promises);
263
265
  }
264
266
  };
265
- function createBinding(details, summary, content) {
266
- return { details, summary, content, timer: void 0, animation: null };
267
- }
268
- function isFocusable(element) {
269
- return element.tabIndex >= 0;
270
- }
271
267
  function waitAnimationFinish(animation) {
272
- if (["idle", "finished"].includes(animation.playState)) {
273
- return Promise.resolve();
274
- } else {
275
- return new Promise(
276
- (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
277
- );
278
- }
268
+ return ["idle", "finished"].includes(animation.playState) ? Promise.resolve() : new Promise(
269
+ (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
270
+ );
279
271
  }
280
272
  /**
281
273
  * Disclosure
282
274
  * WAI-ARIA compliant disclosure pattern implementation in TypeScript.
283
275
  * Using the <details> and <summary> element.
284
276
  *
285
- * @version 1.3.17
277
+ * @version 1.3.19
286
278
  * @author Yusuke Kamiyamane
287
279
  * @license MIT
288
280
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.cts CHANGED
@@ -3,7 +3,7 @@
3
3
  * WAI-ARIA compliant disclosure pattern implementation in TypeScript.
4
4
  * Using the <details> and <summary> element.
5
5
  *
6
- * @version 1.3.17
6
+ * @version 1.3.19
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * WAI-ARIA compliant disclosure pattern implementation in TypeScript.
4
4
  * Using the <details> and <summary> element.
5
5
  *
6
- * @version 1.3.17
6
+ * @version 1.3.19
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -65,7 +65,7 @@ var Disclosure = class _Disclosure {
65
65
  const summary = this.#summaryElements[i];
66
66
  const content = this.#contentElements[i];
67
67
  if (summary && content) {
68
- const binding = createBinding(details, summary, content);
68
+ const binding = this.#createBinding(details, summary, content);
69
69
  this.#bindings.set(details, binding);
70
70
  this.#bindings.set(summary, binding);
71
71
  this.#bindings.set(content, binding);
@@ -99,7 +99,7 @@ var Disclosure = class _Disclosure {
99
99
  !force && await this.#waitAnimationsFinish();
100
100
  this.#contentElements.forEach((content) => {
101
101
  force && this.#bindings.get(content)?.animation?.finish();
102
- this.#onAnimationFinish(content);
102
+ this.#onContentAnimationFinish(content);
103
103
  });
104
104
  this.#animationController?.abort();
105
105
  this.#animationController = null;
@@ -145,7 +145,7 @@ var Disclosure = class _Disclosure {
145
145
  if (!summary) {
146
146
  return;
147
147
  }
148
- if (!isFocusable(summary)) {
148
+ if (!this.#isFocusable(summary)) {
149
149
  summary.setAttribute("aria-disabled", "true");
150
150
  summary.setAttribute("tabindex", "-1");
151
151
  summary.style.setProperty("pointer-events", "none");
@@ -173,6 +173,24 @@ var Disclosure = class _Disclosure {
173
173
  const { details } = binding;
174
174
  this.#toggle(details, !details.hasAttribute("data-disclosure-open"));
175
175
  };
176
+ #onContentAnimationFinish(content) {
177
+ const binding = this.#bindings.get(content);
178
+ if (!binding) {
179
+ return;
180
+ }
181
+ const details = binding.details;
182
+ if (!details) {
183
+ return;
184
+ }
185
+ const name = details.getAttribute("data-disclosure-name");
186
+ name && details.setAttribute("name", name);
187
+ if (!details.hasAttribute("data-disclosure-open")) {
188
+ details.open = false;
189
+ }
190
+ ["block-size", "overflow"].forEach((name2) => {
191
+ content.style.removeProperty(name2);
192
+ });
193
+ }
176
194
  #toggle(details, isOpen) {
177
195
  if (details.hasAttribute("data-disclosure-open") === isOpen) {
178
196
  return;
@@ -180,16 +198,16 @@ var Disclosure = class _Disclosure {
180
198
  const name = details.getAttribute("data-disclosure-name");
181
199
  if (name && isOpen) {
182
200
  details.removeAttribute("name");
183
- const opened = this.#detailsElements.find(
201
+ const open = this.#detailsElements.find(
184
202
  (d) => d.hasAttribute("data-disclosure-open") && d.getAttribute("data-disclosure-name") === name
185
203
  );
186
- opened && this.close(opened);
204
+ open && this.close(open);
187
205
  }
188
206
  const binding = this.#bindings.get(details);
189
207
  if (!binding) {
190
208
  return;
191
209
  }
192
- const { content, timer } = binding;
210
+ const { content } = binding;
193
211
  const startSize = details.open ? content.offsetHeight : 0;
194
212
  binding.animation?.cancel();
195
213
  if (isOpen) {
@@ -197,11 +215,7 @@ var Disclosure = class _Disclosure {
197
215
  }
198
216
  const endSize = isOpen ? content.scrollHeight : 0;
199
217
  binding.animation?.cancel();
200
- timer && cancelAnimationFrame(timer);
201
- binding.timer = requestAnimationFrame(() => {
202
- binding.timer = void 0;
203
- details.toggleAttribute("data-disclosure-open", isOpen);
204
- });
218
+ details.toggleAttribute("data-disclosure-open", isOpen);
205
219
  content.style.setProperty("overflow", "clip");
206
220
  const { duration, easing } = this.#settings.animation;
207
221
  const animation = content.animate(
@@ -221,36 +235,24 @@ var Disclosure = class _Disclosure {
221
235
  "finish",
222
236
  () => {
223
237
  if (binding?.animation === animation) {
224
- this.#onAnimationFinish(content);
238
+ this.#onContentAnimationFinish(content);
225
239
  cleanup();
226
240
  }
227
241
  },
228
242
  { once: true, signal }
229
243
  );
230
244
  }
245
+ #createBinding(details, summary, content) {
246
+ return { details, summary, content, animation: null };
247
+ }
248
+ #isFocusable(element) {
249
+ return element.tabIndex >= 0;
250
+ }
231
251
  #mergeOptions(target, source) {
232
252
  return {
233
253
  animation: { ...target.animation, ...source.animation ?? {} }
234
254
  };
235
255
  }
236
- #onAnimationFinish(content) {
237
- const binding = this.#bindings.get(content);
238
- if (!binding) {
239
- return;
240
- }
241
- const details = binding.details;
242
- if (!details) {
243
- return;
244
- }
245
- const name = details.getAttribute("data-disclosure-name");
246
- name && details.setAttribute("name", name);
247
- if (!details.hasAttribute("data-disclosure-open")) {
248
- details.open = false;
249
- }
250
- ["block-size", "overflow"].forEach((name2) => {
251
- content.style.removeProperty(name2);
252
- });
253
- }
254
256
  async #waitAnimationsFinish() {
255
257
  const promises = [];
256
258
  this.#contentElements.forEach((content) => {
@@ -260,27 +262,17 @@ var Disclosure = class _Disclosure {
260
262
  await Promise.allSettled(promises);
261
263
  }
262
264
  };
263
- function createBinding(details, summary, content) {
264
- return { details, summary, content, timer: void 0, animation: null };
265
- }
266
- function isFocusable(element) {
267
- return element.tabIndex >= 0;
268
- }
269
265
  function waitAnimationFinish(animation) {
270
- if (["idle", "finished"].includes(animation.playState)) {
271
- return Promise.resolve();
272
- } else {
273
- return new Promise(
274
- (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
275
- );
276
- }
266
+ return ["idle", "finished"].includes(animation.playState) ? Promise.resolve() : new Promise(
267
+ (resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
268
+ );
277
269
  }
278
270
  /**
279
271
  * Disclosure
280
272
  * WAI-ARIA compliant disclosure pattern implementation in TypeScript.
281
273
  * Using the <details> and <summary> element.
282
274
  *
283
- * @version 1.3.17
275
+ * @version 1.3.19
284
276
  * @author Yusuke Kamiyamane
285
277
  * @license MIT
286
278
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/disclosure",
3
- "version": "1.3.17",
3
+ "version": "1.3.19",
4
4
  "description": "WAI-ARIA compliant disclosure pattern implementation in TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -53,6 +53,6 @@
53
53
  },
54
54
  "dependencies": {
55
55
  "@y14e/attributes-utils": "^1.1.2",
56
- "@y14e/roving-tabindex": "^3.0.12"
56
+ "@y14e/roving-tabindex": "^3.1.2"
57
57
  }
58
58
  }