feat: expose text span for text style builder (#1011)
* feat: expose textspan for text style builder * fix: content menu will show when collaborating
This commit is contained in:
parent
9f6a29968e
commit
2490f698c3
10 changed files with 47 additions and 31 deletions
|
|
@ -85,7 +85,7 @@ class _CustomizeThemeForEditorState extends State<CustomizeThemeForEditor> {
|
|||
}
|
||||
return const EdgeInsets.symmetric(vertical: 5);
|
||||
},
|
||||
textStyle: (node) {
|
||||
textStyle: (node, {TextSpan? textSpan}) {
|
||||
if (HeadingBlockKeys.type == node.type) {
|
||||
return const TextStyle(color: Colors.yellow);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
typedef BlockComponentTextStyleBuilder = TextStyle Function(
|
||||
Node node, {
|
||||
TextSpan? textSpan,
|
||||
});
|
||||
|
||||
/// only for the common config of block component
|
||||
class BlockComponentConfiguration {
|
||||
const BlockComponentConfiguration({
|
||||
|
|
@ -27,7 +32,7 @@ class BlockComponentConfiguration {
|
|||
) indentPadding;
|
||||
|
||||
/// The text style of a block component.
|
||||
final TextStyle Function(Node node) textStyle;
|
||||
final BlockComponentTextStyleBuilder textStyle;
|
||||
|
||||
/// The placeholder text of a block component.
|
||||
final String Function(Node node) placeholderText;
|
||||
|
|
@ -35,7 +40,7 @@ class BlockComponentConfiguration {
|
|||
/// The placeholder text style of a block component.
|
||||
///
|
||||
/// It inherits the style from [textStyle].
|
||||
final TextStyle Function(Node node) placeholderTextStyle;
|
||||
final BlockComponentTextStyleBuilder placeholderTextStyle;
|
||||
|
||||
/// The padding of a block selection area.
|
||||
final EdgeInsets Function(Node node) blockSelectionAreaMargin;
|
||||
|
|
@ -48,9 +53,9 @@ class BlockComponentConfiguration {
|
|||
|
||||
BlockComponentConfiguration copyWith({
|
||||
EdgeInsets Function(Node node)? padding,
|
||||
TextStyle Function(Node node)? textStyle,
|
||||
BlockComponentTextStyleBuilder? textStyle,
|
||||
String Function(Node node)? placeholderText,
|
||||
TextStyle Function(Node node)? placeholderTextStyle,
|
||||
BlockComponentTextStyleBuilder? placeholderTextStyle,
|
||||
EdgeInsets Function(Node node)? blockSelectionAreaMargin,
|
||||
TextAlign Function(Node node)? textAlign,
|
||||
}) {
|
||||
|
|
@ -72,13 +77,14 @@ mixin BlockComponentConfigurable<T extends StatefulWidget> on State<T> {
|
|||
|
||||
EdgeInsets get padding => configuration.padding(node);
|
||||
|
||||
TextStyle get textStyle => configuration.textStyle(node);
|
||||
TextStyle textStyleWithTextSpan({TextSpan? textSpan}) =>
|
||||
configuration.textStyle(node, textSpan: textSpan);
|
||||
|
||||
TextStyle placeholderTextStyleWithTextSpan({TextSpan? textSpan}) =>
|
||||
configuration.placeholderTextStyle(node, textSpan: textSpan);
|
||||
|
||||
String get placeholderText => configuration.placeholderText(node);
|
||||
|
||||
TextStyle get placeholderTextStyle =>
|
||||
configuration.placeholderTextStyle(node);
|
||||
|
||||
TextAlign get textAlign => configuration.textAlign(node);
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +101,7 @@ EdgeInsets _indentPadding(Node node, TextDirection textDirection) {
|
|||
}
|
||||
}
|
||||
|
||||
TextStyle _textStyle(Node node) {
|
||||
TextStyle _textStyle(Node node, {TextSpan? textSpan}) {
|
||||
return const TextStyle();
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +109,7 @@ String _placeholderText(Node node) {
|
|||
return ' ';
|
||||
}
|
||||
|
||||
TextStyle _placeholderTextStyle(Node node) {
|
||||
TextStyle _placeholderTextStyle(Node node, {TextSpan? textSpan}) {
|
||||
return const TextStyle(
|
||||
color: Colors.grey,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ class _BulletedListBlockComponentWidgetState
|
|||
? widget.iconBuilder!(context, node)
|
||||
: _BulletedListIcon(
|
||||
node: widget.node,
|
||||
textStyle: textStyle,
|
||||
textStyle: textStyleWithTextSpan(),
|
||||
),
|
||||
Flexible(
|
||||
child: AppFlowyRichText(
|
||||
|
|
@ -140,11 +140,11 @@ class _BulletedListBlockComponentWidgetState
|
|||
textAlign: alignment?.toTextAlign ?? textAlign,
|
||||
placeholderText: placeholderText,
|
||||
textSpanDecorator: (textSpan) => textSpan.updateTextStyle(
|
||||
textStyle,
|
||||
textStyleWithTextSpan(textSpan: textSpan),
|
||||
),
|
||||
placeholderTextSpanDecorator: (textSpan) =>
|
||||
textSpan.updateTextStyle(
|
||||
placeholderTextStyle,
|
||||
placeholderTextStyleWithTextSpan(textSpan: textSpan),
|
||||
),
|
||||
textDirection: textDirection,
|
||||
cursorColor: editorState.editorStyle.cursorColor,
|
||||
|
|
|
|||
|
|
@ -139,7 +139,9 @@ class _HeadingBlockComponentWidgetState
|
|||
editorState: editorState,
|
||||
textAlign: alignment?.toTextAlign ?? textAlign,
|
||||
textSpanDecorator: (textSpan) {
|
||||
var result = textSpan.updateTextStyle(textStyle);
|
||||
var result = textSpan.updateTextStyle(
|
||||
textStyleWithTextSpan(textSpan: textSpan),
|
||||
);
|
||||
result = result.updateTextStyle(
|
||||
widget.textStyleBuilder?.call(level) ??
|
||||
defaultTextStyle(level),
|
||||
|
|
@ -153,7 +155,7 @@ class _HeadingBlockComponentWidgetState
|
|||
defaultTextStyle(level),
|
||||
)
|
||||
.updateTextStyle(
|
||||
placeholderTextStyle,
|
||||
placeholderTextStyleWithTextSpan(textSpan: textSpan),
|
||||
),
|
||||
textDirection: textDirection,
|
||||
cursorColor: editorState.editorStyle.cursorColor,
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ class _NumberedListBlockComponentWidgetState
|
|||
)
|
||||
: _NumberedListIcon(
|
||||
node: node,
|
||||
textStyle: textStyle,
|
||||
textStyle: textStyleWithTextSpan(),
|
||||
direction: textDirection,
|
||||
),
|
||||
Flexible(
|
||||
|
|
@ -155,11 +155,11 @@ class _NumberedListBlockComponentWidgetState
|
|||
textAlign: alignment?.toTextAlign ?? textAlign,
|
||||
placeholderText: placeholderText,
|
||||
textSpanDecorator: (textSpan) => textSpan.updateTextStyle(
|
||||
textStyle,
|
||||
textStyleWithTextSpan(textSpan: textSpan),
|
||||
),
|
||||
placeholderTextSpanDecorator: (textSpan) =>
|
||||
textSpan.updateTextStyle(
|
||||
placeholderTextStyle,
|
||||
placeholderTextStyleWithTextSpan(textSpan: textSpan),
|
||||
),
|
||||
textDirection: textDirection,
|
||||
cursorColor: editorState.editorStyle.cursorColor,
|
||||
|
|
|
|||
|
|
@ -163,10 +163,15 @@ class _ParagraphBlockComponentWidgetState
|
|||
editorState: editorState,
|
||||
textAlign: alignment?.toTextAlign ?? textAlign,
|
||||
placeholderText: _showPlaceholder ? placeholderText : ' ',
|
||||
textSpanDecorator: (textSpan) =>
|
||||
textSpan.updateTextStyle(textStyle),
|
||||
textSpanDecorator: (textSpan) => textSpan.updateTextStyle(
|
||||
textStyleWithTextSpan(
|
||||
textSpan: textSpan,
|
||||
),
|
||||
),
|
||||
placeholderTextSpanDecorator: (textSpan) =>
|
||||
textSpan.updateTextStyle(placeholderTextStyle),
|
||||
textSpan.updateTextStyle(
|
||||
placeholderTextStyleWithTextSpan(textSpan: textSpan),
|
||||
),
|
||||
textDirection: textDirection,
|
||||
cursorColor: editorState.editorStyle.cursorColor,
|
||||
selectionColor: editorState.editorStyle.selectionColor,
|
||||
|
|
|
|||
|
|
@ -133,11 +133,11 @@ class _QuoteBlockComponentWidgetState extends State<QuoteBlockComponentWidget>
|
|||
textAlign: alignment?.toTextAlign ?? textAlign,
|
||||
placeholderText: placeholderText,
|
||||
textSpanDecorator: (textSpan) => textSpan.updateTextStyle(
|
||||
textStyle,
|
||||
textStyleWithTextSpan(textSpan: textSpan),
|
||||
),
|
||||
placeholderTextSpanDecorator: (textSpan) =>
|
||||
textSpan.updateTextStyle(
|
||||
placeholderTextStyle,
|
||||
placeholderTextStyleWithTextSpan(textSpan: textSpan),
|
||||
),
|
||||
textDirection: textDirection,
|
||||
cursorColor: editorState.editorStyle.cursorColor,
|
||||
|
|
|
|||
|
|
@ -172,14 +172,15 @@ class _TodoListBlockComponentWidgetState
|
|||
textAlign: alignment?.toTextAlign ?? textAlign,
|
||||
placeholderText: placeholderText,
|
||||
textDirection: textDirection,
|
||||
textSpanDecorator: (textSpan) =>
|
||||
textSpan.updateTextStyle(textStyle).updateTextStyle(
|
||||
widget.textStyleBuilder?.call(checked) ??
|
||||
defaultTextStyle(),
|
||||
),
|
||||
textSpanDecorator: (textSpan) => textSpan
|
||||
.updateTextStyle(textStyleWithTextSpan())
|
||||
.updateTextStyle(
|
||||
widget.textStyleBuilder?.call(checked) ??
|
||||
defaultTextStyle(),
|
||||
),
|
||||
placeholderTextSpanDecorator: (textSpan) =>
|
||||
textSpan.updateTextStyle(
|
||||
placeholderTextStyle,
|
||||
placeholderTextStyleWithTextSpan(textSpan: textSpan),
|
||||
),
|
||||
cursorColor: editorState.editorStyle.cursorColor,
|
||||
selectionColor: editorState.editorStyle.selectionColor,
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ class SelectionMenu extends SelectionMenuService {
|
|||
// Workaround: We can customize the padding through the [EditorStyle],
|
||||
// but the coordinates of overlay are not properly converted currently.
|
||||
// Just subtract the padding here as a result.
|
||||
const menuHeight = 200.0;
|
||||
const menuHeight = 300.0;
|
||||
const menuOffset = Offset(0, 10);
|
||||
final editorOffset =
|
||||
editorState.renderBox?.localToGlobal(Offset.zero) ?? Offset.zero;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ enum CursorUpdateReason {
|
|||
enum SelectionUpdateReason {
|
||||
uiEvent, // like mouse click, keyboard event
|
||||
transaction, // like insert, delete, format
|
||||
remote, // like remote selection
|
||||
selectAll,
|
||||
searchHighlight, // Highlighting search results
|
||||
}
|
||||
|
|
@ -359,6 +360,7 @@ class EditorState {
|
|||
final completer = Completer<void>();
|
||||
|
||||
if (isRemote) {
|
||||
_selectionUpdateReason = SelectionUpdateReason.remote;
|
||||
selection = _applyTransactionFromRemote(transaction);
|
||||
} else {
|
||||
// broadcast to other users here, before applying the transaction
|
||||
|
|
|
|||
Loading…
Reference in a new issue