mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge pull request #798 from LucasXu0/feat/text_style
update text style and document style.
This commit is contained in:
commit
a032a0e8db
@ -37,7 +37,11 @@
|
|||||||
"type": "text",
|
"type": "text",
|
||||||
"delta": [
|
"delta": [
|
||||||
{
|
{
|
||||||
"insert": "At AppFlowy, we embody what we value deep in our hearts, taking inspiration from other great companies while forging our own path. AppFlowy’s five core values are Mission Driven, Aim High & Iterate, Transparency, Collaboration, and Honesty. Together, they spell MATCH. We will continue to iterate and refine these values as we grow."
|
"insert": "At "
|
||||||
|
},
|
||||||
|
{ "insert": "AppFlowy", "attributes": { "code": true, "bold": true, "color": "0xFFED459C"} },
|
||||||
|
{
|
||||||
|
"insert": ", we embody what we value deep in our hearts, taking inspiration from other great companies while forging our own path. AppFlowy’s five core values are Mission Driven, Aim High & Iterate, Transparency, Collaboration, and Honesty. Together, they spell MATCH. We will continue to iterate and refine these values as we grow."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -33,7 +33,7 @@ class EditorNodeWidget extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: node.children
|
children: node.children
|
||||||
.map(
|
.map(
|
||||||
(child) =>
|
(child) =>
|
||||||
|
@ -3,6 +3,7 @@ import 'package:flowy_editor/editor_state.dart';
|
|||||||
import 'package:flowy_editor/infra/flowy_svg.dart';
|
import 'package:flowy_editor/infra/flowy_svg.dart';
|
||||||
import 'package:flowy_editor/render/rich_text/default_selectable.dart';
|
import 'package:flowy_editor/render/rich_text/default_selectable.dart';
|
||||||
import 'package:flowy_editor/render/rich_text/flowy_rich_text.dart';
|
import 'package:flowy_editor/render/rich_text/flowy_rich_text.dart';
|
||||||
|
import 'package:flowy_editor/render/rich_text/rich_text_style.dart';
|
||||||
import 'package:flowy_editor/render/selection/selectable.dart';
|
import 'package:flowy_editor/render/selection/selectable.dart';
|
||||||
import 'package:flowy_editor/service/render_plugin_service.dart';
|
import 'package:flowy_editor/service/render_plugin_service.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -56,21 +57,22 @@ class _BulletedListTextNodeWidgetState extends State<BulletedListTextNodeWidget>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Row(
|
return SizedBox(
|
||||||
children: [
|
width: maxTextNodeWidth,
|
||||||
FlowySvg(
|
child: Row(
|
||||||
size: Size.square(leftPadding),
|
children: [
|
||||||
name: 'point',
|
FlowySvg(
|
||||||
),
|
size: Size.square(leftPadding),
|
||||||
Expanded(
|
name: 'point',
|
||||||
child: FlowyRichText(
|
),
|
||||||
|
FlowyRichText(
|
||||||
key: _richTextKey,
|
key: _richTextKey,
|
||||||
placeholderText: 'List',
|
placeholderText: 'List',
|
||||||
textNode: widget.textNode,
|
textNode: widget.textNode,
|
||||||
editorState: widget.editorState,
|
editorState: widget.editorState,
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,33 +65,34 @@ class _CheckboxNodeWidgetState extends State<CheckboxNodeWidget>
|
|||||||
|
|
||||||
Widget _buildWithSingle(BuildContext context) {
|
Widget _buildWithSingle(BuildContext context) {
|
||||||
final check = widget.textNode.attributes.check;
|
final check = widget.textNode.attributes.check;
|
||||||
return Row(
|
return SizedBox(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
width: maxTextNodeWidth,
|
||||||
children: [
|
child: Row(
|
||||||
GestureDetector(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
child: FlowySvg(
|
children: [
|
||||||
size: Size.square(leftPadding),
|
GestureDetector(
|
||||||
name: check ? 'check' : 'uncheck',
|
child: FlowySvg(
|
||||||
|
size: Size.square(leftPadding),
|
||||||
|
name: check ? 'check' : 'uncheck',
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
debugPrint('[Checkbox] onTap...');
|
||||||
|
TransactionBuilder(widget.editorState)
|
||||||
|
..updateNode(widget.textNode, {
|
||||||
|
StyleKey.checkbox: !check,
|
||||||
|
})
|
||||||
|
..commit();
|
||||||
|
},
|
||||||
),
|
),
|
||||||
onTap: () {
|
FlowyRichText(
|
||||||
debugPrint('[Checkbox] onTap...');
|
|
||||||
TransactionBuilder(widget.editorState)
|
|
||||||
..updateNode(widget.textNode, {
|
|
||||||
StyleKey.checkbox: !check,
|
|
||||||
})
|
|
||||||
..commit();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: FlowyRichText(
|
|
||||||
key: _richTextKey,
|
key: _richTextKey,
|
||||||
placeholderText: 'To-do',
|
placeholderText: 'To-do',
|
||||||
textNode: widget.textNode,
|
textNode: widget.textNode,
|
||||||
textSpanDecorator: _textSpanDecorator,
|
textSpanDecorator: _textSpanDecorator,
|
||||||
editorState: widget.editorState,
|
editorState: widget.editorState,
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,22 +11,6 @@ import 'package:flowy_editor/render/rich_text/rich_text_style.dart';
|
|||||||
import 'package:flowy_editor/render/selection/selectable.dart';
|
import 'package:flowy_editor/render/selection/selectable.dart';
|
||||||
import 'package:flowy_editor/service/render_plugin_service.dart';
|
import 'package:flowy_editor/service/render_plugin_service.dart';
|
||||||
|
|
||||||
class RichTextNodeWidgetBuilder extends NodeWidgetBuilder<TextNode> {
|
|
||||||
@override
|
|
||||||
Widget build(NodeWidgetContext<TextNode> context) {
|
|
||||||
return FlowyRichText(
|
|
||||||
key: context.node.key,
|
|
||||||
textNode: context.node,
|
|
||||||
editorState: context.editorState,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
NodeValidator<Node> get nodeValidator => ((node) {
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef FlowyTextSpanDecorator = TextSpan Function(TextSpan textSpan);
|
typedef FlowyTextSpanDecorator = TextSpan Function(TextSpan textSpan);
|
||||||
|
|
||||||
class FlowyRichText extends StatefulWidget {
|
class FlowyRichText extends StatefulWidget {
|
||||||
|
@ -56,25 +56,22 @@ class _HeadingTextNodeWidgetState extends State<HeadingTextNodeWidget>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column(
|
return SizedBox(
|
||||||
children: [
|
width: maxTextNodeWidth,
|
||||||
Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
top: topPadding,
|
top: topPadding,
|
||||||
bottom: bottomPadding,
|
bottom: bottomPadding,
|
||||||
),
|
),
|
||||||
child: Expanded(
|
child: FlowyRichText(
|
||||||
child: FlowyRichText(
|
key: _richTextKey,
|
||||||
key: _richTextKey,
|
placeholderText: 'Heading',
|
||||||
placeholderText: 'Heading',
|
placeholderTextSpanDecorator: _placeholderTextSpanDecorator,
|
||||||
placeholderTextSpanDecorator: _placeholderTextSpanDecorator,
|
textSpanDecorator: _textSpanDecorator,
|
||||||
textSpanDecorator: _textSpanDecorator,
|
textNode: widget.textNode,
|
||||||
textNode: widget.textNode,
|
editorState: widget.editorState,
|
||||||
editorState: widget.editorState,
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,21 +57,22 @@ class _NumberListTextNodeWidgetState extends State<NumberListTextNodeWidget>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Row(
|
return SizedBox(
|
||||||
children: [
|
width: maxTextNodeWidth,
|
||||||
FlowySvg(
|
child: Row(
|
||||||
size: Size.square(leftPadding),
|
children: [
|
||||||
number: widget.textNode.attributes.number,
|
FlowySvg(
|
||||||
),
|
size: Size.square(leftPadding),
|
||||||
Expanded(
|
number: widget.textNode.attributes.number,
|
||||||
child: FlowyRichText(
|
),
|
||||||
|
FlowyRichText(
|
||||||
key: _richTextKey,
|
key: _richTextKey,
|
||||||
placeholderText: 'List',
|
placeholderText: 'List',
|
||||||
textNode: widget.textNode,
|
textNode: widget.textNode,
|
||||||
editorState: widget.editorState,
|
editorState: widget.editorState,
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,24 +56,25 @@ class _QuotedTextNodeWidgetState extends State<QuotedTextNodeWidget>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Row(
|
return SizedBox(
|
||||||
children: [
|
width: maxTextNodeWidth,
|
||||||
FlowySvg(
|
child: Row(
|
||||||
size: Size(
|
children: [
|
||||||
leftPadding,
|
FlowySvg(
|
||||||
_quoteHeight,
|
size: Size(
|
||||||
|
leftPadding,
|
||||||
|
_quoteHeight,
|
||||||
|
),
|
||||||
|
name: 'quote',
|
||||||
),
|
),
|
||||||
name: 'quote',
|
FlowyRichText(
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: FlowyRichText(
|
|
||||||
key: _richTextKey,
|
key: _richTextKey,
|
||||||
placeholderText: 'Quote',
|
placeholderText: 'Quote',
|
||||||
textNode: widget.textNode,
|
textNode: widget.textNode,
|
||||||
editorState: widget.editorState,
|
editorState: widget.editorState,
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
import 'package:flowy_editor/document/node.dart';
|
||||||
|
import 'package:flowy_editor/editor_state.dart';
|
||||||
|
import 'package:flowy_editor/infra/flowy_svg.dart';
|
||||||
|
import 'package:flowy_editor/render/rich_text/default_selectable.dart';
|
||||||
|
import 'package:flowy_editor/render/rich_text/flowy_rich_text.dart';
|
||||||
|
import 'package:flowy_editor/render/rich_text/rich_text_style.dart';
|
||||||
|
import 'package:flowy_editor/render/selection/selectable.dart';
|
||||||
|
import 'package:flowy_editor/service/render_plugin_service.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class RichTextNodeWidgetBuilder extends NodeWidgetBuilder<TextNode> {
|
||||||
|
@override
|
||||||
|
Widget build(NodeWidgetContext<TextNode> context) {
|
||||||
|
return RichTextNodeWidget(
|
||||||
|
key: context.node.key,
|
||||||
|
textNode: context.node,
|
||||||
|
editorState: context.editorState,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
NodeValidator<Node> get nodeValidator => ((node) {
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class RichTextNodeWidget extends StatefulWidget {
|
||||||
|
const RichTextNodeWidget({
|
||||||
|
Key? key,
|
||||||
|
required this.textNode,
|
||||||
|
required this.editorState,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final TextNode textNode;
|
||||||
|
final EditorState editorState;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<RichTextNodeWidget> createState() => _RichTextNodeWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
// customize
|
||||||
|
|
||||||
|
class _RichTextNodeWidgetState extends State<RichTextNodeWidget>
|
||||||
|
with Selectable, DefaultSelectable {
|
||||||
|
final _richTextKey = GlobalKey(debugLabel: 'rich_text');
|
||||||
|
final leftPadding = 20.0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Selectable<StatefulWidget> get forward =>
|
||||||
|
_richTextKey.currentState as Selectable;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Offset get baseOffset {
|
||||||
|
return Offset.zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
width: maxTextNodeWidth,
|
||||||
|
child: FlowyRichText(
|
||||||
|
key: _richTextKey,
|
||||||
|
textNode: widget.textNode,
|
||||||
|
editorState: widget.editorState,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -59,6 +59,8 @@ class StyleKey {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: customize
|
||||||
|
double maxTextNodeWidth = 780.0;
|
||||||
double baseFontSize = 16.0;
|
double baseFontSize = 16.0;
|
||||||
// TODO: customize.
|
// TODO: customize.
|
||||||
Map<String, double> headingToFontSize = {
|
Map<String, double> headingToFontSize = {
|
||||||
@ -146,7 +148,7 @@ extension DeltaAttributesExtensions on Attributes {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color? get hightlightColor {
|
Color? get highlightColor {
|
||||||
if (containsKey(StyleKey.highlightColor) &&
|
if (containsKey(StyleKey.highlightColor) &&
|
||||||
this[StyleKey.highlightColor] is String) {
|
this[StyleKey.highlightColor] is String) {
|
||||||
return Color(
|
return Color(
|
||||||
@ -183,19 +185,30 @@ class RichTextStyle {
|
|||||||
return TextSpan(
|
return TextSpan(
|
||||||
text: text,
|
text: text,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: fontWeight,
|
fontWeight: _fontWeight,
|
||||||
fontStyle: fontStyle,
|
fontStyle: _fontStyle,
|
||||||
fontSize: fontSize,
|
fontSize: _fontSize,
|
||||||
color: textColor,
|
color: _textColor,
|
||||||
backgroundColor: backgroundColor,
|
decoration: _textDecoration,
|
||||||
decoration: textDecoration,
|
background: _background,
|
||||||
),
|
),
|
||||||
recognizer: recognizer,
|
recognizer: _recognizer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Paint? get _background {
|
||||||
|
if (_backgroundColor != null) {
|
||||||
|
return Paint()
|
||||||
|
..color = _backgroundColor!
|
||||||
|
..strokeWidth = 24.0
|
||||||
|
..style = PaintingStyle.fill
|
||||||
|
..strokeJoin = StrokeJoin.round;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// bold
|
// bold
|
||||||
FontWeight get fontWeight {
|
FontWeight get _fontWeight {
|
||||||
if (attributes.bold) {
|
if (attributes.bold) {
|
||||||
return FontWeight.bold;
|
return FontWeight.bold;
|
||||||
}
|
}
|
||||||
@ -203,38 +216,46 @@ class RichTextStyle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// underline or strikethrough
|
// underline or strikethrough
|
||||||
TextDecoration get textDecoration {
|
TextDecoration get _textDecoration {
|
||||||
|
var decorations = [TextDecoration.none];
|
||||||
if (attributes.underline || attributes.href != null) {
|
if (attributes.underline || attributes.href != null) {
|
||||||
return TextDecoration.underline;
|
decorations.add(TextDecoration.underline);
|
||||||
} else if (attributes.strikethrough) {
|
// TextDecoration.underline;
|
||||||
return TextDecoration.lineThrough;
|
|
||||||
}
|
}
|
||||||
return TextDecoration.none;
|
if (attributes.strikethrough) {
|
||||||
|
decorations.add(TextDecoration.lineThrough);
|
||||||
|
}
|
||||||
|
return TextDecoration.combine(decorations);
|
||||||
}
|
}
|
||||||
|
|
||||||
// font
|
// font
|
||||||
FontStyle get fontStyle =>
|
FontStyle get _fontStyle =>
|
||||||
attributes.italic ? FontStyle.italic : FontStyle.normal;
|
attributes.italic ? FontStyle.italic : FontStyle.normal;
|
||||||
|
|
||||||
// text color
|
// text color
|
||||||
Color get textColor {
|
Color get _textColor {
|
||||||
if (attributes.href != null) {
|
if (attributes.href != null) {
|
||||||
return Colors.lightBlue;
|
return Colors.lightBlue;
|
||||||
}
|
}
|
||||||
return attributes.color ?? Colors.black;
|
return attributes.color ?? Colors.black;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color get backgroundColor {
|
Color? get _backgroundColor {
|
||||||
return attributes.hightlightColor ?? Colors.transparent;
|
if (attributes.highlightColor != null) {
|
||||||
|
return attributes.highlightColor!;
|
||||||
|
} else if (attributes.code) {
|
||||||
|
return Colors.grey.withOpacity(0.4);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// font size
|
// font size
|
||||||
double get fontSize {
|
double get _fontSize {
|
||||||
return baseFontSize;
|
return baseFontSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// recognizer
|
// recognizer
|
||||||
GestureRecognizer? get recognizer {
|
GestureRecognizer? get _recognizer {
|
||||||
final href = attributes.href;
|
final href = attributes.href;
|
||||||
if (href != null) {
|
if (href != null) {
|
||||||
return TapGestureRecognizer()
|
return TapGestureRecognizer()
|
||||||
|
@ -97,11 +97,6 @@ bool formatRichTextPartialStyle(EditorState editorState, String styleKey) {
|
|||||||
Attributes attributes = {
|
Attributes attributes = {
|
||||||
styleKey: value,
|
styleKey: value,
|
||||||
};
|
};
|
||||||
if (styleKey == StyleKey.underline && value) {
|
|
||||||
attributes[StyleKey.strikethrough] = null;
|
|
||||||
} else if (styleKey == StyleKey.strikethrough && value) {
|
|
||||||
attributes[StyleKey.underline] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return formatRichTextStyle(editorState, attributes);
|
return formatRichTextStyle(editorState, attributes);
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,10 @@ import 'package:flowy_editor/editor_state.dart';
|
|||||||
import 'package:flowy_editor/render/editor/editor_entry.dart';
|
import 'package:flowy_editor/render/editor/editor_entry.dart';
|
||||||
import 'package:flowy_editor/render/rich_text/bulleted_list_text.dart';
|
import 'package:flowy_editor/render/rich_text/bulleted_list_text.dart';
|
||||||
import 'package:flowy_editor/render/rich_text/checkbox_text.dart';
|
import 'package:flowy_editor/render/rich_text/checkbox_text.dart';
|
||||||
import 'package:flowy_editor/render/rich_text/flowy_rich_text.dart';
|
|
||||||
import 'package:flowy_editor/render/rich_text/heading_text.dart';
|
import 'package:flowy_editor/render/rich_text/heading_text.dart';
|
||||||
import 'package:flowy_editor/render/rich_text/number_list_text.dart';
|
import 'package:flowy_editor/render/rich_text/number_list_text.dart';
|
||||||
import 'package:flowy_editor/render/rich_text/quoted_text.dart';
|
import 'package:flowy_editor/render/rich_text/quoted_text.dart';
|
||||||
|
import 'package:flowy_editor/render/rich_text/rich_text.dart';
|
||||||
import 'package:flowy_editor/service/input_service.dart';
|
import 'package:flowy_editor/service/input_service.dart';
|
||||||
import 'package:flowy_editor/service/internal_key_event_handlers/arrow_keys_handler.dart';
|
import 'package:flowy_editor/service/internal_key_event_handlers/arrow_keys_handler.dart';
|
||||||
import 'package:flowy_editor/service/internal_key_event_handlers/copy_paste_handler.dart';
|
import 'package:flowy_editor/service/internal_key_event_handlers/copy_paste_handler.dart';
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
import 'package:flowy_editor/document/attributes.dart';
|
||||||
import 'package:flowy_editor/document/node.dart';
|
import 'package:flowy_editor/document/node.dart';
|
||||||
import 'package:flowy_editor/document/position.dart';
|
import 'package:flowy_editor/document/position.dart';
|
||||||
import 'package:flowy_editor/document/selection.dart';
|
import 'package:flowy_editor/document/selection.dart';
|
||||||
@ -91,7 +92,8 @@ FlowyKeyEventHandler enterWithoutShiftInTextNodesHandler =
|
|||||||
..insertNode(
|
..insertNode(
|
||||||
textNode.path.next,
|
textNode.path.next,
|
||||||
textNode.copyWith(
|
textNode.copyWith(
|
||||||
attributes: needCopyAttributes ? textNode.attributes : {},
|
attributes:
|
||||||
|
needCopyAttributes ? Attributes.from(textNode.attributes) : {},
|
||||||
delta: textNode.delta.slice(selection.end.offset),
|
delta: textNode.delta.slice(selection.end.offset),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -23,6 +23,18 @@ FlowyKeyEventHandler updateTextStyleByCommandXHandler = (editorState, event) {
|
|||||||
case 'b':
|
case 'b':
|
||||||
formatBold(editorState);
|
formatBold(editorState);
|
||||||
return KeyEventResult.handled;
|
return KeyEventResult.handled;
|
||||||
|
case 'I':
|
||||||
|
case 'i':
|
||||||
|
formatItalic(editorState);
|
||||||
|
return KeyEventResult.handled;
|
||||||
|
case 'U':
|
||||||
|
case 'u':
|
||||||
|
formatUnderline(editorState);
|
||||||
|
return KeyEventResult.handled;
|
||||||
|
case 'S':
|
||||||
|
case 's':
|
||||||
|
formatStrikethrough(editorState);
|
||||||
|
return KeyEventResult.handled;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user