@y14e/accordion 2.1.2 → 2.1.4

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
@@ -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@2.1.2';
16
+ import { Accordion } from 'https://esm.sh/@y14e/accordion@2.1.4';
17
17
  // or
18
- import { Accordion } from 'https://cdn.jsdelivr.net/npm/@y14e/accordion@2.1.2/+esm';
18
+ import { Accordion } from 'https://cdn.jsdelivr.net/npm/@y14e/accordion@2.1.4/+esm';
19
19
  // or
20
- import { Accordion } from 'https://esm.unpkg.com/@y14e/accordion@2.1.2';
20
+ import { Accordion } from 'https://esm.unpkg.com/@y14e/accordion@2.1.4';
21
21
  ```
22
22
 
23
23
  ## Usage
@@ -207,31 +207,25 @@ function normalizeRadioGroup(elements) {
207
207
  map = /* @__PURE__ */ new Map();
208
208
  }
209
209
  const root = element.getRootNode();
210
- let groups = map.get(root);
210
+ const groups = map.get(root) ?? map.set(root, /* @__PURE__ */ new Map()).get(root);
211
211
  if (!groups) {
212
- groups = /* @__PURE__ */ new Map();
213
- map.set(root, groups);
214
- }
215
- let group = groups.get(element.form);
216
- if (!group) {
217
- group = /* @__PURE__ */ new Map();
218
- groups.set(element.form, group);
212
+ continue;
219
213
  }
220
- let radios = group.get(element.name);
214
+ const { form, name } = element;
215
+ const radios = groups.get(form) ?? groups.set(form, /* @__PURE__ */ new Map()).get(form);
221
216
  if (!radios) {
222
- radios = [];
223
- group.set(element.name, radios);
217
+ continue;
224
218
  }
225
- radios.push(element);
219
+ (radios.get(name) ?? radios.set(name, []).get(name))?.push(element);
226
220
  }
227
221
  if (!map) {
228
222
  return elements;
229
223
  }
230
224
  const placeholder = /* @__PURE__ */ new Set();
231
- for (const groups of map.values()) {
232
- for (const group of groups.values()) {
233
- for (const radios of group.values()) {
234
- const radio = radios.find((r) => r.checked) ?? radios[0];
225
+ for (const v of map.values()) {
226
+ for (const w of v.values()) {
227
+ for (const x of w.values()) {
228
+ const radio = x.find((r) => r.checked) ?? x[0];
235
229
  radio && placeholder.add(radio);
236
230
  }
237
231
  }
@@ -407,8 +401,8 @@ function createRovingTabIndex(container, options = {}) {
407
401
  return () => {
408
402
  };
409
403
  }
410
- const roving = new RovingTabIndex(container, options);
411
- return () => roving.destroy();
404
+ const rovingTabIndex = new RovingTabIndex(container, options);
405
+ return () => rovingTabIndex.destroy();
412
406
  }
413
407
  var RovingTabIndex = class _RovingTabIndex {
414
408
  static #initialized = /* @__PURE__ */ new Set();
@@ -467,18 +461,19 @@ var RovingTabIndex = class _RovingTabIndex {
467
461
  if (!(event instanceof KeyboardEvent)) {
468
462
  return;
469
463
  }
464
+ const { direction, typeahead, wrap = false } = this.#settings;
465
+ const isGrid = direction === "grid";
470
466
  const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
471
- if (altKey || ctrlKey || metaKey || shiftKey) {
467
+ if (!(isGrid && ["End", "Home"].includes(key)) && ctrlKey || altKey || metaKey || shiftKey) {
472
468
  return;
473
469
  }
474
- const { direction, typeahead, wrap } = this.#settings;
475
470
  const isBoth = direction === "both";
476
471
  const isHorizontal = direction === "horizontal";
477
472
  if (![
478
473
  "End",
479
474
  "Home",
480
- ...isBoth ? ["ArrowLeft", "ArrowUp"] : [`Arrow${isHorizontal ? "Left" : "Up"}`],
481
- ...isBoth ? ["ArrowRight", "ArrowDown"] : [`Arrow${isHorizontal ? "Right" : "Down"}`]
475
+ ...isGrid || isBoth ? ["ArrowLeft", "ArrowUp"] : [`Arrow${isHorizontal ? "Left" : "Up"}`],
476
+ ...isGrid || isBoth ? ["ArrowRight", "ArrowDown"] : [`Arrow${isHorizontal ? "Right" : "Down"}`]
482
477
  ].includes(key)) {
483
478
  if (!typeahead || !/^\S$/i.test(key) || !this.#focusablesByFirstChar.has(key.toUpperCase())) {
484
479
  return;
@@ -497,39 +492,48 @@ var RovingTabIndex = class _RovingTabIndex {
497
492
  event.preventDefault();
498
493
  let newIndex;
499
494
  const activeIndex = candidates.indexOf(active);
500
- let focusables = candidates;
495
+ let target = candidates;
501
496
  switch (key) {
502
497
  case "End":
503
- newIndex = -1;
504
- break;
505
- case "Home":
506
- newIndex = 0;
507
- break;
508
- case "ArrowLeft":
509
- case "ArrowUp": {
510
- const rawIndex = activeIndex - 1;
511
- newIndex = wrap ? rawIndex : Math.max(rawIndex, 0);
498
+ case "Home": {
499
+ const rawIndex = key === "End" ? -1 : 0;
500
+ if (isGrid && !ctrlKey) {
501
+ const cell = this.#getCellsOfActiveRow().at(rawIndex);
502
+ newIndex = cell ? candidates.indexOf(cell) : activeIndex;
503
+ } else {
504
+ newIndex = rawIndex;
505
+ }
512
506
  break;
513
507
  }
508
+ case "ArrowLeft":
509
+ case "ArrowUp":
514
510
  case "ArrowRight":
515
511
  case "ArrowDown": {
516
- const rawIndex = activeIndex + 1;
517
- const length = focusables.length;
518
- newIndex = wrap ? rawIndex % length : Math.min(rawIndex, length - 1);
512
+ if (["ArrowUp", "ArrowDown"].includes(key) && isGrid) {
513
+ const cell = this.#getNextCell(key, wrap);
514
+ newIndex = cell ? candidates.indexOf(cell) : activeIndex;
515
+ } else {
516
+ if (isGrid) {
517
+ target = this.#getCellsOfActiveRow();
518
+ }
519
+ const isPrevious = ["ArrowLeft", "ArrowUp"].includes(key);
520
+ const rawIndex = (isGrid ? target.indexOf(active) : activeIndex) + (isPrevious ? -1 : 1);
521
+ newIndex = isPrevious ? wrap ? rawIndex : Math.max(rawIndex, 0) : wrap ? rawIndex % target.length : Math.min(rawIndex, target.length - 1);
522
+ }
519
523
  break;
520
524
  }
521
525
  default: {
522
526
  const focusablesByFirstChar = new Set(
523
527
  this.#focusablesByFirstChar.get(key.toUpperCase()) ?? []
524
528
  );
525
- focusables = candidates.filter((c) => focusablesByFirstChar.has(c));
526
- const afterIndex = focusables.findIndex(
529
+ target = candidates.filter((c) => focusablesByFirstChar.has(c));
530
+ const afterIndex = target.findIndex(
527
531
  (f) => candidates.indexOf(f) > activeIndex
528
532
  );
529
533
  newIndex = afterIndex >= 0 ? afterIndex : 0;
530
534
  }
531
535
  }
532
- const focusable = focusables.at(newIndex);
536
+ const focusable = target.at(newIndex);
533
537
  focusable && focusElement(focusable);
534
538
  };
535
539
  #update(active) {
@@ -599,6 +603,24 @@ var RovingTabIndex = class _RovingTabIndex {
599
603
  const { selector } = this.#settings;
600
604
  return (element) => !selector || [...this.#container.querySelectorAll(selector)].includes(element);
601
605
  }
606
+ #getCellCoords(cell) {
607
+ const { height, left, top, width } = cell.getBoundingClientRect();
608
+ return {
609
+ x: left + width / 2,
610
+ y: top + height / 2
611
+ };
612
+ }
613
+ #getCellsOfActiveRow() {
614
+ const active = getActiveElement();
615
+ if (!(active instanceof Element)) {
616
+ return [];
617
+ }
618
+ const activeRect = active.getBoundingClientRect();
619
+ return this.#getFocusables().filter((cell) => {
620
+ const cellRect = cell.getBoundingClientRect();
621
+ return cellRect.top < activeRect.bottom && cellRect.bottom > activeRect.top;
622
+ });
623
+ }
602
624
  #getFocusables() {
603
625
  return getFocusables(this.#container, {
604
626
  composed: true,
@@ -607,6 +629,50 @@ var RovingTabIndex = class _RovingTabIndex {
607
629
  skipVisibilityCheck: true
608
630
  });
609
631
  }
632
+ #getNextCell(key, wrap) {
633
+ const cells = this.#getFocusables();
634
+ const active = getActiveElement();
635
+ if (!(active instanceof Element)) {
636
+ return null;
637
+ }
638
+ const activeCoords = this.#getCellCoords(active);
639
+ let min = Infinity;
640
+ let result = null;
641
+ for (const cell of cells) {
642
+ if (cell === active) {
643
+ continue;
644
+ }
645
+ const cellCoords = this.#getCellCoords(cell);
646
+ const distances = {
647
+ x: Math.abs(cellCoords.x - activeCoords.x),
648
+ y: Math.abs(cellCoords.y - activeCoords.y)
649
+ };
650
+ if (key === "ArrowUp" && cellCoords.y < activeCoords.y && distances.x < distances.y || key === "ArrowDown" && cellCoords.y > activeCoords.y && distances.x < distances.y) {
651
+ const distance = distances.x ** 2 + distances.y ** 2;
652
+ if (distance < min) {
653
+ min = distance;
654
+ result = cell;
655
+ }
656
+ }
657
+ }
658
+ if (!result && wrap) {
659
+ let max = -Infinity;
660
+ for (const cell of cells) {
661
+ if (cell === active) {
662
+ continue;
663
+ }
664
+ const cellCoords = this.#getCellCoords(cell);
665
+ if (Math.abs(cellCoords.x - activeCoords.x) < cell.getBoundingClientRect().width / 2) {
666
+ const distance = key === "ArrowUp" ? cellCoords.y - activeCoords.y : activeCoords.y - cellCoords.y;
667
+ if (distance > max) {
668
+ max = distance;
669
+ result = cell;
670
+ }
671
+ }
672
+ }
673
+ }
674
+ return result;
675
+ }
610
676
  #resolveOptions(options) {
611
677
  let {
612
678
  direction = "both",
@@ -618,7 +684,7 @@ var RovingTabIndex = class _RovingTabIndex {
618
684
  wrap = false
619
685
  } = options;
620
686
  direction = direction.toLowerCase();
621
- if (!["both", "horizontal", "vertical"].includes(direction)) {
687
+ if (!["both", "grid", "horizontal", "vertical"].includes(direction)) {
622
688
  console.warn("Invalid direction option. Fallback: 'both'.");
623
689
  direction = "both";
624
690
  }
@@ -945,19 +1011,18 @@ var Accordion = class _Accordion {
945
1011
  }
946
1012
  const mergedSelector = merged.selector;
947
1013
  const defaultSelector = defaults.selector;
948
- try {
949
- document.querySelector(mergedSelector.content);
950
- } catch {
951
- const content = defaultSelector.content;
952
- console.warn(`Invalid content selector. Fallback: '${content}'.`);
953
- mergedSelector.content = content;
954
- }
955
- try {
956
- document.querySelector(mergedSelector.trigger);
957
- } catch {
958
- const trigger = defaultSelector.trigger;
959
- console.warn(`Invalid trigger selector. Fallback: '${trigger}'.`);
960
- mergedSelector.trigger = trigger;
1014
+ for (const key of Object.keys(
1015
+ defaultSelector
1016
+ )) {
1017
+ try {
1018
+ document.querySelector(mergedSelector[key]);
1019
+ } catch {
1020
+ const selector = defaultSelector[key];
1021
+ console.warn(
1022
+ `Invalid ${key.replace(/[A-Z]/g, (c) => ` ${c.toLowerCase()}`)} selector. Fallback: '${selector}'.`
1023
+ );
1024
+ mergedSelector[key] = selector;
1025
+ }
961
1026
  }
962
1027
  return merged;
963
1028
  }
@@ -979,7 +1044,7 @@ function waitAnimationFinish(animation) {
979
1044
  * Accordion
980
1045
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
981
1046
  *
982
- * @version 2.1.2
1047
+ * @version 2.1.3
983
1048
  * @author Yusuke Kamiyamane
984
1049
  * @license MIT
985
1050
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1004,7 +1069,7 @@ power-focusable/dist/index.js:
1004
1069
  * High-precision focus management utility with full composed tree support.
1005
1070
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
1006
1071
  *
1007
- * @version 4.3.33
1072
+ * @version 4.4.2
1008
1073
  * @author Yusuke Kamiyamane
1009
1074
  * @license MIT
1010
1075
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1028,7 +1093,7 @@ power-focusable/dist/index.js:
1028
1093
  * Lightweight roving tabindex utility with fully focus management.
1029
1094
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
1030
1095
  *
1031
- * @version 3.1.31
1096
+ * @version 3.3.1
1032
1097
  * @author Yusuke Kamiyamane
1033
1098
  * @license MIT
1034
1099
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -205,31 +205,25 @@ function normalizeRadioGroup(elements) {
205
205
  map = /* @__PURE__ */ new Map();
206
206
  }
207
207
  const root = element.getRootNode();
208
- let groups = map.get(root);
208
+ const groups = map.get(root) ?? map.set(root, /* @__PURE__ */ new Map()).get(root);
209
209
  if (!groups) {
210
- groups = /* @__PURE__ */ new Map();
211
- map.set(root, groups);
212
- }
213
- let group = groups.get(element.form);
214
- if (!group) {
215
- group = /* @__PURE__ */ new Map();
216
- groups.set(element.form, group);
210
+ continue;
217
211
  }
218
- let radios = group.get(element.name);
212
+ const { form, name } = element;
213
+ const radios = groups.get(form) ?? groups.set(form, /* @__PURE__ */ new Map()).get(form);
219
214
  if (!radios) {
220
- radios = [];
221
- group.set(element.name, radios);
215
+ continue;
222
216
  }
223
- radios.push(element);
217
+ (radios.get(name) ?? radios.set(name, []).get(name))?.push(element);
224
218
  }
225
219
  if (!map) {
226
220
  return elements;
227
221
  }
228
222
  const placeholder = /* @__PURE__ */ new Set();
229
- for (const groups of map.values()) {
230
- for (const group of groups.values()) {
231
- for (const radios of group.values()) {
232
- const radio = radios.find((r) => r.checked) ?? radios[0];
223
+ for (const v of map.values()) {
224
+ for (const w of v.values()) {
225
+ for (const x of w.values()) {
226
+ const radio = x.find((r) => r.checked) ?? x[0];
233
227
  radio && placeholder.add(radio);
234
228
  }
235
229
  }
@@ -405,8 +399,8 @@ function createRovingTabIndex(container, options = {}) {
405
399
  return () => {
406
400
  };
407
401
  }
408
- const roving = new RovingTabIndex(container, options);
409
- return () => roving.destroy();
402
+ const rovingTabIndex = new RovingTabIndex(container, options);
403
+ return () => rovingTabIndex.destroy();
410
404
  }
411
405
  var RovingTabIndex = class _RovingTabIndex {
412
406
  static #initialized = /* @__PURE__ */ new Set();
@@ -465,18 +459,19 @@ var RovingTabIndex = class _RovingTabIndex {
465
459
  if (!(event instanceof KeyboardEvent)) {
466
460
  return;
467
461
  }
462
+ const { direction, typeahead, wrap = false } = this.#settings;
463
+ const isGrid = direction === "grid";
468
464
  const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
469
- if (altKey || ctrlKey || metaKey || shiftKey) {
465
+ if (!(isGrid && ["End", "Home"].includes(key)) && ctrlKey || altKey || metaKey || shiftKey) {
470
466
  return;
471
467
  }
472
- const { direction, typeahead, wrap } = this.#settings;
473
468
  const isBoth = direction === "both";
474
469
  const isHorizontal = direction === "horizontal";
475
470
  if (![
476
471
  "End",
477
472
  "Home",
478
- ...isBoth ? ["ArrowLeft", "ArrowUp"] : [`Arrow${isHorizontal ? "Left" : "Up"}`],
479
- ...isBoth ? ["ArrowRight", "ArrowDown"] : [`Arrow${isHorizontal ? "Right" : "Down"}`]
473
+ ...isGrid || isBoth ? ["ArrowLeft", "ArrowUp"] : [`Arrow${isHorizontal ? "Left" : "Up"}`],
474
+ ...isGrid || isBoth ? ["ArrowRight", "ArrowDown"] : [`Arrow${isHorizontal ? "Right" : "Down"}`]
480
475
  ].includes(key)) {
481
476
  if (!typeahead || !/^\S$/i.test(key) || !this.#focusablesByFirstChar.has(key.toUpperCase())) {
482
477
  return;
@@ -495,39 +490,48 @@ var RovingTabIndex = class _RovingTabIndex {
495
490
  event.preventDefault();
496
491
  let newIndex;
497
492
  const activeIndex = candidates.indexOf(active);
498
- let focusables = candidates;
493
+ let target = candidates;
499
494
  switch (key) {
500
495
  case "End":
501
- newIndex = -1;
502
- break;
503
- case "Home":
504
- newIndex = 0;
505
- break;
506
- case "ArrowLeft":
507
- case "ArrowUp": {
508
- const rawIndex = activeIndex - 1;
509
- newIndex = wrap ? rawIndex : Math.max(rawIndex, 0);
496
+ case "Home": {
497
+ const rawIndex = key === "End" ? -1 : 0;
498
+ if (isGrid && !ctrlKey) {
499
+ const cell = this.#getCellsOfActiveRow().at(rawIndex);
500
+ newIndex = cell ? candidates.indexOf(cell) : activeIndex;
501
+ } else {
502
+ newIndex = rawIndex;
503
+ }
510
504
  break;
511
505
  }
506
+ case "ArrowLeft":
507
+ case "ArrowUp":
512
508
  case "ArrowRight":
513
509
  case "ArrowDown": {
514
- const rawIndex = activeIndex + 1;
515
- const length = focusables.length;
516
- newIndex = wrap ? rawIndex % length : Math.min(rawIndex, length - 1);
510
+ if (["ArrowUp", "ArrowDown"].includes(key) && isGrid) {
511
+ const cell = this.#getNextCell(key, wrap);
512
+ newIndex = cell ? candidates.indexOf(cell) : activeIndex;
513
+ } else {
514
+ if (isGrid) {
515
+ target = this.#getCellsOfActiveRow();
516
+ }
517
+ const isPrevious = ["ArrowLeft", "ArrowUp"].includes(key);
518
+ const rawIndex = (isGrid ? target.indexOf(active) : activeIndex) + (isPrevious ? -1 : 1);
519
+ newIndex = isPrevious ? wrap ? rawIndex : Math.max(rawIndex, 0) : wrap ? rawIndex % target.length : Math.min(rawIndex, target.length - 1);
520
+ }
517
521
  break;
518
522
  }
519
523
  default: {
520
524
  const focusablesByFirstChar = new Set(
521
525
  this.#focusablesByFirstChar.get(key.toUpperCase()) ?? []
522
526
  );
523
- focusables = candidates.filter((c) => focusablesByFirstChar.has(c));
524
- const afterIndex = focusables.findIndex(
527
+ target = candidates.filter((c) => focusablesByFirstChar.has(c));
528
+ const afterIndex = target.findIndex(
525
529
  (f) => candidates.indexOf(f) > activeIndex
526
530
  );
527
531
  newIndex = afterIndex >= 0 ? afterIndex : 0;
528
532
  }
529
533
  }
530
- const focusable = focusables.at(newIndex);
534
+ const focusable = target.at(newIndex);
531
535
  focusable && focusElement(focusable);
532
536
  };
533
537
  #update(active) {
@@ -597,6 +601,24 @@ var RovingTabIndex = class _RovingTabIndex {
597
601
  const { selector } = this.#settings;
598
602
  return (element) => !selector || [...this.#container.querySelectorAll(selector)].includes(element);
599
603
  }
604
+ #getCellCoords(cell) {
605
+ const { height, left, top, width } = cell.getBoundingClientRect();
606
+ return {
607
+ x: left + width / 2,
608
+ y: top + height / 2
609
+ };
610
+ }
611
+ #getCellsOfActiveRow() {
612
+ const active = getActiveElement();
613
+ if (!(active instanceof Element)) {
614
+ return [];
615
+ }
616
+ const activeRect = active.getBoundingClientRect();
617
+ return this.#getFocusables().filter((cell) => {
618
+ const cellRect = cell.getBoundingClientRect();
619
+ return cellRect.top < activeRect.bottom && cellRect.bottom > activeRect.top;
620
+ });
621
+ }
600
622
  #getFocusables() {
601
623
  return getFocusables(this.#container, {
602
624
  composed: true,
@@ -605,6 +627,50 @@ var RovingTabIndex = class _RovingTabIndex {
605
627
  skipVisibilityCheck: true
606
628
  });
607
629
  }
630
+ #getNextCell(key, wrap) {
631
+ const cells = this.#getFocusables();
632
+ const active = getActiveElement();
633
+ if (!(active instanceof Element)) {
634
+ return null;
635
+ }
636
+ const activeCoords = this.#getCellCoords(active);
637
+ let min = Infinity;
638
+ let result = null;
639
+ for (const cell of cells) {
640
+ if (cell === active) {
641
+ continue;
642
+ }
643
+ const cellCoords = this.#getCellCoords(cell);
644
+ const distances = {
645
+ x: Math.abs(cellCoords.x - activeCoords.x),
646
+ y: Math.abs(cellCoords.y - activeCoords.y)
647
+ };
648
+ if (key === "ArrowUp" && cellCoords.y < activeCoords.y && distances.x < distances.y || key === "ArrowDown" && cellCoords.y > activeCoords.y && distances.x < distances.y) {
649
+ const distance = distances.x ** 2 + distances.y ** 2;
650
+ if (distance < min) {
651
+ min = distance;
652
+ result = cell;
653
+ }
654
+ }
655
+ }
656
+ if (!result && wrap) {
657
+ let max = -Infinity;
658
+ for (const cell of cells) {
659
+ if (cell === active) {
660
+ continue;
661
+ }
662
+ const cellCoords = this.#getCellCoords(cell);
663
+ if (Math.abs(cellCoords.x - activeCoords.x) < cell.getBoundingClientRect().width / 2) {
664
+ const distance = key === "ArrowUp" ? cellCoords.y - activeCoords.y : activeCoords.y - cellCoords.y;
665
+ if (distance > max) {
666
+ max = distance;
667
+ result = cell;
668
+ }
669
+ }
670
+ }
671
+ }
672
+ return result;
673
+ }
608
674
  #resolveOptions(options) {
609
675
  let {
610
676
  direction = "both",
@@ -616,7 +682,7 @@ var RovingTabIndex = class _RovingTabIndex {
616
682
  wrap = false
617
683
  } = options;
618
684
  direction = direction.toLowerCase();
619
- if (!["both", "horizontal", "vertical"].includes(direction)) {
685
+ if (!["both", "grid", "horizontal", "vertical"].includes(direction)) {
620
686
  console.warn("Invalid direction option. Fallback: 'both'.");
621
687
  direction = "both";
622
688
  }
@@ -943,19 +1009,18 @@ var Accordion = class _Accordion {
943
1009
  }
944
1010
  const mergedSelector = merged.selector;
945
1011
  const defaultSelector = defaults.selector;
946
- try {
947
- document.querySelector(mergedSelector.content);
948
- } catch {
949
- const content = defaultSelector.content;
950
- console.warn(`Invalid content selector. Fallback: '${content}'.`);
951
- mergedSelector.content = content;
952
- }
953
- try {
954
- document.querySelector(mergedSelector.trigger);
955
- } catch {
956
- const trigger = defaultSelector.trigger;
957
- console.warn(`Invalid trigger selector. Fallback: '${trigger}'.`);
958
- mergedSelector.trigger = trigger;
1012
+ for (const key of Object.keys(
1013
+ defaultSelector
1014
+ )) {
1015
+ try {
1016
+ document.querySelector(mergedSelector[key]);
1017
+ } catch {
1018
+ const selector = defaultSelector[key];
1019
+ console.warn(
1020
+ `Invalid ${key.replace(/[A-Z]/g, (c) => ` ${c.toLowerCase()}`)} selector. Fallback: '${selector}'.`
1021
+ );
1022
+ mergedSelector[key] = selector;
1023
+ }
959
1024
  }
960
1025
  return merged;
961
1026
  }
@@ -977,7 +1042,7 @@ function waitAnimationFinish(animation) {
977
1042
  * Accordion
978
1043
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
979
1044
  *
980
- * @version 2.1.2
1045
+ * @version 2.1.3
981
1046
  * @author Yusuke Kamiyamane
982
1047
  * @license MIT
983
1048
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1002,7 +1067,7 @@ power-focusable/dist/index.js:
1002
1067
  * High-precision focus management utility with full composed tree support.
1003
1068
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
1004
1069
  *
1005
- * @version 4.3.33
1070
+ * @version 4.4.2
1006
1071
  * @author Yusuke Kamiyamane
1007
1072
  * @license MIT
1008
1073
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1026,7 +1091,7 @@ power-focusable/dist/index.js:
1026
1091
  * Lightweight roving tabindex utility with fully focus management.
1027
1092
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
1028
1093
  *
1029
- * @version 3.1.31
1094
+ * @version 3.3.1
1030
1095
  * @author Yusuke Kamiyamane
1031
1096
  * @license MIT
1032
1097
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.cjs CHANGED
@@ -287,19 +287,18 @@ var Accordion = class _Accordion {
287
287
  }
288
288
  const mergedSelector = merged.selector;
289
289
  const defaultSelector = defaults.selector;
290
- try {
291
- document.querySelector(mergedSelector.content);
292
- } catch {
293
- const content = defaultSelector.content;
294
- console.warn(`Invalid content selector. Fallback: '${content}'.`);
295
- mergedSelector.content = content;
296
- }
297
- try {
298
- document.querySelector(mergedSelector.trigger);
299
- } catch {
300
- const trigger = defaultSelector.trigger;
301
- console.warn(`Invalid trigger selector. Fallback: '${trigger}'.`);
302
- mergedSelector.trigger = trigger;
290
+ for (const key of Object.keys(
291
+ defaultSelector
292
+ )) {
293
+ try {
294
+ document.querySelector(mergedSelector[key]);
295
+ } catch {
296
+ const selector = defaultSelector[key];
297
+ console.warn(
298
+ `Invalid ${key.replace(/[A-Z]/g, (c) => ` ${c.toLowerCase()}`)} selector. Fallback: '${selector}'.`
299
+ );
300
+ mergedSelector[key] = selector;
301
+ }
303
302
  }
304
303
  return merged;
305
304
  }
@@ -321,7 +320,7 @@ function waitAnimationFinish(animation) {
321
320
  * Accordion
322
321
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
323
322
  *
324
- * @version 2.1.2
323
+ * @version 2.1.3
325
324
  * @author Yusuke Kamiyamane
326
325
  * @license MIT
327
326
  * @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 2.1.2
5
+ * @version 2.1.3
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 2.1.2
5
+ * @version 2.1.3
6
6
  * @author Yusuke Kamiyamane
7
7
  * @license MIT
8
8
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -285,19 +285,18 @@ var Accordion = class _Accordion {
285
285
  }
286
286
  const mergedSelector = merged.selector;
287
287
  const defaultSelector = defaults.selector;
288
- try {
289
- document.querySelector(mergedSelector.content);
290
- } catch {
291
- const content = defaultSelector.content;
292
- console.warn(`Invalid content selector. Fallback: '${content}'.`);
293
- mergedSelector.content = content;
294
- }
295
- try {
296
- document.querySelector(mergedSelector.trigger);
297
- } catch {
298
- const trigger = defaultSelector.trigger;
299
- console.warn(`Invalid trigger selector. Fallback: '${trigger}'.`);
300
- mergedSelector.trigger = trigger;
288
+ for (const key of Object.keys(
289
+ defaultSelector
290
+ )) {
291
+ try {
292
+ document.querySelector(mergedSelector[key]);
293
+ } catch {
294
+ const selector = defaultSelector[key];
295
+ console.warn(
296
+ `Invalid ${key.replace(/[A-Z]/g, (c) => ` ${c.toLowerCase()}`)} selector. Fallback: '${selector}'.`
297
+ );
298
+ mergedSelector[key] = selector;
299
+ }
301
300
  }
302
301
  return merged;
303
302
  }
@@ -319,7 +318,7 @@ function waitAnimationFinish(animation) {
319
318
  * Accordion
320
319
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
321
320
  *
322
- * @version 2.1.2
321
+ * @version 2.1.3
323
322
  * @author Yusuke Kamiyamane
324
323
  * @license MIT
325
324
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/accordion",
3
- "version": "2.1.2",
3
+ "version": "2.1.4",
4
4
  "description": "WAI-ARIA compliant accordion pattern implementation in TypeScript",
5
5
  "keywords": [
6
6
  "a11y",
@@ -56,6 +56,6 @@
56
56
  "dependencies": {
57
57
  "@y14e/attribute-utils": "^2.0.12",
58
58
  "@y14e/button": "^1.0.8",
59
- "@y14e/roving-tabindex": "^3.1.31"
59
+ "@y14e/roving-tabindex": "^3.3.1"
60
60
  }
61
61
  }