@v-c/virtual-list 0.0.1 → 1.0.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/bump.config.ts +6 -0
- package/dist/Filler.cjs +51 -1
- package/dist/Filler.js +47 -56
- package/dist/Item.cjs +26 -1
- package/dist/Item.js +23 -26
- package/dist/List.cjs +408 -1
- package/dist/List.d.ts +45 -9
- package/dist/List.js +403 -274
- package/dist/ScrollBar.cjs +259 -1
- package/dist/ScrollBar.d.ts +3 -97
- package/dist/ScrollBar.js +254 -191
- package/dist/_virtual/rolldown_runtime.cjs +21 -0
- package/dist/hooks/useDiffItem.cjs +19 -1
- package/dist/hooks/useDiffItem.js +16 -20
- package/dist/hooks/useFrameWheel.cjs +63 -1
- package/dist/hooks/useFrameWheel.js +60 -51
- package/dist/hooks/useGetSize.cjs +29 -1
- package/dist/hooks/useGetSize.d.ts +2 -2
- package/dist/hooks/useGetSize.js +27 -23
- package/dist/hooks/useHeights.cjs +66 -1
- package/dist/hooks/useHeights.d.ts +1 -1
- package/dist/hooks/useHeights.js +62 -41
- package/dist/hooks/useMobileTouchMove.cjs +82 -1
- package/dist/hooks/useMobileTouchMove.js +79 -43
- package/dist/hooks/useOriginScroll.cjs +23 -1
- package/dist/hooks/useOriginScroll.js +20 -16
- package/dist/hooks/useScrollDrag.cjs +83 -1
- package/dist/hooks/useScrollDrag.js +77 -48
- package/dist/hooks/useScrollTo.cjs +97 -0
- package/dist/hooks/useScrollTo.d.ts +19 -0
- package/dist/hooks/useScrollTo.js +94 -0
- package/dist/index.cjs +4 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -4
- package/dist/interface.cjs +0 -1
- package/dist/interface.d.ts +1 -1
- package/dist/interface.js +0 -1
- package/dist/utils/CacheMap.cjs +25 -1
- package/dist/utils/CacheMap.d.ts +1 -1
- package/dist/utils/CacheMap.js +23 -28
- package/dist/utils/isFirefox.cjs +4 -1
- package/dist/utils/isFirefox.js +2 -4
- package/dist/utils/scrollbarUtil.cjs +8 -1
- package/dist/utils/scrollbarUtil.js +7 -6
- package/docs/animate.less +31 -0
- package/docs/animate.vue +159 -0
- package/docs/basic.vue +2 -1
- package/docs/nest.vue +1 -1
- package/docs/switch.vue +2 -1
- package/docs/virtual-list.stories.vue +4 -0
- package/package.json +16 -14
- package/src/Filler.tsx +2 -1
- package/src/Item.tsx +2 -1
- package/src/List.tsx +189 -124
- package/src/ScrollBar.tsx +33 -44
- package/src/hooks/useDiffItem.ts +3 -2
- package/src/hooks/useFrameWheel.ts +2 -1
- package/src/hooks/useGetSize.ts +5 -4
- package/src/hooks/useHeights.ts +7 -6
- package/src/hooks/useMobileTouchMove.ts +2 -1
- package/src/hooks/useOriginScroll.ts +2 -1
- package/src/hooks/useScrollDrag.ts +2 -1
- package/src/hooks/useScrollTo.tsx +184 -0
- package/src/index.ts +1 -1
- package/tsconfig.json +7 -0
- package/vitest.config.ts +1 -1
|
@@ -1,52 +1,61 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
function
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
1
|
+
import isFirefox_default from "../utils/isFirefox.js";
|
|
2
|
+
import useOriginScroll from "./useOriginScroll.js";
|
|
3
|
+
import { onUnmounted, ref } from "vue";
|
|
4
|
+
function useFrameWheel(inVirtual, isScrollAtTop, isScrollAtBottom, isScrollAtLeft, isScrollAtRight, horizontalScroll, onWheelDelta) {
|
|
5
|
+
const offsetRef = ref(0);
|
|
6
|
+
let nextFrame = null;
|
|
7
|
+
const wheelValueRef = ref(null);
|
|
8
|
+
const isMouseScrollRef = ref(false);
|
|
9
|
+
const originScroll = useOriginScroll(isScrollAtTop, isScrollAtBottom, isScrollAtLeft, isScrollAtRight);
|
|
10
|
+
function onWheelY(e, deltaY) {
|
|
11
|
+
if (nextFrame) cancelAnimationFrame(nextFrame);
|
|
12
|
+
if (originScroll(false, deltaY)) return;
|
|
13
|
+
const event = e;
|
|
14
|
+
if (!event._virtualHandled) event._virtualHandled = true;
|
|
15
|
+
else return;
|
|
16
|
+
offsetRef.value += deltaY;
|
|
17
|
+
wheelValueRef.value = deltaY;
|
|
18
|
+
if (!isFirefox_default) event.preventDefault();
|
|
19
|
+
nextFrame = requestAnimationFrame(() => {
|
|
20
|
+
const patchMultiple = isMouseScrollRef.value ? 10 : 1;
|
|
21
|
+
onWheelDelta(offsetRef.value * patchMultiple, false);
|
|
22
|
+
offsetRef.value = 0;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function onWheelX(event, deltaX) {
|
|
26
|
+
onWheelDelta(deltaX, true);
|
|
27
|
+
if (!isFirefox_default) event.preventDefault();
|
|
28
|
+
}
|
|
29
|
+
const wheelDirectionRef = ref(null);
|
|
30
|
+
let wheelDirectionClean = null;
|
|
31
|
+
function onWheel(event) {
|
|
32
|
+
if (!inVirtual.value) return;
|
|
33
|
+
if (wheelDirectionClean) cancelAnimationFrame(wheelDirectionClean);
|
|
34
|
+
wheelDirectionClean = requestAnimationFrame(() => {
|
|
35
|
+
wheelDirectionRef.value = null;
|
|
36
|
+
});
|
|
37
|
+
const { deltaX, deltaY, shiftKey } = event;
|
|
38
|
+
let mergedDeltaX = deltaX;
|
|
39
|
+
let mergedDeltaY = deltaY;
|
|
40
|
+
if (wheelDirectionRef.value === "sx" || !wheelDirectionRef.value && (shiftKey || false) && deltaY && !deltaX) {
|
|
41
|
+
mergedDeltaX = deltaY;
|
|
42
|
+
mergedDeltaY = 0;
|
|
43
|
+
wheelDirectionRef.value = "sx";
|
|
44
|
+
}
|
|
45
|
+
const absX = Math.abs(mergedDeltaX);
|
|
46
|
+
const absY = Math.abs(mergedDeltaY);
|
|
47
|
+
if (wheelDirectionRef.value === null) wheelDirectionRef.value = horizontalScroll && absX > absY ? "x" : "y";
|
|
48
|
+
if (wheelDirectionRef.value === "y") onWheelY(event, mergedDeltaY);
|
|
49
|
+
else onWheelX(event, mergedDeltaX);
|
|
50
|
+
}
|
|
51
|
+
function onFireFoxScroll(event) {
|
|
52
|
+
if (!inVirtual.value) return;
|
|
53
|
+
isMouseScrollRef.value = event.detail === wheelValueRef.value;
|
|
54
|
+
}
|
|
55
|
+
onUnmounted(() => {
|
|
56
|
+
if (nextFrame) cancelAnimationFrame(nextFrame);
|
|
57
|
+
if (wheelDirectionClean) cancelAnimationFrame(wheelDirectionClean);
|
|
58
|
+
});
|
|
59
|
+
return [onWheel, onFireFoxScroll];
|
|
49
60
|
}
|
|
50
|
-
export {
|
|
51
|
-
_ as default
|
|
52
|
-
};
|
|
61
|
+
export { useFrameWheel as default };
|
|
@@ -1 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
const require_rolldown_runtime = require("../_virtual/rolldown_runtime.cjs");
|
|
2
|
+
let vue = require("vue");
|
|
3
|
+
function useGetSize(mergedData, getKey, heights, itemHeight) {
|
|
4
|
+
return (0, vue.computed)(() => {
|
|
5
|
+
return (startKey, endKey) => {
|
|
6
|
+
let topIndex = 0;
|
|
7
|
+
let bottomIndex = mergedData.value.length - 1;
|
|
8
|
+
if (startKey !== void 0 && startKey !== null) topIndex = mergedData.value.findIndex((item) => getKey(item) === startKey);
|
|
9
|
+
if (endKey !== void 0 && endKey !== null) bottomIndex = mergedData.value.findIndex((item) => getKey(item) === endKey);
|
|
10
|
+
let top = 0;
|
|
11
|
+
for (let i = 0; i < topIndex; i += 1) {
|
|
12
|
+
const key = getKey(mergedData.value[i]);
|
|
13
|
+
const cacheHeight = heights.get(key);
|
|
14
|
+
top += cacheHeight === void 0 ? itemHeight.value : cacheHeight;
|
|
15
|
+
}
|
|
16
|
+
let bottom = 0;
|
|
17
|
+
for (let i = mergedData.value.length - 1; i > bottomIndex; i -= 1) {
|
|
18
|
+
const key = getKey(mergedData.value[i]);
|
|
19
|
+
const cacheHeight = heights.get(key);
|
|
20
|
+
bottom += cacheHeight === void 0 ? itemHeight.value : cacheHeight;
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
top,
|
|
24
|
+
bottom
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
exports.useGetSize = useGetSize;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { ComputedRef, Ref } from 'vue';
|
|
1
2
|
import { GetKey } from '../interface';
|
|
2
3
|
import { default as CacheMap } from '../utils/CacheMap';
|
|
3
|
-
|
|
4
|
-
export declare function useGetSize<T>(mergedData: Ref<T[]>, getKey: GetKey<T>, heights: CacheMap, itemHeight: number): ComputedRef<(startKey: any, endKey?: any) => {
|
|
4
|
+
export declare function useGetSize<T>(mergedData: Ref<T[]>, getKey: GetKey<T>, heights: CacheMap, itemHeight: Ref<number>): ComputedRef<(startKey: any, endKey?: any) => {
|
|
5
5
|
top: number;
|
|
6
6
|
bottom: number;
|
|
7
7
|
}>;
|
package/dist/hooks/useGetSize.js
CHANGED
|
@@ -1,24 +1,28 @@
|
|
|
1
|
-
import { computed
|
|
2
|
-
function
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import { computed } from "vue";
|
|
2
|
+
function useGetSize(mergedData, getKey, heights, itemHeight) {
|
|
3
|
+
return computed(() => {
|
|
4
|
+
return (startKey, endKey) => {
|
|
5
|
+
let topIndex = 0;
|
|
6
|
+
let bottomIndex = mergedData.value.length - 1;
|
|
7
|
+
if (startKey !== void 0 && startKey !== null) topIndex = mergedData.value.findIndex((item) => getKey(item) === startKey);
|
|
8
|
+
if (endKey !== void 0 && endKey !== null) bottomIndex = mergedData.value.findIndex((item) => getKey(item) === endKey);
|
|
9
|
+
let top = 0;
|
|
10
|
+
for (let i = 0; i < topIndex; i += 1) {
|
|
11
|
+
const key = getKey(mergedData.value[i]);
|
|
12
|
+
const cacheHeight = heights.get(key);
|
|
13
|
+
top += cacheHeight === void 0 ? itemHeight.value : cacheHeight;
|
|
14
|
+
}
|
|
15
|
+
let bottom = 0;
|
|
16
|
+
for (let i = mergedData.value.length - 1; i > bottomIndex; i -= 1) {
|
|
17
|
+
const key = getKey(mergedData.value[i]);
|
|
18
|
+
const cacheHeight = heights.get(key);
|
|
19
|
+
bottom += cacheHeight === void 0 ? itemHeight.value : cacheHeight;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
top,
|
|
23
|
+
bottom
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
});
|
|
21
27
|
}
|
|
22
|
-
export {
|
|
23
|
-
h as useGetSize
|
|
24
|
-
};
|
|
28
|
+
export { useGetSize };
|
|
@@ -1 +1,66 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2
|
+
const require_rolldown_runtime = require("../_virtual/rolldown_runtime.cjs");
|
|
3
|
+
const require_CacheMap = require("../utils/CacheMap.cjs");
|
|
4
|
+
let vue = require("vue");
|
|
5
|
+
function parseNumber(value) {
|
|
6
|
+
const num = parseFloat(value);
|
|
7
|
+
return isNaN(num) ? 0 : num;
|
|
8
|
+
}
|
|
9
|
+
function useHeights(getKey, onItemAdd, onItemRemove) {
|
|
10
|
+
const updatedMark = (0, vue.ref)(0);
|
|
11
|
+
const instanceRef = (0, vue.ref)(/* @__PURE__ */ new Map());
|
|
12
|
+
const heightsRef = (0, vue.reactive)(new require_CacheMap.default());
|
|
13
|
+
const promiseIdRef = (0, vue.ref)(0);
|
|
14
|
+
function cancelRaf() {
|
|
15
|
+
promiseIdRef.value += 1;
|
|
16
|
+
}
|
|
17
|
+
function collectHeight(sync = false) {
|
|
18
|
+
cancelRaf();
|
|
19
|
+
const doCollect = () => {
|
|
20
|
+
let changed = false;
|
|
21
|
+
instanceRef.value.forEach((element, key) => {
|
|
22
|
+
if (element && element.offsetParent) {
|
|
23
|
+
const { offsetHeight } = element;
|
|
24
|
+
const { marginTop, marginBottom } = getComputedStyle(element);
|
|
25
|
+
const marginTopNum = parseNumber(marginTop);
|
|
26
|
+
const marginBottomNum = parseNumber(marginBottom);
|
|
27
|
+
const totalHeight = offsetHeight + marginTopNum + marginBottomNum;
|
|
28
|
+
if (heightsRef.get(key) !== totalHeight) {
|
|
29
|
+
heightsRef.set(key, totalHeight);
|
|
30
|
+
changed = true;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
if (changed) updatedMark.value += 1;
|
|
35
|
+
};
|
|
36
|
+
if (sync) doCollect();
|
|
37
|
+
else {
|
|
38
|
+
promiseIdRef.value += 1;
|
|
39
|
+
const id = promiseIdRef.value;
|
|
40
|
+
Promise.resolve().then(() => {
|
|
41
|
+
if (id === promiseIdRef.value) doCollect();
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function setInstanceRef(item, instance) {
|
|
46
|
+
const key = getKey(item);
|
|
47
|
+
const origin = instanceRef.value.get(key);
|
|
48
|
+
if (origin === instance) return;
|
|
49
|
+
if (instance) {
|
|
50
|
+
instanceRef.value.set(key, instance);
|
|
51
|
+
collectHeight();
|
|
52
|
+
} else instanceRef.value.delete(key);
|
|
53
|
+
if (!origin !== !instance) if (instance) onItemAdd?.(item);
|
|
54
|
+
else onItemRemove?.(item);
|
|
55
|
+
}
|
|
56
|
+
(0, vue.onUnmounted)(() => {
|
|
57
|
+
cancelRaf();
|
|
58
|
+
});
|
|
59
|
+
return [
|
|
60
|
+
setInstanceRef,
|
|
61
|
+
collectHeight,
|
|
62
|
+
heightsRef,
|
|
63
|
+
updatedMark
|
|
64
|
+
];
|
|
65
|
+
}
|
|
66
|
+
exports.default = useHeights;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { GetKey } from '../interface';
|
|
2
1
|
import { Ref } from 'vue';
|
|
2
|
+
import { GetKey } from '../interface';
|
|
3
3
|
import { default as CacheMap } from '../utils/CacheMap';
|
|
4
4
|
export default function useHeights<T>(getKey: GetKey<T>, onItemAdd?: (item: T) => void, onItemRemove?: (item: T) => void): [
|
|
5
5
|
setInstanceRef: (item: T, instance: HTMLElement | null) => void,
|
package/dist/hooks/useHeights.js
CHANGED
|
@@ -1,43 +1,64 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
function
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import CacheMap_default from "../utils/CacheMap.js";
|
|
2
|
+
import { onUnmounted, reactive, ref } from "vue";
|
|
3
|
+
function parseNumber(value) {
|
|
4
|
+
const num = parseFloat(value);
|
|
5
|
+
return isNaN(num) ? 0 : num;
|
|
6
6
|
}
|
|
7
|
-
function
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
7
|
+
function useHeights(getKey, onItemAdd, onItemRemove) {
|
|
8
|
+
const updatedMark = ref(0);
|
|
9
|
+
const instanceRef = ref(/* @__PURE__ */ new Map());
|
|
10
|
+
const heightsRef = reactive(new CacheMap_default());
|
|
11
|
+
const promiseIdRef = ref(0);
|
|
12
|
+
function cancelRaf() {
|
|
13
|
+
promiseIdRef.value += 1;
|
|
14
|
+
}
|
|
15
|
+
function collectHeight(sync = false) {
|
|
16
|
+
cancelRaf();
|
|
17
|
+
const doCollect = () => {
|
|
18
|
+
let changed = false;
|
|
19
|
+
instanceRef.value.forEach((element, key) => {
|
|
20
|
+
if (element && element.offsetParent) {
|
|
21
|
+
const { offsetHeight } = element;
|
|
22
|
+
const { marginTop, marginBottom } = getComputedStyle(element);
|
|
23
|
+
const marginTopNum = parseNumber(marginTop);
|
|
24
|
+
const marginBottomNum = parseNumber(marginBottom);
|
|
25
|
+
const totalHeight = offsetHeight + marginTopNum + marginBottomNum;
|
|
26
|
+
if (heightsRef.get(key) !== totalHeight) {
|
|
27
|
+
heightsRef.set(key, totalHeight);
|
|
28
|
+
changed = true;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
if (changed) updatedMark.value += 1;
|
|
33
|
+
};
|
|
34
|
+
if (sync) doCollect();
|
|
35
|
+
else {
|
|
36
|
+
promiseIdRef.value += 1;
|
|
37
|
+
const id = promiseIdRef.value;
|
|
38
|
+
Promise.resolve().then(() => {
|
|
39
|
+
if (id === promiseIdRef.value) doCollect();
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function setInstanceRef(item, instance) {
|
|
44
|
+
const key = getKey(item);
|
|
45
|
+
const origin = instanceRef.value.get(key);
|
|
46
|
+
if (origin === instance) return;
|
|
47
|
+
if (instance) {
|
|
48
|
+
instanceRef.value.set(key, instance);
|
|
49
|
+
collectHeight();
|
|
50
|
+
} else instanceRef.value.delete(key);
|
|
51
|
+
if (!origin !== !instance) if (instance) onItemAdd?.(item);
|
|
52
|
+
else onItemRemove?.(item);
|
|
53
|
+
}
|
|
54
|
+
onUnmounted(() => {
|
|
55
|
+
cancelRaf();
|
|
56
|
+
});
|
|
57
|
+
return [
|
|
58
|
+
setInstanceRef,
|
|
59
|
+
collectHeight,
|
|
60
|
+
heightsRef,
|
|
61
|
+
updatedMark
|
|
62
|
+
];
|
|
40
63
|
}
|
|
41
|
-
export {
|
|
42
|
-
T as default
|
|
43
|
-
};
|
|
64
|
+
export { useHeights as default };
|
|
@@ -1 +1,82 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2
|
+
const require_rolldown_runtime = require("../_virtual/rolldown_runtime.cjs");
|
|
3
|
+
let vue = require("vue");
|
|
4
|
+
var SMOOTH_PTG = 14 / 15;
|
|
5
|
+
function useMobileTouchMove(inVirtual, listRef, callback) {
|
|
6
|
+
const touchedRef = (0, vue.ref)(false);
|
|
7
|
+
const touchXRef = (0, vue.ref)(0);
|
|
8
|
+
const touchYRef = (0, vue.ref)(0);
|
|
9
|
+
let elementRef = null;
|
|
10
|
+
let touchStartElement = null;
|
|
11
|
+
let intervalId = null;
|
|
12
|
+
let cleanUpEvents;
|
|
13
|
+
const onTouchMove = (e) => {
|
|
14
|
+
if (touchedRef.value) {
|
|
15
|
+
const currentX = Math.ceil(e.touches[0].pageX);
|
|
16
|
+
const currentY = Math.ceil(e.touches[0].pageY);
|
|
17
|
+
let offsetX = touchXRef.value - currentX;
|
|
18
|
+
let offsetY = touchYRef.value - currentY;
|
|
19
|
+
const isHorizontal = Math.abs(offsetX) > Math.abs(offsetY);
|
|
20
|
+
if (isHorizontal) touchXRef.value = currentX;
|
|
21
|
+
else touchYRef.value = currentY;
|
|
22
|
+
const scrollHandled = callback(isHorizontal, isHorizontal ? offsetX : offsetY, false, e);
|
|
23
|
+
if (scrollHandled) e.preventDefault();
|
|
24
|
+
if (intervalId) clearInterval(intervalId);
|
|
25
|
+
if (scrollHandled) intervalId = setInterval(() => {
|
|
26
|
+
if (isHorizontal) offsetX *= SMOOTH_PTG;
|
|
27
|
+
else offsetY *= SMOOTH_PTG;
|
|
28
|
+
const offset = Math.floor(isHorizontal ? offsetX : offsetY);
|
|
29
|
+
if (!callback(isHorizontal, offset, true) || Math.abs(offset) <= .1) {
|
|
30
|
+
if (intervalId) clearInterval(intervalId);
|
|
31
|
+
}
|
|
32
|
+
}, 16);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const onTouchEnd = () => {
|
|
36
|
+
touchedRef.value = false;
|
|
37
|
+
cleanUpEvents();
|
|
38
|
+
};
|
|
39
|
+
const onTouchStart = (e) => {
|
|
40
|
+
cleanUpEvents();
|
|
41
|
+
if (e.touches.length === 1 && !touchedRef.value) {
|
|
42
|
+
touchedRef.value = true;
|
|
43
|
+
touchXRef.value = Math.ceil(e.touches[0].pageX);
|
|
44
|
+
touchYRef.value = Math.ceil(e.touches[0].pageY);
|
|
45
|
+
elementRef = e.target;
|
|
46
|
+
elementRef.addEventListener("touchmove", onTouchMove, { passive: false });
|
|
47
|
+
elementRef.addEventListener("touchend", onTouchEnd, { passive: true });
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
cleanUpEvents = () => {
|
|
51
|
+
if (elementRef) {
|
|
52
|
+
elementRef.removeEventListener("touchmove", onTouchMove);
|
|
53
|
+
elementRef.removeEventListener("touchend", onTouchEnd);
|
|
54
|
+
elementRef = null;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const removeTouchStartListener = () => {
|
|
58
|
+
if (touchStartElement) {
|
|
59
|
+
touchStartElement.removeEventListener("touchstart", onTouchStart);
|
|
60
|
+
touchStartElement = null;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const teardown = () => {
|
|
64
|
+
removeTouchStartListener();
|
|
65
|
+
cleanUpEvents();
|
|
66
|
+
if (intervalId) {
|
|
67
|
+
clearInterval(intervalId);
|
|
68
|
+
intervalId = null;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
(0, vue.onUnmounted)(teardown);
|
|
72
|
+
(0, vue.watch)([inVirtual, listRef], ([enabled, ele], _prev, onCleanup) => {
|
|
73
|
+
if (enabled && ele) {
|
|
74
|
+
touchStartElement = ele;
|
|
75
|
+
ele.addEventListener("touchstart", onTouchStart, { passive: true });
|
|
76
|
+
onCleanup(() => {
|
|
77
|
+
teardown();
|
|
78
|
+
});
|
|
79
|
+
} else teardown();
|
|
80
|
+
}, { immediate: true });
|
|
81
|
+
}
|
|
82
|
+
exports.default = useMobileTouchMove;
|
|
@@ -1,44 +1,80 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
function
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
1
|
+
import { onUnmounted, ref, watch } from "vue";
|
|
2
|
+
var SMOOTH_PTG = 14 / 15;
|
|
3
|
+
function useMobileTouchMove(inVirtual, listRef, callback) {
|
|
4
|
+
const touchedRef = ref(false);
|
|
5
|
+
const touchXRef = ref(0);
|
|
6
|
+
const touchYRef = ref(0);
|
|
7
|
+
let elementRef = null;
|
|
8
|
+
let touchStartElement = null;
|
|
9
|
+
let intervalId = null;
|
|
10
|
+
let cleanUpEvents;
|
|
11
|
+
const onTouchMove = (e) => {
|
|
12
|
+
if (touchedRef.value) {
|
|
13
|
+
const currentX = Math.ceil(e.touches[0].pageX);
|
|
14
|
+
const currentY = Math.ceil(e.touches[0].pageY);
|
|
15
|
+
let offsetX = touchXRef.value - currentX;
|
|
16
|
+
let offsetY = touchYRef.value - currentY;
|
|
17
|
+
const isHorizontal = Math.abs(offsetX) > Math.abs(offsetY);
|
|
18
|
+
if (isHorizontal) touchXRef.value = currentX;
|
|
19
|
+
else touchYRef.value = currentY;
|
|
20
|
+
const scrollHandled = callback(isHorizontal, isHorizontal ? offsetX : offsetY, false, e);
|
|
21
|
+
if (scrollHandled) e.preventDefault();
|
|
22
|
+
if (intervalId) clearInterval(intervalId);
|
|
23
|
+
if (scrollHandled) intervalId = setInterval(() => {
|
|
24
|
+
if (isHorizontal) offsetX *= SMOOTH_PTG;
|
|
25
|
+
else offsetY *= SMOOTH_PTG;
|
|
26
|
+
const offset = Math.floor(isHorizontal ? offsetX : offsetY);
|
|
27
|
+
if (!callback(isHorizontal, offset, true) || Math.abs(offset) <= .1) {
|
|
28
|
+
if (intervalId) clearInterval(intervalId);
|
|
29
|
+
}
|
|
30
|
+
}, 16);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const onTouchEnd = () => {
|
|
34
|
+
touchedRef.value = false;
|
|
35
|
+
cleanUpEvents();
|
|
36
|
+
};
|
|
37
|
+
const onTouchStart = (e) => {
|
|
38
|
+
cleanUpEvents();
|
|
39
|
+
if (e.touches.length === 1 && !touchedRef.value) {
|
|
40
|
+
touchedRef.value = true;
|
|
41
|
+
touchXRef.value = Math.ceil(e.touches[0].pageX);
|
|
42
|
+
touchYRef.value = Math.ceil(e.touches[0].pageY);
|
|
43
|
+
elementRef = e.target;
|
|
44
|
+
elementRef.addEventListener("touchmove", onTouchMove, { passive: false });
|
|
45
|
+
elementRef.addEventListener("touchend", onTouchEnd, { passive: true });
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
cleanUpEvents = () => {
|
|
49
|
+
if (elementRef) {
|
|
50
|
+
elementRef.removeEventListener("touchmove", onTouchMove);
|
|
51
|
+
elementRef.removeEventListener("touchend", onTouchEnd);
|
|
52
|
+
elementRef = null;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const removeTouchStartListener = () => {
|
|
56
|
+
if (touchStartElement) {
|
|
57
|
+
touchStartElement.removeEventListener("touchstart", onTouchStart);
|
|
58
|
+
touchStartElement = null;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const teardown = () => {
|
|
62
|
+
removeTouchStartListener();
|
|
63
|
+
cleanUpEvents();
|
|
64
|
+
if (intervalId) {
|
|
65
|
+
clearInterval(intervalId);
|
|
66
|
+
intervalId = null;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
onUnmounted(teardown);
|
|
70
|
+
watch([inVirtual, listRef], ([enabled, ele], _prev, onCleanup) => {
|
|
71
|
+
if (enabled && ele) {
|
|
72
|
+
touchStartElement = ele;
|
|
73
|
+
ele.addEventListener("touchstart", onTouchStart, { passive: true });
|
|
74
|
+
onCleanup(() => {
|
|
75
|
+
teardown();
|
|
76
|
+
});
|
|
77
|
+
} else teardown();
|
|
78
|
+
}, { immediate: true });
|
|
41
79
|
}
|
|
42
|
-
export {
|
|
43
|
-
H as default
|
|
44
|
-
};
|
|
80
|
+
export { useMobileTouchMove as default };
|
|
@@ -1 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2
|
+
const require_rolldown_runtime = require("../_virtual/rolldown_runtime.cjs");
|
|
3
|
+
let vue = require("vue");
|
|
4
|
+
function useOriginScroll(isScrollAtTop, isScrollAtBottom, isScrollAtLeft, isScrollAtRight) {
|
|
5
|
+
const lockRef = (0, vue.ref)(false);
|
|
6
|
+
let lockTimeout = null;
|
|
7
|
+
function lockScroll() {
|
|
8
|
+
if (lockTimeout) clearTimeout(lockTimeout);
|
|
9
|
+
lockRef.value = true;
|
|
10
|
+
lockTimeout = setTimeout(() => {
|
|
11
|
+
lockRef.value = false;
|
|
12
|
+
}, 50);
|
|
13
|
+
}
|
|
14
|
+
return (isHorizontal, delta, smoothOffset = false) => {
|
|
15
|
+
const originScroll = isHorizontal ? delta < 0 && isScrollAtLeft.value || delta > 0 && isScrollAtRight.value : delta < 0 && isScrollAtTop.value || delta > 0 && isScrollAtBottom.value;
|
|
16
|
+
if (smoothOffset && originScroll) {
|
|
17
|
+
if (lockTimeout) clearTimeout(lockTimeout);
|
|
18
|
+
lockRef.value = false;
|
|
19
|
+
} else if (!originScroll || lockRef.value) lockScroll();
|
|
20
|
+
return !lockRef.value && originScroll;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
exports.default = useOriginScroll;
|