-
Notifications
You must be signed in to change notification settings - Fork 2
Codex/playground pagination toggle #438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
daff834
8a90361
604ca5d
e89b5c7
cc3fdfc
152285c
0dd73d9
0e46641
b453ce8
92a717d
70e839e
115156b
0daf893
86cc031
916c8b7
29974bd
c67a853
f3fd117
d7b435f
08aa7b2
90d1af6
5a498d6
9da7c0c
1645277
f73ae83
233dc17
3f3e212
bf6e694
77307c5
e92121a
3018354
54de7f7
8971d68
7432f0a
a4874d2
42cce98
b36b69b
3997ca3
75ed16c
ccc35a7
62de755
de96756
6cd84ab
e7be784
c8e5bf2
14686c6
419cd46
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@platejs/pagination": patch | ||
| --- | ||
|
|
||
| Mount the registry provider and reflow coordinator automatically from `PaginationPlugin`, so registering the plugin is all that is needed for pages to render and reflow |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@platejs/pagination": patch | ||
| --- | ||
|
|
||
| Fix `measureSnapshot` cache thrashing when the same block is measured at multiple widths. The cache now keys each entry by `(block id, width)` instead of block id alone, so alternating widths (resize, side-by-side editors) stay cached instead of overwriting one slot. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@platejs/pagination": patch | ||
| --- | ||
|
|
||
| `composeLayout` places blocks whole: a block that fits the remaining space is placed, otherwise it moves whole to the next page; a block taller than a full page is placed and overflows. No mid-block splitting. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@platejs/pagination": patch | ||
| --- | ||
|
|
||
| Add `getContinuousBreaks(layout)`: each interior page boundary named by the block (and line) that begins the next page. The continuous overlay anchors its advisory rule to that boundary block's live DOM top, so the line lands on a real block edge instead of a text-only pixel sum that ignores DOM margins. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@platejs/pagination": minor | ||
| --- | ||
|
|
||
| Add an `enabled` option (default `true`) to toggle pagination at runtime. When `false`, the React layer skips layout recompute and renders no page-break overlay; the document is never affected either way. Toggle with `editor.setOption(BasePaginationPlugin, 'enabled', next)`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@platejs/pagination": patch | ||
| --- | ||
|
|
||
| Build the layout `MappingIndex` once during `composeLayout` and expose it on `LayoutOutput.mapping`; projection reads it instead of rebuilding the index on every call. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| --- | ||
| "@platejs/pagination": patch | ||
| --- | ||
|
|
||
| Margin-aware page packing + continuous-overlay polish: | ||
|
|
||
| - Compose now packs pages by a block's **flow height** (text height + the DOM box spacing — margins/padding/borders — supplied by the measurer as `flowHeightPx`), falling back to text height when absent. The page count and break placement now match real DOM flow instead of under-counting per-page capacity. `heightPx`/`lineCount` stay text-only so line-level mapping is unaffected. | ||
| - Overlay labels show `Page N of M` and add a `Page 1 of M` marker, so the first page and total are always visible. | ||
| - Labels moved to the left margin gutter, so they stay on-screen when a narrow viewport overflows the page width. | ||
| - The recompute runs in a layout effect (before paint) instead of a post-paint `requestAnimationFrame`, so the advisory lines appear with the content as soon as the editor hydrates. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@platejs/pagination": patch | ||
| --- | ||
|
|
||
| Fix pagination not working for consumers on published `platejs`: use a literal `'pagination'` key instead of `KEYS.pagination` (unreleased in `@platejs/utils`), mount the registry provider and reflow coordinator in one shared subtree so reflow can read registered pages, and render the page number in each page's bottom margin |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@platejs/pagination": minor | ||
| --- | ||
|
|
||
| Make block measurement pretext-driven. `createDomMeasure` now resolves each block's font and content width from the live editable, then derives height from the line count pretext wraps the text to (new `measureBlockHeight`) — the line count, not the DOM box, owns layout height, so padding/margins no longer perturb pagination. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@platejs/pagination": minor | ||
| --- | ||
|
|
||
| Add `measureTextLines`: real text line-breaking via `@chenglou/pretext`. Given text, a CSS font string, and a content width it returns the wrapped visual lines — each with its text, measured width, and the segment/grapheme cursor range it spans — the foundation for line-accurate pagination (widow/orphan, split points, caret mapping). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@platejs/pagination": patch | ||
| --- | ||
|
|
||
| Continuous-view React host: `PaginationPlugin` runs the pretext pipeline (snapshot → measure → compose) against the live editable on content edits and width changes, then paints advisory page-break rules as an `afterEditable` overlay. Each rule anchors to the live DOM top of the block pretext chose to begin the next page (`breaks` option), so it lands on a real block edge; the `Page N` label sits in the right margin gutter. `pointer-events: none` keeps editing and selection fully native; the document is never mutated. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@platejs/pagination': minor | ||
| --- | ||
|
|
||
| Add `@platejs/pagination` package — render-time overlay pagination (variant A). Pages are derived from `editor.children` and painted as an `afterEditable` overlay; the document is never mutated. Includes header / footer / page-break element plugins, footnote sub-plugin bundling, a DOM-backed measurer with bounded LRU cache keyed by `(node.id, marks-fingerprint, font, width)`, and editor API (`getPages`, `getPageOf`, `getFootnotes`) plus transforms (`insertPageBreak`, `setHeader`, `setFooter`). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| "@platejs/pagination": major | ||
| --- | ||
|
|
||
| Remove the document-mutating pagination engine. Pagination is now a derived projection: the document model is never wrapped in `page` nodes or reflowed between pages. | ||
|
|
||
| Removes `BasePaginationPlugin`, `PaginationPlugin`, `PaginationCoordinator`, `PageElement`, the `registry`/`leaderElection` exports, and the `@platejs/pagination/yjs` entry. The package now exports only the pure layout pipeline: `buildSnapshot`, `measureSnapshot`, `composeLayout`, `getPageGeometry`, `alignContentToLayout`, and the mapping/projection helpers. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@platejs/pagination": patch | ||
| --- | ||
|
|
||
| `buildSnapshot` now records each block's concatenated `text` on the snapshot, so the measurement pass can line-break it. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@platejs/pagination": patch | ||
| --- | ||
|
|
||
| Fix page-break markers for editors whose block UI wraps Slate elements. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@platejs/utils': patch | ||
| --- | ||
|
|
||
| Add `KEYS.pagination`, `KEYS.header`, `KEYS.footer`, `KEYS.pageBreak` for the pagination plugin family |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -129,4 +129,4 @@ packages/plate/docs/ | |
|
|
||
| *.local* | ||
|
|
||
| .omx/ | ||
| .omx/dogfood-output/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| /// <reference types="next" /> | ||
| /// <reference types="next/image-types/global" /> | ||
| /// <reference types="next/navigation-types/compat/navigation" /> | ||
| import "./.next/types/routes.d.ts"; | ||
| import "./.next/dev/types/routes.d.ts"; | ||
|
|
||
| // NOTE: This file should not be edited | ||
| // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| import { PaginationView } from './pagination2-view'; | ||
|
|
||
| // Browser-only: the layout engine measures real DOM, so don't prerender. | ||
| export const dynamic = 'force-dynamic'; | ||
|
|
||
| export default function Page() { | ||
| return <PaginationView />; | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,71 @@ | ||||||||
| 'use client'; | ||||||||
|
|
||||||||
| import * as React from 'react'; | ||||||||
|
|
||||||||
| import { PaginationPlugin } from '@platejs/pagination/react'; | ||||||||
| import type { Value } from 'platejs'; | ||||||||
| import { Plate, PlateContent, usePlateEditor } from 'platejs/react'; | ||||||||
|
|
||||||||
| import { BasicNodesKit } from '@/registry/components/editor/plugins/basic-nodes-kit'; | ||||||||
|
|
||||||||
| const PAGE_W = 794; // A4 @ 96dpi | ||||||||
| const MARGIN = 96; // 1in | ||||||||
|
|
||||||||
|
Comment on lines
+11
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
rg -n '\b(PAGE_W|MARGIN)\b' apps/www/src/app/dev/pagination2/pagination2-view.tsxRepository: cicero-im/plate Length of output: 183 🏁 Script executed: #!/bin/bash
set -euo pipefail
FILE="apps/www/src/app/dev/pagination2/pagination2-view.tsx"
nl -ba "$FILE" | sed -n '1,25p'
echo '---'
nl -ba "$FILE" | sed -n '45,80p'Repository: cicero-im/plate Length of output: 102 🏁 Script executed: #!/bin/bash
set -euo pipefail
FILE="apps/www/src/app/dev/pagination2/pagination2-view.tsx"
cat -n "$FILE" | sed -n '1,25p'
echo '---'
cat -n "$FILE" | sed -n '50,75p'Repository: cicero-im/plate Length of output: 1741 Inline single-use layout literals (PAGE_W, MARGIN).
Proposed diff-const PAGE_W = 794; // A4 @ 96dpi
-const MARGIN = 96; // 1in
-
function makeValue(): Value {
@@
boxShadow: '0 2px 12px rgba(15,23,42,0.12)',
margin: '0 auto',
- padding: MARGIN,
+ padding: 96, // 1in
position: 'relative',
- width: PAGE_W,
+ width: 794, // A4 @ 96dpi
}}
>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||
| function makeValue(): Value { | ||||||||
| const out: Value = []; | ||||||||
| for (let i = 0; i < 40; i++) { | ||||||||
| if (i % 8 === 0) { | ||||||||
| out.push({ children: [{ text: `Section ${i / 8 + 1}` }], type: 'h2' }); | ||||||||
| } else { | ||||||||
| out.push({ | ||||||||
| children: [ | ||||||||
| { | ||||||||
| text: `Paragraph ${i}. This is a reasonably long paragraph of placeholder text so that the content reliably wraps onto multiple lines and flows across several A4 pages, exercising the pagination plugin end to end.`, | ||||||||
| }, | ||||||||
| ], | ||||||||
| type: 'p', | ||||||||
| }); | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| return out; | ||||||||
| } | ||||||||
|
|
||||||||
| /** | ||||||||
| * Continuous-view demo for the pagination plugin: a single A4-width editable in | ||||||||
| * normal flow; the plugin paints advisory page-break lines at each boundary. | ||||||||
| */ | ||||||||
| export function PaginationView() { | ||||||||
| const editor = usePlateEditor({ | ||||||||
| plugins: [...BasicNodesKit, PaginationPlugin], | ||||||||
| value: makeValue(), | ||||||||
| }); | ||||||||
|
|
||||||||
| return ( | ||||||||
| <div | ||||||||
| data-testid="pagination-desk" | ||||||||
| style={{ | ||||||||
| background: 'linear-gradient(#f3f4f6, #e5e7eb)', | ||||||||
| minHeight: '100vh', | ||||||||
| overflow: 'auto', | ||||||||
| padding: 24, | ||||||||
| }} | ||||||||
| > | ||||||||
| <div | ||||||||
| data-testid="pagination-stack" | ||||||||
| style={{ | ||||||||
| background: '#fff', | ||||||||
| boxShadow: '0 2px 12px rgba(15,23,42,0.12)', | ||||||||
| margin: '0 auto', | ||||||||
| padding: MARGIN, | ||||||||
| position: 'relative', | ||||||||
| width: PAGE_W, | ||||||||
| }} | ||||||||
| > | ||||||||
| <Plate editor={editor}> | ||||||||
| <PlateContent style={{ outline: 'none' }} /> | ||||||||
| </Plate> | ||||||||
| </div> | ||||||||
| </div> | ||||||||
| ); | ||||||||
| } | ||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| 'use client'; | ||
|
|
||
| import { PaginationPlugin } from '@platejs/pagination/react'; | ||
|
|
||
| // Continuous-view page-break overlay. Enabled by default so demos show page | ||
| // markers immediately; the toolbar button toggles it at runtime. | ||
| export const PaginationKit = [PaginationPlugin]; |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -384,6 +384,7 @@ export const uiComponents: Registry['items'] = [ | |||||||||||||||||
| 'media-toolbar-button', | ||||||||||||||||||
| 'mode-toolbar-button', | ||||||||||||||||||
| 'more-toolbar-button', | ||||||||||||||||||
| 'pagination-toolbar-button', | ||||||||||||||||||
| 'table-toolbar-button', | ||||||||||||||||||
| 'toggle-toolbar-button', | ||||||||||||||||||
| 'turn-into-toolbar-button', | ||||||||||||||||||
|
|
@@ -796,6 +797,15 @@ export const uiComponents: Registry['items'] = [ | |||||||||||||||||
| title: 'More Toolbar Button', | ||||||||||||||||||
| type: 'registry:ui', | ||||||||||||||||||
| }, | ||||||||||||||||||
| { | ||||||||||||||||||
| dependencies: ['@platejs/pagination'], | ||||||||||||||||||
| description: 'A toolbar button for page break markers.', | ||||||||||||||||||
| files: [{ path: 'ui/pagination-toolbar-button.tsx', type: 'registry:ui' }], | ||||||||||||||||||
|
Comment on lines
+800
to
+803
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update the component description to match behavior. The button toggles pagination on/off rather than inserting “page break markers”; the registry description should reflect that to avoid UI/docs mismatch. ✏️ Suggested wording tweak- description: 'A toolbar button for page break markers.',
+ description: 'A toolbar button to toggle pagination page-break guides.',📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
| name: 'pagination-toolbar-button', | ||||||||||||||||||
| registryDependencies: ['toolbar'], | ||||||||||||||||||
| title: 'Pagination Toolbar Button', | ||||||||||||||||||
| type: 'registry:ui', | ||||||||||||||||||
| }, | ||||||||||||||||||
| { | ||||||||||||||||||
| dependencies: ['@platejs/resizable'], | ||||||||||||||||||
| description: 'A resizable wrapper with resize handles.', | ||||||||||||||||||
|
|
||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| 'use client'; | ||
|
|
||
| import { PaginationPlugin } from '@platejs/pagination/react'; | ||
| import { SeparatorHorizontalIcon } from 'lucide-react'; | ||
| import { useEditorRef, usePluginOption } from 'platejs/react'; | ||
| import type * as React from 'react'; | ||
|
|
||
| import { ToolbarButton } from './toolbar'; | ||
|
|
||
| export function PaginationToolbarButton( | ||
| props: React.ComponentProps<typeof ToolbarButton> | ||
| ) { | ||
| const editor = useEditorRef(); | ||
| const enabled = usePluginOption(PaginationPlugin, 'enabled'); | ||
|
|
||
| return ( | ||
| <ToolbarButton | ||
| {...props} | ||
| onClick={() => editor.setOption(PaginationPlugin, 'enabled', !enabled)} | ||
| pressed={enabled} | ||
| tooltip="Page breaks" | ||
| > | ||
| <SeparatorHorizontalIcon /> | ||
| </ToolbarButton> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use latest-state doc voice instead of release-note/changelog phrasing.
This
.mdcontent is written as change narration. Reword it as current-state reference text only (no “what changed” framing).As per coding guidelines: “NEVER write changelog-style language in documentation (‘has been removed’, ‘new feature’, ‘previously’, ‘now supports’). Docs are user-facing reference for the LATEST state only.”
🤖 Prompt for AI Agents