@y14e/roving-tabindex 3.1.25 → 3.1.27

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/roving-tabindex
13
13
  import { createRovingTabIndex } from '@y14e/roving-tabindex';
14
14
 
15
15
  // CDNs
16
- import { createRovingTabIndex } from 'https://esm.sh/@y14e/roving-tabindex@3.1.24';
16
+ import { createRovingTabIndex } from 'https://esm.sh/@y14e/roving-tabindex@3.1.27';
17
17
  // or
18
- import { createRovingTabIndex } from 'https://cdn.jsdelivr.net/npm/@y14e/roving-tabindex@3.1.24/+esm';
18
+ import { createRovingTabIndex } from 'https://cdn.jsdelivr.net/npm/@y14e/roving-tabindex@3.1.27/+esm';
19
19
  // or
20
- import { createRovingTabIndex } from 'https://esm.unpkg.com/@y14e/roving-tabindex@3.1.24';
20
+ import { createRovingTabIndex } from 'https://esm.unpkg.com/@y14e/roving-tabindex@3.1.27';
21
21
  ```
22
22
 
23
23
  ## 📦 APIs
@@ -4,12 +4,11 @@
4
4
  var DEFAULT_PARSER = (value) => value.split(/\s+/);
5
5
  var DEFAULT_SERIALIZER = (tokens) => tokens.join(" ");
6
6
  function addAttributeToken(element, name, token, options = {}) {
7
+ if (!isValid(element, name, token)) {
8
+ return;
9
+ }
7
10
  const value = element.getAttribute(name)?.trim();
8
- const {
9
- caseInsensitive = false,
10
- parse = DEFAULT_PARSER,
11
- serialize = DEFAULT_SERIALIZER
12
- } = options;
11
+ const { caseInsensitive, parse, serialize } = resolveOptions(options);
13
12
  const tokens = value ? parse(value).filter(Boolean) : [];
14
13
  if (caseInsensitive) {
15
14
  const lower = token.toLowerCase();
@@ -49,6 +48,47 @@ function saveAttributes(element_or_elements, name_or_names) {
49
48
  });
50
49
  });
51
50
  }
51
+ function isValid(element, name, token) {
52
+ if (!(element instanceof Element)) {
53
+ console.warn("Invalid element");
54
+ return false;
55
+ }
56
+ try {
57
+ document.createElement("div").setAttribute(name, "");
58
+ } catch {
59
+ console.warn(`Invalid attribute name: '${name}'`);
60
+ return false;
61
+ }
62
+ if (typeof token !== "string" || !token.trim()) {
63
+ console.warn("Invalid token");
64
+ return false;
65
+ }
66
+ return true;
67
+ }
68
+ function resolveOptions(options) {
69
+ let {
70
+ caseInsensitive = false,
71
+ parse = DEFAULT_PARSER,
72
+ serialize = DEFAULT_SERIALIZER
73
+ } = options;
74
+ if (typeof caseInsensitive !== "boolean") {
75
+ console.warn("Invalid caseInsensitive option. Fallback: false.");
76
+ caseInsensitive = false;
77
+ }
78
+ if (typeof parse !== "function") {
79
+ console.warn(
80
+ "Invalid parser. Fallback: default parser (splits by whitespace)."
81
+ );
82
+ parse = DEFAULT_PARSER;
83
+ }
84
+ if (typeof serialize !== "function") {
85
+ console.warn(
86
+ "Invalid serializer. Fallback: default serializer (joins by whitespace)."
87
+ );
88
+ serialize = DEFAULT_SERIALIZER;
89
+ }
90
+ return { caseInsensitive, parse, serialize };
91
+ }
52
92
 
53
93
  // node_modules/power-focusable/dist/index.js
54
94
  var FOCUSABLE_SELECTOR = `:is(a[href], area[href], button, embed, iframe, input:not([type="hidden" i]), object, select, details > summary:first-of-type, textarea, [contenteditable]:not([contenteditable="false" i]), [controls], [tabindex]):not(:disabled, [hidden], [inert], [tabindex="-1"])`;
@@ -61,37 +101,13 @@ function getFocusables(container = document.body, options = {}) {
61
101
  console.warn("Invalid container element. Fallback: <body> element.");
62
102
  container = document.body;
63
103
  }
64
- let {
65
- composed = false,
104
+ const {
105
+ composed,
66
106
  filter,
67
107
  include,
68
- skipNegativeTabIndexCheck = false,
69
- skipVisibilityCheck = false
70
- } = options;
71
- if (typeof composed !== "boolean") {
72
- console.warn("Invalid composed option. Fallback: false.");
73
- composed = false;
74
- }
75
- if (typeof filter !== "undefined" && typeof filter !== "function") {
76
- console.warn(
77
- "Invalid filter function. Fallback: no filter function (undefined)."
78
- );
79
- filter = void 0;
80
- }
81
- if (typeof include !== "undefined" && typeof include !== "function") {
82
- console.warn(
83
- "Invalid include function. Fallback: no include function (undefined)."
84
- );
85
- include = void 0;
86
- }
87
- if (typeof skipNegativeTabIndexCheck !== "boolean") {
88
- console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
89
- skipNegativeTabIndexCheck = false;
90
- }
91
- if (typeof skipVisibilityCheck !== "boolean") {
92
- console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
93
- skipVisibilityCheck = false;
94
- }
108
+ skipNegativeTabIndexCheck,
109
+ skipVisibilityCheck
110
+ } = resolveOptions2(options);
95
111
  const candidates = [];
96
112
  if (composed || include) {
97
113
  let traverse2 = function(node) {
@@ -135,15 +151,7 @@ function isFocusable(element, options = {}) {
135
151
  console.warn("Invalid element");
136
152
  return false;
137
153
  }
138
- let { skipNegativeTabIndexCheck = false, skipVisibilityCheck = false } = options;
139
- if (typeof skipNegativeTabIndexCheck !== "boolean") {
140
- console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
141
- skipNegativeTabIndexCheck = false;
142
- }
143
- if (typeof skipVisibilityCheck !== "boolean") {
144
- console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
145
- skipVisibilityCheck = false;
146
- }
154
+ const { skipNegativeTabIndexCheck, skipVisibilityCheck } = resolveOptions2(options);
147
155
  if (element.hasAttribute("hidden") || isInert(element)) {
148
156
  return false;
149
157
  }
@@ -318,6 +326,61 @@ function isInert(element) {
318
326
  function isUngroupedRadio(element) {
319
327
  return element.type === "radio" && !!element.name;
320
328
  }
329
+ function resolveOptions2(options) {
330
+ let {
331
+ anchor = getActiveElement(),
332
+ composed = false,
333
+ filter,
334
+ include,
335
+ skipNegativeTabIndexCheck = false,
336
+ skipVisibilityCheck = false,
337
+ wrap = false
338
+ } = options;
339
+ if (!(anchor instanceof Element)) {
340
+ const active = getActiveElement();
341
+ if (active instanceof Element) {
342
+ console.warn("Invalid anchor element. Fallback: active element.");
343
+ anchor = active;
344
+ }
345
+ }
346
+ if (typeof composed !== "boolean") {
347
+ console.warn("Invalid composed option. Fallback: false.");
348
+ composed = false;
349
+ }
350
+ if (filter !== void 0 && typeof filter !== "function") {
351
+ console.warn(
352
+ "Invalid filter function. Fallback: no filter function (undefined)."
353
+ );
354
+ filter = void 0;
355
+ }
356
+ if (include !== void 0 && typeof include !== "function") {
357
+ console.warn(
358
+ "Invalid include function. Fallback: no include function (undefined)."
359
+ );
360
+ include = void 0;
361
+ }
362
+ if (typeof skipNegativeTabIndexCheck !== "boolean") {
363
+ console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
364
+ skipNegativeTabIndexCheck = false;
365
+ }
366
+ if (typeof skipVisibilityCheck !== "boolean") {
367
+ console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
368
+ skipVisibilityCheck = false;
369
+ }
370
+ if (typeof wrap !== "boolean") {
371
+ console.warn("Invalid wrap option. Fallback: false.");
372
+ wrap = false;
373
+ }
374
+ return {
375
+ anchor,
376
+ composed,
377
+ filter,
378
+ include,
379
+ skipNegativeTabIndexCheck,
380
+ skipVisibilityCheck,
381
+ wrap
382
+ };
383
+ }
321
384
 
322
385
  // src/index.ts
323
386
  function createRovingTabIndex(container, options = {}) {
@@ -340,56 +403,7 @@ var RovingTabIndex = class _RovingTabIndex {
340
403
  #isDestroyed = false;
341
404
  constructor(container, options = {}) {
342
405
  this.#container = container;
343
- let {
344
- direction = "both",
345
- navigationOnly = false,
346
- noMemory = false,
347
- noStart = false,
348
- selector = "",
349
- typeahead = false,
350
- wrap = false
351
- } = options;
352
- if (!["both", "horizontal", "vertical"].includes(direction)) {
353
- console.warn("Invalid direction option. Fallback: 'both'.");
354
- direction = "both";
355
- }
356
- if (typeof navigationOnly !== "boolean") {
357
- console.warn("Invalid navigationOnly option. Fallback: false.");
358
- navigationOnly = false;
359
- }
360
- if (typeof noMemory !== "boolean") {
361
- console.warn("Invalid noMemory option. Fallback: false.");
362
- noMemory = false;
363
- }
364
- if (typeof noStart !== "boolean") {
365
- console.warn("Invalid noStart option. Fallback: false.");
366
- noStart = false;
367
- }
368
- if (selector !== "") {
369
- try {
370
- document.querySelector(selector);
371
- } catch {
372
- console.warn("Invalid selector. Fallback: no selector string.");
373
- selector = "";
374
- }
375
- }
376
- if (typeof typeahead !== "boolean") {
377
- console.warn("Invalid typeahead option. Fallback: false.");
378
- typeahead = false;
379
- }
380
- if (typeof wrap !== "boolean") {
381
- console.warn("Invalid wrap option. Fallback: false.");
382
- wrap = false;
383
- }
384
- this.#settings = {
385
- direction,
386
- navigationOnly,
387
- noMemory,
388
- noStart,
389
- selector,
390
- typeahead,
391
- wrap
392
- };
406
+ this.#settings = this.#resolveOptions(options);
393
407
  this.#selectorFilter = this.#createSelectorFilter();
394
408
  this.#initialize();
395
409
  }
@@ -577,13 +591,65 @@ var RovingTabIndex = class _RovingTabIndex {
577
591
  skipVisibilityCheck: true
578
592
  });
579
593
  }
594
+ #resolveOptions(options) {
595
+ let {
596
+ direction = "both",
597
+ navigationOnly = false,
598
+ noMemory = false,
599
+ noStart = false,
600
+ selector = "",
601
+ typeahead = false,
602
+ wrap = false
603
+ } = options;
604
+ if (!["both", "horizontal", "vertical"].includes(direction)) {
605
+ console.warn("Invalid direction option. Fallback: 'both'.");
606
+ direction = "both";
607
+ }
608
+ if (typeof navigationOnly !== "boolean") {
609
+ console.warn("Invalid navigationOnly option. Fallback: false.");
610
+ navigationOnly = false;
611
+ }
612
+ if (typeof noMemory !== "boolean") {
613
+ console.warn("Invalid noMemory option. Fallback: false.");
614
+ noMemory = false;
615
+ }
616
+ if (typeof noStart !== "boolean") {
617
+ console.warn("Invalid noStart option. Fallback: false.");
618
+ noStart = false;
619
+ }
620
+ if (selector !== "") {
621
+ try {
622
+ document.querySelector(selector);
623
+ } catch {
624
+ console.warn("Invalid selector. Fallback: no selector string.");
625
+ selector = "";
626
+ }
627
+ }
628
+ if (typeof typeahead !== "boolean") {
629
+ console.warn("Invalid typeahead option. Fallback: false.");
630
+ typeahead = false;
631
+ }
632
+ if (typeof wrap !== "boolean") {
633
+ console.warn("Invalid wrap option. Fallback: false.");
634
+ wrap = false;
635
+ }
636
+ return {
637
+ direction,
638
+ navigationOnly,
639
+ noMemory,
640
+ noStart,
641
+ selector,
642
+ typeahead,
643
+ wrap
644
+ };
645
+ }
580
646
  };
581
647
  /**
582
648
  * Roving Tabindex
583
649
  * Lightweight roving tabindex utility with fully focus management.
584
650
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
585
651
  *
586
- * @version 3.1.25
652
+ * @version 3.1.27
587
653
  * @author Yusuke Kamiyamane
588
654
  * @license MIT
589
655
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -595,7 +661,7 @@ var RovingTabIndex = class _RovingTabIndex {
595
661
  (**
596
662
  * Attribute Utils
597
663
  *
598
- * @version 2.0.5
664
+ * @version 2.0.8
599
665
  * @author Yusuke Kamiyamane
600
666
  * @license MIT
601
667
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -608,7 +674,7 @@ power-focusable/dist/index.js:
608
674
  * High-precision focus management utility with full composed tree support.
609
675
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
610
676
  *
611
- * @version 4.3.26
677
+ * @version 4.3.29
612
678
  * @author Yusuke Kamiyamane
613
679
  * @license MIT
614
680
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -2,12 +2,11 @@
2
2
  var DEFAULT_PARSER = (value) => value.split(/\s+/);
3
3
  var DEFAULT_SERIALIZER = (tokens) => tokens.join(" ");
4
4
  function addAttributeToken(element, name, token, options = {}) {
5
+ if (!isValid(element, name, token)) {
6
+ return;
7
+ }
5
8
  const value = element.getAttribute(name)?.trim();
6
- const {
7
- caseInsensitive = false,
8
- parse = DEFAULT_PARSER,
9
- serialize = DEFAULT_SERIALIZER
10
- } = options;
9
+ const { caseInsensitive, parse, serialize } = resolveOptions(options);
11
10
  const tokens = value ? parse(value).filter(Boolean) : [];
12
11
  if (caseInsensitive) {
13
12
  const lower = token.toLowerCase();
@@ -47,6 +46,47 @@ function saveAttributes(element_or_elements, name_or_names) {
47
46
  });
48
47
  });
49
48
  }
49
+ function isValid(element, name, token) {
50
+ if (!(element instanceof Element)) {
51
+ console.warn("Invalid element");
52
+ return false;
53
+ }
54
+ try {
55
+ document.createElement("div").setAttribute(name, "");
56
+ } catch {
57
+ console.warn(`Invalid attribute name: '${name}'`);
58
+ return false;
59
+ }
60
+ if (typeof token !== "string" || !token.trim()) {
61
+ console.warn("Invalid token");
62
+ return false;
63
+ }
64
+ return true;
65
+ }
66
+ function resolveOptions(options) {
67
+ let {
68
+ caseInsensitive = false,
69
+ parse = DEFAULT_PARSER,
70
+ serialize = DEFAULT_SERIALIZER
71
+ } = options;
72
+ if (typeof caseInsensitive !== "boolean") {
73
+ console.warn("Invalid caseInsensitive option. Fallback: false.");
74
+ caseInsensitive = false;
75
+ }
76
+ if (typeof parse !== "function") {
77
+ console.warn(
78
+ "Invalid parser. Fallback: default parser (splits by whitespace)."
79
+ );
80
+ parse = DEFAULT_PARSER;
81
+ }
82
+ if (typeof serialize !== "function") {
83
+ console.warn(
84
+ "Invalid serializer. Fallback: default serializer (joins by whitespace)."
85
+ );
86
+ serialize = DEFAULT_SERIALIZER;
87
+ }
88
+ return { caseInsensitive, parse, serialize };
89
+ }
50
90
 
51
91
  // node_modules/power-focusable/dist/index.js
52
92
  var FOCUSABLE_SELECTOR = `:is(a[href], area[href], button, embed, iframe, input:not([type="hidden" i]), object, select, details > summary:first-of-type, textarea, [contenteditable]:not([contenteditable="false" i]), [controls], [tabindex]):not(:disabled, [hidden], [inert], [tabindex="-1"])`;
@@ -59,37 +99,13 @@ function getFocusables(container = document.body, options = {}) {
59
99
  console.warn("Invalid container element. Fallback: <body> element.");
60
100
  container = document.body;
61
101
  }
62
- let {
63
- composed = false,
102
+ const {
103
+ composed,
64
104
  filter,
65
105
  include,
66
- skipNegativeTabIndexCheck = false,
67
- skipVisibilityCheck = false
68
- } = options;
69
- if (typeof composed !== "boolean") {
70
- console.warn("Invalid composed option. Fallback: false.");
71
- composed = false;
72
- }
73
- if (typeof filter !== "undefined" && typeof filter !== "function") {
74
- console.warn(
75
- "Invalid filter function. Fallback: no filter function (undefined)."
76
- );
77
- filter = void 0;
78
- }
79
- if (typeof include !== "undefined" && typeof include !== "function") {
80
- console.warn(
81
- "Invalid include function. Fallback: no include function (undefined)."
82
- );
83
- include = void 0;
84
- }
85
- if (typeof skipNegativeTabIndexCheck !== "boolean") {
86
- console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
87
- skipNegativeTabIndexCheck = false;
88
- }
89
- if (typeof skipVisibilityCheck !== "boolean") {
90
- console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
91
- skipVisibilityCheck = false;
92
- }
106
+ skipNegativeTabIndexCheck,
107
+ skipVisibilityCheck
108
+ } = resolveOptions2(options);
93
109
  const candidates = [];
94
110
  if (composed || include) {
95
111
  let traverse2 = function(node) {
@@ -133,15 +149,7 @@ function isFocusable(element, options = {}) {
133
149
  console.warn("Invalid element");
134
150
  return false;
135
151
  }
136
- let { skipNegativeTabIndexCheck = false, skipVisibilityCheck = false } = options;
137
- if (typeof skipNegativeTabIndexCheck !== "boolean") {
138
- console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
139
- skipNegativeTabIndexCheck = false;
140
- }
141
- if (typeof skipVisibilityCheck !== "boolean") {
142
- console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
143
- skipVisibilityCheck = false;
144
- }
152
+ const { skipNegativeTabIndexCheck, skipVisibilityCheck } = resolveOptions2(options);
145
153
  if (element.hasAttribute("hidden") || isInert(element)) {
146
154
  return false;
147
155
  }
@@ -316,6 +324,61 @@ function isInert(element) {
316
324
  function isUngroupedRadio(element) {
317
325
  return element.type === "radio" && !!element.name;
318
326
  }
327
+ function resolveOptions2(options) {
328
+ let {
329
+ anchor = getActiveElement(),
330
+ composed = false,
331
+ filter,
332
+ include,
333
+ skipNegativeTabIndexCheck = false,
334
+ skipVisibilityCheck = false,
335
+ wrap = false
336
+ } = options;
337
+ if (!(anchor instanceof Element)) {
338
+ const active = getActiveElement();
339
+ if (active instanceof Element) {
340
+ console.warn("Invalid anchor element. Fallback: active element.");
341
+ anchor = active;
342
+ }
343
+ }
344
+ if (typeof composed !== "boolean") {
345
+ console.warn("Invalid composed option. Fallback: false.");
346
+ composed = false;
347
+ }
348
+ if (filter !== void 0 && typeof filter !== "function") {
349
+ console.warn(
350
+ "Invalid filter function. Fallback: no filter function (undefined)."
351
+ );
352
+ filter = void 0;
353
+ }
354
+ if (include !== void 0 && typeof include !== "function") {
355
+ console.warn(
356
+ "Invalid include function. Fallback: no include function (undefined)."
357
+ );
358
+ include = void 0;
359
+ }
360
+ if (typeof skipNegativeTabIndexCheck !== "boolean") {
361
+ console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
362
+ skipNegativeTabIndexCheck = false;
363
+ }
364
+ if (typeof skipVisibilityCheck !== "boolean") {
365
+ console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
366
+ skipVisibilityCheck = false;
367
+ }
368
+ if (typeof wrap !== "boolean") {
369
+ console.warn("Invalid wrap option. Fallback: false.");
370
+ wrap = false;
371
+ }
372
+ return {
373
+ anchor,
374
+ composed,
375
+ filter,
376
+ include,
377
+ skipNegativeTabIndexCheck,
378
+ skipVisibilityCheck,
379
+ wrap
380
+ };
381
+ }
319
382
 
320
383
  // src/index.ts
321
384
  function createRovingTabIndex(container, options = {}) {
@@ -338,56 +401,7 @@ var RovingTabIndex = class _RovingTabIndex {
338
401
  #isDestroyed = false;
339
402
  constructor(container, options = {}) {
340
403
  this.#container = container;
341
- let {
342
- direction = "both",
343
- navigationOnly = false,
344
- noMemory = false,
345
- noStart = false,
346
- selector = "",
347
- typeahead = false,
348
- wrap = false
349
- } = options;
350
- if (!["both", "horizontal", "vertical"].includes(direction)) {
351
- console.warn("Invalid direction option. Fallback: 'both'.");
352
- direction = "both";
353
- }
354
- if (typeof navigationOnly !== "boolean") {
355
- console.warn("Invalid navigationOnly option. Fallback: false.");
356
- navigationOnly = false;
357
- }
358
- if (typeof noMemory !== "boolean") {
359
- console.warn("Invalid noMemory option. Fallback: false.");
360
- noMemory = false;
361
- }
362
- if (typeof noStart !== "boolean") {
363
- console.warn("Invalid noStart option. Fallback: false.");
364
- noStart = false;
365
- }
366
- if (selector !== "") {
367
- try {
368
- document.querySelector(selector);
369
- } catch {
370
- console.warn("Invalid selector. Fallback: no selector string.");
371
- selector = "";
372
- }
373
- }
374
- if (typeof typeahead !== "boolean") {
375
- console.warn("Invalid typeahead option. Fallback: false.");
376
- typeahead = false;
377
- }
378
- if (typeof wrap !== "boolean") {
379
- console.warn("Invalid wrap option. Fallback: false.");
380
- wrap = false;
381
- }
382
- this.#settings = {
383
- direction,
384
- navigationOnly,
385
- noMemory,
386
- noStart,
387
- selector,
388
- typeahead,
389
- wrap
390
- };
404
+ this.#settings = this.#resolveOptions(options);
391
405
  this.#selectorFilter = this.#createSelectorFilter();
392
406
  this.#initialize();
393
407
  }
@@ -575,13 +589,65 @@ var RovingTabIndex = class _RovingTabIndex {
575
589
  skipVisibilityCheck: true
576
590
  });
577
591
  }
592
+ #resolveOptions(options) {
593
+ let {
594
+ direction = "both",
595
+ navigationOnly = false,
596
+ noMemory = false,
597
+ noStart = false,
598
+ selector = "",
599
+ typeahead = false,
600
+ wrap = false
601
+ } = options;
602
+ if (!["both", "horizontal", "vertical"].includes(direction)) {
603
+ console.warn("Invalid direction option. Fallback: 'both'.");
604
+ direction = "both";
605
+ }
606
+ if (typeof navigationOnly !== "boolean") {
607
+ console.warn("Invalid navigationOnly option. Fallback: false.");
608
+ navigationOnly = false;
609
+ }
610
+ if (typeof noMemory !== "boolean") {
611
+ console.warn("Invalid noMemory option. Fallback: false.");
612
+ noMemory = false;
613
+ }
614
+ if (typeof noStart !== "boolean") {
615
+ console.warn("Invalid noStart option. Fallback: false.");
616
+ noStart = false;
617
+ }
618
+ if (selector !== "") {
619
+ try {
620
+ document.querySelector(selector);
621
+ } catch {
622
+ console.warn("Invalid selector. Fallback: no selector string.");
623
+ selector = "";
624
+ }
625
+ }
626
+ if (typeof typeahead !== "boolean") {
627
+ console.warn("Invalid typeahead option. Fallback: false.");
628
+ typeahead = false;
629
+ }
630
+ if (typeof wrap !== "boolean") {
631
+ console.warn("Invalid wrap option. Fallback: false.");
632
+ wrap = false;
633
+ }
634
+ return {
635
+ direction,
636
+ navigationOnly,
637
+ noMemory,
638
+ noStart,
639
+ selector,
640
+ typeahead,
641
+ wrap
642
+ };
643
+ }
578
644
  };
579
645
  /**
580
646
  * Roving Tabindex
581
647
  * Lightweight roving tabindex utility with fully focus management.
582
648
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
583
649
  *
584
- * @version 3.1.25
650
+ * @version 3.1.27
585
651
  * @author Yusuke Kamiyamane
586
652
  * @license MIT
587
653
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -593,7 +659,7 @@ var RovingTabIndex = class _RovingTabIndex {
593
659
  (**
594
660
  * Attribute Utils
595
661
  *
596
- * @version 2.0.5
662
+ * @version 2.0.8
597
663
  * @author Yusuke Kamiyamane
598
664
  * @license MIT
599
665
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -606,7 +672,7 @@ power-focusable/dist/index.js:
606
672
  * High-precision focus management utility with full composed tree support.
607
673
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
608
674
  *
609
- * @version 4.3.26
675
+ * @version 4.3.29
610
676
  * @author Yusuke Kamiyamane
611
677
  * @license MIT
612
678
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.cjs CHANGED
@@ -45,56 +45,7 @@ var RovingTabIndex = class _RovingTabIndex {
45
45
  #isDestroyed = false;
46
46
  constructor(container, options = {}) {
47
47
  this.#container = container;
48
- let {
49
- direction = "both",
50
- navigationOnly = false,
51
- noMemory = false,
52
- noStart = false,
53
- selector = "",
54
- typeahead = false,
55
- wrap = false
56
- } = options;
57
- if (!["both", "horizontal", "vertical"].includes(direction)) {
58
- console.warn("Invalid direction option. Fallback: 'both'.");
59
- direction = "both";
60
- }
61
- if (typeof navigationOnly !== "boolean") {
62
- console.warn("Invalid navigationOnly option. Fallback: false.");
63
- navigationOnly = false;
64
- }
65
- if (typeof noMemory !== "boolean") {
66
- console.warn("Invalid noMemory option. Fallback: false.");
67
- noMemory = false;
68
- }
69
- if (typeof noStart !== "boolean") {
70
- console.warn("Invalid noStart option. Fallback: false.");
71
- noStart = false;
72
- }
73
- if (selector !== "") {
74
- try {
75
- document.querySelector(selector);
76
- } catch {
77
- console.warn("Invalid selector. Fallback: no selector string.");
78
- selector = "";
79
- }
80
- }
81
- if (typeof typeahead !== "boolean") {
82
- console.warn("Invalid typeahead option. Fallback: false.");
83
- typeahead = false;
84
- }
85
- if (typeof wrap !== "boolean") {
86
- console.warn("Invalid wrap option. Fallback: false.");
87
- wrap = false;
88
- }
89
- this.#settings = {
90
- direction,
91
- navigationOnly,
92
- noMemory,
93
- noStart,
94
- selector,
95
- typeahead,
96
- wrap
97
- };
48
+ this.#settings = this.#resolveOptions(options);
98
49
  this.#selectorFilter = this.#createSelectorFilter();
99
50
  this.#initialize();
100
51
  }
@@ -282,13 +233,65 @@ var RovingTabIndex = class _RovingTabIndex {
282
233
  skipVisibilityCheck: true
283
234
  });
284
235
  }
236
+ #resolveOptions(options) {
237
+ let {
238
+ direction = "both",
239
+ navigationOnly = false,
240
+ noMemory = false,
241
+ noStart = false,
242
+ selector = "",
243
+ typeahead = false,
244
+ wrap = false
245
+ } = options;
246
+ if (!["both", "horizontal", "vertical"].includes(direction)) {
247
+ console.warn("Invalid direction option. Fallback: 'both'.");
248
+ direction = "both";
249
+ }
250
+ if (typeof navigationOnly !== "boolean") {
251
+ console.warn("Invalid navigationOnly option. Fallback: false.");
252
+ navigationOnly = false;
253
+ }
254
+ if (typeof noMemory !== "boolean") {
255
+ console.warn("Invalid noMemory option. Fallback: false.");
256
+ noMemory = false;
257
+ }
258
+ if (typeof noStart !== "boolean") {
259
+ console.warn("Invalid noStart option. Fallback: false.");
260
+ noStart = false;
261
+ }
262
+ if (selector !== "") {
263
+ try {
264
+ document.querySelector(selector);
265
+ } catch {
266
+ console.warn("Invalid selector. Fallback: no selector string.");
267
+ selector = "";
268
+ }
269
+ }
270
+ if (typeof typeahead !== "boolean") {
271
+ console.warn("Invalid typeahead option. Fallback: false.");
272
+ typeahead = false;
273
+ }
274
+ if (typeof wrap !== "boolean") {
275
+ console.warn("Invalid wrap option. Fallback: false.");
276
+ wrap = false;
277
+ }
278
+ return {
279
+ direction,
280
+ navigationOnly,
281
+ noMemory,
282
+ noStart,
283
+ selector,
284
+ typeahead,
285
+ wrap
286
+ };
287
+ }
285
288
  };
286
289
  /**
287
290
  * Roving Tabindex
288
291
  * Lightweight roving tabindex utility with fully focus management.
289
292
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
290
293
  *
291
- * @version 3.1.25
294
+ * @version 3.1.27
292
295
  * @author Yusuke Kamiyamane
293
296
  * @license MIT
294
297
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.cts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Lightweight roving tabindex utility with fully focus management.
4
4
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
5
5
  *
6
- * @version 3.1.25
6
+ * @version 3.1.27
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Lightweight roving tabindex utility with fully focus management.
4
4
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
5
5
  *
6
- * @version 3.1.25
6
+ * @version 3.1.27
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -22,56 +22,7 @@ var RovingTabIndex = class _RovingTabIndex {
22
22
  #isDestroyed = false;
23
23
  constructor(container, options = {}) {
24
24
  this.#container = container;
25
- let {
26
- direction = "both",
27
- navigationOnly = false,
28
- noMemory = false,
29
- noStart = false,
30
- selector = "",
31
- typeahead = false,
32
- wrap = false
33
- } = options;
34
- if (!["both", "horizontal", "vertical"].includes(direction)) {
35
- console.warn("Invalid direction option. Fallback: 'both'.");
36
- direction = "both";
37
- }
38
- if (typeof navigationOnly !== "boolean") {
39
- console.warn("Invalid navigationOnly option. Fallback: false.");
40
- navigationOnly = false;
41
- }
42
- if (typeof noMemory !== "boolean") {
43
- console.warn("Invalid noMemory option. Fallback: false.");
44
- noMemory = false;
45
- }
46
- if (typeof noStart !== "boolean") {
47
- console.warn("Invalid noStart option. Fallback: false.");
48
- noStart = false;
49
- }
50
- if (selector !== "") {
51
- try {
52
- document.querySelector(selector);
53
- } catch {
54
- console.warn("Invalid selector. Fallback: no selector string.");
55
- selector = "";
56
- }
57
- }
58
- if (typeof typeahead !== "boolean") {
59
- console.warn("Invalid typeahead option. Fallback: false.");
60
- typeahead = false;
61
- }
62
- if (typeof wrap !== "boolean") {
63
- console.warn("Invalid wrap option. Fallback: false.");
64
- wrap = false;
65
- }
66
- this.#settings = {
67
- direction,
68
- navigationOnly,
69
- noMemory,
70
- noStart,
71
- selector,
72
- typeahead,
73
- wrap
74
- };
25
+ this.#settings = this.#resolveOptions(options);
75
26
  this.#selectorFilter = this.#createSelectorFilter();
76
27
  this.#initialize();
77
28
  }
@@ -259,13 +210,65 @@ var RovingTabIndex = class _RovingTabIndex {
259
210
  skipVisibilityCheck: true
260
211
  });
261
212
  }
213
+ #resolveOptions(options) {
214
+ let {
215
+ direction = "both",
216
+ navigationOnly = false,
217
+ noMemory = false,
218
+ noStart = false,
219
+ selector = "",
220
+ typeahead = false,
221
+ wrap = false
222
+ } = options;
223
+ if (!["both", "horizontal", "vertical"].includes(direction)) {
224
+ console.warn("Invalid direction option. Fallback: 'both'.");
225
+ direction = "both";
226
+ }
227
+ if (typeof navigationOnly !== "boolean") {
228
+ console.warn("Invalid navigationOnly option. Fallback: false.");
229
+ navigationOnly = false;
230
+ }
231
+ if (typeof noMemory !== "boolean") {
232
+ console.warn("Invalid noMemory option. Fallback: false.");
233
+ noMemory = false;
234
+ }
235
+ if (typeof noStart !== "boolean") {
236
+ console.warn("Invalid noStart option. Fallback: false.");
237
+ noStart = false;
238
+ }
239
+ if (selector !== "") {
240
+ try {
241
+ document.querySelector(selector);
242
+ } catch {
243
+ console.warn("Invalid selector. Fallback: no selector string.");
244
+ selector = "";
245
+ }
246
+ }
247
+ if (typeof typeahead !== "boolean") {
248
+ console.warn("Invalid typeahead option. Fallback: false.");
249
+ typeahead = false;
250
+ }
251
+ if (typeof wrap !== "boolean") {
252
+ console.warn("Invalid wrap option. Fallback: false.");
253
+ wrap = false;
254
+ }
255
+ return {
256
+ direction,
257
+ navigationOnly,
258
+ noMemory,
259
+ noStart,
260
+ selector,
261
+ typeahead,
262
+ wrap
263
+ };
264
+ }
262
265
  };
263
266
  /**
264
267
  * Roving Tabindex
265
268
  * Lightweight roving tabindex utility with fully focus management.
266
269
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
267
270
  *
268
- * @version 3.1.25
271
+ * @version 3.1.27
269
272
  * @author Yusuke Kamiyamane
270
273
  * @license MIT
271
274
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,28 +1,7 @@
1
1
  {
2
2
  "name": "@y14e/roving-tabindex",
3
- "version": "3.1.25",
3
+ "version": "3.1.27",
4
4
  "description": "Lightweight roving tabindex utility with fully focus management",
5
- "type": "module",
6
- "main": "./dist/index.cjs",
7
- "module": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
- "exports": {
10
- ".": {
11
- "types": "./dist/index.d.ts",
12
- "import": "./dist/index.js",
13
- "require": "./dist/index.cjs"
14
- }
15
- },
16
- "files": [
17
- "dist",
18
- "LICENSE",
19
- "README.md"
20
- ],
21
- "scripts": {
22
- "build": "tsup",
23
- "prepublishOnly": "npm run build",
24
- "lint": "tsc --noEmit"
25
- },
26
5
  "keywords": [
27
6
  "a11y",
28
7
  "accessibility",
@@ -37,16 +16,41 @@
37
16
  "typescript",
38
17
  "utility"
39
18
  ],
40
- "author": "Yusuke Kamiyamane",
41
- "license": "MIT",
19
+ "homepage": "https://github.com/y14e/roving-tabindex#readme",
20
+ "bugs": {
21
+ "url": "https://github.com/y14e/roving-tabindex/issues"
22
+ },
42
23
  "repository": {
43
24
  "type": "git",
44
25
  "url": "git+https://github.com/y14e/roving-tabindex.git"
45
26
  },
46
- "bugs": {
47
- "url": "https://github.com/y14e/roving-tabindex/issues"
27
+ "license": "MIT",
28
+ "author": "Yusuke Kamiyamane",
29
+ "type": "module",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "import": "./dist/index.js",
34
+ "require": "./dist/index.cjs"
35
+ }
36
+ },
37
+ "main": "./dist/index.cjs",
38
+ "module": "./dist/index.js",
39
+ "types": "./dist/index.d.ts",
40
+ "files": [
41
+ "dist",
42
+ "LICENSE",
43
+ "README.md"
44
+ ],
45
+ "scripts": {
46
+ "build": "tsup",
47
+ "lint": "tsc --noEmit",
48
+ "prepublishOnly": "npm run build"
49
+ },
50
+ "dependencies": {
51
+ "@y14e/attribute-utils": "^2.0.8",
52
+ "power-focusable": "^4.3.29"
48
53
  },
49
- "homepage": "https://github.com/y14e/roving-tabindex#readme",
50
54
  "devDependencies": {
51
55
  "bun-types": "latest",
52
56
  "tsup": "^8.0.0",
@@ -57,9 +61,5 @@
57
61
  },
58
62
  "allowScripts": {
59
63
  "esbuild": true
60
- },
61
- "dependencies": {
62
- "@y14e/attribute-utils": "^2.0.5",
63
- "power-focusable": "^4.3.26"
64
64
  }
65
65
  }