@y14e/roving-tabindex 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,14 +10,14 @@ npm i @y14e/roving-tabindex
10
10
 
11
11
  ```ts
12
12
  // npm
13
- import { createRovingTabIndex } from '@y14e/roving-tabindex@2.1.0';
13
+ import { createRovingTabIndex } from '@y14e/roving-tabindex@2.2.0';
14
14
 
15
15
  // CDNs
16
- import { createRovingTabIndex } from 'https://esm.sh/@y14e/roving-tabindex@2.1.0';
16
+ import { createRovingTabIndex } from 'https://esm.sh/@y14e/roving-tabindex@2.2.0';
17
17
  // or
18
- import { createRovingTabIndex } from 'https://cdn.jsdelivr.net/npm/@y14e/roving-tabindex@2.1.0/+esm';
18
+ import { createRovingTabIndex } from 'https://cdn.jsdelivr.net/npm/@y14e/roving-tabindex@2.2.0/+esm';
19
19
  // or
20
- import { createRovingTabIndex } from 'https://esm.unpkg.com/@y14e/roving-tabindex@2.1.0';
20
+ import { createRovingTabIndex } from 'https://esm.unpkg.com/@y14e/roving-tabindex@2.2.0';
21
21
  ```
22
22
 
23
23
  ## 📦 APIs
@@ -41,6 +41,7 @@ interface RovingTabIndexOptions {
41
41
  direction?: 'horizontal' | 'vertical'; // default: both (undefined)
42
42
  navigationOnly?: boolean; // default: false
43
43
  noMemory?: boolean; // default: false
44
+ noStart?: boolean; // default: false
44
45
  selector?: string;
45
46
  typeahead?: boolean; // default: false
46
47
  wrap?: boolean; // default: false
@@ -55,6 +56,10 @@ If `true`, enables keyboard navigation without modifying `tabindex`. Useful for
55
56
 
56
57
  If `true`, disables focus memory. Focus always starts from the first item.
57
58
 
59
+ ### `noStart`
60
+
61
+ If `true`, does not assign `tabindex="0"` to the first item during initialization.
62
+
58
63
  ### `typeahead`
59
64
 
60
65
  If `true`, enables character-based focus navigation. Typing a character moves focus to the next matching element.
package/dist/index.cjs CHANGED
@@ -300,6 +300,7 @@ function createRovingTabIndex(container, options = {}) {
300
300
  direction,
301
301
  navigationOnly = false,
302
302
  noMemory = false,
303
+ noStart = false,
303
304
  selector,
304
305
  typeahead = false,
305
306
  wrap = false
@@ -316,6 +317,10 @@ function createRovingTabIndex(container, options = {}) {
316
317
  console.warn("Invalid noMemory option. Fallback: false.");
317
318
  noMemory = false;
318
319
  }
320
+ if (typeof noStart !== "boolean") {
321
+ console.warn("Invalid noStart option. Fallback: false.");
322
+ noStart = false;
323
+ }
319
324
  if (typeof selector !== "undefined" && (typeof selector !== "string" || !selector.trim())) {
320
325
  console.warn(
321
326
  "Invalid selector. Fallback: all focusable elements (undefined)."
@@ -330,7 +335,7 @@ function createRovingTabIndex(container, options = {}) {
330
335
  console.warn("Invalid wrap option. Fallback: false.");
331
336
  wrap = false;
332
337
  }
333
- const settings = { navigationOnly, noMemory, typeahead, wrap };
338
+ const settings = { navigationOnly, noMemory, noStart, typeahead, wrap };
334
339
  direction && Object.assign(settings, { direction });
335
340
  selector && Object.assign(settings, { selector });
336
341
  const roving = new RovingTabIndex(container, settings);
@@ -464,7 +469,7 @@ var RovingTabIndex = class {
464
469
  index >= 0 && focusables.splice(index, 1);
465
470
  });
466
471
  }
467
- const { navigationOnly } = this.#options;
472
+ const { navigationOnly, noStart, typeahead } = this.#options;
468
473
  for (const focusable of current) {
469
474
  if (this.#focusables.has(focusable)) {
470
475
  continue;
@@ -474,7 +479,7 @@ var RovingTabIndex = class {
474
479
  saveAttributes([focusable], ["tabindex"]);
475
480
  focusable.setAttribute("tabindex", "-1");
476
481
  }
477
- if (!this.#options.typeahead) {
482
+ if (!typeahead) {
478
483
  continue;
479
484
  }
480
485
  const value = focusable.ariaKeyShortcuts?.trim();
@@ -505,7 +510,7 @@ var RovingTabIndex = class {
505
510
  return;
506
511
  }
507
512
  [...this.#focusables].forEach((focusable, i) => {
508
- focusable.setAttribute("tabindex", i ? "-1" : "0");
513
+ focusable.setAttribute("tabindex", i || noStart ? "-1" : "0");
509
514
  });
510
515
  }
511
516
  #createSelectorFilter() {
@@ -536,7 +541,7 @@ function getActiveElement() {
536
541
  * Lightweight roving tabindex utility with fully focus management.
537
542
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
538
543
  *
539
- * @version 2.1.0
544
+ * @version 2.2.0
540
545
  * @author Yusuke Kamiyamane
541
546
  * @license MIT
542
547
  * @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 2.1.0
6
+ * @version 2.2.0
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -13,6 +13,7 @@ interface RovingTabIndexOptions {
13
13
  readonly direction?: 'horizontal' | 'vertical';
14
14
  readonly navigationOnly?: boolean;
15
15
  readonly noMemory?: boolean;
16
+ readonly noStart?: boolean;
16
17
  readonly selector?: string;
17
18
  readonly typeahead?: boolean;
18
19
  readonly wrap?: boolean;
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 2.1.0
6
+ * @version 2.2.0
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -13,6 +13,7 @@ interface RovingTabIndexOptions {
13
13
  readonly direction?: 'horizontal' | 'vertical';
14
14
  readonly navigationOnly?: boolean;
15
15
  readonly noMemory?: boolean;
16
+ readonly noStart?: boolean;
16
17
  readonly selector?: string;
17
18
  readonly typeahead?: boolean;
18
19
  readonly wrap?: boolean;
package/dist/index.js CHANGED
@@ -298,6 +298,7 @@ function createRovingTabIndex(container, options = {}) {
298
298
  direction,
299
299
  navigationOnly = false,
300
300
  noMemory = false,
301
+ noStart = false,
301
302
  selector,
302
303
  typeahead = false,
303
304
  wrap = false
@@ -314,6 +315,10 @@ function createRovingTabIndex(container, options = {}) {
314
315
  console.warn("Invalid noMemory option. Fallback: false.");
315
316
  noMemory = false;
316
317
  }
318
+ if (typeof noStart !== "boolean") {
319
+ console.warn("Invalid noStart option. Fallback: false.");
320
+ noStart = false;
321
+ }
317
322
  if (typeof selector !== "undefined" && (typeof selector !== "string" || !selector.trim())) {
318
323
  console.warn(
319
324
  "Invalid selector. Fallback: all focusable elements (undefined)."
@@ -328,7 +333,7 @@ function createRovingTabIndex(container, options = {}) {
328
333
  console.warn("Invalid wrap option. Fallback: false.");
329
334
  wrap = false;
330
335
  }
331
- const settings = { navigationOnly, noMemory, typeahead, wrap };
336
+ const settings = { navigationOnly, noMemory, noStart, typeahead, wrap };
332
337
  direction && Object.assign(settings, { direction });
333
338
  selector && Object.assign(settings, { selector });
334
339
  const roving = new RovingTabIndex(container, settings);
@@ -462,7 +467,7 @@ var RovingTabIndex = class {
462
467
  index >= 0 && focusables.splice(index, 1);
463
468
  });
464
469
  }
465
- const { navigationOnly } = this.#options;
470
+ const { navigationOnly, noStart, typeahead } = this.#options;
466
471
  for (const focusable of current) {
467
472
  if (this.#focusables.has(focusable)) {
468
473
  continue;
@@ -472,7 +477,7 @@ var RovingTabIndex = class {
472
477
  saveAttributes([focusable], ["tabindex"]);
473
478
  focusable.setAttribute("tabindex", "-1");
474
479
  }
475
- if (!this.#options.typeahead) {
480
+ if (!typeahead) {
476
481
  continue;
477
482
  }
478
483
  const value = focusable.ariaKeyShortcuts?.trim();
@@ -503,7 +508,7 @@ var RovingTabIndex = class {
503
508
  return;
504
509
  }
505
510
  [...this.#focusables].forEach((focusable, i) => {
506
- focusable.setAttribute("tabindex", i ? "-1" : "0");
511
+ focusable.setAttribute("tabindex", i || noStart ? "-1" : "0");
507
512
  });
508
513
  }
509
514
  #createSelectorFilter() {
@@ -534,7 +539,7 @@ function getActiveElement() {
534
539
  * Lightweight roving tabindex utility with fully focus management.
535
540
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
536
541
  *
537
- * @version 2.1.0
542
+ * @version 2.2.0
538
543
  * @author Yusuke Kamiyamane
539
544
  * @license MIT
540
545
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/roving-tabindex",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "Lightweight roving tabindex utility with fully focus management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",