Skip to content

[Release] Version packages - #5050

Merged
zbeyens merged 2 commits into
mainfrom
changeset-release/main
Jun 30, 2026
Merged

[Release] Version packages#5050
zbeyens merged 2 commits into
mainfrom
changeset-release/main

Conversation

@zbeyens

@zbeyens zbeyens commented Jun 30, 2026

Copy link
Copy Markdown
Member

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.

Releases

@platejs/ai@53.3.0

Minor Changes

@zbeyens
zbeyens requested a review from a team June 30, 2026 11:19
@codesandbox

codesandbox Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

@dosubot dosubot Bot added size:S This PR changes 10-29 lines, ignoring generated files. plugin:ai release labels Jun 30, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e3441b2efb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@@ -1,7 +1,7 @@
[
{
"changelogUrl": "https://github.com/udecode/plate/blob/d142cfb5b9358d97b3ec67448e7e00be41f067a4/packages/plate/CHANGELOG.md",
"content": "`@platejs/core`\n\n### Breaking Changes\n\n- Prepare v54 beta prerelease versioning. ([#5031](https://github.com/udecode/plate/pull/5031))\n\n`@platejs/slate`\n\n### Breaking Changes\n\n- Prepare v54 beta prerelease versioning for Slate. ([#5031](https://github.com/udecode/plate/pull/5031))\n\n[`v53.2.4...v54.0.0-beta.0`](https://github.com/udecode/plate/compare/v53.2.4...v54.0.0-beta.0) · By [@felixfeng33](https://github.com/felixfeng33)",
"content": "`@platejs/core`\n\n### Breaking Changes\n\n- Prepare v54 beta prerelease versioning. ([#5031](https://github.com/udecode/plate/pull/5031))\n\n`@platejs/slate`\n\n### Breaking Changes\n\n- Prepare v54 beta prerelease versioning for Slate. ([#5031](https://github.com/udecode/plate/pull/5031))\n\n[`v53.3.0...v54.0.0-beta.0`](https://github.com/udecode/plate/compare/%40platejs%2Fai%4053.3.0...platejs%4054.0.0-beta.0) · By [@felixfeng33](https://github.com/felixfeng33)",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep beta changelog links on their own release lane

When this release-index data renders the releases page, the v54 beta entry now links its full changelog from @platejs/ai@53.3.0, a stable package release dated 2026-06-30, to platejs@54.0.0-beta.0, whose entry is dated 2026-06-16. That stable tag did not exist when the beta was cut, so users clicking the v54 beta changelog get a cross-lane compare that misrepresents the beta release history; keep prerelease comparisons isolated from later stable package-only releases or leave this beta footer anchored to the prior v53.2.4 release.

Useful? React with 👍 / 👎.

@@ -2612,7 +2624,7 @@
},
{
"changelogUrl": "https://github.com/udecode/plate/blob/605ba3c65afa8c31c1af84e5b0828a3a5242943b/packages/ai/CHANGELOG.md",
"content": "`@udecode/plate-ai`\n\n### Breaking Changes\n\n- Copilot API method changes: ([#4327](https://github.com/udecode/plate/pull/4327))\n - `editor.api.copilot.accept` is now `editor.tf.copilot.accept`.\n - `editor.api.copilot.acceptNextWord` is now `editor.tf.copilot.acceptNextWord`.\n - `editor.api.copilot.reset` is now `editor.api.copilot.reject`.\n- Removed Default Shortcuts for Copilot:\n - Only `accept` (Tab) and `reject` (Escape) shortcuts are included by default for `CopilotPlugin`.\n - `acceptNextWord` and `triggerSuggestion` shortcuts must now be configured manually using the `shortcuts` field when configuring the plugin.\n - Example:\n ```tsx\n CopilotPlugin.configure({\n // ... other options\n shortcuts: {\n acceptNextWord: {\n keys: 'mod+right',\n },\n triggerSuggestion: {\n keys: 'ctrl+space',\n },\n },\n });\n ```\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-alignment`\n\n### Breaking Changes\n\n- Package `@udecode/plate-alignment` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n - `TextAlignPlugin` (formerly `AlignPlugin`) has been moved to the `@platejs/basic-styles` package.\n\n - Migration:\n\n - Remove `@udecode/plate-alignment` from your dependencies.\n - Add `@platejs/basic-styles` to your dependencies if not already present.\n - Import `TextAlignPlugin` from `@platejs/basic-styles/react`.\n\n - Renamed `AlignPlugin` to `TextAlignPlugin` and changed plugin key from `'align'` to `'textAlign'`.\n\n ```ts\n // Before\n import { AlignPlugin } from '@udecode/plate-alignment/react';\n\n // After\n import { TextAlignPlugin } from '@platejs/basic-styles/react';\n ```\n\n - `setAlign` signature change:\n\n ```ts\n // Before\n setAlign(editor, { value: 'center', setNodesOptions });\n\n // After\n setAlign(editor, 'center', setNodesOptions);\n ```\n\n - Removed `useAlignDropdownMenu` and `useAlignDropdownMenuState`. Use it in your own codebase, for example:\n\n ```tsx\n export function AlignToolbarButton() {\n const editor = useEditorRef();\n const value = useSelectionFragmentProp({\n defaultValue: 'start',\n structuralTypes,\n getProp: (node) => node.align,\n });\n\n const onValueChange = (newValue: string) => {\n editor.tf.textAlign.setNodes(newValue as Alignment);\n editor.tf.focus();\n };\n\n // ...\n }\n ```\n\n### Features\n\n- New transform method to `AlignPlugin`: ([#4327](https://github.com/udecode/plate/pull/4327))\n - `editor.tf.textAlign.setNodes` - Transform method for setting alignment values. Alias to `setAlign`\n\n`@udecode/plate-autoformat`\n\n### Breaking Changes\n\n- Replaced `BaseAutoformatPlugin` with `AutoformatPlugin`, which is no longer a React plugin. Migration: Replace `@udecode/plate-autoformat/react` import with `@udecode/plate-autoformat`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-basic-elements`\n\n### Breaking Changes\n\n- Package `@udecode/plate-basic-elements` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `BasicElementsPlugin` has been renamed to `BasicBlocksPlugin`.\n- Its plugins have been moved to the new `@platejs/basic-nodes` package.\n- Migration:\n - Replace `@udecode/plate-basic-elements` with `@platejs/basic-nodes` in your dependencies.\n - Update import paths from `@udecode/plate-basic-elements/react` to `@platejs/basic-nodes/react`.\n - For detailed changes to individual plugins, default HTML tags, and shortcut configurations, refer to the changeset for `@platejs/basic-nodes`.\n\n`@udecode/plate-basic-marks`\n\n### Breaking Changes\n\n- Package `@udecode/plate-basic-marks` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- Its plugins have been moved to the new `@platejs/basic-nodes` package.\n- Migration:\n - Replace `@udecode/plate-basic-marks` with `@platejs/basic-nodes` in your dependencies.\n - Update import paths from `@udecode/plate-basic-marks/react` to `@platejs/basic-nodes/react`.\n - For detailed changes to individual plugins, default HTML tags, and shortcut configurations, refer to the changeset for `@platejs/basic-nodes`.\n\n`@udecode/plate-basic-nodes`\n\n### Breaking Changes\n\n- The packages `@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. ([#4327](https://github.com/udecode/plate/pull/4327))\n- **Migration**:\n - Replace `@udecode/plate-basic-elements` and `@udecode/plate-basic-marks` in your dependencies with `@platejs/basic-nodes`.\n - Update all import paths from `@udecode/plate-basic-elements/react` or `@udecode/plate-basic-marks/react` to `@platejs/basic-nodes/react`.\n - `CodeBlockPlugin` is **not** part of `@platejs/basic-nodes`. Ensure it is imported from `@platejs/code-block/react`.\n- `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' } } })`.\n- Default HTML Tag Changes:\n - **Blocks**: Element plugins in `@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.\n - **Marks**: Mark plugins in `@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.\n- Removed Default Shortcuts:\n - Default keyboard shortcuts are no longer bundled with most plugins (exceptions: bold, italic, underline).\n - Configure shortcuts manually via the `shortcuts` field in plugin configuration.\n - Example (Block Plugins):\n ```ts\n H1Plugin.configure({ shortcuts: { toggle: { keys: 'mod+alt+1' } } });\n BlockquotePlugin.configure({\n shortcuts: { toggle: { keys: 'mod+shift+period' } },\n });\n ```\n - Example (Mark Plugins):\n ```ts\n CodePlugin.configure({ shortcuts: { toggle: { keys: 'mod+e' } } });\n StrikethroughPlugin.configure({\n shortcuts: { toggle: { keys: 'mod+shift+x' } },\n });\n SubscriptPlugin.configure({\n shortcuts: { toggle: { keys: 'mod+comma' } },\n });\n SuperscriptPlugin.configure({\n shortcuts: { toggle: { keys: 'mod+period' } },\n });\n HighlightPlugin.configure({\n shortcuts: { toggle: { keys: 'mod+shift+h' } },\n });\n ```\n\n### Features\n\n- New `toggle` Transforms Added: ([#4327](https://github.com/udecode/plate/pull/4327))\n - Block plugins with new `toggle` transforms: `BlockquotePlugin`, `H1Plugin`, `H2Plugin`, `H3Plugin`, `H4Plugin`, `H5Plugin`, `H6Plugin`.\n - All mark plugins in this package now also feature a `toggle` transform, including: `BoldPlugin`, `ItalicPlugin`, `UnderlinePlugin`, `CodePlugin`, `StrikethroughPlugin`, `SubscriptPlugin`, `SuperscriptPlugin`, `KbdPlugin`, `HighlightPlugin`.\n- Individual Heading Plugins Available:\n - `H1Plugin`, `H2Plugin`, `H3Plugin`, `H4Plugin`, `H5Plugin`, and `H6Plugin` offer a flexible alternative to the general `HeadingPlugin`, allowing granular control over heading level inclusion and configuration (e.g., custom components, shortcuts per level).\n- Plugin Consolidations into `@udecode/plate-basic-nodes`:\n - `KbdPlugin` (formerly from `@udecode/plate-kbd`).\n - `HighlightPlugin` (formerly from `@udecode/plate-highlight`).\n\n`@udecode/plate-block-quote`\n\n### Breaking Changes\n\n- Package `@udecode/plate-block-quote` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `BlockquotePlugin` has been moved to the `@platejs/basic-nodes` package.\n- Migration:\n - Remove `@udecode/plate-block-quote` from your dependencies.\n - Add `@platejs/basic-nodes` to your dependencies if not already present.\n - Import `BlockquotePlugin` from `@platejs/basic-nodes/react`.\n\n`@udecode/plate-break`\n\n### Breaking Changes\n\n- Package `@udecode/plate-break` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `SoftBreakPlugin` has been removed. Migration:\n - For `shift+enter` rules: no migration is needed - this behavior is built into Slate by default.\n - For `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.\n - For more complex break rules: use `overrideEditor` to override the `insertBreak` transform with custom logic.\n- `ExitBreakPlugin` has been moved to `@platejs/utils` (which is re-exported via `platejs`) with a simplified API and improved behavior.\n\n - **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.\n - Migration:\n\n - Remove `@udecode/plate-break` from your dependencies.\n - Replace `@udecode/plate-break` import with `platejs`.\n - **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.\n - Replace complex rule-based configuration with simple shortcuts:\n\n ```tsx\n // Before (old API)\n ExitBreakPlugin.configure({\n options: {\n rules: [\n { hotkey: 'mod+enter' },\n { hotkey: 'mod+shift+enter', before: true },\n ],\n },\n });\n\n // After (new API)\n ExitBreakPlugin.configure({\n shortcuts: {\n insert: { keys: 'mod+enter' },\n insertBefore: { keys: 'mod+shift+enter' },\n },\n });\n ```\n\n`@udecode/plate-callout`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-caption`\n\n### Breaking Changes\n\n- `CaptionPlugin` option `options.plugins` (accepting an array of `PlatePlugin`) has been renamed to `options.query.allow` (accepting an array of plugin keys). ([#4327](https://github.com/udecode/plate/pull/4327))\n- Migration:\n\n ```tsx\n // Before\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin], // ImagePlugin is an example\n },\n });\n\n // After\n CaptionPlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key], // Use the plugin's key\n },\n },\n });\n ```\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-code-block`\n\n### Breaking Changes\n\n- `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`). ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-combobox`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-comments`\n\n### Breaking Changes\n\n- `CommentsPlugin` has been renamed to `CommentPlugin`. ([#4327](https://github.com/udecode/plate/pull/4327))\n- Update imports and plugin configurations accordingly.\n - Example: `CommentsPlugin.key` becomes `CommentPlugin.key`.\n- Package name has been changed to `@platejs/comment`.\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-core`\n\n### Breaking Changes\n\n- `editor.getType()` now takes a `pluginKey: string` instead of a `plugin: PlatePlugin` instance. ([#4327](https://github.com/udecode/plate/pull/4327))\n - Example: Use `editor.getType(ParagraphPlugin.key)` instead of `editor.getType(ParagraphPlugin)`.\n- Plugins without a `key` property will not be registered into the editor.\n- Passing `disabled: true` prop to `PlateContent` will now also set the editor to `readOnly: true` state internally.\n- Editor DOM state properties have been moved under `editor.dom` namespace:\n - `editor.currentKeyboardEvent` is now `editor.dom.currentKeyboardEvent`.\n - `editor.prevSelection` is now `editor.dom.prevSelection`.\n- Editor metadata properties have been moved under `editor.meta` namespace:\n - `editor.isFallback` is now `editor.meta.isFallback`\n - `editor.key` is now `editor.meta.key`\n - `editor.pluginList` is now `editor.meta.pluginList`\n - `editor.shortcuts` is now `editor.meta.shortcuts`\n - `editor.uid` is now `editor.meta.uid`\n- `NodeIdPlugin` is now enabled by default as part of the core plugins. This automatically assigns unique IDs to block nodes.\n - Migration: If you were not previously using `NodeIdPlugin` and wish to maintain the old behavior (no automatic IDs), explicitly disable it in your editor configuration:\n ```ts\n const editor = usePlateEditor({\n // ...other options\n nodeId: false, // Disables automatic node ID generation\n });\n ```\n- The `components` prop has been removed from `serializeHtml` and `PlateStatic`.\n - Migration: Pass the `components` to `createSlateEditor({ components })` or the individual plugins instead.\n- Plugin Shortcuts System Changes:\n - Shortcut keys defined in `editor.shortcuts` are now namespaced by the plugin key (e.g., `code.toggle` for `CodePlugin`).\n - The `priority` property for shortcuts is used to resolve conflicts when multiple shortcuts share the exact same key combination, not for overriding shortcuts by name.\n - `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.\n - Migration: If you need to allow browser default behavior for a specific shortcut, set `preventDefault: false` in its configuration:\n ```ts\n MyPlugin.configure({\n shortcuts: {\n myAction: {\n keys: 'mod+s',\n preventDefault: false, // Example: Allow browser's default save dialog\n },\n },\n });\n ```\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n### Features\n\n- New editor DOM state fields available under `editor.dom`: ([#4327](https://github.com/udecode/plate/pull/4327))\n - `editor.dom.composing`: Boolean, true if the editor is currently composing text (e.g., during IME input).\n - `editor.dom.focused`: Boolean, true if the editor currently has focus.\n - `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.\n- New editor metadata fields:\n - `editor.meta.components` - stores the plugin components by key\n- New hook `useEditorComposing`: Allows subscription to the editor's composing state (`editor.dom.composing`) outside of `PlateContent`.\n- `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.\n- New plugin field: `editOnly` (boolean or object).\n - When `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.\n - By default, `render`, `handlers`, and `inject` are considered edit-only (`true`). `normalizeInitialValue` defaults to always active (`false`).\n - Example: `editOnly: { render: false, normalizeInitialValue: true }` would make rendering active always, but normalization only in edit mode.\n- New plugin field: `render.as` (`keyof HTMLElementTagNameMap`).\n - Specifies the default HTML tag name to be used by `PlateElement` (default: `'div'`) or `PlateLeaf` (default: `'span'`) when rendering the node, but only if no custom `node.component` is provided for the plugin.\n - Example: `render: { as: 'h1' }` would make the plugin render its node as an `<h1>` tag by default without the need to provide a custom component.\n- New plugin field: `node.isContainer` (boolean).\n - When `true`, indicates that the plugin's elements are primarily containers for other content.\n- New plugin field: `node.isStrictSiblings` (boolean).\n - When `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).\n - Used by `editor.tf.insertExitBreak` functionality to determine appropriate exit points in nested structures.\n- New plugin field: `rules` (object).\n - Configures common editing behaviors declaratively instead of overriding editor methods. See documentation for more details.\n - `rules.break`: Controls Enter key behavior (`empty`, `default`, `emptyLineEnd`, `splitReset`)\n - `rules.delete`: Controls Backspace key behavior (`start`, `empty`)\n - `rules.merge`: Controls block merging behavior (`removeEmpty`)\n - `rules.normalize`: Controls normalization behavior (`removeEmpty`)\n - `rules.selection`: Controls cursor positioning behavior (`affinity`)\n - `rules.match`: Conditional rule application based on node properties\n- Plugin shortcuts can now automatically leverage existing plugin transforms by specifying the transform name, in addition to custom handlers.\n- New editor transform methods for keyboard handling:\n - `editor.tf.escape`: Handle Escape key events. Returns `true` if the event is handled.\n - `editor.tf.moveLine`: Handle ArrowDown and ArrowUp key events with `reverse` option for direction. Returns `true` if the event is handled.\n - `editor.tf.selectAll`: Handle Ctrl/Cmd+A key events for selecting all content. Returns `true` if the event is handled.\n - `editor.tf.tab`: Handle Tab and Shift+Tab key events with `reverse` option for Shift+Tab. Returns `true` if the event is handled.\n\n### Bug Fixes\n\n- Fixed an issue where `editor.api` and `editor.tf` (transforms) were not consistently available in the props passed to default element components when no custom component was provided for a plugin. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-csv`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-cursor`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-date`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-diff`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-dnd`\n\n### Breaking Changes\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-docx`\n\n### Breaking Changes\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-emoji`\n\n### Breaking Changes\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-excalidraw`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-find-replace`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-floating`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-font`\n\n### Breaking Changes\n\n- Removed `setBlockBackgroundColor` ([#4327](https://github.com/udecode/plate/pull/4327))\n- Removed `setFontSize` – use `tf.fontSize.addMark` instead:\n\n ```ts\n // Before\n editor.api.fontSize.addMark('16px');\n\n // After\n editor.tf.fontSize.addMark('16px');\n ```\n\n - Removed `useColorInput`. Use it in your own codebase, for example:\n\n ```tsx\n function ColorInput() {\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n\n const onClick = () => {\n inputRef.current?.click();\n };\n\n // ...\n }\n ```\n\n - Removed `useColorsCustom` and `useColorsCustomState`. Use it in your own codebase, for example:\n\n ```tsx\n function ColorCustom({ color, colors, customColors, updateCustomColor }) {\n const [customColor, setCustomColor] = React.useState<string>();\n const [value, setValue] = React.useState<string>(color || '#000000');\n\n React.useEffect(() => {\n if (\n !color ||\n customColors.some((c) => c.value === color) ||\n colors.some((c) => c.value === color)\n ) {\n return;\n }\n\n setCustomColor(color);\n }, [color, colors, customColors]);\n\n const computedColors = React.useMemo(\n () =>\n customColor\n ? [\n ...customColors,\n {\n isBrightColor: false,\n name: '',\n value: customColor,\n },\n ]\n : customColors,\n [customColor, customColors]\n );\n\n const updateCustomColorDebounced = React.useCallback(\n debounce(updateCustomColor, 100),\n [updateCustomColor]\n );\n\n const inputProps = {\n value,\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n setValue(e.target.value);\n updateCustomColorDebounced(e.target.value);\n },\n };\n\n // ...\n }\n ```\n\n - Removed `useColorDropdownMenu` and `useColorDropdownMenuState`. Use it in your own codebase, for example:\n\n ```tsx\n export function FontColorToolbarButton({ nodeType }) {\n const editor = useEditorRef();\n\n const selectionDefined = useEditorSelector(\n (editor) => !!editor.selection,\n []\n );\n\n const color = useEditorSelector(\n (editor) => editor.api.mark(nodeType) as string,\n [nodeType]\n );\n\n const [selectedColor, setSelectedColor] = React.useState<string>();\n const [open, setOpen] = React.useState(false);\n\n const onToggle = React.useCallback(\n (value = !open) => {\n setOpen(value);\n },\n [open, setOpen]\n );\n\n const updateColor = React.useCallback(\n (value: string) => {\n if (editor.selection) {\n setSelectedColor(value);\n editor.tf.select(editor.selection);\n editor.tf.focus();\n editor.tf.addMarks({ [nodeType]: value });\n }\n },\n [editor, nodeType]\n );\n\n const clearColor = React.useCallback(() => {\n if (editor.selection) {\n editor.tf.select(editor.selection);\n editor.tf.focus();\n if (selectedColor) {\n editor.tf.removeMarks(nodeType);\n }\n onToggle();\n }\n }, [editor, selectedColor, onToggle, nodeType]);\n\n React.useEffect(() => {\n if (selectionDefined) {\n setSelectedColor(color);\n }\n }, [color, selectionDefined]);\n\n // ...\n }\n ```\n\n`@udecode/plate-heading`\n\n### Breaking Changes\n\n- Package `@udecode/plate-heading` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n - `HeadingPlugin` and individual heading plugins (e.g., `H1Plugin`) have been moved to `@platejs/basic-nodes`.\n - Migration: Import from `@platejs/basic-nodes/react` (e.g., `import { HeadingPlugin } from '@platejs/basic-nodes/react';`).\n - `TocPlugin` has been moved to `@platejs/toc`.\n - Migration: Add `@platejs/toc` to your dependencies and import `TocPlugin` from `@platejs/toc/react`.\n- Remove `@udecode/plate-heading` from your dependencies.\n\n`@udecode/plate-highlight`\n\n### Breaking Changes\n\n- Package `@udecode/plate-highlight` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `HighlightPlugin` has been moved to the `@platejs/basic-nodes` package.\n- Migration:\n - Remove `@udecode/plate-highlight` from your dependencies.\n - Add `@platejs/basic-nodes` to your dependencies if not already present.\n - Import `HighlightPlugin` from `@platejs/basic-nodes/react`.\n\n`@udecode/plate-horizontal-rule`\n\n### Breaking Changes\n\n- Package `@udecode/plate-horizontal-rule` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `HorizontalRulePlugin` has been moved to the `@platejs/basic-nodes` package.\n- Migration:\n - Remove `@udecode/plate-horizontal-rule` from your dependencies.\n - Add `@platejs/basic-nodes` to your dependencies if not already present.\n - Import `HorizontalRulePlugin` from `@platejs/basic-nodes/react`.\n\n`@udecode/plate-indent`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-indent-list`\n\n### Breaking Changes\n\n- Package `@udecode/plate-indent-list` has been renamed to `@platejs/list`. ([#4327](https://github.com/udecode/plate/pull/4327))\n- Migration:\n - Rename all import paths from `@udecode/plate-indent-list` to `@platejs/list`.\n - Update your `package.json`: remove `@udecode/plate-indent-list` and add `@platejs/list`.\n\n`@udecode/plate-juice`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-kbd`\n\n### Breaking Changes\n\n- Package `@udecode/plate-kbd` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `KbdPlugin` has been moved to the `@platejs/basic-nodes` package.\n- Migration:\n - Remove `@udecode/plate-kbd` from your dependencies.\n - Add `@platejs/basic-nodes` to your dependencies if not already present.\n - Import `KbdPlugin` from `@platejs/basic-nodes/react`.\n\n`@udecode/plate-layout`\n\n### Breaking Changes\n\n- Delete backward from a column start will merge into the previous column ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-line-height`\n\n### Breaking Changes\n\n- Package `@udecode/plate-line-height` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n - `LineHeightPlugin` has been moved to the `@platejs/basic-styles` package.\n\n - Migration:\n\n - Remove `@udecode/plate-line-height` from your dependencies.\n - Add `@platejs/basic-styles` to your dependencies if not already present.\n - Import `LineHeightPlugin` from `@platejs/basic-styles/react`.\n\n - `setLineHeight` signature change:\n\n ```ts\n // Before\n setLineHeight(editor, { value: 1.5, setNodesOptions });\n\n // After\n setLineHeight(editor, 1.5, setNodesOptions);\n ```\n\n - Removed `useLineHeightDropdownMenu` and `useLineHeightDropdownMenuState`. Use it in your own codebase, for example:\n\n ```tsx\n export function LineHeightToolbarButton() {\n const editor = useEditorRef();\n const { defaultNodeValue, validNodeValues: values = [] } =\n editor.getInjectProps(LineHeightPlugin);\n\n const value = useSelectionFragmentProp({\n defaultValue: defaultNodeValue,\n getProp: (node) => node.lineHeight,\n });\n\n const onValueChange = (newValue: string) => {\n editor.tf.lineHeight.setNodes(Number(newValue));\n editor.tf.focus();\n };\n\n // ...\n }\n ```\n\n### Features\n\n- New transform method to `LineHeightPlugin`: ([#4327](https://github.com/udecode/plate/pull/4327))\n - `editor.tf.lineHeight.setNodes` - Transform method for setting line height values. Alias to `setLineHeight`\n\n`@udecode/plate-link`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-list`\n\n### Breaking Changes\n\n- The previous `@udecode/plate-list` (classic list implementation) has been moved to `@platejs/list-classic`. ([#4327](https://github.com/udecode/plate/pull/4327))\n - **Migration for users of the classic list**:\n - Rename all import paths from `@udecode/plate-list` to `@platejs/list-classic`.\n - Update your `package.json`: remove the old `@udecode/plate-list` (if it was a direct dependency) and add `@platejs/list-classic`.\n- This package, `@platejs/list`, now contains the functionality previously in `@udecode/plate-indent-list` (indent-based list system).\n - Plugin names have been generalized: `IndentListPlugin` is now `ListPlugin`, `BaseIndentListPlugin` is `BaseListPlugin`, etc. (`*IndentList*` -> `*List*`).\n - The primary plugin key is now `list` (e.g., `ListPlugin.key`) instead of `listStyleType`.\n - Constants for list keys previously in `INDENT_LIST_KEYS` are now available under `KEYS` from `platejs`.\n - Migration for constants:\n - `INDENT_LIST_KEYS.listStyleType` -> `KEYS.listType`\n - `INDENT_LIST_KEYS.todo` -> `KEYS.listTodo`\n - `INDENT_LIST_KEYS.checked` -> `KEYS.listChecked`\n - Other `INDENT_LIST_KEYS.*` map to `KEYS.*` accordingly.\n - Removed `listStyleTypes` option from `ListPlugin`. You should control list rendering via `render.belowNodes` instead.\n - Removed `renderListBelowNodes`.\n- For changelogs of the indent-based list system (now in this package) version `<=48` (when it was `@udecode/plate-indent-list`), refer to its [archived changelog](https://github.com/udecode/plate/blob/7afd88089f4a76c896f3edf928b03c7e9f2ab903/packages/indent-list/CHANGELOG.md).\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-list-classic`\n\n### Breaking Changes\n\n- **Removed Default Shortcuts** for `BulletedListPlugin` and `NumberedListPlugin`. ([#4327](https://github.com/udecode/plate/pull/4327))\n - These shortcuts must now be configured manually using the `shortcuts` field.\n - Example:\n ```tsx\n BulletedListPlugin.configure({\n shortcuts: { toggle: { keys: 'mod+alt+5' } },\n });\n NumberedListPlugin.configure({\n shortcuts: { toggle: { keys: 'mod+alt+6' } },\n });\n ```\n- Package `@udecode/plate-list` has been moved to `@platejs/list-classic`.\n - **Migration**:\n - Rename all import paths from `@udecode/plate-list` to `@platejs/list-classic`.\n - Update your `package.json`: remove `@udecode/plate-list` and add `@platejs/list-classic`.\n- For changelogs of `@udecode/plate-list` version `<=48`, refer to its [archived changelog](https://github.com/udecode/plate/blob/7afd88089f4a76c896f3edf928b03c7e9f2ab903/packages/list/CHANGELOG.md).\n\n`@udecode/plate-markdown`\n\n### Breaking Changes\n\n- Function `indentListToMdastTree` has been renamed to `listToMdastTree` to align with the list plugin renames (`IndentListPlugin` -> `ListPlugin`). ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-math`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-media`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-mention`\n\n### Breaking Changes\n\n- The type `TMentionInputElement` has been removed. ([#4327](https://github.com/udecode/plate/pull/4327))\n- Use `TComboboxInputElement` from `@udecode/plate` instead for input elements, as mention functionality is built upon the combobox.\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-node-id`\n\n### Breaking Changes\n\n- Package `@udecode/plate-node-id` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `NodeIdPlugin` functionality is now part of `@platejs/core` and is **enabled by default**.\n- Migration:\n\n - Remove `NodeIdPlugin` from your explicit plugin list if it was added manually.\n\n - Remove `@udecode/plate-node-id` from your dependencies.\n\n - If you had `NodeIdPlugin` configured with options, move these options to the `nodeId` field in your main editor configuration (`createPlateEditor` or `usePlateEditor` options).\n Example:\n\n ```ts\n // Before\n // const editor = usePlateEditor({\n // plugins: [\n // NodeIdPlugin.configure({ /* ...your options... */ }),\n // ],\n // });\n\n // After\n const editor = usePlateEditor({\n nodeId: {\n /* ...your options... */\n },\n // ...other editor options\n });\n ```\n\n - 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.\n\n`@udecode/plate-normalizers`\n\n### Breaking Changes\n\n- Package `@udecode/plate-normalizers` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- Its plugins have been moved to `platejs` (which is re-exported via `platejs`).\n- Migration:\n - Remove `@udecode/plate-normalizers` from your dependencies.\n - Update import paths to use `platejs`\n\n`@udecode/plate`\n\n### Breaking Changes\n\n- Renamed package to `platejs`: ([#4327](https://github.com/udecode/plate/pull/4327))\n - Replace all `@udecode/plate/react` with `platejs/react`\n - Replace all `'@udecode/plate'` with `'platejs'`\n\n`@udecode/plate-playwright`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-reset-node`\n\n### Breaking Changes\n\n- 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: ([#4327](https://github.com/udecode/plate/pull/4327))\n\n - Remove `@udecode/plate-reset-node` from your dependencies.\n - Remove any usage of `ResetNodePlugin` from your project.\n - Configure reset behaviors directly on the relevant plugins by defining `rules.break` and/or `rules.delete`.\n\n **Example: Resetting a Blockquote to a Paragraph**\n\n ```typescript\n ResetNodePlugin.configure({\n options: {\n rules: [\n {\n types: [BlockquotePlugin.key],\n defaultType: ParagraphPlugin.key,\n hotkey: 'Enter',\n predicate: (editor) =>\n editor.api.isEmpty(editor.selection, { block: true }),\n },\n ],\n },\n });\n\n // After\n BlockquotePlugin.configure({\n rules: {\n break: { empty: 'reset' },\n delete: { start: 'reset' },\n },\n });\n ```\n\n **For custom reset logic (previously `onReset`):**\n\n ```typescript\n // Before\n ResetNodePlugin.configure({\n options: {\n rules: [\n {\n types: [CodeBlockPlugin.key],\n defaultType: ParagraphPlugin.key,\n hotkey: 'Enter',\n predicate: isCodeBlockEmpty,\n onReset: unwrapCodeBlock,\n },\n ],\n },\n });\n\n // After\n CodeBlockPlugin.configure({\n rules: {\n delete: { empty: 'reset' },\n },\n }).overrideEditor(({ editor, tf: { resetBlock } }) => ({\n transforms: {\n resetBlock(options) {\n if (\n editor.api.block({\n at: options?.at,\n match: { type: editor.getType(CodeBlockPlugin.key) },\n })\n ) {\n unwrapCodeBlock(editor);\n return;\n }\n\n return resetBlock(options);\n },\n },\n }));\n ```\n\n`@udecode/plate-resizable`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-select`\n\n### Breaking Changes\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Package `@udecode/plate-select` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `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.\n- `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.\n- `RemoveEmptyNodesPlugin` has been removed. This behavior is now available through the `rules: { normalize: { removeEmpty: true } }` configuration on individual plugins.\n- Migration:\n - Remove `@udecode/plate-select` from your dependencies.\n - Remove any usage of `SelectOnBackspacePlugin`, `DeletePlugin` from your project.\n - Replace `RemoveEmptyNodesPlugin.configure({ options: { types: ['custom'] } })` with `CustomPlugin.configure({ rules: { normalize: { removeEmpty: true } } })`. This is used by our `LinkPlugin`.\n\n`@udecode/plate-selection`\n\n### Breaking Changes\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-slash-command`\n\n### Breaking Changes\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- The type `TSlashInputElement` has been removed. ([#4327](https://github.com/udecode/plate/pull/4327))\n- Use `TComboboxInputElement` from `platejs` instead for Slash Command input elements, as slash command functionality is built upon the combobox.\n\n`@udecode/slate`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Replaced `editor.api.shouldMergeNodesRemovePrevNode` with `editor.api.shouldMergeNodes`. `shouldMergeNodes` is now controlling the remove + merge behavior ([#4327](https://github.com/udecode/plate/pull/4327))\n\n - Returns `true` if the default merging behavior should be applied.\n - Returns `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.\n\n ```ts\n // Before\n editor.api.shouldMergeNodesRemovePrevNode(prev, current);\n\n // After\n editor.api.shouldMergeNodes(prev, current);\n ```\n\n - Replace `editor.api.fragment` option `structuralTypes` with `unwrap`.\n\n ```ts\n // Before\n editor.api.fragment(editor.selection, { structuralTypes: ['table'] });\n\n // After\n editor.api.fragment(editor.selection, { unwrap: ['table'] });\n ```\n\n### Features\n\n- `editor.tf.insertSoftBreak` now inserts a soft break instead of a hard break. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-suggestion`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-tabbable`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-table`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-tag`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-test-utils`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-toc`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-toggle`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-trailing-block`\n\n### Breaking Changes\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Package `@udecode/plate-trailing-block` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- Its functionality (e.g., `TrailingBlockPlugin`) has been moved to `@platejs/utils` (which is re-exported via `platejs`).\n- Migration:\n - Remove `@udecode/plate-trailing-block` from your dependencies.\n - Update import paths to use `platejs` (e.g., `import { TrailingBlockPlugin } from 'platejs';`).\n\n`@udecode/plate-utils`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- 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. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n - Migration: Update imports for these types to pull from `platejs`.\n\n ```tsx\n // Before\n // import { TImageElement } from '@udecode/plate-media';\n\n // After\n import { TImageElement } from 'platejs';\n ```\n\n - Removed `structuralTypes` option from `useSelectionFragment` and `useSelectionFragmentProp`. These hooks now automatically use `plugin.node.isContainer` from enabled plugins.\n\n - Removed:\n - `createNodesHOC`\n - `createNodesWithHOC`\n - `createNodeHOC`\n\n - Removed `usePlaceholderState` hook.\n - Migration: Use the `BlockPlaceholderPlugin` (typically from `platejs`) instead of the `withPlaceholders` HOC and `usePlaceholderState`. Configure placeholders directly within the `BlockPlaceholderPlugin` options.\n ```ts\n // Example BlockPlaceholderPlugin configuration\n BlockPlaceholderPlugin.configure({\n options: {\n className:\n 'before:absolute before:cursor-text before:opacity-30 before:content-[attr(placeholder)]',\n placeholders: {\n [ParagraphPlugin.key]: 'Type something...',\n // ...other placeholders\n },\n query: ({ editor, path }) => {\n // Example query: only show for top-level empty blocks\n return (\n path.length === 1 && editor.api.isEmpty(editor.children[path[0]])\n );\n },\n },\n });\n ```\n\n### Features\n\n- New plugin `SingleBlockPlugin` to restrict editor content to a single block while preserving line breaks, while `SingleLinePlugin` prevents all line breaks. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n - `@platejs/utils` (and by extension, `platejs`) now exports a comprehensive `KEYS` object containing all official plugin keys.\n\n - This is intended to improve decoupling and provide a centralized way to reference plugin keys.\n - Example Usage:\n\n ```ts\n import { KEYS } from 'platejs';\n\n // Instead of: ParagraphPlugin.key\n // Use: KEYS.p\n ```\n\n - Many node type definitions (e.g., `TParagraphElement`, `TLinkElement`) are also now exported from `platejs`, in addition to being available from their specific plugin packages if those still exist or from `@platejs/basic-nodes`.\n\n`@udecode/plate-yjs`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n[`CHANGELOG`](https://github.com/udecode/plate/pull/4339) · [`v48.0.6...v49.0.0`](https://github.com/udecode/plate/compare/%40udecode%2Fplate-node-id%4048.0.6...%40udecode%2Fplate-ai%4049.0.0) · By [@zbeyens](https://github.com/zbeyens)",
"content": "`@udecode/plate-ai`\n\n### Breaking Changes\n\n- Copilot API method changes: ([#4327](https://github.com/udecode/plate/pull/4327))\n - `editor.api.copilot.accept` is now `editor.tf.copilot.accept`.\n - `editor.api.copilot.acceptNextWord` is now `editor.tf.copilot.acceptNextWord`.\n - `editor.api.copilot.reset` is now `editor.api.copilot.reject`.\n- Removed Default Shortcuts for Copilot:\n - Only `accept` (Tab) and `reject` (Escape) shortcuts are included by default for `CopilotPlugin`.\n - `acceptNextWord` and `triggerSuggestion` shortcuts must now be configured manually using the `shortcuts` field when configuring the plugin.\n - Example:\n ```tsx\n CopilotPlugin.configure({\n // ... other options\n shortcuts: {\n acceptNextWord: {\n keys: 'mod+right',\n },\n triggerSuggestion: {\n keys: 'ctrl+space',\n },\n },\n });\n ```\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-alignment`\n\n### Breaking Changes\n\n- Package `@udecode/plate-alignment` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n - `TextAlignPlugin` (formerly `AlignPlugin`) has been moved to the `@platejs/basic-styles` package.\n\n - Migration:\n\n - Remove `@udecode/plate-alignment` from your dependencies.\n - Add `@platejs/basic-styles` to your dependencies if not already present.\n - Import `TextAlignPlugin` from `@platejs/basic-styles/react`.\n\n - Renamed `AlignPlugin` to `TextAlignPlugin` and changed plugin key from `'align'` to `'textAlign'`.\n\n ```ts\n // Before\n import { AlignPlugin } from '@udecode/plate-alignment/react';\n\n // After\n import { TextAlignPlugin } from '@platejs/basic-styles/react';\n ```\n\n - `setAlign` signature change:\n\n ```ts\n // Before\n setAlign(editor, { value: 'center', setNodesOptions });\n\n // After\n setAlign(editor, 'center', setNodesOptions);\n ```\n\n - Removed `useAlignDropdownMenu` and `useAlignDropdownMenuState`. Use it in your own codebase, for example:\n\n ```tsx\n export function AlignToolbarButton() {\n const editor = useEditorRef();\n const value = useSelectionFragmentProp({\n defaultValue: 'start',\n structuralTypes,\n getProp: (node) => node.align,\n });\n\n const onValueChange = (newValue: string) => {\n editor.tf.textAlign.setNodes(newValue as Alignment);\n editor.tf.focus();\n };\n\n // ...\n }\n ```\n\n### Features\n\n- New transform method to `AlignPlugin`: ([#4327](https://github.com/udecode/plate/pull/4327))\n - `editor.tf.textAlign.setNodes` - Transform method for setting alignment values. Alias to `setAlign`\n\n`@udecode/plate-autoformat`\n\n### Breaking Changes\n\n- Replaced `BaseAutoformatPlugin` with `AutoformatPlugin`, which is no longer a React plugin. Migration: Replace `@udecode/plate-autoformat/react` import with `@udecode/plate-autoformat`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-basic-elements`\n\n### Breaking Changes\n\n- Package `@udecode/plate-basic-elements` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `BasicElementsPlugin` has been renamed to `BasicBlocksPlugin`.\n- Its plugins have been moved to the new `@platejs/basic-nodes` package.\n- Migration:\n - Replace `@udecode/plate-basic-elements` with `@platejs/basic-nodes` in your dependencies.\n - Update import paths from `@udecode/plate-basic-elements/react` to `@platejs/basic-nodes/react`.\n - For detailed changes to individual plugins, default HTML tags, and shortcut configurations, refer to the changeset for `@platejs/basic-nodes`.\n\n`@udecode/plate-basic-marks`\n\n### Breaking Changes\n\n- Package `@udecode/plate-basic-marks` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- Its plugins have been moved to the new `@platejs/basic-nodes` package.\n- Migration:\n - Replace `@udecode/plate-basic-marks` with `@platejs/basic-nodes` in your dependencies.\n - Update import paths from `@udecode/plate-basic-marks/react` to `@platejs/basic-nodes/react`.\n - For detailed changes to individual plugins, default HTML tags, and shortcut configurations, refer to the changeset for `@platejs/basic-nodes`.\n\n`@udecode/plate-basic-nodes`\n\n### Breaking Changes\n\n- The packages `@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. ([#4327](https://github.com/udecode/plate/pull/4327))\n- **Migration**:\n - Replace `@udecode/plate-basic-elements` and `@udecode/plate-basic-marks` in your dependencies with `@platejs/basic-nodes`.\n - Update all import paths from `@udecode/plate-basic-elements/react` or `@udecode/plate-basic-marks/react` to `@platejs/basic-nodes/react`.\n - `CodeBlockPlugin` is **not** part of `@platejs/basic-nodes`. Ensure it is imported from `@platejs/code-block/react`.\n- `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' } } })`.\n- Default HTML Tag Changes:\n - **Blocks**: Element plugins in `@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.\n - **Marks**: Mark plugins in `@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.\n- Removed Default Shortcuts:\n - Default keyboard shortcuts are no longer bundled with most plugins (exceptions: bold, italic, underline).\n - Configure shortcuts manually via the `shortcuts` field in plugin configuration.\n - Example (Block Plugins):\n ```ts\n H1Plugin.configure({ shortcuts: { toggle: { keys: 'mod+alt+1' } } });\n BlockquotePlugin.configure({\n shortcuts: { toggle: { keys: 'mod+shift+period' } },\n });\n ```\n - Example (Mark Plugins):\n ```ts\n CodePlugin.configure({ shortcuts: { toggle: { keys: 'mod+e' } } });\n StrikethroughPlugin.configure({\n shortcuts: { toggle: { keys: 'mod+shift+x' } },\n });\n SubscriptPlugin.configure({\n shortcuts: { toggle: { keys: 'mod+comma' } },\n });\n SuperscriptPlugin.configure({\n shortcuts: { toggle: { keys: 'mod+period' } },\n });\n HighlightPlugin.configure({\n shortcuts: { toggle: { keys: 'mod+shift+h' } },\n });\n ```\n\n### Features\n\n- New `toggle` Transforms Added: ([#4327](https://github.com/udecode/plate/pull/4327))\n - Block plugins with new `toggle` transforms: `BlockquotePlugin`, `H1Plugin`, `H2Plugin`, `H3Plugin`, `H4Plugin`, `H5Plugin`, `H6Plugin`.\n - All mark plugins in this package now also feature a `toggle` transform, including: `BoldPlugin`, `ItalicPlugin`, `UnderlinePlugin`, `CodePlugin`, `StrikethroughPlugin`, `SubscriptPlugin`, `SuperscriptPlugin`, `KbdPlugin`, `HighlightPlugin`.\n- Individual Heading Plugins Available:\n - `H1Plugin`, `H2Plugin`, `H3Plugin`, `H4Plugin`, `H5Plugin`, and `H6Plugin` offer a flexible alternative to the general `HeadingPlugin`, allowing granular control over heading level inclusion and configuration (e.g., custom components, shortcuts per level).\n- Plugin Consolidations into `@udecode/plate-basic-nodes`:\n - `KbdPlugin` (formerly from `@udecode/plate-kbd`).\n - `HighlightPlugin` (formerly from `@udecode/plate-highlight`).\n\n`@udecode/plate-block-quote`\n\n### Breaking Changes\n\n- Package `@udecode/plate-block-quote` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `BlockquotePlugin` has been moved to the `@platejs/basic-nodes` package.\n- Migration:\n - Remove `@udecode/plate-block-quote` from your dependencies.\n - Add `@platejs/basic-nodes` to your dependencies if not already present.\n - Import `BlockquotePlugin` from `@platejs/basic-nodes/react`.\n\n`@udecode/plate-break`\n\n### Breaking Changes\n\n- Package `@udecode/plate-break` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `SoftBreakPlugin` has been removed. Migration:\n - For `shift+enter` rules: no migration is needed - this behavior is built into Slate by default.\n - For `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.\n - For more complex break rules: use `overrideEditor` to override the `insertBreak` transform with custom logic.\n- `ExitBreakPlugin` has been moved to `@platejs/utils` (which is re-exported via `platejs`) with a simplified API and improved behavior.\n\n - **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.\n - Migration:\n\n - Remove `@udecode/plate-break` from your dependencies.\n - Replace `@udecode/plate-break` import with `platejs`.\n - **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.\n - Replace complex rule-based configuration with simple shortcuts:\n\n ```tsx\n // Before (old API)\n ExitBreakPlugin.configure({\n options: {\n rules: [\n { hotkey: 'mod+enter' },\n { hotkey: 'mod+shift+enter', before: true },\n ],\n },\n });\n\n // After (new API)\n ExitBreakPlugin.configure({\n shortcuts: {\n insert: { keys: 'mod+enter' },\n insertBefore: { keys: 'mod+shift+enter' },\n },\n });\n ```\n\n`@udecode/plate-callout`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-caption`\n\n### Breaking Changes\n\n- `CaptionPlugin` option `options.plugins` (accepting an array of `PlatePlugin`) has been renamed to `options.query.allow` (accepting an array of plugin keys). ([#4327](https://github.com/udecode/plate/pull/4327))\n- Migration:\n\n ```tsx\n // Before\n CaptionPlugin.configure({\n options: {\n plugins: [ImagePlugin], // ImagePlugin is an example\n },\n });\n\n // After\n CaptionPlugin.configure({\n options: {\n query: {\n allow: [ImagePlugin.key], // Use the plugin's key\n },\n },\n });\n ```\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-code-block`\n\n### Breaking Changes\n\n- `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`). ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-combobox`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-comments`\n\n### Breaking Changes\n\n- `CommentsPlugin` has been renamed to `CommentPlugin`. ([#4327](https://github.com/udecode/plate/pull/4327))\n- Update imports and plugin configurations accordingly.\n - Example: `CommentsPlugin.key` becomes `CommentPlugin.key`.\n- Package name has been changed to `@platejs/comment`.\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-core`\n\n### Breaking Changes\n\n- `editor.getType()` now takes a `pluginKey: string` instead of a `plugin: PlatePlugin` instance. ([#4327](https://github.com/udecode/plate/pull/4327))\n - Example: Use `editor.getType(ParagraphPlugin.key)` instead of `editor.getType(ParagraphPlugin)`.\n- Plugins without a `key` property will not be registered into the editor.\n- Passing `disabled: true` prop to `PlateContent` will now also set the editor to `readOnly: true` state internally.\n- Editor DOM state properties have been moved under `editor.dom` namespace:\n - `editor.currentKeyboardEvent` is now `editor.dom.currentKeyboardEvent`.\n - `editor.prevSelection` is now `editor.dom.prevSelection`.\n- Editor metadata properties have been moved under `editor.meta` namespace:\n - `editor.isFallback` is now `editor.meta.isFallback`\n - `editor.key` is now `editor.meta.key`\n - `editor.pluginList` is now `editor.meta.pluginList`\n - `editor.shortcuts` is now `editor.meta.shortcuts`\n - `editor.uid` is now `editor.meta.uid`\n- `NodeIdPlugin` is now enabled by default as part of the core plugins. This automatically assigns unique IDs to block nodes.\n - Migration: If you were not previously using `NodeIdPlugin` and wish to maintain the old behavior (no automatic IDs), explicitly disable it in your editor configuration:\n ```ts\n const editor = usePlateEditor({\n // ...other options\n nodeId: false, // Disables automatic node ID generation\n });\n ```\n- The `components` prop has been removed from `serializeHtml` and `PlateStatic`.\n - Migration: Pass the `components` to `createSlateEditor({ components })` or the individual plugins instead.\n- Plugin Shortcuts System Changes:\n - Shortcut keys defined in `editor.shortcuts` are now namespaced by the plugin key (e.g., `code.toggle` for `CodePlugin`).\n - The `priority` property for shortcuts is used to resolve conflicts when multiple shortcuts share the exact same key combination, not for overriding shortcuts by name.\n - `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.\n - Migration: If you need to allow browser default behavior for a specific shortcut, set `preventDefault: false` in its configuration:\n ```ts\n MyPlugin.configure({\n shortcuts: {\n myAction: {\n keys: 'mod+s',\n preventDefault: false, // Example: Allow browser's default save dialog\n },\n },\n });\n ```\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n### Features\n\n- New editor DOM state fields available under `editor.dom`: ([#4327](https://github.com/udecode/plate/pull/4327))\n - `editor.dom.composing`: Boolean, true if the editor is currently composing text (e.g., during IME input).\n - `editor.dom.focused`: Boolean, true if the editor currently has focus.\n - `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.\n- New editor metadata fields:\n - `editor.meta.components` - stores the plugin components by key\n- New hook `useEditorComposing`: Allows subscription to the editor's composing state (`editor.dom.composing`) outside of `PlateContent`.\n- `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.\n- New plugin field: `editOnly` (boolean or object).\n - When `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.\n - By default, `render`, `handlers`, and `inject` are considered edit-only (`true`). `normalizeInitialValue` defaults to always active (`false`).\n - Example: `editOnly: { render: false, normalizeInitialValue: true }` would make rendering active always, but normalization only in edit mode.\n- New plugin field: `render.as` (`keyof HTMLElementTagNameMap`).\n - Specifies the default HTML tag name to be used by `PlateElement` (default: `'div'`) or `PlateLeaf` (default: `'span'`) when rendering the node, but only if no custom `node.component` is provided for the plugin.\n - Example: `render: { as: 'h1' }` would make the plugin render its node as an `<h1>` tag by default without the need to provide a custom component.\n- New plugin field: `node.isContainer` (boolean).\n - When `true`, indicates that the plugin's elements are primarily containers for other content.\n- New plugin field: `node.isStrictSiblings` (boolean).\n - When `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).\n - Used by `editor.tf.insertExitBreak` functionality to determine appropriate exit points in nested structures.\n- New plugin field: `rules` (object).\n - Configures common editing behaviors declaratively instead of overriding editor methods. See documentation for more details.\n - `rules.break`: Controls Enter key behavior (`empty`, `default`, `emptyLineEnd`, `splitReset`)\n - `rules.delete`: Controls Backspace key behavior (`start`, `empty`)\n - `rules.merge`: Controls block merging behavior (`removeEmpty`)\n - `rules.normalize`: Controls normalization behavior (`removeEmpty`)\n - `rules.selection`: Controls cursor positioning behavior (`affinity`)\n - `rules.match`: Conditional rule application based on node properties\n- Plugin shortcuts can now automatically leverage existing plugin transforms by specifying the transform name, in addition to custom handlers.\n- New editor transform methods for keyboard handling:\n - `editor.tf.escape`: Handle Escape key events. Returns `true` if the event is handled.\n - `editor.tf.moveLine`: Handle ArrowDown and ArrowUp key events with `reverse` option for direction. Returns `true` if the event is handled.\n - `editor.tf.selectAll`: Handle Ctrl/Cmd+A key events for selecting all content. Returns `true` if the event is handled.\n - `editor.tf.tab`: Handle Tab and Shift+Tab key events with `reverse` option for Shift+Tab. Returns `true` if the event is handled.\n\n### Bug Fixes\n\n- Fixed an issue where `editor.api` and `editor.tf` (transforms) were not consistently available in the props passed to default element components when no custom component was provided for a plugin. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-csv`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-cursor`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-date`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-diff`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-dnd`\n\n### Breaking Changes\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-docx`\n\n### Breaking Changes\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-emoji`\n\n### Breaking Changes\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-excalidraw`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-find-replace`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-floating`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-font`\n\n### Breaking Changes\n\n- Removed `setBlockBackgroundColor` ([#4327](https://github.com/udecode/plate/pull/4327))\n- Removed `setFontSize` – use `tf.fontSize.addMark` instead:\n\n ```ts\n // Before\n editor.api.fontSize.addMark('16px');\n\n // After\n editor.tf.fontSize.addMark('16px');\n ```\n\n - Removed `useColorInput`. Use it in your own codebase, for example:\n\n ```tsx\n function ColorInput() {\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n\n const onClick = () => {\n inputRef.current?.click();\n };\n\n // ...\n }\n ```\n\n - Removed `useColorsCustom` and `useColorsCustomState`. Use it in your own codebase, for example:\n\n ```tsx\n function ColorCustom({ color, colors, customColors, updateCustomColor }) {\n const [customColor, setCustomColor] = React.useState<string>();\n const [value, setValue] = React.useState<string>(color || '#000000');\n\n React.useEffect(() => {\n if (\n !color ||\n customColors.some((c) => c.value === color) ||\n colors.some((c) => c.value === color)\n ) {\n return;\n }\n\n setCustomColor(color);\n }, [color, colors, customColors]);\n\n const computedColors = React.useMemo(\n () =>\n customColor\n ? [\n ...customColors,\n {\n isBrightColor: false,\n name: '',\n value: customColor,\n },\n ]\n : customColors,\n [customColor, customColors]\n );\n\n const updateCustomColorDebounced = React.useCallback(\n debounce(updateCustomColor, 100),\n [updateCustomColor]\n );\n\n const inputProps = {\n value,\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n setValue(e.target.value);\n updateCustomColorDebounced(e.target.value);\n },\n };\n\n // ...\n }\n ```\n\n - Removed `useColorDropdownMenu` and `useColorDropdownMenuState`. Use it in your own codebase, for example:\n\n ```tsx\n export function FontColorToolbarButton({ nodeType }) {\n const editor = useEditorRef();\n\n const selectionDefined = useEditorSelector(\n (editor) => !!editor.selection,\n []\n );\n\n const color = useEditorSelector(\n (editor) => editor.api.mark(nodeType) as string,\n [nodeType]\n );\n\n const [selectedColor, setSelectedColor] = React.useState<string>();\n const [open, setOpen] = React.useState(false);\n\n const onToggle = React.useCallback(\n (value = !open) => {\n setOpen(value);\n },\n [open, setOpen]\n );\n\n const updateColor = React.useCallback(\n (value: string) => {\n if (editor.selection) {\n setSelectedColor(value);\n editor.tf.select(editor.selection);\n editor.tf.focus();\n editor.tf.addMarks({ [nodeType]: value });\n }\n },\n [editor, nodeType]\n );\n\n const clearColor = React.useCallback(() => {\n if (editor.selection) {\n editor.tf.select(editor.selection);\n editor.tf.focus();\n if (selectedColor) {\n editor.tf.removeMarks(nodeType);\n }\n onToggle();\n }\n }, [editor, selectedColor, onToggle, nodeType]);\n\n React.useEffect(() => {\n if (selectionDefined) {\n setSelectedColor(color);\n }\n }, [color, selectionDefined]);\n\n // ...\n }\n ```\n\n`@udecode/plate-heading`\n\n### Breaking Changes\n\n- Package `@udecode/plate-heading` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n - `HeadingPlugin` and individual heading plugins (e.g., `H1Plugin`) have been moved to `@platejs/basic-nodes`.\n - Migration: Import from `@platejs/basic-nodes/react` (e.g., `import { HeadingPlugin } from '@platejs/basic-nodes/react';`).\n - `TocPlugin` has been moved to `@platejs/toc`.\n - Migration: Add `@platejs/toc` to your dependencies and import `TocPlugin` from `@platejs/toc/react`.\n- Remove `@udecode/plate-heading` from your dependencies.\n\n`@udecode/plate-highlight`\n\n### Breaking Changes\n\n- Package `@udecode/plate-highlight` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `HighlightPlugin` has been moved to the `@platejs/basic-nodes` package.\n- Migration:\n - Remove `@udecode/plate-highlight` from your dependencies.\n - Add `@platejs/basic-nodes` to your dependencies if not already present.\n - Import `HighlightPlugin` from `@platejs/basic-nodes/react`.\n\n`@udecode/plate-horizontal-rule`\n\n### Breaking Changes\n\n- Package `@udecode/plate-horizontal-rule` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `HorizontalRulePlugin` has been moved to the `@platejs/basic-nodes` package.\n- Migration:\n - Remove `@udecode/plate-horizontal-rule` from your dependencies.\n - Add `@platejs/basic-nodes` to your dependencies if not already present.\n - Import `HorizontalRulePlugin` from `@platejs/basic-nodes/react`.\n\n`@udecode/plate-indent`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-indent-list`\n\n### Breaking Changes\n\n- Package `@udecode/plate-indent-list` has been renamed to `@platejs/list`. ([#4327](https://github.com/udecode/plate/pull/4327))\n- Migration:\n - Rename all import paths from `@udecode/plate-indent-list` to `@platejs/list`.\n - Update your `package.json`: remove `@udecode/plate-indent-list` and add `@platejs/list`.\n\n`@udecode/plate-juice`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-kbd`\n\n### Breaking Changes\n\n- Package `@udecode/plate-kbd` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `KbdPlugin` has been moved to the `@platejs/basic-nodes` package.\n- Migration:\n - Remove `@udecode/plate-kbd` from your dependencies.\n - Add `@platejs/basic-nodes` to your dependencies if not already present.\n - Import `KbdPlugin` from `@platejs/basic-nodes/react`.\n\n`@udecode/plate-layout`\n\n### Breaking Changes\n\n- Delete backward from a column start will merge into the previous column ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-line-height`\n\n### Breaking Changes\n\n- Package `@udecode/plate-line-height` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n - `LineHeightPlugin` has been moved to the `@platejs/basic-styles` package.\n\n - Migration:\n\n - Remove `@udecode/plate-line-height` from your dependencies.\n - Add `@platejs/basic-styles` to your dependencies if not already present.\n - Import `LineHeightPlugin` from `@platejs/basic-styles/react`.\n\n - `setLineHeight` signature change:\n\n ```ts\n // Before\n setLineHeight(editor, { value: 1.5, setNodesOptions });\n\n // After\n setLineHeight(editor, 1.5, setNodesOptions);\n ```\n\n - Removed `useLineHeightDropdownMenu` and `useLineHeightDropdownMenuState`. Use it in your own codebase, for example:\n\n ```tsx\n export function LineHeightToolbarButton() {\n const editor = useEditorRef();\n const { defaultNodeValue, validNodeValues: values = [] } =\n editor.getInjectProps(LineHeightPlugin);\n\n const value = useSelectionFragmentProp({\n defaultValue: defaultNodeValue,\n getProp: (node) => node.lineHeight,\n });\n\n const onValueChange = (newValue: string) => {\n editor.tf.lineHeight.setNodes(Number(newValue));\n editor.tf.focus();\n };\n\n // ...\n }\n ```\n\n### Features\n\n- New transform method to `LineHeightPlugin`: ([#4327](https://github.com/udecode/plate/pull/4327))\n - `editor.tf.lineHeight.setNodes` - Transform method for setting line height values. Alias to `setLineHeight`\n\n`@udecode/plate-link`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-list`\n\n### Breaking Changes\n\n- The previous `@udecode/plate-list` (classic list implementation) has been moved to `@platejs/list-classic`. ([#4327](https://github.com/udecode/plate/pull/4327))\n - **Migration for users of the classic list**:\n - Rename all import paths from `@udecode/plate-list` to `@platejs/list-classic`.\n - Update your `package.json`: remove the old `@udecode/plate-list` (if it was a direct dependency) and add `@platejs/list-classic`.\n- This package, `@platejs/list`, now contains the functionality previously in `@udecode/plate-indent-list` (indent-based list system).\n - Plugin names have been generalized: `IndentListPlugin` is now `ListPlugin`, `BaseIndentListPlugin` is `BaseListPlugin`, etc. (`*IndentList*` -> `*List*`).\n - The primary plugin key is now `list` (e.g., `ListPlugin.key`) instead of `listStyleType`.\n - Constants for list keys previously in `INDENT_LIST_KEYS` are now available under `KEYS` from `platejs`.\n - Migration for constants:\n - `INDENT_LIST_KEYS.listStyleType` -> `KEYS.listType`\n - `INDENT_LIST_KEYS.todo` -> `KEYS.listTodo`\n - `INDENT_LIST_KEYS.checked` -> `KEYS.listChecked`\n - Other `INDENT_LIST_KEYS.*` map to `KEYS.*` accordingly.\n - Removed `listStyleTypes` option from `ListPlugin`. You should control list rendering via `render.belowNodes` instead.\n - Removed `renderListBelowNodes`.\n- For changelogs of the indent-based list system (now in this package) version `<=48` (when it was `@udecode/plate-indent-list`), refer to its [archived changelog](https://github.com/udecode/plate/blob/7afd88089f4a76c896f3edf928b03c7e9f2ab903/packages/indent-list/CHANGELOG.md).\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-list-classic`\n\n### Breaking Changes\n\n- **Removed Default Shortcuts** for `BulletedListPlugin` and `NumberedListPlugin`. ([#4327](https://github.com/udecode/plate/pull/4327))\n - These shortcuts must now be configured manually using the `shortcuts` field.\n - Example:\n ```tsx\n BulletedListPlugin.configure({\n shortcuts: { toggle: { keys: 'mod+alt+5' } },\n });\n NumberedListPlugin.configure({\n shortcuts: { toggle: { keys: 'mod+alt+6' } },\n });\n ```\n- Package `@udecode/plate-list` has been moved to `@platejs/list-classic`.\n - **Migration**:\n - Rename all import paths from `@udecode/plate-list` to `@platejs/list-classic`.\n - Update your `package.json`: remove `@udecode/plate-list` and add `@platejs/list-classic`.\n- For changelogs of `@udecode/plate-list` version `<=48`, refer to its [archived changelog](https://github.com/udecode/plate/blob/7afd88089f4a76c896f3edf928b03c7e9f2ab903/packages/list/CHANGELOG.md).\n\n`@udecode/plate-markdown`\n\n### Breaking Changes\n\n- Function `indentListToMdastTree` has been renamed to `listToMdastTree` to align with the list plugin renames (`IndentListPlugin` -> `ListPlugin`). ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-math`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-media`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-mention`\n\n### Breaking Changes\n\n- The type `TMentionInputElement` has been removed. ([#4327](https://github.com/udecode/plate/pull/4327))\n- Use `TComboboxInputElement` from `@udecode/plate` instead for input elements, as mention functionality is built upon the combobox.\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-node-id`\n\n### Breaking Changes\n\n- Package `@udecode/plate-node-id` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `NodeIdPlugin` functionality is now part of `@platejs/core` and is **enabled by default**.\n- Migration:\n\n - Remove `NodeIdPlugin` from your explicit plugin list if it was added manually.\n\n - Remove `@udecode/plate-node-id` from your dependencies.\n\n - If you had `NodeIdPlugin` configured with options, move these options to the `nodeId` field in your main editor configuration (`createPlateEditor` or `usePlateEditor` options).\n Example:\n\n ```ts\n // Before\n // const editor = usePlateEditor({\n // plugins: [\n // NodeIdPlugin.configure({ /* ...your options... */ }),\n // ],\n // });\n\n // After\n const editor = usePlateEditor({\n nodeId: {\n /* ...your options... */\n },\n // ...other editor options\n });\n ```\n\n - 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.\n\n`@udecode/plate-normalizers`\n\n### Breaking Changes\n\n- Package `@udecode/plate-normalizers` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- Its plugins have been moved to `platejs` (which is re-exported via `platejs`).\n- Migration:\n - Remove `@udecode/plate-normalizers` from your dependencies.\n - Update import paths to use `platejs`\n\n`@udecode/plate`\n\n### Breaking Changes\n\n- Renamed package to `platejs`: ([#4327](https://github.com/udecode/plate/pull/4327))\n - Replace all `@udecode/plate/react` with `platejs/react`\n - Replace all `'@udecode/plate'` with `'platejs'`\n\n`@udecode/plate-playwright`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-reset-node`\n\n### Breaking Changes\n\n- 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: ([#4327](https://github.com/udecode/plate/pull/4327))\n\n - Remove `@udecode/plate-reset-node` from your dependencies.\n - Remove any usage of `ResetNodePlugin` from your project.\n - Configure reset behaviors directly on the relevant plugins by defining `rules.break` and/or `rules.delete`.\n\n **Example: Resetting a Blockquote to a Paragraph**\n\n ```typescript\n ResetNodePlugin.configure({\n options: {\n rules: [\n {\n types: [BlockquotePlugin.key],\n defaultType: ParagraphPlugin.key,\n hotkey: 'Enter',\n predicate: (editor) =>\n editor.api.isEmpty(editor.selection, { block: true }),\n },\n ],\n },\n });\n\n // After\n BlockquotePlugin.configure({\n rules: {\n break: { empty: 'reset' },\n delete: { start: 'reset' },\n },\n });\n ```\n\n **For custom reset logic (previously `onReset`):**\n\n ```typescript\n // Before\n ResetNodePlugin.configure({\n options: {\n rules: [\n {\n types: [CodeBlockPlugin.key],\n defaultType: ParagraphPlugin.key,\n hotkey: 'Enter',\n predicate: isCodeBlockEmpty,\n onReset: unwrapCodeBlock,\n },\n ],\n },\n });\n\n // After\n CodeBlockPlugin.configure({\n rules: {\n delete: { empty: 'reset' },\n },\n }).overrideEditor(({ editor, tf: { resetBlock } }) => ({\n transforms: {\n resetBlock(options) {\n if (\n editor.api.block({\n at: options?.at,\n match: { type: editor.getType(CodeBlockPlugin.key) },\n })\n ) {\n unwrapCodeBlock(editor);\n return;\n }\n\n return resetBlock(options);\n },\n },\n }));\n ```\n\n`@udecode/plate-resizable`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-select`\n\n### Breaking Changes\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Package `@udecode/plate-select` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- `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.\n- `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.\n- `RemoveEmptyNodesPlugin` has been removed. This behavior is now available through the `rules: { normalize: { removeEmpty: true } }` configuration on individual plugins.\n- Migration:\n - Remove `@udecode/plate-select` from your dependencies.\n - Remove any usage of `SelectOnBackspacePlugin`, `DeletePlugin` from your project.\n - Replace `RemoveEmptyNodesPlugin.configure({ options: { types: ['custom'] } })` with `CustomPlugin.configure({ rules: { normalize: { removeEmpty: true } } })`. This is used by our `LinkPlugin`.\n\n`@udecode/plate-selection`\n\n### Breaking Changes\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-slash-command`\n\n### Breaking Changes\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- The type `TSlashInputElement` has been removed. ([#4327](https://github.com/udecode/plate/pull/4327))\n- Use `TComboboxInputElement` from `platejs` instead for Slash Command input elements, as slash command functionality is built upon the combobox.\n\n`@udecode/slate`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Replaced `editor.api.shouldMergeNodesRemovePrevNode` with `editor.api.shouldMergeNodes`. `shouldMergeNodes` is now controlling the remove + merge behavior ([#4327](https://github.com/udecode/plate/pull/4327))\n\n - Returns `true` if the default merging behavior should be applied.\n - Returns `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.\n\n ```ts\n // Before\n editor.api.shouldMergeNodesRemovePrevNode(prev, current);\n\n // After\n editor.api.shouldMergeNodes(prev, current);\n ```\n\n - Replace `editor.api.fragment` option `structuralTypes` with `unwrap`.\n\n ```ts\n // Before\n editor.api.fragment(editor.selection, { structuralTypes: ['table'] });\n\n // After\n editor.api.fragment(editor.selection, { unwrap: ['table'] });\n ```\n\n### Features\n\n- `editor.tf.insertSoftBreak` now inserts a soft break instead of a hard break. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-suggestion`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-tabbable`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-table`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-tag`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-test-utils`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-toc`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-toggle`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n`@udecode/plate-trailing-block`\n\n### Breaking Changes\n\n- The following plugins now default to `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 })`. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- Package `@udecode/plate-trailing-block` has been deprecated. ([#4327](https://github.com/udecode/plate/pull/4327))\n- Its functionality (e.g., `TrailingBlockPlugin`) has been moved to `@platejs/utils` (which is re-exported via `platejs`).\n- Migration:\n - Remove `@udecode/plate-trailing-block` from your dependencies.\n - Update import paths to use `platejs` (e.g., `import { TrailingBlockPlugin } from 'platejs';`).\n\n`@udecode/plate-utils`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n- 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. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n - Migration: Update imports for these types to pull from `platejs`.\n\n ```tsx\n // Before\n // import { TImageElement } from '@udecode/plate-media';\n\n // After\n import { TImageElement } from 'platejs';\n ```\n\n - Removed `structuralTypes` option from `useSelectionFragment` and `useSelectionFragmentProp`. These hooks now automatically use `plugin.node.isContainer` from enabled plugins.\n\n - Removed:\n - `createNodesHOC`\n - `createNodesWithHOC`\n - `createNodeHOC`\n\n - Removed `usePlaceholderState` hook.\n - Migration: Use the `BlockPlaceholderPlugin` (typically from `platejs`) instead of the `withPlaceholders` HOC and `usePlaceholderState`. Configure placeholders directly within the `BlockPlaceholderPlugin` options.\n ```ts\n // Example BlockPlaceholderPlugin configuration\n BlockPlaceholderPlugin.configure({\n options: {\n className:\n 'before:absolute before:cursor-text before:opacity-30 before:content-[attr(placeholder)]',\n placeholders: {\n [ParagraphPlugin.key]: 'Type something...',\n // ...other placeholders\n },\n query: ({ editor, path }) => {\n // Example query: only show for top-level empty blocks\n return (\n path.length === 1 && editor.api.isEmpty(editor.children[path[0]])\n );\n },\n },\n });\n ```\n\n### Features\n\n- New plugin `SingleBlockPlugin` to restrict editor content to a single block while preserving line breaks, while `SingleLinePlugin` prevents all line breaks. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n - `@platejs/utils` (and by extension, `platejs`) now exports a comprehensive `KEYS` object containing all official plugin keys.\n\n - This is intended to improve decoupling and provide a centralized way to reference plugin keys.\n - Example Usage:\n\n ```ts\n import { KEYS } from 'platejs';\n\n // Instead of: ParagraphPlugin.key\n // Use: KEYS.p\n ```\n\n - Many node type definitions (e.g., `TParagraphElement`, `TLinkElement`) are also now exported from `platejs`, in addition to being available from their specific plugin packages if those still exist or from `@platejs/basic-nodes`.\n\n`@udecode/plate-yjs`\n\n### Breaking Changes\n\n- Renamed all `@udecode/plate-*` packages to `@platejs/*`. Replace `@udecode/plate-` with `@platejs/` in your code. ([#4327](https://github.com/udecode/plate/pull/4327))\n\n[`CHANGELOG`](https://github.com/udecode/plate/pull/4339) · [`v49.0.0`](https://github.com/udecode/plate/pull/4339) · By [@zbeyens](https://github.com/zbeyens)",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the v49 boundary compare link

When the release sync is rerun with --from v49, this boundary entry has no retained previous release, so the regenerated footer replaces the existing v48.0.6...v49.0.0 compare with a duplicate link back to the release PR. Users opening the v49.0.0 full changelog can no longer see the actual v48-to-v49 diff; preserve the previous footer or keep one pre-boundary release available when recomputing filtered history.

Useful? React with 👍 / 👎.

@zbeyens
zbeyens merged commit 11a7c19 into main Jun 30, 2026
6 checks passed
@zbeyens
zbeyens deleted the changeset-release/main branch June 30, 2026 12:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plugin:ai release size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant