Skip to content

feat(pagination): add enabled option to toggle pagination at runtime#424

Open
arthrod wants to merge 2 commits into
codex/pagination-dogfood-fixesfrom
codex/pagination-enabled-option
Open

feat(pagination): add enabled option to toggle pagination at runtime#424
arthrod wants to merge 2 commits into
codex/pagination-dogfood-fixesfrom
codex/pagination-enabled-option

Conversation

@arthrod
Copy link
Copy Markdown
Collaborator

@arthrod arthrod commented May 24, 2026

Stacked on codex/pagination-dogfood-fixes. Adds a public enabled option to @platejs/pagination so consumers can turn pagination on/off at runtime.

Change

  • BasePaginationPlugin gains enabled: boolean (default true).
  • React layer consumes it: the overlay renders nothing and the layout recompute is skipped when enabled === false. Toggling re-renders (subscribed option) so re-enabling recomputes from the dirty registry. The document is never mutated either way.
  • Toggle at runtime: editor.setOption(BasePaginationPlugin, 'enabled', next).
  • Changeset: minor.

TDD

Red→green on the new public contract (base option seam, createSlateEditor):

  • enables pagination by default — watched it fail (enabled undefined), then declared the option.
  • can be disabled via options.

The React overlay/hook gating is thin glue consuming the tested option (the package's React overlay has no unit tests — only pure geometry; no render-test infra, and the testing-strategy skill forbids adding devDeps for it).

Verification

  • Package: build ✓, typecheck ✓, 51/51 tests ✓, biome clean on changed files.
  • Full monorepo check not run (its eslint . sweep OOMs here; disproportionate for a one-option package change).

🤖 Generated with Claude Code

`enabled` (default true) on BasePaginationPlugin. When false, the React
layer skips layout recompute and renders no overlay; document never
affected. Toggle via editor.setOption(BasePaginationPlugin,'enabled',next).
TDD: base option contract (default true, configurable). Changeset: minor.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@arthrod
Copy link
Copy Markdown
Collaborator Author

arthrod commented May 24, 2026

@coderabbitai review very carefully and fix

@arthrod
Copy link
Copy Markdown
Collaborator Author

arthrod commented May 24, 2026

@gemini review very carefully and fix

@arthrod
Copy link
Copy Markdown
Collaborator Author

arthrod commented May 24, 2026

@Kilo review very carefully and fix

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 24, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

Let me gather the PR details and code changes first.


🏁 Script executed:

#!/bin/bash
# Get PR details and diff
gh pr view 424 --repo cicero-im/plate --json title,body,files,additions,deletions,commits

echo "=== PR DIFF ==="
gh pr diff 424 --repo cicero-im/plate

Length of output: 7737


Let me get more context on the existing implementation to do a thorough review.


🏁 Script executed:

#!/bin/bash
echo "=== Full PaginationPlugin.tsx ==="
cat packages/pagination/src/react/PaginationPlugin.tsx

echo ""
echo "=== Full BasePaginationPlugin.ts ==="
cat packages/pagination/src/lib/BasePaginationPlugin.ts

echo ""
echo "=== Full test file ==="
cat packages/pagination/src/lib/__tests__/BasePaginationPlugin.spec.ts

echo ""
echo "=== Check exports ==="
cat packages/pagination/src/lib/index.ts 2>/dev/null || echo "No lib/index.ts"
cat packages/pagination/src/index.ts 2>/dev/null || echo "No src/index.ts"

echo ""
echo "=== Check if enabled is exported ==="
rg "enabled" packages/pagination/src/ -n

Length of output: 13848


@arthrod I've done a careful review. Here's what I found:


Review Summary

🐛 Bug: ResizeObserver effect has a stale enabled closure

File: packages/pagination/src/react/PaginationPlugin.tsx

The useEffect for the ResizeObserver only has [editor] in its dependency array, but its callback closes over enabled. This means the enabled value captured at observer-setup time is never refreshed:

// enabled is stale here — never updated when the option changes
useEffect(() => {
  ...
  const observer = new ResizeObserver(() => {
    invalidateLayoutRegistry(editor);
    forceRecompute((n) => n + 1); // always fires, even when enabled=false
  });
  ...
}, [editor]); // ← enabled missing from deps

Consequences:

  • If pagination starts disabled, the observer will never call forceRecompute, so resizing while later re-enabling won't force a re-render to pick up the new width.
  • If pagination starts enabled, the observer always calls forceRecompute even when disabled, causing needless re-renders that the layout effect then throws away with if (!enabled) return.

Fix: add enabled to deps and guard forceRecompute:

useEffect(() => {
  const editable = editor.api.toDOMNode(editor);
  if (!editable || typeof ResizeObserver === 'undefined') return;

  const observer = new ResizeObserver(() => {
    invalidateLayoutRegistry(editor); // always: keeps dirty flag fresh for re-enable
    if (enabled) forceRecompute((n) => n + 1); // only re-render when active
  });
  observer.observe(editable);

  return () => observer.disconnect();
}, [editor, enabled]); // ← enabled added

🧪 Missing tests

Two behaviors are described in the PR but have no test coverage:

  1. Runtime toggle via editor.setOption — the advertised public API has no test.
  2. Content edit while disabled marks registry dirty — described as the mechanism that lets re-enabling recompute, but not asserted.

  • Fix stale enabled closure in ResizeObserver useEffect by adding enabled to its deps and guarding forceRecompute
  • Add test: runtime toggle via editor.setOption
  • Add test: content edit while disabled still invalidates the registry

·.¸¸.·´¯·.¸¸.·´¯·.¸¸.·´¯) 🐇 (·.¸¸.·´¯·.¸¸.·´¯·.¸¸.·´¯)


The requested changes have been implemented and a pull request has been created: View PR

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces an enabled option to the pagination plugin, allowing users to toggle pagination at runtime. When disabled, the plugin skips layout recomputations and avoids rendering page-break overlays. The changes include updates to the plugin configuration, React hooks, and the addition of unit tests to verify the new functionality. A review comment suggested optimizing the PaginationBreakLines component by moving the enabled check before DOM lookups to prevent unnecessary processing.

Comment on lines 72 to +73
const editable = editor.api.toDOMNode(editor);
if (!editable || breaks.length === 0) return null;
if (!enabled || !editable || breaks.length === 0) return null;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The enabled check should ideally occur before calling editor.api.toDOMNode(editor) to avoid unnecessary DOM lookups when pagination is disabled.

Suggested change
const editable = editor.api.toDOMNode(editor);
if (!editable || breaks.length === 0) return null;
if (!enabled || !editable || breaks.length === 0) return null;
if (!enabled) return null;
const editable = editor.api.toDOMNode(editor);
if (!editable || breaks.length === 0) return null;

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4219c3bc-da1e-41f0-9352-c96cdb9b94f1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/pagination-enabled-option

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

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