Skip to content

Commit bb3771a

Browse files
authored
chore: bump version 1.1.0 (AppFlowy-IO#284)
1 parent 2b2bce4 commit bb3771a

File tree

7 files changed

+100
-129
lines changed

7 files changed

+100
-129
lines changed

CHANGELOG.md

+17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
## 1.1.0
2+
* feat: support IME by @LucasXu0 in ([#253](https://github.com/AppFlowy-IO/appflowy-editor/pull/253))
3+
* feat: support text and background color in mobile toolbar by @hyj1204 in ([#233](https://github.com/AppFlowy-IO/appflowy-editor/pull/233))
4+
* feat: support broadcast the transaction before applying it by @LucasXu0 in ([#226](https://github.com/AppFlowy-IO/appflowy-editor/pull/226))
5+
* feat: support customizing text attribute key and rendering by @LucasXu0 in ([#244](https://github.com/AppFlowy-IO/appflowy-editor/pull/244))
6+
* feat: support customizing the block icon widget by @LucasXu0 in ([#274](https://github.com/AppFlowy-IO/appflowy-editor/pull/274))
7+
* feat: support uploading images from local files by @Mukund-Tandon in ([#232](https://github.com/AppFlowy-IO/appflowy-editor/pull/232))
8+
* feat: add underline syntax parser by @vedant-pandey in ([#256](https://github.com/AppFlowy-IO/appflowy-editor/pull/256))
9+
* feat: migrate the delta encoder by @LucasXu0 in ([#277](https://github.com/AppFlowy-IO/appflowy-editor/pull/277))
10+
* feat: support divider toolbar item in mobile by @hyj1204 in ([#281](https://github.com/AppFlowy-IO/appflowy-editor/pull/281))
11+
* feat: customized color options by @hyj1204 in ([#270](https://github.com/AppFlowy-IO/appflowy-editor/pull/270))
12+
* feat: support exiting link menu by ESC by @vincenzoursano in ([#124](https://github.com/AppFlowy-IO/appflowy-editor/pull/124))
13+
* fix: focus node doesn't work on mobile by @LucasXu0 in ([#227](https://github.com/AppFlowy-IO/appflowy-editor/pull/227))
14+
* fix: the cursor is inaccuracy when the text contains special emoji by @LucasXu0 in ([#238](https://github.com/AppFlowy-IO/appflowy-editor/pull/238))
15+
* fix: extend attribute keys shouldn't be sliced by @LucasXu0 in ([#248](https://github.com/AppFlowy-IO/appflowy-editor/pull/248))
16+
* fix: keep keyboard appearance as same brightness as system theme by @hyj1204 in ([#264](https://github.com/AppFlowy-IO/appflowy-editor/pull/264))
17+
118
## 1.0.4
219
* feat: support mobile drag selection by @LucasXu0 in ([#209](https://github.com/AppFlowy-IO/appflowy-editor/pull/209))
320
* feat: support customizing number of the numbered list by @LucasXu0 in ([#219](https://github.com/AppFlowy-IO/appflowy-editor/pull/219))

README.md

+21-21
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ and the Flutter guide for
3333
## Key Features
3434

3535
* Build rich, intuitive editors
36-
* Design and modify an ever expanding list of customizable features including
37-
* components (such as form input controls, numbered lists, and rich text widgets)
36+
* Design and modify an ever-expanding list of customizable features including
37+
* block components (such as form input controls, numbered lists, and rich text widgets)
3838
* shortcut events
3939
* themes
40-
* menu options (**coming soon!**)
41-
* [Test-coverage](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/documentation/testing.md) and ongoing maintenance by AppFlowy's core team and community of more than 1,000 builders
40+
* selection menu
41+
* toolbar menu
42+
* [Test Coverage](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/documentation/testing.md) and ongoing maintenance by AppFlowy's core team and community of more than 1,000 builders
4243

4344
## Getting Started
4445

@@ -54,28 +55,28 @@ flutter pub get
5455
Start by creating a new empty AppFlowyEditor object.
5556

5657
```dart
57-
final editorState = EditorState.empty(); // an empty state
58-
final editor = AppFlowyEditor(
59-
editorState: editorState,
58+
final editorState = EditorState.blank(withInitialText: true); // with an empty paragraph
59+
final editor = AppFlowyEditor.standard(
60+
editorState: editorState,
6061
);
6162
```
6263

6364
You can also create an editor from a JSON object in order to configure your initial state. Or you can [create an editor from Markdown or Quill Delta](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/documentation/importing.md).
6465

6566
```dart
66-
final json = ...;
67-
final editorState = EditorState(Document.fromJson(data));
68-
final editor = AppFlowyEditor(
69-
editorState: editorState,
67+
final json = jsonDecode('YOUR INPUT JSON STRING');
68+
final editorState = EditorState(document: Document.fromJson(json));
69+
final editor = AppFlowyEditor.standard(
70+
editorState: editorState,
7071
);
7172
```
7273

7374
> Note: The parameters `localizationsDelegates` need to be assigned in MaterialApp widget
7475
```dart
7576
MaterialApp(
76-
localizationsDelegates: const [
77-
AppFlowyEditorLocalizations.delegate,
78-
],
77+
localizationsDelegates: const [
78+
AppFlowyEditorLocalizations.delegate,
79+
],
7980
);
8081
```
8182

@@ -89,25 +90,24 @@ flutter run
8990

9091
## Customizing Your Editor
9192

92-
### Customizing Components
93+
### Customizing Block Components
9394

9495
Please refer to our documentation on customizing AppFlowy for a detailed discussion about [customizing components](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/documentation/customizing.md#customize-a-component).
9596

9697
Below are some examples of component customizations:
9798

98-
* [Checkbox Text](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/render/rich_text/checkbox_text.dart) demonstrates how to extend new styles based on existing rich text components
99-
* [Image](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/example/lib/plugin/network_image_node_widget.dart) demonstrates how to extend a new node and render it
100-
* See further examples of [rich-text plugins](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/render/rich_text)
99+
* [Todo List Block Component](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/editor/block_component/todo_list_block_component/todo_list_block_component.dart) demonstrates how to extend new styles based on existing rich text components
100+
* [Divider Block Component](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/editor/block_component/divider_block_component/divider_block_component.dart) demonstrates how to extend a new block component and render it
101+
* See further examples of [Rich-Text Plugins](https://github.com/AppFlowy-IO/appflowy-editor/tree/main/lib/src/editor/block_component)
101102

102103
### Customizing Shortcut Events
103104

104105
Please refer to our documentation on customizing AppFlowy for a detailed discussion about [customizing shortcut events](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/documentation/customizing.md#customize-a-shortcut-event).
105106

106107
Below are some examples of shortcut event customizations:
107108

108-
* [BIUS](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/service/internal_key_event_handlers/format_style_handler.dart) demonstrates how to make text bold/italic/underline/strikethrough through shortcut keys
109-
* [Paste HTML](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart) gives you an idea on how to handle pasted styles through shortcut keys
110-
* Need more examples? Check out [Internal key event handlers](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/service/internal_key_event_handlers)
109+
* [BIUS](https://github.com/AppFlowy-IO/appflowy-editor/tree/main/lib/src/editor/editor_component/service/shortcuts/character_shortcut_events/format_single_character) demonstrates how to make text bold/italic/underline/strikethrough through shortcut keys
110+
* Need more examples? Check out [shortcuts](https://github.com/AppFlowy-IO/appflowy-editor/tree/main/lib/src/editor/editor_component/service/shortcuts)
111111

112112
## Glossary
113113
Please refer to the API documentation.

documentation/customizing.md

+53-102
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Customizing Editor Features
22

3-
Note: `AppFlowyEditor` has since been depreciated and `AppFlowyEditor.standard` or `AppFlowyEditor.custom` should be used instead. To recreate the examples below, you would use `AppFlowyEditor.custom`.
4-
53
## Customizing a Shortcut Event
64

75
We will use a simple example to illustrate how to quickly add a shortcut event.
@@ -11,137 +9,90 @@ In this example, text that starts and ends with an underscore ( \_ ) character w
119
Let's start with a blank document:
1210

1311
```dart
14-
@override
15-
Widget build(BuildContext context) {
16-
return Scaffold(
17-
body: Container(
18-
alignment: Alignment.topCenter,
19-
child: AppFlowyEditor(
20-
editorState: EditorState.empty(),
21-
shortcutEvents: const [],
22-
customBuilders: const {},
23-
),
24-
),
25-
);
12+
import 'package:appflowy_editor/appflowy_editor.dart';
13+
import 'package:flutter/material.dart';
14+
15+
class UnderScoreToItalic extends StatelessWidget {
16+
const UnderScoreToItalic({super.key});
17+
18+
@override
19+
Widget build(BuildContext context) {
20+
return AppFlowyEditor.custom(
21+
editorState: EditorState.blank(withInitialText: true),
22+
blockComponentBuilders: standardBlockComponentBuilderMap,
23+
characterShortcutEvents: const [],
24+
);
25+
}
2626
}
2727
```
2828

2929
At this point, nothing magic will happen after typing `_xxx_`.
3030

3131
![Before](./images/customize_a_shortcut_event_before.gif)
3232

33-
To implement our shortcut event we will create a `ShortcutEvent` instance to handle an underscore input.
33+
To implement our shortcut event we will create a `CharacterShortcutEvent` instance to handle an underscore input.
3434

35-
We need to define `key` and `command` in a ShortCutEvent object to customize hotkeys. We recommend using the description of your event as a key. For example, if the underscore `_` is defined to make text italic, the key can be 'Underscore to italic'.
35+
We need to define `key` and `character` in a `CharacterShortcutEvent` object to customize hotkeys. We recommend using the description of your event as a key. For example, if the underscore `_` is defined to make text italic, the key can be 'Underscore to italic'.
3636

37-
> The command, made up of a single keyword such as `underscore` or a combination of keywords using the `+` sign in between to concatenate, is a condition that triggers a user-defined function. To see which keywords are available to define a command, please refer to [key_mapping.dart](../lib/src/service/shortcut_event/key_mapping.dart).
38-
> If more than one commands trigger the same handler, then we use ',' to split them. For example, using CTRL and A or CMD and A to 'select all', we describe it as `cmd+a,ctrl+a`(case-insensitive).
3937

4038
```dart
4139
import 'package:appflowy_editor/appflowy_editor.dart';
4240
import 'package:flutter/material.dart';
4341
44-
ShortcutEvent underscoreToItalicEvent = ShortcutEvent(
42+
// ...
43+
44+
CharacterShortcutEvent underscoreToItalicEvent = CharacterShortcutEvent(
4545
key: 'Underscore to italic',
46-
command: 'shift+underscore',
47-
handler: _underscoreToItalicHandler,
46+
character: '_',
47+
handler: (editorState) async => handleFormatByWrappingWithSingleCharacter(
48+
editorState: editorState,
49+
character: '_',
50+
formatStyle: FormatStyleByWrappingWithSingleChar.italic,
51+
),
4852
);
49-
50-
ShortcutEventHandler _underscoreToItalicHandler = (editorState, event) {
51-
52-
};
5353
```
5454

55-
Then, we need to determine if the currently selected node is a `TextNode` and if the selection is collapsed.
56-
57-
If so, we will continue.
55+
Now our 'underscore handler' function is done and the only task left is to inject it into the AppFlowyEditor.
5856

5957
```dart
60-
// ...
61-
ShortcutEventHandler _underscoreToItalicHandler = (editorState, event) {
62-
// Obtain the selection and selected nodes of the current document through the 'selectionService'
63-
// to determine whether the selection is collapsed and whether the selected node is a text node.
64-
final selectionService = editorState.service.selectionService;
65-
final selection = selectionService.currentSelection.value;
66-
final textNodes = selectionService.currentSelectedNodes.whereType<TextNode>();
67-
if (selection == null || !selection.isSingle || textNodes.length != 1) {
68-
return KeyEventResult.ignored;
69-
}
70-
```
71-
72-
Now, we deal with handling the underscore.
73-
74-
Look for the position of the previous underscore and
75-
1. if one is _not_ found, return without doing anything.
76-
2. if one is found, the text enclosed within the two underscores will be formatted to display in italics.
58+
import 'package:appflowy_editor/appflowy_editor.dart';
59+
import 'package:flutter/material.dart';
7760
78-
```dart
79-
// ...
80-
ShortcutEventHandler _underscoreToItalicHandler = (editorState, event) {
81-
// ...
82-
83-
final textNode = textNodes.first;
84-
final text = textNode.toRawString();
85-
// Determine if an 'underscore' already exists in the text node and only once.
86-
final firstUnderscore = text.indexOf('_');
87-
final lastUnderscore = text.lastIndexOf('_');
88-
if (firstUnderscore == -1 ||
89-
firstUnderscore != lastUnderscore ||
90-
firstUnderscore == selection.start.offset - 1) {
91-
return KeyEventResult.ignored;
92-
}
61+
class UnderScoreToItalic extends StatelessWidget {
62+
const UnderScoreToItalic({super.key});
9363
94-
// Delete the previous 'underscore',
95-
// update the style of the text surrounded by the two underscores to 'italic',
96-
// and update the cursor position.
97-
final transaction = editorState.transaction
98-
..deleteText(textNode, firstUnderscore, 1)
99-
..formatText(
100-
textNode,
101-
firstUnderscore,
102-
selection.end.offset - firstUnderscore - 1,
103-
{
104-
BuiltInAttributeKey.italic: true,
105-
},
106-
)
107-
..afterSelection = Selection.collapsed(
108-
Position(
109-
path: textNode.path,
110-
offset: selection.end.offset - 1,
111-
),
64+
@override
65+
Widget build(BuildContext context) {
66+
return AppFlowyEditor.custom(
67+
editorState: EditorState.blank(withInitialText: true),
68+
blockComponentBuilders: standardBlockComponentBuilderMap,
69+
characterShortcutEvents: [
70+
underScoreToItalicEvent,
71+
],
11272
);
113-
editorState.apply(transaction);
114-
115-
return KeyEventResult.handled;
116-
};
117-
```
118-
119-
Now our 'underscore handler' function is done and the only task left is to inject it into the AppFlowyEditor.
120-
121-
```dart
122-
@override
123-
Widget build(BuildContext context) {
124-
return Scaffold(
125-
body: Container(
126-
alignment: Alignment.topCenter,
127-
child: AppFlowyEditor(
128-
editorState: EditorState.empty(),
129-
customBuilders: const {},
130-
shortcutEvents: [
131-
underscoreToItalic,
132-
],
133-
),
134-
),
135-
);
73+
}
13674
}
75+
76+
CharacterShortcutEvent underScoreToItalicEvent = CharacterShortcutEvent(
77+
key: 'Underscore to italic',
78+
character: '_',
79+
handler: (editorState) async => handleFormatByWrappingWithSingleCharacter(
80+
editorState: editorState,
81+
character: '_',
82+
formatStyle: FormatStyleByWrappingWithSingleChar.italic,
83+
),
84+
);
13785
```
13886

13987
![After](./images/customize_a_shortcut_event_after.gif)
14088

141-
Check out the [complete code](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart) file of this example.
89+
Check out the [complete code](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/example/lib/samples/underscore_to_italic.dart) file of this example.
14290

14391

14492
## Customizing a Component
93+
94+
> ⚠️ Notes: The content below is outdated.
95+
14596
We will use a simple example to show how to quickly add a custom component.
14697

14798
In this example we will render an image from the network.

lib/src/editor/editor_component/service/shortcuts/character_shortcut_events/format_single_character/format_single_character.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ bool handleFormatByWrappingWithSingleCharacter({
7878
// if the text is already formatted, we should remove the format.
7979
final sliced = delta.slice(
8080
headCharIndex + 1,
81-
selection.end.offset - headCharIndex - 1,
81+
selection.end.offset,
8282
);
8383
final result = sliced.everyAttributes((element) => element[style] == true);
8484

pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: appflowy_editor
22
description: A highly customizable rich-text editor for Flutter. The AppFlowy Editor project for AppFlowy and beyond.
3-
version: 1.0.4
3+
version: 1.1.0
44
homepage: https://github.com/AppFlowy-IO/appflowy-editor
55

66
platforms:

test/mobile/toolbar/mobile/toolbar_items/divider_mobile_toolbar_item_test.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import '../../../../new/infra/testable_editor.dart';
55
import '../test_helpers/mobile_app_with_toolbar_widget.dart';
66

77
void main() {
8-
group('dividerMobileToolbarItem\n', () {
8+
group('dividerMobileToolbarItem', () {
99
testWidgets(
1010
'If the user tries to insert a divider while some text is selected, no action should be taken',
1111
(WidgetTester tester) async {

test/new/service/shortcuts/character_shortcut_events/format_by_wrapping_with_single_char/format_italic_test.dart

+6-3
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,12 @@ void main() async {
150150

151151
expect(result, true);
152152
final after = editorState.getNodeAtPath([0])!;
153-
expect(after.delta!.toPlainText(), '$text1$text2');
154-
expect(after.delta!.toList()[0].attributes, null);
155-
expect(after.delta!.toList()[1].attributes, {'italic': true});
153+
final afterDelta = after.delta!;
154+
expect(afterDelta.toPlainText(), '$text1$text2');
155+
final deltaList = afterDelta.toList();
156+
expect(deltaList.length, 2);
157+
expect(deltaList[0].attributes, null);
158+
expect(deltaList[1].attributes, {'italic': true});
156159
});
157160

158161
// Before

0 commit comments

Comments
 (0)