Overview
The Steps plugin allows you to create numbered, step-by-step instructions. It’s perfect for tutorials, guides, and any content that requires a sequential flow.
Installation
npm install @yoopta/steps
Basic Usage
import { StepsPlugin } from '@yoopta/steps' ;
const plugins = [
StepsPlugin ,
// ... other plugins
];
< YooptaEditor
editor = { editor }
plugins = { plugins }
/>
Features
Automatic Numbering : Steps are numbered automatically
Nested Content : Each step has a heading and content area
Keyboard Shortcuts : Type steps to insert
Easy Navigation : Add and remove steps easily
Customizable : Full control over styling
Structure
The Steps plugin consists of nested elements:
step-container
└── step-list
└── step-list-item (multiple)
├── step-list-item-heading
└── step-list-item-content
Configuration
import { StepsPlugin } from '@yoopta/steps' ;
const plugins = [
StepsPlugin ,
];
Options
Description shown in menus
shortcuts
string[]
default: "['steps']"
Keyboard shortcuts to trigger the plugin
Commands
buildStepsElements
Creates the initial steps structure.
import { StepsCommands } from '@yoopta/steps' ;
StepsCommands . buildStepsElements ( editor , { items: 3 });
Number of steps to create initially
addStep
Add a new step after the current one.
StepsCommands . addStep ( editor , {
blockId: 'block-id' ,
at: selection ,
});
deleteStep
Remove a specific step.
StepsCommands . deleteStep ( editor , {
blockId: 'block-id' ,
stepId: 'step-id' ,
});
Keyboard Behavior
Enter on Heading : Creates a new step
Enter in Content : Inserts newline within content
Backspace on Heading : Deletes the step (when empty)
Backspace in Content : Prevents deletion at content start
Initial Structure
When created, the plugin initializes with 2 steps:
{
steps : [
{
heading: 'Step 1 heading' ,
content: 'Step 1 content' ,
},
{
heading: 'Step 2 heading' ,
content: 'Step 2 content' ,
},
],
}
Custom Rendering
import { StepsPlugin } from '@yoopta/steps' ;
const CustomSteps = StepsPlugin . extend ({
elements: {
'step-container' : {
render : ( props ) => (
< div className = "steps-container" { ... props . attributes } >
{ props . children }
</ div >
),
},
'step-list' : {
render : ( props ) => (
< ol className = "steps-list" { ... props . attributes } >
{ props . children }
</ ol >
),
},
'step-list-item' : {
render : ( props ) => (
< li className = "step-item" { ... props . attributes } >
{ props . children }
</ li >
),
},
'step-list-item-heading' : {
render : ( props ) => (
< h3 className = "step-heading" { ... props . attributes } >
{ props . children }
</ h3 >
),
},
'step-list-item-content' : {
render : ( props ) => (
< div className = "step-content" { ... props . attributes } >
{ props . children }
</ div >
),
},
},
});
With Custom Numbering
const CustomSteps = StepsPlugin . extend ({
elements: {
'step-list-item' : {
render : ( props ) => {
// Get step index from path or calculate
const stepNumber = getStepNumber ( props );
return (
< li className = "step-item" { ... props . attributes } >
< div className = "step-number" > { stepNumber } </ div >
{ props . children }
</ li >
);
},
},
},
});
Styling Examples
Basic CSS
.steps-container {
counter-reset : step-counter;
}
.step-item {
counter-increment : step-counter;
position : relative ;
padding-left : 3 rem ;
}
.step-item::before {
content : counter ( step-counter );
position : absolute ;
left : 0 ;
top : 0 ;
width : 2 rem ;
height : 2 rem ;
background : #3b82f6 ;
color : white ;
border-radius : 50 % ;
display : flex ;
align-items : center ;
justify-content : center ;
font-weight : bold ;
}
With Progress Line
.step-list {
position : relative ;
}
.step-list::before {
content : '' ;
position : absolute ;
left : 1 rem ;
top : 2 rem ;
bottom : 2 rem ;
width : 2 px ;
background : #e5e7eb ;
}
.step-item {
position : relative ;
padding-left : 4 rem ;
padding-bottom : 2 rem ;
}
Use Cases
Tutorials Step-by-step coding or software tutorials
Recipes Cooking instructions with numbered steps
Installation Guides Software installation procedures
DIY Instructions Assembly or craft project steps
Best Practices
Use concise, action-oriented headings (e.g., “Install dependencies”)
Provide sufficient detail in content area for each step
Ensure steps follow a logical, sequential order
Include expected outcomes or tips within steps
Combine with Code plugin for technical steps
Advanced Patterns
With Conditional Steps
const ConditionalSteps = StepsPlugin . extend ({
elements: {
'step-list-item' : {
props: {
condition: null , // e.g., "macOS", "Windows"
},
render : ( props ) => {
const { condition } = props . element . props ;
return (
< li className = "step-item" { ... props . attributes } >
{ condition && (
< span className = "step-condition" > { condition } </ span >
) }
{ props . children }
</ li >
);
},
},
},
});
With Completion Tracking
const TrackableSteps = StepsPlugin . extend ({
elements: {
'step-list-item' : {
props: {
completed: false ,
},
render : ( props ) => {
const [ completed , setCompleted ] = useState (
props . element . props . completed
);
return (
< li
className = { `step-item ${ completed ? 'completed' : '' } ` }
{ ... props . attributes }
>
< input
type = "checkbox"
checked = { completed }
onChange = { () => setCompleted ( ! completed ) }
/>
{ props . children }
</ li >
);
},
},
},
});