@pdanpdan/virtual-scroll 0.10.2 → 0.10.3
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/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +549 -522
- package/dist/index.mjs.map +1 -1
- package/dist/virtual-scroll.css +1 -1
- package/package.json +1 -1
- package/src/components/VirtualScroll.vue +1 -1
- package/src/composables/useVirtualScroll.ts +53 -19
- package/src/composables/useVirtualScrollSizes.ts +1 -1
- package/src/extensions/sticky.ts +1 -1
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-200891f5]{outline-offset:1px;block-size:100%;inline-size:100%;position:relative}.virtual-scroll-container[data-v-200891f5]:not(.virtual-scroll--window){overscroll-behavior:contain;overflow:auto}.virtual-scroll-container.virtual-scroll--table[data-v-200891f5]{display:block}.virtual-scroll-container.virtual-scroll--hide-scrollbar[data-v-200891f5]{scrollbar-width:none;-ms-overflow-style:none}.virtual-scroll-container.virtual-scroll--hide-scrollbar[data-v-200891f5]::-webkit-scrollbar{display:none}.virtual-scroll-container.virtual-scroll--horizontal[data-v-200891f5],.virtual-scroll-container.virtual-scroll--both[data-v-200891f5]{white-space:nowrap}.virtual-scroll-scrollbar-container[data-v-200891f5]{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-200891f5]{pointer-events:none;position:absolute;inset-block-start:0;inset-inline-start:0}.virtual-scroll-wrapper[data-v-200891f5]{contain:layout;position:relative}:where(.virtual-scroll--hydrated>.virtual-scroll-wrapper>.virtual-scroll-item[data-v-200891f5]){position:absolute;inset-block-start:0;inset-inline-start:0}.virtual-scroll-item[data-v-200891f5]{box-sizing:border-box;will-change:transform;display:grid}.virtual-scroll-item[data-v-200891f5]:where(.virtual-scroll--debug){background-color:#ff00000d;outline:1px dashed #ff000080}.virtual-scroll-item[data-v-200891f5]:where(.virtual-scroll--debug):where(:hover){z-index:100;background-color:#ff00001a}.virtual-scroll-debug-info[data-v-200891f5]{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-200891f5]{pointer-events:none}.virtual-scroll-header[data-v-200891f5],.virtual-scroll-footer[data-v-200891f5]{z-index:20;position:relative}.virtual-scroll--sticky[data-v-200891f5]{position:sticky}.virtual-scroll--sticky[data-v-200891f5]: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-200891f5]: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-200891f5]:where(.virtual-scroll-item){z-index:10}:is(tbody.virtual-scroll-wrapper[data-v-200891f5],thead.virtual-scroll-header[data-v-200891f5],tfoot.virtual-scroll-footer[data-v-200891f5]),:is(tbody.virtual-scroll-wrapper[data-v-200891f5],thead.virtual-scroll-header[data-v-200891f5],tfoot.virtual-scroll-footer[data-v-200891f5])>tr{min-inline-size:100%;display:inline-flex}:is(tbody.virtual-scroll-wrapper[data-v-200891f5],thead.virtual-scroll-header[data-v-200891f5],tfoot.virtual-scroll-footer[data-v-200891f5])>tr>:is(td,th){align-items:center;display:inline-block}}
|
|
2
2
|
/*$vite$:1*/
|
package/package.json
CHANGED
|
@@ -1100,7 +1100,7 @@ const internalItemRole = computed(() => {
|
|
|
1100
1100
|
}
|
|
1101
1101
|
return 'listitem';
|
|
1102
1102
|
});
|
|
1103
|
-
const itemRole = computed(() => props.itemRole
|
|
1103
|
+
const itemRole = computed(() => props.itemRole ?? internalItemRole.value);
|
|
1104
1104
|
const cellRole = computed(() => {
|
|
1105
1105
|
if (props.role === 'grid' || (!props.role && props.direction === 'both')) {
|
|
1106
1106
|
return 'gridcell';
|
|
@@ -417,21 +417,19 @@ export function useVirtualScroll<T = unknown>(
|
|
|
417
417
|
const scrollBehavior = isCorrection ? 'auto' : (behavior || 'smooth');
|
|
418
418
|
|
|
419
419
|
if (!dryRun) {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
}, 150);
|
|
434
|
-
}
|
|
420
|
+
isProgrammaticScroll.value = true;
|
|
421
|
+
clearTimeout(programmaticScrollTimer);
|
|
422
|
+
if (scrollBehavior === 'smooth') {
|
|
423
|
+
programmaticScrollTimer = setTimeout(() => {
|
|
424
|
+
isProgrammaticScroll.value = false;
|
|
425
|
+
programmaticScrollTimer = undefined;
|
|
426
|
+
checkPendingScroll();
|
|
427
|
+
}, 1000);
|
|
428
|
+
} else {
|
|
429
|
+
programmaticScrollTimer = setTimeout(() => {
|
|
430
|
+
isProgrammaticScroll.value = false;
|
|
431
|
+
programmaticScrollTimer = undefined;
|
|
432
|
+
}, 150);
|
|
435
433
|
}
|
|
436
434
|
}
|
|
437
435
|
|
|
@@ -443,7 +441,7 @@ export function useVirtualScroll<T = unknown>(
|
|
|
443
441
|
scrollOptions.top = Math.max(0, finalY);
|
|
444
442
|
}
|
|
445
443
|
|
|
446
|
-
if (!
|
|
444
|
+
if (!dryRun) {
|
|
447
445
|
scrollTo(container, scrollOptions);
|
|
448
446
|
}
|
|
449
447
|
|
|
@@ -630,7 +628,7 @@ export function useVirtualScroll<T = unknown>(
|
|
|
630
628
|
treeUpdateFlag.value;
|
|
631
629
|
const { start, end } = range.value;
|
|
632
630
|
const items: RenderedItem<T>[] = [];
|
|
633
|
-
const stickyIndices =
|
|
631
|
+
const stickyIndices = (props.value.stickyIndices || []).toSorted((a, b) => a - b);
|
|
634
632
|
const stickySet = new Set(stickyIndices);
|
|
635
633
|
const sortedIndices: number[] = [];
|
|
636
634
|
if (isHydrated.value || !props.value.ssrRange) {
|
|
@@ -840,7 +838,43 @@ export function useVirtualScroll<T = unknown>(
|
|
|
840
838
|
const scrollValueY = actualScrollY;
|
|
841
839
|
const currentRelX = displayToVirtual(scrollValueX, 0, scaleX.value);
|
|
842
840
|
const currentRelY = displayToVirtual(scrollValueY, 0, scaleY.value);
|
|
843
|
-
const { targetX, targetY } = calculateScrollTarget({
|
|
841
|
+
const { targetX, targetY } = calculateScrollTarget({
|
|
842
|
+
rowIndex,
|
|
843
|
+
colIndex,
|
|
844
|
+
options,
|
|
845
|
+
direction: direction.value,
|
|
846
|
+
viewportWidth: viewportWidth.value,
|
|
847
|
+
viewportHeight: viewportHeight.value,
|
|
848
|
+
totalWidth: totalWidth.value,
|
|
849
|
+
totalHeight: totalHeight.value,
|
|
850
|
+
gap: props.value.gap || 0,
|
|
851
|
+
columnGap: props.value.columnGap || 0,
|
|
852
|
+
fixedSize: fixedItemSize.value,
|
|
853
|
+
fixedWidth: fixedColumnWidth.value,
|
|
854
|
+
relativeScrollX: currentRelX,
|
|
855
|
+
relativeScrollY: currentRelY,
|
|
856
|
+
getItemSizeY: (idx) => itemSizesY.get(idx),
|
|
857
|
+
getItemSizeX: (idx) => itemSizesX.get(idx),
|
|
858
|
+
getItemQueryY: (idx) => itemSizesY.query(idx),
|
|
859
|
+
getItemQueryX: (idx) => itemSizesX.query(idx),
|
|
860
|
+
getColumnSize: (idx) => columnSizes.get(idx),
|
|
861
|
+
getColumnQuery: (idx) => columnSizes.query(idx),
|
|
862
|
+
scaleX: scaleX.value,
|
|
863
|
+
scaleY: scaleY.value,
|
|
864
|
+
hostOffsetX: componentOffset.x,
|
|
865
|
+
hostOffsetY: componentOffset.y,
|
|
866
|
+
stickyIndices: props.value.stickyIndices || [],
|
|
867
|
+
stickyStartX: stickyStartX.value,
|
|
868
|
+
stickyStartY: stickyStartY.value,
|
|
869
|
+
stickyEndX: stickyEndX.value,
|
|
870
|
+
stickyEndY: stickyEndY.value,
|
|
871
|
+
flowPaddingStartX: flowStartX.value,
|
|
872
|
+
flowPaddingStartY: flowStartY.value,
|
|
873
|
+
paddingStartX: paddingStartX.value,
|
|
874
|
+
paddingStartY: paddingStartY.value,
|
|
875
|
+
paddingEndX: paddingEndX.value,
|
|
876
|
+
paddingEndY: paddingEndY.value,
|
|
877
|
+
});
|
|
844
878
|
const toleranceX = 2 * scaleX.value;
|
|
845
879
|
const toleranceY = 2 * scaleY.value;
|
|
846
880
|
const reachedX = (colIndex === null || colIndex === undefined) || (viewportWidth.value > 0 && Math.abs(currentRelX - targetX) < toleranceX);
|
|
@@ -858,7 +892,7 @@ export function useVirtualScroll<T = unknown>(
|
|
|
858
892
|
}
|
|
859
893
|
}
|
|
860
894
|
|
|
861
|
-
watch([ treeUpdateFlag, viewportWidth, viewportHeight ], checkPendingScroll);
|
|
895
|
+
watch([ treeUpdateFlag, viewportWidth, viewportHeight, isHydrating ], checkPendingScroll);
|
|
862
896
|
watch(isScrolling, (scrolling) => {
|
|
863
897
|
if (!scrolling) {
|
|
864
898
|
checkPendingScroll();
|
|
@@ -388,7 +388,7 @@ export function useVirtualScrollSizes<T>(
|
|
|
388
388
|
tryUpdateColumn(Number.parseInt(colIndexAttr, 10), inlineSize);
|
|
389
389
|
} else {
|
|
390
390
|
// If the element is a row, try to find cells with data-col-index
|
|
391
|
-
const cells =
|
|
391
|
+
const cells = [ ...element.querySelectorAll('[data-col-index]') ] as HTMLElement[];
|
|
392
392
|
|
|
393
393
|
for (const child of cells) {
|
|
394
394
|
const colIndex = Number.parseInt(child.dataset.colIndex!, 10);
|
package/src/extensions/sticky.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { findPrevStickyIndex } from '../utils/virtual-scroll-logic';
|
|
|
11
11
|
*/
|
|
12
12
|
export function useStickyExtension<T = unknown>(): VirtualScrollExtension<T> {
|
|
13
13
|
const sortedStickyIndices = (ctx: ExtensionContext<T>) =>
|
|
14
|
-
computed(() =>
|
|
14
|
+
computed(() => (ctx.props.value.stickyIndices || []).toSorted((a, b) => a - b));
|
|
15
15
|
|
|
16
16
|
return {
|
|
17
17
|
name: 'sticky',
|