69 lines
1.9 KiB
JavaScript
69 lines
1.9 KiB
JavaScript
|
// Utilities
|
||
|
import { shallowRef, watch } from 'vue';
|
||
|
|
||
|
// Types
|
||
|
|
||
|
export function useScrolling(listRef, textFieldRef) {
|
||
|
const isScrolling = shallowRef(false);
|
||
|
let scrollTimeout;
|
||
|
function onListScroll(e) {
|
||
|
cancelAnimationFrame(scrollTimeout);
|
||
|
isScrolling.value = true;
|
||
|
scrollTimeout = requestAnimationFrame(() => {
|
||
|
scrollTimeout = requestAnimationFrame(() => {
|
||
|
isScrolling.value = false;
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
async function finishScrolling() {
|
||
|
await new Promise(resolve => requestAnimationFrame(resolve));
|
||
|
await new Promise(resolve => requestAnimationFrame(resolve));
|
||
|
await new Promise(resolve => requestAnimationFrame(resolve));
|
||
|
await new Promise(resolve => {
|
||
|
if (isScrolling.value) {
|
||
|
const stop = watch(isScrolling, () => {
|
||
|
stop();
|
||
|
resolve();
|
||
|
});
|
||
|
} else resolve();
|
||
|
});
|
||
|
}
|
||
|
async function onListKeydown(e) {
|
||
|
if (e.key === 'Tab') {
|
||
|
textFieldRef.value?.focus();
|
||
|
}
|
||
|
if (!['PageDown', 'PageUp', 'Home', 'End'].includes(e.key)) return;
|
||
|
const el = listRef.value?.$el;
|
||
|
if (!el) return;
|
||
|
if (e.key === 'Home' || e.key === 'End') {
|
||
|
el.scrollTo({
|
||
|
top: e.key === 'Home' ? 0 : el.scrollHeight,
|
||
|
behavior: 'smooth'
|
||
|
});
|
||
|
}
|
||
|
await finishScrolling();
|
||
|
const children = el.querySelectorAll(':scope > :not(.v-virtual-scroll__spacer)');
|
||
|
if (e.key === 'PageDown' || e.key === 'Home') {
|
||
|
const top = el.getBoundingClientRect().top;
|
||
|
for (const child of children) {
|
||
|
if (child.getBoundingClientRect().top >= top) {
|
||
|
child.focus();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
const bottom = el.getBoundingClientRect().bottom;
|
||
|
for (const child of [...children].reverse()) {
|
||
|
if (child.getBoundingClientRect().bottom <= bottom) {
|
||
|
child.focus();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return {
|
||
|
onListScroll,
|
||
|
onListKeydown
|
||
|
};
|
||
|
}
|
||
|
//# sourceMappingURL=useScrolling.mjs.map
|