diff --git a/frontend/appflowy_flutter/assets/images/editor/add.svg b/frontend/appflowy_flutter/assets/images/editor/add.svg
index c1f9ce4e07..697d992062 100644
--- a/frontend/appflowy_flutter/assets/images/editor/add.svg
+++ b/frontend/appflowy_flutter/assets/images/editor/add.svg
@@ -1,4 +1 @@
-
+
\ No newline at end of file
diff --git a/frontend/appflowy_flutter/assets/images/editor/option.svg b/frontend/appflowy_flutter/assets/images/editor/option.svg
index ced0febe62..25e2c334ea 100644
--- a/frontend/appflowy_flutter/assets/images/editor/option.svg
+++ b/frontend/appflowy_flutter/assets/images/editor/option.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/frontend/appflowy_flutter/assets/translations/en.json b/frontend/appflowy_flutter/assets/translations/en.json
index c8b5f74215..2f7b2f1cf0 100644
--- a/frontend/appflowy_flutter/assets/translations/en.json
+++ b/frontend/appflowy_flutter/assets/translations/en.json
@@ -395,6 +395,10 @@
"mathEquation": {
"addMathEquation": "Add Math Equation",
"editMathEquation": "Edit Math Equation"
+ },
+ "optionAction": {
+ "click": "Click",
+ "toOpenMenu": " to open menu"
}
}
},
diff --git a/frontend/appflowy_flutter/lib/plugins/document/document_page.dart b/frontend/appflowy_flutter/lib/plugins/document/document_page.dart
index 875667056b..ddcfc5c0c3 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/document_page.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/document_page.dart
@@ -89,11 +89,11 @@ class _DocumentPageState extends State {
Widget _buildEditorPage(BuildContext context, DocumentState state) {
final appflowyEditorPage = AppFlowyEditorPage(
editorState: editorState!,
+ header: _buildCoverAndIcon(context),
);
return Column(
children: [
if (state.isDeleted) _buildBanner(context),
- _buildCoverAndIcon(context),
Expanded(
child: appflowyEditorPage,
),
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart
index be86968ced..a1487c39a2 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart
@@ -1,6 +1,6 @@
import 'package:appflowy/plugins/document/application/doc_bloc.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/option_action.dart';
-import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/option_action_button.dart';
+import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/block_action_list.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
import 'package:appflowy/plugins/document/presentation/editor_style.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
@@ -13,9 +13,11 @@ class AppFlowyEditorPage extends StatefulWidget {
const AppFlowyEditorPage({
super.key,
required this.editorState,
+ this.header,
});
final EditorState editorState;
+ final Widget? header;
@override
State createState() => _AppFlowyEditorPageState();
@@ -41,16 +43,12 @@ class _AppFlowyEditorPageState extends State {
final List toolbarItems = [
smartEditItem,
- placeholderItem,
paragraphItem,
...headingItems,
- placeholderItem,
...markdownFormatItems,
- placeholderItem,
quoteItem,
bulletedListItem,
numberedListItem,
- placeholderItem,
linkItem,
textColorItem,
highlightColorItem,
@@ -70,8 +68,15 @@ class _AppFlowyEditorPageState extends State {
(element) => element == slashCommand,
), // remove the default slash command.
customSlashCommand(slashMenuItems),
+
+ // formatGreaterToToggleList,
];
+ late final showSlashMenu = customSlashCommand(
+ slashMenuItems,
+ shouldInsertSlash: false,
+ ).handler;
+
late final styleCustomizer = EditorStyleCustomizer(context: context);
DocumentBloc get documentBloc => context.read();
@@ -92,6 +97,7 @@ class _AppFlowyEditorPageState extends State {
// customize the shortcuts
characterShortcutEvents: characterShortcutEvents,
commandShortcutEvents: commandShortcutEvents,
+ header: widget.header,
);
return Center(
@@ -183,6 +189,7 @@ class _AppFlowyEditorPageState extends State {
),
AutoCompletionBlockKeys.type: AutoCompletionBlockComponentBuilder(),
SmartEditBlockKeys.type: SmartEditBlockComponentBuilder(),
+ // ToggleListBlockKeys.type: ToggleListBlockComponentBuilder(),
};
final builders = {
@@ -207,24 +214,25 @@ class _AppFlowyEditorPageState extends State {
TodoListBlockKeys.type,
CalloutBlockKeys.type
];
- if (!supportColorBuilderTypes.contains(entry.key)) {
- builder.actionBuilder = (context, state) => OptionActionList(
- blockComponentContext: context,
- blockComponentState: state,
- editorState: widget.editorState,
- actions: standardActions,
- );
- continue;
- }
+
final colorAction = [
OptionAction.divider,
OptionAction.color,
];
- builder.actionBuilder = (context, state) => OptionActionList(
+
+ final List actions = [
+ ...standardActions,
+ if (supportColorBuilderTypes.contains(entry.key)) ...colorAction,
+ ];
+
+ builder.actionBuilder = (context, state) => BlockActionList(
blockComponentContext: context,
blockComponentState: state,
editorState: widget.editorState,
- actions: standardActions + colorAction,
+ actions: actions,
+ showSlashMenu: () => showSlashMenu(
+ widget.editorState,
+ ),
);
}
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_add_button.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_add_button.dart
new file mode 100644
index 0000000000..017a1adbb4
--- /dev/null
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_add_button.dart
@@ -0,0 +1,52 @@
+import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/block_action_button.dart';
+import 'package:appflowy_editor/appflowy_editor.dart';
+import 'package:flutter/material.dart';
+
+class BlockAddButton extends StatelessWidget {
+ const BlockAddButton({
+ Key? key,
+ required this.blockComponentContext,
+ required this.blockComponentState,
+ required this.editorState,
+ required this.showSlashMenu,
+ }) : super(key: key);
+
+ final BlockComponentContext blockComponentContext;
+ final BlockComponentState blockComponentState;
+
+ final EditorState editorState;
+ final VoidCallback showSlashMenu;
+
+ @override
+ Widget build(BuildContext context) {
+ return BlockActionButton(
+ svgName: 'editor/add',
+ richMessage: const TextSpan(
+ children: [
+ TextSpan(
+ // todo: l10n.
+ text: 'Click to add below',
+ ),
+ ],
+ ),
+ onTap: () {
+ final transaction = editorState.transaction;
+ // if the current block is not a empty paragraph block, then insert a new block below the current block.
+ final node = blockComponentContext.node;
+ if (node.type != ParagraphBlockKeys.type ||
+ (node.delta?.isNotEmpty ?? true)) {
+ transaction.insertNode(node.path.next, paragraphNode());
+ transaction.afterSelection = Selection.collapse(node.path.next, 0);
+ } else {
+ transaction.afterSelection = Selection.collapse(node.path, 0);
+ }
+ // show the slash menu.
+ editorState.apply(transaction).then(
+ (_) => WidgetsBinding.instance.addPostFrameCallback(
+ (_) => showSlashMenu(),
+ ),
+ );
+ },
+ );
+ }
+}
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_button.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_button.dart
new file mode 100644
index 0000000000..a3ad6b8cee
--- /dev/null
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_button.dart
@@ -0,0 +1,41 @@
+import 'package:flowy_infra/image.dart';
+import 'package:flowy_infra_ui/widget/ignore_parent_gesture.dart';
+import 'package:flutter/material.dart';
+
+class BlockActionButton extends StatelessWidget {
+ const BlockActionButton({
+ super.key,
+ required this.svgName,
+ required this.richMessage,
+ required this.onTap,
+ });
+
+ final String svgName;
+ final InlineSpan richMessage;
+ final VoidCallback onTap;
+
+ @override
+ Widget build(BuildContext context) {
+ return Align(
+ alignment: Alignment.center,
+ child: Tooltip(
+ preferBelow: false,
+ richMessage: richMessage,
+ child: MouseRegion(
+ cursor: SystemMouseCursors.grab,
+ child: IgnoreParentGestureWidget(
+ child: GestureDetector(
+ onTap: onTap,
+ behavior: HitTestBehavior.deferToChild,
+ child: svgWidget(
+ svgName,
+ size: const Size.square(14.0),
+ color: Theme.of(context).iconTheme.color,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_list.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_list.dart
new file mode 100644
index 0000000000..445e6f02b6
--- /dev/null
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_list.dart
@@ -0,0 +1,45 @@
+import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/block_action_add_button.dart';
+import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/block_action_option_button.dart';
+import 'package:flutter/material.dart';
+import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/option_action.dart';
+import 'package:appflowy_editor/appflowy_editor.dart';
+
+class BlockActionList extends StatelessWidget {
+ const BlockActionList({
+ super.key,
+ required this.blockComponentContext,
+ required this.blockComponentState,
+ required this.editorState,
+ required this.actions,
+ required this.showSlashMenu,
+ });
+
+ final BlockComponentContext blockComponentContext;
+ final BlockComponentState blockComponentState;
+ final List actions;
+ final VoidCallback showSlashMenu;
+ final EditorState editorState;
+
+ @override
+ Widget build(BuildContext context) {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ BlockAddButton(
+ blockComponentContext: blockComponentContext,
+ blockComponentState: blockComponentState,
+ editorState: editorState,
+ showSlashMenu: showSlashMenu,
+ ),
+ const SizedBox(width: 8.0),
+ BlockOptionButton(
+ blockComponentContext: blockComponentContext,
+ blockComponentState: blockComponentState,
+ actions: actions,
+ editorState: editorState,
+ ),
+ const SizedBox(width: 6.0),
+ ],
+ );
+ }
+}
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_option_button.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_option_button.dart
new file mode 100644
index 0000000000..4b49a19220
--- /dev/null
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_option_button.dart
@@ -0,0 +1,131 @@
+import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/block_action_button.dart';
+import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/option_action.dart';
+import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
+import 'package:appflowy_editor/appflowy_editor.dart';
+import 'package:appflowy_popover/appflowy_popover.dart';
+import 'package:flutter/material.dart';
+import 'package:appflowy/generated/locale_keys.g.dart';
+import 'package:easy_localization/easy_localization.dart';
+
+class BlockOptionButton extends StatelessWidget {
+ const BlockOptionButton({
+ Key? key,
+ required this.blockComponentContext,
+ required this.blockComponentState,
+ required this.actions,
+ required this.editorState,
+ }) : super(key: key);
+
+ final BlockComponentContext blockComponentContext;
+ final BlockComponentState blockComponentState;
+ final List actions;
+ final EditorState editorState;
+
+ @override
+ Widget build(BuildContext context) {
+ final popoverActions = actions.map((e) {
+ if (e == OptionAction.divider) {
+ return DividerOptionAction();
+ } else if (e == OptionAction.color) {
+ return ColorOptionAction(
+ editorState: editorState,
+ );
+ } else {
+ return OptionActionWrapper(e);
+ }
+ }).toList();
+
+ return PopoverActionList(
+ direction: PopoverDirection.leftWithCenterAligned,
+ actions: popoverActions,
+ onPopupBuilder: () => blockComponentState.alwaysShowActions = true,
+ onClosed: () {
+ editorState.selectionType = null;
+ editorState.selection = null;
+ blockComponentState.alwaysShowActions = false;
+ },
+ onSelected: (action, controller) {
+ if (action is OptionActionWrapper) {
+ _onSelectAction(action.inner);
+ controller.close();
+ }
+ },
+ buildChild: (controller) => _buildOptionButton(controller),
+ );
+ }
+
+ Widget _buildOptionButton(PopoverController controller) {
+ return BlockActionButton(
+ svgName: 'editor/option',
+ richMessage: TextSpan(
+ children: [
+ TextSpan(
+ // todo: customize the color to highlight the text.
+ text: LocaleKeys.document_plugins_optionAction_click.tr(),
+ ),
+ TextSpan(
+ text: LocaleKeys.document_plugins_optionAction_toOpenMenu.tr(),
+ )
+ ],
+ ),
+ onTap: () {
+ controller.show();
+
+ // update selection
+ _updateBlockSelection();
+ },
+ );
+ }
+
+ void _updateBlockSelection() {
+ final startNode = blockComponentContext.node;
+ var endNode = startNode;
+ while (endNode.children.isNotEmpty) {
+ endNode = endNode.children.last;
+ }
+
+ final start = Position(path: startNode.path, offset: 0);
+ final end = endNode.selectable?.end() ??
+ Position(
+ path: endNode.path,
+ offset: endNode.delta?.length ?? 0,
+ );
+
+ editorState.selectionType = SelectionType.block;
+ editorState.selection = Selection(
+ start: start,
+ end: end,
+ );
+ }
+
+ void _onSelectAction(OptionAction action) {
+ final node = blockComponentContext.node;
+ final transaction = editorState.transaction;
+ switch (action) {
+ case OptionAction.delete:
+ transaction.deleteNode(node);
+ break;
+ case OptionAction.duplicate:
+ transaction.insertNode(
+ node.path.next,
+ node.copyWith(),
+ );
+ break;
+ case OptionAction.turnInto:
+ break;
+ case OptionAction.moveUp:
+ transaction.moveNode(node.path.previous, node);
+ break;
+ case OptionAction.moveDown:
+ transaction.moveNode(node.path.next.next, node);
+ break;
+ case OptionAction.color:
+ // show the color picker
+
+ break;
+ case OptionAction.divider:
+ throw UnimplementedError();
+ }
+ editorState.apply(transaction);
+ }
+}
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/code_block/code_block_component.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/code_block/code_block_component.dart
index 40b6b5c717..094626fad1 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/code_block/code_block_component.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/code_block/code_block_component.dart
@@ -206,6 +206,7 @@ class _CodeBlockComponentWidgetState extends State
node: widget.node,
editorState: editorState,
placeholderText: placeholderText,
+ lineHeight: 1.5,
textSpanDecorator: (textSpan) => TextSpan(
style: textStyle,
children: codeTextSpans,
@@ -218,10 +219,12 @@ class _CodeBlockComponentWidgetState extends State
}
Widget _buildSwitchLanguageButton(BuildContext context) {
+ const maxWidth = 100.0;
return AppFlowyPopover(
controller: popoverController,
child: Container(
- width: 100,
+ width: maxWidth,
+ alignment: Alignment.centerLeft,
padding: const EdgeInsets.symmetric(horizontal: 4),
child: FlowyTextButton(
'${language?.capitalize() ?? 'auto'} ',
@@ -229,8 +232,10 @@ class _CodeBlockComponentWidgetState extends State
horizontal: 12.0,
vertical: 4.0,
),
+ constraints: const BoxConstraints(maxWidth: maxWidth),
fontColor: Theme.of(context).colorScheme.onBackground,
fillColor: Colors.transparent,
+ mainAxisAlignment: MainAxisAlignment.start,
onPressed: () {},
),
),
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/widgets/smart_edit_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/widgets/smart_edit_toolbar_item.dart
index 57109dec8b..2ba502859b 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/widgets/smart_edit_toolbar_item.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/widgets/smart_edit_toolbar_item.dart
@@ -12,6 +12,7 @@ import 'package:easy_localization/easy_localization.dart';
final ToolbarItem smartEditItem = ToolbarItem(
id: 'appflowy.editor.smart_edit',
+ group: 0,
isActive: (editorState) {
final selection = editorState.selection;
if (selection == null) {
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/plugins.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/plugins.dart
index 5f07b66ae9..387eeed81b 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/plugins.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/plugins.dart
@@ -18,3 +18,5 @@ export 'math_equation/math_equation_block_component.dart';
export 'openai/widgets/auto_completion_node_widget.dart';
export 'openai/widgets/smart_edit_node_widget.dart';
export 'openai/widgets/smart_edit_toolbar_item.dart';
+export 'toggle/toggle_block_component.dart';
+export 'toggle/toggle_block_shortcut_event.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/toggle/toggle_block_component.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/toggle/toggle_block_component.dart
new file mode 100644
index 0000000000..454ac94d2a
--- /dev/null
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/toggle/toggle_block_component.dart
@@ -0,0 +1,165 @@
+import 'package:appflowy_editor/appflowy_editor.dart';
+import 'package:flowy_infra_ui/flowy_infra_ui.dart';
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+
+class ToggleListBlockKeys {
+ const ToggleListBlockKeys._();
+
+ static const String type = 'toggle_list';
+
+ /// The content of a code block.
+ ///
+ /// The value is a String.
+ static const String delta = 'delta';
+
+ /// The value is a bool.
+ static const String collapsed = 'collapsed';
+}
+
+Node toggleListBlockNode({
+ Delta? delta,
+ bool collapsed = false,
+}) {
+ final attributes = {
+ ToggleListBlockKeys.delta: (delta ?? Delta()).toJson(),
+ ToggleListBlockKeys.collapsed: collapsed,
+ };
+ return Node(
+ type: ToggleListBlockKeys.type,
+ attributes: attributes,
+ children: [paragraphNode()],
+ );
+}
+
+class ToggleListBlockComponentBuilder extends BlockComponentBuilder {
+ ToggleListBlockComponentBuilder({
+ this.configuration = const BlockComponentConfiguration(),
+ this.padding = const EdgeInsets.all(0),
+ });
+
+ @override
+ final BlockComponentConfiguration configuration;
+
+ final EdgeInsets padding;
+
+ @override
+ Widget build(BlockComponentContext blockComponentContext) {
+ final node = blockComponentContext.node;
+ return ToggleListBlockComponentWidget(
+ key: node.key,
+ node: node,
+ configuration: configuration,
+ padding: padding,
+ );
+ }
+
+ @override
+ bool validate(Node node) => node.delta != null;
+}
+
+class ToggleListBlockComponentWidget extends StatefulWidget {
+ const ToggleListBlockComponentWidget({
+ Key? key,
+ required this.node,
+ this.configuration = const BlockComponentConfiguration(),
+ this.padding = const EdgeInsets.all(0),
+ }) : super(key: key);
+
+ final Node node;
+ final BlockComponentConfiguration configuration;
+ final EdgeInsets padding;
+
+ @override
+ State createState() =>
+ _ToggleListBlockComponentWidgetState();
+}
+
+class _ToggleListBlockComponentWidgetState
+ extends State
+ with
+ SelectableMixin,
+ DefaultSelectable,
+ BlockComponentConfigurable,
+ BackgroundColorMixin {
+ // the key used to forward focus to the richtext child
+ @override
+ final forwardKey = GlobalKey(debugLabel: 'flowy_rich_text');
+
+ @override
+ BlockComponentConfiguration get configuration => widget.configuration;
+
+ @override
+ GlobalKey> get containerKey => node.key;
+
+ @override
+ Node get node => widget.node;
+
+ bool get collapsed => node.attributes[ToggleListBlockKeys.collapsed] ?? false;
+
+ late final editorState = context.read();
+
+ @override
+ Widget build(BuildContext context) {
+ return collapsed
+ ? buildToggleListBlockComponent(context)
+ : buildToggleListBlockComponentWithChildren(context);
+ }
+
+ Widget buildToggleListBlockComponentWithChildren(BuildContext context) {
+ return Container(
+ color: backgroundColor,
+ child: NestedListWidget(
+ children: editorState.renderer.buildList(
+ context,
+ widget.node.children,
+ ),
+ child: buildToggleListBlockComponent(context),
+ ),
+ );
+ }
+
+ // build the richtext child
+ Widget buildToggleListBlockComponent(BuildContext context) {
+ return Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ // the emoji picker button for the note
+ FlowyIconButton(
+ width: 24.0,
+ icon: Icon(
+ collapsed ? Icons.arrow_right : Icons.arrow_drop_down,
+ ),
+ onPressed: onCollapsed,
+ ),
+ const SizedBox(
+ width: 4.0,
+ ),
+ Expanded(
+ child: FlowyRichText(
+ key: forwardKey,
+ node: widget.node,
+ editorState: editorState,
+ placeholderText: placeholderText,
+ lineHeight: 1.5,
+ textSpanDecorator: (textSpan) => textSpan.updateTextStyle(
+ textStyle,
+ ),
+ placeholderTextSpanDecorator: (textSpan) =>
+ textSpan.updateTextStyle(
+ placeholderTextStyle,
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ Future onCollapsed() async {
+ final transaction = editorState.transaction
+ ..updateNode(node, {
+ ToggleListBlockKeys.collapsed: !collapsed,
+ });
+ await editorState.apply(transaction);
+ }
+}
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/toggle/toggle_block_shortcut_event.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/toggle/toggle_block_shortcut_event.dart
new file mode 100644
index 0000000000..aa2674de21
--- /dev/null
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/toggle/toggle_block_shortcut_event.dart
@@ -0,0 +1,24 @@
+import 'package:appflowy/plugins/document/presentation/editor_plugins/toggle/toggle_block_component.dart';
+import 'package:appflowy_editor/appflowy_editor.dart';
+
+const _greater = '>';
+
+/// Convert '> ' to toggle list
+///
+/// - support
+/// - desktop
+/// - mobile
+/// - web
+///
+CharacterShortcutEvent formatGreaterToToggleList = CharacterShortcutEvent(
+ key: 'format greater to quote',
+ character: ' ',
+ handler: (editorState) async => await formatMarkdownSymbol(
+ editorState,
+ (node) => node.type != ToggleListBlockKeys.type,
+ (text, _) => text == _greater,
+ (_, node, delta) => toggleListBlockNode(
+ delta: delta.compose(Delta()..delete(_greater.length)),
+ ),
+ ),
+);
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart
index 1e76abe237..a50c5eb8b9 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart
@@ -28,7 +28,10 @@ class EditorStyleCustomizer {
final theme = Theme.of(context);
final fontSize = context.read().state.fontSize;
return EditorStyle.desktop(
- padding: EdgeInsets.symmetric(horizontal: horizontalPadding),
+ padding: EdgeInsets.only(
+ left: horizontalPadding / 2.0,
+ right: horizontalPadding,
+ ),
backgroundColor: theme.colorScheme.surface,
cursorColor: theme.colorScheme.primary,
textStyleConfiguration: TextStyleConfiguration(
@@ -115,11 +118,13 @@ class EditorStyleCustomizer {
}
TextStyle codeBlockStyleBuilder() {
+ final theme = Theme.of(context);
final fontSize = context.read().state.fontSize;
return TextStyle(
fontFamily: 'poppins',
fontSize: fontSize,
height: 1.5,
+ color: theme.colorScheme.onBackground,
);
}
}
diff --git a/frontend/appflowy_flutter/pubspec.lock b/frontend/appflowy_flutter/pubspec.lock
index 6eef9a4b4b..08056a30f8 100644
--- a/frontend/appflowy_flutter/pubspec.lock
+++ b/frontend/appflowy_flutter/pubspec.lock
@@ -45,8 +45,8 @@ packages:
dependency: "direct main"
description:
path: "."
- ref: "4f66f7"
- resolved-ref: "4f66f77debabbc35cf4a56c816f9432a831a40e2"
+ ref: b1a1b14
+ resolved-ref: b1a1b14f35114a7becdb3e2de909d546d7328a59
url: "https://github.com/LucasXu0/appflowy-editor.git"
source: git
version: "0.1.12"
diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml
index 2e80eed867..48bb645aa2 100644
--- a/frontend/appflowy_flutter/pubspec.yaml
+++ b/frontend/appflowy_flutter/pubspec.yaml
@@ -47,7 +47,7 @@ dependencies:
# path: /Users/lucas.xu/Desktop/appflowy-editor
git:
url: https://github.com/LucasXu0/appflowy-editor.git
- ref: 4f66f7
+ ref: b1a1b14
appflowy_popover:
path: packages/appflowy_popover