@y14e/accordion 1.4.11 → 1.4.13

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.11';
13
+ import Accordion from '@y14e/accordion@1.4.13';
14
14
 
15
15
  // CDNs
16
- import Accordion from 'https://esm.sh/@y14e/accordion@1.4.11';
16
+ import Accordion from 'https://esm.sh/@y14e/accordion@1.4.13';
17
17
  // or
18
- import Accordion from 'https://cdn.jsdelivr.net/npm/@y14e/accordion@1.4.11/+esm';
18
+ import Accordion from 'https://cdn.jsdelivr.net/npm/@y14e/accordion@1.4.13/+esm';
19
19
  // or
20
- import Accordion from 'https://esm.unpkg.com/@y14e/accordion@1.4.11';
20
+ import Accordion from 'https://esm.unpkg.com/@y14e/accordion@1.4.13';
21
21
  ```
22
22
 
23
23
  ## Usage
package/dist/index.cjs CHANGED
@@ -1,54 +1,5 @@
1
1
  'use strict';
2
2
 
3
- // node_modules/@y14e/attributes-utils/dist/index.js
4
- var DEFAULT_PARSER = (value) => value.split(/\s+/);
5
- var DEFAULT_SERIALIZER = (tokens) => tokens.join(" ");
6
- function addTokenToAttribute(element, attribute, token, options = {}) {
7
- const {
8
- caseInsensitive = false,
9
- parse = DEFAULT_PARSER,
10
- serialize = DEFAULT_SERIALIZER
11
- } = options;
12
- const value = element.getAttribute(attribute)?.trim();
13
- const tokens = value ? parse(value).filter(Boolean) : [];
14
- if (caseInsensitive) {
15
- const lower = token.toLowerCase();
16
- if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
17
- tokens.push(token);
18
- element.setAttribute(attribute, serialize(tokens));
19
- }
20
- } else {
21
- const set = new Set(tokens);
22
- set.add(token);
23
- element.setAttribute(attribute, serialize([...set]));
24
- }
25
- }
26
- var snapshots = /* @__PURE__ */ new WeakMap();
27
- function restoreAttributes(elements) {
28
- for (const element of elements) {
29
- const snapshot = snapshots.get(element);
30
- if (!snapshot) {
31
- continue;
32
- }
33
- for (const [attribute, value] of snapshot.entries()) {
34
- value === null ? element.removeAttribute(attribute) : element.setAttribute(attribute, value);
35
- }
36
- snapshots.delete(element);
37
- }
38
- }
39
- function saveAttributes(elements, attributes) {
40
- elements.forEach((element) => {
41
- let snapshot = snapshots.get(element);
42
- if (!snapshot) {
43
- snapshot = /* @__PURE__ */ new Map();
44
- snapshots.set(element, snapshot);
45
- }
46
- attributes.forEach((attribute) => {
47
- snapshot.set(attribute, element.getAttribute(attribute));
48
- });
49
- });
50
- }
51
-
52
3
  // node_modules/@y14e/button/dist/index.js
53
4
  var Button = class {
54
5
  #element;
@@ -106,13 +57,13 @@ function getActiveElement() {
106
57
  }
107
58
 
108
59
  // node_modules/@y14e/roving-tabindex/dist/index.js
109
- var DEFAULT_PARSER2 = (value) => value.split(/\s+/);
110
- var DEFAULT_SERIALIZER2 = (tokens) => tokens.join(" ");
111
- function addTokenToAttribute2(element, attribute, token, options = {}) {
60
+ var DEFAULT_PARSER = (value) => value.split(/\s+/);
61
+ var DEFAULT_SERIALIZER = (tokens) => tokens.join(" ");
62
+ function addTokenToAttribute(element, attribute, token, options = {}) {
112
63
  const {
113
64
  caseInsensitive = false,
114
- parse = DEFAULT_PARSER2,
115
- serialize = DEFAULT_SERIALIZER2
65
+ parse = DEFAULT_PARSER,
66
+ serialize = DEFAULT_SERIALIZER
116
67
  } = options;
117
68
  const value = element.getAttribute(attribute)?.trim();
118
69
  const tokens = value ? parse(value).filter(Boolean) : [];
@@ -128,25 +79,25 @@ function addTokenToAttribute2(element, attribute, token, options = {}) {
128
79
  element.setAttribute(attribute, serialize([...set]));
129
80
  }
130
81
  }
131
- var snapshots2 = /* @__PURE__ */ new WeakMap();
132
- function restoreAttributes2(elements) {
82
+ var snapshots = /* @__PURE__ */ new WeakMap();
83
+ function restoreAttributes(elements) {
133
84
  for (const element of elements) {
134
- const snapshot = snapshots2.get(element);
85
+ const snapshot = snapshots.get(element);
135
86
  if (!snapshot) {
136
87
  continue;
137
88
  }
138
89
  for (const [attribute, value] of snapshot.entries()) {
139
90
  value === null ? element.removeAttribute(attribute) : element.setAttribute(attribute, value);
140
91
  }
141
- snapshots2.delete(element);
92
+ snapshots.delete(element);
142
93
  }
143
94
  }
144
- function saveAttributes2(elements, attributes) {
95
+ function saveAttributes(elements, attributes) {
145
96
  elements.forEach((element) => {
146
- let snapshot = snapshots2.get(element);
97
+ let snapshot = snapshots.get(element);
147
98
  if (!snapshot) {
148
99
  snapshot = /* @__PURE__ */ new Map();
149
- snapshots2.set(element, snapshot);
100
+ snapshots.set(element, snapshot);
150
101
  }
151
102
  attributes.forEach((attribute) => {
152
103
  snapshot.set(attribute, element.getAttribute(attribute));
@@ -385,60 +336,12 @@ function createRovingTabIndex(container, options = {}) {
385
336
  return () => {
386
337
  };
387
338
  }
388
- let {
389
- direction,
390
- navigationOnly = false,
391
- noMemory = false,
392
- noStart = false,
393
- selector,
394
- typeahead = false,
395
- wrap = false
396
- } = options;
397
- if (typeof direction !== "undefined" && !["horizontal", "vertical"].includes(direction)) {
398
- console.warn("Invalid direction option. Fallback: both (undefined).");
399
- direction = void 0;
400
- }
401
- if (typeof navigationOnly !== "boolean") {
402
- console.warn("Invalid navigationOnly option. Fallback: false.");
403
- navigationOnly = false;
404
- }
405
- if (typeof noMemory !== "boolean") {
406
- console.warn("Invalid noMemory option. Fallback: false.");
407
- noMemory = false;
408
- }
409
- if (typeof noStart !== "boolean") {
410
- console.warn("Invalid noStart option. Fallback: false.");
411
- noStart = false;
412
- }
413
- if (typeof selector !== "undefined" && (typeof selector !== "string" || !selector.trim())) {
414
- console.warn(
415
- "Invalid selector. Fallback: all focusable elements (undefined)."
416
- );
417
- selector = void 0;
418
- }
419
- if (typeof typeahead !== "boolean") {
420
- console.warn("Invalid typeahead option. Fallback: false.");
421
- typeahead = false;
422
- }
423
- if (typeof wrap !== "boolean") {
424
- console.warn("Invalid wrap option. Fallback: false.");
425
- wrap = false;
426
- }
427
- const settings = {
428
- navigationOnly,
429
- noMemory,
430
- noStart,
431
- typeahead,
432
- wrap
433
- };
434
- direction && Object.assign(settings, { direction });
435
- selector && Object.assign(settings, { selector });
436
- const roving = new RovingTabIndex(container, settings);
339
+ const roving = new RovingTabIndex(container, options);
437
340
  return () => roving.destroy();
438
341
  }
439
342
  var RovingTabIndex = class {
440
343
  #container;
441
- #options;
344
+ #settings;
442
345
  #focusables = /* @__PURE__ */ new Set();
443
346
  #focusablesByFirstChar = /* @__PURE__ */ new Map();
444
347
  #selectorFilter;
@@ -446,7 +349,54 @@ var RovingTabIndex = class {
446
349
  #isDestroyed = false;
447
350
  constructor(container, options = {}) {
448
351
  this.#container = container;
449
- this.#options = options;
352
+ let {
353
+ direction,
354
+ navigationOnly = false,
355
+ noMemory = false,
356
+ noStart = false,
357
+ selector,
358
+ typeahead = false,
359
+ wrap = false
360
+ } = options;
361
+ if (typeof direction !== "undefined" && !["horizontal", "vertical"].includes(direction)) {
362
+ console.warn("Invalid direction option. Fallback: both (undefined).");
363
+ direction = void 0;
364
+ }
365
+ if (typeof navigationOnly !== "boolean") {
366
+ console.warn("Invalid navigationOnly option. Fallback: false.");
367
+ navigationOnly = false;
368
+ }
369
+ if (typeof noMemory !== "boolean") {
370
+ console.warn("Invalid noMemory option. Fallback: false.");
371
+ noMemory = false;
372
+ }
373
+ if (typeof noStart !== "boolean") {
374
+ console.warn("Invalid noStart option. Fallback: false.");
375
+ noStart = false;
376
+ }
377
+ if (typeof selector !== "undefined" && (typeof selector !== "string" || !selector.trim())) {
378
+ console.warn(
379
+ "Invalid selector. Fallback: all focusable elements (undefined)."
380
+ );
381
+ selector = void 0;
382
+ }
383
+ if (typeof typeahead !== "boolean") {
384
+ console.warn("Invalid typeahead option. Fallback: false.");
385
+ typeahead = false;
386
+ }
387
+ if (typeof wrap !== "boolean") {
388
+ console.warn("Invalid wrap option. Fallback: false.");
389
+ wrap = false;
390
+ }
391
+ this.#settings = {
392
+ navigationOnly,
393
+ noMemory,
394
+ noStart,
395
+ typeahead,
396
+ wrap
397
+ };
398
+ direction && Object.assign(this.#settings, { direction });
399
+ selector && Object.assign(this.#settings, { selector });
450
400
  this.#selectorFilter = this.#createSelectorFilter();
451
401
  this.#initialize();
452
402
  }
@@ -457,7 +407,7 @@ var RovingTabIndex = class {
457
407
  this.#isDestroyed = true;
458
408
  this.#controller?.abort();
459
409
  this.#controller = null;
460
- restoreAttributes2([...this.#focusables]);
410
+ restoreAttributes([...this.#focusables]);
461
411
  this.#focusables.clear();
462
412
  this.#focusablesByFirstChar.clear();
463
413
  this.#container.removeAttribute("data-roving-tabindex-initialized");
@@ -482,7 +432,7 @@ var RovingTabIndex = class {
482
432
  return;
483
433
  }
484
434
  const isFocusable22 = this.#focusables.has(target);
485
- this.#options.noMemory && !isFocusable22 ? this.#update(null) : isFocusable22 && this.#update(target);
435
+ this.#settings.noMemory && !isFocusable22 ? this.#update(null) : isFocusable22 && this.#update(target);
486
436
  };
487
437
  #onKeyDown = (event) => {
488
438
  if (!event.composedPath().includes(this.#container)) {
@@ -492,7 +442,7 @@ var RovingTabIndex = class {
492
442
  if (altKey || ctrlKey || metaKey || shiftKey) {
493
443
  return;
494
444
  }
495
- const { direction, typeahead, wrap } = this.#options;
445
+ const { direction, typeahead, wrap } = this.#settings;
496
446
  const isBoth = !direction;
497
447
  const isHorizontal = direction === "horizontal";
498
448
  if (![
@@ -551,7 +501,7 @@ var RovingTabIndex = class {
551
501
  const current = new Set(this.#getFocusables());
552
502
  for (const focusable of this.#focusables) {
553
503
  if (!current.has(focusable)) {
554
- focusable.isConnected && restoreAttributes2([focusable]);
504
+ focusable.isConnected && restoreAttributes([focusable]);
555
505
  this.#focusables.delete(focusable);
556
506
  this.#focusablesByFirstChar.forEach((focusables) => {
557
507
  const index = focusables.indexOf(focusable);
@@ -559,14 +509,14 @@ var RovingTabIndex = class {
559
509
  });
560
510
  }
561
511
  }
562
- const { navigationOnly, noStart, typeahead } = this.#options;
512
+ const { navigationOnly, noStart, typeahead } = this.#settings;
563
513
  for (const focusable of current) {
564
514
  if (this.#focusables.has(focusable)) {
565
515
  continue;
566
516
  }
567
517
  this.#focusables.add(focusable);
568
518
  if (!navigationOnly) {
569
- saveAttributes2([focusable], ["tabindex"]);
519
+ saveAttributes([focusable], ["tabindex"]);
570
520
  focusable.setAttribute("tabindex", "-1");
571
521
  }
572
522
  if (!typeahead) {
@@ -579,8 +529,8 @@ var RovingTabIndex = class {
579
529
  );
580
530
  if (char) {
581
531
  keys.add(char);
582
- saveAttributes2([focusable], ["aria-keyshortcuts"]);
583
- addTokenToAttribute2(focusable, "aria-keyshortcuts", char, {
532
+ saveAttributes([focusable], ["aria-keyshortcuts"]);
533
+ addTokenToAttribute(focusable, "aria-keyshortcuts", char, {
584
534
  caseInsensitive: true
585
535
  });
586
536
  }
@@ -603,14 +553,14 @@ var RovingTabIndex = class {
603
553
  }
604
554
  }
605
555
  #createSelectorFilter() {
606
- const { selector } = this.#options;
556
+ const { selector } = this.#settings;
607
557
  return (element) => !selector || [...this.#container.querySelectorAll(selector)].includes(element);
608
558
  }
609
559
  #getFocusables() {
610
560
  return getFocusables(this.#container, {
611
561
  composed: true,
612
562
  filter: this.#selectorFilter,
613
- skipNegativeTabIndexCheck: !this.#options.navigationOnly,
563
+ skipNegativeTabIndexCheck: !this.#settings.navigationOnly,
614
564
  skipVisibilityCheck: true
615
565
  });
616
566
  }
@@ -680,11 +630,12 @@ var Accordion = class _Accordion {
680
630
  }
681
631
  this.#triggerElements.forEach((trigger2, i) => {
682
632
  const content2 = this.#contentElements[i];
683
- if (content2) {
684
- const binding = createBinding(trigger2, content2);
685
- this.#bindings.set(trigger2, binding);
686
- this.#bindings.set(content2, binding);
633
+ if (!content2) {
634
+ return;
687
635
  }
636
+ const binding = createBinding(trigger2, content2);
637
+ this.#bindings.set(trigger2, binding);
638
+ this.#bindings.set(content2, binding);
688
639
  });
689
640
  this.#initialize();
690
641
  }
@@ -692,11 +643,11 @@ var Accordion = class _Accordion {
692
643
  if (this.#isDestroyed) {
693
644
  return;
694
645
  }
695
- if (!(trigger instanceof HTMLElement)) {
646
+ if (!(trigger instanceof HTMLElement) || !this.#bindings.has(trigger)) {
696
647
  console.warn("Invalid trigger element");
697
648
  return;
698
649
  }
699
- this.#bindings.has(trigger) && this.#toggle(trigger, false);
650
+ this.#toggle(trigger, false);
700
651
  }
701
652
  async destroy(force = false) {
702
653
  if (this.#isDestroyed) {
@@ -727,11 +678,11 @@ var Accordion = class _Accordion {
727
678
  if (this.#isDestroyed) {
728
679
  return;
729
680
  }
730
- if (!(trigger instanceof HTMLElement)) {
681
+ if (!(trigger instanceof HTMLElement) || !this.#bindings.has(trigger)) {
731
682
  console.warn("Invalid trigger element");
732
683
  return;
733
684
  }
734
- this.#bindings.has(trigger) && this.#toggle(trigger, true);
685
+ this.#toggle(trigger, true);
735
686
  }
736
687
  #initialize() {
737
688
  saveAttributes(this.#triggerElements, [
@@ -793,7 +744,10 @@ var Accordion = class _Accordion {
793
744
  return;
794
745
  }
795
746
  const binding = this.#bindings.get(content);
796
- binding && binding.trigger.ariaExpanded === "false" && this.#toggle(binding.trigger, true, true);
747
+ if (!binding) {
748
+ return;
749
+ }
750
+ binding.trigger.ariaExpanded === "false" && this.#toggle(binding.trigger, true, true);
797
751
  };
798
752
  #toggle(trigger, isOpen, isMatch = false) {
799
753
  if (trigger.ariaExpanded === String(isOpen)) {
@@ -858,7 +812,10 @@ var Accordion = class _Accordion {
858
812
  }
859
813
  #onAnimationFinish(content) {
860
814
  const trigger = this.#bindings.get(content)?.trigger;
861
- if (trigger && trigger.ariaExpanded === "false") {
815
+ if (!trigger) {
816
+ return;
817
+ }
818
+ if (trigger.ariaExpanded === "false") {
862
819
  content.setAttribute("hidden", "until-found");
863
820
  }
864
821
  ["block-size", "overflow"].forEach((name) => {
@@ -893,7 +850,7 @@ function waitAnimationFinish(animation) {
893
850
  * Accordion
894
851
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
895
852
  *
896
- * @version 1.4.11
853
+ * @version 1.4.12
897
854
  * @author Yusuke Kamiyamane
898
855
  * @license MIT
899
856
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -901,17 +858,6 @@ function waitAnimationFinish(animation) {
901
858
  */
902
859
  /*! Bundled license information:
903
860
 
904
- @y14e/attributes-utils/dist/index.js:
905
- (**
906
- * Attributes Utils
907
- *
908
- * @version 1.1.2
909
- * @author Yusuke Kamiyamane
910
- * @license MIT
911
- * @copyright Copyright (c) Yusuke Kamiyamane
912
- * @see {@link https://github.com/y14e/attributes-utils}
913
- *)
914
-
915
861
  @y14e/button/dist/index.js:
916
862
  (**
917
863
  * Button
@@ -929,7 +875,7 @@ function waitAnimationFinish(animation) {
929
875
  * Lightweight roving tabindex utility with fully focus management.
930
876
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
931
877
  *
932
- * @version 3.0.5
878
+ * @version 3.0.7
933
879
  * @author Yusuke Kamiyamane
934
880
  * @license MIT
935
881
  * @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.11
5
+ * @version 1.4.12
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.11
5
+ * @version 1.4.12
6
6
  * @author Yusuke Kamiyamane
7
7
  * @license MIT
8
8
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -1,52 +1,3 @@
1
- // node_modules/@y14e/attributes-utils/dist/index.js
2
- var DEFAULT_PARSER = (value) => value.split(/\s+/);
3
- var DEFAULT_SERIALIZER = (tokens) => tokens.join(" ");
4
- function addTokenToAttribute(element, attribute, token, options = {}) {
5
- const {
6
- caseInsensitive = false,
7
- parse = DEFAULT_PARSER,
8
- serialize = DEFAULT_SERIALIZER
9
- } = options;
10
- const value = element.getAttribute(attribute)?.trim();
11
- const tokens = value ? parse(value).filter(Boolean) : [];
12
- if (caseInsensitive) {
13
- const lower = token.toLowerCase();
14
- if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
15
- tokens.push(token);
16
- element.setAttribute(attribute, serialize(tokens));
17
- }
18
- } else {
19
- const set = new Set(tokens);
20
- set.add(token);
21
- element.setAttribute(attribute, serialize([...set]));
22
- }
23
- }
24
- var snapshots = /* @__PURE__ */ new WeakMap();
25
- function restoreAttributes(elements) {
26
- for (const element of elements) {
27
- const snapshot = snapshots.get(element);
28
- if (!snapshot) {
29
- continue;
30
- }
31
- for (const [attribute, value] of snapshot.entries()) {
32
- value === null ? element.removeAttribute(attribute) : element.setAttribute(attribute, value);
33
- }
34
- snapshots.delete(element);
35
- }
36
- }
37
- function saveAttributes(elements, attributes) {
38
- elements.forEach((element) => {
39
- let snapshot = snapshots.get(element);
40
- if (!snapshot) {
41
- snapshot = /* @__PURE__ */ new Map();
42
- snapshots.set(element, snapshot);
43
- }
44
- attributes.forEach((attribute) => {
45
- snapshot.set(attribute, element.getAttribute(attribute));
46
- });
47
- });
48
- }
49
-
50
1
  // node_modules/@y14e/button/dist/index.js
51
2
  var Button = class {
52
3
  #element;
@@ -104,13 +55,13 @@ function getActiveElement() {
104
55
  }
105
56
 
106
57
  // node_modules/@y14e/roving-tabindex/dist/index.js
107
- var DEFAULT_PARSER2 = (value) => value.split(/\s+/);
108
- var DEFAULT_SERIALIZER2 = (tokens) => tokens.join(" ");
109
- function addTokenToAttribute2(element, attribute, token, options = {}) {
58
+ var DEFAULT_PARSER = (value) => value.split(/\s+/);
59
+ var DEFAULT_SERIALIZER = (tokens) => tokens.join(" ");
60
+ function addTokenToAttribute(element, attribute, token, options = {}) {
110
61
  const {
111
62
  caseInsensitive = false,
112
- parse = DEFAULT_PARSER2,
113
- serialize = DEFAULT_SERIALIZER2
63
+ parse = DEFAULT_PARSER,
64
+ serialize = DEFAULT_SERIALIZER
114
65
  } = options;
115
66
  const value = element.getAttribute(attribute)?.trim();
116
67
  const tokens = value ? parse(value).filter(Boolean) : [];
@@ -126,25 +77,25 @@ function addTokenToAttribute2(element, attribute, token, options = {}) {
126
77
  element.setAttribute(attribute, serialize([...set]));
127
78
  }
128
79
  }
129
- var snapshots2 = /* @__PURE__ */ new WeakMap();
130
- function restoreAttributes2(elements) {
80
+ var snapshots = /* @__PURE__ */ new WeakMap();
81
+ function restoreAttributes(elements) {
131
82
  for (const element of elements) {
132
- const snapshot = snapshots2.get(element);
83
+ const snapshot = snapshots.get(element);
133
84
  if (!snapshot) {
134
85
  continue;
135
86
  }
136
87
  for (const [attribute, value] of snapshot.entries()) {
137
88
  value === null ? element.removeAttribute(attribute) : element.setAttribute(attribute, value);
138
89
  }
139
- snapshots2.delete(element);
90
+ snapshots.delete(element);
140
91
  }
141
92
  }
142
- function saveAttributes2(elements, attributes) {
93
+ function saveAttributes(elements, attributes) {
143
94
  elements.forEach((element) => {
144
- let snapshot = snapshots2.get(element);
95
+ let snapshot = snapshots.get(element);
145
96
  if (!snapshot) {
146
97
  snapshot = /* @__PURE__ */ new Map();
147
- snapshots2.set(element, snapshot);
98
+ snapshots.set(element, snapshot);
148
99
  }
149
100
  attributes.forEach((attribute) => {
150
101
  snapshot.set(attribute, element.getAttribute(attribute));
@@ -383,60 +334,12 @@ function createRovingTabIndex(container, options = {}) {
383
334
  return () => {
384
335
  };
385
336
  }
386
- let {
387
- direction,
388
- navigationOnly = false,
389
- noMemory = false,
390
- noStart = false,
391
- selector,
392
- typeahead = false,
393
- wrap = false
394
- } = options;
395
- if (typeof direction !== "undefined" && !["horizontal", "vertical"].includes(direction)) {
396
- console.warn("Invalid direction option. Fallback: both (undefined).");
397
- direction = void 0;
398
- }
399
- if (typeof navigationOnly !== "boolean") {
400
- console.warn("Invalid navigationOnly option. Fallback: false.");
401
- navigationOnly = false;
402
- }
403
- if (typeof noMemory !== "boolean") {
404
- console.warn("Invalid noMemory option. Fallback: false.");
405
- noMemory = false;
406
- }
407
- if (typeof noStart !== "boolean") {
408
- console.warn("Invalid noStart option. Fallback: false.");
409
- noStart = false;
410
- }
411
- if (typeof selector !== "undefined" && (typeof selector !== "string" || !selector.trim())) {
412
- console.warn(
413
- "Invalid selector. Fallback: all focusable elements (undefined)."
414
- );
415
- selector = void 0;
416
- }
417
- if (typeof typeahead !== "boolean") {
418
- console.warn("Invalid typeahead option. Fallback: false.");
419
- typeahead = false;
420
- }
421
- if (typeof wrap !== "boolean") {
422
- console.warn("Invalid wrap option. Fallback: false.");
423
- wrap = false;
424
- }
425
- const settings = {
426
- navigationOnly,
427
- noMemory,
428
- noStart,
429
- typeahead,
430
- wrap
431
- };
432
- direction && Object.assign(settings, { direction });
433
- selector && Object.assign(settings, { selector });
434
- const roving = new RovingTabIndex(container, settings);
337
+ const roving = new RovingTabIndex(container, options);
435
338
  return () => roving.destroy();
436
339
  }
437
340
  var RovingTabIndex = class {
438
341
  #container;
439
- #options;
342
+ #settings;
440
343
  #focusables = /* @__PURE__ */ new Set();
441
344
  #focusablesByFirstChar = /* @__PURE__ */ new Map();
442
345
  #selectorFilter;
@@ -444,7 +347,54 @@ var RovingTabIndex = class {
444
347
  #isDestroyed = false;
445
348
  constructor(container, options = {}) {
446
349
  this.#container = container;
447
- this.#options = options;
350
+ let {
351
+ direction,
352
+ navigationOnly = false,
353
+ noMemory = false,
354
+ noStart = false,
355
+ selector,
356
+ typeahead = false,
357
+ wrap = false
358
+ } = options;
359
+ if (typeof direction !== "undefined" && !["horizontal", "vertical"].includes(direction)) {
360
+ console.warn("Invalid direction option. Fallback: both (undefined).");
361
+ direction = void 0;
362
+ }
363
+ if (typeof navigationOnly !== "boolean") {
364
+ console.warn("Invalid navigationOnly option. Fallback: false.");
365
+ navigationOnly = false;
366
+ }
367
+ if (typeof noMemory !== "boolean") {
368
+ console.warn("Invalid noMemory option. Fallback: false.");
369
+ noMemory = false;
370
+ }
371
+ if (typeof noStart !== "boolean") {
372
+ console.warn("Invalid noStart option. Fallback: false.");
373
+ noStart = false;
374
+ }
375
+ if (typeof selector !== "undefined" && (typeof selector !== "string" || !selector.trim())) {
376
+ console.warn(
377
+ "Invalid selector. Fallback: all focusable elements (undefined)."
378
+ );
379
+ selector = void 0;
380
+ }
381
+ if (typeof typeahead !== "boolean") {
382
+ console.warn("Invalid typeahead option. Fallback: false.");
383
+ typeahead = false;
384
+ }
385
+ if (typeof wrap !== "boolean") {
386
+ console.warn("Invalid wrap option. Fallback: false.");
387
+ wrap = false;
388
+ }
389
+ this.#settings = {
390
+ navigationOnly,
391
+ noMemory,
392
+ noStart,
393
+ typeahead,
394
+ wrap
395
+ };
396
+ direction && Object.assign(this.#settings, { direction });
397
+ selector && Object.assign(this.#settings, { selector });
448
398
  this.#selectorFilter = this.#createSelectorFilter();
449
399
  this.#initialize();
450
400
  }
@@ -455,7 +405,7 @@ var RovingTabIndex = class {
455
405
  this.#isDestroyed = true;
456
406
  this.#controller?.abort();
457
407
  this.#controller = null;
458
- restoreAttributes2([...this.#focusables]);
408
+ restoreAttributes([...this.#focusables]);
459
409
  this.#focusables.clear();
460
410
  this.#focusablesByFirstChar.clear();
461
411
  this.#container.removeAttribute("data-roving-tabindex-initialized");
@@ -480,7 +430,7 @@ var RovingTabIndex = class {
480
430
  return;
481
431
  }
482
432
  const isFocusable22 = this.#focusables.has(target);
483
- this.#options.noMemory && !isFocusable22 ? this.#update(null) : isFocusable22 && this.#update(target);
433
+ this.#settings.noMemory && !isFocusable22 ? this.#update(null) : isFocusable22 && this.#update(target);
484
434
  };
485
435
  #onKeyDown = (event) => {
486
436
  if (!event.composedPath().includes(this.#container)) {
@@ -490,7 +440,7 @@ var RovingTabIndex = class {
490
440
  if (altKey || ctrlKey || metaKey || shiftKey) {
491
441
  return;
492
442
  }
493
- const { direction, typeahead, wrap } = this.#options;
443
+ const { direction, typeahead, wrap } = this.#settings;
494
444
  const isBoth = !direction;
495
445
  const isHorizontal = direction === "horizontal";
496
446
  if (![
@@ -549,7 +499,7 @@ var RovingTabIndex = class {
549
499
  const current = new Set(this.#getFocusables());
550
500
  for (const focusable of this.#focusables) {
551
501
  if (!current.has(focusable)) {
552
- focusable.isConnected && restoreAttributes2([focusable]);
502
+ focusable.isConnected && restoreAttributes([focusable]);
553
503
  this.#focusables.delete(focusable);
554
504
  this.#focusablesByFirstChar.forEach((focusables) => {
555
505
  const index = focusables.indexOf(focusable);
@@ -557,14 +507,14 @@ var RovingTabIndex = class {
557
507
  });
558
508
  }
559
509
  }
560
- const { navigationOnly, noStart, typeahead } = this.#options;
510
+ const { navigationOnly, noStart, typeahead } = this.#settings;
561
511
  for (const focusable of current) {
562
512
  if (this.#focusables.has(focusable)) {
563
513
  continue;
564
514
  }
565
515
  this.#focusables.add(focusable);
566
516
  if (!navigationOnly) {
567
- saveAttributes2([focusable], ["tabindex"]);
517
+ saveAttributes([focusable], ["tabindex"]);
568
518
  focusable.setAttribute("tabindex", "-1");
569
519
  }
570
520
  if (!typeahead) {
@@ -577,8 +527,8 @@ var RovingTabIndex = class {
577
527
  );
578
528
  if (char) {
579
529
  keys.add(char);
580
- saveAttributes2([focusable], ["aria-keyshortcuts"]);
581
- addTokenToAttribute2(focusable, "aria-keyshortcuts", char, {
530
+ saveAttributes([focusable], ["aria-keyshortcuts"]);
531
+ addTokenToAttribute(focusable, "aria-keyshortcuts", char, {
582
532
  caseInsensitive: true
583
533
  });
584
534
  }
@@ -601,14 +551,14 @@ var RovingTabIndex = class {
601
551
  }
602
552
  }
603
553
  #createSelectorFilter() {
604
- const { selector } = this.#options;
554
+ const { selector } = this.#settings;
605
555
  return (element) => !selector || [...this.#container.querySelectorAll(selector)].includes(element);
606
556
  }
607
557
  #getFocusables() {
608
558
  return getFocusables(this.#container, {
609
559
  composed: true,
610
560
  filter: this.#selectorFilter,
611
- skipNegativeTabIndexCheck: !this.#options.navigationOnly,
561
+ skipNegativeTabIndexCheck: !this.#settings.navigationOnly,
612
562
  skipVisibilityCheck: true
613
563
  });
614
564
  }
@@ -678,11 +628,12 @@ var Accordion = class _Accordion {
678
628
  }
679
629
  this.#triggerElements.forEach((trigger2, i) => {
680
630
  const content2 = this.#contentElements[i];
681
- if (content2) {
682
- const binding = createBinding(trigger2, content2);
683
- this.#bindings.set(trigger2, binding);
684
- this.#bindings.set(content2, binding);
631
+ if (!content2) {
632
+ return;
685
633
  }
634
+ const binding = createBinding(trigger2, content2);
635
+ this.#bindings.set(trigger2, binding);
636
+ this.#bindings.set(content2, binding);
686
637
  });
687
638
  this.#initialize();
688
639
  }
@@ -690,11 +641,11 @@ var Accordion = class _Accordion {
690
641
  if (this.#isDestroyed) {
691
642
  return;
692
643
  }
693
- if (!(trigger instanceof HTMLElement)) {
644
+ if (!(trigger instanceof HTMLElement) || !this.#bindings.has(trigger)) {
694
645
  console.warn("Invalid trigger element");
695
646
  return;
696
647
  }
697
- this.#bindings.has(trigger) && this.#toggle(trigger, false);
648
+ this.#toggle(trigger, false);
698
649
  }
699
650
  async destroy(force = false) {
700
651
  if (this.#isDestroyed) {
@@ -725,11 +676,11 @@ var Accordion = class _Accordion {
725
676
  if (this.#isDestroyed) {
726
677
  return;
727
678
  }
728
- if (!(trigger instanceof HTMLElement)) {
679
+ if (!(trigger instanceof HTMLElement) || !this.#bindings.has(trigger)) {
729
680
  console.warn("Invalid trigger element");
730
681
  return;
731
682
  }
732
- this.#bindings.has(trigger) && this.#toggle(trigger, true);
683
+ this.#toggle(trigger, true);
733
684
  }
734
685
  #initialize() {
735
686
  saveAttributes(this.#triggerElements, [
@@ -791,7 +742,10 @@ var Accordion = class _Accordion {
791
742
  return;
792
743
  }
793
744
  const binding = this.#bindings.get(content);
794
- binding && binding.trigger.ariaExpanded === "false" && this.#toggle(binding.trigger, true, true);
745
+ if (!binding) {
746
+ return;
747
+ }
748
+ binding.trigger.ariaExpanded === "false" && this.#toggle(binding.trigger, true, true);
795
749
  };
796
750
  #toggle(trigger, isOpen, isMatch = false) {
797
751
  if (trigger.ariaExpanded === String(isOpen)) {
@@ -856,7 +810,10 @@ var Accordion = class _Accordion {
856
810
  }
857
811
  #onAnimationFinish(content) {
858
812
  const trigger = this.#bindings.get(content)?.trigger;
859
- if (trigger && trigger.ariaExpanded === "false") {
813
+ if (!trigger) {
814
+ return;
815
+ }
816
+ if (trigger.ariaExpanded === "false") {
860
817
  content.setAttribute("hidden", "until-found");
861
818
  }
862
819
  ["block-size", "overflow"].forEach((name) => {
@@ -891,7 +848,7 @@ function waitAnimationFinish(animation) {
891
848
  * Accordion
892
849
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
893
850
  *
894
- * @version 1.4.11
851
+ * @version 1.4.12
895
852
  * @author Yusuke Kamiyamane
896
853
  * @license MIT
897
854
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -899,17 +856,6 @@ function waitAnimationFinish(animation) {
899
856
  */
900
857
  /*! Bundled license information:
901
858
 
902
- @y14e/attributes-utils/dist/index.js:
903
- (**
904
- * Attributes Utils
905
- *
906
- * @version 1.1.2
907
- * @author Yusuke Kamiyamane
908
- * @license MIT
909
- * @copyright Copyright (c) Yusuke Kamiyamane
910
- * @see {@link https://github.com/y14e/attributes-utils}
911
- *)
912
-
913
859
  @y14e/button/dist/index.js:
914
860
  (**
915
861
  * Button
@@ -927,7 +873,7 @@ function waitAnimationFinish(animation) {
927
873
  * Lightweight roving tabindex utility with fully focus management.
928
874
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
929
875
  *
930
- * @version 3.0.5
876
+ * @version 3.0.7
931
877
  * @author Yusuke Kamiyamane
932
878
  * @license MIT
933
879
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/accordion",
3
- "version": "1.4.11",
3
+ "version": "1.4.13",
4
4
  "description": "WAI-ARIA compliant accordion pattern implementation in TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -43,9 +43,8 @@
43
43
  },
44
44
  "homepage": "https://github.com/y14e/accordion#readme",
45
45
  "devDependencies": {
46
- "@y14e/attributes-utils": "^1.1.2",
47
46
  "@y14e/button": "^1.0.2",
48
- "@y14e/roving-tabindex": "^3.0.5",
47
+ "@y14e/roving-tabindex": "^3.0.7",
49
48
  "bun-types": "latest",
50
49
  "tsup": "^8.0.0",
51
50
  "typescript": "^5.6.0",