@y14e/roving-tabindex 2.0.7 → 2.1.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 +9 -4
- package/dist/index.cjs +19 -10
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +19 -10
- package/package.json +3 -3
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.0
|
|
13
|
+
import { createRovingTabIndex } from '@y14e/roving-tabindex@2.1.0';
|
|
14
14
|
|
|
15
15
|
// CDNs
|
|
16
|
-
import { createRovingTabIndex } from 'https://esm.sh/@y14e/roving-tabindex@2.0
|
|
16
|
+
import { createRovingTabIndex } from 'https://esm.sh/@y14e/roving-tabindex@2.1.0';
|
|
17
17
|
// or
|
|
18
|
-
import { createRovingTabIndex } from 'https://cdn.jsdelivr.net/npm/@y14e/roving-tabindex@2.0
|
|
18
|
+
import { createRovingTabIndex } from 'https://cdn.jsdelivr.net/npm/@y14e/roving-tabindex@2.1.0/+esm';
|
|
19
19
|
// or
|
|
20
|
-
import { createRovingTabIndex } from 'https://esm.unpkg.com/@y14e/roving-tabindex@2.0
|
|
20
|
+
import { createRovingTabIndex } from 'https://esm.unpkg.com/@y14e/roving-tabindex@2.1.0';
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
## 📦 APIs
|
|
@@ -40,6 +40,7 @@ const cleanup = createRovingTabIndex(container, options);
|
|
|
40
40
|
interface RovingTabIndexOptions {
|
|
41
41
|
direction?: 'horizontal' | 'vertical'; // default: both (undefined)
|
|
42
42
|
navigationOnly?: boolean; // default: false
|
|
43
|
+
noMemory?: boolean; // default: false
|
|
43
44
|
selector?: string;
|
|
44
45
|
typeahead?: boolean; // default: false
|
|
45
46
|
wrap?: boolean; // default: false
|
|
@@ -50,6 +51,10 @@ interface RovingTabIndexOptions {
|
|
|
50
51
|
|
|
51
52
|
If `true`, enables keyboard navigation without modifying `tabindex`. Useful for widgets like accordions where all items should remain tabbable while still supporting arrow key navigation.
|
|
52
53
|
|
|
54
|
+
### `noMemory`
|
|
55
|
+
|
|
56
|
+
If `true`, disables focus memory. Focus always starts from the first item.
|
|
57
|
+
|
|
53
58
|
### `typeahead`
|
|
54
59
|
|
|
55
60
|
If `true`, enables character-based focus navigation. Typing a character moves focus to the next matching element.
|
package/dist/index.cjs
CHANGED
|
@@ -13,11 +13,10 @@ function addTokenToAttribute(element, attribute, token, options = {}) {
|
|
|
13
13
|
const tokens = value ? parse(value).filter(Boolean) : [];
|
|
14
14
|
if (caseInsensitive) {
|
|
15
15
|
const lower = token.toLowerCase();
|
|
16
|
-
if (tokens.
|
|
17
|
-
|
|
16
|
+
if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
|
|
17
|
+
tokens.push(token);
|
|
18
|
+
element.setAttribute(attribute, serialize(tokens));
|
|
18
19
|
}
|
|
19
|
-
tokens.push(token);
|
|
20
|
-
element.setAttribute(attribute, serialize(tokens));
|
|
21
20
|
return;
|
|
22
21
|
}
|
|
23
22
|
const set = new Set(tokens);
|
|
@@ -300,6 +299,7 @@ function createRovingTabIndex(container, options = {}) {
|
|
|
300
299
|
let {
|
|
301
300
|
direction,
|
|
302
301
|
navigationOnly = false,
|
|
302
|
+
noMemory = false,
|
|
303
303
|
selector,
|
|
304
304
|
typeahead = false,
|
|
305
305
|
wrap = false
|
|
@@ -312,6 +312,10 @@ function createRovingTabIndex(container, options = {}) {
|
|
|
312
312
|
console.warn("Invalid navigationOnly option. Fallback: false.");
|
|
313
313
|
navigationOnly = false;
|
|
314
314
|
}
|
|
315
|
+
if (typeof noMemory !== "boolean") {
|
|
316
|
+
console.warn("Invalid noMemory option. Fallback: false.");
|
|
317
|
+
noMemory = false;
|
|
318
|
+
}
|
|
315
319
|
if (typeof selector !== "undefined" && (typeof selector !== "string" || !selector.trim())) {
|
|
316
320
|
console.warn(
|
|
317
321
|
"Invalid selector. Fallback: all focusable elements (undefined)."
|
|
@@ -326,7 +330,7 @@ function createRovingTabIndex(container, options = {}) {
|
|
|
326
330
|
console.warn("Invalid wrap option. Fallback: false.");
|
|
327
331
|
wrap = false;
|
|
328
332
|
}
|
|
329
|
-
const settings = { navigationOnly, typeahead, wrap };
|
|
333
|
+
const settings = { navigationOnly, noMemory, typeahead, wrap };
|
|
330
334
|
direction && Object.assign(settings, { direction });
|
|
331
335
|
selector && Object.assign(settings, { selector });
|
|
332
336
|
const roving = new RovingTabIndex(container, settings);
|
|
@@ -374,10 +378,15 @@ var RovingTabIndex = class {
|
|
|
374
378
|
}
|
|
375
379
|
#onFocusIn = (event) => {
|
|
376
380
|
const { target } = event;
|
|
377
|
-
if (!(target instanceof Element)
|
|
381
|
+
if (!(target instanceof Element)) {
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
const isFocusable2 = this.#focusables.has(target);
|
|
385
|
+
if (this.#options.noMemory && !isFocusable2) {
|
|
386
|
+
this.#update(null);
|
|
378
387
|
return;
|
|
379
388
|
}
|
|
380
|
-
this.#update(target);
|
|
389
|
+
isFocusable2 && this.#update(target);
|
|
381
390
|
};
|
|
382
391
|
#onKeyDown = (event) => {
|
|
383
392
|
if (!event.composedPath().includes(this.#container)) {
|
|
@@ -527,7 +536,7 @@ function getActiveElement() {
|
|
|
527
536
|
* Lightweight roving tabindex utility with fully focus management.
|
|
528
537
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
529
538
|
*
|
|
530
|
-
* @version 2.0
|
|
539
|
+
* @version 2.1.0
|
|
531
540
|
* @author Yusuke Kamiyamane
|
|
532
541
|
* @license MIT
|
|
533
542
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -539,7 +548,7 @@ function getActiveElement() {
|
|
|
539
548
|
(**
|
|
540
549
|
* Attributes Utils
|
|
541
550
|
*
|
|
542
|
-
* @version 1.1.
|
|
551
|
+
* @version 1.1.1
|
|
543
552
|
* @author Yusuke Kamiyamane
|
|
544
553
|
* @license MIT
|
|
545
554
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -552,7 +561,7 @@ power-focusable/dist/index.js:
|
|
|
552
561
|
* High-precision focus management utility with full composed tree support.
|
|
553
562
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
554
563
|
*
|
|
555
|
-
* @version 4.3.
|
|
564
|
+
* @version 4.3.2
|
|
556
565
|
* @author Yusuke Kamiyamane
|
|
557
566
|
* @license MIT
|
|
558
567
|
* @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.0
|
|
6
|
+
* @version 2.1.0
|
|
7
7
|
* @author Yusuke Kamiyamane
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
interface RovingTabIndexOptions {
|
|
13
13
|
readonly direction?: 'horizontal' | 'vertical';
|
|
14
14
|
readonly navigationOnly?: boolean;
|
|
15
|
+
readonly noMemory?: boolean;
|
|
15
16
|
readonly selector?: string;
|
|
16
17
|
readonly typeahead?: boolean;
|
|
17
18
|
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.0
|
|
6
|
+
* @version 2.1.0
|
|
7
7
|
* @author Yusuke Kamiyamane
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
interface RovingTabIndexOptions {
|
|
13
13
|
readonly direction?: 'horizontal' | 'vertical';
|
|
14
14
|
readonly navigationOnly?: boolean;
|
|
15
|
+
readonly noMemory?: boolean;
|
|
15
16
|
readonly selector?: string;
|
|
16
17
|
readonly typeahead?: boolean;
|
|
17
18
|
readonly wrap?: boolean;
|
package/dist/index.js
CHANGED
|
@@ -11,11 +11,10 @@ function addTokenToAttribute(element, attribute, token, options = {}) {
|
|
|
11
11
|
const tokens = value ? parse(value).filter(Boolean) : [];
|
|
12
12
|
if (caseInsensitive) {
|
|
13
13
|
const lower = token.toLowerCase();
|
|
14
|
-
if (tokens.
|
|
15
|
-
|
|
14
|
+
if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
|
|
15
|
+
tokens.push(token);
|
|
16
|
+
element.setAttribute(attribute, serialize(tokens));
|
|
16
17
|
}
|
|
17
|
-
tokens.push(token);
|
|
18
|
-
element.setAttribute(attribute, serialize(tokens));
|
|
19
18
|
return;
|
|
20
19
|
}
|
|
21
20
|
const set = new Set(tokens);
|
|
@@ -298,6 +297,7 @@ function createRovingTabIndex(container, options = {}) {
|
|
|
298
297
|
let {
|
|
299
298
|
direction,
|
|
300
299
|
navigationOnly = false,
|
|
300
|
+
noMemory = false,
|
|
301
301
|
selector,
|
|
302
302
|
typeahead = false,
|
|
303
303
|
wrap = false
|
|
@@ -310,6 +310,10 @@ function createRovingTabIndex(container, options = {}) {
|
|
|
310
310
|
console.warn("Invalid navigationOnly option. Fallback: false.");
|
|
311
311
|
navigationOnly = false;
|
|
312
312
|
}
|
|
313
|
+
if (typeof noMemory !== "boolean") {
|
|
314
|
+
console.warn("Invalid noMemory option. Fallback: false.");
|
|
315
|
+
noMemory = false;
|
|
316
|
+
}
|
|
313
317
|
if (typeof selector !== "undefined" && (typeof selector !== "string" || !selector.trim())) {
|
|
314
318
|
console.warn(
|
|
315
319
|
"Invalid selector. Fallback: all focusable elements (undefined)."
|
|
@@ -324,7 +328,7 @@ function createRovingTabIndex(container, options = {}) {
|
|
|
324
328
|
console.warn("Invalid wrap option. Fallback: false.");
|
|
325
329
|
wrap = false;
|
|
326
330
|
}
|
|
327
|
-
const settings = { navigationOnly, typeahead, wrap };
|
|
331
|
+
const settings = { navigationOnly, noMemory, typeahead, wrap };
|
|
328
332
|
direction && Object.assign(settings, { direction });
|
|
329
333
|
selector && Object.assign(settings, { selector });
|
|
330
334
|
const roving = new RovingTabIndex(container, settings);
|
|
@@ -372,10 +376,15 @@ var RovingTabIndex = class {
|
|
|
372
376
|
}
|
|
373
377
|
#onFocusIn = (event) => {
|
|
374
378
|
const { target } = event;
|
|
375
|
-
if (!(target instanceof Element)
|
|
379
|
+
if (!(target instanceof Element)) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
const isFocusable2 = this.#focusables.has(target);
|
|
383
|
+
if (this.#options.noMemory && !isFocusable2) {
|
|
384
|
+
this.#update(null);
|
|
376
385
|
return;
|
|
377
386
|
}
|
|
378
|
-
this.#update(target);
|
|
387
|
+
isFocusable2 && this.#update(target);
|
|
379
388
|
};
|
|
380
389
|
#onKeyDown = (event) => {
|
|
381
390
|
if (!event.composedPath().includes(this.#container)) {
|
|
@@ -525,7 +534,7 @@ function getActiveElement() {
|
|
|
525
534
|
* Lightweight roving tabindex utility with fully focus management.
|
|
526
535
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
527
536
|
*
|
|
528
|
-
* @version 2.0
|
|
537
|
+
* @version 2.1.0
|
|
529
538
|
* @author Yusuke Kamiyamane
|
|
530
539
|
* @license MIT
|
|
531
540
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -537,7 +546,7 @@ function getActiveElement() {
|
|
|
537
546
|
(**
|
|
538
547
|
* Attributes Utils
|
|
539
548
|
*
|
|
540
|
-
* @version 1.1.
|
|
549
|
+
* @version 1.1.1
|
|
541
550
|
* @author Yusuke Kamiyamane
|
|
542
551
|
* @license MIT
|
|
543
552
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -550,7 +559,7 @@ power-focusable/dist/index.js:
|
|
|
550
559
|
* High-precision focus management utility with full composed tree support.
|
|
551
560
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
552
561
|
*
|
|
553
|
-
* @version 4.3.
|
|
562
|
+
* @version 4.3.2
|
|
554
563
|
* @author Yusuke Kamiyamane
|
|
555
564
|
* @license MIT
|
|
556
565
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@y14e/roving-tabindex",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Lightweight roving tabindex utility with fully focus management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -48,9 +48,9 @@
|
|
|
48
48
|
},
|
|
49
49
|
"homepage": "https://github.com/y14e/roving-tabindex#readme",
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@y14e/attributes-utils": "^1.1.
|
|
51
|
+
"@y14e/attributes-utils": "^1.1.1",
|
|
52
52
|
"bun-types": "latest",
|
|
53
|
-
"power-focusable": "^4.3.
|
|
53
|
+
"power-focusable": "^4.3.2",
|
|
54
54
|
"tsup": "^8.0.0",
|
|
55
55
|
"typescript": "^5.6.0"
|
|
56
56
|
},
|