The selection menu (also known as the slash command menu) appears when you type / in the editor. It provides quick access to block transformations and insertions.
Overview
The selection menu provides:
Quick block insertion (headings, lists, quotes, etc.)
Block transformations
Custom menu items
Keyboard navigation
By default, the selection menu includes:
Text blocks : Paragraph, Headings (H1-H3)
Lists : Bulleted list, Numbered list, Todo list
Media : Image
Advanced : Quote, Divider, Code block, Table
You can customize which items appear in the selection menu:
import 'package:appflowy_editor/appflowy_editor.dart' ;
import 'package:flutter/material.dart' ;
final customSelectionMenuItems = [
// Headings
SelectionMenuItem . node (
name : 'Heading 1' ,
iconData : Icons .h_mobiledata,
keywords : [ 'heading' , 'h1' ],
nodeBuilder : (editorState, _) => headingNode (level : 1 ),
replace : true ,
),
// Lists
SelectionMenuItem . node (
name : 'Bulleted List' ,
iconData : Icons .list,
keywords : [ 'bulleted' , 'list' , 'ul' ],
nodeBuilder : (editorState, _) => bulletedListNode (),
replace : true ,
),
// Custom item
SelectionMenuItem . node (
name : 'Callout' ,
iconData : Icons .info,
keywords : [ 'callout' , 'info' ],
nodeBuilder : (editorState, _) => calloutNode (),
replace : true ,
),
];
Create custom menu items for your block types:
import 'package:appflowy_editor/appflowy_editor.dart' ;
final customBlockMenuItem = SelectionMenuItem (
name : 'Custom Block' ,
icon : (editorState, isSelected, style) => SelectionMenuIcon (
icon : Icons . extension ,
isSelected : isSelected,
style : style,
),
keywords : [ 'custom' , 'block' ],
handler : (editorState, menuService, context) {
final selection = editorState.selection;
if (selection == null ) {
return ;
}
// Create and insert your custom block
final node = Node (
type : 'custom_block' ,
attributes : {
'content' : '' ,
},
);
final transaction = editorState.transaction;
transaction. insertNode (selection.start.path, node);
transaction.afterSelection = Selection . collapsed (
Position (path : selection.start.path.next),
);
editorState. apply (transaction);
menuService. dismiss ();
},
);
There are different types of selection menu items:
Node-based items
Insert or replace with a new node:
SelectionMenuItem . node (
name : 'Quote' ,
iconData : Icons .format_quote,
keywords : [ 'quote' , 'blockquote' ],
nodeBuilder : (editorState, _) => quoteNode (),
replace : true , // Replace current block
)
Action-based items
Execute custom actions:
SelectionMenuItem (
name : 'Insert Date' ,
icon : (editorState, isSelected, style) => SelectionMenuIcon (
icon : Icons .calendar_today,
isSelected : isSelected,
style : style,
),
keywords : [ 'date' , 'today' ],
handler : (editorState, menuService, context) {
final selection = editorState.selection;
if (selection == null ) return ;
final now = DateTime . now ();
final dateText = ' ${ now . year } - ${ now . month } - ${ now . day } ' ;
editorState. insertTextAtCurrentSelection (dateText);
menuService. dismiss ();
},
)
Apply your custom selection menu to the editor:
import 'package:appflowy_editor/appflowy_editor.dart' ;
import 'package:flutter/material.dart' ;
class EditorWithCustomMenu extends StatelessWidget {
const EditorWithCustomMenu ({ super .key});
@override
Widget build ( BuildContext context) {
return AppFlowyEditor (
editorState : EditorState . blank (),
// Custom selection menu items will be used
);
}
}
Customize the appearance of the selection menu:
final menuStyle = SelectionMenuStyle (
backgroundColor : Colors .white,
borderRadius : BorderRadius . circular ( 8.0 ),
itemHeight : 40.0 ,
itemIconSize : 18.0 ,
itemIconPadding : const EdgeInsets . only (right : 8.0 ),
);
Keyboard navigation
The selection menu supports keyboard navigation:
↑/↓ Arrow keys : Navigate menu items
Enter : Select highlighted item
Escape : Close menu
Type to filter : Items are filtered as you type
Filtering items
Menu items are automatically filtered based on:
Item name
Keywords
User input after /
For example, typing /h1 will show heading-related items.
Custom slash trigger
You can customize the trigger character:
// Use a different character to trigger the menu
CharacterShortcutEvent (
key : 'Show selection menu' ,
character : '@' , // Use @ instead of /
handler : (editorState) async {
// Show selection menu
return true ;
},
)
The selection menu is triggered by the / character by default. Users can type to filter menu items and use arrow keys to navigate.
To disable the selection menu:
AppFlowyEditor . custom (
editorState : editorState,
blockComponentBuilders : standardBlockComponentBuilderMap,
characterShortcutEvents : [
// Remove slash menu shortcut from the list
...standardCharacterShortcutEvents. where (
(event) => event.key != 'Show selection menu' ,
),
],
)
Shortcut Events Create custom keyboard shortcuts
Custom Blocks Build custom block components