Skip to content

fix(MiddleRowFocus): preserve scroll anchor across table operations#756

Merged
lcottercertinia merged 1 commit into
certinia:mainfrom
lukecotter:feat-row-focus-improvements
May 9, 2026
Merged

fix(MiddleRowFocus): preserve scroll anchor across table operations#756
lcottercertinia merged 1 commit into
certinia:mainfrom
lukecotter:feat-row-focus-improvements

Conversation

@lukecotter
Copy link
Copy Markdown
Contributor

📝 PR Overview

Improves row-focus behavior so the user's scroll position is preserved across table operations (sort, filter, single tree toggle) instead of always recentering on the middle visible row.

🛠️ Changes made

  • Capture scroll anchor on dataSorting (Tabulator resets scrollTop before renderStarted, so the previous capture point lost the pre-sort row).
  • Anchor boundaries: when the user is at the top or bottom edge before an operation, restore to that edge instead of centering.
  • Single tree toggle: skip the next recenter so scrollTop stays put. Bulk toggles (expand-all / collapse-all) detect a synchronous burst and run the recenter as before.
  • Workaround for Tabulator filter bug where rerenderRows leaves .tabulator-table paddingTop inflated — detect (scrollTop < paddingTop) and zero it plus vDomTopPad on the next frame.
  • Tests covering middle-row math, sort capture, boundary anchoring, single vs. bulk toggle, and the filter padding mitigation.

🧩 Type of change (check all applicable)

  • 🐛 Bug fix - something not working as expected
  • ✨ New feature – adds new functionality
  • ♻️ Refactor - internal changes with no user impact
  • ⚡ Performance Improvement
  • 📝 Documentation - README or documentation site changes
  • 🔧 Chore - dev tooling, CI, config
  • 💥 Breaking change

📷 Screenshots / gifs / video [optional]

n/a

🔗 Related Issues

fixes #
resolves #
closes #
related #

✅ Tests added?

  • 👍 yes
  • 🙅 no, not needed
  • 🙋 no, I need help

📚 Docs updated?

  • 🔖 README.md
  • 🔖 CHANGELOG.md
  • 📖 help site
  • 🙅 not needed

Anything else we need to know? [optional]

The filter padding fix is a workaround in MiddleRowFocus rather than a direct edit to tabulator_esm.mjs. See tabulator-virtual-scroll-fixes.md "Fix 7" for the related upstream patch context.

Replace the always-recenter behavior with operation-aware scroll
 preservation, addressing four distinct symptoms:

- Single tree expand/collapse no longer jumps to center: a one-shot
  skipNextRender flag is armed on the first toggle of a burst and
  cleared by a second toggle in the same tick, so single toggles
  preserve scrollTop while expand-all/collapse-all still recenters.

- Column sort no longer scrolls to the top: the anchor is captured in
  the dataSorting pre-event instead of renderStarted, since Tabulator
  resets scrollTop before renderStarted fires for sort.

- Filter no longer leaves a blank strip across the top of the table:
  detect the inflated .tabulator-table paddingTop left by Tabulator's
  rerenderRows desync (pre-filter vDomTop/vDomBottom against post-filter
  rows) and zero both paddingTop and renderer.vDomTopPad on the next
  frame. Upstream fix tracked in tabulator-virtual-scroll-fixes.md.

- At-top / at-bottom no longer jumps off the edge: capture wasAtTop /
  wasAtBottom alongside the middle row using a 10px threshold, and on
  restore snap to scrollTop = 0 / scrollHeight - clientHeight instead
  of centering.

Anchor capture/restore is consolidated behind \_captureAnchor /
 \_restoreAnchor / \_clearAnchor so future fields snapshot in one place.

Add unit tests covering each path: single-toggle skip, bulk-toggle
 fall-through, dataSorting pre-capture, paddingTop reset (stale and
 legitimate), and at-top / at-bottom boundary snapping.
@lcottercertinia lcottercertinia merged commit 6416732 into certinia:main May 9, 2026
5 checks passed
@lukecotter lukecotter deleted the feat-row-focus-improvements branch May 9, 2026 15:40
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.

2 participants