@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.
Files changed (66) hide show
  1. package/bump.config.ts +6 -0
  2. package/dist/Filler.cjs +51 -1
  3. package/dist/Filler.js +47 -56
  4. package/dist/Item.cjs +26 -1
  5. package/dist/Item.js +23 -26
  6. package/dist/List.cjs +408 -1
  7. package/dist/List.d.ts +45 -9
  8. package/dist/List.js +403 -274
  9. package/dist/ScrollBar.cjs +259 -1
  10. package/dist/ScrollBar.d.ts +3 -97
  11. package/dist/ScrollBar.js +254 -191
  12. package/dist/_virtual/rolldown_runtime.cjs +21 -0
  13. package/dist/hooks/useDiffItem.cjs +19 -1
  14. package/dist/hooks/useDiffItem.js +16 -20
  15. package/dist/hooks/useFrameWheel.cjs +63 -1
  16. package/dist/hooks/useFrameWheel.js +60 -51
  17. package/dist/hooks/useGetSize.cjs +29 -1
  18. package/dist/hooks/useGetSize.d.ts +2 -2
  19. package/dist/hooks/useGetSize.js +27 -23
  20. package/dist/hooks/useHeights.cjs +66 -1
  21. package/dist/hooks/useHeights.d.ts +1 -1
  22. package/dist/hooks/useHeights.js +62 -41
  23. package/dist/hooks/useMobileTouchMove.cjs +82 -1
  24. package/dist/hooks/useMobileTouchMove.js +79 -43
  25. package/dist/hooks/useOriginScroll.cjs +23 -1
  26. package/dist/hooks/useOriginScroll.js +20 -16
  27. package/dist/hooks/useScrollDrag.cjs +83 -1
  28. package/dist/hooks/useScrollDrag.js +77 -48
  29. package/dist/hooks/useScrollTo.cjs +97 -0
  30. package/dist/hooks/useScrollTo.d.ts +19 -0
  31. package/dist/hooks/useScrollTo.js +94 -0
  32. package/dist/index.cjs +4 -1
  33. package/dist/index.d.ts +1 -1
  34. package/dist/index.js +3 -4
  35. package/dist/interface.cjs +0 -1
  36. package/dist/interface.d.ts +1 -1
  37. package/dist/interface.js +0 -1
  38. package/dist/utils/CacheMap.cjs +25 -1
  39. package/dist/utils/CacheMap.d.ts +1 -1
  40. package/dist/utils/CacheMap.js +23 -28
  41. package/dist/utils/isFirefox.cjs +4 -1
  42. package/dist/utils/isFirefox.js +2 -4
  43. package/dist/utils/scrollbarUtil.cjs +8 -1
  44. package/dist/utils/scrollbarUtil.js +7 -6
  45. package/docs/animate.less +31 -0
  46. package/docs/animate.vue +159 -0
  47. package/docs/basic.vue +2 -1
  48. package/docs/nest.vue +1 -1
  49. package/docs/switch.vue +2 -1
  50. package/docs/virtual-list.stories.vue +4 -0
  51. package/package.json +16 -14
  52. package/src/Filler.tsx +2 -1
  53. package/src/Item.tsx +2 -1
  54. package/src/List.tsx +189 -124
  55. package/src/ScrollBar.tsx +33 -44
  56. package/src/hooks/useDiffItem.ts +3 -2
  57. package/src/hooks/useFrameWheel.ts +2 -1
  58. package/src/hooks/useGetSize.ts +5 -4
  59. package/src/hooks/useHeights.ts +7 -6
  60. package/src/hooks/useMobileTouchMove.ts +2 -1
  61. package/src/hooks/useOriginScroll.ts +2 -1
  62. package/src/hooks/useScrollDrag.ts +2 -1
  63. package/src/hooks/useScrollTo.tsx +184 -0
  64. package/src/index.ts +1 -1
  65. package/tsconfig.json +7 -0
  66. package/vitest.config.ts +1 -1
@@ -1 +1,259 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("vue");function L(e,c){return("touches"in e?e.touches[0]:e)[c?"pageX":"pageY"]-window[c?"scrollX":"scrollY"]}const C=t.defineComponent({name:"ScrollBar",props:{prefixCls:{type:String,required:!0},scrollOffset:{type:Number,required:!0},scrollRange:{type:Number,required:!0},rtl:{type:Boolean,default:!1},onScroll:{type:Function,required:!0},onStartMove:{type:Function,required:!0},onStopMove:{type:Function,required:!0},horizontal:{type:Boolean,default:!1},style:Object,thumbStyle:Object,spinSize:{type:Number,required:!0},containerSize:{type:Number,required:!0},showScrollBar:{type:[Boolean,String]}},setup(e,{expose:c}){const a=t.ref(!1),v=t.ref(null),d=t.ref(null),h=t.computed(()=>!e.rtl),g=t.shallowRef(),y=t.shallowRef(),f=t.ref(e.showScrollBar==="optional"?!0:e.showScrollBar);let i=null;const m=()=>{e.showScrollBar===!0||e.showScrollBar===!1||(i&&clearTimeout(i),f.value=!0,i=setTimeout(()=>{f.value=!1},3e3))},b=t.computed(()=>e.scrollRange-e.containerSize||0),M=t.computed(()=>e.containerSize-e.spinSize||0),u=t.computed(()=>e.scrollOffset===0||b.value===0?0:e.scrollOffset/b.value*M.value),w=t.shallowRef({top:u.value,dragging:a.value,pageY:v.value,startTop:d.value});t.watch([u,a,v,d],()=>{w.value={top:u.value,dragging:a.value,pageY:v.value,startTop:d.value}});const O=o=>{o.stopPropagation(),o.preventDefault()},S=o=>{a.value=!0,v.value=L(o,e.horizontal||!1),d.value=w.value.top,e.onStartMove(),o.stopPropagation(),o.preventDefault()};return t.onMounted(()=>{const o=r=>{r.preventDefault()},n=g.value,l=y.value;n&&l&&(n.addEventListener("touchstart",o,{passive:!1}),l.addEventListener("touchstart",S,{passive:!1}),t.onUnmounted(()=>{n.removeEventListener("touchstart",o),l.removeEventListener("touchstart",S)}))}),t.watch(a,o=>{if(o){let n=null;const l=x=>{const{dragging:B,pageY:q,startTop:$}=w.value;n&&cancelAnimationFrame(n);const z=g.value.getBoundingClientRect(),j=e.containerSize/(e.horizontal?z.width:z.height);if(B){const E=(L(x,e.horizontal||!1)-(q||0))*j;let p=$||0;!h.value&&e.horizontal?p-=E:p+=E;const R=b.value,T=M.value,Y=T?p/T:0;let s=Math.ceil(Y*R);s=Math.max(s,0),s=Math.min(s,R),n=requestAnimationFrame(()=>{e.onScroll(s,e.horizontal)})}},r=()=>{a.value=!1,e.onStopMove()};window.addEventListener("mousemove",l,{passive:!0}),window.addEventListener("touchmove",l,{passive:!0}),window.addEventListener("mouseup",r,{passive:!0}),window.addEventListener("touchend",r,{passive:!0}),t.onUnmounted(()=>{window.removeEventListener("mousemove",l),window.removeEventListener("touchmove",l),window.removeEventListener("mouseup",r),window.removeEventListener("touchend",r),n&&cancelAnimationFrame(n)})}}),t.watch(()=>e.scrollOffset,()=>{m()}),t.onUnmounted(()=>{i&&clearTimeout(i)}),c({delayHidden:m}),()=>{const o=`${e.prefixCls}-scrollbar`,n={position:"absolute",visibility:f.value?void 0:"hidden"},l={position:"absolute",borderRadius:"99px",background:"var(--vc-virtual-list-scrollbar-bg, rgba(0, 0, 0, 0.5))",cursor:"pointer",userSelect:"none"};return e.horizontal?(Object.assign(n,{height:"8px",left:0,right:0,bottom:0}),Object.assign(l,{height:"100%",width:`${e.spinSize}px`,[h.value?"left":"right"]:`${u.value}px`})):(Object.assign(n,{width:"8px",top:0,bottom:0,[h.value?"right":"left"]:0}),Object.assign(l,{width:"100%",height:`${e.spinSize}px`,top:`${u.value}px`})),t.createVNode("div",{ref:g,class:[o,{[`${o}-horizontal`]:e.horizontal,[`${o}-vertical`]:!e.horizontal,[`${o}-visible`]:f.value}],style:{...n,...e.style},onMousedown:O,onMousemove:m},[t.createVNode("div",{ref:y,class:[`${o}-thumb`,{[`${o}-thumb-moving`]:a.value}],style:{...l,...e.thumbStyle},onMousedown:S},null)])}}});exports.default=C;
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_dist_raf = require("@v-c/util/dist/raf");
5
+ __v_c_util_dist_raf = require_rolldown_runtime.__toESM(__v_c_util_dist_raf);
6
+ function getPageXY(e, horizontal) {
7
+ return ("touches" in e ? e.touches[0] : e)[horizontal ? "pageX" : "pageY"] - window[horizontal ? "scrollX" : "scrollY"];
8
+ }
9
+ var ScrollBar_default = /* @__PURE__ */ (0, vue.defineComponent)({
10
+ props: {
11
+ prefixCls: {
12
+ type: String,
13
+ required: true,
14
+ default: void 0
15
+ },
16
+ scrollOffset: {
17
+ type: Number,
18
+ required: true,
19
+ default: void 0
20
+ },
21
+ scrollRange: {
22
+ type: Number,
23
+ required: true,
24
+ default: void 0
25
+ },
26
+ rtl: {
27
+ type: Boolean,
28
+ required: true,
29
+ default: void 0
30
+ },
31
+ onScroll: {
32
+ type: Function,
33
+ required: true,
34
+ default: void 0
35
+ },
36
+ onStartMove: {
37
+ type: Function,
38
+ required: true,
39
+ default: void 0
40
+ },
41
+ onStopMove: {
42
+ type: Function,
43
+ required: true,
44
+ default: void 0
45
+ },
46
+ horizontal: {
47
+ type: Boolean,
48
+ required: false,
49
+ default: void 0
50
+ },
51
+ style: {
52
+ type: Object,
53
+ required: false,
54
+ default: void 0
55
+ },
56
+ thumbStyle: {
57
+ type: Object,
58
+ required: false,
59
+ default: void 0
60
+ },
61
+ spinSize: {
62
+ type: Number,
63
+ required: true,
64
+ default: void 0
65
+ },
66
+ containerSize: {
67
+ type: Number,
68
+ required: true,
69
+ default: void 0
70
+ },
71
+ showScrollBar: {
72
+ type: [Boolean, String],
73
+ required: false,
74
+ default: void 0
75
+ }
76
+ },
77
+ name: "ScrollBar",
78
+ setup(props, { expose }) {
79
+ const dragging = (0, vue.ref)(false);
80
+ const pageXY = (0, vue.ref)(null);
81
+ const startTop = (0, vue.ref)(null);
82
+ const isLTR = (0, vue.computed)(() => !props.rtl);
83
+ const scrollbarRef = (0, vue.shallowRef)();
84
+ const thumbRef = (0, vue.shallowRef)();
85
+ const visible = (0, vue.ref)(props.showScrollBar === "optional" ? true : props.showScrollBar);
86
+ let visibleTimeout = null;
87
+ const delayHidden = () => {
88
+ if (props.showScrollBar === true || props.showScrollBar === false) return;
89
+ if (visibleTimeout) clearTimeout(visibleTimeout);
90
+ visible.value = true;
91
+ visibleTimeout = setTimeout(() => {
92
+ visible.value = false;
93
+ }, 3e3);
94
+ };
95
+ const enableScrollRange = (0, vue.computed)(() => props.scrollRange - props.containerSize || 0);
96
+ const enableOffsetRange = (0, vue.computed)(() => props.containerSize - props.spinSize || 0);
97
+ const top = (0, vue.computed)(() => {
98
+ if (props.scrollOffset === 0 || enableScrollRange.value === 0) return 0;
99
+ return props.scrollOffset / enableScrollRange.value * enableOffsetRange.value;
100
+ });
101
+ const stateRef = (0, vue.shallowRef)({
102
+ top: top.value,
103
+ dragging: dragging.value,
104
+ pageY: pageXY.value,
105
+ startTop: startTop.value
106
+ });
107
+ (0, vue.watch)([
108
+ top,
109
+ dragging,
110
+ pageXY,
111
+ startTop
112
+ ], () => {
113
+ stateRef.value = {
114
+ top: top.value,
115
+ dragging: dragging.value,
116
+ pageY: pageXY.value,
117
+ startTop: startTop.value
118
+ };
119
+ });
120
+ const onContainerMouseDown = (e) => {
121
+ e.stopPropagation();
122
+ e.preventDefault();
123
+ };
124
+ const onThumbMouseDown = (e) => {
125
+ dragging.value = true;
126
+ pageXY.value = getPageXY(e, props.horizontal || false);
127
+ startTop.value = stateRef.value.top;
128
+ props?.onStartMove?.();
129
+ e.stopPropagation();
130
+ e.preventDefault();
131
+ };
132
+ (0, vue.onMounted)(() => {
133
+ const onScrollbarTouchStart = (e) => {
134
+ e.preventDefault();
135
+ };
136
+ const scrollbarEle = scrollbarRef.value;
137
+ const thumbEle = thumbRef.value;
138
+ if (scrollbarEle && thumbEle) {
139
+ scrollbarEle.addEventListener("touchstart", onScrollbarTouchStart, { passive: false });
140
+ thumbEle.addEventListener("touchstart", onThumbMouseDown, { passive: false });
141
+ (0, vue.onUnmounted)(() => {
142
+ scrollbarEle.removeEventListener("touchstart", onScrollbarTouchStart);
143
+ thumbEle.removeEventListener("touchstart", onThumbMouseDown);
144
+ });
145
+ }
146
+ });
147
+ (0, vue.watch)(dragging, (isDragging, _O, onCleanup) => {
148
+ if (isDragging) {
149
+ let moveRafId = null;
150
+ const onMouseMove = (e) => {
151
+ const { dragging: stateDragging, pageY: statePageY, startTop: stateStartTop } = stateRef.value;
152
+ __v_c_util_dist_raf.default.cancel(moveRafId);
153
+ const rect = scrollbarRef.value.getBoundingClientRect();
154
+ const scale = props.containerSize / (props.horizontal ? rect.width : rect.height);
155
+ if (stateDragging) {
156
+ const offset = (getPageXY(e, props.horizontal || false) - (statePageY || 0)) * scale;
157
+ let newTop = stateStartTop || 0;
158
+ if (!isLTR.value && props.horizontal) newTop -= offset;
159
+ else newTop += offset;
160
+ const tmpEnableScrollRange = enableScrollRange.value;
161
+ const tmpEnableOffsetRange = enableOffsetRange.value;
162
+ const ptg = tmpEnableOffsetRange ? newTop / tmpEnableOffsetRange : 0;
163
+ let newScrollTop = Math.ceil(ptg * tmpEnableScrollRange);
164
+ newScrollTop = Math.max(newScrollTop, 0);
165
+ newScrollTop = Math.min(newScrollTop, tmpEnableScrollRange);
166
+ moveRafId = (0, __v_c_util_dist_raf.default)(() => {
167
+ props?.onScroll?.(newScrollTop, props.horizontal);
168
+ });
169
+ }
170
+ };
171
+ const onMouseUp = () => {
172
+ dragging.value = false;
173
+ props.onStopMove();
174
+ };
175
+ window.addEventListener("mousemove", onMouseMove, { passive: true });
176
+ window.addEventListener("touchmove", onMouseMove, { passive: true });
177
+ window.addEventListener("mouseup", onMouseUp, { passive: true });
178
+ window.addEventListener("touchend", onMouseUp, { passive: true });
179
+ onCleanup(() => {
180
+ window.removeEventListener("mousemove", onMouseMove);
181
+ window.removeEventListener("touchmove", onMouseMove);
182
+ window.removeEventListener("mouseup", onMouseUp);
183
+ window.removeEventListener("touchend", onMouseUp);
184
+ __v_c_util_dist_raf.default.cancel(moveRafId);
185
+ });
186
+ }
187
+ });
188
+ (0, vue.watch)(() => props.scrollOffset, (_n, _o, onCleanup) => {
189
+ delayHidden();
190
+ onCleanup(() => {
191
+ if (visibleTimeout) clearTimeout(visibleTimeout);
192
+ });
193
+ });
194
+ expose({ delayHidden });
195
+ return () => {
196
+ const { prefixCls, horizontal } = props;
197
+ const scrollbarPrefixCls = `${prefixCls}-scrollbar`;
198
+ const containerStyle = {
199
+ position: "absolute",
200
+ visibility: visible.value ? void 0 : "hidden"
201
+ };
202
+ const thumbStyle = {
203
+ position: "absolute",
204
+ borderRadius: "99px",
205
+ background: "var(--vc-virtual-list-scrollbar-bg, rgba(0, 0, 0, 0.5))",
206
+ cursor: "pointer",
207
+ userSelect: "none"
208
+ };
209
+ if (props.horizontal) {
210
+ Object.assign(containerStyle, {
211
+ height: "8px",
212
+ left: 0,
213
+ right: 0,
214
+ bottom: 0
215
+ });
216
+ Object.assign(thumbStyle, {
217
+ height: "100%",
218
+ width: `${props.spinSize}px`,
219
+ [isLTR.value ? "left" : "right"]: `${top.value}px`
220
+ });
221
+ } else {
222
+ Object.assign(containerStyle, {
223
+ width: "8px",
224
+ top: 0,
225
+ bottom: 0,
226
+ [isLTR.value ? "right" : "left"]: 0
227
+ });
228
+ Object.assign(thumbStyle, {
229
+ width: "100%",
230
+ height: `${props.spinSize}px`,
231
+ top: `${top.value}px`
232
+ });
233
+ }
234
+ return (0, vue.createVNode)("div", {
235
+ "ref": scrollbarRef,
236
+ "class": [scrollbarPrefixCls, {
237
+ [`${scrollbarPrefixCls}-horizontal`]: horizontal,
238
+ [`${scrollbarPrefixCls}-vertical`]: !horizontal,
239
+ [`${scrollbarPrefixCls}-visible`]: visible.value
240
+ }],
241
+ "style": {
242
+ ...containerStyle,
243
+ ...props.style
244
+ },
245
+ "onMousedown": onContainerMouseDown,
246
+ "onMousemove": delayHidden
247
+ }, [(0, vue.createVNode)("div", {
248
+ "ref": thumbRef,
249
+ "class": [`${scrollbarPrefixCls}-thumb`, { [`${scrollbarPrefixCls}-thumb-moving`]: dragging.value }],
250
+ "style": {
251
+ ...thumbStyle,
252
+ ...props.thumbStyle
253
+ },
254
+ "onMousedown": onThumbMouseDown
255
+ }, null)]);
256
+ };
257
+ }
258
+ });
259
+ exports.default = ScrollBar_default;
@@ -1,4 +1,5 @@
1
- import { CSSProperties, PropType } from 'vue';
1
+ import { CSSProperties } from 'vue';
2
+ export type ScrollBarDirectionType = 'ltr' | 'rtl';
2
3
  export interface ScrollBarProps {
3
4
  prefixCls: string;
4
5
  scrollOffset: number;
@@ -17,100 +18,5 @@ export interface ScrollBarProps {
17
18
  export interface ScrollBarRef {
18
19
  delayHidden: () => void;
19
20
  }
20
- declare const _default: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
21
- prefixCls: {
22
- type: StringConstructor;
23
- required: true;
24
- };
25
- scrollOffset: {
26
- type: NumberConstructor;
27
- required: true;
28
- };
29
- scrollRange: {
30
- type: NumberConstructor;
31
- required: true;
32
- };
33
- rtl: {
34
- type: BooleanConstructor;
35
- default: boolean;
36
- };
37
- onScroll: {
38
- type: PropType<(scrollOffset: number, horizontal?: boolean) => void>;
39
- required: true;
40
- };
41
- onStartMove: {
42
- type: PropType<() => void>;
43
- required: true;
44
- };
45
- onStopMove: {
46
- type: PropType<() => void>;
47
- required: true;
48
- };
49
- horizontal: {
50
- type: BooleanConstructor;
51
- default: boolean;
52
- };
53
- style: PropType<CSSProperties>;
54
- thumbStyle: PropType<CSSProperties>;
55
- spinSize: {
56
- type: NumberConstructor;
57
- required: true;
58
- };
59
- containerSize: {
60
- type: NumberConstructor;
61
- required: true;
62
- };
63
- showScrollBar: {
64
- type: PropType<boolean | "optional">;
65
- };
66
- }>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
67
- prefixCls: {
68
- type: StringConstructor;
69
- required: true;
70
- };
71
- scrollOffset: {
72
- type: NumberConstructor;
73
- required: true;
74
- };
75
- scrollRange: {
76
- type: NumberConstructor;
77
- required: true;
78
- };
79
- rtl: {
80
- type: BooleanConstructor;
81
- default: boolean;
82
- };
83
- onScroll: {
84
- type: PropType<(scrollOffset: number, horizontal?: boolean) => void>;
85
- required: true;
86
- };
87
- onStartMove: {
88
- type: PropType<() => void>;
89
- required: true;
90
- };
91
- onStopMove: {
92
- type: PropType<() => void>;
93
- required: true;
94
- };
95
- horizontal: {
96
- type: BooleanConstructor;
97
- default: boolean;
98
- };
99
- style: PropType<CSSProperties>;
100
- thumbStyle: PropType<CSSProperties>;
101
- spinSize: {
102
- type: NumberConstructor;
103
- required: true;
104
- };
105
- containerSize: {
106
- type: NumberConstructor;
107
- required: true;
108
- };
109
- showScrollBar: {
110
- type: PropType<boolean | "optional">;
111
- };
112
- }>> & Readonly<{}>, {
113
- rtl: boolean;
114
- horizontal: boolean;
115
- }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
21
+ declare const _default: import('vue').DefineComponent<ScrollBarProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<ScrollBarProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
116
22
  export default _default;