Skip to content

Show row resize guideline and keep scroll on page 2#172

Merged
hackerwins merged 2 commits into
mainfrom
fix/table-resize-page2-guideline
May 1, 2026
Merged

Show row resize guideline and keep scroll on page 2#172
hackerwins merged 2 commits into
mainfrom
fix/table-resize-page2-guideline

Conversation

@hackerwins

Copy link
Copy Markdown
Collaborator

Summary

  • Row resize drag guideline now appears on the page where the cursor is, not off-screen, when the document is scrolled past page 1.
  • Resizing a row on page 2 with the caret on page 1 no longer snaps the viewport back to page 1.
  • Defensive refactor: renderer and hit-test share getTableOriginYForPageLine, so the row-border hit area can no longer drift away from the painted border on a split-row continuation page.

Root causes

Guideline off-screen (editor.ts): The drag-guideline draw runs after docCanvas.render() has restored the canvas context to identity, but dragGuideline.x/y are in unscaled document coordinates. Drawing at canvas pixel y = absolute_doc_y placed the horizontal line below the visible viewport when scrolled (e.g. scrollTop ≈ 1118 → line drawn at y = 1605, canvas height ~787). The vertical (column) guideline accidentally worked because scrollLeft is normally 0. Convert to canvas pixels with (coord - scroll) * scaleFactor for both axes — also correct under mobile zoom-to-fit.

Viewport snap on resize (editor.ts + text-editor.ts): applyBorderDrag requested a render through the path that always sets needsScrollIntoView = true, so the next paint scrolled the cursor (still on page 1) into view. Added requestRenderNoCursorScroll for layout-only changes that don't move the caret.

Latent split-row hit-test bug (pagination.ts + doc-canvas.ts + text-editor.ts): The renderer used pageY + pl.y - rowYOffsets[lineIndex] - rowSplitOffset to position a continuation fragment, but the resolver used bandTop - rowYOffsets[firstPl.lineIndex] (no rowSplitOffset). On a page that starts with a row-split continuation, the resolver's virtual table origin diverged from the renderer's by the page-1 fragment height, so row-border hit-testing missed every row by that offset. Extracted getTableOriginYForPageLine(pageY, pl, rowYOffsets) so both paths share the same formula. The helper bounds-checks lineIndex so any future split-rendering regression fails loudly instead of silently producing NaN coordinates.

Pre-push harness fix (knip.json): With docs registered in knip workspaces, knip used main/module from packages/docs/package.json (which point at dist/) as its only entry roots — so once docs was built, knip flagged scripts/verify-ime-browser.mjs as unused dead code and broke verify:entropy in the pre-push harness. Add a packages/docs workspace block matching the sheets pattern.

Test plan

  • pnpm verify:fast (684/684 tests pass)
  • pnpm verify:entropy passes after building docs
  • Puppeteer reproduction of guideline bug on the user's shared doc:
    • row resize drag at page 2 → blue dashed horizontal guideline visible under cursor (was invisible)
    • column resize drag → vertical guideline still visible (no regression)
    • resize row on page 2 with caret on page 1 → viewport stays at scrollTop=1118 (was snapping back to 0)
  • New table-origin-y.test.ts regression: helper returns the same virtual origin for the split fragment and follow-up rows on the same page; reverting the rowSplitOffset term in the helper makes this test fail.

🤖 Generated with Claude Code

hackerwins and others added 2 commits May 1, 2026 18:10
Two user-reported bugs interacted on tables that live on page 2 of a
multi-page document.

Row resize drag guideline was painted off-screen because `editor.ts`
draws the guideline AFTER `docCanvas.render()` has restored the canvas
context to identity, but `dragGuideline.x/y` are in unscaled document
coordinates. With a `scrollTop ≈ 1118`, the horizontal line landed at
canvas pixel y ≈ 1605, well below the visible area. Vertical (column)
guidelines accidentally worked because horizontal scroll is normally
zero. Convert the coords with `(coord - scroll) * scaleFactor` so both
axes track the cursor under any scroll or zoom-to-fit.

Resize on page 2 with the caret on page 1 snapped the viewport back
to page 1 because `applyBorderDrag` requested a full render through
the path that always sets `needsScrollIntoView = true`. The user did
not move the caret, so the next paint scrolled it into view, undoing
their scroll. Add a `requestRenderNoCursorScroll` callback for
layout-only changes that don't move the caret and have the resize
path use it.

While there, extract `getTableOriginYForPageLine` in `pagination.ts`
so renderer (`DocCanvas`) and hit-test (`TextEditor.resolveTableFromMouse`)
share the same virtual-origin formula. The resolver had been dropping
the `rowSplitOffset` term that the renderer applied — a latent bug
that would offset the row-border hit area by the page-1 fragment
height when a row split lands as the first PageLine on the next page.
The helper bounds-checks `lineIndex` so future split-rendering
regressions fail loudly instead of silently producing NaN coordinates.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Without this entry, knip used `main`/`module` from
`packages/docs/package.json` (which point at `dist/`) as its only
entry roots, so once the docs package was built `verify:entropy`
flagged `packages/docs/scripts/verify-ime-browser.mjs` as unused dead
code and broke the pre-push harness. Add a workspace block matching
the sheets pattern so knip scans `src/`, `test/`, and `scripts/*.mjs`
as legitimate entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@hackerwins has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 49 minutes and 30 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a0ae94f9-369c-4b74-988f-966bdce6ca94

📥 Commits

Reviewing files that changed from the base of the PR and between a008f65 and 4ab6682.

📒 Files selected for processing (10)
  • docs/tasks/README.md
  • docs/tasks/active/20260501-table-resize-row-split-lessons.md
  • docs/tasks/active/20260501-table-resize-row-split-todo.md
  • docs/tasks/archive/README.md
  • knip.json
  • packages/docs/src/view/doc-canvas.ts
  • packages/docs/src/view/editor.ts
  • packages/docs/src/view/pagination.ts
  • packages/docs/src/view/text-editor.ts
  • packages/docs/test/view/table-origin-y.test.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/table-resize-page2-guideline

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 49 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@hackerwins
hackerwins merged commit 888d1ad into main May 1, 2026
1 check passed
@hackerwins
hackerwins deleted the fix/table-resize-page2-guideline branch May 1, 2026 09:24
@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor

Verification: verify:self

Result: ✅ PASS in 129.3s

Lane Status Duration
sheets:build ✅ pass 13.5s
docs:build ✅ pass 11.1s
verify:fast ✅ pass 64.1s
frontend:build ✅ pass 17.6s
verify:frontend:chunks ✅ pass 0.3s
backend:build ✅ pass 4.8s
cli:build ✅ pass 1.8s
verify:entropy ✅ pass 15.9s

Verification: verify:integration

Result: ✅ PASS

@codecov

codecov Bot commented May 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 33.33333% with 20 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
packages/docs/src/view/editor.ts 0.00% 8 Missing ⚠️
packages/docs/src/view/text-editor.ts 0.00% 6 Missing ⚠️
packages/docs/src/view/pagination.ts 61.53% 5 Missing ⚠️
packages/docs/src/view/doc-canvas.ts 66.66% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@hackerwins hackerwins mentioned this pull request May 1, 2026
3 tasks
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.

1 participant