power-focusable 4.1.1 → 4.1.3
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.cjs +30 -17
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +30 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,10 +35,10 @@ import { ... } 'https://unpkg.com/power-focusable/dist/index.js';
|
|
|
35
35
|
|
|
36
36
|
```ts
|
|
37
37
|
interface PowerFocusableOptions {
|
|
38
|
-
anchor?: Element | null; // default:
|
|
38
|
+
anchor?: Element | null; // default: active element
|
|
39
39
|
composed?: boolean; // default: false
|
|
40
|
-
filter?: (element: Element) => boolean;
|
|
41
|
-
include?: (element: Element) => boolean;
|
|
40
|
+
filter?: (element: Element) => boolean;
|
|
41
|
+
include?: (element: Element) => boolean;
|
|
42
42
|
wrap?: boolean; // default: false
|
|
43
43
|
}
|
|
44
44
|
```
|
package/dist/index.cjs
CHANGED
|
@@ -44,9 +44,18 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
44
44
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
45
45
|
container = document.body;
|
|
46
46
|
}
|
|
47
|
-
const { composed = false
|
|
47
|
+
const { composed = false } = options;
|
|
48
|
+
let { filter, include } = options;
|
|
49
|
+
if (filter && typeof filter !== "function") {
|
|
50
|
+
console.warn("Invalid filter function. Fallback: undefined.");
|
|
51
|
+
filter = void 0;
|
|
52
|
+
}
|
|
53
|
+
if (include && typeof include !== "function") {
|
|
54
|
+
console.warn("Invalid include function. Fallback: undefined.");
|
|
55
|
+
include = void 0;
|
|
56
|
+
}
|
|
48
57
|
const elements = [];
|
|
49
|
-
if (composed ||
|
|
58
|
+
if (composed || include) {
|
|
50
59
|
let traverse2 = function(node) {
|
|
51
60
|
if (node instanceof Element) {
|
|
52
61
|
if (isFocusable(node) || include?.(node)) {
|
|
@@ -75,7 +84,8 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
75
84
|
}
|
|
76
85
|
}
|
|
77
86
|
}
|
|
78
|
-
|
|
87
|
+
const unfiltered = normalizeRadioGroup(sortByTabIndex(elements));
|
|
88
|
+
return filter ? unfiltered.filter(filter) : unfiltered;
|
|
79
89
|
}
|
|
80
90
|
function getNextFocusable(container = document.body, options = {}) {
|
|
81
91
|
if (!(container instanceof Element)) {
|
|
@@ -154,22 +164,25 @@ function isFocusable(element) {
|
|
|
154
164
|
return true;
|
|
155
165
|
}
|
|
156
166
|
function getRelativeFocusable(container, offset, options) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
167
|
+
let anchor = options.anchor ?? getActiveElement();
|
|
168
|
+
const { composed = false, filter, include, wrap = false } = options;
|
|
169
|
+
if (!(anchor instanceof Element)) {
|
|
170
|
+
const active = getActiveElement();
|
|
171
|
+
if (active instanceof Element) {
|
|
172
|
+
console.warn("Invalid anchor element. Fallback: active element.");
|
|
173
|
+
anchor = active;
|
|
174
|
+
} else {
|
|
175
|
+
console.warn("Invalid anchor element");
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
168
178
|
}
|
|
169
|
-
if (!
|
|
179
|
+
if (!containsComposed(container, anchor)) {
|
|
180
|
+
console.warn("Mismatch elements");
|
|
170
181
|
return null;
|
|
171
182
|
}
|
|
172
|
-
|
|
183
|
+
const focusables = getFocusables(container, { composed, filter, include });
|
|
184
|
+
const { length } = focusables;
|
|
185
|
+
if (!length) {
|
|
173
186
|
return null;
|
|
174
187
|
}
|
|
175
188
|
const currentIndex = focusables.indexOf(anchor);
|
|
@@ -398,7 +411,7 @@ function isUngroupedRadio(element) {
|
|
|
398
411
|
* High-precision focus management utility with full composed tree support.
|
|
399
412
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
400
413
|
*
|
|
401
|
-
* @version 4.1.
|
|
414
|
+
* @version 4.1.3
|
|
402
415
|
* @author Yusuke Kamiyamane
|
|
403
416
|
* @license MIT
|
|
404
417
|
* @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.3
|
|
7
7
|
* @author Yusuke Kamiyamane
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
interface PowerFocusableOptions {
|
|
13
13
|
readonly anchor?: Element | null;
|
|
14
14
|
readonly composed?: boolean;
|
|
15
|
-
readonly filter?: (element: Element) => boolean;
|
|
15
|
+
readonly filter?: ((element: Element) => boolean) | undefined;
|
|
16
16
|
readonly include?: ((element: Element) => boolean) | undefined;
|
|
17
17
|
readonly wrap?: boolean;
|
|
18
18
|
}
|
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.3
|
|
7
7
|
* @author Yusuke Kamiyamane
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
interface PowerFocusableOptions {
|
|
13
13
|
readonly anchor?: Element | null;
|
|
14
14
|
readonly composed?: boolean;
|
|
15
|
-
readonly filter?: (element: Element) => boolean;
|
|
15
|
+
readonly filter?: ((element: Element) => boolean) | undefined;
|
|
16
16
|
readonly include?: ((element: Element) => boolean) | undefined;
|
|
17
17
|
readonly wrap?: boolean;
|
|
18
18
|
}
|
package/dist/index.js
CHANGED
|
@@ -42,9 +42,18 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
42
42
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
43
43
|
container = document.body;
|
|
44
44
|
}
|
|
45
|
-
const { composed = false
|
|
45
|
+
const { composed = false } = options;
|
|
46
|
+
let { filter, include } = options;
|
|
47
|
+
if (filter && typeof filter !== "function") {
|
|
48
|
+
console.warn("Invalid filter function. Fallback: undefined.");
|
|
49
|
+
filter = void 0;
|
|
50
|
+
}
|
|
51
|
+
if (include && typeof include !== "function") {
|
|
52
|
+
console.warn("Invalid include function. Fallback: undefined.");
|
|
53
|
+
include = void 0;
|
|
54
|
+
}
|
|
46
55
|
const elements = [];
|
|
47
|
-
if (composed ||
|
|
56
|
+
if (composed || include) {
|
|
48
57
|
let traverse2 = function(node) {
|
|
49
58
|
if (node instanceof Element) {
|
|
50
59
|
if (isFocusable(node) || include?.(node)) {
|
|
@@ -73,7 +82,8 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
73
82
|
}
|
|
74
83
|
}
|
|
75
84
|
}
|
|
76
|
-
|
|
85
|
+
const unfiltered = normalizeRadioGroup(sortByTabIndex(elements));
|
|
86
|
+
return filter ? unfiltered.filter(filter) : unfiltered;
|
|
77
87
|
}
|
|
78
88
|
function getNextFocusable(container = document.body, options = {}) {
|
|
79
89
|
if (!(container instanceof Element)) {
|
|
@@ -152,22 +162,25 @@ function isFocusable(element) {
|
|
|
152
162
|
return true;
|
|
153
163
|
}
|
|
154
164
|
function getRelativeFocusable(container, offset, options) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
165
|
+
let anchor = options.anchor ?? getActiveElement();
|
|
166
|
+
const { composed = false, filter, include, wrap = false } = options;
|
|
167
|
+
if (!(anchor instanceof Element)) {
|
|
168
|
+
const active = getActiveElement();
|
|
169
|
+
if (active instanceof Element) {
|
|
170
|
+
console.warn("Invalid anchor element. Fallback: active element.");
|
|
171
|
+
anchor = active;
|
|
172
|
+
} else {
|
|
173
|
+
console.warn("Invalid anchor element");
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
166
176
|
}
|
|
167
|
-
if (!
|
|
177
|
+
if (!containsComposed(container, anchor)) {
|
|
178
|
+
console.warn("Mismatch elements");
|
|
168
179
|
return null;
|
|
169
180
|
}
|
|
170
|
-
|
|
181
|
+
const focusables = getFocusables(container, { composed, filter, include });
|
|
182
|
+
const { length } = focusables;
|
|
183
|
+
if (!length) {
|
|
171
184
|
return null;
|
|
172
185
|
}
|
|
173
186
|
const currentIndex = focusables.indexOf(anchor);
|
|
@@ -396,7 +409,7 @@ function isUngroupedRadio(element) {
|
|
|
396
409
|
* High-precision focus management utility with full composed tree support.
|
|
397
410
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
398
411
|
*
|
|
399
|
-
* @version 4.1.
|
|
412
|
+
* @version 4.1.3
|
|
400
413
|
* @author Yusuke Kamiyamane
|
|
401
414
|
* @license MIT
|
|
402
415
|
* @copyright Copyright (c) Yusuke Kamiyamane
|