docs/migration/index.mdx
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
platejs:
@udecode/plate/react with platejs/react'@udecode/plate' with 'platejs'@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.Replaced editor.api.shouldMergeNodesRemovePrevNode with editor.api.shouldMergeNodes. shouldMergeNodes is now controlling the remove + merge behavior
true if the default merging behavior should be applied.false if the default merging behavior should not be applied. This is used by Plate to prevent void blocks deletion, and to prioritize empty block deletion over merging.// Before
editor.api.shouldMergeNodesRemovePrevNode(prev, current);
// After
editor.api.shouldMergeNodes(prev, current);
Replace editor.api.fragment option structuralTypes with unwrap.
// Before
editor.api.fragment(editor.selection, { structuralTypes: ['table'] });
// After
editor.api.fragment(editor.selection, { unwrap: ['table'] });
editor.getType() now takes a pluginKey: string instead of a plugin: PlatePlugin instance.
editor.getType(ParagraphPlugin.key) instead of editor.getType(ParagraphPlugin).key property will not be registered into the editor.disabled: true prop to PlateContent will now also set the editor to readOnly: true state internally.editor.dom namespace:
editor.currentKeyboardEvent is now editor.dom.currentKeyboardEvent.editor.prevSelection is now editor.dom.prevSelection.editor.meta namespace:
editor.isFallback is now editor.meta.isFallbackeditor.key is now editor.meta.keyeditor.pluginList is now editor.meta.pluginListeditor.shortcuts is now editor.meta.shortcutseditor.uid is now editor.meta.uidNodeIdPlugin is now enabled by default as part of the core plugins. This automatically assigns unique IDs to block nodes.
NodeIdPlugin and wish to maintain the old behavior (no automatic IDs), explicitly disable it in your editor configuration:
const editor = usePlateEditor({
// ...other options
nodeId: false, // Disables automatic node ID generation
});
components prop has been removed from serializeHtml and PlateStatic.
components to createSlateEditor({ components }) or the individual plugins instead.editor.shortcuts are now namespaced by the plugin key (e.g., code.toggle for CodePlugin).priority property for shortcuts is used to resolve conflicts when multiple shortcuts share the exact same key combination, not for overriding shortcuts by name.preventDefault for plugin shortcuts now defaults to true, unless the handler returns false (i.e. not handled). This means browser default actions for these key combinations will be prevented unless explicitly allowed.
preventDefault: false in its configuration:
MyPlugin.configure({
shortcuts: {
myAction: {
keys: 'mod+s',
preventDefault: false, // Example: Allow browser's default save dialog
},
},
});
@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.editor.dom:
editor.dom.composing: Boolean, true if the editor is currently composing text (e.g., during IME input).editor.dom.focused: Boolean, true if the editor currently has focus.editor.dom.readOnly: Boolean, true if the editor is in read-only mode. Passing the readOnly prop to PlateContent will sync its value to this state and to the useEditorReadOnly hook.editor.meta.components - stores the plugin components by keyuseEditorComposing: Allows subscription to the editor's composing state (editor.dom.composing) outside of PlateContent.createPlateEditor and usePlateEditor now accept a readOnly option to initialize the editor in a read-only state. For dynamic read-only changes after initialization, continue to use the readOnly prop on the <Plate> or <PlateContent> component.editOnly (boolean or object).
true or when specific properties are true in the object, Plate will disable certain plugin behaviors (handlers, rendering, injections) in read-only mode and re-enable them if the editor becomes editable.render, handlers, and inject are considered edit-only (true). normalizeInitialValue defaults to always active (false).editOnly: { render: false, normalizeInitialValue: true } would make rendering active always, but normalization only in edit mode.render.as (keyof HTMLElementTagNameMap).
PlateElement (default: 'div') or PlateLeaf (default: 'span') when rendering the node, but only if no custom node.component is provided for the plugin.render: { as: 'h1' } would make the plugin render its node as an <h1> tag by default without the need to provide a custom component.node.isContainer (boolean).
true, indicates that the plugin's elements are primarily containers for other content.node.isStrictSiblings (boolean).
true, indicates that the element enforces strict sibling type constraints and only allows specific siblings (e.g., td can only have td siblings, column can only have column siblings).editor.tf.insertExitBreak functionality to determine appropriate exit points in nested structures.rules (object).
rules.break: Controls Enter key behavior (empty, default, emptyLineEnd, splitReset)rules.delete: Controls Backspace key behavior (start, empty)rules.merge: Controls block merging behavior (removeEmpty)rules.normalize: Controls normalization behavior (removeEmpty)rules.selection: Controls cursor positioning behavior (affinity)rules.match: Conditional rule application based on node propertieseditor.tf.escape: Handle Escape key events. Returns true if the event is handled.editor.tf.moveLine: Handle ArrowDown and ArrowUp key events with reverse option for direction. Returns true if the event is handled.editor.tf.selectAll: Handle Ctrl/Cmd+A key events for selecting all content. Returns true if the event is handled.editor.tf.tab: Handle Tab and Shift+Tab key events with reverse option for Shift+Tab. Returns true if the event is handled.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.Node type definitions (e.g., TImageElement, TParagraphElement) previously co-located with their respective plugin packages (like @udecode/plate-media) have been centralized into @platejs/utils. These are typically re-exported via the main platejs package.
Migration: Update imports for these types to pull from platejs.
// Before
// import { TImageElement } from '@udecode/plate-media';
// After
import { TImageElement } from 'platejs';
Removed structuralTypes option from useSelectionFragment and useSelectionFragmentProp. These hooks now automatically use plugin.node.isContainer from enabled plugins.
Removed:
createNodesHOCcreateNodesWithHOCcreateNodeHOCRemoved usePlaceholderState hook.
BlockPlaceholderPlugin (typically from platejs) instead of the withPlaceholders HOC and usePlaceholderState. Configure placeholders directly within the BlockPlaceholderPlugin options.
// Example BlockPlaceholderPlugin configuration
BlockPlaceholderPlugin.configure({
options: {
className:
'before:absolute before:cursor-text before:opacity-30 before:content-[attr(placeholder)]',
placeholders: {
[ParagraphPlugin.key]: 'Type something...',
// ...other placeholders
},
query: ({ editor, path }) => {
// Example query: only show for top-level empty blocks
return (
path.length === 1 && editor.api.isEmpty(editor.children[path[0]])
);
},
},
});
editor.api.copilot.accept is now editor.tf.copilot.accept.editor.api.copilot.acceptNextWord is now editor.tf.copilot.acceptNextWord.editor.api.copilot.reset is now editor.api.copilot.reject.accept (Tab) and reject (Escape) shortcuts are included by default for CopilotPlugin.acceptNextWord and triggerSuggestion shortcuts must now be configured manually using the shortcuts field when configuring the plugin.CopilotPlugin.configure({
// ... other options
shortcuts: {
acceptNextWord: {
keys: 'mod+right',
},
triggerSuggestion: {
keys: 'ctrl+space',
},
},
});
@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.Package @udecode/plate-alignment has been deprecated.
TextAlignPlugin (formerly AlignPlugin) has been moved to the @platejs/basic-styles package.
Migration:
@udecode/plate-alignment from your dependencies.@platejs/basic-styles to your dependencies if not already present.TextAlignPlugin from @platejs/basic-styles/react.Renamed AlignPlugin to TextAlignPlugin and changed plugin key from 'align' to 'textAlign'.
// Before
import { AlignPlugin } from '@udecode/plate-alignment/react';
// After
import { TextAlignPlugin } from '@platejs/basic-styles/react';
setAlign signature change:
// Before
setAlign(editor, { value: 'center', setNodesOptions });
// After
setAlign(editor, 'center', setNodesOptions);
useAlignDropdownMenu and useAlignDropdownMenuState. Use it in your own codebase, for example:export function AlignToolbarButton() {
const editor = useEditorRef();
const value = useSelectionFragmentProp({
defaultValue: 'start',
structuralTypes,
getProp: (node) => node.align,
});
const onValueChange = (newValue: string) => {
editor.tf.textAlign.setNodes(newValue as Alignment);
editor.tf.focus();
};
// ...
}
BaseAutoformatPlugin with AutoformatPlugin, which is no longer a React plugin. Migration: Replace @udecode/plate-autoformat/react import with @udecode/plate-autoformat.editOnly: true. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure its editOnly field. For example, SomePlugin.configure({ editOnly: false }).@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-basic-elements has been deprecated.BasicElementsPlugin has been renamed to BasicBlocksPlugin.@platejs/basic-nodes package.@udecode/plate-basic-elements with @platejs/basic-nodes in your dependencies.@udecode/plate-basic-elements/react to @platejs/basic-nodes/react.@platejs/basic-nodes.@udecode/plate-basic-marks has been deprecated.@platejs/basic-nodes package.@udecode/plate-basic-marks with @platejs/basic-nodes in your dependencies.@udecode/plate-basic-marks/react to @platejs/basic-nodes/react.@platejs/basic-nodes.@udecode/plate-basic-elements and @udecode/plate-basic-marks have been deprecated. All their plugins are now consolidated into the new @platejs/basic-nodes package.@udecode/plate-basic-elements and @udecode/plate-basic-marks in your dependencies with @platejs/basic-nodes.@udecode/plate-basic-elements/react or @udecode/plate-basic-marks/react to @platejs/basic-nodes/react.CodeBlockPlugin is not part of @platejs/basic-nodes. Ensure it is imported from @platejs/code-block/react.SkipMarkPlugin (standalone) is removed. Its functionality is now built into the core editor. To enable boundary clearing for a specific mark, configure the mark plugin directly: plugin.configure({ rules: { selection: { affinity: 'outward' } } }).@udecode/plate-basic-nodes (e.g., BlockquotePlugin, HeadingPlugin, HorizontalRulePlugin) now default to rendering with specific HTML tags (<blockquote>, <h1>-<h6>, <hr> respectively). ParagraphPlugin still defaults to <div>. If you relied on previous defaults or need different tags, provide a custom component or use the render.as option.@udecode/plate-basic-nodes (e.g., BoldPlugin, CodePlugin, ItalicPlugin) now default to specific HTML tags (<strong>, <code>, <em> respectively). If you relied on previous defaults or need different tags, provide a custom component or use the render.as option.shortcuts field in plugin configuration.H1Plugin.configure({ shortcuts: { toggle: { keys: 'mod+alt+1' } } });
BlockquotePlugin.configure({
shortcuts: { toggle: { keys: 'mod+shift+period' } },
});
CodePlugin.configure({ shortcuts: { toggle: { keys: 'mod+e' } } });
StrikethroughPlugin.configure({
shortcuts: { toggle: { keys: 'mod+shift+x' } },
});
SubscriptPlugin.configure({
shortcuts: { toggle: { keys: 'mod+comma' } },
});
SuperscriptPlugin.configure({
shortcuts: { toggle: { keys: 'mod+period' } },
});
HighlightPlugin.configure({
shortcuts: { toggle: { keys: 'mod+shift+h' } },
});
@udecode/plate-block-quote has been deprecated.BlockquotePlugin has been moved to the @platejs/basic-nodes package.@udecode/plate-block-quote from your dependencies.@platejs/basic-nodes to your dependencies if not already present.BlockquotePlugin from @platejs/basic-nodes/react.Package @udecode/plate-break has been deprecated.
SoftBreakPlugin has been removed. Migration:
shift+enter rules: no migration is needed - this behavior is built into Plate by default.enter rules: use plugin.configure({ rules: { break: { default: 'lineBreak' } } }) to insert a line break instead of a hard break on Enter keydown when the selection is within the configured node type.overrideEditor to override the insertBreak transform with custom logic.ExitBreakPlugin has been moved to @platejs/utils (which is re-exported via platejs) with a simplified API and improved behavior.
Behavior Change: Instead of always exiting to the root level of the document, exiting will now insert a block to the nearest exitable ancestor that has isStrictSiblings: false. This means deeply nested structures (like tables in columns) are exitable at many levels.
Migration:
Remove @udecode/plate-break from your dependencies.
Replace @udecode/plate-break import with platejs.
Important: If not using Plate plugins, you must set isStrictSiblings: true on your custom node plugins that can't have paragraph siblings for exit break to work correctly.
Replace complex rule-based configuration with simple shortcuts:
// Before (old API)
ExitBreakPlugin.configure({
options: {
rules: [
{ hotkey: 'mod+enter' },
{ hotkey: 'mod+shift+enter', before: true },
],
},
});
// After (new API)
ExitBreakPlugin.configure({
shortcuts: {
insert: { keys: 'mod+enter' },
insertBefore: { keys: 'mod+shift+enter' },
},
});
@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.CaptionPlugin option options.plugins (accepting an array of PlatePlugin) has been renamed to options.query.allow (accepting an array of plugin keys).
Migration:
// Before
CaptionPlugin.configure({
options: {
plugins: [ImagePlugin], // ImagePlugin is an example
},
});
// After
CaptionPlugin.configure({
options: {
query: {
allow: [ImagePlugin.key], // Use the plugin's key
},
},
});
@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.CodeBlockPlugin now defaults to rendering the code block container with a <pre> HTML tag if no custom component is provided for CodeBlockElement (or the plugin key code_block).@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.CommentsPlugin has been renamed to CommentPlugin.CommentsPlugin.key becomes CommentPlugin.key.@platejs/comment.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.editOnly: true. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure its editOnly field. For example, SomePlugin.configure({ editOnly: false }).@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.editOnly: true. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure its editOnly field. For example, SomePlugin.configure({ editOnly: false }).@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.editOnly: true. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure its editOnly field. For example, SomePlugin.configure({ editOnly: false }).@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.setBlockBackgroundColorsetFontSize – use tf.fontSize.addMark instead:// Before
editor.api.fontSize.addMark('16px');
// After
editor.tf.fontSize.addMark('16px');
useColorInput. Use it in your own codebase, for example:function ColorInput() {
const inputRef = React.useRef<HTMLInputElement | null>(null);
const onClick = () => {
inputRef.current?.click();
};
// ...
}
useColorsCustom and useColorsCustomState. Use it in your own codebase, for example:function ColorCustom({ color, colors, customColors, updateCustomColor }) {
const [customColor, setCustomColor] = React.useState<string>();
const [value, setValue] = React.useState<string>(color || '#000000');
React.useEffect(() => {
if (
!color ||
customColors.some((c) => c.value === color) ||
colors.some((c) => c.value === color)
) {
return;
}
setCustomColor(color);
}, [color, colors, customColors]);
const computedColors = React.useMemo(
() =>
customColor
? [
...customColors,
{
isBrightColor: false,
name: '',
value: customColor,
},
]
: customColors,
[customColor, customColors]
);
const updateCustomColorDebounced = React.useCallback(
debounce(updateCustomColor, 100),
[updateCustomColor]
);
const inputProps = {
value,
onChange: (e: React.ChangeEvent<HTMLInputElement>) => {
setValue(e.target.value);
updateCustomColorDebounced(e.target.value);
},
};
// ...
}
useColorDropdownMenu and useColorDropdownMenuState. Use it in your own codebase, for example:export function FontColorToolbarButton({ nodeType }) {
const editor = useEditorRef();
const selectionDefined = useEditorSelector(
(editor) => !!editor.selection,
[]
);
const color = useEditorSelector(
(editor) => editor.api.mark(nodeType) as string,
[nodeType]
);
const [selectedColor, setSelectedColor] = React.useState<string>();
const [open, setOpen] = React.useState(false);
const onToggle = React.useCallback(
(value = !open) => {
setOpen(value);
},
[open, setOpen]
);
const updateColor = React.useCallback(
(value: string) => {
if (editor.selection) {
setSelectedColor(value);
editor.tf.select(editor.selection);
editor.tf.focus();
editor.tf.addMarks({ [nodeType]: value });
}
},
[editor, nodeType]
);
const clearColor = React.useCallback(() => {
if (editor.selection) {
editor.tf.select(editor.selection);
editor.tf.focus();
if (selectedColor) {
editor.tf.removeMarks(nodeType);
}
onToggle();
}
}, [editor, selectedColor, onToggle, nodeType]);
React.useEffect(() => {
if (selectionDefined) {
setSelectedColor(color);
}
}, [color, selectionDefined]);
// ...
}
@udecode/plate-heading has been deprecated.
HeadingPlugin and individual heading plugins (e.g., H1Plugin) have been moved to @platejs/basic-nodes.
@platejs/basic-nodes/react (e.g., import { HeadingPlugin } from '@platejs/basic-nodes/react';).TocPlugin has been moved to @platejs/toc.
@platejs/toc to your dependencies and import TocPlugin from @platejs/toc/react.@udecode/plate-heading from your dependencies.HEADING_LEVELS has been removed. Use KEYS.heading instead.@udecode/plate-highlight has been deprecated.HighlightPlugin has been moved to the @platejs/basic-nodes package.@udecode/plate-highlight from your dependencies.@platejs/basic-nodes to your dependencies if not already present.HighlightPlugin from @platejs/basic-nodes/react.@udecode/plate-horizontal-rule has been deprecated.HorizontalRulePlugin has been moved to the @platejs/basic-nodes package.@udecode/plate-horizontal-rule from your dependencies.@platejs/basic-nodes to your dependencies if not already present.HorizontalRulePlugin from @platejs/basic-nodes/react.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-indent-list has been renamed to @platejs/list.@udecode/plate-indent-list to @platejs/list.package.json: remove @udecode/plate-indent-list and add @platejs/list.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-kbd has been deprecated.KbdPlugin has been moved to the @platejs/basic-nodes package.@udecode/plate-kbd from your dependencies.@platejs/basic-nodes to your dependencies if not already present.KbdPlugin from @platejs/basic-nodes/react.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.Package @udecode/plate-line-height has been deprecated.
LineHeightPlugin has been moved to the @platejs/basic-styles package.
Migration:
@udecode/plate-line-height from your dependencies.@platejs/basic-styles to your dependencies if not already present.LineHeightPlugin from @platejs/basic-styles/react.setLineHeight signature change:
// Before
setLineHeight(editor, { value: 1.5, setNodesOptions });
// After
setLineHeight(editor, 1.5, setNodesOptions);
useLineHeightDropdownMenu and useLineHeightDropdownMenuState. Use it in your own codebase, for example:export function LineHeightToolbarButton() {
const editor = useEditorRef();
const { defaultNodeValue, validNodeValues: values = [] } =
editor.getInjectProps(LineHeightPlugin);
const value = useSelectionFragmentProp({
defaultValue: defaultNodeValue,
getProp: (node) => node.lineHeight,
});
const onValueChange = (newValue: string) => {
editor.tf.lineHeight.setNodes(Number(newValue));
editor.tf.focus();
};
// ...
}
@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-list (classic list implementation) has been moved to @platejs/list-classic.
@udecode/plate-list to @platejs/list-classic.package.json: remove the old @udecode/plate-list (if it was a direct dependency) and add @platejs/list-classic.@platejs/list, now contains the functionality previously in @udecode/plate-indent-list (indent-based list system).
IndentListPlugin is now ListPlugin, BaseIndentListPlugin is BaseListPlugin, etc. (*IndentList* -> *List*).list (e.g., ListPlugin.key) instead of listStyleType.INDENT_LIST_KEYS are now available under KEYS from platejs.
INDENT_LIST_KEYS.listStyleType -> KEYS.listTypeINDENT_LIST_KEYS.todo -> KEYS.listTodoINDENT_LIST_KEYS.checked -> KEYS.listCheckedINDENT_LIST_KEYS.* map to KEYS.* accordingly.listStyleTypes option from ListPlugin. You should control list rendering via render.belowNodes instead.renderListBelowNodes.<=48 (when it was @udecode/plate-indent-list), refer to its archived changelog.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.BulletedListPlugin and NumberedListPlugin.
shortcuts field.BulletedListPlugin.configure({
shortcuts: { toggle: { keys: 'mod+alt+5' } },
});
NumberedListPlugin.configure({
shortcuts: { toggle: { keys: 'mod+alt+6' } },
});
@udecode/plate-list has been moved to @platejs/list-classic.
@udecode/plate-list to @platejs/list-classic.package.json: remove @udecode/plate-list and add @platejs/list-classic.@udecode/plate-list version <=48, refer to its archived changelog.indentListToMdastTree has been renamed to listToMdastTree to align with the list plugin renames (IndentListPlugin -> ListPlugin).@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.TMentionInputElement has been removed.TComboboxInputElement from @udecode/plate instead for input elements, as mention functionality is built upon the combobox.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.Package @udecode/plate-node-id has been deprecated.
NodeIdPlugin functionality is now part of @platejs/core and is enabled by default.
Migration:
Remove NodeIdPlugin from your explicit plugin list if it was added manually.
Remove @udecode/plate-node-id from your dependencies.
If you had NodeIdPlugin configured with options, move these options to the nodeId field in your main editor configuration (createPlateEditor or usePlateEditor options).
Example:
// Before
// const editor = usePlateEditor({
// plugins: [
// NodeIdPlugin.configure({ /* ...your options... */ }),
// ],
// });
// After
const editor = usePlateEditor({
nodeId: {
/* ...your options... */
},
// ...other editor options
});
If you want to disable automatic node ID generation (to replicate behavior if you weren't using NodeIdPlugin before), set nodeId: false in your editor configuration.
@udecode/plate-normalizers has been deprecated.platejs (which is re-exported via platejs).@udecode/plate-normalizers from your dependencies.platejs@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.#4327 by @zbeyens – Package @udecode/plate-reset-node has been deprecated. Its functionality (e.g., ResetNodePlugin) is now exclusively configured using the rules.break and rules.delete options on plugin definitions. Migration:
@udecode/plate-reset-node from your dependencies.ResetNodePlugin from your project.rules.break and/or rules.delete.Example: Resetting a Blockquote to a Paragraph
ResetNodePlugin.configure({
options: {
rules: [
{
types: [BlockquotePlugin.key],
defaultType: ParagraphPlugin.key,
hotkey: 'Enter',
predicate: (editor) =>
editor.api.isEmpty(editor.selection, { block: true }),
},
],
},
});
// After
BlockquotePlugin.configure({
rules: {
break: { empty: 'reset' },
delete: { start: 'reset' },
},
});
For custom reset logic (previously onReset):
// Before
ResetNodePlugin.configure({
options: {
rules: [
{
types: [CodeBlockPlugin.key],
defaultType: ParagraphPlugin.key,
hotkey: 'Enter',
predicate: isCodeBlockEmpty,
onReset: unwrapCodeBlock,
},
],
},
});
// After
CodeBlockPlugin.configure({
rules: {
delete: { empty: 'reset' },
},
}).overrideEditor(({ editor, tf: { resetBlock } }) => ({
transforms: {
resetBlock(options) {
if (
editor.api.block({
at: options?.at,
match: { type: editor.getType(CodeBlockPlugin.key) },
})
) {
unwrapCodeBlock(editor);
return;
}
return resetBlock(options);
},
},
}));
@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.editOnly: true. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure its editOnly field. For example, SomePlugin.configure({ editOnly: false }).@udecode/plate-select has been deprecated.SelectOnBackspacePlugin has been removed. This behavior is now built into Plate by default: delete (backward/forward) at the start of a block will select the previous/next void block instead of removing it.DeletePlugin has been removed. This behavior is now built into Plate by default: delete (backward/forward) from an empty block will remove it instead of merging.RemoveEmptyNodesPlugin has been removed. This behavior is now available through the rules: { normalize: { removeEmpty: true } } configuration on individual plugins.@udecode/plate-select from your dependencies.SelectOnBackspacePlugin, DeletePlugin from your project.RemoveEmptyNodesPlugin.configure({ options: { types: ['custom'] } }) with CustomPlugin.configure({ rules: { normalize: { removeEmpty: true } } }). This is used by our LinkPlugin.editOnly: true. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure its editOnly field. For example, SomePlugin.configure({ editOnly: false }).@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.editOnly: true. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure its editOnly field. For example, SomePlugin.configure({ editOnly: false }).@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.TSlashInputElement has been removed.TComboboxInputElement from platejs instead for Slash Command input elements, as slash command functionality is built upon the combobox.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.@udecode/plate-* packages to @platejs/*. Replace @udecode/plate- with @platejs/ in your code.editOnly: true. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure its editOnly field. For example, SomePlugin.configure({ editOnly: false }).@udecode/plate-trailing-block has been deprecated.TrailingBlockPlugin) has been moved to @platejs/utils (which is re-exported via platejs).@udecode/plate-trailing-block from your dependencies.platejs (e.g., import { TrailingBlockPlugin } from 'platejs';).