Skip to content

feat: support custom code block renderers - #546

Open
mariomile wants to merge 1 commit into
prosekit:masterfrom
mariomile:mario-codex/custom-code-block-renderers
Open

feat: support custom code block renderers#546
mariomile wants to merge 1 commit into
prosekit:masterfrom
mariomile:mario-codex/custom-code-block-renderers

Conversation

@mariomile

@mariomile mariomile commented Sep 10, 2026

Copy link
Copy Markdown

Code-block consumers currently cannot render host-owned widgets in the document while keeping fenced Markdown as the source of truth. This adds an optional renderCodeBlock callback that receives the fence language, body, and an undoable updateCode transaction.

Custom content renders at the code block's document position. The source stays hidden while the caret is elsewhere, reappears for keyboard editing when the caret enters the block, and falls back to the existing source/toolbar/preview whenever the callback returns null. Host widget lists are isolated from the outer editor's prose list styles while nested Markdown editors keep their own styling.

This also adds the opt-in insertMarkdown(markdown, { selection: 'after-block' }) path used by hosts inserting rendered fences from dialogs. It inserts a closed block slice, preserves any paragraph suffix, creates an ordinary following paragraph when needed, and places the caret there in the same undoable transaction.

Validation:

  • pnpm vitest run packages/core/src/extensions/commands.test.ts packages/react/src/components/code-block-view.test.tsx (53 tests)
  • pnpm typecheck
  • pnpm --filter @meowdown/core build
  • pnpm --filter @meowdown/react build
  • pnpm lint

Summary by CodeRabbit

  • New Features

    • Added support for custom rendering of code blocks, including synchronized content updates and undo support.
    • Added an option to place the cursor after an inserted Markdown block.
    • Improved code block styling for custom-rendered content.
    • Exposed new rendering and Markdown insertion options through the public editor API.
  • Bug Fixes

    • Ensured text following inserted code blocks remains outside the block.
    • Automatically creates a trailing paragraph when a block ends the document.

@mariomile
mariomile requested a review from ocavue as a code owner September 10, 2026 09:21
@vercel

vercel Bot commented Sep 10, 2026

Copy link
Copy Markdown

@mariomile is attempting to deploy a commit to the ocavue's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 1489d53a-b189-45b8-870f-19ad4a000eef

📥 Commits

Reviewing files that changed from the base of the PR and between 9d2f5af and 4e8c7fe.

📒 Files selected for processing (12)
  • packages/core/src/extensions/commands.test.ts
  • packages/core/src/extensions/commands.ts
  • packages/core/src/index.ts
  • packages/react/src/components/code-block-view.module.css
  • packages/react/src/components/code-block-view.module.d.css.ts
  • packages/react/src/components/code-block-view.test.tsx
  • packages/react/src/components/code-block-view.tsx
  • packages/react/src/components/editor.tsx
  • packages/react/src/components/prosekit-editor.tsx
  • packages/react/src/components/types.ts
  • packages/react/src/extensions/code-block-view.ts
  • packages/react/src/index.ts

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The PR adds an after-block option to Markdown insertion and supports host-provided code block rendering in the React editor. It updates public types, editor wiring, custom-content styles, and tests for insertion, rendering, editing, deletion, and undo behavior.

Changes

Code block insertion and rendering

Layer / File(s) Summary
After-block Markdown insertion
packages/core/src/extensions/commands.ts, packages/core/src/extensions/commands.test.ts, packages/core/src/index.ts
insertMarkdown accepts `selection: 'end'
Custom code block rendering
packages/react/src/components/code-block-view.tsx, packages/react/src/extensions/code-block-view.ts, packages/react/src/index.ts
Code blocks accept a renderCodeBlock callback. Custom content replaces the editable view, while updateCode writes changes back to the document.
Editor integration and validation
packages/react/src/components/editor.tsx, packages/react/src/components/prosekit-editor.tsx, packages/react/src/components/types.ts, packages/react/src/components/code-block-view.module.css, packages/react/src/components/code-block-view.module.d.css.ts, packages/react/src/components/code-block-view.test.tsx
React editor APIs forward the new renderer and insertion options. Styles isolate host-rendered lists. Tests cover fallback rendering, document order, updates, deletion, undo, and list styling.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 4e8c7

No concrete correctness, integration, or availability risk remains; the PR is ready for normal merge checks.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 13 functions across 11 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the primary change: support for custom code block renderers. It is concise and specific.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 13 functions across 11 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

Some tools did not complete. Review the errors below.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/core/src/extensions/commands.test.ts

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

packages/core/src/extensions/commands.ts

ESLint skipped: the matched ESLint configuration already failed (missing-dependency).

packages/core/src/index.ts

ESLint skipped: the matched ESLint configuration already failed (missing-dependency).

  • 9 others

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

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

@pkg-pr-new

pkg-pr-new Bot commented Sep 10, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@meowdown/core@546
npm i https://pkg.pr.new/@meowdown/markdown@546
npm i https://pkg.pr.new/@meowdown/react@546

commit: 4e8c7fe

Comment on lines +14 to +19
/**
* Where the caret lands after a code-block fragment. `after-block` keeps
* any paragraph suffix outside the inserted block and creates an ordinary
* following paragraph when needed.
*/
selection?: 'end' | 'after-block'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I feel this is not the correct way to add "an ordinary following paragraph" after a code block. We probably should provide a more general way, like a ProseMirror command.

@ocavue

ocavue commented Sep 10, 2026

Copy link
Copy Markdown
Member

#548 might provide better flexibility if you want to customize the code block React component

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.

2 participants