power-focusable 4.1.2 → 4.1.4
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 +5 -5
- package/dist/index.cjs +23 -20
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +23 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,11 +35,11 @@ import { ... } 'https://unpkg.com/power-focusable/dist/index.js';
|
|
|
35
35
|
|
|
36
36
|
```ts
|
|
37
37
|
interface PowerFocusableOptions {
|
|
38
|
-
anchor?: Element | null;
|
|
39
|
-
composed?: boolean;
|
|
40
|
-
filter?: (
|
|
41
|
-
include?: (
|
|
42
|
-
wrap?: boolean;
|
|
38
|
+
anchor?: Element | null; // default: active element
|
|
39
|
+
composed?: boolean; // default: false
|
|
40
|
+
filter?: (element: Element) => boolean;
|
|
41
|
+
include?: (element: Element) => boolean;
|
|
42
|
+
wrap?: boolean; // default: false
|
|
43
43
|
}
|
|
44
44
|
```
|
|
45
45
|
|
package/dist/index.cjs
CHANGED
|
@@ -6,10 +6,10 @@ function createFocusTrap(container = document.body) {
|
|
|
6
6
|
if (!(container instanceof Element)) {
|
|
7
7
|
throw new Error("Invalid container element");
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
focusElement(container);
|
|
10
10
|
if (getActiveElement() !== container) {
|
|
11
11
|
const first = getFocusables(container, { composed: true })[0];
|
|
12
|
-
first &&
|
|
12
|
+
first && focusElement(first);
|
|
13
13
|
}
|
|
14
14
|
function onKeyDown(event) {
|
|
15
15
|
const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
|
|
@@ -27,7 +27,7 @@ function createFocusTrap(container = document.body) {
|
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
event.preventDefault();
|
|
30
|
-
|
|
30
|
+
focusElement(focusable);
|
|
31
31
|
}
|
|
32
32
|
let controller = new AbortController();
|
|
33
33
|
document.addEventListener("keydown", onKeyDown, {
|
|
@@ -47,11 +47,11 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
47
47
|
const { composed = false } = options;
|
|
48
48
|
let { filter, include } = options;
|
|
49
49
|
if (filter && typeof filter !== "function") {
|
|
50
|
-
console.warn("Invalid filter function
|
|
50
|
+
console.warn("Invalid filter function");
|
|
51
51
|
filter = void 0;
|
|
52
52
|
}
|
|
53
53
|
if (include && typeof include !== "function") {
|
|
54
|
-
console.warn("Invalid include function
|
|
54
|
+
console.warn("Invalid include function");
|
|
55
55
|
include = void 0;
|
|
56
56
|
}
|
|
57
57
|
const elements = [];
|
|
@@ -164,22 +164,25 @@ function isFocusable(element) {
|
|
|
164
164
|
return true;
|
|
165
165
|
}
|
|
166
166
|
function getRelativeFocusable(container, offset, options) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
|
+
}
|
|
178
178
|
}
|
|
179
|
-
if (!
|
|
179
|
+
if (!containsComposed(container, anchor)) {
|
|
180
|
+
console.warn("Anchor (active) element not within container");
|
|
180
181
|
return null;
|
|
181
182
|
}
|
|
182
|
-
|
|
183
|
+
const focusables = getFocusables(container, { composed, filter, include });
|
|
184
|
+
const { length } = focusables;
|
|
185
|
+
if (!length) {
|
|
183
186
|
return null;
|
|
184
187
|
}
|
|
185
188
|
const currentIndex = focusables.indexOf(anchor);
|
|
@@ -357,7 +360,7 @@ function restoreInert(element) {
|
|
|
357
360
|
}
|
|
358
361
|
inertRefCounts.set(element, count - 1);
|
|
359
362
|
}
|
|
360
|
-
function
|
|
363
|
+
function focusElement(element) {
|
|
361
364
|
"focus" in element && typeof element.focus === "function" && element.focus();
|
|
362
365
|
}
|
|
363
366
|
function getActiveElement() {
|
|
@@ -408,7 +411,7 @@ function isUngroupedRadio(element) {
|
|
|
408
411
|
* High-precision focus management utility with full composed tree support.
|
|
409
412
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
410
413
|
*
|
|
411
|
-
* @version 4.1.
|
|
414
|
+
* @version 4.1.4
|
|
412
415
|
* @author Yusuke Kamiyamane
|
|
413
416
|
* @license MIT
|
|
414
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.4
|
|
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.4
|
|
7
7
|
* @author Yusuke Kamiyamane
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.js
CHANGED
|
@@ -4,10 +4,10 @@ function createFocusTrap(container = document.body) {
|
|
|
4
4
|
if (!(container instanceof Element)) {
|
|
5
5
|
throw new Error("Invalid container element");
|
|
6
6
|
}
|
|
7
|
-
|
|
7
|
+
focusElement(container);
|
|
8
8
|
if (getActiveElement() !== container) {
|
|
9
9
|
const first = getFocusables(container, { composed: true })[0];
|
|
10
|
-
first &&
|
|
10
|
+
first && focusElement(first);
|
|
11
11
|
}
|
|
12
12
|
function onKeyDown(event) {
|
|
13
13
|
const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
|
|
@@ -25,7 +25,7 @@ function createFocusTrap(container = document.body) {
|
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
event.preventDefault();
|
|
28
|
-
|
|
28
|
+
focusElement(focusable);
|
|
29
29
|
}
|
|
30
30
|
let controller = new AbortController();
|
|
31
31
|
document.addEventListener("keydown", onKeyDown, {
|
|
@@ -45,11 +45,11 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
45
45
|
const { composed = false } = options;
|
|
46
46
|
let { filter, include } = options;
|
|
47
47
|
if (filter && typeof filter !== "function") {
|
|
48
|
-
console.warn("Invalid filter function
|
|
48
|
+
console.warn("Invalid filter function");
|
|
49
49
|
filter = void 0;
|
|
50
50
|
}
|
|
51
51
|
if (include && typeof include !== "function") {
|
|
52
|
-
console.warn("Invalid include function
|
|
52
|
+
console.warn("Invalid include function");
|
|
53
53
|
include = void 0;
|
|
54
54
|
}
|
|
55
55
|
const elements = [];
|
|
@@ -162,22 +162,25 @@ function isFocusable(element) {
|
|
|
162
162
|
return true;
|
|
163
163
|
}
|
|
164
164
|
function getRelativeFocusable(container, offset, options) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
+
}
|
|
176
176
|
}
|
|
177
|
-
if (!
|
|
177
|
+
if (!containsComposed(container, anchor)) {
|
|
178
|
+
console.warn("Anchor (active) element not within container");
|
|
178
179
|
return null;
|
|
179
180
|
}
|
|
180
|
-
|
|
181
|
+
const focusables = getFocusables(container, { composed, filter, include });
|
|
182
|
+
const { length } = focusables;
|
|
183
|
+
if (!length) {
|
|
181
184
|
return null;
|
|
182
185
|
}
|
|
183
186
|
const currentIndex = focusables.indexOf(anchor);
|
|
@@ -355,7 +358,7 @@ function restoreInert(element) {
|
|
|
355
358
|
}
|
|
356
359
|
inertRefCounts.set(element, count - 1);
|
|
357
360
|
}
|
|
358
|
-
function
|
|
361
|
+
function focusElement(element) {
|
|
359
362
|
"focus" in element && typeof element.focus === "function" && element.focus();
|
|
360
363
|
}
|
|
361
364
|
function getActiveElement() {
|
|
@@ -406,7 +409,7 @@ function isUngroupedRadio(element) {
|
|
|
406
409
|
* High-precision focus management utility with full composed tree support.
|
|
407
410
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
408
411
|
*
|
|
409
|
-
* @version 4.1.
|
|
412
|
+
* @version 4.1.4
|
|
410
413
|
* @author Yusuke Kamiyamane
|
|
411
414
|
* @license MIT
|
|
412
415
|
* @copyright Copyright (c) Yusuke Kamiyamane
|