Skip to content

Remove extra horizontal scrollbar space, improve row height estimation - #40

Closed
hovhannesmarikyan wants to merge 29 commits into
mainfrom
pre-release
Closed

Remove extra horizontal scrollbar space, improve row height estimation#40
hovhannesmarikyan wants to merge 29 commits into
mainfrom
pre-release

Conversation

@hovhannesmarikyan

Copy link
Copy Markdown

Problem

The grid's ideal-height calculation always reserved vertical space for a horizontal scrollbar, even when the content didn't actually overflow horizontally — leaving dead space below the grid in the
common case where everything fits.

For variable row heights (rowHeight as a function), the estimate also averaged only the first 10 rows and extrapolated that average across the entire dataset. On large, heterogeneous datasets this
could be significantly off, producing an incorrect ideal height and, ironically, a spurious scrollbar of its own.

Change

  • Extracted the ideal-size calculation out of data-editor.tsx into a pure, exported computeIdealSize function in data-editor-fns.ts so it's unit-testable in isolation.
  • Horizontal-scrollbar height is now only reserved when contentWidth > clientAreaWidth (i.e. the content actually overflows horizontally), removing the dead space in the non-overflowing case.
  • For function-based rowHeight, once the client area has been measured, the new logic sums exact row heights until the viewport is filled (with a minimum 10-row floor so the average isn't based on a
    single outlier row), then extrapolates the remainder from that average — instead of always averaging just the first 10 rows regardless of dataset size. This stays O(1)-ish for huge datasets while
    being far more accurate than the old fixed 10-row average.
  • Before the client area has been measured (first render), it still falls back to the bounded 10-row sample average, as before.
  • Memoized clientAreaWidth/clientAreaHeight as primitives out of clientSize so the idealWidth/idealHeight useMemo doesn't re-run on every scroll tick just because clientSize got a new array reference.

rahulyadav5524 and others added 29 commits December 18, 2025 12:40
Fix test to perform click with the pointer events.
`walkRowsInCol` does not clip scrolling rows at freezeY, so the last
visible scrolling row's y-range crosses into the freeze band. Glide's
normal flow relies on each column repainting the frozen row's fill after
the scrolling walk to overwrite that overflow. With a wide `span` this
short-circuits via `handledSpans` for every column after the first,
leaving scrolling-row content visible inside the frozen span; per-column
selection/highlight accents were also skipped for the same reason.

Fall through with `skipContents=true` for sticky rows so each column
repaints its own fill. Content stays drawn once by the initial span push.
Non-frozen spans keep the short-circuit — they don't hit the
overflow-into-freeze-band issue and rely on the wide-fill column for
highlightRegions.

Adds a regression test that fails without the fix.
`walkRowsInCol` does not clip scrolling rows at freezeY, so the last
visible scrolling row's y-range crosses into the freeze band. Glide's
normal flow relies on each column repainting the frozen row's fill after
the scrolling walk to overwrite that overflow. With a wide `span` this
short-circuits via `handledSpans` for every column after the first,
leaving scrolling-row content visible inside the frozen span; per-column
selection/highlight accents were also skipped for the same reason.

Fall through with `skipContents=true` for sticky rows so each column
repaints its own fill. Content stays drawn once by the initial span push.
Non-frozen spans keep the short-circuit — they don't hit the
overflow-into-freeze-band issue and rely on the wide-fill column for
highlightRegions.

Adds a regression test that fails without the fix.
Stop per-column repainting for spans in frozen trailing rows and
restore single-pass span rendering. Clamp scrollable row walking and
full redraw painting to the frozen-row boundary, with a sticky-span
exception to avoid group-row seam darkening. Update tests for the new
row count and span fill behavior.
The `onKeyDown` visible-region check treats frozen columns/rows as
always out of view, since the tracked scrollable region excludes
them by design. This silently blocks type-to-edit (pressing a
character key to start editing) for any cell inside a frozen
region, while Enter-to-edit and click-to-edit are unaffected since
neither consults the visible region.

Exempt cells inside `vr.extras.freezeRegions` from this check,
mirroring the identical `isInFreezeArea` pattern already used in
`getMangledCellContent`'s strict-mode branch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Header column reordering uses native HTML5 drag-and-drop. isActivelyDraggingHeader
is set true on mousedown for header cells, but was only ever cleared in onMouseUp.
Native DnD release delivers dragend, not mouseup, to the drag source, so the ref
stayed stuck true after any header drag. Every subsequent mousemove then re-armed
scrollDir from the live cursor position (see onMouseMoveImpl), driving the
autoscroll RAF loop indefinitely with no mouse button held, until the user
produced a real mouseup via an unrelated click.

Reset both isActivelyDraggingHeader and scrollDir in onDragEnd, which already
fires unconditionally on the native dragend event.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 32818558472

Coverage decreased (-0.04%) to 89.236%

Details

  • Coverage decreased (-0.04%) from the base build.
  • Patch coverage: 100 uncovered changes across 6 files (745 of 845 lines covered, 88.17%).
  • 6 coverage regressions across 2 files.

Uncovered Changes

File Changed Covered %
packages/core/src/internal/data-grid/render/data-grid-render.walk.ts 80 44 55.0%
packages/core/src/internal/data-grid/render/data-grid-render.blit.ts 44 9 20.45%
packages/core/src/data-editor/data-editor.tsx 139 121 87.05%
packages/core/src/internal/data-grid/render/data-grid-render.header.ts 201 196 97.51%
packages/core/src/internal/data-grid/render/data-grid-render.ts 75 71 94.67%
packages/core/src/internal/data-grid/data-grid.tsx 98 96 97.96%
Total (14 files) 845 745 88.17%

Coverage Regressions

6 previously-covered lines in 2 files lost coverage.

File Lines Losing Coverage Coverage
packages/core/src/data-editor/data-editor.tsx 4 87.83%
packages/core/src/internal/data-grid/render/data-grid-render.header.ts 2 81.95%

Coverage Stats

Coverage Status
Relevant Lines: 20506
Covered Lines: 18608
Line Coverage: 90.74%
Relevant Branches: 3788
Covered Branches: 3071
Branch Coverage: 81.07%
Branches in Coverage %: Yes
Coverage Strength: 3250.79 hits per line

💛 - Coveralls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants