feat : allow developer to change toolbar color as well as option to show default toolbar items and html to document converter added (#58)
* change toolbar and added export so developer can modify according to its need * revert some chages from examples * html to document convertion added * test added * code formated * node to html added image parameter * toolbar color and elevation added in editor stylee * code formated * remove duplicated exports * fix test improts and formating
This commit is contained in:
parent
c19239e071
commit
865195f8c6
32 changed files with 71 additions and 34 deletions
|
|
@ -27,7 +27,6 @@ export 'src/service/input_service.dart';
|
|||
export 'src/service/shortcut_event/keybinding.dart';
|
||||
export 'src/service/shortcut_event/shortcut_event.dart';
|
||||
export 'src/service/shortcut_event/shortcut_event_handler.dart';
|
||||
export 'src/extensions/attributes_extension.dart';
|
||||
export 'src/render/rich_text/default_selectable.dart';
|
||||
export 'src/render/rich_text/flowy_rich_text.dart';
|
||||
export 'src/render/selection_menu/selection_menu_widget.dart';
|
||||
|
|
@ -45,7 +44,11 @@ export 'src/plugins/quill_delta/delta_document_encoder.dart';
|
|||
export 'src/commands/text/text_commands.dart';
|
||||
export 'src/commands/command_extension.dart';
|
||||
export 'src/render/toolbar/toolbar_item.dart';
|
||||
export 'src/extensions/node_extensions.dart';
|
||||
export 'src/render/action_menu/action_menu.dart';
|
||||
export 'src/render/action_menu/action_menu_item.dart';
|
||||
export 'src/core/document/node_iterator.dart';
|
||||
export 'src/infra/flowy_svg.dart';
|
||||
export 'src/extensions/extensions.dart';
|
||||
export 'src/service/default_text_operations/format_rich_text_style.dart';
|
||||
export 'src/infra/html_converter.dart';
|
||||
export 'src/service/internal_key_event_handlers/copy_paste_handler.dart';
|
||||
|
|
|
|||
9
lib/src/extensions/extensions.dart
Normal file
9
lib/src/extensions/extensions.dart
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export 'attributes_extension.dart';
|
||||
export 'color_extension.dart';
|
||||
export 'editor_state_extensions.dart';
|
||||
export 'node_extensions.dart';
|
||||
export 'object_extensions.dart';
|
||||
export 'text_node_extensions.dart';
|
||||
|
||||
export 'text_style_extension.dart';
|
||||
export 'url_launcher_extension.dart';
|
||||
|
|
@ -10,6 +10,8 @@ import 'package:html/parser.dart' show parse;
|
|||
import 'package:html/dom.dart' as html;
|
||||
import 'package:appflowy_editor/src/core/legacy/built_in_attribute_keys.dart';
|
||||
|
||||
import '../core/document/document.dart';
|
||||
|
||||
class HTMLTag {
|
||||
static const h1 = "h1";
|
||||
static const h2 = "h2";
|
||||
|
|
@ -60,6 +62,16 @@ class HTMLToNodesConverter {
|
|||
return _handleContainer(childNodes);
|
||||
}
|
||||
|
||||
Document toDocument() {
|
||||
final childNodes = _document.body?.nodes.toList() ?? <html.Node>[];
|
||||
return Document.fromJson({
|
||||
"document": {
|
||||
"type": "editor",
|
||||
"children": _handleContainer(childNodes).map((e) => e.toJson()).toList()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
List<Node> _handleContainer(List<html.Node> childNodes) {
|
||||
final delta = Delta();
|
||||
final result = <Node>[];
|
||||
|
|
@ -432,6 +444,12 @@ class NodesToHTMLConverter {
|
|||
} else {
|
||||
_addTextNode(textNode);
|
||||
}
|
||||
} else if (node.type == "image") {
|
||||
final textNode = node;
|
||||
final anchor = html.Element.tag(HTMLTag.image);
|
||||
anchor.attributes["src"] = textNode.attributes["image_src"];
|
||||
|
||||
_result.add(anchor);
|
||||
}
|
||||
// TODO: handle image and other blocks
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor/src/infra/flowy_svg.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Represents a single action inside an action menu.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor/src/render/rich_text/built_in_text_widget.dart';
|
||||
|
||||
import 'package:appflowy_editor/src/extensions/text_style_extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:appflowy_editor/src/extensions/theme_extension.dart';
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ class EditorStyle extends ThemeExtension<EditorStyle> {
|
|||
final Color? selectionMenuItemSelectedTextColor;
|
||||
final Color? selectionMenuItemSelectedIconColor;
|
||||
final Color? selectionMenuItemSelectedColor;
|
||||
final Color? toolbarColor;
|
||||
final double toolbarElevation;
|
||||
|
||||
// Text styles
|
||||
final EdgeInsets? textPadding;
|
||||
|
|
@ -49,6 +51,8 @@ class EditorStyle extends ThemeExtension<EditorStyle> {
|
|||
required this.selectionMenuItemSelectedTextColor,
|
||||
required this.selectionMenuItemSelectedIconColor,
|
||||
required this.selectionMenuItemSelectedColor,
|
||||
required this.toolbarColor,
|
||||
required this.toolbarElevation,
|
||||
required this.textPadding,
|
||||
required this.textStyle,
|
||||
required this.placeholderTextStyle,
|
||||
|
|
@ -74,6 +78,8 @@ class EditorStyle extends ThemeExtension<EditorStyle> {
|
|||
Color? selectionMenuItemSelectedTextColor,
|
||||
Color? selectionMenuItemSelectedIconColor,
|
||||
Color? selectionMenuItemSelectedColor,
|
||||
Color? toolbarColor,
|
||||
double? toolbarElevation,
|
||||
TextStyle? textStyle,
|
||||
TextStyle? placeholderTextStyle,
|
||||
TextStyle? bold,
|
||||
|
|
@ -102,6 +108,8 @@ class EditorStyle extends ThemeExtension<EditorStyle> {
|
|||
this.selectionMenuItemSelectedIconColor,
|
||||
selectionMenuItemSelectedColor:
|
||||
selectionMenuItemSelectedColor ?? this.selectionMenuItemSelectedColor,
|
||||
toolbarColor: toolbarColor ?? this.toolbarColor,
|
||||
toolbarElevation: toolbarElevation ?? this.toolbarElevation,
|
||||
textPadding: textPadding ?? textPadding,
|
||||
textStyle: textStyle ?? this.textStyle,
|
||||
placeholderTextStyle: placeholderTextStyle ?? this.placeholderTextStyle,
|
||||
|
|
@ -160,6 +168,8 @@ class EditorStyle extends ThemeExtension<EditorStyle> {
|
|||
other.selectionMenuItemSelectedColor,
|
||||
t,
|
||||
),
|
||||
toolbarColor: Color.lerp(toolbarColor, other.toolbarColor, t),
|
||||
toolbarElevation: toolbarElevation,
|
||||
textStyle: TextStyle.lerp(textStyle, other.textStyle, t),
|
||||
placeholderTextStyle:
|
||||
TextStyle.lerp(placeholderTextStyle, other.placeholderTextStyle, t),
|
||||
|
|
@ -189,6 +199,8 @@ class EditorStyle extends ThemeExtension<EditorStyle> {
|
|||
selectionMenuItemSelectedTextColor: const Color.fromARGB(255, 56, 91, 247),
|
||||
selectionMenuItemSelectedIconColor: const Color.fromARGB(255, 56, 91, 247),
|
||||
selectionMenuItemSelectedColor: const Color(0xFFE0F8FF),
|
||||
toolbarColor: const Color(0xFF333333),
|
||||
toolbarElevation: 0.0,
|
||||
textPadding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
textStyle: const TextStyle(fontSize: 16.0, color: Colors.black),
|
||||
placeholderTextStyle: const TextStyle(fontSize: 16.0, color: Colors.grey),
|
||||
|
|
@ -222,5 +234,7 @@ class EditorStyle extends ThemeExtension<EditorStyle> {
|
|||
selectionMenuItemSelectedTextColor: const Color(0xFF131720),
|
||||
selectionMenuItemSelectedIconColor: const Color(0xFF131720),
|
||||
selectionMenuItemSelectedColor: const Color(0xFF00BCF0),
|
||||
toolbarColor: const Color(0xFF131720),
|
||||
toolbarElevation: 0.0,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor/src/infra/flowy_svg.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
Iterable<ThemeExtension<dynamic>> get lightPluginStyleExtension => [
|
||||
|
|
|
|||
|
|
@ -1,13 +1,8 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor/src/extensions/url_launcher_extension.dart';
|
||||
import 'package:appflowy_editor/src/flutter/overlay.dart';
|
||||
import 'package:appflowy_editor/src/infra/clipboard.dart';
|
||||
import 'package:appflowy_editor/src/infra/flowy_svg.dart';
|
||||
import 'package:appflowy_editor/src/render/color_menu/color_picker.dart';
|
||||
import 'package:appflowy_editor/src/render/link_menu/link_menu.dart';
|
||||
import 'package:appflowy_editor/src/extensions/text_node_extensions.dart';
|
||||
import 'package:appflowy_editor/src/extensions/editor_state_extensions.dart';
|
||||
import 'package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ class ToolbarWidget extends StatefulWidget {
|
|||
final EditorState editorState;
|
||||
final LayerLink layerLink;
|
||||
final Offset offset;
|
||||
|
||||
final List<ToolbarItem> items;
|
||||
|
||||
final Alignment alignment;
|
||||
|
||||
@override
|
||||
|
|
@ -56,7 +58,8 @@ class _ToolbarWidgetState extends State<ToolbarWidget> with ToolbarMixin {
|
|||
Widget _buildToolbar(BuildContext context) {
|
||||
return Material(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
color: const Color(0xFF333333),
|
||||
color: widget.editorState.editorStyle.toolbarColor,
|
||||
elevation: widget.editorState.editorStyle.toolbarElevation,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
|
||||
child: SizedBox(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor/src/extensions/text_node_extensions.dart';
|
||||
|
||||
void insertHeadingAfterSelection(EditorState editorState, String heading) {
|
||||
insertTextNodeAfterSelection(editorState, {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ class AppFlowyEditor extends StatefulWidget {
|
|||
this.autoFocus = false,
|
||||
this.focusedSelection,
|
||||
this.customActionMenuBuilder,
|
||||
this.showDefaultToolbar = true,
|
||||
this.shrinkWrap = false,
|
||||
ThemeData? themeData,
|
||||
}) : super(key: key) {
|
||||
|
|
@ -53,7 +54,7 @@ class AppFlowyEditor extends StatefulWidget {
|
|||
|
||||
/// Keyboard event handlers.
|
||||
final List<ShortcutEvent> shortcutEvents;
|
||||
|
||||
final bool showDefaultToolbar;
|
||||
final List<SelectionMenuItem> selectionMenuItems;
|
||||
|
||||
final List<ToolbarItem> toolbarItems;
|
||||
|
|
@ -170,6 +171,7 @@ class _AppFlowyEditorState extends State<AppFlowyEditor> {
|
|||
],
|
||||
editorState: editorState,
|
||||
child: FlowyToolbar(
|
||||
showDefaultToolbar: widget.showDefaultToolbar,
|
||||
key: editorState.service.toolbarServiceKey,
|
||||
editorState: editorState,
|
||||
child:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor/src/infra/clipboard.dart';
|
||||
import 'package:appflowy_editor/src/infra/html_converter.dart';
|
||||
import 'package:appflowy_editor/src/service/internal_key_event_handlers/number_list_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor/src/extensions/text_node_extensions.dart';
|
||||
import 'package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import 'package:flutter/material.dart' hide Overlay, OverlayEntry;
|
|||
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor/src/render/toolbar/toolbar_widget.dart';
|
||||
import 'package:appflowy_editor/src/extensions/object_extensions.dart';
|
||||
|
||||
abstract class AppFlowyToolbarService {
|
||||
/// Show the toolbar widget beside the offset.
|
||||
|
|
@ -25,8 +24,9 @@ class FlowyToolbar extends StatefulWidget {
|
|||
Key? key,
|
||||
required this.editorState,
|
||||
required this.child,
|
||||
required this.showDefaultToolbar,
|
||||
}) : super(key: key);
|
||||
|
||||
final bool showDefaultToolbar;
|
||||
final EditorState editorState;
|
||||
final Widget child;
|
||||
|
||||
|
|
@ -44,7 +44,9 @@ class _FlowyToolbarState extends State<FlowyToolbar>
|
|||
void initState() {
|
||||
super.initState();
|
||||
|
||||
toolbarItems = [...defaultToolbarItems, ...widget.editorState.toolbarItems]
|
||||
toolbarItems = widget.showDefaultToolbar
|
||||
? [...defaultToolbarItems, ...widget.editorState.toolbarItems]
|
||||
: [...widget.editorState.toolbarItems]
|
||||
..sort((a, b) => a.type.compareTo(b.type));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../infra/test_editor.dart';
|
||||
|
||||
void main() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../infra/test_editor.dart';
|
||||
|
||||
void main() {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import 'dart:collection';
|
|||
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import '../infra/test_editor.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import '../infra/test_editor.dart';
|
||||
|
||||
class MockNode extends Mock implements Node {}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import 'package:appflowy_editor/src/infra/flowy_svg.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../test_helper.dart';
|
||||
|
||||
void main() {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,14 @@ void main() {
|
|||
expect(html.isNotEmpty, true);
|
||||
});
|
||||
});
|
||||
group('HTMLConverterDocument tests', () {
|
||||
test('HTMLToNodesConverter', () {
|
||||
final converter = HTMLToNodesConverter(rawHTML);
|
||||
final document = converter.toDocument();
|
||||
|
||||
expect(document.root.children.isNotEmpty, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const rawHTML = """<h1>AppFlowyEditor</h1>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor/src/infra/flowy_svg.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../../test_helper.dart';
|
||||
|
||||
void main() {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue