.agents/skills/plate-plugin-creator/rules/composition.md
If the semantic base exists, wrap it.
Prefer:
export const MentionPlugin = toPlatePlugin(BaseMentionPlugin);
over re-declaring the same semantics in createPlatePlugin.
plugins array when they are
part of the semantic contract.Good example:
export const CodeBlockPlugin = toPlatePlugin(BaseCodeBlockPlugin, {
plugins: [CodeLinePlugin, CodeSyntaxPlugin],
});
If you need to adjust a nested child plugin, use configurePlugin instead of
copy-pasting a new child plugin definition.
That keeps the ownership boundary obvious and preserves shared behavior.
extend
Merge config or compute context-aware config.extendPlugin
Reach into a nested plugin when the parent owns that decision.overrideEditor
Change editor behavior itself.handlers
Use for events that actually belong at the plugin boundary, not as a dumping
ground for logic that should be a transform or editor override.transformProps For React-Only Node AugmentationWhen the job is "augment props on already-rendered nodes in the Plate layer",
prefer inject.nodeProps.transformProps.
This is especially good when:
Good fits:
BlockSelectionPluginNavigationFeedbackPluginDo not over-apply this rule. transformProps is for prop augmentation. It is
not a blanket replacement for node.component, render, wrapper plugins, or
useHooks.
Keep helpers inline when they are single-use and context-local.
If you extract a helper:
SlateEditor by habitDo not create abstraction sludge just because a callback body is slightly long.