mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: refactor theme plugin, use themedata extension
This commit is contained in:
parent
68da3955c1
commit
cdee706f46
@ -38,6 +38,7 @@ class MyApp extends StatelessWidget {
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
// extensions: [HeadingPluginStyle.light],
|
||||
),
|
||||
home: const MyHomePage(title: 'AppFlowyEditor Example'),
|
||||
);
|
||||
@ -125,28 +126,48 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
_editorState!.transactionStream.listen((event) {
|
||||
debugPrint('Transaction: ${event.toJson()}');
|
||||
});
|
||||
return Container(
|
||||
color: darkMode ? Colors.black : Colors.white,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: AppFlowyEditor(
|
||||
editorState: _editorState!,
|
||||
editorStyle: _editorStyle,
|
||||
editable: true,
|
||||
customBuilders: {
|
||||
'text/code_block': CodeBlockNodeWidgetBuilder(),
|
||||
'tex': TeXBlockNodeWidgetBuidler(),
|
||||
'horizontal_rule': HorizontalRuleWidgetBuilder(),
|
||||
},
|
||||
shortcutEvents: [
|
||||
enterInCodeBlock,
|
||||
ignoreKeysInCodeBlock,
|
||||
insertHorizontalRule,
|
||||
],
|
||||
selectionMenuItems: [
|
||||
codeBlockMenuItem,
|
||||
teXBlockMenuItem,
|
||||
horizontalRuleMenuItem,
|
||||
],
|
||||
final themeData = darkMode
|
||||
? ThemeData.dark().copyWith(extensions: [
|
||||
HeadingPluginStyle.dark,
|
||||
CheckboxPluginStyle.dark,
|
||||
NumberListPluginStyle.dark,
|
||||
QuotedTextPluginStyle.dark,
|
||||
BulletedListPluginStyle.dark
|
||||
])
|
||||
: ThemeData.light().copyWith(
|
||||
extensions: [
|
||||
HeadingPluginStyle.light,
|
||||
CheckboxPluginStyle.light,
|
||||
NumberListPluginStyle.light,
|
||||
QuotedTextPluginStyle.light,
|
||||
BulletedListPluginStyle.light
|
||||
],
|
||||
);
|
||||
return Theme(
|
||||
data: themeData,
|
||||
child: Container(
|
||||
color: darkMode ? Colors.black : Colors.white,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: AppFlowyEditor(
|
||||
editorState: _editorState!,
|
||||
editorStyle: _editorStyle,
|
||||
editable: true,
|
||||
customBuilders: {
|
||||
'text/code_block': CodeBlockNodeWidgetBuilder(),
|
||||
'tex': TeXBlockNodeWidgetBuidler(),
|
||||
'horizontal_rule': HorizontalRuleWidgetBuilder(),
|
||||
},
|
||||
shortcutEvents: [
|
||||
enterInCodeBlock,
|
||||
ignoreKeysInCodeBlock,
|
||||
insertHorizontalRule,
|
||||
],
|
||||
selectionMenuItems: [
|
||||
codeBlockMenuItem,
|
||||
teXBlockMenuItem,
|
||||
horizontalRuleMenuItem,
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
|
@ -31,3 +31,4 @@ export 'src/render/rich_text/default_selectable.dart';
|
||||
export 'src/render/rich_text/flowy_rich_text.dart';
|
||||
export 'src/render/selection_menu/selection_menu_widget.dart';
|
||||
export 'src/l10n/l10n.dart';
|
||||
export 'src/render/style/built_in_plugin_styles.dart';
|
||||
|
@ -1,10 +1,10 @@
|
||||
import 'package:appflowy_editor/src/core/document/node.dart';
|
||||
import 'package:appflowy_editor/src/editor_state.dart';
|
||||
import 'package:appflowy_editor/src/infra/flowy_svg.dart';
|
||||
import 'package:appflowy_editor/src/render/rich_text/built_in_text_widget.dart';
|
||||
import 'package:appflowy_editor/src/render/rich_text/default_selectable.dart';
|
||||
import 'package:appflowy_editor/src/render/rich_text/flowy_rich_text.dart';
|
||||
import 'package:appflowy_editor/src/render/selection/selectable.dart';
|
||||
import 'package:appflowy_editor/src/render/style/built_in_plugin_styles.dart';
|
||||
import 'package:appflowy_editor/src/service/render_plugin_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:appflowy_editor/src/extensions/text_style_extension.dart';
|
||||
@ -45,11 +45,7 @@ class BulletedListTextNodeWidget extends BuiltInTextWidget {
|
||||
// customize
|
||||
|
||||
class _BulletedListTextNodeWidgetState extends State<BulletedListTextNodeWidget>
|
||||
with
|
||||
SelectableMixin,
|
||||
DefaultSelectable,
|
||||
BuiltInStyleMixin,
|
||||
BuiltInTextWidgetMixin {
|
||||
with SelectableMixin, DefaultSelectable, BuiltInTextWidgetMixin {
|
||||
@override
|
||||
final iconKey = GlobalKey();
|
||||
|
||||
@ -64,17 +60,23 @@ class _BulletedListTextNodeWidgetState extends State<BulletedListTextNodeWidget>
|
||||
return super.baseOffset.translate(0, padding.top);
|
||||
}
|
||||
|
||||
Color get bulletColor {
|
||||
final bulletColor = widget.editorState.editorStyle.style(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
'bulletColor',
|
||||
);
|
||||
if (bulletColor is Color) {
|
||||
return bulletColor;
|
||||
}
|
||||
return Colors.black;
|
||||
}
|
||||
BulletedListPluginStyle get style =>
|
||||
Theme.of(context).extension<BulletedListPluginStyle>()!;
|
||||
|
||||
EdgeInsets get padding => style.padding(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
);
|
||||
|
||||
TextStyle get textStyle => style.textStyle(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
);
|
||||
|
||||
Widget get icon => style.icon(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget buildWithSingle(BuildContext context) {
|
||||
@ -83,13 +85,9 @@ class _BulletedListTextNodeWidgetState extends State<BulletedListTextNodeWidget>
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
FlowySvg(
|
||||
Container(
|
||||
key: iconKey,
|
||||
width: iconSize?.width,
|
||||
height: iconSize?.height,
|
||||
padding: iconPadding,
|
||||
color: bulletColor,
|
||||
name: 'point',
|
||||
child: icon,
|
||||
),
|
||||
Flexible(
|
||||
child: FlowyRichText(
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor/src/commands/text/text_commands.dart';
|
||||
import 'package:appflowy_editor/src/infra/flowy_svg.dart';
|
||||
import 'package:appflowy_editor/src/render/rich_text/built_in_text_widget.dart';
|
||||
|
||||
import 'package:appflowy_editor/src/extensions/text_style_extension.dart';
|
||||
@ -39,11 +38,7 @@ class CheckboxNodeWidget extends BuiltInTextWidget {
|
||||
}
|
||||
|
||||
class _CheckboxNodeWidgetState extends State<CheckboxNodeWidget>
|
||||
with
|
||||
SelectableMixin,
|
||||
DefaultSelectable,
|
||||
BuiltInStyleMixin,
|
||||
BuiltInTextWidgetMixin {
|
||||
with SelectableMixin, DefaultSelectable, BuiltInTextWidgetMixin {
|
||||
@override
|
||||
final iconKey = GlobalKey();
|
||||
|
||||
@ -58,6 +53,24 @@ class _CheckboxNodeWidgetState extends State<CheckboxNodeWidget>
|
||||
return super.baseOffset.translate(0, padding.top);
|
||||
}
|
||||
|
||||
CheckboxPluginStyle get style =>
|
||||
Theme.of(context).extension<CheckboxPluginStyle>()!;
|
||||
|
||||
EdgeInsets get padding => style.padding(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
);
|
||||
|
||||
TextStyle get textStyle => style.textStyle(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
);
|
||||
|
||||
Widget get icon => style.icon(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget buildWithSingle(BuildContext context) {
|
||||
final check = widget.textNode.attributes.check;
|
||||
@ -68,12 +81,7 @@ class _CheckboxNodeWidgetState extends State<CheckboxNodeWidget>
|
||||
children: [
|
||||
GestureDetector(
|
||||
key: iconKey,
|
||||
child: FlowySvg(
|
||||
width: iconSize?.width,
|
||||
height: iconSize?.height,
|
||||
padding: iconPadding,
|
||||
name: check ? 'check' : 'uncheck',
|
||||
),
|
||||
child: icon,
|
||||
onTap: () async {
|
||||
await widget.editorState.formatTextToCheckbox(
|
||||
widget.editorState,
|
||||
|
@ -4,6 +4,7 @@ import 'package:appflowy_editor/src/render/rich_text/built_in_text_widget.dart';
|
||||
import 'package:appflowy_editor/src/render/rich_text/default_selectable.dart';
|
||||
import 'package:appflowy_editor/src/render/rich_text/flowy_rich_text.dart';
|
||||
import 'package:appflowy_editor/src/render/selection/selectable.dart';
|
||||
import 'package:appflowy_editor/src/render/style/built_in_plugin_styles.dart';
|
||||
import 'package:appflowy_editor/src/service/render_plugin_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:appflowy_editor/src/extensions/attributes_extension.dart';
|
||||
@ -43,7 +44,7 @@ class HeadingTextNodeWidget extends BuiltInTextWidget {
|
||||
|
||||
// customize
|
||||
class _HeadingTextNodeWidgetState extends State<HeadingTextNodeWidget>
|
||||
with SelectableMixin, DefaultSelectable, BuiltInStyleMixin {
|
||||
with SelectableMixin, DefaultSelectable {
|
||||
@override
|
||||
GlobalKey? get iconKey => null;
|
||||
|
||||
@ -58,6 +59,19 @@ class _HeadingTextNodeWidgetState extends State<HeadingTextNodeWidget>
|
||||
return padding.topLeft;
|
||||
}
|
||||
|
||||
HeadingPluginStyle get style =>
|
||||
Theme.of(context).extension<HeadingPluginStyle>()!;
|
||||
|
||||
EdgeInsets get padding => style.padding(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
);
|
||||
|
||||
TextStyle get textStyle => style.textStyle(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
|
@ -4,6 +4,7 @@ import 'package:appflowy_editor/src/render/rich_text/built_in_text_widget.dart';
|
||||
import 'package:appflowy_editor/src/render/rich_text/default_selectable.dart';
|
||||
import 'package:appflowy_editor/src/render/rich_text/flowy_rich_text.dart';
|
||||
import 'package:appflowy_editor/src/render/selection/selectable.dart';
|
||||
import 'package:appflowy_editor/src/render/style/plugin_style.dart';
|
||||
import 'package:appflowy_editor/src/service/render_plugin_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:appflowy_editor/src/extensions/attributes_extension.dart';
|
||||
@ -43,7 +44,7 @@ class NumberListTextNodeWidget extends BuiltInTextWidget {
|
||||
}
|
||||
|
||||
class _NumberListTextNodeWidgetState extends State<NumberListTextNodeWidget>
|
||||
with SelectableMixin, DefaultSelectable, BuiltInStyleMixin {
|
||||
with SelectableMixin, DefaultSelectable {
|
||||
@override
|
||||
final iconKey = GlobalKey();
|
||||
|
||||
@ -70,6 +71,24 @@ class _NumberListTextNodeWidgetState extends State<NumberListTextNodeWidget>
|
||||
return Colors.black;
|
||||
}
|
||||
|
||||
NumberListPluginStyle get style =>
|
||||
Theme.of(context).extension<NumberListPluginStyle>()!;
|
||||
|
||||
EdgeInsets get padding => style.padding(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
);
|
||||
|
||||
TextStyle get textStyle => style.textStyle(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
);
|
||||
|
||||
Widget get icon => style.icon(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
@ -79,15 +98,7 @@ class _NumberListTextNodeWidgetState extends State<NumberListTextNodeWidget>
|
||||
children: [
|
||||
Container(
|
||||
key: iconKey,
|
||||
padding: iconPadding,
|
||||
child: Text(
|
||||
'${widget.textNode.attributes.number.toString()}.',
|
||||
style: TextStyle(
|
||||
fontSize: widget.editorState.editorStyle.textStyle
|
||||
.defaultTextStyle.fontSize,
|
||||
color: numberColor,
|
||||
),
|
||||
),
|
||||
child: icon,
|
||||
),
|
||||
Flexible(
|
||||
child: FlowyRichText(
|
||||
|
@ -1,10 +1,10 @@
|
||||
import 'package:appflowy_editor/src/core/document/node.dart';
|
||||
import 'package:appflowy_editor/src/editor_state.dart';
|
||||
import 'package:appflowy_editor/src/infra/flowy_svg.dart';
|
||||
import 'package:appflowy_editor/src/render/rich_text/built_in_text_widget.dart';
|
||||
import 'package:appflowy_editor/src/render/rich_text/default_selectable.dart';
|
||||
import 'package:appflowy_editor/src/render/rich_text/flowy_rich_text.dart';
|
||||
import 'package:appflowy_editor/src/render/selection/selectable.dart';
|
||||
import 'package:appflowy_editor/src/render/style/built_in_plugin_styles.dart';
|
||||
import 'package:appflowy_editor/src/service/render_plugin_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:appflowy_editor/src/extensions/text_style_extension.dart';
|
||||
@ -44,7 +44,7 @@ class QuotedTextNodeWidget extends BuiltInTextWidget {
|
||||
// customize
|
||||
|
||||
class _QuotedTextNodeWidgetState extends State<QuotedTextNodeWidget>
|
||||
with SelectableMixin, DefaultSelectable, BuiltInStyleMixin {
|
||||
with SelectableMixin, DefaultSelectable {
|
||||
@override
|
||||
final iconKey = GlobalKey();
|
||||
|
||||
@ -59,6 +59,24 @@ class _QuotedTextNodeWidgetState extends State<QuotedTextNodeWidget>
|
||||
return super.baseOffset.translate(0, padding.top);
|
||||
}
|
||||
|
||||
QuotedTextPluginStyle get style =>
|
||||
Theme.of(context).extension<QuotedTextPluginStyle>()!;
|
||||
|
||||
EdgeInsets get padding => style.padding(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
);
|
||||
|
||||
TextStyle get textStyle => style.textStyle(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
);
|
||||
|
||||
Widget get icon => style.icon(
|
||||
widget.editorState,
|
||||
widget.textNode,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
@ -67,11 +85,9 @@ class _QuotedTextNodeWidgetState extends State<QuotedTextNodeWidget>
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
FlowySvg(
|
||||
Container(
|
||||
key: iconKey,
|
||||
width: iconSize?.width,
|
||||
padding: iconPadding,
|
||||
name: 'quote',
|
||||
child: icon,
|
||||
),
|
||||
Flexible(
|
||||
child: FlowyRichText(
|
||||
|
@ -4,6 +4,100 @@ import 'package:appflowy_editor/src/core/document/node.dart';
|
||||
import 'package:appflowy_editor/src/editor_state.dart';
|
||||
import 'package:appflowy_editor/src/extensions/attributes_extension.dart';
|
||||
|
||||
class EditorStyleV2 extends ThemeExtension<EditorStyleV2> {
|
||||
// Editor styles
|
||||
final EdgeInsets? padding;
|
||||
final Color? cursorColor;
|
||||
final Color? selectionColor;
|
||||
|
||||
// Text styles
|
||||
final TextStyle? textStyle;
|
||||
final TextStyle? placeholderTextStyle;
|
||||
final double lineHeight;
|
||||
|
||||
// Rich text styles
|
||||
final TextStyle? bold;
|
||||
final TextStyle? italic;
|
||||
final TextStyle? underline;
|
||||
final TextStyle? strikethrough;
|
||||
final TextStyle? href;
|
||||
final TextStyle? code;
|
||||
final String? highlightColorHex;
|
||||
|
||||
EditorStyleV2({
|
||||
required this.padding,
|
||||
required this.cursorColor,
|
||||
required this.selectionColor,
|
||||
required this.textStyle,
|
||||
required this.placeholderTextStyle,
|
||||
required this.bold,
|
||||
required this.italic,
|
||||
required this.underline,
|
||||
required this.strikethrough,
|
||||
required this.href,
|
||||
required this.code,
|
||||
required this.highlightColorHex,
|
||||
required this.lineHeight,
|
||||
});
|
||||
|
||||
@override
|
||||
EditorStyleV2 copyWith({
|
||||
EdgeInsets? padding,
|
||||
Color? cursorColor,
|
||||
Color? selectionColor,
|
||||
TextStyle? textStyle,
|
||||
TextStyle? placeholderTextStyle,
|
||||
TextStyle? bold,
|
||||
TextStyle? italic,
|
||||
TextStyle? underline,
|
||||
TextStyle? strikethrough,
|
||||
TextStyle? href,
|
||||
TextStyle? code,
|
||||
String? highlightColorHex,
|
||||
double? lineHeight,
|
||||
}) {
|
||||
return EditorStyleV2(
|
||||
padding: padding ?? this.padding,
|
||||
cursorColor: cursorColor ?? this.cursorColor,
|
||||
selectionColor: selectionColor ?? this.selectionColor,
|
||||
textStyle: textStyle ?? this.textStyle,
|
||||
placeholderTextStyle: placeholderTextStyle ?? this.placeholderTextStyle,
|
||||
bold: bold ?? this.bold,
|
||||
italic: italic ?? this.italic,
|
||||
underline: underline ?? this.underline,
|
||||
strikethrough: strikethrough ?? this.strikethrough,
|
||||
href: href ?? this.href,
|
||||
code: code ?? this.code,
|
||||
highlightColorHex: highlightColorHex ?? this.highlightColorHex,
|
||||
lineHeight: lineHeight ?? this.lineHeight,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
ThemeExtension<EditorStyleV2> lerp(
|
||||
ThemeExtension<EditorStyleV2>? other, double t) {
|
||||
if (other == null || other is! EditorStyleV2) {
|
||||
return this;
|
||||
}
|
||||
return EditorStyleV2(
|
||||
padding: EdgeInsets.lerp(padding, other.padding, t),
|
||||
cursorColor: Color.lerp(cursorColor, other.cursorColor, t),
|
||||
selectionColor: Color.lerp(selectionColor, other.selectionColor, t),
|
||||
textStyle: TextStyle.lerp(textStyle, other.textStyle, t),
|
||||
placeholderTextStyle:
|
||||
TextStyle.lerp(placeholderTextStyle, other.placeholderTextStyle, t),
|
||||
bold: TextStyle.lerp(bold, other.bold, t),
|
||||
italic: TextStyle.lerp(italic, other.italic, t),
|
||||
underline: TextStyle.lerp(underline, other.underline, t),
|
||||
strikethrough: TextStyle.lerp(strikethrough, other.strikethrough, t),
|
||||
href: TextStyle.lerp(href, other.href, t),
|
||||
code: TextStyle.lerp(code, other.code, t),
|
||||
highlightColorHex: highlightColorHex,
|
||||
lineHeight: lineHeight,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
typedef PluginStyler = Object Function(EditorState editorState, Node node);
|
||||
typedef PluginStyle = Map<String, PluginStyler>;
|
||||
|
||||
@ -41,6 +135,7 @@ class EditorStyle {
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
EditorStyle copyWith({
|
||||
EdgeInsets? padding,
|
||||
BuiltInTextStyle? textStyle,
|
||||
|
@ -0,0 +1,312 @@
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor/src/infra/flowy_svg.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
typedef TextStyleCustomizer = TextStyle Function(
|
||||
EditorState editorState, TextNode textNode);
|
||||
typedef PaddingCustomizer = EdgeInsets Function(
|
||||
EditorState editorState, TextNode textNode);
|
||||
typedef IconCustomizer = Widget Function(
|
||||
EditorState editorState, TextNode textNode);
|
||||
|
||||
class HeadingPluginStyle extends ThemeExtension<HeadingPluginStyle> {
|
||||
const HeadingPluginStyle({
|
||||
required this.textStyle,
|
||||
required this.padding,
|
||||
});
|
||||
|
||||
final TextStyleCustomizer textStyle;
|
||||
final PaddingCustomizer padding;
|
||||
|
||||
@override
|
||||
HeadingPluginStyle copyWith({
|
||||
TextStyleCustomizer? textStyle,
|
||||
PaddingCustomizer? padding,
|
||||
}) {
|
||||
return HeadingPluginStyle(
|
||||
textStyle: textStyle ?? this.textStyle,
|
||||
padding: padding ?? this.padding,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
ThemeExtension<HeadingPluginStyle> lerp(
|
||||
ThemeExtension<HeadingPluginStyle>? other, double t) {
|
||||
if (other is! HeadingPluginStyle) {
|
||||
return this;
|
||||
}
|
||||
return HeadingPluginStyle(
|
||||
textStyle: other.textStyle,
|
||||
padding: other.padding,
|
||||
);
|
||||
}
|
||||
|
||||
static final light = HeadingPluginStyle(
|
||||
padding: (_, __) => const EdgeInsets.symmetric(vertical: 8.0),
|
||||
textStyle: (editorState, textNode) {
|
||||
final headingToFontSize = {
|
||||
'h1': 32.0,
|
||||
'h2': 28.0,
|
||||
'h3': 24.0,
|
||||
'h4': 18.0,
|
||||
'h5': 18.0,
|
||||
'h6': 18.0,
|
||||
};
|
||||
final fontSize = headingToFontSize[textNode.attributes.heading] ?? 18.0;
|
||||
return TextStyle(
|
||||
fontSize: fontSize,
|
||||
fontWeight: FontWeight.bold,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
static final dark = light;
|
||||
}
|
||||
|
||||
class CheckboxPluginStyle extends ThemeExtension<CheckboxPluginStyle> {
|
||||
const CheckboxPluginStyle({
|
||||
required this.textStyle,
|
||||
required this.padding,
|
||||
required this.icon,
|
||||
});
|
||||
|
||||
final TextStyleCustomizer textStyle;
|
||||
final PaddingCustomizer padding;
|
||||
final IconCustomizer icon;
|
||||
|
||||
@override
|
||||
CheckboxPluginStyle copyWith({
|
||||
TextStyleCustomizer? textStyle,
|
||||
PaddingCustomizer? padding,
|
||||
IconCustomizer? icon,
|
||||
}) {
|
||||
return CheckboxPluginStyle(
|
||||
textStyle: textStyle ?? this.textStyle,
|
||||
padding: padding ?? this.padding,
|
||||
icon: icon ?? this.icon,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
ThemeExtension<CheckboxPluginStyle> lerp(
|
||||
ThemeExtension<CheckboxPluginStyle>? other, double t) {
|
||||
if (other is! CheckboxPluginStyle) {
|
||||
return this;
|
||||
}
|
||||
return CheckboxPluginStyle(
|
||||
textStyle: other.textStyle,
|
||||
padding: other.padding,
|
||||
icon: other.icon,
|
||||
);
|
||||
}
|
||||
|
||||
static final light = CheckboxPluginStyle(
|
||||
padding: (_, __) => const EdgeInsets.symmetric(vertical: 8.0),
|
||||
textStyle: (editorState, textNode) => const TextStyle(),
|
||||
icon: (editorState, textNode) {
|
||||
final isCheck = textNode.attributes.check;
|
||||
const iconSize = Size.square(20.0);
|
||||
const iconPadding = EdgeInsets.only(right: 5.0);
|
||||
return FlowySvg(
|
||||
width: iconSize.width,
|
||||
height: iconSize.height,
|
||||
padding: iconPadding,
|
||||
name: isCheck ? 'check' : 'uncheck',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
static final dark = light;
|
||||
}
|
||||
|
||||
class BulletedListPluginStyle extends ThemeExtension<BulletedListPluginStyle> {
|
||||
const BulletedListPluginStyle({
|
||||
required this.textStyle,
|
||||
required this.padding,
|
||||
required this.icon,
|
||||
});
|
||||
|
||||
final TextStyleCustomizer textStyle;
|
||||
final PaddingCustomizer padding;
|
||||
final IconCustomizer icon;
|
||||
|
||||
@override
|
||||
BulletedListPluginStyle copyWith({
|
||||
TextStyleCustomizer? textStyle,
|
||||
PaddingCustomizer? padding,
|
||||
IconCustomizer? icon,
|
||||
}) {
|
||||
return BulletedListPluginStyle(
|
||||
textStyle: textStyle ?? this.textStyle,
|
||||
padding: padding ?? this.padding,
|
||||
icon: icon ?? this.icon,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
ThemeExtension<BulletedListPluginStyle> lerp(
|
||||
ThemeExtension<BulletedListPluginStyle>? other, double t) {
|
||||
if (other is! BulletedListPluginStyle) {
|
||||
return this;
|
||||
}
|
||||
return BulletedListPluginStyle(
|
||||
textStyle: other.textStyle,
|
||||
padding: other.padding,
|
||||
icon: other.icon,
|
||||
);
|
||||
}
|
||||
|
||||
static final light = BulletedListPluginStyle(
|
||||
padding: (_, __) => const EdgeInsets.symmetric(vertical: 8.0),
|
||||
textStyle: (_, __) => const TextStyle(),
|
||||
icon: (_, __) {
|
||||
const iconSize = Size.square(20.0);
|
||||
const iconPadding = EdgeInsets.only(right: 5.0);
|
||||
return FlowySvg(
|
||||
width: iconSize.width,
|
||||
height: iconSize.height,
|
||||
padding: iconPadding,
|
||||
color: Colors.black,
|
||||
name: 'point',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
static final dark = light.copyWith(icon: (_, __) {
|
||||
const iconSize = Size.square(20.0);
|
||||
const iconPadding = EdgeInsets.only(right: 5.0);
|
||||
return FlowySvg(
|
||||
width: iconSize.width,
|
||||
height: iconSize.height,
|
||||
padding: iconPadding,
|
||||
color: Colors.white,
|
||||
name: 'point',
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
class NumberListPluginStyle extends ThemeExtension<NumberListPluginStyle> {
|
||||
const NumberListPluginStyle({
|
||||
required this.textStyle,
|
||||
required this.padding,
|
||||
required this.icon,
|
||||
});
|
||||
|
||||
final TextStyleCustomizer textStyle;
|
||||
final PaddingCustomizer padding;
|
||||
final IconCustomizer icon;
|
||||
|
||||
@override
|
||||
NumberListPluginStyle copyWith({
|
||||
TextStyleCustomizer? textStyle,
|
||||
PaddingCustomizer? padding,
|
||||
IconCustomizer? icon,
|
||||
}) {
|
||||
return NumberListPluginStyle(
|
||||
textStyle: textStyle ?? this.textStyle,
|
||||
padding: padding ?? this.padding,
|
||||
icon: icon ?? this.icon,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
ThemeExtension<NumberListPluginStyle> lerp(
|
||||
ThemeExtension<NumberListPluginStyle>? other,
|
||||
double t,
|
||||
) {
|
||||
if (other is! NumberListPluginStyle) {
|
||||
return this;
|
||||
}
|
||||
return NumberListPluginStyle(
|
||||
textStyle: other.textStyle,
|
||||
padding: other.padding,
|
||||
icon: other.icon,
|
||||
);
|
||||
}
|
||||
|
||||
static final light = NumberListPluginStyle(
|
||||
padding: (_, __) => const EdgeInsets.symmetric(vertical: 8.0),
|
||||
textStyle: (_, __) => const TextStyle(),
|
||||
icon: (_, textNode) {
|
||||
const iconPadding = EdgeInsets.only(left: 5.0, right: 5.0);
|
||||
return Container(
|
||||
padding: iconPadding,
|
||||
child: Text(
|
||||
'${textNode.attributes.number.toString()}.',
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
static final dark = light.copyWith(icon: (editorState, textNode) {
|
||||
const iconPadding = EdgeInsets.only(left: 5.0, right: 5.0);
|
||||
return Container(
|
||||
padding: iconPadding,
|
||||
child: Text(
|
||||
'${textNode.attributes.number.toString()}.',
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
class QuotedTextPluginStyle extends ThemeExtension<QuotedTextPluginStyle> {
|
||||
const QuotedTextPluginStyle({
|
||||
required this.textStyle,
|
||||
required this.padding,
|
||||
required this.icon,
|
||||
});
|
||||
|
||||
final TextStyleCustomizer textStyle;
|
||||
final PaddingCustomizer padding;
|
||||
final IconCustomizer icon;
|
||||
|
||||
@override
|
||||
QuotedTextPluginStyle copyWith({
|
||||
TextStyleCustomizer? textStyle,
|
||||
PaddingCustomizer? padding,
|
||||
IconCustomizer? icon,
|
||||
}) {
|
||||
return QuotedTextPluginStyle(
|
||||
textStyle: textStyle ?? this.textStyle,
|
||||
padding: padding ?? this.padding,
|
||||
icon: icon ?? this.icon,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
ThemeExtension<QuotedTextPluginStyle> lerp(
|
||||
ThemeExtension<QuotedTextPluginStyle>? other, double t) {
|
||||
if (other is! QuotedTextPluginStyle) {
|
||||
return this;
|
||||
}
|
||||
return QuotedTextPluginStyle(
|
||||
textStyle: other.textStyle,
|
||||
padding: other.padding,
|
||||
icon: other.icon,
|
||||
);
|
||||
}
|
||||
|
||||
static final light = QuotedTextPluginStyle(
|
||||
padding: (_, __) => const EdgeInsets.symmetric(vertical: 8.0),
|
||||
textStyle: (_, __) => const TextStyle(),
|
||||
icon: (_, __) {
|
||||
const iconSize = Size.square(20.0);
|
||||
const iconPadding = EdgeInsets.only(right: 5.0);
|
||||
return FlowySvg(
|
||||
width: iconSize.width,
|
||||
padding: iconPadding,
|
||||
name: 'quote',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
static final dark = light;
|
||||
}
|
Loading…
Reference in New Issue
Block a user