power-focusable 4.1.4 → 4.1.6
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 +15 -3
- package/dist/index.cjs +35 -23
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +35 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,11 +105,14 @@ getFocusables(container, { composed: true });
|
|
|
105
105
|
|
|
106
106
|
// Uses custom filter function
|
|
107
107
|
getFocusables(container, { filter: (element) => !element.matches('[data-skip-focus]') });
|
|
108
|
+
|
|
109
|
+
// Uses custom include function
|
|
110
|
+
getFocusables(container, { filter: (element) => element.matches('[data-roving-tabindex]') });
|
|
108
111
|
```
|
|
109
112
|
|
|
110
113
|
### `getNextFocusable`
|
|
111
114
|
|
|
112
|
-
Returns the next focusable element within the container, starting from
|
|
115
|
+
Returns the next focusable element within the container, starting from active element.
|
|
113
116
|
|
|
114
117
|
```ts
|
|
115
118
|
getNextFocusable(container);
|
|
@@ -126,13 +129,16 @@ getNextFocusable(container, { composed: true });
|
|
|
126
129
|
// Uses custom filter function
|
|
127
130
|
getNextFocusable(container, { filter: (element) => !element.matches('[data-skip-focus]') });
|
|
128
131
|
|
|
132
|
+
// Uses custom include function
|
|
133
|
+
getNextFocusable(container, { filter: (element) => element.matches('[data-roving-tabindex]') });
|
|
134
|
+
|
|
129
135
|
// Wraps around to the first element when reaching the end
|
|
130
136
|
getNextFocusable(container, { wrap: true });
|
|
131
137
|
```
|
|
132
138
|
|
|
133
139
|
### `getPreviousFocusable`
|
|
134
140
|
|
|
135
|
-
Returns the previous focusable element within the container, starting from
|
|
141
|
+
Returns the previous focusable element within the container, starting from active element.
|
|
136
142
|
|
|
137
143
|
```ts
|
|
138
144
|
getPreviousFocusable(container);
|
|
@@ -149,7 +155,10 @@ getPreviousFocusable(container, { composed: true });
|
|
|
149
155
|
// Uses custom filter function
|
|
150
156
|
getPreviousFocusable(container, { filter: (element) => !element.matches('[data-skip-focus]') });
|
|
151
157
|
|
|
152
|
-
//
|
|
158
|
+
// Uses custom include function
|
|
159
|
+
getPreviousFocusable(container, { filter: (element) => element.matches('[data-roving-tabindex]') });
|
|
160
|
+
|
|
161
|
+
// Wraps around to the last element when reaching the end
|
|
153
162
|
getPreviousFocusable(container, { wrap: true });
|
|
154
163
|
|
|
155
164
|
```
|
|
@@ -169,6 +178,9 @@ hasFocusable(container, { composed: true });
|
|
|
169
178
|
|
|
170
179
|
// Uses custom filter function
|
|
171
180
|
hasFocusable(container, { filter: (element) => !element.matches('[data-skip-focus]') });
|
|
181
|
+
|
|
182
|
+
// Uses custom include function
|
|
183
|
+
hasFocusable(container, { filter: (element) => element.matches('[data-roving-tabindex]') });
|
|
172
184
|
```
|
|
173
185
|
|
|
174
186
|
### `inertOutside`
|
package/dist/index.cjs
CHANGED
|
@@ -44,14 +44,17 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
44
44
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
45
45
|
container = document.body;
|
|
46
46
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
let { composed = false, filter, include } = options;
|
|
48
|
+
if (typeof composed !== "boolean") {
|
|
49
|
+
console.warn("Invalid composed. Fallback: false.");
|
|
50
|
+
composed = false;
|
|
51
|
+
}
|
|
52
|
+
if (typeof filter !== "undefined" && typeof filter !== "function") {
|
|
53
|
+
console.warn("Invalid filter. Fallback: no filter function (undefined).");
|
|
51
54
|
filter = void 0;
|
|
52
55
|
}
|
|
53
|
-
if (include && typeof include !== "function") {
|
|
54
|
-
console.warn("Invalid include function");
|
|
56
|
+
if (typeof include !== "undefined" && typeof include !== "function") {
|
|
57
|
+
console.warn("Invalid include. Fallback: no include function (undefined).");
|
|
55
58
|
include = void 0;
|
|
56
59
|
}
|
|
57
60
|
const elements = [];
|
|
@@ -88,24 +91,12 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
88
91
|
return filter ? unfiltered.filter(filter) : unfiltered;
|
|
89
92
|
}
|
|
90
93
|
function getNextFocusable(container = document.body, options = {}) {
|
|
91
|
-
if (!(container instanceof Element)) {
|
|
92
|
-
console.warn("Invalid container element. Fallback: <body> element.");
|
|
93
|
-
container = document.body;
|
|
94
|
-
}
|
|
95
94
|
return getRelativeFocusable(container, 1, options);
|
|
96
95
|
}
|
|
97
96
|
function getPreviousFocusable(container = document.body, options = {}) {
|
|
98
|
-
if (!(container instanceof Element)) {
|
|
99
|
-
console.warn("Invalid container element. Fallback: <body> element.");
|
|
100
|
-
container = document.body;
|
|
101
|
-
}
|
|
102
97
|
return getRelativeFocusable(container, -1, options);
|
|
103
98
|
}
|
|
104
99
|
function hasFocusable(container = document.body, options = {}) {
|
|
105
|
-
if (!(container instanceof Element)) {
|
|
106
|
-
console.warn("Invalid container element. Fallback: <body> element.");
|
|
107
|
-
container = document.body;
|
|
108
|
-
}
|
|
109
100
|
return !!getFocusables(container, options).length;
|
|
110
101
|
}
|
|
111
102
|
function inertOutside(element) {
|
|
@@ -164,8 +155,13 @@ function isFocusable(element) {
|
|
|
164
155
|
return true;
|
|
165
156
|
}
|
|
166
157
|
function getRelativeFocusable(container, offset, options) {
|
|
167
|
-
let
|
|
168
|
-
|
|
158
|
+
let {
|
|
159
|
+
anchor = getActiveElement(),
|
|
160
|
+
composed = false,
|
|
161
|
+
filter,
|
|
162
|
+
include,
|
|
163
|
+
wrap = false
|
|
164
|
+
} = options;
|
|
169
165
|
if (!(anchor instanceof Element)) {
|
|
170
166
|
const active = getActiveElement();
|
|
171
167
|
if (active instanceof Element) {
|
|
@@ -180,6 +176,22 @@ function getRelativeFocusable(container, offset, options) {
|
|
|
180
176
|
console.warn("Anchor (active) element not within container");
|
|
181
177
|
return null;
|
|
182
178
|
}
|
|
179
|
+
if (typeof composed !== "boolean") {
|
|
180
|
+
console.warn("Invalid composed. Fallback: false.");
|
|
181
|
+
composed = false;
|
|
182
|
+
}
|
|
183
|
+
if (typeof filter !== "undefined" && typeof filter !== "function") {
|
|
184
|
+
console.warn("Invalid filter. Fallback: no filter function (undefined).");
|
|
185
|
+
filter = void 0;
|
|
186
|
+
}
|
|
187
|
+
if (typeof include !== "undefined" && typeof include !== "function") {
|
|
188
|
+
console.warn("Invalid include. Fallback: no include function (undefined).");
|
|
189
|
+
include = void 0;
|
|
190
|
+
}
|
|
191
|
+
if (typeof wrap !== "boolean") {
|
|
192
|
+
console.warn("Invalid wrap. Fallback: false.");
|
|
193
|
+
wrap = false;
|
|
194
|
+
}
|
|
183
195
|
const focusables = getFocusables(container, { composed, filter, include });
|
|
184
196
|
const { length } = focusables;
|
|
185
197
|
if (!length) {
|
|
@@ -345,7 +357,7 @@ function applyInert(element) {
|
|
|
345
357
|
}
|
|
346
358
|
const count = inertRefCounts.get(element) ?? 0;
|
|
347
359
|
inertRefCounts.set(element, count + 1);
|
|
348
|
-
count === 0 && element.
|
|
360
|
+
count === 0 && element.setAttribute("inert", "");
|
|
349
361
|
return true;
|
|
350
362
|
}
|
|
351
363
|
function restoreInert(element) {
|
|
@@ -355,7 +367,7 @@ function restoreInert(element) {
|
|
|
355
367
|
}
|
|
356
368
|
if (count === 1) {
|
|
357
369
|
inertRefCounts.delete(element);
|
|
358
|
-
element.
|
|
370
|
+
element.removeAttribute("inert");
|
|
359
371
|
return;
|
|
360
372
|
}
|
|
361
373
|
inertRefCounts.set(element, count - 1);
|
|
@@ -411,7 +423,7 @@ function isUngroupedRadio(element) {
|
|
|
411
423
|
* High-precision focus management utility with full composed tree support.
|
|
412
424
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
413
425
|
*
|
|
414
|
-
* @version 4.1.
|
|
426
|
+
* @version 4.1.6
|
|
415
427
|
* @author Yusuke Kamiyamane
|
|
416
428
|
* @license MIT
|
|
417
429
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.d.cts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* High-precision focus management utility with full composed tree support.
|
|
4
4
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
5
5
|
*
|
|
6
|
-
* @version 4.1.
|
|
6
|
+
* @version 4.1.6
|
|
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
|
* High-precision focus management utility with full composed tree support.
|
|
4
4
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
5
5
|
*
|
|
6
|
-
* @version 4.1.
|
|
6
|
+
* @version 4.1.6
|
|
7
7
|
* @author Yusuke Kamiyamane
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.js
CHANGED
|
@@ -42,14 +42,17 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
42
42
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
43
43
|
container = document.body;
|
|
44
44
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
let { composed = false, filter, include } = options;
|
|
46
|
+
if (typeof composed !== "boolean") {
|
|
47
|
+
console.warn("Invalid composed. Fallback: false.");
|
|
48
|
+
composed = false;
|
|
49
|
+
}
|
|
50
|
+
if (typeof filter !== "undefined" && typeof filter !== "function") {
|
|
51
|
+
console.warn("Invalid filter. Fallback: no filter function (undefined).");
|
|
49
52
|
filter = void 0;
|
|
50
53
|
}
|
|
51
|
-
if (include && typeof include !== "function") {
|
|
52
|
-
console.warn("Invalid include function");
|
|
54
|
+
if (typeof include !== "undefined" && typeof include !== "function") {
|
|
55
|
+
console.warn("Invalid include. Fallback: no include function (undefined).");
|
|
53
56
|
include = void 0;
|
|
54
57
|
}
|
|
55
58
|
const elements = [];
|
|
@@ -86,24 +89,12 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
86
89
|
return filter ? unfiltered.filter(filter) : unfiltered;
|
|
87
90
|
}
|
|
88
91
|
function getNextFocusable(container = document.body, options = {}) {
|
|
89
|
-
if (!(container instanceof Element)) {
|
|
90
|
-
console.warn("Invalid container element. Fallback: <body> element.");
|
|
91
|
-
container = document.body;
|
|
92
|
-
}
|
|
93
92
|
return getRelativeFocusable(container, 1, options);
|
|
94
93
|
}
|
|
95
94
|
function getPreviousFocusable(container = document.body, options = {}) {
|
|
96
|
-
if (!(container instanceof Element)) {
|
|
97
|
-
console.warn("Invalid container element. Fallback: <body> element.");
|
|
98
|
-
container = document.body;
|
|
99
|
-
}
|
|
100
95
|
return getRelativeFocusable(container, -1, options);
|
|
101
96
|
}
|
|
102
97
|
function hasFocusable(container = document.body, options = {}) {
|
|
103
|
-
if (!(container instanceof Element)) {
|
|
104
|
-
console.warn("Invalid container element. Fallback: <body> element.");
|
|
105
|
-
container = document.body;
|
|
106
|
-
}
|
|
107
98
|
return !!getFocusables(container, options).length;
|
|
108
99
|
}
|
|
109
100
|
function inertOutside(element) {
|
|
@@ -162,8 +153,13 @@ function isFocusable(element) {
|
|
|
162
153
|
return true;
|
|
163
154
|
}
|
|
164
155
|
function getRelativeFocusable(container, offset, options) {
|
|
165
|
-
let
|
|
166
|
-
|
|
156
|
+
let {
|
|
157
|
+
anchor = getActiveElement(),
|
|
158
|
+
composed = false,
|
|
159
|
+
filter,
|
|
160
|
+
include,
|
|
161
|
+
wrap = false
|
|
162
|
+
} = options;
|
|
167
163
|
if (!(anchor instanceof Element)) {
|
|
168
164
|
const active = getActiveElement();
|
|
169
165
|
if (active instanceof Element) {
|
|
@@ -178,6 +174,22 @@ function getRelativeFocusable(container, offset, options) {
|
|
|
178
174
|
console.warn("Anchor (active) element not within container");
|
|
179
175
|
return null;
|
|
180
176
|
}
|
|
177
|
+
if (typeof composed !== "boolean") {
|
|
178
|
+
console.warn("Invalid composed. Fallback: false.");
|
|
179
|
+
composed = false;
|
|
180
|
+
}
|
|
181
|
+
if (typeof filter !== "undefined" && typeof filter !== "function") {
|
|
182
|
+
console.warn("Invalid filter. Fallback: no filter function (undefined).");
|
|
183
|
+
filter = void 0;
|
|
184
|
+
}
|
|
185
|
+
if (typeof include !== "undefined" && typeof include !== "function") {
|
|
186
|
+
console.warn("Invalid include. Fallback: no include function (undefined).");
|
|
187
|
+
include = void 0;
|
|
188
|
+
}
|
|
189
|
+
if (typeof wrap !== "boolean") {
|
|
190
|
+
console.warn("Invalid wrap. Fallback: false.");
|
|
191
|
+
wrap = false;
|
|
192
|
+
}
|
|
181
193
|
const focusables = getFocusables(container, { composed, filter, include });
|
|
182
194
|
const { length } = focusables;
|
|
183
195
|
if (!length) {
|
|
@@ -343,7 +355,7 @@ function applyInert(element) {
|
|
|
343
355
|
}
|
|
344
356
|
const count = inertRefCounts.get(element) ?? 0;
|
|
345
357
|
inertRefCounts.set(element, count + 1);
|
|
346
|
-
count === 0 && element.
|
|
358
|
+
count === 0 && element.setAttribute("inert", "");
|
|
347
359
|
return true;
|
|
348
360
|
}
|
|
349
361
|
function restoreInert(element) {
|
|
@@ -353,7 +365,7 @@ function restoreInert(element) {
|
|
|
353
365
|
}
|
|
354
366
|
if (count === 1) {
|
|
355
367
|
inertRefCounts.delete(element);
|
|
356
|
-
element.
|
|
368
|
+
element.removeAttribute("inert");
|
|
357
369
|
return;
|
|
358
370
|
}
|
|
359
371
|
inertRefCounts.set(element, count - 1);
|
|
@@ -409,7 +421,7 @@ function isUngroupedRadio(element) {
|
|
|
409
421
|
* High-precision focus management utility with full composed tree support.
|
|
410
422
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
411
423
|
*
|
|
412
|
-
* @version 4.1.
|
|
424
|
+
* @version 4.1.6
|
|
413
425
|
* @author Yusuke Kamiyamane
|
|
414
426
|
* @license MIT
|
|
415
427
|
* @copyright Copyright (c) Yusuke Kamiyamane
|