Major Changes
-
#4941 by @zbeyens – Deprecate
@platejs/autoformat. Markdown shortcuts and text substitutions are now authored asinputRuleson each feature plugin, andAutoformatPluginremains only as an inert compatibility export.Migration:
- Remove
AutoformatPluginfrom your plugins and replace@platejs/autoformatafter migrating rules. - Replace each old
AutoformatRulewith the matching rule factory on the plugin that owns the feature. See the table below. - Replace symbol substitutions (arrows, fractions, smart quotes, legal, math operators) with
createTextSubstitutionInputRuleregistered on a localcreateSlatePlugin. - Replace
rules[].querywithenabledon the rule factory call. Replace the global code-block guard with a per-pluginenabledcheck. - Drop
enableUndoOnDelete— undo-on-delete is the built-in behavior. - Replace custom
AutoformatRuledefinitions withcreateRuleFactoryfromplatejs.
// Before import { AutoformatPlugin } from "@platejs/autoformat"; const editor = createPlateEditor({ plugins: [ AutoformatPlugin.configure({ options: { enableUndoOnDelete: true, rules: [ { match: "# ", mode: "block", type: KEYS.h1 }, { match: "**", mode: "mark", type: KEYS.bold }, { match: "* ", mode: "block", type: "list", format: (editor) => toggleList(editor, { listStyleType: KEYS.ul }), }, ], }, }), ], }); // After import { BoldRules } from "@platejs/basic-nodes"; import { BoldPlugin } from "@platejs/basic-nodes/react"; import { HeadingRules } from "@platejs/basic-nodes"; import { H1Plugin } from "@platejs/basic-nodes/react"; import { BulletedListRules } from "@platejs/list"; import { ListPlugin } from "@platejs/list/react"; const editor = createPlateEditor({ plugins: [ H1Plugin.configure({ inputRules: [HeadingRules.markdown()] }), BoldPlugin.configure({ inputRules: [BoldRules.markdown({ variant: "*" })], }), ListPlugin.configure({ inputRules: [BulletedListRules.markdown({ variant: "-" })], }), ], });
Rule Map
Basic blocks —
@platejs/basic-nodesOld rule New rule { match: '# '..'###### ', mode: 'block', type: KEYS.h1..h6 }HxPlugin.configure({ inputRules: [HeadingRules.markdown()] })— register on eachH1Plugin..H6Plugin{ match: '> ', mode: 'block', type: KEYS.blockquote }BlockquotePlugin.configure({ inputRules: [BlockquoteRules.markdown()] }){ match: ['---', '—-', '___ '], mode: 'block', type: KEYS.hr }HorizontalRulePlugin.configure({ inputRules: [HorizontalRuleRules.markdown({ variant: '-' }), HorizontalRuleRules.markdown({ variant: '_' })] })Basic marks —
@platejs/basic-nodesOld rule New rule Owning plugin { match: '**', mode: 'mark', type: KEYS.bold }BoldRules.markdown({ variant: '*' })BoldPlugin{ match: '__', mode: 'mark', type: KEYS.underline }UnderlineRules.markdown()UnderlinePlugin{ match: '*', mode: 'mark', type: KEYS.italic }ItalicRules.markdown({ variant: '*' })ItalicPlugin{ match: '_', mode: 'mark', type: KEYS.italic }ItalicRules.markdown({ variant: '_' })ItalicPlugin{ match: '`', mode: 'mark', type: KEYS.code }CodeRules.markdown()CodePlugin{ match: '~~', mode: 'mark', type: KEYS.strikethrough }StrikethroughRules.markdown()StrikethroughPlugin{ match: '~', mode: 'mark', type: KEYS.sub }SubscriptRules.markdown()SubscriptPlugin{ match: '^', mode: 'mark', type: KEYS.sup }SuperscriptRules.markdown()SuperscriptPlugin{ match: '==', mode: 'mark', type: KEYS.highlight }HighlightRules.markdown({ variant: '==' })HighlightPlugin{ match: '≡', mode: 'mark', type: KEYS.highlight }HighlightRules.markdown({ variant: '≡' })HighlightPlugin{ match: '***', mode: 'mark', type: [bold, italic] }MarkComboRules.markdown({ variant: 'boldItalic' })BoldPlugin{ match: '__*', mode: 'mark', type: [underline, italic] }MarkComboRules.markdown({ variant: 'italicUnderline' })BoldPlugin{ match: '__**', mode: 'mark', type: [underline, bold] }MarkComboRules.markdown({ variant: 'boldUnderline' })BoldPlugin{ match: '___***', mode: 'mark', type: [underline, bold, italic] }MarkComboRules.markdown({ variant: 'boldItalicUnderline' })BoldPluginRegister each family on its owning plugin:
BoldPlugin.configure({ inputRules: [ BoldRules.markdown({ variant: "*" }), BoldRules.markdown({ variant: "_" }), MarkComboRules.markdown({ variant: "boldItalic" }), MarkComboRules.markdown({ variant: "boldUnderline" }), MarkComboRules.markdown({ variant: "boldItalicUnderline" }), MarkComboRules.markdown({ variant: "italicUnderline" }), ], });
Code block —
@platejs/code-blockOld rule New rule { match: '```', mode: 'block', type: KEYS.codeBlock, format: insertEmptyCodeBlock }CodeBlockPlugin.configure({ inputRules: [CodeBlockRules.markdown({ on: 'match' })] })Lists —
@platejs/listand@platejs/list-classicOld rule New rule { match: ['- ', '* '], mode: 'block', format: toggleList(..., { listStyleType: KEYS.ul }) }BulletedListRules.markdown({ variant: '-' }),BulletedListRules.markdown({ variant: '*' }){ match: /^\d+\.$ |^\d+\)$ /, matchByRegex: true, format: toggleList(..., { listStyleType: KEYS.ol }) }OrderedListRules.markdown({ variant: '.' }),OrderedListRules.markdown({ variant: ')' }){ match: '[] ', mode: 'block', format: toggleList(..., { listStyleType: KEYS.listTodo }) }TaskListRules.markdown({ checked: false }){ match: '[x] ', mode: 'block', format: toggleList + setNodes({ checked: true }) }TaskListRules.markdown({ checked: true })ListPlugin.configure({ inputRules: [ BulletedListRules.markdown({ variant: "-" }), BulletedListRules.markdown({ variant: "*" }), OrderedListRules.markdown({ variant: "." }), OrderedListRules.markdown({ variant: ")" }), TaskListRules.markdown({ checked: false }), TaskListRules.markdown({ checked: true }), ], });
Replace
@platejs/listwith@platejs/list-classicimports when using the classic list model. The factory names are identical.Math —
@platejs/mathOld rule New rule Inline equation $…$InlineEquationPlugin.configure({ inputRules: [MathRules.markdown({ variant: '$' })] })Block equation $$…$$EquationPlugin.configure({ inputRules: [MathRules.markdown({ on: 'break', variant: '$$' })] })Link —
@platejs/linkOld behavior New rule [text](url)markdownLinkRules.markdown()Autolink on paste LinkRules.autolink({ variant: 'paste' })Autolink on space LinkRules.autolink({ variant: 'space' })Autolink on Enter LinkRules.autolink({ variant: 'break' })LinkPlugin.configure({ inputRules: [ LinkRules.markdown(), LinkRules.autolink({ variant: "paste" }), LinkRules.autolink({ variant: "space" }), LinkRules.autolink({ variant: "break" }), ], });
Text substitutions (arrows, fractions, legal, math operators, smart quotes)
Move these to a local
createSlatePluginwithcreateTextSubstitutionInputRule:import { createSlatePlugin, createTextSubstitutionInputRule, KEYS, } from "platejs"; const isTextSubstitutionBlocked = (editor) => editor.api.some({ match: { type: [editor.getType(KEYS.codeBlock)] } }); const ShortcutsPlugin = createSlatePlugin({ key: "shortcuts", inputRules: [ createTextSubstitutionInputRule({ enabled: ({ editor }) => !isTextSubstitutionBlocked(editor), patterns: [ { format: "→", match: "->" }, { format: "⇒", match: "=>" }, { format: "½", match: "1/2" }, { format: "™", match: ["(tm)", "(TM)"] }, { format: ["“", "”"], match: '"' }, ], }), ], });
Each pattern set is just data —
autoformatArrow,autoformatLegal,autoformatMath,autoformatPunctuation,autoformatSmartQuotes, andautoformatLegalHtmlfrom the old package map 1:1 ontopatternsarrays.AutoformatKitin the Plate registry is pre-built with all of them.Custom rules
Old
AutoformatRuleobjects have no direct replacement. Build a rule family withcreateRuleFactory:import { createRuleFactory } from "platejs"; const MyRules = { markdown: createRuleFactory({ type: "blockMatch", match: "!! ", format: "my-block", }), }; MyPlugin.configure({ inputRules: [MyRules.markdown()] });
Option removals
enableUndoOnDelete— removed. Backspace on a rule-inserted node restores the source text by default.rules[].query— replaced byenabledon the rule factory call.rules[].preFormat/rules[].format— replaced by rule-familyformatandresolvecallbacks insidecreateRuleFactory.rules[].trigger— rule families set their own trigger. Override it with thetriggeroption on a customcreateRuleFactorycall.
See the Autoformat doc for the kit path and the Plugin Input Rules guide for the full runtime.
- Remove