feat: add support for diff rendering, apply and reject#2312
feat: add support for diff rendering, apply and reject#2312Saul-Mirone merged 13 commits intomainfrom
Conversation
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
@milkdown/components
@milkdown/core
@milkdown/crepe
@milkdown/ctx
@milkdown/exception
@milkdown/kit
@milkdown/prose
@milkdown/transformer
@milkdown/utils
@milkdown/react
@milkdown/vue
@milkdown/plugin-automd
@milkdown/plugin-block
@milkdown/plugin-clipboard
@milkdown/plugin-collab
@milkdown/plugin-cursor
@milkdown/plugin-diff
@milkdown/plugin-emoji
@milkdown/plugin-highlight
@milkdown/plugin-history
@milkdown/plugin-indent
@milkdown/plugin-listener
@milkdown/plugin-prism
@milkdown/plugin-slash
@milkdown/plugin-tooltip
@milkdown/plugin-trailing
@milkdown/plugin-upload
@milkdown/preset-commonmark
@milkdown/preset-gfm
@milkdown/theme-nord
commit: |
There was a problem hiding this comment.
Pull request overview
Adds a new diff-review capability to Milkdown (plugin + UI component) and wires it into Crepe, Storybook, and E2E so users can render diffs and accept/reject changes.
Changes:
- Introduces
@milkdown/plugin-diffwith commands/state for starting diff review and accepting/rejecting changes. - Adds a diff decoration component (
@milkdown/components/diff) to render inserted/removed content and per-change controls. - Integrates the feature into Crepe + Storybook demos and adds Playwright coverage.
Reviewed changes
Copilot reviewed 41 out of 44 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.json | Adds project reference for the new diff plugin package. |
| storybook/stories/plugins/diff.stories.ts | New Storybook story demonstrating diff review + commands. |
| storybook/stories/plugins/diff.css | Styling for diff decorations/controls used in the Storybook demo. |
| storybook/stories/crepe/setup.ts | Extends Crepe Storybook setup with diff args + a diff review toolbar helper. |
| storybook/stories/crepe/nord.stories.ts | Adds Crepe diff review story and hides diff args in non-diff stories. |
| storybook/stories/crepe/nord-dark.stories.ts | Adds Crepe diff review story and hides diff args in non-diff stories. |
| storybook/stories/crepe/frame.stories.ts | Adds Crepe diff review story and hides diff args in non-diff stories. |
| storybook/stories/crepe/frame-dark.stories.ts | Adds Crepe diff review story and hides diff args in non-diff stories. |
| storybook/stories/crepe/crepe.stories.ts | Adds Crepe diff review story and hides diff args in non-diff stories. |
| storybook/stories/crepe/crepe-dark.stories.ts | Adds Crepe diff review story and hides diff args in non-diff stories. |
| pnpm-lock.yaml | Adds workspace links for @milkdown/plugin-diff where needed. |
| packages/plugins/plugin-diff/vitest.config.ts | Vitest config for the new plugin package tests. |
| packages/plugins/plugin-diff/vite.config.ts | Vite build config for the new plugin package. |
| packages/plugins/plugin-diff/tsconfig.json | TS build config and references for the new plugin package. |
| packages/plugins/plugin-diff/src/types.ts | Defines diff state/config/action/range types. |
| packages/plugins/plugin-diff/src/index.ts | Public exports and diff plugin bundle. |
| packages/plugins/plugin-diff/src/diff-plugin.ts | ProseMirror plugin managing diff state + edit locking. |
| packages/plugins/plugin-diff/src/diff-config.ts | Context config slice for diff (e.g. lock-on-review). |
| packages/plugins/plugin-diff/src/diff-compute.ts | ChangeSet-based document diff computation with custom token encoding. |
| packages/plugins/plugin-diff/src/diff-commands.ts | Commands for starting review and accepting/rejecting changes. |
| packages/plugins/plugin-diff/src/test/diff-plugin.spec.ts | Unit tests for diff state helpers (pending/rejected filtering). |
| packages/plugins/plugin-diff/src/test/diff-compute.spec.ts | Unit tests for diff computation across node types. |
| packages/plugins/plugin-diff/src/internal/with-meta.ts | Metadata helper for plugin-diff plugins. |
| packages/plugins/plugin-diff/package.json | New published package definition for @milkdown/plugin-diff. |
| packages/kit/tsconfig.json | Adds TS reference to plugin-diff so kit can re-export it. |
| packages/kit/src/plugin/diff.ts | Re-export entry for @milkdown/kit/plugin/diff. |
| packages/kit/src/component/diff.ts | Re-export entry for @milkdown/kit/component/diff. |
| packages/kit/package.json | Adds subpath exports for kit diff plugin + diff component. |
| packages/crepe/src/theme/common/style.css | Includes diff theme CSS in the common Crepe theme bundle. |
| packages/crepe/src/theme/common/diff.css | Adds Crepe theme styling for diff decorations/controls. |
| packages/crepe/src/feature/loader.ts | Loads the new Crepe diff feature. |
| packages/crepe/src/feature/index.ts | Adds CrepeFeature.Diff and config typing/defaults. |
| packages/crepe/src/feature/diff/index.ts | Implements Crepe diff feature wiring (plugin + component config). |
| packages/components/tsconfig.json | Adds TS reference to plugin-diff for the new diff component. |
| packages/components/src/diff/index.ts | New diff component entry exporting config + decoration plugin. |
| packages/components/src/diff/diff-decoration-plugin.ts | Renders diff decorations/widgets + per-change accept/reject controls. |
| packages/components/src/diff/config.ts | Diff component configuration slice. |
| packages/components/package.json | Adds @milkdown/components/diff export and dependency on plugin-diff. |
| e2e/tests/crepe/diff.spec.ts | New Playwright coverage for diff review interactions. |
| e2e/src/data.ts | Registers the new crepe-diff e2e case. |
| e2e/src/crepe-diff/main.ts | E2E harness page exposing diff commands to tests. |
| e2e/src/crepe-diff/index.ts | Declares the “Crepe Diff” e2e case metadata. |
| e2e/src/crepe-diff/index.html | New e2e page entry for diff tests. |
| e2e/shim.d.ts | Adds global typings for diff-related e2e helpers. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 43 out of 46 changed files in this pull request and generated 3 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 43 out of 46 changed files in this pull request and generated 3 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 43 out of 46 changed files in this pull request and generated 2 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 43 out of 46 changed files in this pull request and generated 3 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 43 out of 46 changed files in this pull request and generated 3 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
This PR adds diff review support to milkdown. Users can compare two markdown documents side-by-side within the editor, see what changed, and accept or reject each change individually.
diff.mp4
What's new
@milkdown/plugin-diff— the headless diff engine. It computes changes between two ProseMirror documents using prosemirror-changeset (Myers diff), manages diff state (pending/rejected changes), and provides commands for accept/reject/clear operations. The editor is locked during review by default.@milkdown/components/diff— the decoration layer that renders the diff UI. Deletions get strikethrough (inline) or a faded overlay with red dashed outline (block). Insertions are shown as green widgets with the new content serialized from the target document. Each change has Accept/Reject buttons.Crepe integration —
CrepeFeature.Difffeature flag, theme CSS (diff.css) with CSS variables for all 6 themes, and a DiffReview story in every Storybook theme variant.Handling custom node views
ProseMirror's inline decorations can't penetrate custom node views (CodeMirror, image-block, table). To handle this, changes inside these nodes are merged into block-level replacements. Which node types get this treatment is configurable via
customBlockTypes— no node type names are hardcoded in the core packages.A custom token encoder makes prosemirror-changeset aware of atom node attribute changes (e.g. different image src), which the default encoder ignores.
Notable details
acceptDiffRange/rejectDiffRange) for merged block changes, so accepting a table change replaces the whole table at once instead of individual cellssnapToBlockBoundarywalks up the node tree to find the right insertion point, so widgets inside blockquotes/lists render at the correct positionfromB/toBcoordinates directly (not indices) to avoid index drift after previous rejectionsHow did you test this change?