@marianmeres/stuic 1.12.0 → 1.14.0
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/dist/actions/focus-trap.js +28 -24
- package/package.json +2 -2
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
// copied from skeleton
|
|
2
|
-
const defaults = { enabled: true, autoFocusFirst:
|
|
3
|
-
// Action: Focus Trap
|
|
1
|
+
// initially copied from skeleton, adjusted
|
|
2
|
+
const defaults = { enabled: true, autoFocusFirst: true };
|
|
4
3
|
export function focusTrap(node, options = {}) {
|
|
5
4
|
let { enabled, autoFocusFirst } = { ...defaults, ...(options || {}) };
|
|
6
5
|
const focusableSelectors = [
|
|
7
|
-
'
|
|
8
|
-
|
|
9
|
-
'details',
|
|
10
|
-
'iframe',
|
|
6
|
+
'[contentEditable=true]',
|
|
7
|
+
//
|
|
11
8
|
'button:not([disabled])',
|
|
12
9
|
'input:not([disabled])',
|
|
13
10
|
'select:not([disabled])',
|
|
14
11
|
'textarea:not([disabled])',
|
|
15
|
-
|
|
16
|
-
'[
|
|
12
|
+
//
|
|
13
|
+
'a[href]',
|
|
14
|
+
'area[href]',
|
|
15
|
+
'details',
|
|
16
|
+
'iframe',
|
|
17
|
+
// see more below on tabindexes
|
|
18
|
+
'[tabindex]:not([tabindex^="-"])',
|
|
17
19
|
].join(',');
|
|
18
20
|
let first;
|
|
19
21
|
let last;
|
|
@@ -34,20 +36,25 @@ export function focusTrap(node, options = {}) {
|
|
|
34
36
|
const queryElements = (fromObserver) => {
|
|
35
37
|
if (enabled === false)
|
|
36
38
|
return;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
//
|
|
39
|
+
let maxTabindex = 0;
|
|
40
|
+
let focusable = [...node.querySelectorAll(focusableSelectors)]
|
|
41
|
+
// filter negative tabindexes (afaik there is no :not([disabled] OR [tabindex^="-"]))
|
|
40
42
|
.filter((e) => {
|
|
43
|
+
// reusing loop for a side job here... see sort below
|
|
44
|
+
maxTabindex = Math.max(maxTabindex, parseInt(e.getAttribute('tabindex') || '0'));
|
|
45
|
+
//
|
|
41
46
|
if (e.getAttribute('disabled') === '')
|
|
42
47
|
return false;
|
|
43
48
|
if ((e.getAttribute('tabindex') || '').startsWith('-'))
|
|
44
49
|
return false;
|
|
45
50
|
return true;
|
|
46
51
|
})
|
|
47
|
-
// sort by tabindex, so the first/last will work as expected
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
// important to sort by tabindex, so the first/last will work as expected
|
|
53
|
+
// but must increase zero to max + 1 first, because browsers focus zeros as last...
|
|
54
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
|
|
55
|
+
.sort((e1, e2) => {
|
|
56
|
+
const a = parseInt(e1.getAttribute('tabindex') || '0') || maxTabindex + 1;
|
|
57
|
+
const b = parseInt(e2.getAttribute('tabindex') || '0') || maxTabindex + 1;
|
|
51
58
|
return a - b;
|
|
52
59
|
});
|
|
53
60
|
if (focusable.length) {
|
|
@@ -63,20 +70,17 @@ export function focusTrap(node, options = {}) {
|
|
|
63
70
|
};
|
|
64
71
|
queryElements(false);
|
|
65
72
|
function cleanup() {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if (last)
|
|
69
|
-
last.removeEventListener('keydown', onLastElemKeydown);
|
|
73
|
+
first && first.removeEventListener('keydown', onFirstElemKeydown);
|
|
74
|
+
last && last.removeEventListener('keydown', onLastElemKeydown);
|
|
70
75
|
}
|
|
71
76
|
// When children of node are changed (added or removed)
|
|
72
|
-
const
|
|
73
|
-
if (
|
|
77
|
+
const observer = new MutationObserver((mutations, observer) => {
|
|
78
|
+
if (mutations.length) {
|
|
74
79
|
cleanup();
|
|
75
80
|
queryElements(true);
|
|
76
81
|
}
|
|
77
82
|
return observer;
|
|
78
|
-
};
|
|
79
|
-
const observer = new MutationObserver(onObservationChange);
|
|
83
|
+
});
|
|
80
84
|
observer.observe(node, { childList: true, subtree: true });
|
|
81
85
|
// Lifecycle
|
|
82
86
|
return {
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marianmeres/stuic",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "vite dev",
|
|
6
|
-
"build": "vite build && npm run package",
|
|
6
|
+
"build": "vite build && npm run package && node ./scripts/date.js",
|
|
7
7
|
"build:watch": "fswatch -o src | xargs -n1 -I{} npm run build",
|
|
8
8
|
"preview": "vite preview",
|
|
9
9
|
"package": "svelte-kit sync && svelte-package && publint",
|