power-focusable 2.0.1 → 2.0.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 +6 -6
- package/dist/index.cjs +6 -6
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ Returns all focusable elements within the container.
|
|
|
67
67
|
getFocusables(container);
|
|
68
68
|
// => HTMLElement[]
|
|
69
69
|
//
|
|
70
|
-
// container (optional): HTMLElement (default:
|
|
70
|
+
// container (optional): HTMLElement (default: <body>)
|
|
71
71
|
|
|
72
72
|
// Traverses the composed tree (including shadow DOM; slower)
|
|
73
73
|
getFocusables(container, { composed: true });
|
|
@@ -81,7 +81,7 @@ Returns the next focusable element within the container, starting from `document
|
|
|
81
81
|
getNextFocusable(container);
|
|
82
82
|
// => HTMLElement | null
|
|
83
83
|
//
|
|
84
|
-
// container (optional): HTMLElement (default:
|
|
84
|
+
// container (optional): HTMLElement (default: <body>)
|
|
85
85
|
|
|
86
86
|
// Specifies the starting element
|
|
87
87
|
getNextFocusable(container, { active: document.querySelector('.button') });
|
|
@@ -89,7 +89,7 @@ getNextFocusable(container, { active: document.querySelector('.button') });
|
|
|
89
89
|
// Traverses the composed tree (including shadow DOM; slower)
|
|
90
90
|
getNextFocusable(container, { composed: true });
|
|
91
91
|
|
|
92
|
-
// Wraps around to the first element when reaching the end
|
|
92
|
+
// Wraps around to the first element when reaching the end
|
|
93
93
|
getNextFocusable(container, { wrap: true });
|
|
94
94
|
```
|
|
95
95
|
|
|
@@ -101,7 +101,7 @@ Returns the previous focusable element within the container, starting from `docu
|
|
|
101
101
|
getPreviousFocusable(container);
|
|
102
102
|
// => HTMLElement | null
|
|
103
103
|
//
|
|
104
|
-
// container (optional): HTMLElement (default:
|
|
104
|
+
// container (optional): HTMLElement (default: <body>)
|
|
105
105
|
|
|
106
106
|
// Specifies the starting element
|
|
107
107
|
getPreviousFocusable(container, { active: document.querySelector('.button') });
|
|
@@ -109,7 +109,7 @@ getPreviousFocusable(container, { active: document.querySelector('.button') });
|
|
|
109
109
|
// Traverses the composed tree (including shadow DOM; slower)
|
|
110
110
|
getPreviousFocusable(container, { composed: true });
|
|
111
111
|
|
|
112
|
-
//Wraps around to the last element when reaching the end
|
|
112
|
+
//Wraps around to the last element when reaching the end
|
|
113
113
|
getPreviousFocusable(container, { wrap: true });
|
|
114
114
|
|
|
115
115
|
```
|
|
@@ -122,7 +122,7 @@ Returns whether the container contains at least one focusable element.
|
|
|
122
122
|
hasFocusable(container);
|
|
123
123
|
// => boolean
|
|
124
124
|
//
|
|
125
|
-
// container (optional): HTMLElement (default:
|
|
125
|
+
// container (optional): HTMLElement (default: <body>)
|
|
126
126
|
```
|
|
127
127
|
|
|
128
128
|
### `isFocusable`
|
package/dist/index.cjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
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"])`;
|
|
5
|
+
var tabIndexCache = /* @__PURE__ */ new WeakMap();
|
|
5
6
|
function getFocusables(container = document.body, options = {}) {
|
|
6
7
|
if (!(container instanceof HTMLElement)) {
|
|
7
8
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
@@ -40,17 +41,16 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
40
41
|
].filter(isFocusable)
|
|
41
42
|
);
|
|
42
43
|
}
|
|
43
|
-
const cache = /* @__PURE__ */ new WeakMap();
|
|
44
44
|
function sort(elements2) {
|
|
45
45
|
const ordered = [];
|
|
46
46
|
const natural = [];
|
|
47
47
|
function getTabIndex(element) {
|
|
48
|
-
const cached =
|
|
48
|
+
const cached = tabIndexCache.get(element);
|
|
49
49
|
if (cached !== void 0) {
|
|
50
50
|
return cached;
|
|
51
51
|
}
|
|
52
52
|
const number = Number(element.getAttribute("tabindex"));
|
|
53
|
-
|
|
53
|
+
tabIndexCache.set(element, number);
|
|
54
54
|
return number;
|
|
55
55
|
}
|
|
56
56
|
elements2.forEach((element) => {
|
|
@@ -59,7 +59,7 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
59
59
|
ordered.sort((a, b) => getTabIndex(a) - getTabIndex(b));
|
|
60
60
|
return [...ordered, ...natural];
|
|
61
61
|
}
|
|
62
|
-
function
|
|
62
|
+
function normalize(elements2) {
|
|
63
63
|
let map = null;
|
|
64
64
|
for (const element of elements2) {
|
|
65
65
|
if (element instanceof HTMLInputElement && element.type === "radio" && element.name) {
|
|
@@ -91,7 +91,7 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
91
91
|
return true;
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
|
-
return
|
|
94
|
+
return normalize(sort(elements));
|
|
95
95
|
}
|
|
96
96
|
function getNextFocusable(container = document.body, options = {}) {
|
|
97
97
|
if (!(container instanceof HTMLElement)) {
|
|
@@ -192,7 +192,7 @@ function getRelativeFocusable(container, offset = 0, options) {
|
|
|
192
192
|
* High-precision focus management utility with shadow DOM support.
|
|
193
193
|
* Handles complex focus rules including tabindex ordering, radio groups, etc.
|
|
194
194
|
*
|
|
195
|
-
* @version 2.0.
|
|
195
|
+
* @version 2.0.3
|
|
196
196
|
* @author Yusuke Kamiyamane
|
|
197
197
|
* @license MIT
|
|
198
198
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.d.cts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* High-precision focus management utility with shadow DOM support.
|
|
4
4
|
* Handles complex focus rules including tabindex ordering, radio groups, etc.
|
|
5
5
|
*
|
|
6
|
-
* @version 2.0.
|
|
6
|
+
* @version 2.0.3
|
|
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 shadow DOM support.
|
|
4
4
|
* Handles complex focus rules including tabindex ordering, radio groups, etc.
|
|
5
5
|
*
|
|
6
|
-
* @version 2.0.
|
|
6
|
+
* @version 2.0.3
|
|
7
7
|
* @author Yusuke Kamiyamane
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
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"])`;
|
|
3
|
+
var tabIndexCache = /* @__PURE__ */ new WeakMap();
|
|
3
4
|
function getFocusables(container = document.body, options = {}) {
|
|
4
5
|
if (!(container instanceof HTMLElement)) {
|
|
5
6
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
@@ -38,17 +39,16 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
38
39
|
].filter(isFocusable)
|
|
39
40
|
);
|
|
40
41
|
}
|
|
41
|
-
const cache = /* @__PURE__ */ new WeakMap();
|
|
42
42
|
function sort(elements2) {
|
|
43
43
|
const ordered = [];
|
|
44
44
|
const natural = [];
|
|
45
45
|
function getTabIndex(element) {
|
|
46
|
-
const cached =
|
|
46
|
+
const cached = tabIndexCache.get(element);
|
|
47
47
|
if (cached !== void 0) {
|
|
48
48
|
return cached;
|
|
49
49
|
}
|
|
50
50
|
const number = Number(element.getAttribute("tabindex"));
|
|
51
|
-
|
|
51
|
+
tabIndexCache.set(element, number);
|
|
52
52
|
return number;
|
|
53
53
|
}
|
|
54
54
|
elements2.forEach((element) => {
|
|
@@ -57,7 +57,7 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
57
57
|
ordered.sort((a, b) => getTabIndex(a) - getTabIndex(b));
|
|
58
58
|
return [...ordered, ...natural];
|
|
59
59
|
}
|
|
60
|
-
function
|
|
60
|
+
function normalize(elements2) {
|
|
61
61
|
let map = null;
|
|
62
62
|
for (const element of elements2) {
|
|
63
63
|
if (element instanceof HTMLInputElement && element.type === "radio" && element.name) {
|
|
@@ -89,7 +89,7 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
89
89
|
return true;
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
|
-
return
|
|
92
|
+
return normalize(sort(elements));
|
|
93
93
|
}
|
|
94
94
|
function getNextFocusable(container = document.body, options = {}) {
|
|
95
95
|
if (!(container instanceof HTMLElement)) {
|
|
@@ -190,7 +190,7 @@ function getRelativeFocusable(container, offset = 0, options) {
|
|
|
190
190
|
* High-precision focus management utility with shadow DOM support.
|
|
191
191
|
* Handles complex focus rules including tabindex ordering, radio groups, etc.
|
|
192
192
|
*
|
|
193
|
-
* @version 2.0.
|
|
193
|
+
* @version 2.0.3
|
|
194
194
|
* @author Yusuke Kamiyamane
|
|
195
195
|
* @license MIT
|
|
196
196
|
* @copyright Copyright (c) Yusuke Kamiyamane
|