feat: expose TipTap/ProseMirror globals for custom rich editor extensions#19559
Open
leek wants to merge 4 commits intofilamentphp:4.xfrom
Open
feat: expose TipTap/ProseMirror globals for custom rich editor extensions#19559leek wants to merge 4 commits intofilamentphp:4.xfrom
leek wants to merge 4 commits intofilamentphp:4.xfrom
Conversation
Custom extensions loaded via RichContentPlugin::getTipTapJsExtensions() are fetched at runtime via dynamic import(). Each extension bundle must currently include its own copy of TipTap/ProseMirror, leading to: - Duplicate ProseMirror instances on the page - instanceof checks failing across bundles (e.g. DecorationSet) - ~150-200 KB of redundant JS per extension This adds window.Filament.TipTap with the core ProseMirror modules (@tiptap/core, @tiptap/pm/state, @tiptap/pm/view, @tiptap/pm/model) already bundled in rich-editor.js. Custom extension builds can mark @tiptap/* as external and resolve from this global at runtime, sharing the same ProseMirror instance as the host editor. Non-breaking: existing extensions that bundle their own TipTap continue to work unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Custom extensions loaded via
RichContentPlugin::getTipTapJsExtensions()are fetched at runtime via dynamicimport(). Each extension bundle must currently include its own copy of TipTap/ProseMirror because there's no way to reference the copy already bundled inrich-editor.js. This leads to:instanceoffailures across bundles (e.g.DecorationSet,Node,Mark) — requiring monkey-patches to work around@tiptap/core,prosemirror-state, etc.)This is particularly painful for Tiptap Pro extensions (Pages, TableKit) which import heavily from
@tiptap/coreand@tiptap/pm/*.Solution
Expose
window.Filament.TipTapwith the core ProseMirror modules that are already bundled inrich-editor.js:Custom extension builds can then mark
@tiptap/*as external and resolve from this global at runtime, sharing the exact same ProseMirror instance as the host editor.Example: esbuild plugin for custom extensions
Changes
packages/forms/resources/js/components/rich-editor-entry.js— new thin wrapper that exposeswindow.Filament.TipTapand re-exports the existing Alpine componentbin/build.js— points the rich-editor build at the wrapper entry pointpackages/forms/dist/components/rich-editor.js— rebuilt (bundle size unchanged — the modules were already included, we're just assigning them towindow)Non-breaking
Existing custom extensions that bundle their own TipTap continue to work unchanged. This simply gives extension authors the option to externalize
@tiptap/*and eliminate duplicate ProseMirror instances.