@y14e/accordion 1.4.18 → 2.0.2
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 +12 -11
- package/dist/index.bundle.cjs +38 -35
- package/dist/index.bundle.js +38 -35
- package/dist/index.cjs +18 -12
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +18 -12
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -13,11 +13,11 @@ npm i @y14e/accordion
|
|
|
13
13
|
import Accordion from '@y14e/accordion';
|
|
14
14
|
|
|
15
15
|
// CDNs
|
|
16
|
-
import Accordion from 'https://esm.sh/@y14e/accordion@
|
|
16
|
+
import Accordion from 'https://esm.sh/@y14e/accordion@2.0.2';
|
|
17
17
|
// or
|
|
18
|
-
import Accordion from 'https://cdn.jsdelivr.net/npm/@y14e/accordion@
|
|
18
|
+
import Accordion from 'https://cdn.jsdelivr.net/npm/@y14e/accordion@2.0.2/+esm';
|
|
19
19
|
// or
|
|
20
|
-
import Accordion from 'https://esm.unpkg.com/@y14e/accordion@
|
|
20
|
+
import Accordion from 'https://esm.unpkg.com/@y14e/accordion@2.0.2';
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
## Usage
|
|
@@ -36,12 +36,13 @@ new Accordion(root, options);
|
|
|
36
36
|
```ts
|
|
37
37
|
interface AccordionOptions {
|
|
38
38
|
animation?: {
|
|
39
|
-
duration?: number;
|
|
40
|
-
easing?: string;
|
|
39
|
+
duration?: number; // ms (default: 300)
|
|
40
|
+
easing?: string; // <easing-function> (default: 'ease')
|
|
41
41
|
};
|
|
42
|
+
collapsible?: boolean; // default: true
|
|
42
43
|
selector?: {
|
|
43
|
-
content?: string;
|
|
44
|
-
trigger?: string;
|
|
44
|
+
content?: string; // default: '[data-accordion-content]'
|
|
45
|
+
trigger?: string; // default: '[data-accordion-trigger]'
|
|
45
46
|
};
|
|
46
47
|
}
|
|
47
48
|
```
|
|
@@ -68,10 +69,10 @@ new Accordion(root);
|
|
|
68
69
|
|
|
69
70
|
## 📦 APIs
|
|
70
71
|
|
|
71
|
-
### `
|
|
72
|
+
### `collapse`
|
|
72
73
|
|
|
73
74
|
```ts
|
|
74
|
-
accordion.
|
|
75
|
+
accordion.collapse(trigger);
|
|
75
76
|
// => void
|
|
76
77
|
//
|
|
77
78
|
// trigger: HTMLElement
|
|
@@ -88,10 +89,10 @@ accordion.destroy(force);
|
|
|
88
89
|
// force (optional): If true, skips waiting for animations to finish.
|
|
89
90
|
```
|
|
90
91
|
|
|
91
|
-
### `
|
|
92
|
+
### `expand`
|
|
92
93
|
|
|
93
94
|
```ts
|
|
94
|
-
accordion.
|
|
95
|
+
accordion.expand(trigger);
|
|
95
96
|
// => void
|
|
96
97
|
//
|
|
97
98
|
// trigger: HTMLElement
|
package/dist/index.bundle.cjs
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
var DEFAULT_PARSER = (value) => value.split(/\s+/);
|
|
5
5
|
var DEFAULT_SERIALIZER = (tokens) => tokens.join(" ");
|
|
6
6
|
function addTokenToAttribute(element, attribute, token, options = {}) {
|
|
7
|
+
const value = element.getAttribute(attribute)?.trim();
|
|
7
8
|
const {
|
|
8
9
|
caseInsensitive = false,
|
|
9
10
|
parse = DEFAULT_PARSER,
|
|
10
11
|
serialize = DEFAULT_SERIALIZER
|
|
11
12
|
} = options;
|
|
12
|
-
const value = element.getAttribute(attribute)?.trim();
|
|
13
13
|
const tokens = value ? parse(value).filter(Boolean) : [];
|
|
14
14
|
if (caseInsensitive) {
|
|
15
15
|
const lower = token.toLowerCase();
|
|
@@ -402,13 +402,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
402
402
|
console.warn("Invalid wrap option. Fallback: false.");
|
|
403
403
|
wrap = false;
|
|
404
404
|
}
|
|
405
|
-
this.#settings = {
|
|
406
|
-
navigationOnly,
|
|
407
|
-
noMemory,
|
|
408
|
-
noStart,
|
|
409
|
-
typeahead,
|
|
410
|
-
wrap
|
|
411
|
-
};
|
|
405
|
+
this.#settings = { navigationOnly, noMemory, noStart, typeahead, wrap };
|
|
412
406
|
direction && Object.assign(this.#settings, { direction });
|
|
413
407
|
selector && Object.assign(this.#settings, { selector });
|
|
414
408
|
this.#selectorFilter = this.#createSelectorFilter();
|
|
@@ -427,29 +421,32 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
427
421
|
}
|
|
428
422
|
#initialize() {
|
|
429
423
|
this.#update(getActiveElement());
|
|
430
|
-
if (!(this.#container instanceof HTMLElement)) {
|
|
431
|
-
return;
|
|
432
|
-
}
|
|
433
424
|
this.#controller = new AbortController();
|
|
434
425
|
const { signal } = this.#controller;
|
|
435
|
-
|
|
436
|
-
this.#settings.noMemory &&
|
|
426
|
+
this.#container.addEventListener("focusin", this.#onFocusIn, { signal });
|
|
427
|
+
this.#settings.noMemory && this.#container.addEventListener("focusout", this.#onFocusOut, {
|
|
428
|
+
signal
|
|
429
|
+
});
|
|
437
430
|
this.#container.addEventListener("keydown", this.#onKeyDown, { signal });
|
|
438
431
|
}
|
|
439
432
|
#onFocusIn = (event) => {
|
|
440
|
-
|
|
441
|
-
if (!(target instanceof Element)) {
|
|
433
|
+
if (!(event instanceof FocusEvent)) {
|
|
442
434
|
return;
|
|
443
435
|
}
|
|
444
|
-
const
|
|
445
|
-
|
|
436
|
+
const { target } = event;
|
|
437
|
+
target instanceof Element && this.#update(target);
|
|
446
438
|
};
|
|
447
439
|
#onFocusOut = (event) => {
|
|
448
|
-
if (!event
|
|
449
|
-
|
|
440
|
+
if (!(event instanceof FocusEvent)) {
|
|
441
|
+
return;
|
|
450
442
|
}
|
|
443
|
+
const target = event.relatedTarget;
|
|
444
|
+
(!(target instanceof Element) || !this.#focusables.has(target)) && this.#update();
|
|
451
445
|
};
|
|
452
446
|
#onKeyDown = (event) => {
|
|
447
|
+
if (!(event instanceof KeyboardEvent)) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
453
450
|
const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
|
|
454
451
|
if (altKey || ctrlKey || metaKey || shiftKey) {
|
|
455
452
|
return;
|
|
@@ -468,7 +465,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
468
465
|
}
|
|
469
466
|
}
|
|
470
467
|
const active = getActiveElement();
|
|
471
|
-
if (!(active instanceof
|
|
468
|
+
if (!(active instanceof Element)) {
|
|
472
469
|
return;
|
|
473
470
|
}
|
|
474
471
|
const current = this.#getFocusables();
|
|
@@ -588,8 +585,9 @@ var Accordion = class _Accordion {
|
|
|
588
585
|
#rootElement;
|
|
589
586
|
#defaults = {
|
|
590
587
|
animation: { duration: 300, easing: "ease" },
|
|
588
|
+
collapsible: true,
|
|
591
589
|
selector: {
|
|
592
|
-
content: "
|
|
590
|
+
content: "[data-accordion-content]",
|
|
593
591
|
trigger: "[data-accordion-trigger]"
|
|
594
592
|
}
|
|
595
593
|
};
|
|
@@ -645,7 +643,7 @@ var Accordion = class _Accordion {
|
|
|
645
643
|
});
|
|
646
644
|
this.#initialize();
|
|
647
645
|
}
|
|
648
|
-
|
|
646
|
+
collapse(trigger) {
|
|
649
647
|
if (this.#isDestroyed) {
|
|
650
648
|
return;
|
|
651
649
|
}
|
|
@@ -680,7 +678,7 @@ var Accordion = class _Accordion {
|
|
|
680
678
|
this.#contentElements.length = 0;
|
|
681
679
|
this.#rootElement.removeAttribute("data-accordion-initialized");
|
|
682
680
|
}
|
|
683
|
-
|
|
681
|
+
expand(trigger) {
|
|
684
682
|
if (this.#isDestroyed) {
|
|
685
683
|
return;
|
|
686
684
|
}
|
|
@@ -765,21 +763,24 @@ var Accordion = class _Accordion {
|
|
|
765
763
|
}
|
|
766
764
|
binding.trigger.ariaExpanded === "false" && this.#toggle(binding.trigger, true, true);
|
|
767
765
|
};
|
|
768
|
-
#toggle(trigger,
|
|
769
|
-
if (trigger.ariaExpanded === String(
|
|
766
|
+
#toggle(trigger, isExpand, isMatch = false, isProgrammatic = false) {
|
|
767
|
+
if (trigger.ariaExpanded === String(isExpand)) {
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
if (!isExpand && !isProgrammatic && !this.#settings.collapsible && this.#triggerElements.filter((trigger2) => trigger2.ariaExpanded === "true").length <= 1) {
|
|
770
771
|
return;
|
|
771
772
|
}
|
|
772
773
|
const name = trigger.getAttribute("data-accordion-name");
|
|
773
|
-
if (name &&
|
|
774
|
-
const
|
|
774
|
+
if (name && isExpand) {
|
|
775
|
+
const expanded = this.#triggerElements.find(
|
|
775
776
|
(t) => t !== trigger && t.getAttribute("data-accordion-name") === name && t.ariaExpanded === "true"
|
|
776
777
|
);
|
|
777
|
-
|
|
778
|
+
expanded && this.#toggle(expanded, false, isMatch, true);
|
|
778
779
|
}
|
|
779
780
|
trigger.setAttribute(
|
|
780
781
|
"aria-label",
|
|
781
782
|
trigger.getAttribute(
|
|
782
|
-
`data-accordion-${
|
|
783
|
+
`data-accordion-${isExpand ? "expanded" : "collapsed"}-label`
|
|
783
784
|
) ?? trigger.ariaLabel ?? ""
|
|
784
785
|
);
|
|
785
786
|
const binding = this.#bindings.get(trigger);
|
|
@@ -791,7 +792,7 @@ var Accordion = class _Accordion {
|
|
|
791
792
|
if (content.hidden) {
|
|
792
793
|
content.hidden = false;
|
|
793
794
|
}
|
|
794
|
-
const endSize =
|
|
795
|
+
const endSize = isExpand ? content.scrollHeight : 0;
|
|
795
796
|
binding.animation?.cancel();
|
|
796
797
|
content.style.setProperty("overflow", "clip");
|
|
797
798
|
const { duration, easing } = this.#settings.animation;
|
|
@@ -800,7 +801,7 @@ var Accordion = class _Accordion {
|
|
|
800
801
|
{ duration: isMatch ? 0 : duration, easing }
|
|
801
802
|
);
|
|
802
803
|
binding.animation = animation;
|
|
803
|
-
trigger.setAttribute("aria-expanded", String(
|
|
804
|
+
trigger.setAttribute("aria-expanded", String(isExpand));
|
|
804
805
|
function cleanup() {
|
|
805
806
|
if (binding?.animation === animation) {
|
|
806
807
|
binding.animation = null;
|
|
@@ -828,6 +829,8 @@ var Accordion = class _Accordion {
|
|
|
828
829
|
}
|
|
829
830
|
#mergeOptions(target, source) {
|
|
830
831
|
return {
|
|
832
|
+
...target,
|
|
833
|
+
...source,
|
|
831
834
|
animation: { ...target.animation, ...source.animation ?? {} },
|
|
832
835
|
selector: { ...target.selector, ...source.selector ?? {} }
|
|
833
836
|
};
|
|
@@ -850,7 +853,7 @@ function waitAnimationFinish(animation) {
|
|
|
850
853
|
* Accordion
|
|
851
854
|
* WAI-ARIA compliant accordion pattern implementation in TypeScript.
|
|
852
855
|
*
|
|
853
|
-
* @version
|
|
856
|
+
* @version 2.0.2
|
|
854
857
|
* @author Yusuke Kamiyamane
|
|
855
858
|
* @license MIT
|
|
856
859
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -862,7 +865,7 @@ function waitAnimationFinish(animation) {
|
|
|
862
865
|
(**
|
|
863
866
|
* Attributes Utils
|
|
864
867
|
*
|
|
865
|
-
* @version 1.1.
|
|
868
|
+
* @version 1.1.3
|
|
866
869
|
* @author Yusuke Kamiyamane
|
|
867
870
|
* @license MIT
|
|
868
871
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -875,7 +878,7 @@ power-focusable/dist/index.js:
|
|
|
875
878
|
* High-precision focus management utility with full composed tree support.
|
|
876
879
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
877
880
|
*
|
|
878
|
-
* @version 4.3.
|
|
881
|
+
* @version 4.3.8
|
|
879
882
|
* @author Yusuke Kamiyamane
|
|
880
883
|
* @license MIT
|
|
881
884
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -899,7 +902,7 @@ power-focusable/dist/index.js:
|
|
|
899
902
|
* Lightweight roving tabindex utility with fully focus management.
|
|
900
903
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
901
904
|
*
|
|
902
|
-
* @version 3.1.
|
|
905
|
+
* @version 3.1.6
|
|
903
906
|
* @author Yusuke Kamiyamane
|
|
904
907
|
* @license MIT
|
|
905
908
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.bundle.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
var DEFAULT_PARSER = (value) => value.split(/\s+/);
|
|
3
3
|
var DEFAULT_SERIALIZER = (tokens) => tokens.join(" ");
|
|
4
4
|
function addTokenToAttribute(element, attribute, token, options = {}) {
|
|
5
|
+
const value = element.getAttribute(attribute)?.trim();
|
|
5
6
|
const {
|
|
6
7
|
caseInsensitive = false,
|
|
7
8
|
parse = DEFAULT_PARSER,
|
|
8
9
|
serialize = DEFAULT_SERIALIZER
|
|
9
10
|
} = options;
|
|
10
|
-
const value = element.getAttribute(attribute)?.trim();
|
|
11
11
|
const tokens = value ? parse(value).filter(Boolean) : [];
|
|
12
12
|
if (caseInsensitive) {
|
|
13
13
|
const lower = token.toLowerCase();
|
|
@@ -400,13 +400,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
400
400
|
console.warn("Invalid wrap option. Fallback: false.");
|
|
401
401
|
wrap = false;
|
|
402
402
|
}
|
|
403
|
-
this.#settings = {
|
|
404
|
-
navigationOnly,
|
|
405
|
-
noMemory,
|
|
406
|
-
noStart,
|
|
407
|
-
typeahead,
|
|
408
|
-
wrap
|
|
409
|
-
};
|
|
403
|
+
this.#settings = { navigationOnly, noMemory, noStart, typeahead, wrap };
|
|
410
404
|
direction && Object.assign(this.#settings, { direction });
|
|
411
405
|
selector && Object.assign(this.#settings, { selector });
|
|
412
406
|
this.#selectorFilter = this.#createSelectorFilter();
|
|
@@ -425,29 +419,32 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
425
419
|
}
|
|
426
420
|
#initialize() {
|
|
427
421
|
this.#update(getActiveElement());
|
|
428
|
-
if (!(this.#container instanceof HTMLElement)) {
|
|
429
|
-
return;
|
|
430
|
-
}
|
|
431
422
|
this.#controller = new AbortController();
|
|
432
423
|
const { signal } = this.#controller;
|
|
433
|
-
|
|
434
|
-
this.#settings.noMemory &&
|
|
424
|
+
this.#container.addEventListener("focusin", this.#onFocusIn, { signal });
|
|
425
|
+
this.#settings.noMemory && this.#container.addEventListener("focusout", this.#onFocusOut, {
|
|
426
|
+
signal
|
|
427
|
+
});
|
|
435
428
|
this.#container.addEventListener("keydown", this.#onKeyDown, { signal });
|
|
436
429
|
}
|
|
437
430
|
#onFocusIn = (event) => {
|
|
438
|
-
|
|
439
|
-
if (!(target instanceof Element)) {
|
|
431
|
+
if (!(event instanceof FocusEvent)) {
|
|
440
432
|
return;
|
|
441
433
|
}
|
|
442
|
-
const
|
|
443
|
-
|
|
434
|
+
const { target } = event;
|
|
435
|
+
target instanceof Element && this.#update(target);
|
|
444
436
|
};
|
|
445
437
|
#onFocusOut = (event) => {
|
|
446
|
-
if (!event
|
|
447
|
-
|
|
438
|
+
if (!(event instanceof FocusEvent)) {
|
|
439
|
+
return;
|
|
448
440
|
}
|
|
441
|
+
const target = event.relatedTarget;
|
|
442
|
+
(!(target instanceof Element) || !this.#focusables.has(target)) && this.#update();
|
|
449
443
|
};
|
|
450
444
|
#onKeyDown = (event) => {
|
|
445
|
+
if (!(event instanceof KeyboardEvent)) {
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
451
448
|
const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
|
|
452
449
|
if (altKey || ctrlKey || metaKey || shiftKey) {
|
|
453
450
|
return;
|
|
@@ -466,7 +463,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
466
463
|
}
|
|
467
464
|
}
|
|
468
465
|
const active = getActiveElement();
|
|
469
|
-
if (!(active instanceof
|
|
466
|
+
if (!(active instanceof Element)) {
|
|
470
467
|
return;
|
|
471
468
|
}
|
|
472
469
|
const current = this.#getFocusables();
|
|
@@ -586,8 +583,9 @@ var Accordion = class _Accordion {
|
|
|
586
583
|
#rootElement;
|
|
587
584
|
#defaults = {
|
|
588
585
|
animation: { duration: 300, easing: "ease" },
|
|
586
|
+
collapsible: true,
|
|
589
587
|
selector: {
|
|
590
|
-
content: "
|
|
588
|
+
content: "[data-accordion-content]",
|
|
591
589
|
trigger: "[data-accordion-trigger]"
|
|
592
590
|
}
|
|
593
591
|
};
|
|
@@ -643,7 +641,7 @@ var Accordion = class _Accordion {
|
|
|
643
641
|
});
|
|
644
642
|
this.#initialize();
|
|
645
643
|
}
|
|
646
|
-
|
|
644
|
+
collapse(trigger) {
|
|
647
645
|
if (this.#isDestroyed) {
|
|
648
646
|
return;
|
|
649
647
|
}
|
|
@@ -678,7 +676,7 @@ var Accordion = class _Accordion {
|
|
|
678
676
|
this.#contentElements.length = 0;
|
|
679
677
|
this.#rootElement.removeAttribute("data-accordion-initialized");
|
|
680
678
|
}
|
|
681
|
-
|
|
679
|
+
expand(trigger) {
|
|
682
680
|
if (this.#isDestroyed) {
|
|
683
681
|
return;
|
|
684
682
|
}
|
|
@@ -763,21 +761,24 @@ var Accordion = class _Accordion {
|
|
|
763
761
|
}
|
|
764
762
|
binding.trigger.ariaExpanded === "false" && this.#toggle(binding.trigger, true, true);
|
|
765
763
|
};
|
|
766
|
-
#toggle(trigger,
|
|
767
|
-
if (trigger.ariaExpanded === String(
|
|
764
|
+
#toggle(trigger, isExpand, isMatch = false, isProgrammatic = false) {
|
|
765
|
+
if (trigger.ariaExpanded === String(isExpand)) {
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
if (!isExpand && !isProgrammatic && !this.#settings.collapsible && this.#triggerElements.filter((trigger2) => trigger2.ariaExpanded === "true").length <= 1) {
|
|
768
769
|
return;
|
|
769
770
|
}
|
|
770
771
|
const name = trigger.getAttribute("data-accordion-name");
|
|
771
|
-
if (name &&
|
|
772
|
-
const
|
|
772
|
+
if (name && isExpand) {
|
|
773
|
+
const expanded = this.#triggerElements.find(
|
|
773
774
|
(t) => t !== trigger && t.getAttribute("data-accordion-name") === name && t.ariaExpanded === "true"
|
|
774
775
|
);
|
|
775
|
-
|
|
776
|
+
expanded && this.#toggle(expanded, false, isMatch, true);
|
|
776
777
|
}
|
|
777
778
|
trigger.setAttribute(
|
|
778
779
|
"aria-label",
|
|
779
780
|
trigger.getAttribute(
|
|
780
|
-
`data-accordion-${
|
|
781
|
+
`data-accordion-${isExpand ? "expanded" : "collapsed"}-label`
|
|
781
782
|
) ?? trigger.ariaLabel ?? ""
|
|
782
783
|
);
|
|
783
784
|
const binding = this.#bindings.get(trigger);
|
|
@@ -789,7 +790,7 @@ var Accordion = class _Accordion {
|
|
|
789
790
|
if (content.hidden) {
|
|
790
791
|
content.hidden = false;
|
|
791
792
|
}
|
|
792
|
-
const endSize =
|
|
793
|
+
const endSize = isExpand ? content.scrollHeight : 0;
|
|
793
794
|
binding.animation?.cancel();
|
|
794
795
|
content.style.setProperty("overflow", "clip");
|
|
795
796
|
const { duration, easing } = this.#settings.animation;
|
|
@@ -798,7 +799,7 @@ var Accordion = class _Accordion {
|
|
|
798
799
|
{ duration: isMatch ? 0 : duration, easing }
|
|
799
800
|
);
|
|
800
801
|
binding.animation = animation;
|
|
801
|
-
trigger.setAttribute("aria-expanded", String(
|
|
802
|
+
trigger.setAttribute("aria-expanded", String(isExpand));
|
|
802
803
|
function cleanup() {
|
|
803
804
|
if (binding?.animation === animation) {
|
|
804
805
|
binding.animation = null;
|
|
@@ -826,6 +827,8 @@ var Accordion = class _Accordion {
|
|
|
826
827
|
}
|
|
827
828
|
#mergeOptions(target, source) {
|
|
828
829
|
return {
|
|
830
|
+
...target,
|
|
831
|
+
...source,
|
|
829
832
|
animation: { ...target.animation, ...source.animation ?? {} },
|
|
830
833
|
selector: { ...target.selector, ...source.selector ?? {} }
|
|
831
834
|
};
|
|
@@ -848,7 +851,7 @@ function waitAnimationFinish(animation) {
|
|
|
848
851
|
* Accordion
|
|
849
852
|
* WAI-ARIA compliant accordion pattern implementation in TypeScript.
|
|
850
853
|
*
|
|
851
|
-
* @version
|
|
854
|
+
* @version 2.0.2
|
|
852
855
|
* @author Yusuke Kamiyamane
|
|
853
856
|
* @license MIT
|
|
854
857
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -860,7 +863,7 @@ function waitAnimationFinish(animation) {
|
|
|
860
863
|
(**
|
|
861
864
|
* Attributes Utils
|
|
862
865
|
*
|
|
863
|
-
* @version 1.1.
|
|
866
|
+
* @version 1.1.3
|
|
864
867
|
* @author Yusuke Kamiyamane
|
|
865
868
|
* @license MIT
|
|
866
869
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -873,7 +876,7 @@ power-focusable/dist/index.js:
|
|
|
873
876
|
* High-precision focus management utility with full composed tree support.
|
|
874
877
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
875
878
|
*
|
|
876
|
-
* @version 4.3.
|
|
879
|
+
* @version 4.3.8
|
|
877
880
|
* @author Yusuke Kamiyamane
|
|
878
881
|
* @license MIT
|
|
879
882
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -897,7 +900,7 @@ power-focusable/dist/index.js:
|
|
|
897
900
|
* Lightweight roving tabindex utility with fully focus management.
|
|
898
901
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
899
902
|
*
|
|
900
|
-
* @version 3.1.
|
|
903
|
+
* @version 3.1.6
|
|
901
904
|
* @author Yusuke Kamiyamane
|
|
902
905
|
* @license MIT
|
|
903
906
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.cjs
CHANGED
|
@@ -14,8 +14,9 @@ var Accordion = class _Accordion {
|
|
|
14
14
|
#rootElement;
|
|
15
15
|
#defaults = {
|
|
16
16
|
animation: { duration: 300, easing: "ease" },
|
|
17
|
+
collapsible: true,
|
|
17
18
|
selector: {
|
|
18
|
-
content: "
|
|
19
|
+
content: "[data-accordion-content]",
|
|
19
20
|
trigger: "[data-accordion-trigger]"
|
|
20
21
|
}
|
|
21
22
|
};
|
|
@@ -71,7 +72,7 @@ var Accordion = class _Accordion {
|
|
|
71
72
|
});
|
|
72
73
|
this.#initialize();
|
|
73
74
|
}
|
|
74
|
-
|
|
75
|
+
collapse(trigger) {
|
|
75
76
|
if (this.#isDestroyed) {
|
|
76
77
|
return;
|
|
77
78
|
}
|
|
@@ -106,7 +107,7 @@ var Accordion = class _Accordion {
|
|
|
106
107
|
this.#contentElements.length = 0;
|
|
107
108
|
this.#rootElement.removeAttribute("data-accordion-initialized");
|
|
108
109
|
}
|
|
109
|
-
|
|
110
|
+
expand(trigger) {
|
|
110
111
|
if (this.#isDestroyed) {
|
|
111
112
|
return;
|
|
112
113
|
}
|
|
@@ -191,21 +192,24 @@ var Accordion = class _Accordion {
|
|
|
191
192
|
}
|
|
192
193
|
binding.trigger.ariaExpanded === "false" && this.#toggle(binding.trigger, true, true);
|
|
193
194
|
};
|
|
194
|
-
#toggle(trigger,
|
|
195
|
-
if (trigger.ariaExpanded === String(
|
|
195
|
+
#toggle(trigger, isExpand, isMatch = false, isProgrammatic = false) {
|
|
196
|
+
if (trigger.ariaExpanded === String(isExpand)) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (!isExpand && !isProgrammatic && !this.#settings.collapsible && this.#triggerElements.filter((trigger2) => trigger2.ariaExpanded === "true").length <= 1) {
|
|
196
200
|
return;
|
|
197
201
|
}
|
|
198
202
|
const name = trigger.getAttribute("data-accordion-name");
|
|
199
|
-
if (name &&
|
|
200
|
-
const
|
|
203
|
+
if (name && isExpand) {
|
|
204
|
+
const expanded = this.#triggerElements.find(
|
|
201
205
|
(t) => t !== trigger && t.getAttribute("data-accordion-name") === name && t.ariaExpanded === "true"
|
|
202
206
|
);
|
|
203
|
-
|
|
207
|
+
expanded && this.#toggle(expanded, false, isMatch, true);
|
|
204
208
|
}
|
|
205
209
|
trigger.setAttribute(
|
|
206
210
|
"aria-label",
|
|
207
211
|
trigger.getAttribute(
|
|
208
|
-
`data-accordion-${
|
|
212
|
+
`data-accordion-${isExpand ? "expanded" : "collapsed"}-label`
|
|
209
213
|
) ?? trigger.ariaLabel ?? ""
|
|
210
214
|
);
|
|
211
215
|
const binding = this.#bindings.get(trigger);
|
|
@@ -217,7 +221,7 @@ var Accordion = class _Accordion {
|
|
|
217
221
|
if (content.hidden) {
|
|
218
222
|
content.hidden = false;
|
|
219
223
|
}
|
|
220
|
-
const endSize =
|
|
224
|
+
const endSize = isExpand ? content.scrollHeight : 0;
|
|
221
225
|
binding.animation?.cancel();
|
|
222
226
|
content.style.setProperty("overflow", "clip");
|
|
223
227
|
const { duration, easing } = this.#settings.animation;
|
|
@@ -226,7 +230,7 @@ var Accordion = class _Accordion {
|
|
|
226
230
|
{ duration: isMatch ? 0 : duration, easing }
|
|
227
231
|
);
|
|
228
232
|
binding.animation = animation;
|
|
229
|
-
trigger.setAttribute("aria-expanded", String(
|
|
233
|
+
trigger.setAttribute("aria-expanded", String(isExpand));
|
|
230
234
|
function cleanup() {
|
|
231
235
|
if (binding?.animation === animation) {
|
|
232
236
|
binding.animation = null;
|
|
@@ -254,6 +258,8 @@ var Accordion = class _Accordion {
|
|
|
254
258
|
}
|
|
255
259
|
#mergeOptions(target, source) {
|
|
256
260
|
return {
|
|
261
|
+
...target,
|
|
262
|
+
...source,
|
|
257
263
|
animation: { ...target.animation, ...source.animation ?? {} },
|
|
258
264
|
selector: { ...target.selector, ...source.selector ?? {} }
|
|
259
265
|
};
|
|
@@ -276,7 +282,7 @@ function waitAnimationFinish(animation) {
|
|
|
276
282
|
* Accordion
|
|
277
283
|
* WAI-ARIA compliant accordion pattern implementation in TypeScript.
|
|
278
284
|
*
|
|
279
|
-
* @version
|
|
285
|
+
* @version 2.0.2
|
|
280
286
|
* @author Yusuke Kamiyamane
|
|
281
287
|
* @license MIT
|
|
282
288
|
* @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
|
|
5
|
+
* @version 2.0.2
|
|
6
6
|
* @author Yusuke Kamiyamane
|
|
7
7
|
* @license MIT
|
|
8
8
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -13,6 +13,7 @@ interface AccordionOptions {
|
|
|
13
13
|
readonly duration?: number;
|
|
14
14
|
readonly easing?: string;
|
|
15
15
|
};
|
|
16
|
+
readonly collapsible?: boolean;
|
|
16
17
|
readonly selector?: {
|
|
17
18
|
readonly content?: string;
|
|
18
19
|
readonly trigger?: string;
|
|
@@ -22,9 +23,9 @@ declare class Accordion {
|
|
|
22
23
|
#private;
|
|
23
24
|
static defaults: AccordionOptions;
|
|
24
25
|
constructor(root: HTMLElement, options?: AccordionOptions);
|
|
25
|
-
|
|
26
|
+
collapse(trigger: HTMLElement): void;
|
|
26
27
|
destroy(force?: boolean): Promise<void>;
|
|
27
|
-
|
|
28
|
+
expand(trigger: HTMLElement): void;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export { type AccordionOptions, Accordion as default };
|
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
|
|
5
|
+
* @version 2.0.2
|
|
6
6
|
* @author Yusuke Kamiyamane
|
|
7
7
|
* @license MIT
|
|
8
8
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -13,6 +13,7 @@ interface AccordionOptions {
|
|
|
13
13
|
readonly duration?: number;
|
|
14
14
|
readonly easing?: string;
|
|
15
15
|
};
|
|
16
|
+
readonly collapsible?: boolean;
|
|
16
17
|
readonly selector?: {
|
|
17
18
|
readonly content?: string;
|
|
18
19
|
readonly trigger?: string;
|
|
@@ -22,9 +23,9 @@ declare class Accordion {
|
|
|
22
23
|
#private;
|
|
23
24
|
static defaults: AccordionOptions;
|
|
24
25
|
constructor(root: HTMLElement, options?: AccordionOptions);
|
|
25
|
-
|
|
26
|
+
collapse(trigger: HTMLElement): void;
|
|
26
27
|
destroy(force?: boolean): Promise<void>;
|
|
27
|
-
|
|
28
|
+
expand(trigger: HTMLElement): void;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export { type AccordionOptions, Accordion as default };
|
package/dist/index.js
CHANGED
|
@@ -8,8 +8,9 @@ var Accordion = class _Accordion {
|
|
|
8
8
|
#rootElement;
|
|
9
9
|
#defaults = {
|
|
10
10
|
animation: { duration: 300, easing: "ease" },
|
|
11
|
+
collapsible: true,
|
|
11
12
|
selector: {
|
|
12
|
-
content: "
|
|
13
|
+
content: "[data-accordion-content]",
|
|
13
14
|
trigger: "[data-accordion-trigger]"
|
|
14
15
|
}
|
|
15
16
|
};
|
|
@@ -65,7 +66,7 @@ var Accordion = class _Accordion {
|
|
|
65
66
|
});
|
|
66
67
|
this.#initialize();
|
|
67
68
|
}
|
|
68
|
-
|
|
69
|
+
collapse(trigger) {
|
|
69
70
|
if (this.#isDestroyed) {
|
|
70
71
|
return;
|
|
71
72
|
}
|
|
@@ -100,7 +101,7 @@ var Accordion = class _Accordion {
|
|
|
100
101
|
this.#contentElements.length = 0;
|
|
101
102
|
this.#rootElement.removeAttribute("data-accordion-initialized");
|
|
102
103
|
}
|
|
103
|
-
|
|
104
|
+
expand(trigger) {
|
|
104
105
|
if (this.#isDestroyed) {
|
|
105
106
|
return;
|
|
106
107
|
}
|
|
@@ -185,21 +186,24 @@ var Accordion = class _Accordion {
|
|
|
185
186
|
}
|
|
186
187
|
binding.trigger.ariaExpanded === "false" && this.#toggle(binding.trigger, true, true);
|
|
187
188
|
};
|
|
188
|
-
#toggle(trigger,
|
|
189
|
-
if (trigger.ariaExpanded === String(
|
|
189
|
+
#toggle(trigger, isExpand, isMatch = false, isProgrammatic = false) {
|
|
190
|
+
if (trigger.ariaExpanded === String(isExpand)) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (!isExpand && !isProgrammatic && !this.#settings.collapsible && this.#triggerElements.filter((trigger2) => trigger2.ariaExpanded === "true").length <= 1) {
|
|
190
194
|
return;
|
|
191
195
|
}
|
|
192
196
|
const name = trigger.getAttribute("data-accordion-name");
|
|
193
|
-
if (name &&
|
|
194
|
-
const
|
|
197
|
+
if (name && isExpand) {
|
|
198
|
+
const expanded = this.#triggerElements.find(
|
|
195
199
|
(t) => t !== trigger && t.getAttribute("data-accordion-name") === name && t.ariaExpanded === "true"
|
|
196
200
|
);
|
|
197
|
-
|
|
201
|
+
expanded && this.#toggle(expanded, false, isMatch, true);
|
|
198
202
|
}
|
|
199
203
|
trigger.setAttribute(
|
|
200
204
|
"aria-label",
|
|
201
205
|
trigger.getAttribute(
|
|
202
|
-
`data-accordion-${
|
|
206
|
+
`data-accordion-${isExpand ? "expanded" : "collapsed"}-label`
|
|
203
207
|
) ?? trigger.ariaLabel ?? ""
|
|
204
208
|
);
|
|
205
209
|
const binding = this.#bindings.get(trigger);
|
|
@@ -211,7 +215,7 @@ var Accordion = class _Accordion {
|
|
|
211
215
|
if (content.hidden) {
|
|
212
216
|
content.hidden = false;
|
|
213
217
|
}
|
|
214
|
-
const endSize =
|
|
218
|
+
const endSize = isExpand ? content.scrollHeight : 0;
|
|
215
219
|
binding.animation?.cancel();
|
|
216
220
|
content.style.setProperty("overflow", "clip");
|
|
217
221
|
const { duration, easing } = this.#settings.animation;
|
|
@@ -220,7 +224,7 @@ var Accordion = class _Accordion {
|
|
|
220
224
|
{ duration: isMatch ? 0 : duration, easing }
|
|
221
225
|
);
|
|
222
226
|
binding.animation = animation;
|
|
223
|
-
trigger.setAttribute("aria-expanded", String(
|
|
227
|
+
trigger.setAttribute("aria-expanded", String(isExpand));
|
|
224
228
|
function cleanup() {
|
|
225
229
|
if (binding?.animation === animation) {
|
|
226
230
|
binding.animation = null;
|
|
@@ -248,6 +252,8 @@ var Accordion = class _Accordion {
|
|
|
248
252
|
}
|
|
249
253
|
#mergeOptions(target, source) {
|
|
250
254
|
return {
|
|
255
|
+
...target,
|
|
256
|
+
...source,
|
|
251
257
|
animation: { ...target.animation, ...source.animation ?? {} },
|
|
252
258
|
selector: { ...target.selector, ...source.selector ?? {} }
|
|
253
259
|
};
|
|
@@ -270,7 +276,7 @@ function waitAnimationFinish(animation) {
|
|
|
270
276
|
* Accordion
|
|
271
277
|
* WAI-ARIA compliant accordion pattern implementation in TypeScript.
|
|
272
278
|
*
|
|
273
|
-
* @version
|
|
279
|
+
* @version 2.0.2
|
|
274
280
|
* @author Yusuke Kamiyamane
|
|
275
281
|
* @license MIT
|
|
276
282
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@y14e/accordion",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "WAI-ARIA compliant accordion pattern implementation in TypeScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"node": ">=18"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@y14e/attributes-utils": "^1.1.
|
|
55
|
+
"@y14e/attributes-utils": "^1.1.3",
|
|
56
56
|
"@y14e/button": "^1.0.6",
|
|
57
|
-
"@y14e/roving-tabindex": "^3.1.
|
|
57
|
+
"@y14e/roving-tabindex": "^3.1.6"
|
|
58
58
|
}
|
|
59
59
|
}
|