@y14e/accordion 2.0.8 → 2.0.10

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.0.7";
16
+ import { Accordion } from "https://esm.sh/@y14e/accordion@2.0.10";
17
17
  // or
18
- import { Accordion } from "https://cdn.jsdelivr.net/npm/@y14e/accordion@2.0.7/+esm";
18
+ import { Accordion } from "https://cdn.jsdelivr.net/npm/@y14e/accordion@2.0.10/+esm";
19
19
  // or
20
- import { Accordion } from "https://esm.unpkg.com/@y14e/accordion@2.0.7";
20
+ import { Accordion } from "https://esm.unpkg.com/@y14e/accordion@2.0.10";
21
21
  ```
22
22
 
23
23
  ## Usage
@@ -368,56 +368,6 @@ var Button = class {
368
368
  };
369
369
  };
370
370
 
371
- // node_modules/@y14e/attribute-util/dist/index.js
372
- var DEFAULT_PARSER2 = (value) => value.split(/\s+/);
373
- var DEFAULT_SERIALIZER2 = (tokens) => tokens.join(" ");
374
- function addAttributeToken2(element, name, token, options = {}) {
375
- const value = element.getAttribute(name)?.trim();
376
- const {
377
- caseInsensitive = false,
378
- parse = DEFAULT_PARSER2,
379
- serialize = DEFAULT_SERIALIZER2
380
- } = options;
381
- const tokens = value ? parse(value).filter(Boolean) : [];
382
- if (caseInsensitive) {
383
- const lower = token.toLowerCase();
384
- if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
385
- tokens.push(token);
386
- element.setAttribute(name, serialize(tokens));
387
- }
388
- } else {
389
- const set = new Set(tokens);
390
- set.add(token);
391
- element.setAttribute(name, serialize([...set]));
392
- }
393
- }
394
- var snapshots2 = /* @__PURE__ */ new WeakMap();
395
- function restoreAttributes2(element_or_elements) {
396
- for (const element of Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]) {
397
- const snapshot = snapshots2.get(element);
398
- if (!snapshot) {
399
- continue;
400
- }
401
- for (const [name, value] of snapshot.entries()) {
402
- value === null ? element.removeAttribute(name) : element.setAttribute(name, value);
403
- }
404
- snapshots2.delete(element);
405
- }
406
- }
407
- function saveAttributes2(element_or_elements, name_or_names) {
408
- const names = Array.isArray(name_or_names) ? name_or_names : [name_or_names];
409
- (Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]).forEach((element) => {
410
- let snapshot = snapshots2.get(element);
411
- if (!snapshot) {
412
- snapshot = /* @__PURE__ */ new Map();
413
- snapshots2.set(element, snapshot);
414
- }
415
- names.forEach((name) => {
416
- snapshot.set(name, element.getAttribute(name));
417
- });
418
- });
419
- }
420
-
421
371
  // node_modules/@y14e/roving-tabindex/dist/index.js
422
372
  function createRovingTabIndex(container, options = {}) {
423
373
  if (!(container instanceof Element)) {
@@ -465,17 +415,9 @@ var RovingTabIndex = class _RovingTabIndex {
465
415
  noStart = false;
466
416
  }
467
417
  if (selector !== "") {
468
- let hasError = false;
469
- if (typeof selector !== "string" || !selector.trim()) {
470
- hasError = true;
471
- } else {
472
- try {
473
- this.#container.querySelector(selector);
474
- } catch {
475
- hasError = true;
476
- }
477
- }
478
- if (hasError) {
418
+ try {
419
+ document.querySelector(selector);
420
+ } catch {
479
421
  console.warn("Invalid selector. Fallback: no selector string.");
480
422
  selector = "";
481
423
  }
@@ -509,7 +451,7 @@ var RovingTabIndex = class _RovingTabIndex {
509
451
  this.#controller = null;
510
452
  this.#focusables.forEach((focusable) => {
511
453
  _RovingTabIndex.#initialized.delete(focusable);
512
- restoreAttributes2(focusable);
454
+ restoreAttributes(focusable);
513
455
  });
514
456
  this.#focusables.clear();
515
457
  this.#focusablesByFirstChar.clear();
@@ -614,7 +556,7 @@ var RovingTabIndex = class _RovingTabIndex {
614
556
  for (const focusable of this.#focusables) {
615
557
  if (!current.has(focusable)) {
616
558
  _RovingTabIndex.#initialized.delete(focusable);
617
- restoreAttributes2(focusable);
559
+ restoreAttributes(focusable);
618
560
  this.#focusables.delete(focusable);
619
561
  for (const [key, focusables] of this.#focusablesByFirstChar) {
620
562
  const index = focusables.indexOf(focusable);
@@ -636,7 +578,7 @@ var RovingTabIndex = class _RovingTabIndex {
636
578
  this.#focusables.add(focusable);
637
579
  _RovingTabIndex.#initialized.add(focusable);
638
580
  if (!navigationOnly) {
639
- saveAttributes2(focusable, "tabindex");
581
+ saveAttributes(focusable, "tabindex");
640
582
  focusable.setAttribute("tabindex", "-1");
641
583
  }
642
584
  if (!typeahead) {
@@ -649,8 +591,8 @@ var RovingTabIndex = class _RovingTabIndex {
649
591
  );
650
592
  if (char) {
651
593
  keys.add(char);
652
- saveAttributes2(focusable, "aria-keyshortcuts");
653
- addAttributeToken2(focusable, "aria-keyshortcuts", char, {
594
+ saveAttributes(focusable, "aria-keyshortcuts");
595
+ addAttributeToken(focusable, "aria-keyshortcuts", char, {
654
596
  caseInsensitive: true
655
597
  });
656
598
  }
@@ -691,7 +633,10 @@ var Accordion = class _Accordion {
691
633
  static defaults = {};
692
634
  #rootElement;
693
635
  #defaults = {
694
- animation: { duration: 300, easing: "ease" },
636
+ animation: {
637
+ duration: 300,
638
+ easing: "ease"
639
+ },
695
640
  collapsible: true,
696
641
  selector: {
697
642
  content: "[data-accordion-content]",
@@ -942,12 +887,49 @@ var Accordion = class _Accordion {
942
887
  return !element.hasAttribute("disabled") && element.tabIndex >= 0;
943
888
  }
944
889
  #mergeOptions(target, source) {
945
- return {
890
+ const merged = {
946
891
  ...target,
947
892
  ...source,
948
893
  animation: { ...target.animation, ...source.animation ?? {} },
949
894
  selector: { ...target.selector, ...source.selector ?? {} }
950
895
  };
896
+ const animation = merged.animation;
897
+ const duration = animation.duration;
898
+ if (typeof duration !== "number" || Number.isNaN(duration)) {
899
+ const duration2 = this.#defaults.animation.duration;
900
+ console.warn(`Invalid animation duration. Fallback: ${duration2} (ms).`);
901
+ animation.duration = duration2;
902
+ }
903
+ if (duration < 0) {
904
+ console.warn("Invalid animation duration. Fallback: 0 (ms).");
905
+ animation.duration = 0;
906
+ }
907
+ if (!CSS.supports("animation-timing-function", animation.easing)) {
908
+ const easing = this.#defaults.animation.easing;
909
+ console.warn(`Invalid animation easing. Fallback: '${easing}'.`);
910
+ animation.easing = easing;
911
+ }
912
+ if (typeof merged.collapsible !== "boolean") {
913
+ const collapsible = this.#defaults.collapsible;
914
+ console.warn(`Invalid collapsible option. Fallback: ${collapsible}.`);
915
+ merged.collapsible = collapsible;
916
+ }
917
+ const selector = merged.selector;
918
+ try {
919
+ document.querySelector(selector.content);
920
+ } catch {
921
+ const content = this.#defaults.selector.content;
922
+ console.warn(`Invalid content selector. Fallback: '${content}'.`);
923
+ selector.content = content;
924
+ }
925
+ try {
926
+ document.querySelector(selector.trigger);
927
+ } catch {
928
+ const trigger = this.#defaults.selector.trigger;
929
+ console.warn(`Invalid trigger selector. Fallback: '${trigger}'.`);
930
+ selector.trigger = trigger;
931
+ }
932
+ return merged;
951
933
  }
952
934
  async #waitAnimationsFinish() {
953
935
  const promises = [];
@@ -967,7 +949,7 @@ function waitAnimationFinish(animation) {
967
949
  * Accordion
968
950
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
969
951
  *
970
- * @version 2.0.8
952
+ * @version 2.0.10
971
953
  * @author Yusuke Kamiyamane
972
954
  * @license MIT
973
955
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -992,7 +974,7 @@ power-focusable/dist/index.js:
992
974
  * High-precision focus management utility with full composed tree support.
993
975
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
994
976
  *
995
- * @version 4.3.26
977
+ * @version 4.3.28
996
978
  * @author Yusuke Kamiyamane
997
979
  * @license MIT
998
980
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1010,24 +992,13 @@ power-focusable/dist/index.js:
1010
992
  * @see {@link https://github.com/y14e/button}
1011
993
  *)
1012
994
 
1013
- @y14e/attribute-util/dist/index.js:
1014
- (**
1015
- * Attribute Util
1016
- *
1017
- * @version 2.0.3
1018
- * @author Yusuke Kamiyamane
1019
- * @license MIT
1020
- * @copyright Copyright (c) Yusuke Kamiyamane
1021
- * @see {@link https://github.com/y14e/attribute-util}
1022
- *)
1023
-
1024
995
  @y14e/roving-tabindex/dist/index.js:
1025
996
  (**
1026
997
  * Roving Tabindex
1027
998
  * Lightweight roving tabindex utility with fully focus management.
1028
999
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
1029
1000
  *
1030
- * @version 3.1.22
1001
+ * @version 3.1.25
1031
1002
  * @author Yusuke Kamiyamane
1032
1003
  * @license MIT
1033
1004
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -366,56 +366,6 @@ var Button = class {
366
366
  };
367
367
  };
368
368
 
369
- // node_modules/@y14e/attribute-util/dist/index.js
370
- var DEFAULT_PARSER2 = (value) => value.split(/\s+/);
371
- var DEFAULT_SERIALIZER2 = (tokens) => tokens.join(" ");
372
- function addAttributeToken2(element, name, token, options = {}) {
373
- const value = element.getAttribute(name)?.trim();
374
- const {
375
- caseInsensitive = false,
376
- parse = DEFAULT_PARSER2,
377
- serialize = DEFAULT_SERIALIZER2
378
- } = options;
379
- const tokens = value ? parse(value).filter(Boolean) : [];
380
- if (caseInsensitive) {
381
- const lower = token.toLowerCase();
382
- if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
383
- tokens.push(token);
384
- element.setAttribute(name, serialize(tokens));
385
- }
386
- } else {
387
- const set = new Set(tokens);
388
- set.add(token);
389
- element.setAttribute(name, serialize([...set]));
390
- }
391
- }
392
- var snapshots2 = /* @__PURE__ */ new WeakMap();
393
- function restoreAttributes2(element_or_elements) {
394
- for (const element of Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]) {
395
- const snapshot = snapshots2.get(element);
396
- if (!snapshot) {
397
- continue;
398
- }
399
- for (const [name, value] of snapshot.entries()) {
400
- value === null ? element.removeAttribute(name) : element.setAttribute(name, value);
401
- }
402
- snapshots2.delete(element);
403
- }
404
- }
405
- function saveAttributes2(element_or_elements, name_or_names) {
406
- const names = Array.isArray(name_or_names) ? name_or_names : [name_or_names];
407
- (Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]).forEach((element) => {
408
- let snapshot = snapshots2.get(element);
409
- if (!snapshot) {
410
- snapshot = /* @__PURE__ */ new Map();
411
- snapshots2.set(element, snapshot);
412
- }
413
- names.forEach((name) => {
414
- snapshot.set(name, element.getAttribute(name));
415
- });
416
- });
417
- }
418
-
419
369
  // node_modules/@y14e/roving-tabindex/dist/index.js
420
370
  function createRovingTabIndex(container, options = {}) {
421
371
  if (!(container instanceof Element)) {
@@ -463,17 +413,9 @@ var RovingTabIndex = class _RovingTabIndex {
463
413
  noStart = false;
464
414
  }
465
415
  if (selector !== "") {
466
- let hasError = false;
467
- if (typeof selector !== "string" || !selector.trim()) {
468
- hasError = true;
469
- } else {
470
- try {
471
- this.#container.querySelector(selector);
472
- } catch {
473
- hasError = true;
474
- }
475
- }
476
- if (hasError) {
416
+ try {
417
+ document.querySelector(selector);
418
+ } catch {
477
419
  console.warn("Invalid selector. Fallback: no selector string.");
478
420
  selector = "";
479
421
  }
@@ -507,7 +449,7 @@ var RovingTabIndex = class _RovingTabIndex {
507
449
  this.#controller = null;
508
450
  this.#focusables.forEach((focusable) => {
509
451
  _RovingTabIndex.#initialized.delete(focusable);
510
- restoreAttributes2(focusable);
452
+ restoreAttributes(focusable);
511
453
  });
512
454
  this.#focusables.clear();
513
455
  this.#focusablesByFirstChar.clear();
@@ -612,7 +554,7 @@ var RovingTabIndex = class _RovingTabIndex {
612
554
  for (const focusable of this.#focusables) {
613
555
  if (!current.has(focusable)) {
614
556
  _RovingTabIndex.#initialized.delete(focusable);
615
- restoreAttributes2(focusable);
557
+ restoreAttributes(focusable);
616
558
  this.#focusables.delete(focusable);
617
559
  for (const [key, focusables] of this.#focusablesByFirstChar) {
618
560
  const index = focusables.indexOf(focusable);
@@ -634,7 +576,7 @@ var RovingTabIndex = class _RovingTabIndex {
634
576
  this.#focusables.add(focusable);
635
577
  _RovingTabIndex.#initialized.add(focusable);
636
578
  if (!navigationOnly) {
637
- saveAttributes2(focusable, "tabindex");
579
+ saveAttributes(focusable, "tabindex");
638
580
  focusable.setAttribute("tabindex", "-1");
639
581
  }
640
582
  if (!typeahead) {
@@ -647,8 +589,8 @@ var RovingTabIndex = class _RovingTabIndex {
647
589
  );
648
590
  if (char) {
649
591
  keys.add(char);
650
- saveAttributes2(focusable, "aria-keyshortcuts");
651
- addAttributeToken2(focusable, "aria-keyshortcuts", char, {
592
+ saveAttributes(focusable, "aria-keyshortcuts");
593
+ addAttributeToken(focusable, "aria-keyshortcuts", char, {
652
594
  caseInsensitive: true
653
595
  });
654
596
  }
@@ -689,7 +631,10 @@ var Accordion = class _Accordion {
689
631
  static defaults = {};
690
632
  #rootElement;
691
633
  #defaults = {
692
- animation: { duration: 300, easing: "ease" },
634
+ animation: {
635
+ duration: 300,
636
+ easing: "ease"
637
+ },
693
638
  collapsible: true,
694
639
  selector: {
695
640
  content: "[data-accordion-content]",
@@ -940,12 +885,49 @@ var Accordion = class _Accordion {
940
885
  return !element.hasAttribute("disabled") && element.tabIndex >= 0;
941
886
  }
942
887
  #mergeOptions(target, source) {
943
- return {
888
+ const merged = {
944
889
  ...target,
945
890
  ...source,
946
891
  animation: { ...target.animation, ...source.animation ?? {} },
947
892
  selector: { ...target.selector, ...source.selector ?? {} }
948
893
  };
894
+ const animation = merged.animation;
895
+ const duration = animation.duration;
896
+ if (typeof duration !== "number" || Number.isNaN(duration)) {
897
+ const duration2 = this.#defaults.animation.duration;
898
+ console.warn(`Invalid animation duration. Fallback: ${duration2} (ms).`);
899
+ animation.duration = duration2;
900
+ }
901
+ if (duration < 0) {
902
+ console.warn("Invalid animation duration. Fallback: 0 (ms).");
903
+ animation.duration = 0;
904
+ }
905
+ if (!CSS.supports("animation-timing-function", animation.easing)) {
906
+ const easing = this.#defaults.animation.easing;
907
+ console.warn(`Invalid animation easing. Fallback: '${easing}'.`);
908
+ animation.easing = easing;
909
+ }
910
+ if (typeof merged.collapsible !== "boolean") {
911
+ const collapsible = this.#defaults.collapsible;
912
+ console.warn(`Invalid collapsible option. Fallback: ${collapsible}.`);
913
+ merged.collapsible = collapsible;
914
+ }
915
+ const selector = merged.selector;
916
+ try {
917
+ document.querySelector(selector.content);
918
+ } catch {
919
+ const content = this.#defaults.selector.content;
920
+ console.warn(`Invalid content selector. Fallback: '${content}'.`);
921
+ selector.content = content;
922
+ }
923
+ try {
924
+ document.querySelector(selector.trigger);
925
+ } catch {
926
+ const trigger = this.#defaults.selector.trigger;
927
+ console.warn(`Invalid trigger selector. Fallback: '${trigger}'.`);
928
+ selector.trigger = trigger;
929
+ }
930
+ return merged;
949
931
  }
950
932
  async #waitAnimationsFinish() {
951
933
  const promises = [];
@@ -965,7 +947,7 @@ function waitAnimationFinish(animation) {
965
947
  * Accordion
966
948
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
967
949
  *
968
- * @version 2.0.8
950
+ * @version 2.0.10
969
951
  * @author Yusuke Kamiyamane
970
952
  * @license MIT
971
953
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -990,7 +972,7 @@ power-focusable/dist/index.js:
990
972
  * High-precision focus management utility with full composed tree support.
991
973
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
992
974
  *
993
- * @version 4.3.26
975
+ * @version 4.3.28
994
976
  * @author Yusuke Kamiyamane
995
977
  * @license MIT
996
978
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1008,24 +990,13 @@ power-focusable/dist/index.js:
1008
990
  * @see {@link https://github.com/y14e/button}
1009
991
  *)
1010
992
 
1011
- @y14e/attribute-util/dist/index.js:
1012
- (**
1013
- * Attribute Util
1014
- *
1015
- * @version 2.0.3
1016
- * @author Yusuke Kamiyamane
1017
- * @license MIT
1018
- * @copyright Copyright (c) Yusuke Kamiyamane
1019
- * @see {@link https://github.com/y14e/attribute-util}
1020
- *)
1021
-
1022
993
  @y14e/roving-tabindex/dist/index.js:
1023
994
  (**
1024
995
  * Roving Tabindex
1025
996
  * Lightweight roving tabindex utility with fully focus management.
1026
997
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
1027
998
  *
1028
- * @version 3.1.22
999
+ * @version 3.1.25
1029
1000
  * @author Yusuke Kamiyamane
1030
1001
  * @license MIT
1031
1002
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.cjs CHANGED
@@ -29,7 +29,10 @@ var Accordion = class _Accordion {
29
29
  static defaults = {};
30
30
  #rootElement;
31
31
  #defaults = {
32
- animation: { duration: 300, easing: "ease" },
32
+ animation: {
33
+ duration: 300,
34
+ easing: "ease"
35
+ },
33
36
  collapsible: true,
34
37
  selector: {
35
38
  content: "[data-accordion-content]",
@@ -280,12 +283,49 @@ var Accordion = class _Accordion {
280
283
  return !element.hasAttribute("disabled") && element.tabIndex >= 0;
281
284
  }
282
285
  #mergeOptions(target, source) {
283
- return {
286
+ const merged = {
284
287
  ...target,
285
288
  ...source,
286
289
  animation: { ...target.animation, ...source.animation ?? {} },
287
290
  selector: { ...target.selector, ...source.selector ?? {} }
288
291
  };
292
+ const animation = merged.animation;
293
+ const duration = animation.duration;
294
+ if (typeof duration !== "number" || Number.isNaN(duration)) {
295
+ const duration2 = this.#defaults.animation.duration;
296
+ console.warn(`Invalid animation duration. Fallback: ${duration2} (ms).`);
297
+ animation.duration = duration2;
298
+ }
299
+ if (duration < 0) {
300
+ console.warn("Invalid animation duration. Fallback: 0 (ms).");
301
+ animation.duration = 0;
302
+ }
303
+ if (!CSS.supports("animation-timing-function", animation.easing)) {
304
+ const easing = this.#defaults.animation.easing;
305
+ console.warn(`Invalid animation easing. Fallback: '${easing}'.`);
306
+ animation.easing = easing;
307
+ }
308
+ if (typeof merged.collapsible !== "boolean") {
309
+ const collapsible = this.#defaults.collapsible;
310
+ console.warn(`Invalid collapsible option. Fallback: ${collapsible}.`);
311
+ merged.collapsible = collapsible;
312
+ }
313
+ const selector = merged.selector;
314
+ try {
315
+ document.querySelector(selector.content);
316
+ } catch {
317
+ const content = this.#defaults.selector.content;
318
+ console.warn(`Invalid content selector. Fallback: '${content}'.`);
319
+ selector.content = content;
320
+ }
321
+ try {
322
+ document.querySelector(selector.trigger);
323
+ } catch {
324
+ const trigger = this.#defaults.selector.trigger;
325
+ console.warn(`Invalid trigger selector. Fallback: '${trigger}'.`);
326
+ selector.trigger = trigger;
327
+ }
328
+ return merged;
289
329
  }
290
330
  async #waitAnimationsFinish() {
291
331
  const promises = [];
@@ -305,7 +345,7 @@ function waitAnimationFinish(animation) {
305
345
  * Accordion
306
346
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
307
347
  *
308
- * @version 2.0.8
348
+ * @version 2.0.10
309
349
  * @author Yusuke Kamiyamane
310
350
  * @license MIT
311
351
  * @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.0.8
5
+ * @version 2.0.10
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.0.8
5
+ * @version 2.0.10
6
6
  * @author Yusuke Kamiyamane
7
7
  * @license MIT
8
8
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -7,7 +7,10 @@ var Accordion = class _Accordion {
7
7
  static defaults = {};
8
8
  #rootElement;
9
9
  #defaults = {
10
- animation: { duration: 300, easing: "ease" },
10
+ animation: {
11
+ duration: 300,
12
+ easing: "ease"
13
+ },
11
14
  collapsible: true,
12
15
  selector: {
13
16
  content: "[data-accordion-content]",
@@ -258,12 +261,49 @@ var Accordion = class _Accordion {
258
261
  return !element.hasAttribute("disabled") && element.tabIndex >= 0;
259
262
  }
260
263
  #mergeOptions(target, source) {
261
- return {
264
+ const merged = {
262
265
  ...target,
263
266
  ...source,
264
267
  animation: { ...target.animation, ...source.animation ?? {} },
265
268
  selector: { ...target.selector, ...source.selector ?? {} }
266
269
  };
270
+ const animation = merged.animation;
271
+ const duration = animation.duration;
272
+ if (typeof duration !== "number" || Number.isNaN(duration)) {
273
+ const duration2 = this.#defaults.animation.duration;
274
+ console.warn(`Invalid animation duration. Fallback: ${duration2} (ms).`);
275
+ animation.duration = duration2;
276
+ }
277
+ if (duration < 0) {
278
+ console.warn("Invalid animation duration. Fallback: 0 (ms).");
279
+ animation.duration = 0;
280
+ }
281
+ if (!CSS.supports("animation-timing-function", animation.easing)) {
282
+ const easing = this.#defaults.animation.easing;
283
+ console.warn(`Invalid animation easing. Fallback: '${easing}'.`);
284
+ animation.easing = easing;
285
+ }
286
+ if (typeof merged.collapsible !== "boolean") {
287
+ const collapsible = this.#defaults.collapsible;
288
+ console.warn(`Invalid collapsible option. Fallback: ${collapsible}.`);
289
+ merged.collapsible = collapsible;
290
+ }
291
+ const selector = merged.selector;
292
+ try {
293
+ document.querySelector(selector.content);
294
+ } catch {
295
+ const content = this.#defaults.selector.content;
296
+ console.warn(`Invalid content selector. Fallback: '${content}'.`);
297
+ selector.content = content;
298
+ }
299
+ try {
300
+ document.querySelector(selector.trigger);
301
+ } catch {
302
+ const trigger = this.#defaults.selector.trigger;
303
+ console.warn(`Invalid trigger selector. Fallback: '${trigger}'.`);
304
+ selector.trigger = trigger;
305
+ }
306
+ return merged;
267
307
  }
268
308
  async #waitAnimationsFinish() {
269
309
  const promises = [];
@@ -283,7 +323,7 @@ function waitAnimationFinish(animation) {
283
323
  * Accordion
284
324
  * WAI-ARIA compliant accordion pattern implementation in TypeScript.
285
325
  *
286
- * @version 2.0.8
326
+ * @version 2.0.10
287
327
  * @author Yusuke Kamiyamane
288
328
  * @license MIT
289
329
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,11 +1,27 @@
1
1
  {
2
2
  "name": "@y14e/accordion",
3
- "version": "2.0.8",
3
+ "version": "2.0.10",
4
4
  "description": "WAI-ARIA compliant accordion pattern implementation in TypeScript",
5
+ "keywords": [
6
+ "a11y",
7
+ "accessibility",
8
+ "accordion",
9
+ "collapsible",
10
+ "component",
11
+ "typescript",
12
+ "utility"
13
+ ],
14
+ "homepage": "https://github.com/y14e/accordion#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/y14e/accordion/issues"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/y14e/accordion.git"
21
+ },
22
+ "license": "MIT",
23
+ "author": "Yusuke Kamiyamane",
5
24
  "type": "module",
6
- "main": "./dist/index.cjs",
7
- "module": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
25
  "exports": {
10
26
  ".": {
11
27
  "types": "./dist/index.d.ts",
@@ -13,6 +29,9 @@
13
29
  "require": "./dist/index.cjs"
14
30
  }
15
31
  },
32
+ "main": "./dist/index.cjs",
33
+ "module": "./dist/index.js",
34
+ "types": "./dist/index.d.ts",
16
35
  "files": [
17
36
  "dist",
18
37
  "LICENSE",
@@ -20,28 +39,9 @@
20
39
  ],
21
40
  "scripts": {
22
41
  "build": "tsup",
23
- "prepublishOnly": "npm run build",
24
- "lint": "tsc --noEmit"
25
- },
26
- "keywords": [
27
- "a11y",
28
- "accessibility",
29
- "accordion",
30
- "collapsible",
31
- "component",
32
- "typescript",
33
- "utility"
34
- ],
35
- "author": "Yusuke Kamiyamane",
36
- "license": "MIT",
37
- "repository": {
38
- "type": "git",
39
- "url": "git+https://github.com/y14e/accordion.git"
42
+ "lint": "tsc --noEmit",
43
+ "prepublishOnly": "npm run build"
40
44
  },
41
- "bugs": {
42
- "url": "https://github.com/y14e/accordion/issues"
43
- },
44
- "homepage": "https://github.com/y14e/accordion#readme",
45
45
  "devDependencies": {
46
46
  "bun-types": "latest",
47
47
  "tsup": "^8.0.0",
@@ -56,6 +56,6 @@
56
56
  "dependencies": {
57
57
  "@y14e/attribute-utils": "^2.0.5",
58
58
  "@y14e/button": "^1.0.8",
59
- "@y14e/roving-tabindex": "^3.1.22"
59
+ "@y14e/roving-tabindex": "^3.1.25"
60
60
  }
61
61
  }