@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,17 +1,21 @@
|
|
|
1
|
-
import { ref
|
|
2
|
-
function
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
import { ref } from "vue";
|
|
2
|
+
function useOriginScroll(isScrollAtTop, isScrollAtBottom, isScrollAtLeft, isScrollAtRight) {
|
|
3
|
+
const lockRef = ref(false);
|
|
4
|
+
let lockTimeout = null;
|
|
5
|
+
function lockScroll() {
|
|
6
|
+
if (lockTimeout) clearTimeout(lockTimeout);
|
|
7
|
+
lockRef.value = true;
|
|
8
|
+
lockTimeout = setTimeout(() => {
|
|
9
|
+
lockRef.value = false;
|
|
10
|
+
}, 50);
|
|
11
|
+
}
|
|
12
|
+
return (isHorizontal, delta, smoothOffset = false) => {
|
|
13
|
+
const originScroll = isHorizontal ? delta < 0 && isScrollAtLeft.value || delta > 0 && isScrollAtRight.value : delta < 0 && isScrollAtTop.value || delta > 0 && isScrollAtBottom.value;
|
|
14
|
+
if (smoothOffset && originScroll) {
|
|
15
|
+
if (lockTimeout) clearTimeout(lockTimeout);
|
|
16
|
+
lockRef.value = false;
|
|
17
|
+
} else if (!originScroll || lockRef.value) lockScroll();
|
|
18
|
+
return !lockRef.value && originScroll;
|
|
19
|
+
};
|
|
14
20
|
}
|
|
15
|
-
export {
|
|
16
|
-
m as default
|
|
17
|
-
};
|
|
21
|
+
export { useOriginScroll as default };
|
|
@@ -1 +1,83 @@
|
|
|
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 smoothScrollOffset(offset) {
|
|
5
|
+
return Math.floor(offset ** .5);
|
|
6
|
+
}
|
|
7
|
+
function getPageXY(e, horizontal) {
|
|
8
|
+
return ("touches" in e ? e.touches[0] : e)[horizontal ? "pageX" : "pageY"] - window[horizontal ? "scrollX" : "scrollY"];
|
|
9
|
+
}
|
|
10
|
+
function useScrollDrag(inVirtual, componentRef, onScrollOffset) {
|
|
11
|
+
let cachedElement = null;
|
|
12
|
+
let cachedDocument = null;
|
|
13
|
+
let mouseDownLock = false;
|
|
14
|
+
let rafId = null;
|
|
15
|
+
let offset = 0;
|
|
16
|
+
const stopScroll = () => {
|
|
17
|
+
if (rafId !== null) {
|
|
18
|
+
cancelAnimationFrame(rafId);
|
|
19
|
+
rafId = null;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const continueScroll = () => {
|
|
23
|
+
stopScroll();
|
|
24
|
+
rafId = requestAnimationFrame(() => {
|
|
25
|
+
onScrollOffset(offset);
|
|
26
|
+
continueScroll();
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
const clearDragState = () => {
|
|
30
|
+
mouseDownLock = false;
|
|
31
|
+
stopScroll();
|
|
32
|
+
};
|
|
33
|
+
const onMouseDown = (e) => {
|
|
34
|
+
if (e.target.draggable || e.button !== 0) return;
|
|
35
|
+
const event = e;
|
|
36
|
+
if (!event._virtualHandled) {
|
|
37
|
+
event._virtualHandled = true;
|
|
38
|
+
mouseDownLock = true;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const onMouseMove = (e) => {
|
|
42
|
+
if (mouseDownLock && cachedElement) {
|
|
43
|
+
const mouseY = getPageXY(e, false);
|
|
44
|
+
const { top, bottom } = cachedElement.getBoundingClientRect();
|
|
45
|
+
if (mouseY <= top) {
|
|
46
|
+
offset = -smoothScrollOffset(top - mouseY);
|
|
47
|
+
continueScroll();
|
|
48
|
+
} else if (mouseY >= bottom) {
|
|
49
|
+
offset = smoothScrollOffset(mouseY - bottom);
|
|
50
|
+
continueScroll();
|
|
51
|
+
} else stopScroll();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const teardown = () => {
|
|
55
|
+
if (cachedElement) {
|
|
56
|
+
cachedElement.removeEventListener("mousedown", onMouseDown);
|
|
57
|
+
cachedElement = null;
|
|
58
|
+
}
|
|
59
|
+
if (cachedDocument) {
|
|
60
|
+
cachedDocument.removeEventListener("mouseup", clearDragState);
|
|
61
|
+
cachedDocument.removeEventListener("mousemove", onMouseMove);
|
|
62
|
+
cachedDocument.removeEventListener("dragend", clearDragState);
|
|
63
|
+
cachedDocument = null;
|
|
64
|
+
}
|
|
65
|
+
clearDragState();
|
|
66
|
+
};
|
|
67
|
+
(0, vue.onUnmounted)(teardown);
|
|
68
|
+
(0, vue.watch)([inVirtual, componentRef], ([enabled, ele], _prev, onCleanup) => {
|
|
69
|
+
if (enabled && ele) {
|
|
70
|
+
cachedElement = ele;
|
|
71
|
+
cachedDocument = ele.ownerDocument;
|
|
72
|
+
cachedElement.addEventListener("mousedown", onMouseDown);
|
|
73
|
+
cachedDocument.addEventListener("mouseup", clearDragState);
|
|
74
|
+
cachedDocument.addEventListener("mousemove", onMouseMove);
|
|
75
|
+
cachedDocument.addEventListener("dragend", clearDragState);
|
|
76
|
+
onCleanup(() => {
|
|
77
|
+
teardown();
|
|
78
|
+
});
|
|
79
|
+
} else teardown();
|
|
80
|
+
}, { immediate: true });
|
|
81
|
+
}
|
|
82
|
+
exports.default = useScrollDrag;
|
|
83
|
+
exports.getPageXY = getPageXY;
|
|
@@ -1,51 +1,80 @@
|
|
|
1
|
-
import { onUnmounted
|
|
2
|
-
function
|
|
3
|
-
|
|
1
|
+
import { onUnmounted, watch } from "vue";
|
|
2
|
+
function smoothScrollOffset(offset) {
|
|
3
|
+
return Math.floor(offset ** .5);
|
|
4
4
|
}
|
|
5
|
-
function
|
|
6
|
-
|
|
5
|
+
function getPageXY(e, horizontal) {
|
|
6
|
+
return ("touches" in e ? e.touches[0] : e)[horizontal ? "pageX" : "pageY"] - window[horizontal ? "scrollX" : "scrollY"];
|
|
7
7
|
}
|
|
8
|
-
function
|
|
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
|
-
|
|
8
|
+
function useScrollDrag(inVirtual, componentRef, onScrollOffset) {
|
|
9
|
+
let cachedElement = null;
|
|
10
|
+
let cachedDocument = null;
|
|
11
|
+
let mouseDownLock = false;
|
|
12
|
+
let rafId = null;
|
|
13
|
+
let offset = 0;
|
|
14
|
+
const stopScroll = () => {
|
|
15
|
+
if (rafId !== null) {
|
|
16
|
+
cancelAnimationFrame(rafId);
|
|
17
|
+
rafId = null;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const continueScroll = () => {
|
|
21
|
+
stopScroll();
|
|
22
|
+
rafId = requestAnimationFrame(() => {
|
|
23
|
+
onScrollOffset(offset);
|
|
24
|
+
continueScroll();
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
const clearDragState = () => {
|
|
28
|
+
mouseDownLock = false;
|
|
29
|
+
stopScroll();
|
|
30
|
+
};
|
|
31
|
+
const onMouseDown = (e) => {
|
|
32
|
+
if (e.target.draggable || e.button !== 0) return;
|
|
33
|
+
const event = e;
|
|
34
|
+
if (!event._virtualHandled) {
|
|
35
|
+
event._virtualHandled = true;
|
|
36
|
+
mouseDownLock = true;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const onMouseMove = (e) => {
|
|
40
|
+
if (mouseDownLock && cachedElement) {
|
|
41
|
+
const mouseY = getPageXY(e, false);
|
|
42
|
+
const { top, bottom } = cachedElement.getBoundingClientRect();
|
|
43
|
+
if (mouseY <= top) {
|
|
44
|
+
offset = -smoothScrollOffset(top - mouseY);
|
|
45
|
+
continueScroll();
|
|
46
|
+
} else if (mouseY >= bottom) {
|
|
47
|
+
offset = smoothScrollOffset(mouseY - bottom);
|
|
48
|
+
continueScroll();
|
|
49
|
+
} else stopScroll();
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const teardown = () => {
|
|
53
|
+
if (cachedElement) {
|
|
54
|
+
cachedElement.removeEventListener("mousedown", onMouseDown);
|
|
55
|
+
cachedElement = null;
|
|
56
|
+
}
|
|
57
|
+
if (cachedDocument) {
|
|
58
|
+
cachedDocument.removeEventListener("mouseup", clearDragState);
|
|
59
|
+
cachedDocument.removeEventListener("mousemove", onMouseMove);
|
|
60
|
+
cachedDocument.removeEventListener("dragend", clearDragState);
|
|
61
|
+
cachedDocument = null;
|
|
62
|
+
}
|
|
63
|
+
clearDragState();
|
|
64
|
+
};
|
|
65
|
+
onUnmounted(teardown);
|
|
66
|
+
watch([inVirtual, componentRef], ([enabled, ele], _prev, onCleanup) => {
|
|
67
|
+
if (enabled && ele) {
|
|
68
|
+
cachedElement = ele;
|
|
69
|
+
cachedDocument = ele.ownerDocument;
|
|
70
|
+
cachedElement.addEventListener("mousedown", onMouseDown);
|
|
71
|
+
cachedDocument.addEventListener("mouseup", clearDragState);
|
|
72
|
+
cachedDocument.addEventListener("mousemove", onMouseMove);
|
|
73
|
+
cachedDocument.addEventListener("dragend", clearDragState);
|
|
74
|
+
onCleanup(() => {
|
|
75
|
+
teardown();
|
|
76
|
+
});
|
|
77
|
+
} else teardown();
|
|
78
|
+
}, { immediate: true });
|
|
47
79
|
}
|
|
48
|
-
export {
|
|
49
|
-
M as default,
|
|
50
|
-
b as getPageXY
|
|
51
|
-
};
|
|
80
|
+
export { useScrollDrag as default, getPageXY };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2
|
+
const require_rolldown_runtime = require("../_virtual/rolldown_runtime.cjs");
|
|
3
|
+
let vue = require("vue");
|
|
4
|
+
let __v_c_util = require("@v-c/util");
|
|
5
|
+
let __v_c_util_dist_raf = require("@v-c/util/dist/raf");
|
|
6
|
+
__v_c_util_dist_raf = require_rolldown_runtime.__toESM(__v_c_util_dist_raf);
|
|
7
|
+
var MAX_TIMES = 10;
|
|
8
|
+
function useScrollTo(containerRef, data, heights, itemHeight, getKey, collectHeight, syncScrollTop, triggerFlash) {
|
|
9
|
+
const scrollRef = (0, vue.shallowRef)();
|
|
10
|
+
const syncState = (0, vue.shallowRef)(null);
|
|
11
|
+
(0, vue.watch)([syncState, containerRef], () => {
|
|
12
|
+
if (syncState.value && syncState.value.times < MAX_TIMES) {
|
|
13
|
+
if (!containerRef.value) {
|
|
14
|
+
syncState.value = { ...syncState.value };
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
collectHeight();
|
|
18
|
+
const { targetAlign, originAlign, index, offset } = syncState.value;
|
|
19
|
+
const height = containerRef.value.clientHeight;
|
|
20
|
+
let needCollectHeight = false;
|
|
21
|
+
let newTargetAlign = targetAlign ?? null;
|
|
22
|
+
let targetTop = null;
|
|
23
|
+
if (height) {
|
|
24
|
+
const mergedAlign = targetAlign || originAlign;
|
|
25
|
+
let stackTop = 0;
|
|
26
|
+
let itemTop = 0;
|
|
27
|
+
let itemBottom = 0;
|
|
28
|
+
const maxLen = Math.min(data.value.length - 1, index);
|
|
29
|
+
for (let i = 0; i <= maxLen; i += 1) {
|
|
30
|
+
const key = getKey(data.value[i]);
|
|
31
|
+
itemTop = stackTop;
|
|
32
|
+
const cacheHeight = heights.get(key);
|
|
33
|
+
itemBottom = itemTop + (cacheHeight === void 0 ? itemHeight.value : cacheHeight);
|
|
34
|
+
stackTop = itemBottom;
|
|
35
|
+
}
|
|
36
|
+
let leftHeight = mergedAlign === "top" ? offset : height - offset;
|
|
37
|
+
for (let i = maxLen; i >= 0; i -= 1) {
|
|
38
|
+
const key = getKey(data.value[i]);
|
|
39
|
+
const cacheHeight = heights.get(key);
|
|
40
|
+
if (cacheHeight === void 0) {
|
|
41
|
+
needCollectHeight = true;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
leftHeight -= cacheHeight;
|
|
45
|
+
if (leftHeight <= 0) break;
|
|
46
|
+
}
|
|
47
|
+
switch (mergedAlign) {
|
|
48
|
+
case "top":
|
|
49
|
+
targetTop = itemTop - offset;
|
|
50
|
+
break;
|
|
51
|
+
case "bottom":
|
|
52
|
+
targetTop = itemBottom - height + offset;
|
|
53
|
+
break;
|
|
54
|
+
default: {
|
|
55
|
+
const { scrollTop } = containerRef.value;
|
|
56
|
+
const scrollBottom = scrollTop + height;
|
|
57
|
+
if (itemTop < scrollTop) newTargetAlign = "top";
|
|
58
|
+
else if (itemBottom > scrollBottom) newTargetAlign = "bottom";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (targetTop !== null) syncScrollTop(targetTop);
|
|
62
|
+
if (targetTop !== syncState.value.lastTop) needCollectHeight = true;
|
|
63
|
+
}
|
|
64
|
+
if (needCollectHeight) syncState.value = {
|
|
65
|
+
...syncState.value,
|
|
66
|
+
times: syncState.value.times + 1,
|
|
67
|
+
targetAlign: newTargetAlign,
|
|
68
|
+
lastTop: targetTop
|
|
69
|
+
};
|
|
70
|
+
} else if (process.env.NODE_ENV !== "production" && syncState.value?.times === MAX_TIMES) (0, __v_c_util.warning)(false, "Seems `scrollTo` with `rc-virtual-list` reach the max limitation. Please fire issue for us. Thanks.");
|
|
71
|
+
}, {
|
|
72
|
+
immediate: true,
|
|
73
|
+
flush: "post"
|
|
74
|
+
});
|
|
75
|
+
return (arg) => {
|
|
76
|
+
if (arg === null || arg === void 0) {
|
|
77
|
+
triggerFlash();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
__v_c_util_dist_raf.default.cancel(scrollRef.value);
|
|
81
|
+
if (typeof arg === "number") syncScrollTop(arg);
|
|
82
|
+
else if (arg && typeof arg === "object") {
|
|
83
|
+
let index;
|
|
84
|
+
const { align } = arg;
|
|
85
|
+
if ("index" in arg) ({index} = arg);
|
|
86
|
+
else index = data.value.findIndex((item) => getKey(item) === arg.key);
|
|
87
|
+
const { offset = 0 } = arg;
|
|
88
|
+
syncState.value = {
|
|
89
|
+
times: 0,
|
|
90
|
+
index,
|
|
91
|
+
offset,
|
|
92
|
+
originAlign: align
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
exports.default = useScrollTo;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Key } from '@v-c/util/dist/type';
|
|
2
|
+
import { Ref } from 'vue';
|
|
3
|
+
import { GetKey } from '../interface.ts';
|
|
4
|
+
import { default as CacheMap } from '../utils/CacheMap.ts';
|
|
5
|
+
export type ScrollAlign = 'top' | 'bottom' | 'auto';
|
|
6
|
+
export interface ScrollPos {
|
|
7
|
+
left?: number;
|
|
8
|
+
top?: number;
|
|
9
|
+
}
|
|
10
|
+
export type ScrollTarget = {
|
|
11
|
+
index: number;
|
|
12
|
+
align?: ScrollAlign;
|
|
13
|
+
offset?: number;
|
|
14
|
+
} | {
|
|
15
|
+
key: Key;
|
|
16
|
+
align?: ScrollAlign;
|
|
17
|
+
offset?: number;
|
|
18
|
+
};
|
|
19
|
+
export default function useScrollTo(containerRef: Ref<HTMLDivElement>, data: Ref<any[]>, heights: CacheMap, itemHeight: Ref<number>, getKey: GetKey<any>, collectHeight: () => void, syncScrollTop: (newTop: number) => void, triggerFlash: () => void): (arg: number | ScrollTarget) => void;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { shallowRef, watch } from "vue";
|
|
2
|
+
import { warning } from "@v-c/util";
|
|
3
|
+
import raf from "@v-c/util/dist/raf";
|
|
4
|
+
var MAX_TIMES = 10;
|
|
5
|
+
function useScrollTo(containerRef, data, heights, itemHeight, getKey, collectHeight, syncScrollTop, triggerFlash) {
|
|
6
|
+
const scrollRef = shallowRef();
|
|
7
|
+
const syncState = shallowRef(null);
|
|
8
|
+
watch([syncState, containerRef], () => {
|
|
9
|
+
if (syncState.value && syncState.value.times < MAX_TIMES) {
|
|
10
|
+
if (!containerRef.value) {
|
|
11
|
+
syncState.value = { ...syncState.value };
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
collectHeight();
|
|
15
|
+
const { targetAlign, originAlign, index, offset } = syncState.value;
|
|
16
|
+
const height = containerRef.value.clientHeight;
|
|
17
|
+
let needCollectHeight = false;
|
|
18
|
+
let newTargetAlign = targetAlign ?? null;
|
|
19
|
+
let targetTop = null;
|
|
20
|
+
if (height) {
|
|
21
|
+
const mergedAlign = targetAlign || originAlign;
|
|
22
|
+
let stackTop = 0;
|
|
23
|
+
let itemTop = 0;
|
|
24
|
+
let itemBottom = 0;
|
|
25
|
+
const maxLen = Math.min(data.value.length - 1, index);
|
|
26
|
+
for (let i = 0; i <= maxLen; i += 1) {
|
|
27
|
+
const key = getKey(data.value[i]);
|
|
28
|
+
itemTop = stackTop;
|
|
29
|
+
const cacheHeight = heights.get(key);
|
|
30
|
+
itemBottom = itemTop + (cacheHeight === void 0 ? itemHeight.value : cacheHeight);
|
|
31
|
+
stackTop = itemBottom;
|
|
32
|
+
}
|
|
33
|
+
let leftHeight = mergedAlign === "top" ? offset : height - offset;
|
|
34
|
+
for (let i = maxLen; i >= 0; i -= 1) {
|
|
35
|
+
const key = getKey(data.value[i]);
|
|
36
|
+
const cacheHeight = heights.get(key);
|
|
37
|
+
if (cacheHeight === void 0) {
|
|
38
|
+
needCollectHeight = true;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
leftHeight -= cacheHeight;
|
|
42
|
+
if (leftHeight <= 0) break;
|
|
43
|
+
}
|
|
44
|
+
switch (mergedAlign) {
|
|
45
|
+
case "top":
|
|
46
|
+
targetTop = itemTop - offset;
|
|
47
|
+
break;
|
|
48
|
+
case "bottom":
|
|
49
|
+
targetTop = itemBottom - height + offset;
|
|
50
|
+
break;
|
|
51
|
+
default: {
|
|
52
|
+
const { scrollTop } = containerRef.value;
|
|
53
|
+
const scrollBottom = scrollTop + height;
|
|
54
|
+
if (itemTop < scrollTop) newTargetAlign = "top";
|
|
55
|
+
else if (itemBottom > scrollBottom) newTargetAlign = "bottom";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (targetTop !== null) syncScrollTop(targetTop);
|
|
59
|
+
if (targetTop !== syncState.value.lastTop) needCollectHeight = true;
|
|
60
|
+
}
|
|
61
|
+
if (needCollectHeight) syncState.value = {
|
|
62
|
+
...syncState.value,
|
|
63
|
+
times: syncState.value.times + 1,
|
|
64
|
+
targetAlign: newTargetAlign,
|
|
65
|
+
lastTop: targetTop
|
|
66
|
+
};
|
|
67
|
+
} else if (process.env.NODE_ENV !== "production" && syncState.value?.times === MAX_TIMES) warning(false, "Seems `scrollTo` with `rc-virtual-list` reach the max limitation. Please fire issue for us. Thanks.");
|
|
68
|
+
}, {
|
|
69
|
+
immediate: true,
|
|
70
|
+
flush: "post"
|
|
71
|
+
});
|
|
72
|
+
return (arg) => {
|
|
73
|
+
if (arg === null || arg === void 0) {
|
|
74
|
+
triggerFlash();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
raf.cancel(scrollRef.value);
|
|
78
|
+
if (typeof arg === "number") syncScrollTop(arg);
|
|
79
|
+
else if (arg && typeof arg === "object") {
|
|
80
|
+
let index;
|
|
81
|
+
const { align } = arg;
|
|
82
|
+
if ("index" in arg) ({index} = arg);
|
|
83
|
+
else index = data.value.findIndex((item) => getKey(item) === arg.key);
|
|
84
|
+
const { offset = 0 } = arg;
|
|
85
|
+
syncState.value = {
|
|
86
|
+
times: 0,
|
|
87
|
+
index,
|
|
88
|
+
offset,
|
|
89
|
+
originAlign: align
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export { useScrollTo as default };
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2
|
+
const require_List = require("./List.cjs");
|
|
3
|
+
var src_default = require_List.default;
|
|
4
|
+
exports.default = src_default;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
1
|
+
import List_default from "./List.js";
|
|
2
|
+
var src_default = List_default;
|
|
3
|
+
export { src_default as default };
|
package/dist/interface.cjs
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|
package/dist/interface.d.ts
CHANGED
package/dist/interface.js
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
package/dist/utils/CacheMap.cjs
CHANGED
|
@@ -1 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2
|
+
var CacheMap = class {
|
|
3
|
+
maps;
|
|
4
|
+
id = 0;
|
|
5
|
+
diffRecords = /* @__PURE__ */ new Map();
|
|
6
|
+
constructor() {
|
|
7
|
+
this.maps = Object.create(null);
|
|
8
|
+
}
|
|
9
|
+
set(key, value) {
|
|
10
|
+
this.diffRecords.set(key, this.maps[key]);
|
|
11
|
+
this.maps[key] = value;
|
|
12
|
+
this.id += 1;
|
|
13
|
+
}
|
|
14
|
+
get(key) {
|
|
15
|
+
return this.maps[key];
|
|
16
|
+
}
|
|
17
|
+
resetRecord() {
|
|
18
|
+
this.diffRecords.clear();
|
|
19
|
+
}
|
|
20
|
+
getRecord() {
|
|
21
|
+
return this.diffRecords;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
var CacheMap_default = CacheMap;
|
|
25
|
+
exports.default = CacheMap_default;
|
package/dist/utils/CacheMap.d.ts
CHANGED
package/dist/utils/CacheMap.js
CHANGED
|
@@ -1,29 +1,24 @@
|
|
|
1
|
-
class
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
getRecord() {
|
|
24
|
-
return this.diffRecords;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
export {
|
|
28
|
-
r as default
|
|
1
|
+
var CacheMap = class {
|
|
2
|
+
maps;
|
|
3
|
+
id = 0;
|
|
4
|
+
diffRecords = /* @__PURE__ */ new Map();
|
|
5
|
+
constructor() {
|
|
6
|
+
this.maps = Object.create(null);
|
|
7
|
+
}
|
|
8
|
+
set(key, value) {
|
|
9
|
+
this.diffRecords.set(key, this.maps[key]);
|
|
10
|
+
this.maps[key] = value;
|
|
11
|
+
this.id += 1;
|
|
12
|
+
}
|
|
13
|
+
get(key) {
|
|
14
|
+
return this.maps[key];
|
|
15
|
+
}
|
|
16
|
+
resetRecord() {
|
|
17
|
+
this.diffRecords.clear();
|
|
18
|
+
}
|
|
19
|
+
getRecord() {
|
|
20
|
+
return this.diffRecords;
|
|
21
|
+
}
|
|
29
22
|
};
|
|
23
|
+
var CacheMap_default = CacheMap;
|
|
24
|
+
export { CacheMap_default as default };
|
package/dist/utils/isFirefox.cjs
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2
|
+
var isFF = typeof navigator === "object" && /Firefox/i.test(navigator.userAgent);
|
|
3
|
+
var isFirefox_default = isFF;
|
|
4
|
+
exports.default = isFirefox_default;
|
package/dist/utils/isFirefox.js
CHANGED
|
@@ -1 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
var MIN_SIZE = 20;
|
|
2
|
+
function getSpinSize(containerSize = 0, scrollRange = 0) {
|
|
3
|
+
let baseSize = containerSize / scrollRange * containerSize;
|
|
4
|
+
if (isNaN(baseSize)) baseSize = 0;
|
|
5
|
+
baseSize = Math.max(baseSize, MIN_SIZE);
|
|
6
|
+
return Math.floor(baseSize);
|
|
7
|
+
}
|
|
8
|
+
exports.getSpinSize = getSpinSize;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
var MIN_SIZE = 20;
|
|
2
|
+
function getSpinSize(containerSize = 0, scrollRange = 0) {
|
|
3
|
+
let baseSize = containerSize / scrollRange * containerSize;
|
|
4
|
+
if (isNaN(baseSize)) baseSize = 0;
|
|
5
|
+
baseSize = Math.max(baseSize, MIN_SIZE);
|
|
6
|
+
return Math.floor(baseSize);
|
|
4
7
|
}
|
|
5
|
-
export {
|
|
6
|
-
i as getSpinSize
|
|
7
|
-
};
|
|
8
|
+
export { getSpinSize };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
.motion {
|
|
2
|
+
transition: all 0.3s;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.item {
|
|
6
|
+
display: inline-block;
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
margin: 0;
|
|
9
|
+
padding: 0 16px;
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
line-height: 31px;
|
|
12
|
+
position: relative;
|
|
13
|
+
|
|
14
|
+
&:hover {
|
|
15
|
+
background: rgba(255, 0, 0, 0.1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
&::after {
|
|
19
|
+
content: '';
|
|
20
|
+
border-bottom: 1px solid gray;
|
|
21
|
+
position: absolute;
|
|
22
|
+
bottom: 0;
|
|
23
|
+
left: 0;
|
|
24
|
+
right: 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
button {
|
|
28
|
+
vertical-align: text-top;
|
|
29
|
+
margin-right: 8px;
|
|
30
|
+
}
|
|
31
|
+
}
|