AppFlowy Editor provides a powerful shortcut system that allows you to define custom keyboard shortcuts and character-triggered events. You can create shortcuts for text formatting, block transformations, and custom behaviors.
Overview
There are two types of shortcut events:
CharacterShortcutEvent - Triggered when specific characters are typed
CommandShortcutEvent - Triggered by keyboard combinations (Ctrl/Cmd + key)
Character shortcut events
CharacterShortcutEvent allows you to trigger actions when users type specific characters. This is perfect for markdown-style formatting.
Basic example: Underscore to italic
Here’s an example that converts _text_ to italic formatting:
import 'package:appflowy_editor/appflowy_editor.dart' ;
import 'package:flutter/material.dart' ;
CharacterShortcutEvent underscoreToItalicEvent = CharacterShortcutEvent (
key : 'Underscore to italic' ,
character : '_' ,
handler : (editorState) async => handleFormatByWrappingWithSingleCharacter (
editorState : editorState,
character : '_' ,
formatStyle : FormatStyleByWrappingWithSingleChar .italic,
),
);
Source: documentation/customizing.md:44-52
Applying character shortcuts
Inject your custom shortcuts into the editor:
class UnderScoreToItalic extends StatelessWidget {
const UnderScoreToItalic ({ super .key});
@override
Widget build ( BuildContext context) {
return AppFlowyEditor . custom (
editorState : EditorState . blank (withInitialText : true ),
blockComponentBuilders : standardBlockComponentBuilderMap,
characterShortcutEvents : [
underScoreToItalicEvent,
// Add more character shortcuts here
],
);
}
}
Source: documentation/customizing.md:61-74
Built-in character shortcuts
AppFlowy Editor includes many built-in character shortcuts:
# - Convert to heading 1
## - Convert to heading 2
### - Convert to heading 3
* or - - Convert to bulleted list
1. - Convert to numbered list
> - Convert to quote
**text** - Bold formatting
*text* - Italic formatting
`code` - Code formatting
--- - Insert divider
See the CharacterShortcutEvent API for more examples.
Command shortcut events
CommandShortcutEvent handles keyboard combinations like Ctrl+B for bold or Cmd+Z for undo.
Creating command shortcuts
import 'package:appflowy_editor/appflowy_editor.dart' ;
import 'package:flutter/material.dart' ;
import 'package:flutter/services.dart' ;
CommandShortcutEvent customBoldShortcut = CommandShortcutEvent (
key : 'Toggle bold' ,
command : 'ctrl+b' ,
macOSCommand : 'cmd+b' ,
handler : (editorState) {
final selection = editorState.selection;
if (selection == null || selection.isCollapsed) {
return KeyEventResult .ignored;
}
editorState. toggleAttribute (
AppFlowyRichTextKeys .bold,
);
return KeyEventResult .handled;
},
);
Define different shortcuts for different platforms:
CommandShortcutEvent (
key : 'Save document' ,
command : 'ctrl+s' , // Windows/Linux
macOSCommand : 'cmd+s' , // macOS
handler : (editorState) {
// Save logic here
return KeyEventResult .handled;
},
)
Applying command shortcuts
AppFlowyEditor . custom (
editorState : editorState,
blockComponentBuilders : standardBlockComponentBuilderMap,
commandShortcutEvents : [
customBoldShortcut,
// Add more command shortcuts
],
)
Advanced patterns
Multi-character triggers
You can create shortcuts that trigger on multiple characters:
CharacterShortcutEvent (
key : 'Smart quotes' ,
character : '"' ,
handler : (editorState) async {
// Replace straight quotes with smart quotes
final selection = editorState.selection;
if (selection == null ) {
return false ;
}
// Implementation here
return true ;
},
)
Conditional shortcuts
Make shortcuts context-aware:
CommandShortcutEvent (
key : 'Indent list item' ,
command : 'tab' ,
handler : (editorState) {
final selection = editorState.selection;
if (selection == null ) {
return KeyEventResult .ignored;
}
final node = editorState. getNodeAtPath (selection.start.path);
if (node == null ) {
return KeyEventResult .ignored;
}
// Only indent if it's a list item
if (node.type == BulletedListBlockKeys .type ||
node.type == NumberedListBlockKeys .type) {
// Indent logic
return KeyEventResult .handled;
}
return KeyEventResult .ignored;
},
)
Shortcut events are evaluated in the order they’re added to the list. If a handler returns true or KeyEventResult.handled, subsequent shortcuts won’t be evaluated.
Combining with standard shortcuts
You can combine your custom shortcuts with the built-in ones:
final customShortcuts = [
underscoreToItalicEvent,
customBoldShortcut,
];
AppFlowyEditor . custom (
editorState : editorState,
blockComponentBuilders : standardBlockComponentBuilderMap,
characterShortcutEvents : [
...standardCharacterShortcutEvents,
...customShortcuts,
],
commandShortcutEvents : [
...standardCommandShortcutEvents,
customBoldShortcut,
],
)
Be careful not to override important system shortcuts (like Ctrl+C for copy) unless you have a specific reason to do so.
CharacterShortcutEvent API Complete API reference for character shortcuts
CommandShortcutEvent API Complete API reference for command shortcuts