@y14e/roving-tabindex 1.2.4 → 1.2.5
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/dist/index.cjs +22 -22
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +22 -22
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -9,8 +9,8 @@ function addTokenToAttribute(element, attribute, token, options = {}) {
|
|
|
9
9
|
parse = defaultParser,
|
|
10
10
|
serialize = defaultSerializer
|
|
11
11
|
} = options;
|
|
12
|
-
const
|
|
13
|
-
const tokens =
|
|
12
|
+
const value = element.getAttribute(attribute)?.trim();
|
|
13
|
+
const tokens = value ? parse(value).filter(Boolean) : [];
|
|
14
14
|
if (caseInsensitive) {
|
|
15
15
|
const lower = token.toLowerCase();
|
|
16
16
|
if (tokens.some((token2) => token2.toLowerCase() === lower)) {
|
|
@@ -345,16 +345,16 @@ var RovingTabIndex = class {
|
|
|
345
345
|
if (!(active instanceof HTMLElement)) {
|
|
346
346
|
return;
|
|
347
347
|
}
|
|
348
|
-
const
|
|
349
|
-
if (!
|
|
348
|
+
const current = this.#getFocusables();
|
|
349
|
+
if (!current.includes(active)) {
|
|
350
350
|
return;
|
|
351
351
|
}
|
|
352
352
|
event.preventDefault();
|
|
353
353
|
event.stopPropagation();
|
|
354
|
-
const currentIndex =
|
|
354
|
+
const currentIndex = current.indexOf(active);
|
|
355
355
|
let rawIndex;
|
|
356
356
|
let newIndex = currentIndex;
|
|
357
|
-
let target =
|
|
357
|
+
let target = current;
|
|
358
358
|
switch (key) {
|
|
359
359
|
case "End":
|
|
360
360
|
newIndex = -1;
|
|
@@ -370,7 +370,7 @@ var RovingTabIndex = class {
|
|
|
370
370
|
case "ArrowRight":
|
|
371
371
|
case "ArrowDown":
|
|
372
372
|
rawIndex = currentIndex + 1;
|
|
373
|
-
newIndex = wrap ? rawIndex %
|
|
373
|
+
newIndex = wrap ? rawIndex % current.length : Math.min(rawIndex, current.length - 1);
|
|
374
374
|
break;
|
|
375
375
|
default: {
|
|
376
376
|
if (!typeahead) {
|
|
@@ -378,7 +378,7 @@ var RovingTabIndex = class {
|
|
|
378
378
|
}
|
|
379
379
|
target = this.#focusablesByFirstChar.get(key.toUpperCase()) ?? [];
|
|
380
380
|
const foundIndex = target.findIndex(
|
|
381
|
-
(focusable2) =>
|
|
381
|
+
(focusable2) => current.indexOf(focusable2) > currentIndex
|
|
382
382
|
);
|
|
383
383
|
newIndex = foundIndex !== -1 ? foundIndex : 0;
|
|
384
384
|
}
|
|
@@ -391,7 +391,7 @@ var RovingTabIndex = class {
|
|
|
391
391
|
focusElement(focusable);
|
|
392
392
|
};
|
|
393
393
|
#update(active) {
|
|
394
|
-
const
|
|
394
|
+
const current = /* @__PURE__ */ new Set([
|
|
395
395
|
...this.#getFocusables(),
|
|
396
396
|
...getFocusables(this.#container, {
|
|
397
397
|
composed: true,
|
|
@@ -399,21 +399,21 @@ var RovingTabIndex = class {
|
|
|
399
399
|
})
|
|
400
400
|
]);
|
|
401
401
|
for (const focusable of this.#focusables) {
|
|
402
|
-
if (
|
|
402
|
+
if (current.has(focusable)) {
|
|
403
403
|
continue;
|
|
404
404
|
}
|
|
405
405
|
if (focusable.isConnected) {
|
|
406
406
|
restoreAttributes([focusable]);
|
|
407
407
|
}
|
|
408
408
|
this.#focusables.delete(focusable);
|
|
409
|
-
this.#focusablesByFirstChar.forEach((
|
|
410
|
-
const index =
|
|
411
|
-
if (index
|
|
412
|
-
|
|
409
|
+
this.#focusablesByFirstChar.forEach((focusables) => {
|
|
410
|
+
const index = focusables.indexOf(focusable);
|
|
411
|
+
if (index >= 0) {
|
|
412
|
+
focusables.splice(index, 1);
|
|
413
413
|
}
|
|
414
414
|
});
|
|
415
415
|
}
|
|
416
|
-
for (const focusable of
|
|
416
|
+
for (const focusable of current) {
|
|
417
417
|
if (this.#focusables.has(focusable)) {
|
|
418
418
|
continue;
|
|
419
419
|
}
|
|
@@ -423,9 +423,9 @@ var RovingTabIndex = class {
|
|
|
423
423
|
if (!this.#options.typeahead) {
|
|
424
424
|
continue;
|
|
425
425
|
}
|
|
426
|
-
const
|
|
426
|
+
const value = focusable.ariaKeyShortcuts?.trim();
|
|
427
427
|
const keys = new Set(
|
|
428
|
-
|
|
428
|
+
value ? value.split(/\s+/).filter((key) => /^\S$/i.test(key)).map((key) => key.toUpperCase()) : []
|
|
429
429
|
);
|
|
430
430
|
const char = focusable.textContent?.trim()?.at(0)?.toUpperCase();
|
|
431
431
|
if (char) {
|
|
@@ -436,9 +436,9 @@ var RovingTabIndex = class {
|
|
|
436
436
|
});
|
|
437
437
|
}
|
|
438
438
|
keys.forEach((key) => {
|
|
439
|
-
const
|
|
440
|
-
|
|
441
|
-
this.#focusablesByFirstChar.set(key,
|
|
439
|
+
const focusables = this.#focusablesByFirstChar.get(key) ?? [];
|
|
440
|
+
focusables.push(focusable);
|
|
441
|
+
this.#focusablesByFirstChar.set(key, focusables);
|
|
442
442
|
});
|
|
443
443
|
}
|
|
444
444
|
if (active && this.#focusables.has(active)) {
|
|
@@ -478,7 +478,7 @@ function getActiveElement() {
|
|
|
478
478
|
* Lightweight roving tabindex utility with fully focus management.
|
|
479
479
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
480
480
|
*
|
|
481
|
-
* @version 1.2.
|
|
481
|
+
* @version 1.2.5
|
|
482
482
|
* @author Yusuke Kamiyamane
|
|
483
483
|
* @license MIT
|
|
484
484
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -490,7 +490,7 @@ function getActiveElement() {
|
|
|
490
490
|
(**
|
|
491
491
|
* Attributes Utils
|
|
492
492
|
*
|
|
493
|
-
* @version 1.0.
|
|
493
|
+
* @version 1.0.5
|
|
494
494
|
* @author Yusuke Kamiyamane
|
|
495
495
|
* @license MIT
|
|
496
496
|
* @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 1.2.
|
|
6
|
+
* @version 1.2.5
|
|
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 1.2.
|
|
6
|
+
* @version 1.2.5
|
|
7
7
|
* @author Yusuke Kamiyamane
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.js
CHANGED
|
@@ -7,8 +7,8 @@ function addTokenToAttribute(element, attribute, token, options = {}) {
|
|
|
7
7
|
parse = defaultParser,
|
|
8
8
|
serialize = defaultSerializer
|
|
9
9
|
} = options;
|
|
10
|
-
const
|
|
11
|
-
const tokens =
|
|
10
|
+
const value = element.getAttribute(attribute)?.trim();
|
|
11
|
+
const tokens = value ? parse(value).filter(Boolean) : [];
|
|
12
12
|
if (caseInsensitive) {
|
|
13
13
|
const lower = token.toLowerCase();
|
|
14
14
|
if (tokens.some((token2) => token2.toLowerCase() === lower)) {
|
|
@@ -343,16 +343,16 @@ var RovingTabIndex = class {
|
|
|
343
343
|
if (!(active instanceof HTMLElement)) {
|
|
344
344
|
return;
|
|
345
345
|
}
|
|
346
|
-
const
|
|
347
|
-
if (!
|
|
346
|
+
const current = this.#getFocusables();
|
|
347
|
+
if (!current.includes(active)) {
|
|
348
348
|
return;
|
|
349
349
|
}
|
|
350
350
|
event.preventDefault();
|
|
351
351
|
event.stopPropagation();
|
|
352
|
-
const currentIndex =
|
|
352
|
+
const currentIndex = current.indexOf(active);
|
|
353
353
|
let rawIndex;
|
|
354
354
|
let newIndex = currentIndex;
|
|
355
|
-
let target =
|
|
355
|
+
let target = current;
|
|
356
356
|
switch (key) {
|
|
357
357
|
case "End":
|
|
358
358
|
newIndex = -1;
|
|
@@ -368,7 +368,7 @@ var RovingTabIndex = class {
|
|
|
368
368
|
case "ArrowRight":
|
|
369
369
|
case "ArrowDown":
|
|
370
370
|
rawIndex = currentIndex + 1;
|
|
371
|
-
newIndex = wrap ? rawIndex %
|
|
371
|
+
newIndex = wrap ? rawIndex % current.length : Math.min(rawIndex, current.length - 1);
|
|
372
372
|
break;
|
|
373
373
|
default: {
|
|
374
374
|
if (!typeahead) {
|
|
@@ -376,7 +376,7 @@ var RovingTabIndex = class {
|
|
|
376
376
|
}
|
|
377
377
|
target = this.#focusablesByFirstChar.get(key.toUpperCase()) ?? [];
|
|
378
378
|
const foundIndex = target.findIndex(
|
|
379
|
-
(focusable2) =>
|
|
379
|
+
(focusable2) => current.indexOf(focusable2) > currentIndex
|
|
380
380
|
);
|
|
381
381
|
newIndex = foundIndex !== -1 ? foundIndex : 0;
|
|
382
382
|
}
|
|
@@ -389,7 +389,7 @@ var RovingTabIndex = class {
|
|
|
389
389
|
focusElement(focusable);
|
|
390
390
|
};
|
|
391
391
|
#update(active) {
|
|
392
|
-
const
|
|
392
|
+
const current = /* @__PURE__ */ new Set([
|
|
393
393
|
...this.#getFocusables(),
|
|
394
394
|
...getFocusables(this.#container, {
|
|
395
395
|
composed: true,
|
|
@@ -397,21 +397,21 @@ var RovingTabIndex = class {
|
|
|
397
397
|
})
|
|
398
398
|
]);
|
|
399
399
|
for (const focusable of this.#focusables) {
|
|
400
|
-
if (
|
|
400
|
+
if (current.has(focusable)) {
|
|
401
401
|
continue;
|
|
402
402
|
}
|
|
403
403
|
if (focusable.isConnected) {
|
|
404
404
|
restoreAttributes([focusable]);
|
|
405
405
|
}
|
|
406
406
|
this.#focusables.delete(focusable);
|
|
407
|
-
this.#focusablesByFirstChar.forEach((
|
|
408
|
-
const index =
|
|
409
|
-
if (index
|
|
410
|
-
|
|
407
|
+
this.#focusablesByFirstChar.forEach((focusables) => {
|
|
408
|
+
const index = focusables.indexOf(focusable);
|
|
409
|
+
if (index >= 0) {
|
|
410
|
+
focusables.splice(index, 1);
|
|
411
411
|
}
|
|
412
412
|
});
|
|
413
413
|
}
|
|
414
|
-
for (const focusable of
|
|
414
|
+
for (const focusable of current) {
|
|
415
415
|
if (this.#focusables.has(focusable)) {
|
|
416
416
|
continue;
|
|
417
417
|
}
|
|
@@ -421,9 +421,9 @@ var RovingTabIndex = class {
|
|
|
421
421
|
if (!this.#options.typeahead) {
|
|
422
422
|
continue;
|
|
423
423
|
}
|
|
424
|
-
const
|
|
424
|
+
const value = focusable.ariaKeyShortcuts?.trim();
|
|
425
425
|
const keys = new Set(
|
|
426
|
-
|
|
426
|
+
value ? value.split(/\s+/).filter((key) => /^\S$/i.test(key)).map((key) => key.toUpperCase()) : []
|
|
427
427
|
);
|
|
428
428
|
const char = focusable.textContent?.trim()?.at(0)?.toUpperCase();
|
|
429
429
|
if (char) {
|
|
@@ -434,9 +434,9 @@ var RovingTabIndex = class {
|
|
|
434
434
|
});
|
|
435
435
|
}
|
|
436
436
|
keys.forEach((key) => {
|
|
437
|
-
const
|
|
438
|
-
|
|
439
|
-
this.#focusablesByFirstChar.set(key,
|
|
437
|
+
const focusables = this.#focusablesByFirstChar.get(key) ?? [];
|
|
438
|
+
focusables.push(focusable);
|
|
439
|
+
this.#focusablesByFirstChar.set(key, focusables);
|
|
440
440
|
});
|
|
441
441
|
}
|
|
442
442
|
if (active && this.#focusables.has(active)) {
|
|
@@ -476,7 +476,7 @@ function getActiveElement() {
|
|
|
476
476
|
* Lightweight roving tabindex utility with fully focus management.
|
|
477
477
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
478
478
|
*
|
|
479
|
-
* @version 1.2.
|
|
479
|
+
* @version 1.2.5
|
|
480
480
|
* @author Yusuke Kamiyamane
|
|
481
481
|
* @license MIT
|
|
482
482
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -488,7 +488,7 @@ function getActiveElement() {
|
|
|
488
488
|
(**
|
|
489
489
|
* Attributes Utils
|
|
490
490
|
*
|
|
491
|
-
* @version 1.0.
|
|
491
|
+
* @version 1.0.5
|
|
492
492
|
* @author Yusuke Kamiyamane
|
|
493
493
|
* @license MIT
|
|
494
494
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@y14e/roving-tabindex",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.5",
|
|
4
4
|
"description": "Lightweight roving tabindex utility with fully focus management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
},
|
|
49
49
|
"homepage": "https://github.com/y14e/roving-tabindex#readme",
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@y14e/attributes-utils": "^1.0.
|
|
51
|
+
"@y14e/attributes-utils": "^1.0.5",
|
|
52
52
|
"bun-types": "latest",
|
|
53
53
|
"power-focusable": "^4.1.7",
|
|
54
54
|
"tsup": "^8.0.0",
|