docs/plans/2026-05-30-fix-pagination-virtualized-selection-shift.md
Objective:
Fix the virtualized pagination bug where selecting a paragraph shifts its text left on /examples/pagination?page_layout=single&strategy=virtualized.
Completion threshold: The bug is reproduced before the fix, covered by focused Playwright regression, fixed at the pagination/native-flow ownership boundary, typechecked, formatted, and reviewed with no accepted actionable findings.
Verification surface:
site/examples/ts/pagination.tsx owns the selected/native-flow render path. playwright/integration/examples/pagination.test.ts owns the browser regression for projected text becoming native flow after selection.
Constraints: Keep the patch scoped to virtualized pagination selected text. Do not change staged pagination, non-virtualized layout, projection geometry, package exports, registry output, commits, PRs, or tracker state.
Boundaries:
.tmp/slate-v2 pagination example and its Playwright integration test..tmp/slate-v2/site/examples/ts/pagination.tsx, .tmp/slate-v2/playwright/integration/examples/pagination.test.ts, and this goal plan.http://localhost:3100/examples/pagination?page_layout=single&strategy=virtualized.Blocked condition: None. The bug was reproducible locally and the focused proof runs.
Work Checklist:
.tmp/slate-v2..tmp/slate-v2 except this plan check.Start Gates:
| Gate | Applies | Evidence |
|---|---|---|
| Skill analysis before edits | yes | Used slate-patch and autogoal for a browser/editor bug with measurable proof. |
| Active goal checked or created | yes | Active Codex goal created for this virtualized selection shift. |
| Source of truth read before edits | yes | Read pagination projection/render code and nearby pagination Playwright tests. |
| TDD decision before behavior change | yes | Added failing focused Playwright regression before the fix. |
| Browser route identified | yes | /examples/pagination?page_layout=single&strategy=virtualized. |
| Browser tool decision recorded | yes | Browser plugin tool discovery did not expose a browser control tool; used repo Playwright harness. |
Completion Gates:
| Gate | Applies | Evidence |
|---|---|---|
| Bug reproduced before fix | yes | Before fix, projected leaf left was 341px and selected native-flow leaf left was 339px. |
| Targeted behavior verification | yes | Focused Playwright alignment test passes after the fix. |
| TypeScript changed | yes | bun typecheck:site passed in .tmp/slate-v2. |
| Formatting | yes | bunx biome check --write site/examples/ts/pagination.tsx playwright/integration/examples/pagination.test.ts passed in .tmp/slate-v2. |
| Browser surface changed | yes | Playwright exercised the target route and selection transition. |
| Package exports or install graph | no | N/A: no package export, manifest, lockfile, or install graph changes. |
| Changeset | no | N/A: example/test-only fix in Slate v2 checkout. |
| Autoreview | yes | Local autoreview ran for the pagination alignment patch; result recorded below. |
| PR or tracker sync | no | N/A: user asked for local fix, not git or tracker update. |
Phase / pass table:
| Phase | Status | Evidence | Next |
|---|---|---|---|
| Intake and source read | complete | Route, repro, projection and render paths identified. | implementation |
| Implementation | complete | Added selected/native-flow inline inset for virtualized text blocks. | verification |
| Verification | complete | Formatter, site typecheck, focused Playwright proofs passed. | closeout |
| Review | complete | Autoreview result handled. | final response |
| Closeout | complete | Plan and goal ready to close. | final response |
Findings:
PAGE_CONTENT_INLINE_INSET, but the selected paragraph switches to native flow text and previously started at the block left edge.Decisions and tradeoffs:
Implementation notes:
paddingLeft: PAGE_CONTENT_INLINE_INSET for flowElement && usesVirtualizedLayout text blocks.Review fixes:
wrapWidthPreserved.Error attempts:
| Error / failed attempt | Count | Next different move | Resolution |
|---|---|---|---|
| Red focused Playwright regression before fix | 1 | Apply native-flow inset in virtualized render path. | Green after patch. |
Verification evidence:
.tmp/slate-v2: bunx biome check --write site/examples/ts/pagination.tsx playwright/integration/examples/pagination.test.ts.tmp/slate-v2: bun typecheck:site.tmp/slate-v2: PLAYWRIGHT_BASE_URL=http://localhost:3100 PLAYWRIGHT_RETRIES=0 PLAYWRIGHT_WORKERS=1 bun playwright playwright/integration/examples/pagination.test.ts --project=chromium --grep "keeps virtualized pagination text aligned".tmp/slate-v2: PLAYWRIGHT_RETRIES=0 PLAYWRIGHT_WORKERS=1 bun playwright playwright/integration/examples/pagination.test.ts --project=chromium --grep "keeps virtualized pagination text aligned|moves the cursor between the first two virtualized"Final handoff contract:
Open risks: None known for this scoped fix. Broader pagination interactions remain covered by adjacent focused Playwright tests, not a full browser sweep.
Final handoff / sync:
Reboot status:
| Question | Answer |
|---|---|
| Where am I? | Closeout |
| Where am I going? | Final response after autoreview and plan check |
| What is the goal? | Fix selected paragraph left shift in virtualized pagination |