Skip to content

Commit 13805af

Browse files
authored
feat: customized color options (AppFlowy-IO#270)
1 parent 31934d7 commit 13805af

16 files changed

+131
-385
lines changed

example/lib/pages/simple_editor.dart

+3-79
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ class SimpleEditor extends StatelessWidget {
4444
bulletedListItem,
4545
numberedListItem,
4646
linkItem,
47-
textColorItem,
48-
highlightColorItem
47+
buildTextColorItem(),
48+
buildHighlightColorItem()
4949
],
5050
editorState: editorState,
5151
scrollController: scrollController,
@@ -69,7 +69,7 @@ class SimpleEditor extends StatelessWidget {
6969
editorState: editorState,
7070
toolbarItems: [
7171
textDecorationMobileToolbarItem,
72-
textAndBackgroundColorMobileToolbarItem,
72+
buildTextAndBackgroundColorMobileToolbarItem(),
7373
headingMobileToolbarItem,
7474
todoListMobileToolbarItem,
7575
listMobileToolbarItem,
@@ -78,82 +78,6 @@ class SimpleEditor extends StatelessWidget {
7878
dividerMobileToolbarItem,
7979
codeMobileToolbarItem,
8080
],
81-
textColorOptions: [
82-
ColorOption(
83-
colorHex: Colors.grey.toHex(),
84-
name: AppFlowyEditorLocalizations.current.fontColorGray,
85-
),
86-
ColorOption(
87-
colorHex: Colors.brown.toHex(),
88-
name: AppFlowyEditorLocalizations.current.fontColorBrown,
89-
),
90-
ColorOption(
91-
colorHex: Colors.yellow.toHex(),
92-
name: AppFlowyEditorLocalizations.current.fontColorYellow,
93-
),
94-
ColorOption(
95-
colorHex: Colors.green.toHex(),
96-
name: AppFlowyEditorLocalizations.current.fontColorGreen,
97-
),
98-
ColorOption(
99-
colorHex: Colors.blue.toHex(),
100-
name: AppFlowyEditorLocalizations.current.fontColorBlue,
101-
),
102-
ColorOption(
103-
colorHex: Colors.purple.toHex(),
104-
name: AppFlowyEditorLocalizations.current.fontColorPurple,
105-
),
106-
ColorOption(
107-
colorHex: Colors.pink.toHex(),
108-
name: AppFlowyEditorLocalizations.current.fontColorPink,
109-
),
110-
ColorOption(
111-
colorHex: Colors.red.toHex(),
112-
name: AppFlowyEditorLocalizations.current.fontColorRed,
113-
),
114-
],
115-
backgroundColorOptions: [
116-
ColorOption(
117-
colorHex: Colors.grey.withOpacity(0.3).toHex(),
118-
name: AppFlowyEditorLocalizations
119-
.current.backgroundColorGray,
120-
),
121-
ColorOption(
122-
colorHex: Colors.brown.withOpacity(0.3).toHex(),
123-
name: AppFlowyEditorLocalizations
124-
.current.backgroundColorBrown,
125-
),
126-
ColorOption(
127-
colorHex: Colors.yellow.withOpacity(0.3).toHex(),
128-
name: AppFlowyEditorLocalizations
129-
.current.backgroundColorYellow,
130-
),
131-
ColorOption(
132-
colorHex: Colors.green.withOpacity(0.3).toHex(),
133-
name: AppFlowyEditorLocalizations
134-
.current.backgroundColorGreen,
135-
),
136-
ColorOption(
137-
colorHex: Colors.blue.withOpacity(0.3).toHex(),
138-
name: AppFlowyEditorLocalizations
139-
.current.backgroundColorBlue,
140-
),
141-
ColorOption(
142-
colorHex: Colors.purple.withOpacity(0.3).toHex(),
143-
name: AppFlowyEditorLocalizations
144-
.current.backgroundColorPurple,
145-
),
146-
ColorOption(
147-
colorHex: Colors.pink.withOpacity(0.3).toHex(),
148-
name: AppFlowyEditorLocalizations
149-
.current.backgroundColorPink,
150-
),
151-
ColorOption(
152-
colorHex: Colors.red.withOpacity(0.3).toHex(),
153-
name: AppFlowyEditorLocalizations
154-
.current.backgroundColorRed,
155-
),
156-
],
15781
),
15882
],
15983
);

lib/src/editor/toolbar/desktop/items/color/color_menu.dart

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ void showColorMenu(
66
EditorState editorState,
77
Selection selection, {
88
String? currentColorHex,
9+
List<ColorOption>? textColorOptions,
10+
List<ColorOption>? highlightColorOptions,
911
required bool isTextColor,
1012
}) {
1113
// Since link format is only available for single line selection,
@@ -44,8 +46,8 @@ void showColorMenu(
4446
editorState: editorState,
4547
selectedColorHex: currentColorHex,
4648
colorOptions: isTextColor
47-
? generateTextColorOptions()
48-
: generateHighlightColorOptions(),
49+
? textColorOptions ?? generateTextColorOptions()
50+
: highlightColorOptions ?? generateHighlightColorOptions(),
4951
onSubmittedColorHex: (color) {
5052
isTextColor
5153
? formatFontColor(

lib/src/editor/toolbar/desktop/items/color/color_picker.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ class ResetTextColorButton extends StatelessWidget {
173173
onPressed: () {
174174
final selection = editorState.selection!;
175175
editorState
176-
.formatDelta(selection, {BuiltInAttributeKey.textColor: null});
176+
.formatDelta(selection, {FlowyRichTextKeys.textColor: null});
177177
dismissOverlay();
178178
},
179179
icon: FlowySvg(
@@ -225,7 +225,7 @@ class ClearHighlightColorButton extends StatelessWidget {
225225
final selection = editorState.selection!;
226226
editorState.formatDelta(
227227
selection,
228-
{BuiltInAttributeKey.highlightColor: null},
228+
{FlowyRichTextKeys.highlightColor: null},
229229
);
230230
dismissOverlay();
231231
},
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,38 @@
11
import 'package:appflowy_editor/appflowy_editor.dart';
22
import 'package:flutter/material.dart';
33

4-
final highlightColorItem = ToolbarItem(
5-
id: 'editor.highlightColor',
6-
group: 4,
7-
isActive: onlyShowInTextType,
8-
builder: (context, editorState) {
9-
String? highlightColorHex;
4+
ToolbarItem buildHighlightColorItem({List<ColorOption>? colorOptions}) {
5+
return ToolbarItem(
6+
id: 'editor.highlightColor',
7+
group: 4,
8+
isActive: onlyShowInTextType,
9+
builder: (context, editorState) {
10+
String? highlightColorHex;
1011

11-
final selection = editorState.selection!;
12-
final nodes = editorState.getNodesInSelection(selection);
13-
final isHighlight = nodes.allSatisfyInSelection(selection, (delta) {
14-
return delta.everyAttributes(
15-
(attributes) => attributes[FlowyRichTextKeys.highlightColor] != null,
12+
final selection = editorState.selection!;
13+
final nodes = editorState.getNodesInSelection(selection);
14+
final isHighlight = nodes.allSatisfyInSelection(selection, (delta) {
15+
return delta.everyAttributes((attributes) {
16+
highlightColorHex = attributes[FlowyRichTextKeys.highlightColor];
17+
return highlightColorHex != null;
18+
});
19+
});
20+
return IconItemWidget(
21+
iconName: 'toolbar/highlight_color',
22+
iconSize: const Size.square(14),
23+
isHighlight: isHighlight,
24+
tooltip: AppFlowyEditorLocalizations.current.highlightColor,
25+
onPressed: () {
26+
showColorMenu(
27+
context,
28+
editorState,
29+
selection,
30+
currentColorHex: highlightColorHex,
31+
isTextColor: false,
32+
highlightColorOptions: colorOptions,
33+
);
34+
},
1635
);
17-
});
18-
return IconItemWidget(
19-
iconName: 'toolbar/highlight_color',
20-
iconSize: const Size.square(14),
21-
isHighlight: isHighlight,
22-
tooltip: AppFlowyEditorLocalizations.current.highlightColor,
23-
onPressed: () {
24-
showColorMenu(
25-
context,
26-
editorState,
27-
selection,
28-
currentColorHex: highlightColorHex,
29-
isTextColor: false,
30-
);
31-
},
32-
);
33-
},
34-
);
36+
},
37+
);
38+
}
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,39 @@
11
import 'package:appflowy_editor/appflowy_editor.dart';
22
import 'package:flutter/material.dart';
33

4-
final textColorItem = ToolbarItem(
5-
id: 'editor.textColor',
6-
group: 4,
7-
isActive: onlyShowInTextType,
8-
builder: (context, editorState) {
9-
String? textColorHex;
10-
final selection = editorState.selection!;
11-
final nodes = editorState.getNodesInSelection(selection);
12-
final isHighlight = nodes.allSatisfyInSelection(selection, (delta) {
13-
return delta.everyAttributes(
14-
(attributes) => attributes[FlowyRichTextKeys.textColor] != null,
4+
ToolbarItem buildTextColorItem({
5+
List<ColorOption>? colorOptions,
6+
}) {
7+
return ToolbarItem(
8+
id: 'editor.textColor',
9+
group: 4,
10+
isActive: onlyShowInTextType,
11+
builder: (context, editorState) {
12+
String? textColorHex;
13+
final selection = editorState.selection!;
14+
final nodes = editorState.getNodesInSelection(selection);
15+
final isHighlight = nodes.allSatisfyInSelection(selection, (delta) {
16+
return delta.everyAttributes((attributes) {
17+
textColorHex = attributes[FlowyRichTextKeys.textColor];
18+
return (textColorHex != null);
19+
});
20+
});
21+
return IconItemWidget(
22+
iconName: 'toolbar/text_color',
23+
isHighlight: isHighlight,
24+
iconSize: const Size.square(14),
25+
tooltip: AppFlowyEditorLocalizations.current.textColor,
26+
onPressed: () {
27+
showColorMenu(
28+
context,
29+
editorState,
30+
selection,
31+
currentColorHex: textColorHex,
32+
isTextColor: true,
33+
textColorOptions: colorOptions,
34+
);
35+
},
1536
);
16-
});
17-
return IconItemWidget(
18-
iconName: 'toolbar/text_color',
19-
isHighlight: isHighlight,
20-
iconSize: const Size.square(14),
21-
tooltip: AppFlowyEditorLocalizations.current.textColor,
22-
onPressed: () {
23-
showColorMenu(
24-
context,
25-
editorState,
26-
selection,
27-
currentColorHex: textColorHex,
28-
isTextColor: true,
29-
);
30-
},
31-
);
32-
},
33-
);
37+
},
38+
);
39+
}

lib/src/editor/toolbar/mobile/mobile_toolbar.dart

+1-76
Original file line numberDiff line numberDiff line change
@@ -20,78 +20,7 @@ class MobileToolbar extends StatelessWidget {
2020
this.buttonSpacing = 8.0,
2121
this.buttonBorderWidth = 1.0,
2222
this.buttonSelectedBorderWidth = 2.0,
23-
this.textColorOptions = const [
24-
ColorOption(
25-
colorHex: '#808080',
26-
name: 'Gray',
27-
),
28-
ColorOption(
29-
colorHex: '#A52A2A',
30-
name: 'Brown',
31-
),
32-
ColorOption(
33-
colorHex: '#FFFF00',
34-
name: 'Yellow',
35-
),
36-
ColorOption(
37-
colorHex: '#008000',
38-
name: 'Green',
39-
),
40-
ColorOption(
41-
colorHex: '#0000FF',
42-
name: 'Blue',
43-
),
44-
ColorOption(
45-
colorHex: '#800080',
46-
name: 'Purple',
47-
),
48-
ColorOption(
49-
colorHex: '#FFC0CB',
50-
name: 'Pink',
51-
),
52-
ColorOption(
53-
colorHex: '#FF0000',
54-
name: 'Red',
55-
),
56-
],
57-
this.backgroundColorOptions = const [
58-
ColorOption(
59-
colorHex: '#4D4D4D',
60-
name: 'Gray',
61-
),
62-
ColorOption(
63-
colorHex: '#A52A2A',
64-
name: 'Brown',
65-
),
66-
ColorOption(
67-
colorHex: '#FFFF00',
68-
name: 'Yellow',
69-
),
70-
ColorOption(
71-
colorHex: '#008000',
72-
name: 'Green',
73-
),
74-
ColorOption(
75-
colorHex: '#0000FF',
76-
name: 'Blue',
77-
),
78-
ColorOption(
79-
colorHex: '#800080',
80-
name: 'Purple',
81-
),
82-
ColorOption(
83-
colorHex: '#FFC0CB',
84-
name: 'Pink',
85-
),
86-
ColorOption(
87-
colorHex: '#FF0000',
88-
name: 'Red',
89-
),
90-
],
91-
}) : assert(
92-
textColorOptions.length > 0 && backgroundColorOptions.length > 0,
93-
);
94-
23+
});
9524
final EditorState editorState;
9625
final List<MobileToolbarItem> toolbarItems;
9726
// MobileToolbarStyle parameters
@@ -108,8 +37,6 @@ class MobileToolbar extends StatelessWidget {
10837
final double buttonSpacing;
10938
final double buttonBorderWidth;
11039
final double buttonSelectedBorderWidth;
111-
final List<ColorOption> textColorOptions;
112-
final List<ColorOption> backgroundColorOptions;
11340

11441
@override
11542
Widget build(BuildContext context) {
@@ -133,8 +60,6 @@ class MobileToolbar extends StatelessWidget {
13360
buttonSpacing: buttonSpacing,
13461
buttonBorderWidth: buttonBorderWidth,
13562
buttonSelectedBorderWidth: buttonSelectedBorderWidth,
136-
textColorOptions: textColorOptions,
137-
backgroundColorOptions: backgroundColorOptions,
13863
child: MobileToolbarWidget(
13964
// Use selection as key to force rebuild toolbar widget when selection changed.
14065
key: ValueKey(selection),

0 commit comments

Comments
 (0)