stk-table-vue 0.11.1 → 0.11.2
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/lib/index-t5SJ6KNv.js +1 -1
- package/lib/src/StkTable/useScrollbar.d.ts +1 -1
- package/lib/src/StkTable/useVirtualScroll.d.ts +1 -1
- package/lib/stk-table-vue.js +76 -24
- package/lib/style.css +1 -1
- package/package.json +1 -1
- package/src/StkTable/StkTable.vue +25 -6
- package/src/StkTable/features/useAreaSelection.ts +62 -7
- package/src/StkTable/useScrollbar.ts +2 -1
- package/src/StkTable/useVirtualScroll.ts +2 -1
package/lib/index-t5SJ6KNv.js
CHANGED
|
@@ -18,7 +18,7 @@ export type ScrollbarOptions = {
|
|
|
18
18
|
* @param options 滚动条配置选项
|
|
19
19
|
* @returns 滚动条相关状态和方法
|
|
20
20
|
*/
|
|
21
|
-
export declare function useScrollbar(props: any, containerRef: Ref<HTMLDivElement | undefined>, virtualScroll: Ref<VirtualScrollStore>, virtualScrollX: Ref<VirtualScrollXStore>, updateVirtualScrollY: (sTop?: number) => void, scrollbarOptions: Ref<Required<ScrollbarOptions
|
|
21
|
+
export declare function useScrollbar(props: any, containerRef: Ref<HTMLDivElement | undefined>, virtualScroll: Ref<VirtualScrollStore>, virtualScrollX: Ref<VirtualScrollXStore>, updateVirtualScrollY: (sTop?: number) => void, scrollbarOptions: Ref<Required<ScrollbarOptions>>, isExperimentalScrollY: Ref<boolean | undefined>): readonly [Ref<{
|
|
22
22
|
h: number;
|
|
23
23
|
w: number;
|
|
24
24
|
t: number;
|
|
@@ -41,7 +41,7 @@ export type VirtualScrollXStore = {
|
|
|
41
41
|
* virtual scroll
|
|
42
42
|
* @returns
|
|
43
43
|
*/
|
|
44
|
-
export declare function useVirtualScroll<DT extends Record<string, any>>(props: any, tableContainerRef: Ref<HTMLElement | undefined>, trRef: Ref<HTMLTableRowElement[] | undefined>, dataSourceCopy: ShallowRef<PrivateRowDT[]>, tableHeaderLast: ShallowRef<PrivateStkTableColumn<PrivateRowDT>[]>, tableHeaders: ShallowRef<PrivateStkTableColumn<PrivateRowDT>[][]>, rowKeyGen: RowKeyGen, maxRowSpan: Map<UniqKey, number>, scrollbarOptions: Ref<Required<ScrollbarOptions
|
|
44
|
+
export declare function useVirtualScroll<DT extends Record<string, any>>(props: any, tableContainerRef: Ref<HTMLElement | undefined>, trRef: Ref<HTMLTableRowElement[] | undefined>, dataSourceCopy: ShallowRef<PrivateRowDT[]>, tableHeaderLast: ShallowRef<PrivateStkTableColumn<PrivateRowDT>[]>, tableHeaders: ShallowRef<PrivateStkTableColumn<PrivateRowDT>[][]>, rowKeyGen: RowKeyGen, maxRowSpan: Map<UniqKey, number>, scrollbarOptions: Ref<Required<ScrollbarOptions>>, isExperimentalScrollY: Ref<boolean | undefined>): readonly [Ref<{
|
|
45
45
|
containerHeight: number;
|
|
46
46
|
pageSize: number;
|
|
47
47
|
startIndex: number;
|
package/lib/stk-table-vue.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* name: stk-table-vue
|
|
3
|
-
* version: v0.11.
|
|
3
|
+
* version: v0.11.2
|
|
4
4
|
* description: High performance realtime virtual table for vue3 and vue2.7
|
|
5
5
|
* author: japlus
|
|
6
6
|
* homepage: https://ja-plus.github.io/stk-table-vue/
|
|
@@ -365,6 +365,42 @@ function useAreaSelection(props, emits, tableContainerRef, dataSourceCopy, table
|
|
|
365
365
|
}
|
|
366
366
|
return map;
|
|
367
367
|
});
|
|
368
|
+
const getFixedColWidths = computed(() => {
|
|
369
|
+
const cols = tableHeaderLast.value;
|
|
370
|
+
const leftAccumulated = [];
|
|
371
|
+
const rightAccumulated = [];
|
|
372
|
+
let leftSum = 0;
|
|
373
|
+
let rightSum = 0;
|
|
374
|
+
for (let i = 0, j = cols.length - 1; i < cols.length; i++, j--) {
|
|
375
|
+
const leftCol = cols[i];
|
|
376
|
+
const rightCol = cols[j];
|
|
377
|
+
if ((leftCol == null ? void 0 : leftCol.fixed) === "left") {
|
|
378
|
+
leftSum += getCalculatedColWidth(leftCol);
|
|
379
|
+
leftAccumulated.push({ i, w: leftSum });
|
|
380
|
+
}
|
|
381
|
+
if ((rightCol == null ? void 0 : rightCol.fixed) === "right") {
|
|
382
|
+
rightSum += getCalculatedColWidth(rightCol);
|
|
383
|
+
rightAccumulated.unshift({ i: j, w: rightSum });
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return (colIndex) => {
|
|
387
|
+
let leftFixedWidth = 0;
|
|
388
|
+
for (let i = leftAccumulated.length - 1; i >= 0; i--) {
|
|
389
|
+
if (leftAccumulated[i].i < colIndex) {
|
|
390
|
+
leftFixedWidth = leftAccumulated[i].w;
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
let rightFixedWidth = 0;
|
|
395
|
+
for (let i = rightAccumulated.length - 1; i >= 0; i--) {
|
|
396
|
+
if (rightAccumulated[i].i > colIndex) {
|
|
397
|
+
rightFixedWidth = rightAccumulated[i].w;
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
return [leftFixedWidth, rightFixedWidth];
|
|
402
|
+
};
|
|
403
|
+
});
|
|
368
404
|
const selectedCellKeys = computed(() => {
|
|
369
405
|
const range = selectionRange.value;
|
|
370
406
|
if (!range) return /* @__PURE__ */ new Set();
|
|
@@ -764,11 +800,12 @@ function useAreaSelection(props, emits, tableContainerRef, dataSourceCopy, table
|
|
|
764
800
|
const targetColRight = targetColLeft + targetColWidth;
|
|
765
801
|
const visibleLeft = container.scrollLeft;
|
|
766
802
|
const visibleRight = visibleLeft + vsx.containerWidth;
|
|
803
|
+
const [leftFixedWidth, rightFixedWidth] = getFixedColWidths.value(colIndex);
|
|
767
804
|
let newScrollLeft = null;
|
|
768
|
-
if (targetColLeft < visibleLeft) {
|
|
769
|
-
newScrollLeft = targetColLeft;
|
|
770
|
-
} else if (targetColRight > visibleRight) {
|
|
771
|
-
newScrollLeft = targetColRight - vsx.containerWidth;
|
|
805
|
+
if (targetColLeft < visibleLeft + leftFixedWidth) {
|
|
806
|
+
newScrollLeft = targetColLeft - leftFixedWidth;
|
|
807
|
+
} else if (targetColRight > visibleRight - rightFixedWidth) {
|
|
808
|
+
newScrollLeft = targetColRight - vsx.containerWidth + rightFixedWidth;
|
|
772
809
|
}
|
|
773
810
|
if (newScrollTop !== null || newScrollLeft !== null) {
|
|
774
811
|
scrollTo(newScrollTop, newScrollLeft);
|
|
@@ -1586,7 +1623,7 @@ function useRowExpand(emits, dataSourceCopy, rowKeyGen) {
|
|
|
1586
1623
|
}
|
|
1587
1624
|
return [toggleExpandRow, setRowExpand];
|
|
1588
1625
|
}
|
|
1589
|
-
function useScrollbar(props, containerRef, virtualScroll, virtualScrollX, updateVirtualScrollY, scrollbarOptions) {
|
|
1626
|
+
function useScrollbar(props, containerRef, virtualScroll, virtualScrollX, updateVirtualScrollY, scrollbarOptions, isExperimentalScrollY) {
|
|
1590
1627
|
const showScrollbar = ref({ x: false, y: false });
|
|
1591
1628
|
const scrollbar = ref({ h: 0, w: 0, t: 0, l: 0 });
|
|
1592
1629
|
let isDraggingVertical = false;
|
|
@@ -1650,7 +1687,6 @@ function useScrollbar(props, containerRef, virtualScroll, virtualScrollX, update
|
|
|
1650
1687
|
document.addEventListener("touchend", onDragEnd);
|
|
1651
1688
|
}
|
|
1652
1689
|
function onVerticalDrag(e) {
|
|
1653
|
-
var _a;
|
|
1654
1690
|
if (!isDraggingVertical) return;
|
|
1655
1691
|
e.preventDefault();
|
|
1656
1692
|
const clientY = e instanceof MouseEvent ? e.clientY : e.touches[0].clientY;
|
|
@@ -1659,7 +1695,7 @@ function useScrollbar(props, containerRef, virtualScroll, virtualScrollX, update
|
|
|
1659
1695
|
const scrollRange = scrollHeight - containerHeight;
|
|
1660
1696
|
const trackRange = containerHeight - scrollbar.value.h;
|
|
1661
1697
|
const scrollDelta = deltaY / trackRange * scrollRange;
|
|
1662
|
-
if (
|
|
1698
|
+
if (isExperimentalScrollY.value) {
|
|
1663
1699
|
const ratio = containerHeight / scrollHeight;
|
|
1664
1700
|
const top = Math.round((dragStartTop + scrollDelta) * ratio);
|
|
1665
1701
|
const maxTop = containerHeight - scrollbar.value.h;
|
|
@@ -2106,7 +2142,7 @@ function useTree(props, dataSourceCopy, rowKeyGen, emits) {
|
|
|
2106
2142
|
return [toggleTreeNode, setTreeExpand, flatTreeData];
|
|
2107
2143
|
}
|
|
2108
2144
|
const VUE2_SCROLL_TIMEOUT_MS = 200;
|
|
2109
|
-
function useVirtualScroll(props, tableContainerRef, trRef, dataSourceCopy, tableHeaderLast, tableHeaders, rowKeyGen, maxRowSpan, scrollbarOptions) {
|
|
2145
|
+
function useVirtualScroll(props, tableContainerRef, trRef, dataSourceCopy, tableHeaderLast, tableHeaders, rowKeyGen, maxRowSpan, scrollbarOptions, isExperimentalScrollY) {
|
|
2110
2146
|
const tableHeaderHeight = computed(() => props.headerRowHeight * tableHeaders.value.length);
|
|
2111
2147
|
const virtualScroll = ref({
|
|
2112
2148
|
containerHeight: 0,
|
|
@@ -2266,7 +2302,6 @@ function useVirtualScroll(props, tableContainerRef, trRef, dataSourceCopy, table
|
|
|
2266
2302
|
}
|
|
2267
2303
|
}
|
|
2268
2304
|
function updateVirtualScrollY(sTop = 0) {
|
|
2269
|
-
var _a;
|
|
2270
2305
|
const { pageSize, scrollTop, startIndex: oldStartIndex, endIndex: oldEndIndex, containerHeight } = virtualScroll.value;
|
|
2271
2306
|
const dataSourceCopyTemp = dataSourceCopy.value;
|
|
2272
2307
|
const dataLength = dataSourceCopyTemp.length;
|
|
@@ -2276,7 +2311,7 @@ function useVirtualScroll(props, tableContainerRef, trRef, dataSourceCopy, table
|
|
|
2276
2311
|
const { enabled: scrollbarEnable } = scrollbarOptions.value;
|
|
2277
2312
|
if (scrollbarEnable) {
|
|
2278
2313
|
vsValue.scrollHeight = scrollHeight;
|
|
2279
|
-
if (
|
|
2314
|
+
if (isExperimentalScrollY.value) {
|
|
2280
2315
|
let maxTop;
|
|
2281
2316
|
sTop = sTop < 0 ? 0 : sTop < (maxTop = scrollHeight - containerHeight) ? sTop : maxTop;
|
|
2282
2317
|
vsValue.translateY = props.scrollRowByRow ? 0 : -(sTop % rowHeight);
|
|
@@ -2647,6 +2682,13 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
2647
2682
|
height: 8,
|
|
2648
2683
|
...typeof props.scrollbar === "boolean" ? { enabled: props.scrollbar } : props.scrollbar
|
|
2649
2684
|
}));
|
|
2685
|
+
const isExperimentalScrollY = computed(() => {
|
|
2686
|
+
var _a, _b;
|
|
2687
|
+
if (((_a = scrollbarOptions.value) == null ? void 0 : _a.enabled) && props.scrollRowByRow) {
|
|
2688
|
+
return true;
|
|
2689
|
+
}
|
|
2690
|
+
return (_b = props.experimental) == null ? void 0 : _b.scrollY;
|
|
2691
|
+
});
|
|
2650
2692
|
const rowKeyGenCache = /* @__PURE__ */ new WeakMap();
|
|
2651
2693
|
const [isSRBRActive] = useScrollRowByRow(props, tableContainerRef);
|
|
2652
2694
|
const [onThDragStart, onThDragOver, onThDrop, isHeaderDraggable] = useThDrag(props, emits, colKeyGen);
|
|
@@ -2669,7 +2711,18 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
2669
2711
|
updateVirtualScrollX,
|
|
2670
2712
|
setAutoHeight,
|
|
2671
2713
|
clearAllAutoHeight
|
|
2672
|
-
] = useVirtualScroll(
|
|
2714
|
+
] = useVirtualScroll(
|
|
2715
|
+
props,
|
|
2716
|
+
tableContainerRef,
|
|
2717
|
+
trRef,
|
|
2718
|
+
dataSourceCopy,
|
|
2719
|
+
tableHeaderLast,
|
|
2720
|
+
tableHeaders,
|
|
2721
|
+
rowKeyGen,
|
|
2722
|
+
maxRowSpan,
|
|
2723
|
+
scrollbarOptions,
|
|
2724
|
+
isExperimentalScrollY
|
|
2725
|
+
);
|
|
2673
2726
|
const rafUpdateVirtualScrollYForWheel = rafThrottle((scrollTop) => {
|
|
2674
2727
|
updateVirtualScrollY(scrollTop);
|
|
2675
2728
|
});
|
|
@@ -2679,7 +2732,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
2679
2732
|
virtualScroll,
|
|
2680
2733
|
virtualScrollX,
|
|
2681
2734
|
updateVirtualScrollY,
|
|
2682
|
-
scrollbarOptions
|
|
2735
|
+
scrollbarOptions,
|
|
2736
|
+
isExperimentalScrollY
|
|
2683
2737
|
);
|
|
2684
2738
|
const [hiddenCellMap, mergeCellsWrapper, hoverMergedCells, updateHoverMergedCells, activeMergedCells, updateActiveMergedCells] = useMergeCells(
|
|
2685
2739
|
rowActiveProp,
|
|
@@ -3151,7 +3205,6 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
3151
3205
|
}
|
|
3152
3206
|
const [isWheeling, setIsWheeling] = useWheeling();
|
|
3153
3207
|
function onTableWheel(e) {
|
|
3154
|
-
var _a;
|
|
3155
3208
|
if (props.smoothScroll) return;
|
|
3156
3209
|
if (isColResizing.value) {
|
|
3157
3210
|
e.stopPropagation();
|
|
@@ -3169,7 +3222,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
3169
3222
|
if (isWheeling()) {
|
|
3170
3223
|
e.preventDefault();
|
|
3171
3224
|
}
|
|
3172
|
-
if (
|
|
3225
|
+
if (isExperimentalScrollY.value) {
|
|
3173
3226
|
rafUpdateVirtualScrollYForWheel(scrollTop + deltaY);
|
|
3174
3227
|
updateCustomScrollbar();
|
|
3175
3228
|
} else {
|
|
@@ -3487,7 +3540,6 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
3487
3540
|
setFilter
|
|
3488
3541
|
});
|
|
3489
3542
|
return (_ctx, _cache) => {
|
|
3490
|
-
var _a, _b, _c, _d;
|
|
3491
3543
|
return openBlock(), createElementBlock("div", {
|
|
3492
3544
|
ref_key: "tableContainerRef",
|
|
3493
3545
|
ref: tableContainerRef,
|
|
@@ -3514,7 +3566,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
3514
3566
|
"scroll-row-by-row": unref(isSRBRActive),
|
|
3515
3567
|
"scrollbar-on": scrollbarOptions.value.enabled,
|
|
3516
3568
|
"is-area-selecting": unref(isAreaSelecting),
|
|
3517
|
-
"exp-scroll-y":
|
|
3569
|
+
"exp-scroll-y": isExperimentalScrollY.value
|
|
3518
3570
|
}]),
|
|
3519
3571
|
tabindex: props.areaSelection ? 0 : void 0,
|
|
3520
3572
|
style: normalizeStyle({
|
|
@@ -3529,7 +3581,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
3529
3581
|
onScroll: onTableScroll,
|
|
3530
3582
|
onWheel: onTableWheel
|
|
3531
3583
|
}, [
|
|
3532
|
-
!
|
|
3584
|
+
!isExperimentalScrollY.value && SRBRTotalHeight.value ? (openBlock(), createElementBlock("div", {
|
|
3533
3585
|
key: 0,
|
|
3534
3586
|
class: "row-by-row-table-height",
|
|
3535
3587
|
style: normalizeStyle(`height: ${SRBRTotalHeight.value}px`)
|
|
@@ -3656,7 +3708,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
3656
3708
|
onMousedown: onCellMouseDown,
|
|
3657
3709
|
onMouseover: onCellMouseOver
|
|
3658
3710
|
}, [
|
|
3659
|
-
!
|
|
3711
|
+
!isExperimentalScrollY.value && unref(virtual_on) && !unref(isSRBRActive) ? (openBlock(), createElementBlock("tr", {
|
|
3660
3712
|
key: 0,
|
|
3661
3713
|
style: normalizeStyle(`height:${unref(virtualScroll).offsetTop}px`),
|
|
3662
3714
|
class: "padding-top-tr"
|
|
@@ -3689,16 +3741,16 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
3689
3741
|
row: row.__EXP_R__,
|
|
3690
3742
|
col: row.__EXP_C__
|
|
3691
3743
|
}, () => {
|
|
3692
|
-
var
|
|
3744
|
+
var _a;
|
|
3693
3745
|
return [
|
|
3694
|
-
createTextVNode(toDisplayString(((
|
|
3746
|
+
createTextVNode(toDisplayString(((_a = row.__EXP_R__) == null ? void 0 : _a[row.__EXP_C__.dataIndex]) ?? ""), 1)
|
|
3695
3747
|
];
|
|
3696
3748
|
})
|
|
3697
3749
|
])
|
|
3698
3750
|
], 8, _hoisted_16)) : (openBlock(true), createElementBlock(Fragment, { key: 2 }, renderList(unref(virtualX_columnPart), (col, colIndex) => {
|
|
3699
|
-
var
|
|
3751
|
+
var _a;
|
|
3700
3752
|
return openBlock(), createElementBlock(Fragment, null, [
|
|
3701
|
-
!unref(hiddenCellMap) || !((
|
|
3753
|
+
!unref(hiddenCellMap) || !((_a = unref(hiddenCellMap)[rowKeyGen(row)]) == null ? void 0 : _a.has(colKeyGen.value(col))) ? (openBlock(), createElementBlock("td", mergeProps({
|
|
3702
3754
|
key: colKeyGen.value(col)
|
|
3703
3755
|
}, { ref_for: true }, getTDProps(row, col, rowIndex, colIndex), {
|
|
3704
3756
|
onMouseenter: onCellMouseEnter,
|
|
@@ -3756,7 +3808,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
3756
3808
|
unref(virtualX_on) ? (openBlock(), createElementBlock("td", _hoisted_22)) : createCommentVNode("", true)
|
|
3757
3809
|
], 16, _hoisted_14);
|
|
3758
3810
|
}), 128)),
|
|
3759
|
-
!
|
|
3811
|
+
!isExperimentalScrollY.value ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
3760
3812
|
unref(virtual_on) && !unref(isSRBRActive) ? (openBlock(), createElementBlock("tr", {
|
|
3761
3813
|
key: 0,
|
|
3762
3814
|
style: normalizeStyle(`height: ${unref(virtual_offsetBottom)}px`)
|
package/lib/style.css
CHANGED
package/package.json
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
'scroll-row-by-row': isSRBRActive,
|
|
27
27
|
'scrollbar-on': scrollbarOptions.enabled,
|
|
28
28
|
'is-area-selecting': isAreaSelecting,
|
|
29
|
-
'exp-scroll-y':
|
|
29
|
+
'exp-scroll-y': isExperimentalScrollY,
|
|
30
30
|
}"
|
|
31
31
|
:tabindex="props.areaSelection ? 0 : void 0"
|
|
32
32
|
:style="{
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
@scroll="onTableScroll"
|
|
42
42
|
@wheel="onTableWheel"
|
|
43
43
|
>
|
|
44
|
-
<div v-if="!
|
|
44
|
+
<div v-if="!isExperimentalScrollY && SRBRTotalHeight" class="row-by-row-table-height" :style="`height: ${SRBRTotalHeight}px`"></div>
|
|
45
45
|
|
|
46
46
|
<div v-if="colResizable" ref="colResizeIndicatorRef" class="column-resize-indicator"></div>
|
|
47
47
|
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
@mouseover="onCellMouseOver"
|
|
133
133
|
>
|
|
134
134
|
<tr
|
|
135
|
-
v-if="!
|
|
135
|
+
v-if="!isExperimentalScrollY && virtual_on && !isSRBRActive"
|
|
136
136
|
:style="`height:${virtualScroll.offsetTop}px`"
|
|
137
137
|
class="padding-top-tr"
|
|
138
138
|
>
|
|
@@ -208,7 +208,7 @@
|
|
|
208
208
|
</template>
|
|
209
209
|
<td v-if="virtualX_on" class="vt-x-right"></td>
|
|
210
210
|
</tr>
|
|
211
|
-
<template v-if="!
|
|
211
|
+
<template v-if="!isExperimentalScrollY">
|
|
212
212
|
<tr v-if="virtual_on && !isSRBRActive" :style="`height: ${virtual_offsetBottom}px`"></tr>
|
|
213
213
|
<tr v-if="SRBRBottomHeight" :style="`height: ${SRBRBottomHeight}px`"></tr>
|
|
214
214
|
</template>
|
|
@@ -798,6 +798,13 @@ const scrollbarOptions = computed(() => ({
|
|
|
798
798
|
...(typeof props.scrollbar === 'boolean' ? { enabled: props.scrollbar } : props.scrollbar),
|
|
799
799
|
}));
|
|
800
800
|
|
|
801
|
+
const isExperimentalScrollY = computed(() => {
|
|
802
|
+
if (scrollbarOptions.value?.enabled && props.scrollRowByRow) {
|
|
803
|
+
return true;
|
|
804
|
+
}
|
|
805
|
+
return props.experimental?.scrollY;
|
|
806
|
+
});
|
|
807
|
+
|
|
801
808
|
const rowKeyGenCache = new WeakMap();
|
|
802
809
|
|
|
803
810
|
const [isSRBRActive] = useScrollRowByRow(props, tableContainerRef);
|
|
@@ -825,7 +832,18 @@ const [
|
|
|
825
832
|
updateVirtualScrollX,
|
|
826
833
|
setAutoHeight,
|
|
827
834
|
clearAllAutoHeight,
|
|
828
|
-
] = useVirtualScroll(
|
|
835
|
+
] = useVirtualScroll(
|
|
836
|
+
props,
|
|
837
|
+
tableContainerRef,
|
|
838
|
+
trRef,
|
|
839
|
+
dataSourceCopy,
|
|
840
|
+
tableHeaderLast,
|
|
841
|
+
tableHeaders,
|
|
842
|
+
rowKeyGen,
|
|
843
|
+
maxRowSpan,
|
|
844
|
+
scrollbarOptions,
|
|
845
|
+
isExperimentalScrollY,
|
|
846
|
+
);
|
|
829
847
|
|
|
830
848
|
/** requestAnimationFrame throttled version of updateVirtualScrollY for smoother wheel scrolling */
|
|
831
849
|
const rafUpdateVirtualScrollYForWheel = rafThrottle((scrollTop: number) => {
|
|
@@ -839,6 +857,7 @@ const [scrollbar, showScrollbar, onVerticalScrollbarMouseDown, onHorizontalScrol
|
|
|
839
857
|
virtualScrollX,
|
|
840
858
|
updateVirtualScrollY,
|
|
841
859
|
scrollbarOptions,
|
|
860
|
+
isExperimentalScrollY,
|
|
842
861
|
);
|
|
843
862
|
|
|
844
863
|
const [hiddenCellMap, mergeCellsWrapper, hoverMergedCells, updateHoverMergedCells, activeMergedCells, updateActiveMergedCells] = useMergeCells(
|
|
@@ -1438,7 +1457,7 @@ function onTableWheel(e: WheelEvent) {
|
|
|
1438
1457
|
if (isWheeling()) {
|
|
1439
1458
|
e.preventDefault();
|
|
1440
1459
|
}
|
|
1441
|
-
if (
|
|
1460
|
+
if (isExperimentalScrollY.value) {
|
|
1442
1461
|
rafUpdateVirtualScrollYForWheel(scrollTop + deltaY);
|
|
1443
1462
|
updateCustomScrollbar();
|
|
1444
1463
|
} else {
|
|
@@ -72,6 +72,60 @@ export function useAreaSelection<DT extends Record<string, any>>(
|
|
|
72
72
|
return map;
|
|
73
73
|
});
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* 获取固定列宽度的函数
|
|
77
|
+
* 缓存每个固定列位置的累计宽度,查询时直接返回
|
|
78
|
+
* @param colIndex 目标列索引
|
|
79
|
+
* @returns [leftFixedWidth, rightFixedWidth]
|
|
80
|
+
*/
|
|
81
|
+
const getFixedColWidths = computed(() => {
|
|
82
|
+
const cols = tableHeaderLast.value;
|
|
83
|
+
type FixedColWidth = { i: number; /** accumulated width */ w: number };
|
|
84
|
+
// 保存每个固定列位置的累计宽度(包含当前列)
|
|
85
|
+
const leftAccumulated: FixedColWidth[] = [];
|
|
86
|
+
const rightAccumulated: FixedColWidth[] = [];
|
|
87
|
+
|
|
88
|
+
let leftSum = 0;
|
|
89
|
+
let rightSum = 0;
|
|
90
|
+
|
|
91
|
+
for (let i = 0, j = cols.length - 1; i < cols.length; i++, j--) {
|
|
92
|
+
const leftCol = cols[i];
|
|
93
|
+
const rightCol = cols[j];
|
|
94
|
+
|
|
95
|
+
if (leftCol?.fixed === 'left') {
|
|
96
|
+
leftSum += getCalculatedColWidth(leftCol);
|
|
97
|
+
leftAccumulated.push({ i, w: leftSum });
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (rightCol?.fixed === 'right') {
|
|
101
|
+
rightSum += getCalculatedColWidth(rightCol);
|
|
102
|
+
rightAccumulated.unshift({ i: j, w: rightSum });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return (colIndex: number) => {
|
|
107
|
+
// 查找目标列左侧最近的固定列的累计宽度
|
|
108
|
+
let leftFixedWidth = 0;
|
|
109
|
+
for (let i = leftAccumulated.length - 1; i >= 0; i--) {
|
|
110
|
+
if (leftAccumulated[i].i < colIndex) {
|
|
111
|
+
leftFixedWidth = leftAccumulated[i].w;
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 查找目标列右侧最近的固定列的累计宽度
|
|
117
|
+
let rightFixedWidth = 0;
|
|
118
|
+
for (let i = rightAccumulated.length - 1; i >= 0; i--) {
|
|
119
|
+
if (rightAccumulated[i].i > colIndex) {
|
|
120
|
+
rightFixedWidth = rightAccumulated[i].w;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return [leftFixedWidth, rightFixedWidth] as const;
|
|
126
|
+
};
|
|
127
|
+
});
|
|
128
|
+
|
|
75
129
|
/** 根据 selectionRange 计算选区内所有 cellKey 的集合 */
|
|
76
130
|
const selectedCellKeys = computed<Set<string>>(() => {
|
|
77
131
|
const range = selectionRange.value;
|
|
@@ -639,14 +693,15 @@ export function useAreaSelection<DT extends Record<string, any>>(
|
|
|
639
693
|
const visibleLeft = container.scrollLeft;
|
|
640
694
|
const visibleRight = visibleLeft + vsx.containerWidth;
|
|
641
695
|
|
|
642
|
-
//
|
|
696
|
+
// 计算固定列的宽度(用于检测遮挡)
|
|
697
|
+
const [leftFixedWidth, rightFixedWidth] = getFixedColWidths.value(colIndex);
|
|
643
698
|
let newScrollLeft: number | null = null;
|
|
644
|
-
if (targetColLeft < visibleLeft) {
|
|
645
|
-
//
|
|
646
|
-
newScrollLeft = targetColLeft;
|
|
647
|
-
} else if (targetColRight > visibleRight) {
|
|
648
|
-
//
|
|
649
|
-
newScrollLeft = targetColRight - vsx.containerWidth;
|
|
699
|
+
if (targetColLeft < visibleLeft + leftFixedWidth) {
|
|
700
|
+
// 目标列在左侧固定列遮挡区域内,需要向左滚动
|
|
701
|
+
newScrollLeft = targetColLeft - leftFixedWidth;
|
|
702
|
+
} else if (targetColRight > visibleRight - rightFixedWidth) {
|
|
703
|
+
// 目标列在右侧固定列遮挡区域内,需要向右滚动
|
|
704
|
+
newScrollLeft = targetColRight - vsx.containerWidth + rightFixedWidth;
|
|
650
705
|
}
|
|
651
706
|
|
|
652
707
|
// 执行滚动
|
|
@@ -27,6 +27,7 @@ export function useScrollbar(
|
|
|
27
27
|
virtualScrollX: Ref<VirtualScrollXStore>,
|
|
28
28
|
updateVirtualScrollY: (sTop?: number) => void,
|
|
29
29
|
scrollbarOptions: Ref<Required<ScrollbarOptions>>,
|
|
30
|
+
isExperimentalScrollY: Ref<boolean | undefined>,
|
|
30
31
|
) {
|
|
31
32
|
const showScrollbar = ref({ x: false, y: false });
|
|
32
33
|
const scrollbar = ref({ h: 0, w: 0, t: 0, l: 0 });
|
|
@@ -114,7 +115,7 @@ export function useScrollbar(
|
|
|
114
115
|
const trackRange = containerHeight - scrollbar.value.h;
|
|
115
116
|
const scrollDelta = (deltaY / trackRange) * scrollRange;
|
|
116
117
|
|
|
117
|
-
if (
|
|
118
|
+
if (isExperimentalScrollY.value) {
|
|
118
119
|
const ratio = containerHeight / scrollHeight;
|
|
119
120
|
const top = Math.round((dragStartTop + scrollDelta) * ratio);
|
|
120
121
|
const maxTop = containerHeight - scrollbar.value.h;
|
|
@@ -57,6 +57,7 @@ export function useVirtualScroll<DT extends Record<string, any>>(
|
|
|
57
57
|
rowKeyGen: RowKeyGen,
|
|
58
58
|
maxRowSpan: Map<UniqKey, number>,
|
|
59
59
|
scrollbarOptions: Ref<Required<ScrollbarOptions>>,
|
|
60
|
+
isExperimentalScrollY: Ref<boolean | undefined>,
|
|
60
61
|
) {
|
|
61
62
|
const tableHeaderHeight = computed(() => props.headerRowHeight * tableHeaders.value.length);
|
|
62
63
|
|
|
@@ -276,7 +277,7 @@ export function useVirtualScroll<DT extends Record<string, any>>(
|
|
|
276
277
|
const { enabled: scrollbarEnable } = scrollbarOptions.value;
|
|
277
278
|
if (scrollbarEnable) {
|
|
278
279
|
vsValue.scrollHeight = scrollHeight;
|
|
279
|
-
if (
|
|
280
|
+
if (isExperimentalScrollY.value) {
|
|
280
281
|
let maxTop: number;
|
|
281
282
|
sTop = sTop < 0 ? 0 : sTop < (maxTop = scrollHeight - containerHeight) ? sTop : maxTop;
|
|
282
283
|
vsValue.translateY = props.scrollRowByRow ? 0 : -(sTop % rowHeight);
|