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 mobile page style #769

Merged
merged 3 commits into from
Apr 16, 2024
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
2 changes: 1 addition & 1 deletion example/lib/pages/customize_theme_for_editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class _CustomizeThemeForEditorState extends State<CustomizeThemeForEditor> {
// todo-list block
TodoListBlockKeys.type: TodoListBlockComponentBuilder(
configuration: configuration,
iconBuilder: (context, node) {
iconBuilder: (context, node, ___) {
final checked = node.attributes[TodoListBlockKeys.checked] as bool;
return GestureDetector(
onTap: () => editorState.apply(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class TextStyleConfiguration {
this.autoComplete = const TextStyle(
color: Colors.grey,
),
this.applyHeightToFirstAscent = false,
this.applyHeightToLastDescent = false,
});

/// default text style
Expand All @@ -49,6 +51,10 @@ class TextStyleConfiguration {
/// auto complete text style
final TextStyle autoComplete;

/// apply line height to the first or the last ascent
final bool applyHeightToFirstAscent;
final bool applyHeightToLastDescent;

TextStyleConfiguration copyWith({
TextStyle? text,
TextStyle? bold,
Expand All @@ -58,6 +64,8 @@ class TextStyleConfiguration {
TextStyle? href,
TextStyle? code,
TextStyle? autoComplete,
bool? applyHeightToFirstAscent,
bool? applyHeightToLastDescent,
}) {
return TextStyleConfiguration(
text: text ?? this.text,
Expand All @@ -68,6 +76,10 @@ class TextStyleConfiguration {
href: href ?? this.href,
code: code ?? this.code,
autoComplete: autoComplete ?? this.autoComplete,
applyHeightToFirstAscent:
applyHeightToFirstAscent ?? this.applyHeightToFirstAscent,
applyHeightToLastDescent:
applyHeightToLastDescent ?? this.applyHeightToLastDescent,
);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
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:numerus/roman/roman.dart';
import 'package:provider/provider.dart';
Expand Down Expand Up @@ -40,13 +39,19 @@ Node numberedListNode({
);
}

typedef NumberedListIconBuilder = Widget Function(
BuildContext context,
Node node,
TextDirection direction,
);

class NumberedListBlockComponentBuilder extends BlockComponentBuilder {
NumberedListBlockComponentBuilder({
super.configuration,
this.iconBuilder,
});

final BlockIconBuilder? iconBuilder;
final NumberedListIconBuilder? iconBuilder;

@override
BlockComponentWidget build(BlockComponentContext blockComponentContext) {
Expand Down Expand Up @@ -78,7 +83,7 @@ class NumberedListBlockComponentWidget extends BlockComponentStatefulWidget {
this.iconBuilder,
});

final BlockIconBuilder? iconBuilder;
final NumberedListIconBuilder? iconBuilder;

@override
State<NumberedListBlockComponentWidget> createState() =>
Expand Down Expand Up @@ -131,7 +136,11 @@ class _NumberedListBlockComponentWidgetState
textDirection: textDirection,
children: [
widget.iconBuilder != null
? widget.iconBuilder!(context, node)
? widget.iconBuilder!(
context,
node,
textDirection,
)
: _NumberedListIcon(
node: node,
textStyle: textStyle,
Expand Down
63 changes: 31 additions & 32 deletions lib/src/editor/block_component/rich_text/appflowy_rich_text.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
import 'dart:math';
import 'dart:ui';

import 'package:appflowy_editor/src/core/document/attributes.dart';
import 'package:appflowy_editor/src/core/document/node.dart';
import 'package:appflowy_editor/src/core/document/path.dart';
import 'package:appflowy_editor/src/core/document/text_delta.dart';
import 'package:appflowy_editor/src/core/location/position.dart';
import 'package:appflowy_editor/src/core/location/selection.dart';
import 'package:appflowy_editor/src/editor/block_component/base_component/selection/block_selection_container.dart';
import 'package:appflowy_editor/src/editor/block_component/rich_text/appflowy_rich_text_keys.dart';
import 'package:appflowy_editor/src/editor/util/color_util.dart';
import 'package:appflowy_editor/src/editor_state.dart';
import 'package:appflowy_editor/src/extensions/text_style_extension.dart';
import 'package:appflowy_editor/src/render/selection/selectable.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
Expand Down Expand Up @@ -122,6 +111,9 @@ class _AppFlowyRichTextState extends State<AppFlowyRichText>
bool get enableAutoComplete =>
widget.editorState.enableAutoComplete && autoCompleteTextProvider != null;

TextStyleConfiguration get textStyleConfiguration =>
widget.editorState.editorStyle.textStyleConfiguration;

@override
Widget build(BuildContext context) {
Widget child = _buildRichText(context);
Expand Down Expand Up @@ -328,9 +320,11 @@ class _AppFlowyRichTextState extends State<AppFlowyRichText>
final textSpan = getPlaceholderTextSpan();
return RichText(
key: placeholderTextKey,
textHeightBehavior: const TextHeightBehavior(
applyHeightToFirstAscent: false,
applyHeightToLastDescent: false,
textHeightBehavior: TextHeightBehavior(
applyHeightToFirstAscent:
textStyleConfiguration.applyHeightToFirstAscent,
applyHeightToLastDescent:
textStyleConfiguration.applyHeightToLastDescent,
),
text: widget.placeholderTextSpanDecorator != null
? widget.placeholderTextSpanDecorator!(textSpan)
Expand All @@ -347,9 +341,11 @@ class _AppFlowyRichTextState extends State<AppFlowyRichText>
return RichText(
key: textKey,
textAlign: widget.textAlign ?? TextAlign.start,
textHeightBehavior: const TextHeightBehavior(
applyHeightToFirstAscent: false,
applyHeightToLastDescent: false,
textHeightBehavior: TextHeightBehavior(
applyHeightToFirstAscent:
textStyleConfiguration.applyHeightToFirstAscent,
applyHeightToLastDescent:
textStyleConfiguration.applyHeightToLastDescent,
),
text: widget.textSpanDecorator != null
? widget.textSpanDecorator!(textSpan)
Expand Down Expand Up @@ -394,9 +390,11 @@ class _AppFlowyRichTextState extends State<AppFlowyRichText>
);
return RichText(
textAlign: widget.textAlign ?? TextAlign.start,
textHeightBehavior: const TextHeightBehavior(
applyHeightToFirstAscent: false,
applyHeightToLastDescent: false,
textHeightBehavior: TextHeightBehavior(
applyHeightToFirstAscent:
textStyleConfiguration.applyHeightToFirstAscent,
applyHeightToLastDescent:
textStyleConfiguration.applyHeightToLastDescent,
),
text: widget.textSpanDecorator != null
? widget.textSpanDecorator!(textSpan)
Expand All @@ -410,12 +408,13 @@ class _AppFlowyRichTextState extends State<AppFlowyRichText>
}

TextSpan getPlaceholderTextSpan() {
final style = widget.editorState.editorStyle.textStyleConfiguration;
return TextSpan(
children: [
TextSpan(
text: widget.placeholderText,
style: style.text.copyWith(height: widget.lineHeight),
style: textStyleConfiguration.text.copyWith(
height: widget.lineHeight,
),
),
],
);
Expand All @@ -426,28 +425,28 @@ class _AppFlowyRichTextState extends State<AppFlowyRichText>
}) {
int offset = 0;
List<InlineSpan> textSpans = [];
final style = widget.editorState.editorStyle.textStyleConfiguration;
for (final textInsert in textInserts) {
TextStyle textStyle = style.text.copyWith(height: widget.lineHeight);
TextStyle textStyle =
textStyleConfiguration.text.copyWith(height: widget.lineHeight);
final attributes = textInsert.attributes;
if (attributes != null) {
if (attributes.bold == true) {
textStyle = textStyle.combine(style.bold);
textStyle = textStyle.combine(textStyleConfiguration.bold);
}
if (attributes.italic == true) {
textStyle = textStyle.combine(style.italic);
textStyle = textStyle.combine(textStyleConfiguration.italic);
}
if (attributes.underline == true) {
textStyle = textStyle.combine(style.underline);
textStyle = textStyle.combine(textStyleConfiguration.underline);
}
if (attributes.strikethrough == true) {
textStyle = textStyle.combine(style.strikethrough);
textStyle = textStyle.combine(textStyleConfiguration.strikethrough);
}
if (attributes.href != null) {
textStyle = textStyle.combine(style.href);
textStyle = textStyle.combine(textStyleConfiguration.href);
}
if (attributes.code == true) {
textStyle = textStyle.combine(style.code);
textStyle = textStyle.combine(textStyleConfiguration.code);
}
if (attributes.backgroundColor != null) {
textStyle = textStyle.combine(
Expand Down Expand Up @@ -475,7 +474,7 @@ class _AppFlowyRichTextState extends State<AppFlowyRichText>
);
}
if (attributes.autoComplete == true) {
textStyle = textStyle.combine(style.autoComplete);
textStyle = textStyle.combine(textStyleConfiguration.autoComplete);
}
if (attributes.transparent == true) {
textStyle = textStyle.combine(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
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:flutter/services.dart';
import 'package:provider/provider.dart';
Expand Down Expand Up @@ -42,6 +41,12 @@ Node todoListNode({
);
}

typedef TodoListIconBuilder = Widget Function(
BuildContext context,
Node node,
VoidCallback onCheck,
);

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

final BlockIconBuilder? iconBuilder;
final TodoListIconBuilder? iconBuilder;

final List<LogicalKeyboardKey>? toggleChildrenTriggers;

Expand Down Expand Up @@ -95,7 +100,7 @@ class TodoListBlockComponentWidget extends BlockComponentStatefulWidget {
});

final TextStyle Function(bool checked)? textStyleBuilder;
final BlockIconBuilder? iconBuilder;
final TodoListIconBuilder? iconBuilder;
final List<LogicalKeyboardKey>? toggleChildrenTriggers;

@override
Expand Down Expand Up @@ -151,7 +156,11 @@ class _TodoListBlockComponentWidgetState
textDirection: textDirection,
children: [
widget.iconBuilder != null
? widget.iconBuilder!(context, node)
? widget.iconBuilder!(
context,
node,
checkOrUncheck,
)
: _TodoListIcon(
checked: checked,
onTap: checkOrUncheck,
Expand Down
4 changes: 2 additions & 2 deletions test/customer/custom_block_icon_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ class CustomBlockIcon extends StatelessWidget {
iconBuilder: (_, __) => Icon(iconMap[BulletedListBlockKeys.type]),
),
NumberedListBlockKeys.type: NumberedListBlockComponentBuilder(
iconBuilder: (_, __) => Icon(iconMap[NumberedListBlockKeys.type]),
iconBuilder: (_, __, ___) => Icon(iconMap[NumberedListBlockKeys.type]),
),
TodoListBlockKeys.type: TodoListBlockComponentBuilder(
iconBuilder: (_, __) => Icon(iconMap[TodoListBlockKeys.type]),
iconBuilder: (_, __, ___) => Icon(iconMap[TodoListBlockKeys.type]),
),
QuoteBlockKeys.type: QuoteBlockComponentBuilder(
iconBuilder: (_, __) => Icon(iconMap[QuoteBlockKeys.type]),
Expand Down
Loading