Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support customizing the block icon #274

Merged
merged 1 commit into from
Jul 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';

typedef BlockIconBuilder = Widget Function(BuildContext context, Node node);
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/editor/block_component/base_component/block_icon_builder.dart';
import 'package:flutter/material.dart';

class BulletedListBlockKeys {
Expand All @@ -25,18 +26,22 @@ Node bulletedListNode({
class BulletedListBlockComponentBuilder extends BlockComponentBuilder {
BulletedListBlockComponentBuilder({
this.configuration = const BlockComponentConfiguration(),
this.iconBuilder,
});

@override
final BlockComponentConfiguration configuration;

final BlockIconBuilder? iconBuilder;

@override
BlockComponentWidget build(BlockComponentContext blockComponentContext) {
final node = blockComponentContext.node;
return BulletedListBlockComponentWidget(
key: node.key,
node: node,
configuration: configuration,
iconBuilder: iconBuilder,
showActions: showActions(node),
actionBuilder: (context, state) => actionBuilder(
blockComponentContext,
Expand All @@ -56,8 +61,11 @@ class BulletedListBlockComponentWidget extends BlockComponentStatefulWidget {
super.showActions,
super.actionBuilder,
super.configuration = const BlockComponentConfiguration(),
this.iconBuilder,
});

final BlockIconBuilder? iconBuilder;

@override
State<BulletedListBlockComponentWidget> createState() =>
_BulletedListBlockComponentWidgetState();
Expand Down Expand Up @@ -92,10 +100,12 @@ class _BulletedListBlockComponentWidgetState
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
_BulletedListIcon(
node: widget.node,
textStyle: textStyle,
),
widget.iconBuilder != null
? widget.iconBuilder!(context, node)
: _BulletedListIcon(
node: widget.node,
textStyle: textStyle,
),
Flexible(
child: FlowyRichText(
key: forwardKey,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/editor/block_component/base_component/block_icon_builder.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class NumberedListBlockKeys {
const NumberedListBlockKeys._();
Expand Down Expand Up @@ -31,18 +33,22 @@ Node numberedListNode({
class NumberedListBlockComponentBuilder extends BlockComponentBuilder {
NumberedListBlockComponentBuilder({
this.configuration = const BlockComponentConfiguration(),
this.iconBuilder,
});

@override
final BlockComponentConfiguration configuration;

final BlockIconBuilder? iconBuilder;

@override
BlockComponentWidget build(BlockComponentContext blockComponentContext) {
final node = blockComponentContext.node;
return NumberedListBlockComponentWidget(
key: node.key,
node: node,
configuration: configuration,
iconBuilder: iconBuilder,
showActions: showActions(node),
actionBuilder: (context, state) => actionBuilder(
blockComponentContext,
Expand All @@ -62,8 +68,11 @@ class NumberedListBlockComponentWidget extends BlockComponentStatefulWidget {
super.showActions,
super.actionBuilder,
super.configuration = const BlockComponentConfiguration(),
this.iconBuilder,
});

final BlockIconBuilder? iconBuilder;

@override
State<NumberedListBlockComponentWidget> createState() =>
_NumberedListBlockComponentWidgetState();
Expand Down Expand Up @@ -98,7 +107,12 @@ class _NumberedListBlockComponentWidgetState
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
defaultIcon(),
widget.iconBuilder != null
? widget.iconBuilder!(context, node)
: _NumberedListIcon(
node: node,
textStyle: textStyle,
),
Flexible(
child: FlowyRichText(
key: forwardKey,
Expand Down Expand Up @@ -128,10 +142,22 @@ class _NumberedListBlockComponentWidgetState

return child;
}
}

Widget defaultIcon() {
class _NumberedListIcon extends StatelessWidget {
const _NumberedListIcon({
required this.node,
required this.textStyle,
});

final Node node;
final TextStyle textStyle;

@override
Widget build(BuildContext context) {
final editorState = context.read<EditorState>();
final text = editorState.editorStyle.textStyleConfiguration.text;
final level = _NumberedListIconBuilder(node: widget.node).level;
final level = _NumberedListIconBuilder(node: node).level;
return Padding(
padding: const EdgeInsets.only(right: 5.0),
child: Text.rich(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/editor/block_component/base_component/block_icon_builder.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

Expand Down Expand Up @@ -26,18 +27,22 @@ Node quoteNode({
class QuoteBlockComponentBuilder extends BlockComponentBuilder {
QuoteBlockComponentBuilder({
this.configuration = const BlockComponentConfiguration(),
this.iconBuilder,
});

@override
final BlockComponentConfiguration configuration;

final BlockIconBuilder? iconBuilder;

@override
BlockComponentWidget build(BlockComponentContext blockComponentContext) {
final node = blockComponentContext.node;
return QuoteBlockComponentWidget(
key: node.key,
node: node,
configuration: configuration,
iconBuilder: iconBuilder,
showActions: showActions(node),
actionBuilder: (context, state) => actionBuilder(
blockComponentContext,
Expand All @@ -57,8 +62,11 @@ class QuoteBlockComponentWidget extends BlockComponentStatefulWidget {
super.showActions,
super.actionBuilder,
super.configuration = const BlockComponentConfiguration(),
this.iconBuilder,
});

final BlockIconBuilder? iconBuilder;

@override
State<QuoteBlockComponentWidget> createState() =>
_QuoteBlockComponentWidgetState();
Expand Down Expand Up @@ -94,7 +102,9 @@ class _QuoteBlockComponentWidgetState extends State<QuoteBlockComponentWidget>
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
defaultIcon(),
widget.iconBuilder != null
? widget.iconBuilder!(context, node)
: const _QuoteIcon(),
Flexible(
child: FlowyRichText(
key: forwardKey,
Expand Down Expand Up @@ -125,9 +135,13 @@ class _QuoteBlockComponentWidgetState extends State<QuoteBlockComponentWidget>

return child;
}
}

// TODO: support custom icon.
Widget defaultIcon() {
class _QuoteIcon extends StatelessWidget {
const _QuoteIcon();

@override
Widget build(BuildContext context) {
return const FlowySvg(
width: 20,
height: 20,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/editor/block_component/base_component/block_icon_builder.dart';
import 'package:flutter/material.dart';

class TodoListBlockKeys {
Expand Down Expand Up @@ -33,7 +34,7 @@ class TodoListBlockComponentBuilder extends BlockComponentBuilder {
TodoListBlockComponentBuilder({
this.configuration = const BlockComponentConfiguration(),
this.textStyleBuilder,
this.icon,
this.iconBuilder,
});

@override
Expand All @@ -42,8 +43,7 @@ class TodoListBlockComponentBuilder extends BlockComponentBuilder {
/// The text style of the todo list block.
final TextStyle Function(bool checked)? textStyleBuilder;

/// The icon of the todo list block.
final Widget? Function(bool checked)? icon;
final BlockIconBuilder? iconBuilder;

@override
BlockComponentWidget build(BlockComponentContext blockComponentContext) {
Expand All @@ -53,7 +53,7 @@ class TodoListBlockComponentBuilder extends BlockComponentBuilder {
node: node,
configuration: configuration,
textStyleBuilder: textStyleBuilder,
icon: icon,
iconBuilder: iconBuilder,
showActions: showActions(node),
actionBuilder: (context, state) => actionBuilder(
blockComponentContext,
Expand All @@ -77,11 +77,11 @@ class TodoListBlockComponentWidget extends BlockComponentStatefulWidget {
super.actionBuilder,
super.configuration = const BlockComponentConfiguration(),
this.textStyleBuilder,
this.icon,
this.iconBuilder,
});

final TextStyle Function(bool checked)? textStyleBuilder;
final Widget? Function(bool checked)? icon;
final BlockIconBuilder? iconBuilder;

@override
State<TodoListBlockComponentWidget> createState() =>
Expand Down Expand Up @@ -119,10 +119,12 @@ class _TodoListBlockComponentWidgetState
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
_TodoListIcon(
icon: widget.icon?.call(checked) ?? defaultCheckboxIcon(),
onTap: checkOrUncheck,
),
widget.iconBuilder != null
? widget.iconBuilder!(context, node)
: _TodoListIcon(
checked: checked,
onTap: checkOrUncheck,
),
Flexible(
child: FlowyRichText(
key: forwardKey,
Expand Down Expand Up @@ -163,15 +165,6 @@ class _TodoListBlockComponentWidgetState
return editorState.apply(transaction);
}

FlowySvg defaultCheckboxIcon() {
return FlowySvg(
width: 22,
height: 22,
padding: const EdgeInsets.only(right: 5.0),
name: checked ? 'check' : 'uncheck',
);
}

TextStyle? defaultTextStyle() {
if (!checked) {
return null;
Expand All @@ -185,12 +178,12 @@ class _TodoListBlockComponentWidgetState

class _TodoListIcon extends StatelessWidget {
const _TodoListIcon({
required this.icon,
required this.onTap,
required this.checked,
});

final Widget icon;
final VoidCallback onTap;
final bool checked;

@override
Widget build(BuildContext context) {
Expand All @@ -199,7 +192,12 @@ class _TodoListIcon extends StatelessWidget {
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: onTap,
child: icon,
child: FlowySvg(
width: 22,
height: 22,
padding: const EdgeInsets.only(right: 5.0),
name: checked ? 'check' : 'uncheck',
),
),
);
}
Expand Down
4 changes: 3 additions & 1 deletion lib/src/editor/toolbar/desktop/items/icon_item_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class IconItemWidget extends StatelessWidget {
this.iconSize = const Size.square(18.0),
required this.iconName,
required this.isHighlight,
this.highlightColor = Colors.lightBlue,
this.tooltip,
this.onPressed,
});
Expand All @@ -16,14 +17,15 @@ class IconItemWidget extends StatelessWidget {
final Size iconSize;
final String iconName;
final bool isHighlight;
final Color highlightColor;
final String? tooltip;
final VoidCallback? onPressed;

@override
Widget build(BuildContext context) {
Widget child = FlowySvg(
name: iconName,
color: isHighlight ? Colors.lightBlue : null,
color: isHighlight ? highlightColor : null,
width: iconSize.width,
height: iconSize.height,
);
Expand Down
Loading