123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- // 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 {
- onScrollPassive: onListScroll,
- onKeydown: onListKeydown
- }; // typescript doesn't know about vue's event merging
- }
- //# sourceMappingURL=useScrolling.mjs.map
|