← Back to Craft
AgentCraft
Rich-text and block editors
Extends an existing editor engine with schema-aware blocks and commands instead of bypassing its document model.
rich-text-block-editors
See how it helpsWhen is it useful?
Use when adding custom blocks, slash menus or structural transforms.
What does it help you do?
- Uses the engine's node, mark and schema extension points.
- Isolates custom interactive views from ordinary text editing.
- Preserves selection and history across block transformations.
Try asking this
Add a callout block and a paragraph-to-callout command with reliable undo and keyboard editing. Convert a selected paragraph, edit its text and undo the edits in order. Preserve text marks, cursor position and a valid document schema throughout.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
Rich Text & Block Editors
Use this skill when building or extending rich-text and block-based editors (such as ProseMirror, Tiptap, Lexical, Slate, or BlockNote) with custom blocks, inline marks, and interactive node views.
Extending Existing Engines Instead of Reinventing Them
- Leverage the Engine's Schema, Node, and Mark Primitives:
- Do not build a custom
contenteditablerich-text engine from scratch when standard editing primitives are needed. - Model inline formatting (bold, italic, code, links, highlights) as Marks (or inline nodes in Lexical) with explicit exclusivity, spanning, and inclusive/non-inclusive boundary rules (e.g., typing at the end of a link or inline-code span should not trap the user inside the mark forever).
- Model structural elements (paragraphs, headings, callouts, checklists, tables, code blocks, embeds, columns) as Block Nodes with strict content expressions (
inline*,block+, oratom: true).
- Do not build a custom
- Isolating & Atomic Custom Node Views:
- When embedding interactive UI components (e.g., image galleries, chart blocks, database views, form inputs, variable chips) inside the editor via
NodeView/DecoratorNode:- Mark non-text custom blocks as
atom: trueorisolating: trueas appropriate. - Stop event propagation (
stopEvent) inside custom interactive inputs (such as a caption input, dropdown, or code sub-editor) so typing or pressingBackspaceinside the widget does not delete the surrounding block in the parent editor. - Always provide a way for the keyboard caret to navigate into, around, and past atomic blocks (e.g., gap cursor support at document start/end and between adjacent non-text blocks).
- Mark non-text custom blocks as
- When embedding interactive UI components (e.g., image galleries, chart blocks, database views, form inputs, variable chips) inside the editor via
Block Operations, Slash Menus & Turn-Into Transforms
- Preserve Content Across Block Type Conversions ("Turn Into"):
- Converting a paragraph $\leftrightarrow$ heading $\leftrightarrow$ bullet/numbered/todo list item $\leftrightarrow$ quote/callout must preserve inline text, marks, and compatible child blocks within a single transaction.
- Slash Commands & Floating Menus:
- Anchor slash menus (
/) and bubble toolbars to the resolved selection coordinates using virtual positioning, dismiss cleanly onEscapeor outside click, and filter commands without stealing IME composition input.
- Anchor slash menus (
Checklist
- Are inline marks configured with clear boundary rules so users can easily type outside links and code spans?
- Do custom
NodeView/DecoratorNodewidgets isolate their internal events soBackspaceor arrow keys inside an input do not corrupt the parent document? - Can the keyboard cursor reach before, between, and after atomic blocks (gap cursor)?
- Do "Turn into" block conversions preserve inline text and marks inside a single undoable transaction?
Included files 1
SKILL.md
