mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: update documentation for customizing a theme
This commit is contained in:
parent
862ba3173a
commit
90b9456b0b
@ -16,7 +16,6 @@ Widget build(BuildContext context) {
|
||||
alignment: Alignment.topCenter,
|
||||
child: AppFlowyEditor(
|
||||
editorState: EditorState.empty(),
|
||||
editorStyle: EditorStyle.defaultStyle(),
|
||||
shortcutEvents: const [],
|
||||
customBuilders: const {},
|
||||
),
|
||||
@ -93,7 +92,7 @@ ShortcutEventHandler _underscoreToItalicHandler = (editorState, event) {
|
||||
// Delete the previous 'underscore',
|
||||
// update the style of the text surrounded by the two underscores to 'italic',
|
||||
// and update the cursor position.
|
||||
TransactionBuilder(editorState)
|
||||
final transaction = editorState.transaction
|
||||
..deleteText(textNode, firstUnderscore, 1)
|
||||
..formatText(
|
||||
textNode,
|
||||
@ -108,8 +107,8 @@ ShortcutEventHandler _underscoreToItalicHandler = (editorState, event) {
|
||||
path: textNode.path,
|
||||
offset: selection.end.offset - 1,
|
||||
),
|
||||
)
|
||||
..commit();
|
||||
);
|
||||
editorState.apply(transaction);
|
||||
|
||||
return KeyEventResult.handled;
|
||||
};
|
||||
@ -125,7 +124,6 @@ Widget build(BuildContext context) {
|
||||
alignment: Alignment.topCenter,
|
||||
child: AppFlowyEditor(
|
||||
editorState: EditorState.empty(),
|
||||
editorStyle: EditorStyle.defaultStyle(),
|
||||
customBuilders: const {},
|
||||
shortcutEvents: [
|
||||
underscoreToItalic,
|
||||
@ -138,7 +136,7 @@ Widget build(BuildContext context) {
|
||||
|
||||
![After](./images/customize_a_shortcut_event_after.gif)
|
||||
|
||||
Check out the [complete code](https://github.com/AppFlowy-IO/AppFlowy/blob/main/frontend/app_flowy/packages/appflowy_editor/example/lib/plugin/underscore_to_italic.dart) file of this example.
|
||||
Check out the [complete code](https://github.com/AppFlowy-IO/AppFlowy/blob/main/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart) file of this example.
|
||||
|
||||
|
||||
## Customizing a Component
|
||||
@ -156,7 +154,6 @@ Widget build(BuildContext context) {
|
||||
alignment: Alignment.topCenter,
|
||||
child: AppFlowyEditor(
|
||||
editorState: EditorState.empty(),
|
||||
editorStyle: EditorStyle.defaultStyle(),
|
||||
shortcutEvents: const [],
|
||||
customBuilders: const {},
|
||||
),
|
||||
@ -180,7 +177,7 @@ We'll use `network_image` in this case. And we add `network_image_src` to the `a
|
||||
|
||||
Then, we create a class that inherits [NodeWidgetBuilder](../lib/src/service/render_plugin_service.dart). As shown in the autoprompt, we need to implement two functions:
|
||||
1. one returns a widget
|
||||
2. the other verifies the correctness of the [Node](../lib/src/document/node.dart).
|
||||
2. the other verifies the correctness of the [Node](../lib/src/core/document/node.dart).
|
||||
|
||||
|
||||
```dart
|
||||
@ -308,7 +305,7 @@ return AppFlowyEditor(
|
||||
|
||||
Check out the [complete code](https://github.com/AppFlowy-IO/AppFlowy/blob/main/frontend/app_flowy/packages/appflowy_editor/example/lib/plugin/network_image_node_widget.dart) file of this example.
|
||||
|
||||
## Customizing a Theme (New Feature in 0.0.5, Alpha)
|
||||
## Customizing a Theme (New Feature in 0.0.7)
|
||||
|
||||
We will use a simple example to illustrate how to quickly customize a theme.
|
||||
|
||||
@ -322,7 +319,6 @@ Widget build(BuildContext context) {
|
||||
alignment: Alignment.topCenter,
|
||||
child: AppFlowyEditor(
|
||||
editorState: EditorState.empty(),
|
||||
editorStyle: EditorStyle.defaultStyle(),
|
||||
shortcutEvents: const [],
|
||||
customBuilders: const {},
|
||||
),
|
||||
@ -338,44 +334,41 @@ At this point, the editor looks like ...
|
||||
Next, we will customize the `EditorStyle`.
|
||||
|
||||
```dart
|
||||
EditorStyle _customizedStyle() {
|
||||
final editorStyle = EditorStyle.defaultStyle();
|
||||
return editorStyle.copyWith(
|
||||
cursorColor: Colors.white,
|
||||
selectionColor: Colors.blue.withOpacity(0.3),
|
||||
textStyle: editorStyle.textStyle.copyWith(
|
||||
defaultTextStyle: GoogleFonts.poppins().copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: 14.0,
|
||||
),
|
||||
defaultPlaceholderTextStyle: GoogleFonts.poppins().copyWith(
|
||||
color: Colors.white.withOpacity(0.5),
|
||||
fontSize: 14.0,
|
||||
),
|
||||
bold: const TextStyle(fontWeight: FontWeight.w900),
|
||||
code: TextStyle(
|
||||
fontStyle: FontStyle.italic,
|
||||
color: Colors.red[300],
|
||||
backgroundColor: Colors.grey.withOpacity(0.3),
|
||||
),
|
||||
highlightColorHex: '0x6FFFEB3B',
|
||||
ThemeData customizeEditorTheme(BuildContext context) {
|
||||
final dark = EditorStyle.dark;
|
||||
final editorStyle = dark.copyWith(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 150),
|
||||
cursorColor: Colors.red.shade600,
|
||||
selectionColor: Colors.yellow.shade600.withOpacity(0.5),
|
||||
textStyle: GoogleFonts.poppins().copyWith(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
),
|
||||
pluginStyles: {
|
||||
'text/quote': builtInPluginStyle
|
||||
..update(
|
||||
'textStyle',
|
||||
(_) {
|
||||
return (EditorState editorState, Node node) {
|
||||
return TextStyle(
|
||||
color: Colors.blue[200],
|
||||
fontStyle: FontStyle.italic,
|
||||
fontSize: 12.0,
|
||||
);
|
||||
};
|
||||
},
|
||||
),
|
||||
},
|
||||
placeholderTextStyle: GoogleFonts.poppins().copyWith(
|
||||
fontSize: 14,
|
||||
color: Colors.grey.shade400,
|
||||
),
|
||||
code: dark.code?.copyWith(
|
||||
backgroundColor: Colors.lightBlue.shade200,
|
||||
fontStyle: FontStyle.italic,
|
||||
),
|
||||
highlightColorHex: '0x60FF0000', // red
|
||||
);
|
||||
|
||||
final quote = QuotedTextPluginStyle.dark.copyWith(
|
||||
textStyle: (_, __) => GoogleFonts.poppins().copyWith(
|
||||
fontSize: 14,
|
||||
color: Colors.blue.shade400,
|
||||
fontStyle: FontStyle.italic,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
);
|
||||
|
||||
return Theme.of(context).copyWith(extensions: [
|
||||
editorStyle,
|
||||
...darkPlguinStyleExtension,
|
||||
quote,
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
@ -389,7 +382,7 @@ Widget build(BuildContext context) {
|
||||
alignment: Alignment.topCenter,
|
||||
child: AppFlowyEditor(
|
||||
editorState: EditorState.empty(),
|
||||
editorStyle: _customizedStyle(),
|
||||
themeData: customizeEditorTheme(context),
|
||||
shortcutEvents: const [],
|
||||
customBuilders: const {},
|
||||
),
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 300 KiB After Width: | Height: | Size: 528 KiB |
Binary file not shown.
Before Width: | Height: | Size: 343 KiB After Width: | Height: | Size: 1.1 MiB |
@ -1,6 +1,7 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:example/plugin/editor_theme.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -54,6 +55,8 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
bool darkMode = false;
|
||||
Future<String>? _jsonString;
|
||||
|
||||
ThemeData? _editorThemeData;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@ -102,7 +105,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
_editorState!.transactionStream.listen((event) {
|
||||
debugPrint('Transaction: ${event.toJson()}');
|
||||
});
|
||||
final themeData = Theme.of(context).copyWith(extensions: [
|
||||
_editorThemeData ??= Theme.of(context).copyWith(extensions: [
|
||||
if (darkMode) ...darkEditorStyleExtension,
|
||||
if (darkMode) ...darkPlguinStyleExtension,
|
||||
if (!darkMode) ...lightEditorStyleExtension,
|
||||
@ -114,7 +117,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
child: AppFlowyEditor(
|
||||
editorState: _editorState!,
|
||||
editable: true,
|
||||
themeData: themeData,
|
||||
themeData: _editorThemeData,
|
||||
customBuilders: {
|
||||
'text/code_block': CodeBlockNodeWidgetBuilder(),
|
||||
'tex': TeXBlockNodeWidgetBuidler(),
|
||||
@ -162,13 +165,22 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
onPressed: () async => await _importDocument(),
|
||||
),
|
||||
ActionButton(
|
||||
icon: const Icon(Icons.color_lens),
|
||||
icon: const Icon(Icons.dark_mode),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
darkMode = !darkMode;
|
||||
});
|
||||
},
|
||||
),
|
||||
ActionButton(
|
||||
icon: const Icon(Icons.color_lens),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_editorThemeData = customizeEditorTheme(context);
|
||||
darkMode = true;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -228,6 +240,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
void _switchToPage(int pageIndex) {
|
||||
if (pageIndex != _pageIndex) {
|
||||
setState(() {
|
||||
_editorThemeData = null;
|
||||
_editorState = null;
|
||||
_pageIndex = pageIndex;
|
||||
});
|
||||
|
@ -0,0 +1,40 @@
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
ThemeData customizeEditorTheme(BuildContext context) {
|
||||
final dark = EditorStyle.dark;
|
||||
final editorStyle = dark.copyWith(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 150),
|
||||
cursorColor: Colors.red.shade600,
|
||||
selectionColor: Colors.yellow.shade600.withOpacity(0.5),
|
||||
textStyle: GoogleFonts.poppins().copyWith(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
),
|
||||
placeholderTextStyle: GoogleFonts.poppins().copyWith(
|
||||
fontSize: 14,
|
||||
color: Colors.grey.shade400,
|
||||
),
|
||||
code: dark.code?.copyWith(
|
||||
backgroundColor: Colors.lightBlue.shade200,
|
||||
fontStyle: FontStyle.italic,
|
||||
),
|
||||
highlightColorHex: '0x60FF0000', // red
|
||||
);
|
||||
|
||||
final quote = QuotedTextPluginStyle.dark.copyWith(
|
||||
textStyle: (_, __) => GoogleFonts.poppins().copyWith(
|
||||
fontSize: 14,
|
||||
color: Colors.blue.shade400,
|
||||
fontStyle: FontStyle.italic,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
);
|
||||
|
||||
return Theme.of(context).copyWith(extensions: [
|
||||
editorStyle,
|
||||
...darkPlguinStyleExtension,
|
||||
quote,
|
||||
]);
|
||||
}
|
@ -117,7 +117,13 @@ class CheckboxPluginStyle extends ThemeExtension<CheckboxPluginStyle> {
|
||||
|
||||
static final light = CheckboxPluginStyle(
|
||||
padding: (_, __) => const EdgeInsets.symmetric(vertical: 8.0),
|
||||
textStyle: (editorState, textNode) => const TextStyle(),
|
||||
textStyle: (editorState, textNode) {
|
||||
final isCheck = textNode.attributes.check;
|
||||
return TextStyle(
|
||||
decoration: isCheck ? TextDecoration.lineThrough : null,
|
||||
color: isCheck ? Colors.grey.shade400 : null,
|
||||
);
|
||||
},
|
||||
icon: (editorState, textNode) {
|
||||
final isCheck = textNode.attributes.check;
|
||||
const iconSize = Size.square(20.0);
|
||||
|
Loading…
Reference in New Issue
Block a user