chore: bump version 1.1.0 (#284)
This commit is contained in:
parent
2b2bce4f3c
commit
bb3771af63
7 changed files with 100 additions and 129 deletions
17
CHANGELOG.md
17
CHANGELOG.md
|
|
@ -1,3 +1,20 @@
|
|||
## 1.1.0
|
||||
* feat: support IME by @LucasXu0 in ([#253](https://github.com/AppFlowy-IO/appflowy-editor/pull/253))
|
||||
* feat: support text and background color in mobile toolbar by @hyj1204 in ([#233](https://github.com/AppFlowy-IO/appflowy-editor/pull/233))
|
||||
* feat: support broadcast the transaction before applying it by @LucasXu0 in ([#226](https://github.com/AppFlowy-IO/appflowy-editor/pull/226))
|
||||
* feat: support customizing text attribute key and rendering by @LucasXu0 in ([#244](https://github.com/AppFlowy-IO/appflowy-editor/pull/244))
|
||||
* feat: support customizing the block icon widget by @LucasXu0 in ([#274](https://github.com/AppFlowy-IO/appflowy-editor/pull/274))
|
||||
* feat: support uploading images from local files by @Mukund-Tandon in ([#232](https://github.com/AppFlowy-IO/appflowy-editor/pull/232))
|
||||
* feat: add underline syntax parser by @vedant-pandey in ([#256](https://github.com/AppFlowy-IO/appflowy-editor/pull/256))
|
||||
* feat: migrate the delta encoder by @LucasXu0 in ([#277](https://github.com/AppFlowy-IO/appflowy-editor/pull/277))
|
||||
* feat: support divider toolbar item in mobile by @hyj1204 in ([#281](https://github.com/AppFlowy-IO/appflowy-editor/pull/281))
|
||||
* feat: customized color options by @hyj1204 in ([#270](https://github.com/AppFlowy-IO/appflowy-editor/pull/270))
|
||||
* feat: support exiting link menu by ESC by @vincenzoursano in ([#124](https://github.com/AppFlowy-IO/appflowy-editor/pull/124))
|
||||
* fix: focus node doesn't work on mobile by @LucasXu0 in ([#227](https://github.com/AppFlowy-IO/appflowy-editor/pull/227))
|
||||
* fix: the cursor is inaccuracy when the text contains special emoji by @LucasXu0 in ([#238](https://github.com/AppFlowy-IO/appflowy-editor/pull/238))
|
||||
* fix: extend attribute keys shouldn't be sliced by @LucasXu0 in ([#248](https://github.com/AppFlowy-IO/appflowy-editor/pull/248))
|
||||
* fix: keep keyboard appearance as same brightness as system theme by @hyj1204 in ([#264](https://github.com/AppFlowy-IO/appflowy-editor/pull/264))
|
||||
|
||||
## 1.0.4
|
||||
* feat: support mobile drag selection by @LucasXu0 in ([#209](https://github.com/AppFlowy-IO/appflowy-editor/pull/209))
|
||||
* feat: support customizing number of the numbered list by @LucasXu0 in ([#219](https://github.com/AppFlowy-IO/appflowy-editor/pull/219))
|
||||
|
|
|
|||
42
README.md
42
README.md
|
|
@ -33,12 +33,13 @@ and the Flutter guide for
|
|||
## Key Features
|
||||
|
||||
* Build rich, intuitive editors
|
||||
* Design and modify an ever expanding list of customizable features including
|
||||
* components (such as form input controls, numbered lists, and rich text widgets)
|
||||
* Design and modify an ever-expanding list of customizable features including
|
||||
* block components (such as form input controls, numbered lists, and rich text widgets)
|
||||
* shortcut events
|
||||
* themes
|
||||
* menu options (**coming soon!**)
|
||||
* [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
|
||||
* selection menu
|
||||
* toolbar menu
|
||||
* [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
|
||||
|
||||
## Getting Started
|
||||
|
||||
|
|
@ -54,28 +55,28 @@ flutter pub get
|
|||
Start by creating a new empty AppFlowyEditor object.
|
||||
|
||||
```dart
|
||||
final editorState = EditorState.empty(); // an empty state
|
||||
final editor = AppFlowyEditor(
|
||||
editorState: editorState,
|
||||
final editorState = EditorState.blank(withInitialText: true); // with an empty paragraph
|
||||
final editor = AppFlowyEditor.standard(
|
||||
editorState: editorState,
|
||||
);
|
||||
```
|
||||
|
||||
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).
|
||||
|
||||
```dart
|
||||
final json = ...;
|
||||
final editorState = EditorState(Document.fromJson(data));
|
||||
final editor = AppFlowyEditor(
|
||||
editorState: editorState,
|
||||
final json = jsonDecode('YOUR INPUT JSON STRING');
|
||||
final editorState = EditorState(document: Document.fromJson(json));
|
||||
final editor = AppFlowyEditor.standard(
|
||||
editorState: editorState,
|
||||
);
|
||||
```
|
||||
|
||||
> Note: The parameters `localizationsDelegates` need to be assigned in MaterialApp widget
|
||||
```dart
|
||||
MaterialApp(
|
||||
localizationsDelegates: const [
|
||||
AppFlowyEditorLocalizations.delegate,
|
||||
],
|
||||
localizationsDelegates: const [
|
||||
AppFlowyEditorLocalizations.delegate,
|
||||
],
|
||||
);
|
||||
```
|
||||
|
||||
|
|
@ -89,15 +90,15 @@ flutter run
|
|||
|
||||
## Customizing Your Editor
|
||||
|
||||
### Customizing Components
|
||||
### Customizing Block Components
|
||||
|
||||
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).
|
||||
|
||||
Below are some examples of component customizations:
|
||||
|
||||
* [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
|
||||
* [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
|
||||
* See further examples of [rich-text plugins](https://github.com/AppFlowy-IO/appflowy-editor/blob/main/lib/src/render/rich_text)
|
||||
* [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
|
||||
* [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
|
||||
* See further examples of [Rich-Text Plugins](https://github.com/AppFlowy-IO/appflowy-editor/tree/main/lib/src/editor/block_component)
|
||||
|
||||
### Customizing Shortcut Events
|
||||
|
||||
|
|
@ -105,9 +106,8 @@ Please refer to our documentation on customizing AppFlowy for a detailed discuss
|
|||
|
||||
Below are some examples of shortcut event customizations:
|
||||
|
||||
* [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
|
||||
* [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
|
||||
* 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)
|
||||
* [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
|
||||
* Need more examples? Check out [shortcuts](https://github.com/AppFlowy-IO/appflowy-editor/tree/main/lib/src/editor/editor_component/service/shortcuts)
|
||||
|
||||
## Glossary
|
||||
Please refer to the API documentation.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
# Customizing Editor Features
|
||||
|
||||
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`.
|
||||
|
||||
## Customizing a Shortcut Event
|
||||
|
||||
We will use a simple example to illustrate how to quickly add a shortcut event.
|
||||
|
|
@ -11,18 +9,20 @@ In this example, text that starts and ends with an underscore ( \_ ) character w
|
|||
Let's start with a blank document:
|
||||
|
||||
```dart
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
alignment: Alignment.topCenter,
|
||||
child: AppFlowyEditor(
|
||||
editorState: EditorState.empty(),
|
||||
shortcutEvents: const [],
|
||||
customBuilders: const {},
|
||||
),
|
||||
),
|
||||
);
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class UnderScoreToItalic extends StatelessWidget {
|
||||
const UnderScoreToItalic({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppFlowyEditor.custom(
|
||||
editorState: EditorState.blank(withInitialText: true),
|
||||
blockComponentBuilders: standardBlockComponentBuilderMap,
|
||||
characterShortcutEvents: const [],
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -30,118 +30,69 @@ At this point, nothing magic will happen after typing `_xxx_`.
|
|||
|
||||

|
||||
|
||||
To implement our shortcut event we will create a `ShortcutEvent` instance to handle an underscore input.
|
||||
To implement our shortcut event we will create a `CharacterShortcutEvent` instance to handle an underscore input.
|
||||
|
||||
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'.
|
||||
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'.
|
||||
|
||||
> 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).
|
||||
> 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).
|
||||
|
||||
```dart
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
ShortcutEvent underscoreToItalicEvent = ShortcutEvent(
|
||||
// ...
|
||||
|
||||
CharacterShortcutEvent underscoreToItalicEvent = CharacterShortcutEvent(
|
||||
key: 'Underscore to italic',
|
||||
command: 'shift+underscore',
|
||||
handler: _underscoreToItalicHandler,
|
||||
character: '_',
|
||||
handler: (editorState) async => handleFormatByWrappingWithSingleCharacter(
|
||||
editorState: editorState,
|
||||
character: '_',
|
||||
formatStyle: FormatStyleByWrappingWithSingleChar.italic,
|
||||
),
|
||||
);
|
||||
|
||||
ShortcutEventHandler _underscoreToItalicHandler = (editorState, event) {
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
Then, we need to determine if the currently selected node is a `TextNode` and if the selection is collapsed.
|
||||
|
||||
If so, we will continue.
|
||||
|
||||
```dart
|
||||
// ...
|
||||
ShortcutEventHandler _underscoreToItalicHandler = (editorState, event) {
|
||||
// Obtain the selection and selected nodes of the current document through the 'selectionService'
|
||||
// to determine whether the selection is collapsed and whether the selected node is a text node.
|
||||
final selectionService = editorState.service.selectionService;
|
||||
final selection = selectionService.currentSelection.value;
|
||||
final textNodes = selectionService.currentSelectedNodes.whereType<TextNode>();
|
||||
if (selection == null || !selection.isSingle || textNodes.length != 1) {
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
```
|
||||
|
||||
Now, we deal with handling the underscore.
|
||||
|
||||
Look for the position of the previous underscore and
|
||||
1. if one is _not_ found, return without doing anything.
|
||||
2. if one is found, the text enclosed within the two underscores will be formatted to display in italics.
|
||||
|
||||
```dart
|
||||
// ...
|
||||
ShortcutEventHandler _underscoreToItalicHandler = (editorState, event) {
|
||||
// ...
|
||||
|
||||
final textNode = textNodes.first;
|
||||
final text = textNode.toRawString();
|
||||
// Determine if an 'underscore' already exists in the text node and only once.
|
||||
final firstUnderscore = text.indexOf('_');
|
||||
final lastUnderscore = text.lastIndexOf('_');
|
||||
if (firstUnderscore == -1 ||
|
||||
firstUnderscore != lastUnderscore ||
|
||||
firstUnderscore == selection.start.offset - 1) {
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
|
||||
// Delete the previous 'underscore',
|
||||
// update the style of the text surrounded by the two underscores to 'italic',
|
||||
// and update the cursor position.
|
||||
final transaction = editorState.transaction
|
||||
..deleteText(textNode, firstUnderscore, 1)
|
||||
..formatText(
|
||||
textNode,
|
||||
firstUnderscore,
|
||||
selection.end.offset - firstUnderscore - 1,
|
||||
{
|
||||
BuiltInAttributeKey.italic: true,
|
||||
},
|
||||
)
|
||||
..afterSelection = Selection.collapsed(
|
||||
Position(
|
||||
path: textNode.path,
|
||||
offset: selection.end.offset - 1,
|
||||
),
|
||||
);
|
||||
editorState.apply(transaction);
|
||||
|
||||
return KeyEventResult.handled;
|
||||
};
|
||||
```
|
||||
|
||||
Now our 'underscore handler' function is done and the only task left is to inject it into the AppFlowyEditor.
|
||||
|
||||
```dart
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
alignment: Alignment.topCenter,
|
||||
child: AppFlowyEditor(
|
||||
editorState: EditorState.empty(),
|
||||
customBuilders: const {},
|
||||
shortcutEvents: [
|
||||
underscoreToItalic,
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class UnderScoreToItalic extends StatelessWidget {
|
||||
const UnderScoreToItalic({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppFlowyEditor.custom(
|
||||
editorState: EditorState.blank(withInitialText: true),
|
||||
blockComponentBuilders: standardBlockComponentBuilderMap,
|
||||
characterShortcutEvents: [
|
||||
underScoreToItalicEvent,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
CharacterShortcutEvent underScoreToItalicEvent = CharacterShortcutEvent(
|
||||
key: 'Underscore to italic',
|
||||
character: '_',
|
||||
handler: (editorState) async => handleFormatByWrappingWithSingleCharacter(
|
||||
editorState: editorState,
|
||||
character: '_',
|
||||
formatStyle: FormatStyleByWrappingWithSingleChar.italic,
|
||||
),
|
||||
);
|
||||
```
|
||||
|
||||

|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
|
||||
## Customizing a Component
|
||||
|
||||
> ⚠️ Notes: The content below is outdated.
|
||||
|
||||
We will use a simple example to show how to quickly add a custom component.
|
||||
|
||||
In this example we will render an image from the network.
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ bool handleFormatByWrappingWithSingleCharacter({
|
|||
// if the text is already formatted, we should remove the format.
|
||||
final sliced = delta.slice(
|
||||
headCharIndex + 1,
|
||||
selection.end.offset - headCharIndex - 1,
|
||||
selection.end.offset,
|
||||
);
|
||||
final result = sliced.everyAttributes((element) => element[style] == true);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
name: appflowy_editor
|
||||
description: A highly customizable rich-text editor for Flutter. The AppFlowy Editor project for AppFlowy and beyond.
|
||||
version: 1.0.4
|
||||
version: 1.1.0
|
||||
homepage: https://github.com/AppFlowy-IO/appflowy-editor
|
||||
|
||||
platforms:
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import '../../../../new/infra/testable_editor.dart';
|
|||
import '../test_helpers/mobile_app_with_toolbar_widget.dart';
|
||||
|
||||
void main() {
|
||||
group('dividerMobileToolbarItem\n', () {
|
||||
group('dividerMobileToolbarItem', () {
|
||||
testWidgets(
|
||||
'If the user tries to insert a divider while some text is selected, no action should be taken',
|
||||
(WidgetTester tester) async {
|
||||
|
|
|
|||
|
|
@ -150,9 +150,12 @@ void main() async {
|
|||
|
||||
expect(result, true);
|
||||
final after = editorState.getNodeAtPath([0])!;
|
||||
expect(after.delta!.toPlainText(), '$text1$text2');
|
||||
expect(after.delta!.toList()[0].attributes, null);
|
||||
expect(after.delta!.toList()[1].attributes, {'italic': true});
|
||||
final afterDelta = after.delta!;
|
||||
expect(afterDelta.toPlainText(), '$text1$text2');
|
||||
final deltaList = afterDelta.toList();
|
||||
expect(deltaList.length, 2);
|
||||
expect(deltaList[0].attributes, null);
|
||||
expect(deltaList[1].attributes, {'italic': true});
|
||||
});
|
||||
|
||||
// Before
|
||||
|
|
|
|||
Loading…
Reference in a new issue