Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "fix: avoid selection gap with frozen rows\n\n",
"type": "none",
"packageName": "@visactor/vtable"
}
],
"packageName": "@visactor/vtable",
"email": "892739385@qq.com"
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,30 @@ describe('listTable init test', () => {
expect(listTable.cellIsInVisualView(3, 39)).toBe(true);
expect(listTable.cellIsInVisualView(3, 38)).toBe(true);
});

test('listTable body visible row range should ignore frozen rows offset duplication', () => {
const optionWithFrozenRows = {
...option,
frozenRowCount: 5,
rightFrozenColCount: 0,
bottomFrozenRowCount: 0,
container: createDiv(),
records
};
optionWithFrozenRows.container.style.position = 'relative';
optionWithFrozenRows.container.style.width = '1000px';
optionWithFrozenRows.container.style.height = '800px';

const frozenTable = new ListTable(optionWithFrozenRows);
frozenTable.scrollTop = 400;

expect(frozenTable.getBodyVisibleRowRange()).toEqual({
rowStart: 10,
rowEnd: 28
});
expect(frozenTable.getBodyVisibleCellRange()).toMatchObject({
rowStart: 10,
rowEnd: 28
});
});
});
81 changes: 81 additions & 0 deletions packages/vtable/examples/debug/issue-5027.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import * as VTable from '../../src';

const CONTAINER_ID = 'vTable';

function createRecords(count: number) {
return Array.from({ length: count }, (_, index) => ({
name: `John ${index + 1}`,
age: 18 + (index % 10),
gender: index % 2 === 0 ? 'male' : 'female',
hobby: index % 3 === 0 ? '🏀' : index % 3 === 1 ? '🎸' : '📚'
}));
}

export function createTable() {
const container = document.getElementById(CONTAINER_ID);
if (!container) {
throw new Error('Cannot find VTable container');
}
const option: VTable.ListTableConstructorOptions = {
container,
columns: [
{
field: 'name',
title: 'name',
width: 180
},
{
field: 'age',
title: 'age',
width: 120
},
{
field: 'gender',
title: 'gender',
width: 140
},
{
field: 'hobby',
title: 'hobby',
width: 140
}
],
records: createRecords(2000),
frozenRowCount: 5,
heightMode: 'standard',
widthMode: 'standard',
select: {
headerSelectMode: 'inline',
highlightMode: 'column'
},
theme: VTable.themes.DEFAULT.extends({
scrollStyle: {
visible: 'always',
hoverOn: false
}
})
};

const tableInstance = new VTable.ListTable(option);

// Preselect the age column so the scrollbar drag issue can be reproduced immediately.
tableInstance.selectCol(1);

const info = document.createElement('div');
info.style.cssText = ['margin: 8px 0', 'font-size: 12px', 'line-height: 18px', 'color: #333'].join(';');
info.innerText = 'issue-5027: drag the vertical scrollbar while the age column is selected and frozenRowCount is 5.';
container.parentElement?.insertBefore(info, container);

const w = window as unknown as {
tableInstance?: VTable.ListTable;
issue5027?: {
table: VTable.ListTable;
selectAgeColumn: () => void;
};
};
w.tableInstance = tableInstance;
w.issue5027 = {
table: tableInstance,
selectAgeColumn: () => tableInstance.selectCol(1)
};
}
4 changes: 4 additions & 0 deletions packages/vtable/examples/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export const menus = [
{
path: 'debug',
name: 'issue-5114'
},
{
path: 'debug',
name: 'issue-5027'
}
]
},
Expand Down
17 changes: 11 additions & 6 deletions packages/vtable/src/core/BaseTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2503,17 +2503,19 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {
/** 获取表格body部分的显示单元格范围 */
getBodyVisibleCellRange() {
const { scrollTop, scrollLeft } = this;
const frozenRowsHeight = this.getFrozenRowsHeight();
const frozenColsContentWidth = this.getFrozenColsContentWidth();
const frozenColsOffset = this.getFrozenColsOffset();
const bottomFrozenRowsHeight = this.getBottomFrozenRowsHeight();
const rightFrozenColsWidth = this.getRightFrozenColsWidth();
// 计算非冻结
const { row: rowStart } = this.getRowAt(scrollTop + frozenRowsHeight + 1);
const rowStart = Math.max(this.getTargetRowAt(scrollTop + 1)?.row ?? -1, this.frozenRowCount);
const { col: colStart } = this.getColAt(scrollLeft + frozenColsContentWidth + 1);
const rowEnd =
this.getAllRowsHeight() > this.tableNoFrameHeight
? this.getRowAt(scrollTop + this.tableNoFrameHeight - 1 - bottomFrozenRowsHeight).row
? Math.max(
this.getTargetRowAt(scrollTop + this.tableNoFrameHeight - 1 - bottomFrozenRowsHeight)?.row ?? -1,
rowStart
)
: this.rowCount - 1;
const colEnd =
this.getAllColsWidth() > this.tableNoFrameWidth
Expand All @@ -2532,13 +2534,16 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {
*/
getBodyVisibleRowRange(start_deltaY: number = 0, end_deltaY: number = 0) {
const { scrollTop } = this;
const frozenRowsHeight = this.getFrozenRowsHeight();
const bottomFrozenRowsHeight = this.getBottomFrozenRowsHeight();
// 计算非冻结
const { row: rowStart } = this.getRowAt(scrollTop + frozenRowsHeight + 1 + start_deltaY);
const rowStart = Math.max(this.getTargetRowAt(scrollTop + 1 + start_deltaY)?.row ?? -1, this.frozenRowCount);
const rowEnd =
this.getAllRowsHeight() > this.tableNoFrameHeight
? this.getRowAt(scrollTop + this.tableNoFrameHeight - 1 - bottomFrozenRowsHeight + end_deltaY).row
? Math.max(
this.getTargetRowAt(scrollTop + this.tableNoFrameHeight - 1 - bottomFrozenRowsHeight + end_deltaY)?.row ??
-1,
rowStart
)
: this.rowCount - 1;
if (rowEnd < 0) {
return null;
Expand Down
Loading