mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: add bulleted-list and number-list
This commit is contained in:
parent
734b642fcc
commit
51bc965029
frontend/app_flowy/packages/flowy_editor
example/assets
lib
@ -111,8 +111,8 @@
|
||||
{ "insert": " and just typing." }
|
||||
],
|
||||
"attributes": {
|
||||
"list": "todo",
|
||||
"todo": true
|
||||
"subtype": "checkbox",
|
||||
"checkbox": true
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -130,8 +130,8 @@
|
||||
}
|
||||
],
|
||||
"attributes": {
|
||||
"list": "todo",
|
||||
"todo": true
|
||||
"subtype": "checkbox",
|
||||
"checkbox": true
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -146,8 +146,8 @@
|
||||
{ "insert": "." }
|
||||
],
|
||||
"attributes": {
|
||||
"list": "todo",
|
||||
"todo": true
|
||||
"subtype": "checkbox",
|
||||
"checkbox": true
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -170,7 +170,7 @@
|
||||
}
|
||||
],
|
||||
"attributes": {
|
||||
"list": "bullet"
|
||||
"subtype": "bullet-list"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -181,7 +181,7 @@
|
||||
}
|
||||
],
|
||||
"attributes": {
|
||||
"list": "bullet"
|
||||
"subtype": "bullet-list"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -192,7 +192,7 @@
|
||||
}
|
||||
],
|
||||
"attributes": {
|
||||
"list": "bullet"
|
||||
"subtype": "bullet-list"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -225,6 +225,7 @@
|
||||
}
|
||||
],
|
||||
"attributes": {
|
||||
"subtype": "number-list",
|
||||
"number": 1
|
||||
}
|
||||
},
|
||||
@ -236,6 +237,7 @@
|
||||
}
|
||||
],
|
||||
"attributes": {
|
||||
"subtype": "number-list",
|
||||
"number": 2
|
||||
}
|
||||
},
|
||||
@ -247,6 +249,7 @@
|
||||
}
|
||||
],
|
||||
"attributes": {
|
||||
"subtype": "number-list",
|
||||
"number": 3
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
import 'dart:async';
|
||||
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/flowy_rich_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/service/service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@ -47,6 +49,10 @@ class EditorState {
|
||||
renderPlugins.register('text', RichTextNodeWidgetBuilder.create);
|
||||
renderPlugins.register('text/checkbox', CheckboxNodeWidgetBuilder.create);
|
||||
renderPlugins.register('text/heading', HeadingTextNodeWidgetBuilder.create);
|
||||
renderPlugins.register(
|
||||
'text/bullet-list', BulletedListTextNodeWidgetBuilder.create);
|
||||
renderPlugins.register(
|
||||
'text/number-list', NumberListTextNodeWidgetBuilder.create);
|
||||
undoManager.state = this;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,73 @@
|
||||
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/node_widget_builder.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/selection/selectable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class BulletedListTextNodeWidgetBuilder extends NodeWidgetBuilder {
|
||||
BulletedListTextNodeWidgetBuilder.create({
|
||||
required super.editorState,
|
||||
required super.node,
|
||||
required super.key,
|
||||
}) : super.create();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BulletedListTextNodeWidget(
|
||||
key: key,
|
||||
textNode: node as TextNode,
|
||||
editorState: editorState,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class BulletedListTextNodeWidget extends StatefulWidget {
|
||||
const BulletedListTextNodeWidget({
|
||||
Key? key,
|
||||
required this.textNode,
|
||||
required this.editorState,
|
||||
}) : super(key: key);
|
||||
|
||||
final TextNode textNode;
|
||||
final EditorState editorState;
|
||||
|
||||
@override
|
||||
State<BulletedListTextNodeWidget> createState() =>
|
||||
_BulletedListTextNodeWidgetState();
|
||||
}
|
||||
|
||||
// customize
|
||||
|
||||
class _BulletedListTextNodeWidgetState extends State<BulletedListTextNodeWidget>
|
||||
with Selectable, DefaultSelectable {
|
||||
final _richTextKey = GlobalKey(debugLabel: 'heading_text');
|
||||
final leftPadding = 20.0;
|
||||
|
||||
@override
|
||||
Selectable<StatefulWidget> get forward =>
|
||||
_richTextKey.currentState as Selectable;
|
||||
|
||||
@override
|
||||
Offset get baseOffset {
|
||||
return Offset(leftPadding, 0);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
const FlowySvg(
|
||||
name: 'point',
|
||||
),
|
||||
FlowyRichText(
|
||||
key: _richTextKey,
|
||||
textNode: widget.textNode,
|
||||
editorState: widget.editorState,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -68,15 +68,15 @@ class _FlowyRichTextState extends State<FlowyRichText> with Selectable {
|
||||
final attributes = _textNode.attributes;
|
||||
// TODO: use factory method ??
|
||||
if (attributes.list == 'todo') {
|
||||
return _buildTodoListRichText(context);
|
||||
// return _buildTodoListRichText(context);
|
||||
} else if (attributes.list == 'bullet') {
|
||||
return _buildBulletedListRichText(context);
|
||||
// return _buildBulletedListRichText(context);
|
||||
} else if (attributes.quote == true) {
|
||||
return _buildQuotedRichText(context);
|
||||
} else if (attributes.heading != null) {
|
||||
// return _buildHeadingRichText(context);
|
||||
} else if (attributes.number != null) {
|
||||
return _buildNumberListRichText(context);
|
||||
// return _buildNumberListRichText(context);
|
||||
}
|
||||
return _buildRichText(context);
|
||||
}
|
||||
|
@ -1,13 +1,10 @@
|
||||
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/node_widget_builder.dart';
|
||||
import 'package:flowy_editor/render/render_plugins.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/extensions/object_extensions.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class HeadingTextNodeWidgetBuilder extends NodeWidgetBuilder {
|
||||
|
@ -0,0 +1,74 @@
|
||||
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/node_widget_builder.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:flutter/material.dart';
|
||||
|
||||
class NumberListTextNodeWidgetBuilder extends NodeWidgetBuilder {
|
||||
NumberListTextNodeWidgetBuilder.create({
|
||||
required super.editorState,
|
||||
required super.node,
|
||||
required super.key,
|
||||
}) : super.create();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return NumberListTextNodeWidget(
|
||||
key: key,
|
||||
textNode: node as TextNode,
|
||||
editorState: editorState,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NumberListTextNodeWidget extends StatefulWidget {
|
||||
const NumberListTextNodeWidget({
|
||||
Key? key,
|
||||
required this.textNode,
|
||||
required this.editorState,
|
||||
}) : super(key: key);
|
||||
|
||||
final TextNode textNode;
|
||||
final EditorState editorState;
|
||||
|
||||
@override
|
||||
State<NumberListTextNodeWidget> createState() =>
|
||||
_NumberListTextNodeWidgetState();
|
||||
}
|
||||
|
||||
// customize
|
||||
|
||||
class _NumberListTextNodeWidgetState extends State<NumberListTextNodeWidget>
|
||||
with Selectable, DefaultSelectable {
|
||||
final _richTextKey = GlobalKey(debugLabel: 'heading_text');
|
||||
final leftPadding = 20.0;
|
||||
|
||||
@override
|
||||
Selectable<StatefulWidget> get forward =>
|
||||
_richTextKey.currentState as Selectable;
|
||||
|
||||
@override
|
||||
Offset get baseOffset {
|
||||
return Offset(leftPadding, 0);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
FlowySvg(
|
||||
number: widget.textNode.attributes.number,
|
||||
),
|
||||
FlowyRichText(
|
||||
key: _richTextKey,
|
||||
textNode: widget.textNode,
|
||||
editorState: widget.editorState,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user