@pdanpdan/virtual-scroll 0.9.1 → 0.10.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/README.md +82 -4
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +170 -153
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +833 -692
- package/dist/index.mjs.map +1 -1
- package/dist/virtual-scroll.css +1 -1
- package/package.json +1 -1
- package/src/components/VirtualScroll.vue +30 -20
- package/src/composables/useVirtualScroll.ts +365 -804
- package/src/composables/useVirtualScrollSizes.ts +28 -37
- package/src/composables/useVirtualScrollbar.ts +16 -0
- package/src/extensions/all.ts +7 -0
- package/src/extensions/coordinate-scaling.ts +30 -0
- package/src/extensions/index.ts +88 -0
- package/src/extensions/infinite-loading.ts +47 -0
- package/src/extensions/prepend-restoration.ts +49 -0
- package/src/extensions/rtl.ts +42 -0
- package/src/extensions/snapping.ts +82 -0
- package/src/extensions/sticky.ts +43 -0
- package/src/types.ts +27 -7
- package/src/utils/scroll.ts +1 -1
- package/src/utils/virtual-scroll-logic.ts +33 -0
package/dist/virtual-scroll.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
@layer components{.virtual-scrollbar-track{--vsi-scrollbar-bg:var(--vs-scrollbar-bg,light-dark(#e6e6e6e6,#1e1e1ee6));--vsi-scrollbar-thumb-bg:var(--vs-scrollbar-thumb-bg,light-dark(#0000004d,#ffffff4d));--vsi-scrollbar-thumb-hover-bg:var(--vs-scrollbar-thumb-hover-bg,light-dark(#0009,#fff9));--vsi-scrollbar-radius:var(--vs-scrollbar-radius,4px);--vsi-scrollbar-size:var(--vs-scrollbar-size,8px);contain:layout;background-color:var(--vsi-scrollbar-bg);border-radius:var(--vsi-scrollbar-radius);z-index:30;-webkit-user-select:none;user-select:none;pointer-events:auto;transition:opacity .2s;position:absolute}.virtual-scrollbar-track.virtual-scrollbar-track--vertical{inline-size:var(--vsi-scrollbar-size);inset-block-start:2px;inset-inline-end:2px}.virtual-scrollbar-track.virtual-scrollbar-track--horizontal{block-size:var(--vsi-scrollbar-size);inset-block-end:2px;inset-inline-start:2px}.virtual-scrollbar-thumb{background-color:var(--vsi-scrollbar-thumb-bg);border-radius:var(--vsi-scrollbar-radius);touch-action:none;pointer-events:auto;cursor:pointer;position:absolute}.virtual-scrollbar-thumb:hover,.virtual-scrollbar-thumb:active,.virtual-scrollbar-thumb.virtual-scrollbar-thumb--active{background-color:var(--vsi-scrollbar-thumb-hover-bg)}.virtual-scrollbar-thumb.virtual-scrollbar-thumb--vertical{inline-size:100%}.virtual-scrollbar-thumb.virtual-scrollbar-thumb--horizontal{block-size:100%}.virtual-scroll-container[data-v-
|
|
1
|
+
@layer components{.virtual-scrollbar-track{--vsi-scrollbar-bg:var(--vs-scrollbar-bg,light-dark(#e6e6e6e6,#1e1e1ee6));--vsi-scrollbar-thumb-bg:var(--vs-scrollbar-thumb-bg,light-dark(#0000004d,#ffffff4d));--vsi-scrollbar-thumb-hover-bg:var(--vs-scrollbar-thumb-hover-bg,light-dark(#0009,#fff9));--vsi-scrollbar-radius:var(--vs-scrollbar-radius,4px);--vsi-scrollbar-size:var(--vs-scrollbar-size,8px);contain:layout;background-color:var(--vsi-scrollbar-bg);border-radius:var(--vsi-scrollbar-radius);z-index:30;-webkit-user-select:none;user-select:none;pointer-events:auto;transition:opacity .2s;position:absolute}.virtual-scrollbar-track.virtual-scrollbar-track--vertical{inline-size:var(--vsi-scrollbar-size);inset-block-start:2px;inset-inline-end:2px}.virtual-scrollbar-track.virtual-scrollbar-track--horizontal{block-size:var(--vsi-scrollbar-size);inset-block-end:2px;inset-inline-start:2px}.virtual-scrollbar-thumb{background-color:var(--vsi-scrollbar-thumb-bg);border-radius:var(--vsi-scrollbar-radius);touch-action:none;pointer-events:auto;cursor:pointer;position:absolute}.virtual-scrollbar-thumb:hover,.virtual-scrollbar-thumb:active,.virtual-scrollbar-thumb.virtual-scrollbar-thumb--active{background-color:var(--vsi-scrollbar-thumb-hover-bg)}.virtual-scrollbar-thumb.virtual-scrollbar-thumb--vertical{inline-size:100%}.virtual-scrollbar-thumb.virtual-scrollbar-thumb--horizontal{block-size:100%}.virtual-scroll-container[data-v-a75851a5]{outline-offset:1px;block-size:100%;inline-size:100%;position:relative}.virtual-scroll-container[data-v-a75851a5]:not(.virtual-scroll--window){overscroll-behavior:contain;overflow:auto}.virtual-scroll-container.virtual-scroll--table[data-v-a75851a5]{display:block}.virtual-scroll-container.virtual-scroll--hide-scrollbar[data-v-a75851a5]{scrollbar-width:none;-ms-overflow-style:none}.virtual-scroll-container.virtual-scroll--hide-scrollbar[data-v-a75851a5]::-webkit-scrollbar{display:none}.virtual-scroll-container.virtual-scroll--horizontal[data-v-a75851a5],.virtual-scroll-container.virtual-scroll--both[data-v-a75851a5]{white-space:nowrap}.virtual-scroll-scrollbar-container[data-v-a75851a5]{z-index:30;pointer-events:none;block-size:0;inline-size:100%;position:sticky;inset-block-start:0;inset-inline-start:0;overflow:visible}.virtual-scroll-scrollbar-viewport[data-v-a75851a5]{pointer-events:none;position:absolute;inset-block-start:0;inset-inline-start:0}.virtual-scroll-wrapper[data-v-a75851a5]{contain:layout;position:relative}:where(.virtual-scroll--hydrated>.virtual-scroll-wrapper>.virtual-scroll-item[data-v-a75851a5]){position:absolute;inset-block-start:0;inset-inline-start:0}.virtual-scroll-item[data-v-a75851a5]{box-sizing:border-box;will-change:transform;display:grid}.virtual-scroll-item[data-v-a75851a5]:where(.virtual-scroll--debug){background-color:#ff00000d;outline:1px dashed #ff000080}.virtual-scroll-item[data-v-a75851a5]:where(.virtual-scroll--debug):where(:hover){z-index:100;background-color:#ff00001a}.virtual-scroll-debug-info[data-v-a75851a5]{color:#fff;pointer-events:none;z-index:100;background:#000000b3;border-radius:4px;padding:2px 4px;font-family:monospace;font-size:10px;position:absolute;inset-block-start:2px;inset-inline-end:2px}.virtual-scroll-spacer[data-v-a75851a5]{pointer-events:none}.virtual-scroll-header[data-v-a75851a5],.virtual-scroll-footer[data-v-a75851a5]{z-index:20;position:relative}.virtual-scroll--sticky[data-v-a75851a5]{position:sticky}.virtual-scroll--sticky[data-v-a75851a5]:where(.virtual-scroll-header){box-sizing:border-box;min-inline-size:100%;inset-block-start:0;inset-inline-start:0}.virtual-scroll--sticky[data-v-a75851a5]:where(.virtual-scroll-footer){box-sizing:border-box;min-inline-size:100%;inset-block-end:0;inset-inline-start:0}.virtual-scroll--sticky[data-v-a75851a5]:where(.virtual-scroll-item){z-index:10}:is(tbody.virtual-scroll-wrapper[data-v-a75851a5],thead.virtual-scroll-header[data-v-a75851a5],tfoot.virtual-scroll-footer[data-v-a75851a5]),:is(tbody.virtual-scroll-wrapper[data-v-a75851a5],thead.virtual-scroll-header[data-v-a75851a5],tfoot.virtual-scroll-footer[data-v-a75851a5])>tr{min-inline-size:100%;display:inline-flex}:is(tbody.virtual-scroll-wrapper[data-v-a75851a5],thead.virtual-scroll-header[data-v-a75851a5],tfoot.virtual-scroll-footer[data-v-a75851a5])>tr>:is(td,th){align-items:center;display:inline-block}}
|
|
2
2
|
/*$vite$:1*/
|
package/package.json
CHANGED
|
@@ -22,6 +22,14 @@ import {
|
|
|
22
22
|
useVirtualScroll,
|
|
23
23
|
} from '../composables/useVirtualScroll';
|
|
24
24
|
import { useVirtualScrollbar } from '../composables/useVirtualScrollbar';
|
|
25
|
+
import {
|
|
26
|
+
useCoordinateScalingExtension,
|
|
27
|
+
useInfiniteLoadingExtension,
|
|
28
|
+
usePrependRestorationExtension,
|
|
29
|
+
useRtlExtension,
|
|
30
|
+
useSnappingExtension,
|
|
31
|
+
useStickyExtension,
|
|
32
|
+
} from '../extensions/all';
|
|
25
33
|
import { getPaddingX, getPaddingY, isWindowLike } from '../utils/scroll';
|
|
26
34
|
import {
|
|
27
35
|
calculateInertiaStep,
|
|
@@ -107,6 +115,17 @@ const instanceId = useId();
|
|
|
107
115
|
*/
|
|
108
116
|
const containerId = computed(() => `vs-container-${ instanceId }`);
|
|
109
117
|
|
|
118
|
+
const extensions = [
|
|
119
|
+
useRtlExtension<T>(),
|
|
120
|
+
useSnappingExtension<T>(),
|
|
121
|
+
useStickyExtension<T>(),
|
|
122
|
+
useInfiniteLoadingExtension<T>({
|
|
123
|
+
onLoad: (dir) => emit('load', dir),
|
|
124
|
+
}),
|
|
125
|
+
usePrependRestorationExtension<T>(),
|
|
126
|
+
useCoordinateScalingExtension<T>(),
|
|
127
|
+
];
|
|
128
|
+
|
|
110
129
|
const measuredPaddingStart = ref(0);
|
|
111
130
|
const measuredPaddingEnd = ref(0);
|
|
112
131
|
|
|
@@ -202,7 +221,7 @@ const {
|
|
|
202
221
|
renderedVirtualHeight,
|
|
203
222
|
getRowIndexAt,
|
|
204
223
|
getColIndexAt,
|
|
205
|
-
} = useVirtualScroll(virtualScrollProps);
|
|
224
|
+
} = useVirtualScroll(virtualScrollProps, extensions);
|
|
206
225
|
|
|
207
226
|
const useVirtualScrolling = computed(() => scaleX.value !== 1 || scaleY.value !== 1);
|
|
208
227
|
|
|
@@ -316,25 +335,6 @@ watch(scrollDetails, (details, oldDetails) => {
|
|
|
316
335
|
colEnd: details.columnRange.end,
|
|
317
336
|
});
|
|
318
337
|
}
|
|
319
|
-
|
|
320
|
-
if (props.loading) {
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// vertical or both
|
|
325
|
-
if (props.direction !== 'horizontal' && details.totalSize) {
|
|
326
|
-
const remaining = details.totalSize.height - (details.scrollOffset.y + details.viewportSize.height);
|
|
327
|
-
if (remaining <= props.loadDistance) {
|
|
328
|
-
emit('load', 'vertical');
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
// horizontal or both
|
|
332
|
-
if (props.direction !== 'vertical' && details.totalSize) {
|
|
333
|
-
const remaining = details.totalSize.width - (details.scrollOffset.x + details.viewportSize.width);
|
|
334
|
-
if (remaining <= props.loadDistance) {
|
|
335
|
-
emit('load', 'horizontal');
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
338
|
});
|
|
339
339
|
|
|
340
340
|
watch(isHydrated, (hydrated) => {
|
|
@@ -1247,6 +1247,16 @@ defineExpose({
|
|
|
1247
1247
|
*/
|
|
1248
1248
|
getItemSize,
|
|
1249
1249
|
|
|
1250
|
+
/**
|
|
1251
|
+
* Whether the component is in table mode.
|
|
1252
|
+
*/
|
|
1253
|
+
isTable,
|
|
1254
|
+
|
|
1255
|
+
/**
|
|
1256
|
+
* The tag used for rendering items.
|
|
1257
|
+
*/
|
|
1258
|
+
itemTag: computed(() => props.itemTag || 'div'),
|
|
1259
|
+
|
|
1250
1260
|
/**
|
|
1251
1261
|
* Helper to get the row (or item) index at a specific vertical (or horizontal in horizontal mode) virtual offset (VU).
|
|
1252
1262
|
* @param offset - The virtual pixel offset.
|