Overview
Custom blocks allow you to extend AppFlowy Editor with new content types beyond the standard blocks. You can create blocks for any content: code blocks, callouts, embeds, interactive widgets, or domain-specific components.Block Component Architecture
Every block component consists of three main parts:1. Block Keys
Define constants for your block type and attributes:2. Node Factory Function
Create a helper function to generate nodes:3. Block Component Classes
Implement three classes:- Builder - Factory for creating widgets
- Widget - Stateful widget for the block
- State - Widget state with rendering logic
Example: Callout Block
Let’s create a callout block with an icon and colored background:Step 1: Define Block Keys
Step 2: Create Node Factory
Step 3: Create Builder
Step 4: Create Widget
Step 5: Implement State
Step 6: Register in Editor
Essential Mixins
SelectableMixin
Provides basic selection functionality:start()- Starting positionend()- Ending positiongetPositionInOffset()- Position from offsetgetRectsInSelection()- Selection rectanglesgetSelectionInRange()- Selection from range
DefaultSelectableMixin
Provides default implementations for text-based blocks:- Text selection
- Cursor positioning
- Selection rectangles
BlockComponentConfigurable
Provides access to configuration:padding- Block paddingtextStyleWithTextSpan()- Text stylingplaceholderText- Placeholder texttextAlign- Text alignment
NestedBlockComponentStatefulWidgetMixin
Enables nested children support:BlockComponentBackgroundColorMixin
Adds background color support:backgroundColorpropertydecorationwith background
BlockComponentTextDirectionMixin
Adds text direction support:calculateTextDirection()method- LTR/RTL handling
BlockComponentAlignMixin
Adds alignment support:alignmentproperty- Text alignment handling
Example: Code Block
Here’s a syntax-highlighted code block:Example: Toggle/Disclosure Block
A collapsible block with show/hide functionality:Non-Editable Blocks
For blocks without text content (like images or dividers):Block Validation
Implement validation to ensure block integrity:Action Builders
Add custom actions (drag handles, menus):Testing Custom Blocks
Best Practices
- Use appropriate mixins - Only include what you need
- Validate thoroughly - Ensure block structure is valid
- Handle edge cases - Empty states, invalid data
- Provide defaults - Sensible default values
- Document attributes - Clear documentation for attributes
- Test extensively - Unit and integration tests
- Consider accessibility - Keyboard navigation, screen readers
- Performance - Avoid expensive operations in build
- State management - Keep state minimal and efficient
- Consistent styling - Match editor’s design system
Common Patterns
Text-Based Blocks
- Use
DefaultSelectableMixin - Include
AppFlowyRichTextwidget - Support Delta format
Container Blocks
- Use
NestedBlockComponentStatefulWidgetMixin - Render children with
editorState.renderer.build() - Support nesting
Visual Blocks
- Implement custom
SelectableMixinmethods - Use
CursorStyle.coverfor non-text blocks - Return proper rectangles for selection
Interactive Blocks
- Add gesture detectors
- Update state through transactions
- Handle user interactions properly
Related
Block Component Overview
Learn about the block system
Standard Blocks
Explore built-in block types