mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-08 11:31:57 +08:00
🐛 fix(data-grid): 修复筛选应用后横向滚动导致字段值错位
- 数据刷新后重置滚动恢复标记,允许重新同步横向偏移 - 虚拟表格恢复滚动时统一走 applyVirtualHorizontalOffset,避免表头与单元格错位 - 补充 DataGrid 横向滚动恢复回归断言 - Refs #508
This commit is contained in:
@@ -500,6 +500,12 @@ describe('DataGrid layout', () => {
|
||||
expect(source).toContain('return originalRenderContent;');
|
||||
expect(source).toContain('if (scrollSnapshotRafRef.current !== null) return;');
|
||||
expect(source).toContain('scrollSnapshotRafRef.current = requestAnimationFrame');
|
||||
expect(source).toContain('didRestoreScrollRef.current = false;');
|
||||
expect(source).toContain('useEffect(() => {');
|
||||
expect(source).toContain('}, [connectionId, dbName, tableName, data]);');
|
||||
expect(source).toContain('const applied = applyVirtualHorizontalOffset(tableContainer, nextLeft);');
|
||||
expect(source).toContain('resolvedLeft = readVirtualHorizontalOffset(tableContainer);');
|
||||
expect(source).toContain('lastReportedScrollRef.current = { top: nextTop, left: resolvedLeft };');
|
||||
expect(source).toContain("const dataGridBackdropFilter = isV2Ui || isMacLike ? 'none' : (opacity < 0.999 ? 'blur(14px)' : 'none');");
|
||||
expect(source).toContain('rowHoverable={!enableVirtual}');
|
||||
expect(columnTitleSource).toContain("data-grid-column-highlighted={highlighted ? 'true' : undefined}");
|
||||
|
||||
@@ -1920,6 +1920,12 @@ const DataGrid: React.FC<DataGridProps> = ({
|
||||
const lastReportedScrollRef = useRef<{ top: number; left: number }>({ top: 0, left: 0 });
|
||||
const didRestoreScrollRef = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
// 结果集刷新后需要允许重新恢复滚动位置;否则筛选/排序重载时可能只保留外部滚动条位置,
|
||||
// 但虚拟表格内部横向偏移已被重建为初始值,进而造成表头与单元格错位。
|
||||
didRestoreScrollRef.current = false;
|
||||
}, [connectionId, dbName, tableName, data]);
|
||||
|
||||
// 批量编辑模式状态
|
||||
const [cellEditMode, setCellEditMode] = useState(false);
|
||||
const [selectedCells, setSelectedCells] = useState<Set<string>>(new Set());
|
||||
@@ -6781,32 +6787,49 @@ const DataGrid: React.FC<DataGridProps> = ({
|
||||
|
||||
let rafId = requestAnimationFrame(() => {
|
||||
const verticalTarget = pickVerticalScrollTarget(tableContainer);
|
||||
const horizontalTargets = pickHorizontalScrollTargets(tableContainer);
|
||||
const nextTop = Math.max(0, scrollSnapshot.top);
|
||||
const nextLeft = Math.max(0, scrollSnapshot.left);
|
||||
if (verticalTarget && Math.abs(verticalTarget.scrollTop - scrollSnapshot.top) > 1) {
|
||||
verticalTarget.scrollTop = nextTop;
|
||||
}
|
||||
let resolvedLeft = nextLeft;
|
||||
if (Math.abs(nextLeft) > 0.5) {
|
||||
horizontalTargets.forEach(target => {
|
||||
if (Math.abs(target.scrollLeft - nextLeft) > 1) {
|
||||
target.scrollLeft = nextLeft;
|
||||
if (enableVirtual) {
|
||||
const applied = applyVirtualHorizontalOffset(tableContainer, nextLeft);
|
||||
if (applied) {
|
||||
resolvedLeft = readVirtualHorizontalOffset(tableContainer);
|
||||
} else {
|
||||
const fallbackTargets = pickHorizontalScrollTargets(tableContainer);
|
||||
fallbackTargets.forEach(target => {
|
||||
if (Math.abs(target.scrollLeft - nextLeft) > 1) {
|
||||
target.scrollLeft = nextLeft;
|
||||
}
|
||||
});
|
||||
resolvedLeft = fallbackTargets[0]?.scrollLeft ?? nextLeft;
|
||||
}
|
||||
});
|
||||
const externalScroll = externalHorizontalScrollRef.current;
|
||||
if (externalScroll && Math.abs(externalScroll.scrollLeft - nextLeft) > 1) {
|
||||
externalScroll.scrollLeft = nextLeft;
|
||||
} else {
|
||||
const horizontalTargets = pickHorizontalScrollTargets(tableContainer);
|
||||
horizontalTargets.forEach(target => {
|
||||
if (Math.abs(target.scrollLeft - nextLeft) > 1) {
|
||||
target.scrollLeft = nextLeft;
|
||||
}
|
||||
});
|
||||
resolvedLeft = horizontalTargets[0]?.scrollLeft ?? nextLeft;
|
||||
}
|
||||
lastTableScrollLeftRef.current = nextLeft;
|
||||
lastExternalScrollLeftRef.current = nextLeft;
|
||||
const externalScroll = externalHorizontalScrollRef.current;
|
||||
if (externalScroll && Math.abs(externalScroll.scrollLeft - resolvedLeft) > 1) {
|
||||
externalScroll.scrollLeft = resolvedLeft;
|
||||
}
|
||||
lastTableScrollLeftRef.current = resolvedLeft;
|
||||
lastExternalScrollLeftRef.current = resolvedLeft;
|
||||
}
|
||||
lastReportedScrollRef.current = { top: nextTop, left: nextLeft };
|
||||
lastReportedScrollRef.current = { top: nextTop, left: resolvedLeft };
|
||||
didRestoreScrollRef.current = true;
|
||||
onScrollSnapshotChange?.({ top: nextTop, left: nextLeft });
|
||||
onScrollSnapshotChange?.({ top: nextTop, left: resolvedLeft });
|
||||
});
|
||||
|
||||
return () => cancelAnimationFrame(rafId);
|
||||
}, [isTableSurfaceActive, mergedDisplayData.length, scrollSnapshot, pickHorizontalScrollTargets, pickVerticalScrollTarget, onScrollSnapshotChange]);
|
||||
}, [applyVirtualHorizontalOffset, data, enableVirtual, isTableSurfaceActive, mergedDisplayData.length, onScrollSnapshotChange, pickHorizontalScrollTargets, pickVerticalScrollTarget, readVirtualHorizontalOffset, scrollSnapshot]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isTableSurfaceActive) return;
|
||||
|
||||
Reference in New Issue
Block a user