@stonecrop/utilities 0.30.0 → 0.32.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/tsdoc-metadata.json +1 -1
- package/dist/utilities.js +400 -267
- package/dist/utilities.js.map +1 -1
- package/package.json +28 -25
- package/dist/assets/sample_data/coa.json +0 -2362
- package/dist/assets/sample_data/financials.json +0 -252
- package/dist/assets/sample_data/forecast.json +0 -2792
- package/dist/assets/sample_data/forecast_items.json +0 -126
- package/dist/assets/sample_data/http_logs.json +0 -252
- package/dist/assets/sample_data/inbox.json +0 -355
- package/dist/assets/sample_data/parts.json +0 -1322
- package/dist/assets/sample_data/repos.json +0 -1142
- package/dist/src/composables/keyboard.d.ts +0 -13
- package/dist/src/composables/keyboard.d.ts.map +0 -1
- package/dist/src/composables/keyboard.js +0 -503
- package/dist/src/composables/visibility/index.d.ts +0 -24
- package/dist/src/composables/visibility/index.d.ts.map +0 -1
- package/dist/src/composables/visibility/index.js +0 -47
- package/dist/src/index.d.ts +0 -11
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -8
- package/dist/src/types/index.d.ts +0 -18
- package/dist/src/types/index.d.ts.map +0 -1
- package/dist/src/types/index.js +0 -0
- package/dist/utilities.tsbuildinfo +0 -1
- package/src/assets/sample_data/coa.json +0 -2362
- package/src/assets/sample_data/financials.json +0 -252
- package/src/assets/sample_data/forecast.json +0 -2792
- package/src/assets/sample_data/forecast_items.json +0 -126
- package/src/assets/sample_data/http_logs.json +0 -252
- package/src/assets/sample_data/inbox.json +0 -355
- package/src/assets/sample_data/parts.json +0 -1322
- package/src/assets/sample_data/repos.json +0 -1142
- package/src/composables/keyboard.ts +0 -499
- package/src/composables/visibility/index.ts +0 -68
- package/src/index.ts +0 -13
- package/src/types/index.ts +0 -28
package/dist/tsdoc-metadata.json
CHANGED
package/dist/utilities.js
CHANGED
|
@@ -1,271 +1,404 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
import { onBeforeUnmount, onMounted, ref, watch } from "vue";
|
|
2
|
+
import { defaultWindow, unrefElement, useEventListener, useFocusWithin } from "@vueuse/core";
|
|
3
|
+
//#region src/composables/visibility/index.ts
|
|
4
|
+
/**
|
|
5
|
+
* Tracks the visibility of an element within the viewport.
|
|
6
|
+
*
|
|
7
|
+
* Compatibility version to get Stonecrop keyboard navigation to work. This function is a copy of the
|
|
8
|
+
* `useElementVisibility` function from VueUse v9.13.0, with the `IntersectionObserver` API removed.
|
|
9
|
+
*
|
|
10
|
+
* This version uses the `getBoundingClientRect` method to determine if an element is visible
|
|
11
|
+
* in the viewport. This is less performant than the `IntersectionObserver` API, but it is
|
|
12
|
+
* more compatible.
|
|
13
|
+
*
|
|
14
|
+
* Note: the newer versions of the VueUse dependencies imported here are sufficient for this composable.
|
|
15
|
+
* (Last verified: v10.9.0 on May 2, 2024)
|
|
16
|
+
*
|
|
17
|
+
* @see https://v9-13-0.vueuse.org/core/useElementVisibility
|
|
18
|
+
* @param element - Element to track visibility for
|
|
19
|
+
* @param options - Configuration options (window, scrollTarget)
|
|
20
|
+
*/
|
|
21
|
+
function useElementVisibility(element, { window = defaultWindow, scrollTarget } = {}) {
|
|
22
|
+
const elementIsVisible = ref(false);
|
|
23
|
+
const testBounding = () => {
|
|
24
|
+
if (!window) return;
|
|
25
|
+
const document = window.document;
|
|
26
|
+
const el = unrefElement(element);
|
|
27
|
+
if (!el) elementIsVisible.value = false;
|
|
28
|
+
else {
|
|
29
|
+
const rect = el.getBoundingClientRect();
|
|
30
|
+
elementIsVisible.value = rect.top <= (window.innerHeight || document.documentElement.clientHeight) && rect.left <= (window.innerWidth || document.documentElement.clientWidth) && rect.bottom >= 0 && rect.right >= 0;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
watch(() => unrefElement(element), () => testBounding(), {
|
|
34
|
+
immediate: true,
|
|
35
|
+
flush: "post"
|
|
36
|
+
});
|
|
37
|
+
if (window) useEventListener(scrollTarget || window, "scroll", testBounding, {
|
|
38
|
+
capture: false,
|
|
39
|
+
passive: true
|
|
40
|
+
});
|
|
41
|
+
return elementIsVisible;
|
|
22
42
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}, H = (e) => {
|
|
30
|
-
let t;
|
|
31
|
-
if (e instanceof HTMLTableCellElement) {
|
|
32
|
-
const n = e.parentElement?.previousElementSibling;
|
|
33
|
-
if (n instanceof HTMLTableRowElement) {
|
|
34
|
-
const s = Array.from(n.children)[e.cellIndex];
|
|
35
|
-
s instanceof HTMLElement && (t = s);
|
|
36
|
-
}
|
|
37
|
-
} else if (e instanceof HTMLTableRowElement) {
|
|
38
|
-
const n = e.previousElementSibling;
|
|
39
|
-
n instanceof HTMLTableRowElement && (t = n);
|
|
40
|
-
}
|
|
41
|
-
return t && (!u(t) || !f(t)) ? H(t) : t;
|
|
42
|
-
}, W = (e) => {
|
|
43
|
-
if (!(e.target instanceof HTMLElement)) return;
|
|
44
|
-
const t = e.target;
|
|
45
|
-
let n;
|
|
46
|
-
if (t instanceof HTMLTableCellElement) {
|
|
47
|
-
const l = t.parentElement?.parentElement;
|
|
48
|
-
if (l) {
|
|
49
|
-
const o = l.firstElementChild?.children[t.cellIndex];
|
|
50
|
-
o instanceof HTMLElement && (n = o);
|
|
51
|
-
}
|
|
52
|
-
} else if (t instanceof HTMLTableRowElement) {
|
|
53
|
-
const l = t.parentElement;
|
|
54
|
-
if (l) {
|
|
55
|
-
const s = l.firstElementChild;
|
|
56
|
-
s instanceof HTMLTableRowElement && (n = s);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return n && (!u(n) || !f(n)) ? L(n) : n;
|
|
60
|
-
}, R = (e) => {
|
|
61
|
-
if (e.target instanceof HTMLElement)
|
|
62
|
-
return L(e.target);
|
|
63
|
-
}, L = (e) => {
|
|
64
|
-
let t;
|
|
65
|
-
if (e instanceof HTMLTableCellElement) {
|
|
66
|
-
const n = e.parentElement?.nextElementSibling;
|
|
67
|
-
if (n) {
|
|
68
|
-
const s = Array.from(n.children)[e.cellIndex];
|
|
69
|
-
s instanceof HTMLElement && (t = s);
|
|
70
|
-
}
|
|
71
|
-
} else if (e instanceof HTMLTableRowElement) {
|
|
72
|
-
const n = e.nextElementSibling;
|
|
73
|
-
n instanceof HTMLTableRowElement && (t = n);
|
|
74
|
-
}
|
|
75
|
-
return t && (!u(t) || !f(t)) ? L(t) : t;
|
|
76
|
-
}, q = (e) => {
|
|
77
|
-
if (!(e.target instanceof HTMLElement)) return;
|
|
78
|
-
const t = e.target;
|
|
79
|
-
let n;
|
|
80
|
-
if (t instanceof HTMLTableCellElement) {
|
|
81
|
-
const l = t.parentElement?.parentElement;
|
|
82
|
-
if (l) {
|
|
83
|
-
const o = l.lastElementChild?.children[t.cellIndex];
|
|
84
|
-
o instanceof HTMLElement && (n = o);
|
|
85
|
-
}
|
|
86
|
-
} else if (t instanceof HTMLTableRowElement) {
|
|
87
|
-
const l = t.parentElement;
|
|
88
|
-
if (l) {
|
|
89
|
-
const s = l.lastElementChild;
|
|
90
|
-
s instanceof HTMLTableRowElement && (n = s);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return n && (!u(n) || !f(n)) ? H(n) : n;
|
|
94
|
-
}, x = (e) => {
|
|
95
|
-
if (e.target instanceof HTMLElement)
|
|
96
|
-
return h(e.target);
|
|
97
|
-
}, h = (e) => {
|
|
98
|
-
let t;
|
|
99
|
-
const n = e.previousElementSibling;
|
|
100
|
-
if (n instanceof HTMLElement)
|
|
101
|
-
t = n;
|
|
102
|
-
else {
|
|
103
|
-
const s = e.parentElement?.previousElementSibling?.lastElementChild;
|
|
104
|
-
s instanceof HTMLElement && (t = s);
|
|
105
|
-
}
|
|
106
|
-
return t && (!u(t) || !f(t)) ? h(t) : t;
|
|
107
|
-
}, S = (e) => {
|
|
108
|
-
if (e.target instanceof HTMLElement)
|
|
109
|
-
return M(e.target);
|
|
110
|
-
}, M = (e) => {
|
|
111
|
-
let t;
|
|
112
|
-
const n = e.nextElementSibling;
|
|
113
|
-
if (n instanceof HTMLElement)
|
|
114
|
-
t = n;
|
|
115
|
-
else {
|
|
116
|
-
const s = e.parentElement?.nextElementSibling?.firstElementChild;
|
|
117
|
-
s instanceof HTMLElement && (t = s);
|
|
118
|
-
}
|
|
119
|
-
return t && (!u(t) || !f(t)) ? M(t) : t;
|
|
120
|
-
}, k = (e) => {
|
|
121
|
-
if (!(e.target instanceof HTMLElement)) return;
|
|
122
|
-
const n = e.target.parentElement?.firstElementChild, l = n instanceof HTMLElement ? n : null;
|
|
123
|
-
return l && (!u(l) || !f(l)) ? M(l) : l;
|
|
124
|
-
}, A = (e) => {
|
|
125
|
-
if (!(e.target instanceof HTMLElement)) return;
|
|
126
|
-
const n = e.target.parentElement?.lastElementChild, l = n instanceof HTMLElement ? n : null;
|
|
127
|
-
return l && (!u(l) || !f(l)) ? h(l) : l;
|
|
128
|
-
}, d = ["alt", "control", "shift", "meta"], N = {
|
|
129
|
-
ArrowUp: "up",
|
|
130
|
-
ArrowDown: "down",
|
|
131
|
-
ArrowLeft: "left",
|
|
132
|
-
ArrowRight: "right"
|
|
133
|
-
}, V = {
|
|
134
|
-
"keydown.up": (e) => {
|
|
135
|
-
const t = b(e);
|
|
136
|
-
t && (e.preventDefault(), e.stopPropagation(), t.focus());
|
|
137
|
-
},
|
|
138
|
-
"keydown.down": (e) => {
|
|
139
|
-
const t = R(e);
|
|
140
|
-
t && (e.preventDefault(), e.stopPropagation(), t.focus());
|
|
141
|
-
},
|
|
142
|
-
"keydown.left": (e) => {
|
|
143
|
-
const t = x(e);
|
|
144
|
-
e.preventDefault(), e.stopPropagation(), t && t.focus();
|
|
145
|
-
},
|
|
146
|
-
"keydown.right": (e) => {
|
|
147
|
-
const t = S(e);
|
|
148
|
-
e.preventDefault(), e.stopPropagation(), t && t.focus();
|
|
149
|
-
},
|
|
150
|
-
"keydown.control.up": (e) => {
|
|
151
|
-
const t = W(e);
|
|
152
|
-
t && (e.preventDefault(), e.stopPropagation(), t.focus());
|
|
153
|
-
},
|
|
154
|
-
"keydown.control.down": (e) => {
|
|
155
|
-
const t = q(e);
|
|
156
|
-
t && (e.preventDefault(), e.stopPropagation(), t.focus());
|
|
157
|
-
},
|
|
158
|
-
"keydown.control.left": (e) => {
|
|
159
|
-
const t = k(e);
|
|
160
|
-
t && (e.preventDefault(), e.stopPropagation(), t.focus());
|
|
161
|
-
},
|
|
162
|
-
"keydown.control.right": (e) => {
|
|
163
|
-
const t = A(e);
|
|
164
|
-
t && (e.preventDefault(), e.stopPropagation(), t.focus());
|
|
165
|
-
},
|
|
166
|
-
"keydown.end": (e) => {
|
|
167
|
-
const t = A(e);
|
|
168
|
-
t && (e.preventDefault(), e.stopPropagation(), t.focus());
|
|
169
|
-
},
|
|
170
|
-
"keydown.enter": (e) => {
|
|
171
|
-
if (!(e.target instanceof HTMLElement)) return;
|
|
172
|
-
if (e.target instanceof HTMLTableCellElement) {
|
|
173
|
-
e.preventDefault(), e.stopPropagation();
|
|
174
|
-
const n = R(e);
|
|
175
|
-
n && n.focus();
|
|
176
|
-
}
|
|
177
|
-
},
|
|
178
|
-
"keydown.shift.enter": (e) => {
|
|
179
|
-
if (!(e.target instanceof HTMLElement)) return;
|
|
180
|
-
if (e.target instanceof HTMLTableCellElement) {
|
|
181
|
-
e.preventDefault(), e.stopPropagation();
|
|
182
|
-
const n = b(e);
|
|
183
|
-
n && n.focus();
|
|
184
|
-
}
|
|
185
|
-
},
|
|
186
|
-
"keydown.home": (e) => {
|
|
187
|
-
const t = k(e);
|
|
188
|
-
t && (e.preventDefault(), e.stopPropagation(), t.focus());
|
|
189
|
-
},
|
|
190
|
-
"keydown.tab": (e) => {
|
|
191
|
-
const t = S(e);
|
|
192
|
-
t && (e.preventDefault(), e.stopPropagation(), t.focus());
|
|
193
|
-
},
|
|
194
|
-
"keydown.shift.tab": (e) => {
|
|
195
|
-
const t = x(e);
|
|
196
|
-
t && (e.preventDefault(), e.stopPropagation(), t.focus());
|
|
197
|
-
}
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/composables/keyboard.ts
|
|
45
|
+
var isVisible = (element) => {
|
|
46
|
+
let visible = useElementVisibility(element).value;
|
|
47
|
+
visible = visible && element.offsetHeight > 0;
|
|
48
|
+
return visible;
|
|
198
49
|
};
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
50
|
+
var isFocusable = (element) => {
|
|
51
|
+
return element.tabIndex >= 0;
|
|
52
|
+
};
|
|
53
|
+
var getUpCell = (event) => {
|
|
54
|
+
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
55
|
+
return getUpCellEl(event.target);
|
|
56
|
+
};
|
|
57
|
+
var getUpCellEl = (element) => {
|
|
58
|
+
let $upCell;
|
|
59
|
+
if (element instanceof HTMLTableCellElement) {
|
|
60
|
+
const $prevSibling = element.parentElement?.previousElementSibling;
|
|
61
|
+
if ($prevSibling instanceof HTMLTableRowElement) {
|
|
62
|
+
const $cellEl = Array.from($prevSibling.children)[element.cellIndex];
|
|
63
|
+
if ($cellEl instanceof HTMLElement) $upCell = $cellEl;
|
|
64
|
+
}
|
|
65
|
+
} else if (element instanceof HTMLTableRowElement) {
|
|
66
|
+
const $prevSibling = element.previousElementSibling;
|
|
67
|
+
if ($prevSibling instanceof HTMLTableRowElement) $upCell = $prevSibling;
|
|
68
|
+
}
|
|
69
|
+
if ($upCell && (!isFocusable($upCell) || !isVisible($upCell))) return getUpCellEl($upCell);
|
|
70
|
+
return $upCell;
|
|
71
|
+
};
|
|
72
|
+
var getTopCell = (event) => {
|
|
73
|
+
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
74
|
+
const $target = event.target;
|
|
75
|
+
let $topCell;
|
|
76
|
+
if ($target instanceof HTMLTableCellElement) {
|
|
77
|
+
const $table = $target.parentElement?.parentElement;
|
|
78
|
+
if ($table) {
|
|
79
|
+
const $navEl = $table.firstElementChild?.children[$target.cellIndex];
|
|
80
|
+
if ($navEl instanceof HTMLElement) $topCell = $navEl;
|
|
81
|
+
}
|
|
82
|
+
} else if ($target instanceof HTMLTableRowElement) {
|
|
83
|
+
const $parent = $target.parentElement;
|
|
84
|
+
if ($parent) {
|
|
85
|
+
const $firstEl = $parent.firstElementChild;
|
|
86
|
+
if ($firstEl instanceof HTMLTableRowElement) $topCell = $firstEl;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if ($topCell && (!isFocusable($topCell) || !isVisible($topCell))) return getDownCellEl($topCell);
|
|
90
|
+
return $topCell;
|
|
91
|
+
};
|
|
92
|
+
var getDownCell = (event) => {
|
|
93
|
+
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
94
|
+
return getDownCellEl(event.target);
|
|
95
|
+
};
|
|
96
|
+
var getDownCellEl = (element) => {
|
|
97
|
+
let $downCell;
|
|
98
|
+
if (element instanceof HTMLTableCellElement) {
|
|
99
|
+
const $nextSibling = element.parentElement?.nextElementSibling;
|
|
100
|
+
if ($nextSibling) {
|
|
101
|
+
const $cellEl = Array.from($nextSibling.children)[element.cellIndex];
|
|
102
|
+
if ($cellEl instanceof HTMLElement) $downCell = $cellEl;
|
|
103
|
+
}
|
|
104
|
+
} else if (element instanceof HTMLTableRowElement) {
|
|
105
|
+
const $nextSibling = element.nextElementSibling;
|
|
106
|
+
if ($nextSibling instanceof HTMLTableRowElement) $downCell = $nextSibling;
|
|
107
|
+
}
|
|
108
|
+
if ($downCell && (!isFocusable($downCell) || !isVisible($downCell))) return getDownCellEl($downCell);
|
|
109
|
+
return $downCell;
|
|
110
|
+
};
|
|
111
|
+
var getBottomCell = (event) => {
|
|
112
|
+
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
113
|
+
const $target = event.target;
|
|
114
|
+
let $bottomCell;
|
|
115
|
+
if ($target instanceof HTMLTableCellElement) {
|
|
116
|
+
const $table = $target.parentElement?.parentElement;
|
|
117
|
+
if ($table) {
|
|
118
|
+
const $navEl = $table.lastElementChild?.children[$target.cellIndex];
|
|
119
|
+
if ($navEl instanceof HTMLElement) $bottomCell = $navEl;
|
|
120
|
+
}
|
|
121
|
+
} else if ($target instanceof HTMLTableRowElement) {
|
|
122
|
+
const $parent = $target.parentElement;
|
|
123
|
+
if ($parent) {
|
|
124
|
+
const $lastEl = $parent.lastElementChild;
|
|
125
|
+
if ($lastEl instanceof HTMLTableRowElement) $bottomCell = $lastEl;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if ($bottomCell && (!isFocusable($bottomCell) || !isVisible($bottomCell))) return getUpCellEl($bottomCell);
|
|
129
|
+
return $bottomCell;
|
|
130
|
+
};
|
|
131
|
+
var getPrevCell = (event) => {
|
|
132
|
+
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
133
|
+
return getPrevCellEl(event.target);
|
|
134
|
+
};
|
|
135
|
+
var getPrevCellEl = (element) => {
|
|
136
|
+
let $prevCell;
|
|
137
|
+
const $prevSibling = element.previousElementSibling;
|
|
138
|
+
if ($prevSibling instanceof HTMLElement) $prevCell = $prevSibling;
|
|
139
|
+
else {
|
|
140
|
+
const $lastEl = (element.parentElement?.previousElementSibling)?.lastElementChild;
|
|
141
|
+
if ($lastEl instanceof HTMLElement) $prevCell = $lastEl;
|
|
142
|
+
}
|
|
143
|
+
if ($prevCell && (!isFocusable($prevCell) || !isVisible($prevCell))) return getPrevCellEl($prevCell);
|
|
144
|
+
return $prevCell;
|
|
145
|
+
};
|
|
146
|
+
var getNextCell = (event) => {
|
|
147
|
+
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
148
|
+
return getNextCellEl(event.target);
|
|
149
|
+
};
|
|
150
|
+
var getNextCellEl = (element) => {
|
|
151
|
+
let $nextCell;
|
|
152
|
+
const $nextSibling = element.nextElementSibling;
|
|
153
|
+
if ($nextSibling instanceof HTMLElement) $nextCell = $nextSibling;
|
|
154
|
+
else {
|
|
155
|
+
const $firstEl = (element.parentElement?.nextElementSibling)?.firstElementChild;
|
|
156
|
+
if ($firstEl instanceof HTMLElement) $nextCell = $firstEl;
|
|
157
|
+
}
|
|
158
|
+
if ($nextCell && (!isFocusable($nextCell) || !isVisible($nextCell))) return getNextCellEl($nextCell);
|
|
159
|
+
return $nextCell;
|
|
160
|
+
};
|
|
161
|
+
var getFirstCell = (event) => {
|
|
162
|
+
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
163
|
+
const $firstEl = event.target.parentElement?.firstElementChild;
|
|
164
|
+
const $firstCell = $firstEl instanceof HTMLElement ? $firstEl : null;
|
|
165
|
+
if ($firstCell && (!isFocusable($firstCell) || !isVisible($firstCell))) return getNextCellEl($firstCell);
|
|
166
|
+
return $firstCell;
|
|
167
|
+
};
|
|
168
|
+
var getLastCell = (event) => {
|
|
169
|
+
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
170
|
+
const $lastEl = event.target.parentElement?.lastElementChild;
|
|
171
|
+
const $lastCell = $lastEl instanceof HTMLElement ? $lastEl : null;
|
|
172
|
+
if ($lastCell && (!isFocusable($lastCell) || !isVisible($lastCell))) return getPrevCellEl($lastCell);
|
|
173
|
+
return $lastCell;
|
|
174
|
+
};
|
|
175
|
+
var modifierKeys = [
|
|
176
|
+
"alt",
|
|
177
|
+
"control",
|
|
178
|
+
"shift",
|
|
179
|
+
"meta"
|
|
180
|
+
];
|
|
181
|
+
var eventKeyMap = {
|
|
182
|
+
ArrowUp: "up",
|
|
183
|
+
ArrowDown: "down",
|
|
184
|
+
ArrowLeft: "left",
|
|
185
|
+
ArrowRight: "right"
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Default keypress handlers for keyboard navigation
|
|
189
|
+
* @public
|
|
190
|
+
*/
|
|
191
|
+
var defaultKeypressHandlers = {
|
|
192
|
+
"keydown.up": (event) => {
|
|
193
|
+
const $upCell = getUpCell(event);
|
|
194
|
+
if ($upCell) {
|
|
195
|
+
event.preventDefault();
|
|
196
|
+
event.stopPropagation();
|
|
197
|
+
$upCell.focus();
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
"keydown.down": (event) => {
|
|
201
|
+
const $downCell = getDownCell(event);
|
|
202
|
+
if ($downCell) {
|
|
203
|
+
event.preventDefault();
|
|
204
|
+
event.stopPropagation();
|
|
205
|
+
$downCell.focus();
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"keydown.left": (event) => {
|
|
209
|
+
const $prevCell = getPrevCell(event);
|
|
210
|
+
event.preventDefault();
|
|
211
|
+
event.stopPropagation();
|
|
212
|
+
if ($prevCell) $prevCell.focus();
|
|
213
|
+
},
|
|
214
|
+
"keydown.right": (event) => {
|
|
215
|
+
const $nextCell = getNextCell(event);
|
|
216
|
+
event.preventDefault();
|
|
217
|
+
event.stopPropagation();
|
|
218
|
+
if ($nextCell) $nextCell.focus();
|
|
219
|
+
},
|
|
220
|
+
"keydown.control.up": (event) => {
|
|
221
|
+
const $topCell = getTopCell(event);
|
|
222
|
+
if ($topCell) {
|
|
223
|
+
event.preventDefault();
|
|
224
|
+
event.stopPropagation();
|
|
225
|
+
$topCell.focus();
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
"keydown.control.down": (event) => {
|
|
229
|
+
const $bottomCell = getBottomCell(event);
|
|
230
|
+
if ($bottomCell) {
|
|
231
|
+
event.preventDefault();
|
|
232
|
+
event.stopPropagation();
|
|
233
|
+
$bottomCell.focus();
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
"keydown.control.left": (event) => {
|
|
237
|
+
const $firstCell = getFirstCell(event);
|
|
238
|
+
if ($firstCell) {
|
|
239
|
+
event.preventDefault();
|
|
240
|
+
event.stopPropagation();
|
|
241
|
+
$firstCell.focus();
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
"keydown.control.right": (event) => {
|
|
245
|
+
const $lastCell = getLastCell(event);
|
|
246
|
+
if ($lastCell) {
|
|
247
|
+
event.preventDefault();
|
|
248
|
+
event.stopPropagation();
|
|
249
|
+
$lastCell.focus();
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
"keydown.end": (event) => {
|
|
253
|
+
const $lastCell = getLastCell(event);
|
|
254
|
+
if ($lastCell) {
|
|
255
|
+
event.preventDefault();
|
|
256
|
+
event.stopPropagation();
|
|
257
|
+
$lastCell.focus();
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
"keydown.enter": (event) => {
|
|
261
|
+
if (!(event.target instanceof HTMLElement)) return;
|
|
262
|
+
if (event.target instanceof HTMLTableCellElement) {
|
|
263
|
+
event.preventDefault();
|
|
264
|
+
event.stopPropagation();
|
|
265
|
+
const $downCell = getDownCell(event);
|
|
266
|
+
if ($downCell) $downCell.focus();
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
"keydown.shift.enter": (event) => {
|
|
270
|
+
if (!(event.target instanceof HTMLElement)) return;
|
|
271
|
+
if (event.target instanceof HTMLTableCellElement) {
|
|
272
|
+
event.preventDefault();
|
|
273
|
+
event.stopPropagation();
|
|
274
|
+
const $upCell = getUpCell(event);
|
|
275
|
+
if ($upCell) $upCell.focus();
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
"keydown.home": (event) => {
|
|
279
|
+
const $firstCell = getFirstCell(event);
|
|
280
|
+
if ($firstCell) {
|
|
281
|
+
event.preventDefault();
|
|
282
|
+
event.stopPropagation();
|
|
283
|
+
$firstCell.focus();
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
"keydown.tab": (event) => {
|
|
287
|
+
const $nextCell = getNextCell(event);
|
|
288
|
+
if ($nextCell) {
|
|
289
|
+
event.preventDefault();
|
|
290
|
+
event.stopPropagation();
|
|
291
|
+
$nextCell.focus();
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
"keydown.shift.tab": (event) => {
|
|
295
|
+
const $prevCell = getPrevCell(event);
|
|
296
|
+
if ($prevCell) {
|
|
297
|
+
event.preventDefault();
|
|
298
|
+
event.stopPropagation();
|
|
299
|
+
$prevCell.focus();
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
/**
|
|
304
|
+
* Gets the parent element from a keyboard navigation option.
|
|
305
|
+
* @internal
|
|
306
|
+
*/
|
|
307
|
+
function getParentElement(option) {
|
|
308
|
+
let $parent = null;
|
|
309
|
+
if (option.parent) {
|
|
310
|
+
if (typeof option.parent === "string") $parent = document.querySelector(option.parent);
|
|
311
|
+
else if (option.parent instanceof HTMLElement) $parent = option.parent;
|
|
312
|
+
else $parent = option.parent.value;
|
|
313
|
+
}
|
|
314
|
+
return $parent;
|
|
263
315
|
}
|
|
264
|
-
|
|
316
|
+
/**
|
|
317
|
+
* Keyboard navigation composable
|
|
318
|
+
* @param options - Keyboard navigation options
|
|
319
|
+
* @public
|
|
320
|
+
*/
|
|
321
|
+
function useKeyboardNav(options) {
|
|
322
|
+
const getSelectorsFromOption = (option) => {
|
|
323
|
+
const $parent = getParentElement(option);
|
|
324
|
+
let selectors = [];
|
|
325
|
+
if (typeof option.selectors === "string") selectors = $parent ? Array.from($parent.querySelectorAll(option.selectors)) : Array.from(document.querySelectorAll(option.selectors));
|
|
326
|
+
else if (Array.isArray(option.selectors)) for (const element of option.selectors) if (element instanceof HTMLElement) selectors.push(element);
|
|
327
|
+
else selectors.push(element.$el);
|
|
328
|
+
else if (option.selectors instanceof HTMLElement) selectors.push(option.selectors);
|
|
329
|
+
else if (option.selectors?.value) {
|
|
330
|
+
if (Array.isArray(option.selectors.value)) for (const element of option.selectors.value) if (element instanceof HTMLElement) selectors.push(element);
|
|
331
|
+
else selectors.push(element.$el);
|
|
332
|
+
else selectors.push(option.selectors.value);
|
|
333
|
+
}
|
|
334
|
+
return selectors;
|
|
335
|
+
};
|
|
336
|
+
const getSelectors = (option) => {
|
|
337
|
+
const $parent = getParentElement(option);
|
|
338
|
+
let selectors = [];
|
|
339
|
+
if (option.selectors) selectors = getSelectorsFromOption(option);
|
|
340
|
+
else if ($parent) selectors = Array.from($parent.children).filter((el) => el instanceof HTMLElement).filter((selector) => {
|
|
341
|
+
return isFocusable(selector) && isVisible(selector);
|
|
342
|
+
});
|
|
343
|
+
return selectors;
|
|
344
|
+
};
|
|
345
|
+
const getEventListener = (option) => {
|
|
346
|
+
return (event) => {
|
|
347
|
+
const activeKey = eventKeyMap[event.key] || event.key.toLowerCase();
|
|
348
|
+
if (modifierKeys.includes(activeKey)) return;
|
|
349
|
+
const handlers = option.handlers || defaultKeypressHandlers;
|
|
350
|
+
for (const key of Object.keys(handlers)) {
|
|
351
|
+
const [eventType, ...keys] = key.split(".");
|
|
352
|
+
if (eventType !== "keydown") continue;
|
|
353
|
+
if (keys.includes(activeKey)) {
|
|
354
|
+
const listener = handlers[key];
|
|
355
|
+
const hasModifier = keys.filter((k) => modifierKeys.includes(k));
|
|
356
|
+
const isModifierActive = modifierKeys.some((mk) => {
|
|
357
|
+
const modifierKey = mk.charAt(0).toUpperCase() + mk.slice(1);
|
|
358
|
+
return event.getModifierState(modifierKey);
|
|
359
|
+
});
|
|
360
|
+
if (hasModifier.length > 0) {
|
|
361
|
+
if (isModifierActive) {
|
|
362
|
+
for (const modifier of modifierKeys) if (keys.includes(modifier)) {
|
|
363
|
+
const modifierKey = modifier.charAt(0).toUpperCase() + modifier.slice(1);
|
|
364
|
+
if (event.getModifierState(modifierKey)) listener(event);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
} else if (!isModifierActive) listener(event);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
};
|
|
372
|
+
const watchStopHandlers = [];
|
|
373
|
+
onMounted(() => {
|
|
374
|
+
for (const option of options) {
|
|
375
|
+
const $parent = getParentElement(option);
|
|
376
|
+
const selectors = getSelectors(option);
|
|
377
|
+
const listener = getEventListener(option);
|
|
378
|
+
const listenerElements = $parent ? [$parent] : selectors;
|
|
379
|
+
for (const element of listenerElements) {
|
|
380
|
+
const { focused } = useFocusWithin(ref(element));
|
|
381
|
+
const stopHandler = watch(focused, (value) => {
|
|
382
|
+
if (value) element.addEventListener("keydown", listener);
|
|
383
|
+
else element.removeEventListener("keydown", listener);
|
|
384
|
+
});
|
|
385
|
+
watchStopHandlers.push(stopHandler);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
onBeforeUnmount(() => {
|
|
390
|
+
for (const stopHandler of watchStopHandlers) stopHandler();
|
|
391
|
+
});
|
|
265
392
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
393
|
+
//#endregion
|
|
394
|
+
//#region src/index.ts
|
|
395
|
+
/**
|
|
396
|
+
* Install all utility components
|
|
397
|
+
* @param _app - Vue app instance
|
|
398
|
+
* @public
|
|
399
|
+
*/
|
|
400
|
+
function install(_app) {}
|
|
401
|
+
//#endregion
|
|
402
|
+
export { defaultKeypressHandlers, install, useKeyboardNav };
|
|
403
|
+
|
|
404
|
+
//# sourceMappingURL=utilities.js.map
|