-
Notifications
You must be signed in to change notification settings - Fork 249
How to: display an editor
Matt Carroll edited this page Apr 6, 2021
·
1 revision
To display an editor, you first need a Document
to display within the editor.
Documents are currently entirely in-memory.
You can compose a document with code similar to the following:
return MutableDocument(nodes: [
ParagraphNode(
id: DocumentEditor.createNodeId(),
text: AttributedText(text: 'Super Editor'),
metadata: {
'blockType': 'header1',
},
),
ParagraphNode(
id: DocumentEditor.createNodeId(),
text: AttributedText(text: 'Rich text and multimedia'),
metadata: {
'blockType': 'header2',
},
),
ParagraphNode(
id: DocumentEditor.createNodeId(),
text: AttributedText(
text: _loremIpsum1,
attributions: [
SpanMarker(attribution: 'bold', offset: 20, markerType: SpanMarkerType.start),
SpanMarker(attribution: 'bold', offset: 80, markerType: SpanMarkerType.end),
],
),
metadata: {
'textAlign': 'justify',
}),
ParagraphNode(
id: DocumentEditor.createNodeId(),
text: AttributedText(text: _loremIpsum1),
metadata: {
'textAlign': 'center',
},
),
ParagraphNode(
id: DocumentEditor.createNodeId(),
text: AttributedText(text: 'This is some important quotation about something.'),
metadata: {
'blockType': 'blockquote',
},
),
ParagraphNode(
id: DocumentEditor.createNodeId(),
text: AttributedText(text: _loremIpsum1),
metadata: {
'textAlign': 'right',
},
),
ListItemNode.unordered(
id: DocumentEditor.createNodeId(),
text: AttributedText(text: 'This is the 1st list item.'),
),
ListItemNode.unordered(
id: DocumentEditor.createNodeId(),
text: AttributedText(text: 'This is the 2nd list item.'),
),
ListItemNode.unordered(
id: DocumentEditor.createNodeId(),
text: AttributedText(text: 'This is the 3rd list item.'),
indent: 1,
),
HorizontalRuleNode(id: DocumentEditor.createNodeId()),
ListItemNode.ordered(
id: DocumentEditor.createNodeId(),
text: AttributedText(text: 'This is the 1st list item.'),
),
ListItemNode.ordered(
id: DocumentEditor.createNodeId(),
text: AttributedText(text: 'This is the 2nd list item.'),
),
ListItemNode.ordered(
id: DocumentEditor.createNodeId(),
text: AttributedText(text: 'This is the 3rd list item.'),
indent: 1,
),
ParagraphNode(
id: DocumentEditor.createNodeId(),
text: AttributedText(text: _loremIpsum2),
),
ImageNode(
id: DocumentEditor.createNodeId(),
imageUrl:
'https://images.unsplash.com/photo-1612099453097-26a809f51e96?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80',
),
ParagraphNode(
id: DocumentEditor.createNodeId(),
text: AttributedText(text: _loremIpsum3),
),
]);
Display a standard editor with default behavior and rendering:
// Create a DocumentEditor in initState() or some other location
// that only runs once.
final documentEditor = DocumentEditor(document: doc);
// In a build() method, create the Editor widget.
return Editor.standard(
editor: documentEditor,
showDebugPaint: showDebugPaint, // Optional: true to paint debug style UI, false otherwise
);
Display an editor that only shows plain text styling, and displays placeholder boxes for all non-paragraph nodes:
final documentEditor = DocumentEditor(document: doc);
return Editor.custom(
editor: documentEditor,
textStyleBuilder: (attributions) {
// Force all text to look the same, regardless of attributions.
return TextStyle(
color: Colors.black,
fontSize: 13,
fontWeight: FontWeight.normal,
);
},
componentBuilders: [
(ComponentContext componentContext) {
if (componentContext.currentNode is ParagraphNode) {
return paragraphBuilder(componentContext);
} else {
// Display a placeholder box for all nodes other than
// ParagraphNodes
return UnknownComponent();
}
}
],
showDebugPaint: showDebugPaint,
);
Display an editor in dark mode with a custom font:
final documentEditor = DocumentEditor(document: doc);
return Editor.custom(
editor: documentEditor,
textStyleBuilder: (attributions) {
// Make the text white and use a custom GoogleFont.
final style = defaultStyleBuilder(attributions);
return style.copyWith(
color: Colors.white,
fontFamily: GoogleFonts.merriweather().fontFamily,
height: 1.8,
);
},
// Make the selection color yellow to contrast with dark background.
selectionStyle: SelectionStyle(
textCaretColor: Colors.yellow,
selectionColor: Colors.yellow.withOpacity(0.3),
),
componentBuilders: [
// Replace the regular horizontal rule with a light green one.
(ComponentContext componentContext) {
if (componentContext.currentNode is! HorizontalRuleNode) {
return null;
}
final standardHr = horizontalRuleBuilder(componentContext) as HorizontalRuleComponent;
return HorizontalRuleComponent(
componentKey: standardHr.componentKey,
color: Colors.lightGreenAccent,
isSelected: standardHr.isSelected,
selectionColor: standardHr.selectionColor,
);
},
// Customize unordered list items to show an icon instead of a leading dot.
(ComponentContext componentContext) {
if (componentContext.currentNode is! ListItemNode ||
(componentContext.currentNode as ListItemNode).type != ListItemType.unordered) {
return null;
}
final standardUl = unorderedListItemBuilder(componentContext) as UnorderedListItemComponent;
return UnorderedListItemComponent(
textKey: componentContext.componentKey,
text: standardUl.text,
styleBuilder: standardUl.styleBuilder,
dotBuilder: (context, component) {
return Align(
alignment: Alignment.centerRight,
child: Padding(
padding: const EdgeInsets.only(right: 10),
child: Icon(
Icons.opacity,
size: 12,
color: component.styleBuilder({}).color,
),
),
);
},
indent: standardUl.indent,
textSelection: standardUl.textSelection,
selectionColor: standardUl.selectionColor,
hasCaret: standardUl.hasCaret,
caretColor: standardUl.caretColor,
showDebugPaint: standardUl.showDebugPaint,
);
},
...defaultComponentBuilders,
],
showDebugPaint: showDebugPaint,
);