@y14e/roving-tabindex 3.1.13 → 3.1.15
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 +3 -3
- package/dist/index.bundle.cjs +48 -46
- package/dist/index.bundle.js +48 -46
- package/dist/index.cjs +13 -12
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +13 -12
- package/package.json +2 -2
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.
|
|
16
|
+
import { createRovingTabIndex } from 'https://esm.sh/@y14e/roving-tabindex@3.1.15';
|
|
17
17
|
// or
|
|
18
|
-
import { createRovingTabIndex } from 'https://cdn.jsdelivr.net/npm/@y14e/roving-tabindex@3.1.
|
|
18
|
+
import { createRovingTabIndex } from 'https://cdn.jsdelivr.net/npm/@y14e/roving-tabindex@3.1.15/+esm';
|
|
19
19
|
// or
|
|
20
|
-
import { createRovingTabIndex } from 'https://esm.unpkg.com/@y14e/roving-tabindex@3.1.
|
|
20
|
+
import { createRovingTabIndex } from 'https://esm.unpkg.com/@y14e/roving-tabindex@3.1.15';
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
## 📦 APIs
|
package/dist/index.bundle.cjs
CHANGED
|
@@ -51,7 +51,7 @@ function saveAttributes(elements, attributes) {
|
|
|
51
51
|
|
|
52
52
|
// node_modules/power-focusable/dist/index.js
|
|
53
53
|
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"])`;
|
|
54
|
-
var
|
|
54
|
+
var FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX = FOCUSABLE_SELECTOR.replace(
|
|
55
55
|
/(,\s*)?\[tabindex="-1"\]/g,
|
|
56
56
|
""
|
|
57
57
|
);
|
|
@@ -91,14 +91,14 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
91
91
|
console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
|
|
92
92
|
skipVisibilityCheck = false;
|
|
93
93
|
}
|
|
94
|
-
const
|
|
94
|
+
const candidates = [];
|
|
95
95
|
if (composed || include) {
|
|
96
96
|
let traverse2 = function(node) {
|
|
97
97
|
if (isFocusable(node, {
|
|
98
98
|
skipNegativeTabIndexCheck,
|
|
99
99
|
skipVisibilityCheck
|
|
100
100
|
}) || include?.(node)) {
|
|
101
|
-
|
|
101
|
+
candidates[candidates.length] = node;
|
|
102
102
|
}
|
|
103
103
|
const children2 = composed ? getComposedChildren(node) : getChildren(node);
|
|
104
104
|
for (let i = 0, l = children2.length; i < l; i++) {
|
|
@@ -112,21 +112,22 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
112
112
|
child && traverse2(child);
|
|
113
113
|
}
|
|
114
114
|
} else {
|
|
115
|
-
const
|
|
116
|
-
skipNegativeTabIndexCheck ?
|
|
115
|
+
const matches = container.querySelectorAll(
|
|
116
|
+
skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX : FOCUSABLE_SELECTOR
|
|
117
117
|
);
|
|
118
|
-
for (let i = 0, l =
|
|
119
|
-
const
|
|
120
|
-
if (
|
|
118
|
+
for (let i = 0, l = matches.length; i < l; i++) {
|
|
119
|
+
const matched = matches[i];
|
|
120
|
+
if (matched && isFocusable(matched, {
|
|
121
121
|
skipNegativeTabIndexCheck,
|
|
122
122
|
skipVisibilityCheck
|
|
123
123
|
})) {
|
|
124
|
-
|
|
124
|
+
candidates[candidates.length] = matched;
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
return normalizeRadioGroup(
|
|
129
|
+
sortByTabIndex(filter ? candidates.filter(filter) : candidates)
|
|
130
|
+
);
|
|
130
131
|
}
|
|
131
132
|
function isFocusable(element, options = {}) {
|
|
132
133
|
if (!(element instanceof Element)) {
|
|
@@ -149,7 +150,7 @@ function isFocusable(element, options = {}) {
|
|
|
149
150
|
return false;
|
|
150
151
|
}
|
|
151
152
|
if (!element.matches(
|
|
152
|
-
skipNegativeTabIndexCheck ?
|
|
153
|
+
skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX : FOCUSABLE_SELECTOR
|
|
153
154
|
)) {
|
|
154
155
|
return false;
|
|
155
156
|
}
|
|
@@ -195,7 +196,7 @@ function isDisabledDeep(element) {
|
|
|
195
196
|
return false;
|
|
196
197
|
}
|
|
197
198
|
function normalizeRadioGroup(elements) {
|
|
198
|
-
let
|
|
199
|
+
let map = null;
|
|
199
200
|
for (let i = 0, l = elements.length; i < l; i++) {
|
|
200
201
|
const element = elements[i];
|
|
201
202
|
if (!(element instanceof HTMLInputElement)) {
|
|
@@ -204,35 +205,35 @@ function normalizeRadioGroup(elements) {
|
|
|
204
205
|
if (!isUngroupedRadio(element)) {
|
|
205
206
|
continue;
|
|
206
207
|
}
|
|
207
|
-
if (!
|
|
208
|
-
|
|
208
|
+
if (!map) {
|
|
209
|
+
map = /* @__PURE__ */ new Map();
|
|
209
210
|
}
|
|
210
211
|
const root = element.getRootNode();
|
|
211
|
-
let
|
|
212
|
-
if (!
|
|
213
|
-
|
|
214
|
-
|
|
212
|
+
let value = map.get(root);
|
|
213
|
+
if (!value) {
|
|
214
|
+
value = /* @__PURE__ */ new Map();
|
|
215
|
+
map.set(root, value);
|
|
215
216
|
}
|
|
216
|
-
let
|
|
217
|
-
if (!
|
|
218
|
-
|
|
219
|
-
|
|
217
|
+
let v = value.get(element.form);
|
|
218
|
+
if (!v) {
|
|
219
|
+
v = /* @__PURE__ */ new Map();
|
|
220
|
+
value.set(element.form, v);
|
|
220
221
|
}
|
|
221
|
-
let
|
|
222
|
-
if (!
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
let vv = v.get(element.name);
|
|
223
|
+
if (!vv) {
|
|
224
|
+
vv = [];
|
|
225
|
+
v.set(element.name, vv);
|
|
225
226
|
}
|
|
226
|
-
|
|
227
|
+
vv[vv.length] = element;
|
|
227
228
|
}
|
|
228
|
-
if (!
|
|
229
|
+
if (!map) {
|
|
229
230
|
return elements;
|
|
230
231
|
}
|
|
231
232
|
const placeholder = /* @__PURE__ */ new Set();
|
|
232
|
-
for (const
|
|
233
|
-
for (const
|
|
234
|
-
for (const
|
|
235
|
-
const radio =
|
|
233
|
+
for (const value of map.values()) {
|
|
234
|
+
for (const v of value.values()) {
|
|
235
|
+
for (const vv of v.values()) {
|
|
236
|
+
const radio = vv.find((element) => element.checked) ?? vv[0];
|
|
236
237
|
radio && placeholder.add(radio);
|
|
237
238
|
}
|
|
238
239
|
}
|
|
@@ -459,16 +460,16 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
459
460
|
if (!(active instanceof Element)) {
|
|
460
461
|
return;
|
|
461
462
|
}
|
|
462
|
-
const
|
|
463
|
+
const candidates = this.#getFocusables().filter(
|
|
463
464
|
(focusable2) => this.#focusables.has(focusable2)
|
|
464
465
|
);
|
|
465
|
-
if (!
|
|
466
|
+
if (!candidates.includes(active)) {
|
|
466
467
|
return;
|
|
467
468
|
}
|
|
468
469
|
event.preventDefault();
|
|
469
|
-
const
|
|
470
|
+
const activeIndex = candidates.indexOf(active);
|
|
470
471
|
let newIndex;
|
|
471
|
-
let target =
|
|
472
|
+
let target = candidates;
|
|
472
473
|
switch (key) {
|
|
473
474
|
case "End":
|
|
474
475
|
newIndex = -1;
|
|
@@ -478,25 +479,26 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
478
479
|
break;
|
|
479
480
|
case "ArrowLeft":
|
|
480
481
|
case "ArrowUp": {
|
|
481
|
-
const rawIndex =
|
|
482
|
+
const rawIndex = activeIndex - 1;
|
|
482
483
|
newIndex = wrap ? rawIndex : Math.max(rawIndex, 0);
|
|
483
484
|
break;
|
|
484
485
|
}
|
|
485
486
|
case "ArrowRight":
|
|
486
487
|
case "ArrowDown": {
|
|
487
|
-
const rawIndex =
|
|
488
|
-
|
|
488
|
+
const rawIndex = activeIndex + 1;
|
|
489
|
+
const length = target.length;
|
|
490
|
+
newIndex = wrap ? rawIndex % length : Math.min(rawIndex, length - 1);
|
|
489
491
|
break;
|
|
490
492
|
}
|
|
491
493
|
default: {
|
|
492
494
|
const focusables = new Set(
|
|
493
495
|
this.#focusablesByFirstChar.get(key.toUpperCase()) ?? []
|
|
494
496
|
);
|
|
495
|
-
target =
|
|
496
|
-
const
|
|
497
|
-
(focusable2) =>
|
|
497
|
+
target = candidates.filter((focusable2) => focusables.has(focusable2));
|
|
498
|
+
const afterIndex = target.findIndex(
|
|
499
|
+
(focusable2) => candidates.indexOf(focusable2) > activeIndex
|
|
498
500
|
);
|
|
499
|
-
newIndex =
|
|
501
|
+
newIndex = afterIndex >= 0 ? afterIndex : 0;
|
|
500
502
|
}
|
|
501
503
|
}
|
|
502
504
|
const focusable = target.at(newIndex);
|
|
@@ -583,7 +585,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
583
585
|
* Lightweight roving tabindex utility with fully focus management.
|
|
584
586
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
585
587
|
*
|
|
586
|
-
* @version 3.1.
|
|
588
|
+
* @version 3.1.15
|
|
587
589
|
* @author Yusuke Kamiyamane
|
|
588
590
|
* @license MIT
|
|
589
591
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -608,7 +610,7 @@ power-focusable/dist/index.js:
|
|
|
608
610
|
* High-precision focus management utility with full composed tree support.
|
|
609
611
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
610
612
|
*
|
|
611
|
-
* @version 4.3.
|
|
613
|
+
* @version 4.3.19
|
|
612
614
|
* @author Yusuke Kamiyamane
|
|
613
615
|
* @license MIT
|
|
614
616
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.bundle.js
CHANGED
|
@@ -49,7 +49,7 @@ function saveAttributes(elements, attributes) {
|
|
|
49
49
|
|
|
50
50
|
// node_modules/power-focusable/dist/index.js
|
|
51
51
|
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"])`;
|
|
52
|
-
var
|
|
52
|
+
var FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX = FOCUSABLE_SELECTOR.replace(
|
|
53
53
|
/(,\s*)?\[tabindex="-1"\]/g,
|
|
54
54
|
""
|
|
55
55
|
);
|
|
@@ -89,14 +89,14 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
89
89
|
console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
|
|
90
90
|
skipVisibilityCheck = false;
|
|
91
91
|
}
|
|
92
|
-
const
|
|
92
|
+
const candidates = [];
|
|
93
93
|
if (composed || include) {
|
|
94
94
|
let traverse2 = function(node) {
|
|
95
95
|
if (isFocusable(node, {
|
|
96
96
|
skipNegativeTabIndexCheck,
|
|
97
97
|
skipVisibilityCheck
|
|
98
98
|
}) || include?.(node)) {
|
|
99
|
-
|
|
99
|
+
candidates[candidates.length] = node;
|
|
100
100
|
}
|
|
101
101
|
const children2 = composed ? getComposedChildren(node) : getChildren(node);
|
|
102
102
|
for (let i = 0, l = children2.length; i < l; i++) {
|
|
@@ -110,21 +110,22 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
110
110
|
child && traverse2(child);
|
|
111
111
|
}
|
|
112
112
|
} else {
|
|
113
|
-
const
|
|
114
|
-
skipNegativeTabIndexCheck ?
|
|
113
|
+
const matches = container.querySelectorAll(
|
|
114
|
+
skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX : FOCUSABLE_SELECTOR
|
|
115
115
|
);
|
|
116
|
-
for (let i = 0, l =
|
|
117
|
-
const
|
|
118
|
-
if (
|
|
116
|
+
for (let i = 0, l = matches.length; i < l; i++) {
|
|
117
|
+
const matched = matches[i];
|
|
118
|
+
if (matched && isFocusable(matched, {
|
|
119
119
|
skipNegativeTabIndexCheck,
|
|
120
120
|
skipVisibilityCheck
|
|
121
121
|
})) {
|
|
122
|
-
|
|
122
|
+
candidates[candidates.length] = matched;
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
return normalizeRadioGroup(
|
|
127
|
+
sortByTabIndex(filter ? candidates.filter(filter) : candidates)
|
|
128
|
+
);
|
|
128
129
|
}
|
|
129
130
|
function isFocusable(element, options = {}) {
|
|
130
131
|
if (!(element instanceof Element)) {
|
|
@@ -147,7 +148,7 @@ function isFocusable(element, options = {}) {
|
|
|
147
148
|
return false;
|
|
148
149
|
}
|
|
149
150
|
if (!element.matches(
|
|
150
|
-
skipNegativeTabIndexCheck ?
|
|
151
|
+
skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX : FOCUSABLE_SELECTOR
|
|
151
152
|
)) {
|
|
152
153
|
return false;
|
|
153
154
|
}
|
|
@@ -193,7 +194,7 @@ function isDisabledDeep(element) {
|
|
|
193
194
|
return false;
|
|
194
195
|
}
|
|
195
196
|
function normalizeRadioGroup(elements) {
|
|
196
|
-
let
|
|
197
|
+
let map = null;
|
|
197
198
|
for (let i = 0, l = elements.length; i < l; i++) {
|
|
198
199
|
const element = elements[i];
|
|
199
200
|
if (!(element instanceof HTMLInputElement)) {
|
|
@@ -202,35 +203,35 @@ function normalizeRadioGroup(elements) {
|
|
|
202
203
|
if (!isUngroupedRadio(element)) {
|
|
203
204
|
continue;
|
|
204
205
|
}
|
|
205
|
-
if (!
|
|
206
|
-
|
|
206
|
+
if (!map) {
|
|
207
|
+
map = /* @__PURE__ */ new Map();
|
|
207
208
|
}
|
|
208
209
|
const root = element.getRootNode();
|
|
209
|
-
let
|
|
210
|
-
if (!
|
|
211
|
-
|
|
212
|
-
|
|
210
|
+
let value = map.get(root);
|
|
211
|
+
if (!value) {
|
|
212
|
+
value = /* @__PURE__ */ new Map();
|
|
213
|
+
map.set(root, value);
|
|
213
214
|
}
|
|
214
|
-
let
|
|
215
|
-
if (!
|
|
216
|
-
|
|
217
|
-
|
|
215
|
+
let v = value.get(element.form);
|
|
216
|
+
if (!v) {
|
|
217
|
+
v = /* @__PURE__ */ new Map();
|
|
218
|
+
value.set(element.form, v);
|
|
218
219
|
}
|
|
219
|
-
let
|
|
220
|
-
if (!
|
|
221
|
-
|
|
222
|
-
|
|
220
|
+
let vv = v.get(element.name);
|
|
221
|
+
if (!vv) {
|
|
222
|
+
vv = [];
|
|
223
|
+
v.set(element.name, vv);
|
|
223
224
|
}
|
|
224
|
-
|
|
225
|
+
vv[vv.length] = element;
|
|
225
226
|
}
|
|
226
|
-
if (!
|
|
227
|
+
if (!map) {
|
|
227
228
|
return elements;
|
|
228
229
|
}
|
|
229
230
|
const placeholder = /* @__PURE__ */ new Set();
|
|
230
|
-
for (const
|
|
231
|
-
for (const
|
|
232
|
-
for (const
|
|
233
|
-
const radio =
|
|
231
|
+
for (const value of map.values()) {
|
|
232
|
+
for (const v of value.values()) {
|
|
233
|
+
for (const vv of v.values()) {
|
|
234
|
+
const radio = vv.find((element) => element.checked) ?? vv[0];
|
|
234
235
|
radio && placeholder.add(radio);
|
|
235
236
|
}
|
|
236
237
|
}
|
|
@@ -457,16 +458,16 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
457
458
|
if (!(active instanceof Element)) {
|
|
458
459
|
return;
|
|
459
460
|
}
|
|
460
|
-
const
|
|
461
|
+
const candidates = this.#getFocusables().filter(
|
|
461
462
|
(focusable2) => this.#focusables.has(focusable2)
|
|
462
463
|
);
|
|
463
|
-
if (!
|
|
464
|
+
if (!candidates.includes(active)) {
|
|
464
465
|
return;
|
|
465
466
|
}
|
|
466
467
|
event.preventDefault();
|
|
467
|
-
const
|
|
468
|
+
const activeIndex = candidates.indexOf(active);
|
|
468
469
|
let newIndex;
|
|
469
|
-
let target =
|
|
470
|
+
let target = candidates;
|
|
470
471
|
switch (key) {
|
|
471
472
|
case "End":
|
|
472
473
|
newIndex = -1;
|
|
@@ -476,25 +477,26 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
476
477
|
break;
|
|
477
478
|
case "ArrowLeft":
|
|
478
479
|
case "ArrowUp": {
|
|
479
|
-
const rawIndex =
|
|
480
|
+
const rawIndex = activeIndex - 1;
|
|
480
481
|
newIndex = wrap ? rawIndex : Math.max(rawIndex, 0);
|
|
481
482
|
break;
|
|
482
483
|
}
|
|
483
484
|
case "ArrowRight":
|
|
484
485
|
case "ArrowDown": {
|
|
485
|
-
const rawIndex =
|
|
486
|
-
|
|
486
|
+
const rawIndex = activeIndex + 1;
|
|
487
|
+
const length = target.length;
|
|
488
|
+
newIndex = wrap ? rawIndex % length : Math.min(rawIndex, length - 1);
|
|
487
489
|
break;
|
|
488
490
|
}
|
|
489
491
|
default: {
|
|
490
492
|
const focusables = new Set(
|
|
491
493
|
this.#focusablesByFirstChar.get(key.toUpperCase()) ?? []
|
|
492
494
|
);
|
|
493
|
-
target =
|
|
494
|
-
const
|
|
495
|
-
(focusable2) =>
|
|
495
|
+
target = candidates.filter((focusable2) => focusables.has(focusable2));
|
|
496
|
+
const afterIndex = target.findIndex(
|
|
497
|
+
(focusable2) => candidates.indexOf(focusable2) > activeIndex
|
|
496
498
|
);
|
|
497
|
-
newIndex =
|
|
499
|
+
newIndex = afterIndex >= 0 ? afterIndex : 0;
|
|
498
500
|
}
|
|
499
501
|
}
|
|
500
502
|
const focusable = target.at(newIndex);
|
|
@@ -581,7 +583,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
581
583
|
* Lightweight roving tabindex utility with fully focus management.
|
|
582
584
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
583
585
|
*
|
|
584
|
-
* @version 3.1.
|
|
586
|
+
* @version 3.1.15
|
|
585
587
|
* @author Yusuke Kamiyamane
|
|
586
588
|
* @license MIT
|
|
587
589
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -606,7 +608,7 @@ power-focusable/dist/index.js:
|
|
|
606
608
|
* High-precision focus management utility with full composed tree support.
|
|
607
609
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
608
610
|
*
|
|
609
|
-
* @version 4.3.
|
|
611
|
+
* @version 4.3.19
|
|
610
612
|
* @author Yusuke Kamiyamane
|
|
611
613
|
* @license MIT
|
|
612
614
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.cjs
CHANGED
|
@@ -145,16 +145,16 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
145
145
|
if (!(active instanceof Element)) {
|
|
146
146
|
return;
|
|
147
147
|
}
|
|
148
|
-
const
|
|
148
|
+
const candidates = this.#getFocusables().filter(
|
|
149
149
|
(focusable2) => this.#focusables.has(focusable2)
|
|
150
150
|
);
|
|
151
|
-
if (!
|
|
151
|
+
if (!candidates.includes(active)) {
|
|
152
152
|
return;
|
|
153
153
|
}
|
|
154
154
|
event.preventDefault();
|
|
155
|
-
const
|
|
155
|
+
const activeIndex = candidates.indexOf(active);
|
|
156
156
|
let newIndex;
|
|
157
|
-
let target =
|
|
157
|
+
let target = candidates;
|
|
158
158
|
switch (key) {
|
|
159
159
|
case "End":
|
|
160
160
|
newIndex = -1;
|
|
@@ -164,25 +164,26 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
164
164
|
break;
|
|
165
165
|
case "ArrowLeft":
|
|
166
166
|
case "ArrowUp": {
|
|
167
|
-
const rawIndex =
|
|
167
|
+
const rawIndex = activeIndex - 1;
|
|
168
168
|
newIndex = wrap ? rawIndex : Math.max(rawIndex, 0);
|
|
169
169
|
break;
|
|
170
170
|
}
|
|
171
171
|
case "ArrowRight":
|
|
172
172
|
case "ArrowDown": {
|
|
173
|
-
const rawIndex =
|
|
174
|
-
|
|
173
|
+
const rawIndex = activeIndex + 1;
|
|
174
|
+
const length = target.length;
|
|
175
|
+
newIndex = wrap ? rawIndex % length : Math.min(rawIndex, length - 1);
|
|
175
176
|
break;
|
|
176
177
|
}
|
|
177
178
|
default: {
|
|
178
179
|
const focusables = new Set(
|
|
179
180
|
this.#focusablesByFirstChar.get(key.toUpperCase()) ?? []
|
|
180
181
|
);
|
|
181
|
-
target =
|
|
182
|
-
const
|
|
183
|
-
(focusable2) =>
|
|
182
|
+
target = candidates.filter((focusable2) => focusables.has(focusable2));
|
|
183
|
+
const afterIndex = target.findIndex(
|
|
184
|
+
(focusable2) => candidates.indexOf(focusable2) > activeIndex
|
|
184
185
|
);
|
|
185
|
-
newIndex =
|
|
186
|
+
newIndex = afterIndex >= 0 ? afterIndex : 0;
|
|
186
187
|
}
|
|
187
188
|
}
|
|
188
189
|
const focusable = target.at(newIndex);
|
|
@@ -269,7 +270,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
269
270
|
* Lightweight roving tabindex utility with fully focus management.
|
|
270
271
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
271
272
|
*
|
|
272
|
-
* @version 3.1.
|
|
273
|
+
* @version 3.1.15
|
|
273
274
|
* @author Yusuke Kamiyamane
|
|
274
275
|
* @license MIT
|
|
275
276
|
* @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.
|
|
6
|
+
* @version 3.1.15
|
|
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.
|
|
6
|
+
* @version 3.1.15
|
|
7
7
|
* @author Yusuke Kamiyamane
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.js
CHANGED
|
@@ -143,16 +143,16 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
143
143
|
if (!(active instanceof Element)) {
|
|
144
144
|
return;
|
|
145
145
|
}
|
|
146
|
-
const
|
|
146
|
+
const candidates = this.#getFocusables().filter(
|
|
147
147
|
(focusable2) => this.#focusables.has(focusable2)
|
|
148
148
|
);
|
|
149
|
-
if (!
|
|
149
|
+
if (!candidates.includes(active)) {
|
|
150
150
|
return;
|
|
151
151
|
}
|
|
152
152
|
event.preventDefault();
|
|
153
|
-
const
|
|
153
|
+
const activeIndex = candidates.indexOf(active);
|
|
154
154
|
let newIndex;
|
|
155
|
-
let target =
|
|
155
|
+
let target = candidates;
|
|
156
156
|
switch (key) {
|
|
157
157
|
case "End":
|
|
158
158
|
newIndex = -1;
|
|
@@ -162,25 +162,26 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
162
162
|
break;
|
|
163
163
|
case "ArrowLeft":
|
|
164
164
|
case "ArrowUp": {
|
|
165
|
-
const rawIndex =
|
|
165
|
+
const rawIndex = activeIndex - 1;
|
|
166
166
|
newIndex = wrap ? rawIndex : Math.max(rawIndex, 0);
|
|
167
167
|
break;
|
|
168
168
|
}
|
|
169
169
|
case "ArrowRight":
|
|
170
170
|
case "ArrowDown": {
|
|
171
|
-
const rawIndex =
|
|
172
|
-
|
|
171
|
+
const rawIndex = activeIndex + 1;
|
|
172
|
+
const length = target.length;
|
|
173
|
+
newIndex = wrap ? rawIndex % length : Math.min(rawIndex, length - 1);
|
|
173
174
|
break;
|
|
174
175
|
}
|
|
175
176
|
default: {
|
|
176
177
|
const focusables = new Set(
|
|
177
178
|
this.#focusablesByFirstChar.get(key.toUpperCase()) ?? []
|
|
178
179
|
);
|
|
179
|
-
target =
|
|
180
|
-
const
|
|
181
|
-
(focusable2) =>
|
|
180
|
+
target = candidates.filter((focusable2) => focusables.has(focusable2));
|
|
181
|
+
const afterIndex = target.findIndex(
|
|
182
|
+
(focusable2) => candidates.indexOf(focusable2) > activeIndex
|
|
182
183
|
);
|
|
183
|
-
newIndex =
|
|
184
|
+
newIndex = afterIndex >= 0 ? afterIndex : 0;
|
|
184
185
|
}
|
|
185
186
|
}
|
|
186
187
|
const focusable = target.at(newIndex);
|
|
@@ -267,7 +268,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
267
268
|
* Lightweight roving tabindex utility with fully focus management.
|
|
268
269
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
269
270
|
*
|
|
270
|
-
* @version 3.1.
|
|
271
|
+
* @version 3.1.15
|
|
271
272
|
* @author Yusuke Kamiyamane
|
|
272
273
|
* @license MIT
|
|
273
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.
|
|
3
|
+
"version": "3.1.15",
|
|
4
4
|
"description": "Lightweight roving tabindex utility with fully focus management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -57,6 +57,6 @@
|
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@y14e/attributes-utils": "^1.1.3",
|
|
60
|
-
"power-focusable": "^4.3.
|
|
60
|
+
"power-focusable": "^4.3.19"
|
|
61
61
|
}
|
|
62
62
|
}
|