@y14e/roving-tabindex 3.1.24 → 3.1.26

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.26';
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.26/+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.26';
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,45 @@ 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
+ if (!element.hasAttribute(name)) {
57
+ console.warn("Invalid attribute 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
+ }
52
90
 
53
91
  // node_modules/power-focusable/dist/index.js
54
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"])`;
@@ -340,64 +378,7 @@ var RovingTabIndex = class _RovingTabIndex {
340
378
  #isDestroyed = false;
341
379
  constructor(container, options = {}) {
342
380
  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
- let hasError = false;
370
- if (typeof selector !== "string" || !selector.trim()) {
371
- hasError = true;
372
- } else {
373
- try {
374
- this.#container.querySelector(selector);
375
- } catch {
376
- hasError = true;
377
- }
378
- }
379
- if (hasError) {
380
- console.warn("Invalid selector. Fallback: no selector string.");
381
- selector = "";
382
- }
383
- }
384
- if (typeof typeahead !== "boolean") {
385
- console.warn("Invalid typeahead option. Fallback: false.");
386
- typeahead = false;
387
- }
388
- if (typeof wrap !== "boolean") {
389
- console.warn("Invalid wrap option. Fallback: false.");
390
- wrap = false;
391
- }
392
- this.#settings = {
393
- direction,
394
- navigationOnly,
395
- noMemory,
396
- noStart,
397
- selector,
398
- typeahead,
399
- wrap
400
- };
381
+ this.#settings = this.#resolveOptions(options);
401
382
  this.#selectorFilter = this.#createSelectorFilter();
402
383
  this.#initialize();
403
384
  }
@@ -585,13 +566,65 @@ var RovingTabIndex = class _RovingTabIndex {
585
566
  skipVisibilityCheck: true
586
567
  });
587
568
  }
569
+ #resolveOptions(options) {
570
+ let {
571
+ direction = "both",
572
+ navigationOnly = false,
573
+ noMemory = false,
574
+ noStart = false,
575
+ selector = "",
576
+ typeahead = false,
577
+ wrap = false
578
+ } = options;
579
+ if (!["both", "horizontal", "vertical"].includes(direction)) {
580
+ console.warn("Invalid direction option. Fallback: 'both'.");
581
+ direction = "both";
582
+ }
583
+ if (typeof navigationOnly !== "boolean") {
584
+ console.warn("Invalid navigationOnly option. Fallback: false.");
585
+ navigationOnly = false;
586
+ }
587
+ if (typeof noMemory !== "boolean") {
588
+ console.warn("Invalid noMemory option. Fallback: false.");
589
+ noMemory = false;
590
+ }
591
+ if (typeof noStart !== "boolean") {
592
+ console.warn("Invalid noStart option. Fallback: false.");
593
+ noStart = false;
594
+ }
595
+ if (selector !== "") {
596
+ try {
597
+ document.querySelector(selector);
598
+ } catch {
599
+ console.warn("Invalid selector. Fallback: no selector string.");
600
+ selector = "";
601
+ }
602
+ }
603
+ if (typeof typeahead !== "boolean") {
604
+ console.warn("Invalid typeahead option. Fallback: false.");
605
+ typeahead = false;
606
+ }
607
+ if (typeof wrap !== "boolean") {
608
+ console.warn("Invalid wrap option. Fallback: false.");
609
+ wrap = false;
610
+ }
611
+ return {
612
+ direction,
613
+ navigationOnly,
614
+ noMemory,
615
+ noStart,
616
+ selector,
617
+ typeahead,
618
+ wrap
619
+ };
620
+ }
588
621
  };
589
622
  /**
590
623
  * Roving Tabindex
591
624
  * Lightweight roving tabindex utility with fully focus management.
592
625
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
593
626
  *
594
- * @version 3.1.24
627
+ * @version 3.1.26
595
628
  * @author Yusuke Kamiyamane
596
629
  * @license MIT
597
630
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -603,7 +636,7 @@ var RovingTabIndex = class _RovingTabIndex {
603
636
  (**
604
637
  * Attribute Utils
605
638
  *
606
- * @version 2.0.5
639
+ * @version 2.0.6
607
640
  * @author Yusuke Kamiyamane
608
641
  * @license MIT
609
642
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -616,7 +649,7 @@ power-focusable/dist/index.js:
616
649
  * High-precision focus management utility with full composed tree support.
617
650
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
618
651
  *
619
- * @version 4.3.26
652
+ * @version 4.3.28
620
653
  * @author Yusuke Kamiyamane
621
654
  * @license MIT
622
655
  * @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,45 @@ 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
+ if (!element.hasAttribute(name)) {
55
+ console.warn("Invalid attribute name");
56
+ return false;
57
+ }
58
+ if (typeof token !== "string" || !token.trim()) {
59
+ console.warn("Invalid token");
60
+ return false;
61
+ }
62
+ return true;
63
+ }
64
+ function resolveOptions(options) {
65
+ let {
66
+ caseInsensitive = false,
67
+ parse = DEFAULT_PARSER,
68
+ serialize = DEFAULT_SERIALIZER
69
+ } = options;
70
+ if (typeof caseInsensitive !== "boolean") {
71
+ console.warn("Invalid caseInsensitive option. Fallback: false.");
72
+ caseInsensitive = false;
73
+ }
74
+ if (typeof parse !== "function") {
75
+ console.warn(
76
+ "Invalid parser. Fallback: default parser (splits by whitespace)."
77
+ );
78
+ parse = DEFAULT_PARSER;
79
+ }
80
+ if (typeof serialize !== "function") {
81
+ console.warn(
82
+ "Invalid serializer. Fallback: default serializer (joins by whitespace)."
83
+ );
84
+ serialize = DEFAULT_SERIALIZER;
85
+ }
86
+ return { caseInsensitive, parse, serialize };
87
+ }
50
88
 
51
89
  // node_modules/power-focusable/dist/index.js
52
90
  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"])`;
@@ -338,64 +376,7 @@ var RovingTabIndex = class _RovingTabIndex {
338
376
  #isDestroyed = false;
339
377
  constructor(container, options = {}) {
340
378
  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
- let hasError = false;
368
- if (typeof selector !== "string" || !selector.trim()) {
369
- hasError = true;
370
- } else {
371
- try {
372
- this.#container.querySelector(selector);
373
- } catch {
374
- hasError = true;
375
- }
376
- }
377
- if (hasError) {
378
- console.warn("Invalid selector. Fallback: no selector string.");
379
- selector = "";
380
- }
381
- }
382
- if (typeof typeahead !== "boolean") {
383
- console.warn("Invalid typeahead option. Fallback: false.");
384
- typeahead = false;
385
- }
386
- if (typeof wrap !== "boolean") {
387
- console.warn("Invalid wrap option. Fallback: false.");
388
- wrap = false;
389
- }
390
- this.#settings = {
391
- direction,
392
- navigationOnly,
393
- noMemory,
394
- noStart,
395
- selector,
396
- typeahead,
397
- wrap
398
- };
379
+ this.#settings = this.#resolveOptions(options);
399
380
  this.#selectorFilter = this.#createSelectorFilter();
400
381
  this.#initialize();
401
382
  }
@@ -583,13 +564,65 @@ var RovingTabIndex = class _RovingTabIndex {
583
564
  skipVisibilityCheck: true
584
565
  });
585
566
  }
567
+ #resolveOptions(options) {
568
+ let {
569
+ direction = "both",
570
+ navigationOnly = false,
571
+ noMemory = false,
572
+ noStart = false,
573
+ selector = "",
574
+ typeahead = false,
575
+ wrap = false
576
+ } = options;
577
+ if (!["both", "horizontal", "vertical"].includes(direction)) {
578
+ console.warn("Invalid direction option. Fallback: 'both'.");
579
+ direction = "both";
580
+ }
581
+ if (typeof navigationOnly !== "boolean") {
582
+ console.warn("Invalid navigationOnly option. Fallback: false.");
583
+ navigationOnly = false;
584
+ }
585
+ if (typeof noMemory !== "boolean") {
586
+ console.warn("Invalid noMemory option. Fallback: false.");
587
+ noMemory = false;
588
+ }
589
+ if (typeof noStart !== "boolean") {
590
+ console.warn("Invalid noStart option. Fallback: false.");
591
+ noStart = false;
592
+ }
593
+ if (selector !== "") {
594
+ try {
595
+ document.querySelector(selector);
596
+ } catch {
597
+ console.warn("Invalid selector. Fallback: no selector string.");
598
+ selector = "";
599
+ }
600
+ }
601
+ if (typeof typeahead !== "boolean") {
602
+ console.warn("Invalid typeahead option. Fallback: false.");
603
+ typeahead = false;
604
+ }
605
+ if (typeof wrap !== "boolean") {
606
+ console.warn("Invalid wrap option. Fallback: false.");
607
+ wrap = false;
608
+ }
609
+ return {
610
+ direction,
611
+ navigationOnly,
612
+ noMemory,
613
+ noStart,
614
+ selector,
615
+ typeahead,
616
+ wrap
617
+ };
618
+ }
586
619
  };
587
620
  /**
588
621
  * Roving Tabindex
589
622
  * Lightweight roving tabindex utility with fully focus management.
590
623
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
591
624
  *
592
- * @version 3.1.24
625
+ * @version 3.1.26
593
626
  * @author Yusuke Kamiyamane
594
627
  * @license MIT
595
628
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -601,7 +634,7 @@ var RovingTabIndex = class _RovingTabIndex {
601
634
  (**
602
635
  * Attribute Utils
603
636
  *
604
- * @version 2.0.5
637
+ * @version 2.0.6
605
638
  * @author Yusuke Kamiyamane
606
639
  * @license MIT
607
640
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -614,7 +647,7 @@ power-focusable/dist/index.js:
614
647
  * High-precision focus management utility with full composed tree support.
615
648
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
616
649
  *
617
- * @version 4.3.26
650
+ * @version 4.3.28
618
651
  * @author Yusuke Kamiyamane
619
652
  * @license MIT
620
653
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.cjs CHANGED
@@ -45,64 +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
- let hasError = false;
75
- if (typeof selector !== "string" || !selector.trim()) {
76
- hasError = true;
77
- } else {
78
- try {
79
- this.#container.querySelector(selector);
80
- } catch {
81
- hasError = true;
82
- }
83
- }
84
- if (hasError) {
85
- console.warn("Invalid selector. Fallback: no selector string.");
86
- selector = "";
87
- }
88
- }
89
- if (typeof typeahead !== "boolean") {
90
- console.warn("Invalid typeahead option. Fallback: false.");
91
- typeahead = false;
92
- }
93
- if (typeof wrap !== "boolean") {
94
- console.warn("Invalid wrap option. Fallback: false.");
95
- wrap = false;
96
- }
97
- this.#settings = {
98
- direction,
99
- navigationOnly,
100
- noMemory,
101
- noStart,
102
- selector,
103
- typeahead,
104
- wrap
105
- };
48
+ this.#settings = this.#resolveOptions(options);
106
49
  this.#selectorFilter = this.#createSelectorFilter();
107
50
  this.#initialize();
108
51
  }
@@ -290,13 +233,65 @@ var RovingTabIndex = class _RovingTabIndex {
290
233
  skipVisibilityCheck: true
291
234
  });
292
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
+ }
293
288
  };
294
289
  /**
295
290
  * Roving Tabindex
296
291
  * Lightweight roving tabindex utility with fully focus management.
297
292
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
298
293
  *
299
- * @version 3.1.24
294
+ * @version 3.1.26
300
295
  * @author Yusuke Kamiyamane
301
296
  * @license MIT
302
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.24
6
+ * @version 3.1.26
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.24
6
+ * @version 3.1.26
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -22,64 +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
- let hasError = false;
52
- if (typeof selector !== "string" || !selector.trim()) {
53
- hasError = true;
54
- } else {
55
- try {
56
- this.#container.querySelector(selector);
57
- } catch {
58
- hasError = true;
59
- }
60
- }
61
- if (hasError) {
62
- console.warn("Invalid selector. Fallback: no selector string.");
63
- selector = "";
64
- }
65
- }
66
- if (typeof typeahead !== "boolean") {
67
- console.warn("Invalid typeahead option. Fallback: false.");
68
- typeahead = false;
69
- }
70
- if (typeof wrap !== "boolean") {
71
- console.warn("Invalid wrap option. Fallback: false.");
72
- wrap = false;
73
- }
74
- this.#settings = {
75
- direction,
76
- navigationOnly,
77
- noMemory,
78
- noStart,
79
- selector,
80
- typeahead,
81
- wrap
82
- };
25
+ this.#settings = this.#resolveOptions(options);
83
26
  this.#selectorFilter = this.#createSelectorFilter();
84
27
  this.#initialize();
85
28
  }
@@ -267,13 +210,65 @@ var RovingTabIndex = class _RovingTabIndex {
267
210
  skipVisibilityCheck: true
268
211
  });
269
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
+ }
270
265
  };
271
266
  /**
272
267
  * Roving Tabindex
273
268
  * Lightweight roving tabindex utility with fully focus management.
274
269
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
275
270
  *
276
- * @version 3.1.24
271
+ * @version 3.1.26
277
272
  * @author Yusuke Kamiyamane
278
273
  * @license MIT
279
274
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/roving-tabindex",
3
- "version": "3.1.24",
3
+ "version": "3.1.26",
4
4
  "description": "Lightweight roving tabindex utility with fully focus management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -59,7 +59,7 @@
59
59
  "esbuild": true
60
60
  },
61
61
  "dependencies": {
62
- "@y14e/attribute-utils": "^2.0.5",
63
- "power-focusable": "^4.3.26"
62
+ "@y14e/attribute-utils": "^2.0.6",
63
+ "power-focusable": "^4.3.28"
64
64
  }
65
65
  }