Overview
The Paragraph plugin is the fundamental building block of any document. It provides basic text formatting and should always be included in your editor configuration.
Installation
npm install @yoopta/paragraph
Basic Usage
Pass the plugin to createYooptaEditor; do not pass plugins to <YooptaEditor>.
import { useMemo } from 'react' ;
import YooptaEditor , { createYooptaEditor } from '@yoopta/editor' ;
import Paragraph from '@yoopta/paragraph' ;
const plugins = [ Paragraph ];
export default function Editor () {
const editor = useMemo (() => createYooptaEditor ({ plugins , marks: [] }), []);
return < YooptaEditor editor = { editor } onChange = { () => {} } /> ;
}
Features
Plain Text : Write unformatted text
Text Marks : Supports bold, italic, underline, etc.
Alignment : Left, center, right alignment
Keyboard Shortcuts : Type p or text to insert
Default Block : Typically the default block type
Indentation : Support for nested indentation
Configuration
The Paragraph plugin works out of the box with minimal configuration:
import { Paragraph } from '@yoopta/paragraph' ;
const plugins = [ Paragraph ];
Options
Display title in UI menus
Description shown in menus
shortcuts
string[]
default: "['p', 'text']"
Keyboard shortcuts to trigger the plugin
Commands
Use the Blocks namespace from @yoopta/editor:
import { Blocks } from '@yoopta/editor' ;
// Transform current block to a Paragraph block
Blocks . toggleBlock ( editor , 'Paragraph' , { preserveContent: true });
// Insert a new paragraph block
Blocks . insertBlock ( editor , 'Paragraph' , { at: editor . path . current , focus: true });
// Update paragraph alignment (block meta)
Blocks . updateBlock ( editor , blockId , {
meta: { align: 'center' },
});
Custom Rendering
import { Paragraph } from '@yoopta/paragraph' ;
const CustomParagraph = Paragraph . extend ({
elements: {
paragraph: {
render : ( props ) => {
return (
< p className = "custom-paragraph" { ... props . attributes } >
{ props . children }
</ p >
);
},
},
},
});
With Custom Styling
const StyledParagraph = Paragraph . extend ({
elements: {
paragraph: {
render : ( props ) => {
const align = props . blockData ?. meta ?. align || 'left' ;
return (
< p className = { `paragraph- ${ align } ` } style = { { textAlign: align } } { ... props . attributes } >
{ props . children }
</ p >
);
},
},
},
});
Parsers
HTML Deserialization
The plugin automatically deserializes <p> tags:
< p > This is a paragraph with < strong > bold </ strong > and < em > italic </ em > text. </ p >
HTML Serialization
< p data-meta-align = "left" data-meta-depth = "0" > Your paragraph content </ p >
Markdown Serialization
Email Serialization
The plugin provides email-compatible HTML with inline styles:
< table style = "width: 100%" >
< tbody >
< tr >
< td >
< p style = "font-size: 16px; line-height: 1.75rem; margin: .5rem 0" > Your paragraph content </ p >
</ td >
</ tr >
</ tbody >
</ table >
Text Marks
The Paragraph plugin supports all standard text marks:
Bold : Ctrl/Cmd + B
Italic : Ctrl/Cmd + I
Underline : Ctrl/Cmd + U
Strikethrough : Ctrl/Cmd + Shift + S
Code : Ctrl/Cmd + E
Links : Ctrl/Cmd + K
Each paragraph block can have metadata:
{
align : 'left' | 'center' | 'right' ,
depth : number , // Indentation level
}
Use Cases
Blog Posts Main body text for articles and posts
Documentation Descriptive text in technical docs
Landing Pages Marketing copy and descriptions
Notes Quick notes and text entries
Best Practices
The Paragraph plugin should always be included as it’s typically the default block type
Configure Paragraph as the default block type for new content
The Paragraph plugin should remain simple - use other plugins for complex formatting
Use text marks (bold, italic) for inline formatting within paragraphs
Extensions
The Paragraph plugin includes custom Slate extensions for normalized behavior:
withParagraph
import { withParagraph } from '@yoopta/paragraph' ;
// Applied automatically by the plugin
const slate = withParagraph ( createEditor ());
This extension handles:
Text normalization
Empty paragraph handling
Consistent whitespace behavior
Advanced Patterns
With Drop Caps
const DropCapParagraph = Paragraph . extend ({
elements: {
paragraph: {
render : ( props ) => {
const hasDropCap = props . element . props ?. dropCap ;
return (
< p className = { hasDropCap ? 'drop-cap' : '' } { ... props . attributes } >
{ props . children }
</ p >
);
},
},
},
});
.drop-cap::first-letter {
float : left ;
font-size : 3 em ;
line-height : 0.9 ;
margin : 0 0.1 em 0 0 ;
}
With Character Count
const CountedParagraph = Paragraph . extend ({
elements: {
paragraph: {
render : ( props ) => {
const text = props . element . children . map (( n ) => n . text ). join ( '' );
const count = text . length ;
return (
< div className = "paragraph-wrapper" >
< p { ... props . attributes } > { props . children } </ p >
< span className = "char-count" > { count } characters </ span >
</ div >
);
},
},
},
});