Community Extension: multi-page-view #6076
Abhishek79201
started this conversation in
Community Extensions
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Description
I'm trying to build a multi-page text editor using TipTap (ProseMirror under the hood). My goal is to replicate something like Microsoft Word or Google Docs, where each page:
Has a fixed width (8.5" * 96 = 816px).
Has a fixed height (11" * 96 = 1056px).
Respects margins at the top, bottom, left, and right.
Visually shows page breaks when the content overflows onto the next page.
What I've Tried:
I measure each top-level block in the document using nodeDOM(nodeStart).getBoundingClientRect().
Whenever adding the next block would exceed the USABLE_HEIGHT_PX, I insert a custom “spacer” node into the document to simulate a page break.
I also have a PaginationPlugin that adds decorations (dashed lines) at those breakpoints.
The entire editor is wrapped in a container that stacks multiple “page backgrounds” (white rectangles with box-shadows).
Then I rely on absolute positioning for the editable text so it flows over multiple backgrounds.
I run the pagination logic on onUpdate with a small setTimeout or ResizeObserver to recalc page breaks.
Issues I'm Facing:
Flicker (Layout Jank): On every keystroke, the insertion/removal of “spacer” nodes causes multiple layout reflows. The page count changes frequently, causing flicker in the UI.
Accuracy of Page Breaks: Because I measure the DOM and then immediately modify it by inserting spacers, the measurements can sometimes be off, or cause new page breaks in an unexpected spot.
Performance: In larger documents, recalculating on every change (especially if it’s just a short keystroke) is expensive.
Key Questions:
How can I reduce flicker and repeated reflow while still getting accurate page breaks?
Is there a “best practice” for simulating or implementing true multi-page layout in TipTap/ProseMirror?
Would a “hidden measuring layer” approach or a purely decorative approach (no actual “spacer” nodes in the doc) be better? If so, how can I handle cursor/selection properly across pages?
Any suggestions to chunk the document into separate blocks for each page without losing continuity of content or selection?
My Current Code: Below is a simplified version showing how I’m currently doing it. I have some constants for page dimensions, a SpacerNode, a PageBreakExtension, a PaginationPlugin, plus a helper to calculate page breaks based on measured heights, and the main component.
Usage
you have to create react project and paste this code
Type
Other
Other
Any guidance or example code to help me:
Avoid flicker from repeated DOM measurements + doc changes.
Possibly measure in a hidden layer and then just visually split pages in the final layout (instead of physically inserting “spacer” nodes).
Or any other approach that yields a stable, multi-page doc view?
Thanks in advance for any help!
Beta Was this translation helpful? Give feedback.
All reactions