fix(grid): keep DOM results at the first row

This commit is contained in:
t8y2 committed 2026-08-27 11:08:42 +08:00
1 parent 8bc31d3319
commit d2326acb81
3 files changed
+36 -1

No files matched your search

@@ -608,3 +608,34 @@ describe("DataGrid visible large-value preview lifecycle", () => {
expect(visibleHydrationCalls()).toHaveLength(0);
});
});
describe("DataGrid DOM initial scroll position", () => {
it("keeps the first row visible while the virtual list finishes measuring", async () => {
const { host, replaceResult } = mountGrid(hydratedResult(1, "value"));
await settle();
const scroller = host.querySelector<HTMLElement>(".data-grid-scroller");
if (!scroller) throw new Error("Data grid scroller not found");
Object.defineProperties(scroller, {
scrollTop: { configurable: true, writable: true, value: 0 },
scrollWidth: { configurable: true, value: 1200 },
clientWidth: { configurable: true, value: 600 },
clientHeight: { configurable: true, value: 500 },
scrollHeight: {
configurable: true,
get: () => (scroller.classList.contains("has-horizontal-scrollbar") ? 2600 : 500),
},
});
replaceResult({
columns: ["id", "payload"],
rows: Array.from({ length: 100 }, (_, index) => [index + 1, `row-${index + 1}`]),
affected_rows: 0,
execution_time_ms: 0,
});
await settle();
expect(scroller.classList.contains("has-horizontal-scrollbar")).toBe(true);
expect(scroller.scrollTop).toBe(0);
});
});
@@ -29,6 +29,10 @@ describe("data grid bottom anchoring", () => {
it("does not anchor a user who is away from the bottom", () => {
expect(isDataGridAtScrollBottom({ scrollTop: 700, scrollHeight: 1000, clientHeight: 260 })).toBe(false);
});
it("does not treat an unmeasured non-scrollable grid as bottom-anchored", () => {
expect(isDataGridAtScrollBottom({ scrollTop: 0, scrollHeight: 500, clientHeight: 500 })).toBe(false);
});
});
describe("data grid horizontal restoration", () => {
@@ -69,7 +69,7 @@ export function didDataGridInfiniteScrollContextChange(current: readonly string[
export function isDataGridAtScrollBottom(metrics: DataGridScrollMetrics, tolerance = 1): boolean {
const maxScrollTop = Math.max(0, metrics.scrollHeight - metrics.clientHeight);
return maxScrollTop - metrics.scrollTop <= tolerance;
return maxScrollTop > tolerance && maxScrollTop - metrics.scrollTop <= tolerance;
}
export function dataGridBottomScrollTop(metrics: Pick<DataGridScrollMetrics, "scrollHeight" | "clientHeight">): number {