mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: add heading widget to example
This commit is contained in:
parent
4422d2b4d2
commit
fef9e20e46
@ -12,50 +12,65 @@
|
||||
{
|
||||
"type": "text",
|
||||
"delta": [
|
||||
{ "insert": "With " },
|
||||
{ "insert": "AppFlowy", "attributes": { "href": "https://www.appflowy.io/" } },
|
||||
{ "insert": ", you can build detailed lists of to-do’s for different projects while tracking the status of each one" }
|
||||
{ "insert": "👋 Welcome to AppFlowy!", "attributes": { "href": "https://www.appflowy.io/", "heading": "h1" } }
|
||||
],
|
||||
"attributes": {
|
||||
"subtype": "with-heading",
|
||||
"heading": "h1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"delta": [
|
||||
{ "insert": "Here are the basics", "attributes": { "heading": "h2" } }
|
||||
],
|
||||
"attributes": {
|
||||
"subtype": "with-heading",
|
||||
"heading": "h2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"delta": [
|
||||
{ "insert": "Click anywhere and just start typing." }
|
||||
],
|
||||
"attributes": {
|
||||
"subtype": "with-checkbox",
|
||||
"checkbox": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"delta": [
|
||||
{ "insert": "Highlight", "attributes": { "highlight": "0xFFFFFF00" } },
|
||||
{ "insert": " Click anywhere and just start typing" },
|
||||
{ "insert": " any text, and use the menu at the bottom to " },
|
||||
{ "insert": "style", "attributes": { "italic": true } },
|
||||
{ "insert": " your ", "attributes": { "bold": true } },
|
||||
{ "insert": "writing", "attributes": { "underline": true } },
|
||||
{ "insert": " howeverv you like.", "attributes": { "strikethrough": true } }
|
||||
],
|
||||
"attributes": {
|
||||
"subtype": "with-checkbox",
|
||||
"font-size": 30,
|
||||
"checkbox": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"delta": [
|
||||
{ "insert": "You can " },
|
||||
{ "insert": "host", "attributes": { "italic": true } },
|
||||
{ "insert": " " },
|
||||
{ "insert": "AppFlowy", "attributes": { "bold": true } },
|
||||
{ "insert": " " },
|
||||
{ "insert": "wherever you want", "attributes": { "underline": true }},
|
||||
{ "insert": "; no vendor lock-in." }
|
||||
{ "insert": "Have a question? ", "attributes": { "heading": "h2" } }
|
||||
],
|
||||
"attributes": {
|
||||
"subtype": "with-checkbox",
|
||||
"text-type": "heading1",
|
||||
"font-size": 30,
|
||||
"checkbox": false
|
||||
"attributes": {
|
||||
"subtype": "with-heading",
|
||||
"heading": "h2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"delta": [{ "insert": "Design and modify AppFlowy your way with an open core codebase." }],
|
||||
"attributes": {
|
||||
"text-type": "heading1",
|
||||
"font-size": 30
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"delta": [{ "insert": "AppFlowy is built with Flutter and Rust. What does this mean? Faster development, better native experience, and more reliable performance." }],
|
||||
"attributes": {
|
||||
"text-type": "heading1",
|
||||
"font-size": 30,
|
||||
"content": "dddddddddddddddddddd"
|
||||
}
|
||||
"delta": [
|
||||
{ "insert": "Click the '?' at the bottom right for help and support."}
|
||||
],
|
||||
"attributes": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:example/plugin/document_node_widget.dart';
|
||||
import 'package:example/plugin/text_with_heading_node_widget.dart';
|
||||
import 'package:example/plugin/image_node_widget.dart';
|
||||
import 'package:example/plugin/text_node_widget.dart';
|
||||
import 'package:example/plugin/text_with_check_box_node_widget.dart';
|
||||
@ -66,7 +67,8 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
..register('editor', EditorNodeWidgetBuilder.create)
|
||||
..register('text', TextNodeBuilder.create)
|
||||
..register('image', ImageNodeBuilder.create)
|
||||
..register('text/with-checkbox', TextWithCheckBoxNodeBuilder.create);
|
||||
..register('text/with-checkbox', TextWithCheckBoxNodeBuilder.create)
|
||||
..register('text/with-heading', TextWithHeadingNodeBuilder.create);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -30,17 +30,7 @@ class _ImageNodeWidget extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
child: _build(context),
|
||||
onTap: () {
|
||||
TransactionBuilder(editorState)
|
||||
..updateNode(node, {
|
||||
'image_src':
|
||||
"https://images.pexels.com/photos/9995076/pexels-photo-9995076.png?cs=srgb&dl=pexels-temmuz-uzun-9995076.jpg&fm=jpg&w=640&h=400"
|
||||
})
|
||||
..commit();
|
||||
},
|
||||
);
|
||||
return _build(context);
|
||||
}
|
||||
|
||||
Widget _build(BuildContext context) {
|
||||
|
@ -158,6 +158,8 @@ TextSpan _textInsertToTextSpan(TextInsert textInsert) {
|
||||
TextDecoration? decoration;
|
||||
GestureRecognizer? gestureRecognizer;
|
||||
Color? color;
|
||||
Color highLightColor = Colors.transparent;
|
||||
double fontSize = 16.0;
|
||||
final attributes = textInsert.attributes;
|
||||
if (attributes?['bold'] == true) {
|
||||
fontWeight = FontWeight.bold;
|
||||
@ -168,6 +170,12 @@ TextSpan _textInsertToTextSpan(TextInsert textInsert) {
|
||||
if (attributes?['underline'] == true) {
|
||||
decoration = TextDecoration.underline;
|
||||
}
|
||||
if (attributes?['strikethrough'] == true) {
|
||||
decoration = TextDecoration.lineThrough;
|
||||
}
|
||||
if (attributes?['highlight'] is String) {
|
||||
highLightColor = Color(int.parse(attributes!['highlight']));
|
||||
}
|
||||
if (attributes?['href'] is String) {
|
||||
color = const Color.fromARGB(255, 55, 120, 245);
|
||||
decoration = TextDecoration.underline;
|
||||
@ -176,6 +184,16 @@ TextSpan _textInsertToTextSpan(TextInsert textInsert) {
|
||||
launchUrlString(attributes?['href']);
|
||||
};
|
||||
}
|
||||
final heading = attributes?['heading'] as String?;
|
||||
if (heading != null) {
|
||||
// TODO: make it better
|
||||
if (heading == 'h1') {
|
||||
fontSize = 30.0;
|
||||
} else if (heading == 'h2') {
|
||||
fontSize = 20.0;
|
||||
}
|
||||
fontWeight = FontWeight.bold;
|
||||
}
|
||||
return TextSpan(
|
||||
text: textInsert.content,
|
||||
style: TextStyle(
|
||||
@ -183,7 +201,8 @@ TextSpan _textInsertToTextSpan(TextInsert textInsert) {
|
||||
fontStyle: fontStyle,
|
||||
decoration: decoration,
|
||||
color: color,
|
||||
fontSize: 16,
|
||||
fontSize: fontSize,
|
||||
backgroundColor: highLightColor,
|
||||
),
|
||||
recognizer: gestureRecognizer,
|
||||
);
|
||||
|
@ -0,0 +1,45 @@
|
||||
import 'package:flowy_editor/flowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TextWithHeadingNodeBuilder extends NodeWidgetBuilder {
|
||||
TextWithHeadingNodeBuilder.create({
|
||||
required super.editorState,
|
||||
required super.node,
|
||||
}) : super.create() {
|
||||
nodeValidator = (node) => node.attributes.containsKey('heading');
|
||||
}
|
||||
|
||||
String get heading => node.attributes['heading'] as String;
|
||||
Widget buildPadding() {
|
||||
if (heading == 'h1') {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
);
|
||||
} else if (heading == 'h1') {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
);
|
||||
}
|
||||
return const Padding(
|
||||
padding: EdgeInsets.only(top: 0),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext buildContext) {
|
||||
return Column(
|
||||
children: [
|
||||
buildPadding(),
|
||||
renderPlugins.buildWidget(
|
||||
context: NodeWidgetContext(
|
||||
buildContext: buildContext,
|
||||
node: node,
|
||||
editorState: editorState,
|
||||
),
|
||||
withSubtype: false,
|
||||
),
|
||||
buildPadding(),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user