|
|
# Flutter Quill Extensions |
|
|
|
|
|
An extensions for [flutter_quill](https://pub.dev/packages/flutter_quill) |
|
|
to support embedding widgets like images, formulas, videos, tables and more. |
|
|
|
|
|
Check [Flutter Quill](https://github.com/singerdmx/flutter-quill) for details of use. |
|
|
|
|
|
> The support for tables is currently limited and under development, more are changes expected to arrive. We are actively working on enhancing its functionality and usability. We appreciate your feedback as it is invaluable in helping us refine and expand this feature. |
|
|
|
|
|
## 📚 Table of Contents |
|
|
|
|
|
- [Flutter Quill Extensions](#flutter-quill-extensions) |
|
|
- [📚 Table of Contents](#-table-of-contents) |
|
|
- [📝 About](#-about) |
|
|
- [📦 Installation](#-installation) |
|
|
- [🛠 Platform Specific Configurations](#-platform-specific-configurations) |
|
|
- [🚀 Usage](#-usage) |
|
|
- [⚙️ Configurations](#️-configurations) |
|
|
- [📦 Embed Blocks](#-embed-blocks) |
|
|
- [🔍 Element properties](#-element-properties) |
|
|
- [🔧 Custom Element properties](#-custom-element-properties) |
|
|
- [🖼️ Image Assets](#️-image-assets) |
|
|
- [🎯 Drag and drop feature](#-drag-and-drop-feature) |
|
|
- [💡 Features](#-features) |
|
|
- [🤝 Contributing](#-contributing) |
|
|
- [🌟 Acknowledgments](#-acknowledgments) |
|
|
|
|
|
## 📝 About |
|
|
|
|
|
Flutter Quill is a rich editor text. |
|
|
It'd allow you to customize a lot of things, |
|
|
it has custom embed builders that allow you to render custom widgets in the editor <br> |
|
|
|
|
|
This is an extension to extend its functionalities by adding more features like images, videos, and more |
|
|
|
|
|
## 📦 Installation |
|
|
|
|
|
Before starting using this package, please make sure to install |
|
|
[flutter_quill](https://github.com/singerdmx/flutter-quill) package first and follow |
|
|
its usage instructions. |
|
|
|
|
|
```yaml |
|
|
dependencies: |
|
|
flutter_quill_extensions: ^<latest-version-here> |
|
|
``` |
|
|
|
|
|
<p align="center">OR</p> |
|
|
|
|
|
```yaml |
|
|
dependencies: |
|
|
flutter_quill_extensions: |
|
|
git: https://github.com/singerdmx/flutter-quill.git |
|
|
path: flutter_quill_extensions |
|
|
ref: v<latest-version-here> |
|
|
``` |
|
|
|
|
|
## 🛠 Platform Specific Configurations |
|
|
|
|
|
The package uses the following plugins: |
|
|
|
|
|
1. [`gal`](https://github.com/natsuk4ze/) plugin to save images. |
|
|
For this to work, you need to add the appropriate configurations |
|
|
See <https://github.com/natsuk4ze/gal#-get-started> to add the needed lines. |
|
|
2. [`image_picker`](https://pub.dev/packages/image_picker) plugin for picking images so please make sure to follow the |
|
|
instructions |
|
|
3. [`youtube_player_flutter`](https://pub.dev/packages/youtube_player_flutter) plugin which |
|
|
uses [`flutter_inappwebview`](https://pub.dev/packages/flutter_inappwebview) which has a requirement on web, please |
|
|
follow this [link](https://pub.dev/packages/flutter_inappwebview#installation) to set up the support for web |
|
|
4. [`image_picker`](https://pub.dev/packages/image_picker) which also |
|
|
requires some configurations, follow this [link](https://pub.dev/packages/image_picker#installation). |
|
|
It's needed for |
|
|
Android, iOS, and macOS, we must inform you that you can't pick photos using the camera on a desktop so make sure to |
|
|
handle that if you plan on adding support for the desktop, this may change in the future, and for more info follow |
|
|
this [link](https://pub.dev/packages/image_picker#windows-macos-and-linux) |
|
|
5. [`super_clipboard`](https://pub.dev/packages/super_clipboard) which needs some setup on Android only, it's used to |
|
|
support copying images and pasting them into editor then you must set up it, open the page in pub.dev and read |
|
|
the `README.md` or click on this [link](https://pub.dev/packages/super_clipboard#android-support) to get the |
|
|
instructions. |
|
|
|
|
|
The minSdkVersion is `23` as `super_clipboard` requires it |
|
|
|
|
|
|
|
|
> For loading the image from the internet <br> <br> |
|
|
> **Android**: you need to add permissions in `AndroidManifest.xml`, Follow |
|
|
> this [Android Guide](https://developer.android.com/training/basics/network-ops/connecting) |
|
|
> or [Flutter Networking](https://docs.flutter.dev/data-and-backend/networking#android) for more info, the internet |
|
|
> permission is included by default only for debugging, you need to follow this link to add it in the release version |
|
|
> too. you should allow loading images and videos only for the `https` protocol but if you want http too then you need |
|
|
> to |
|
|
> configure your Android application to accept `http` in the release mode, follow |
|
|
> this [Android Cleartext / Plaintext HTTP](https://developer.android.com/privacy-and-security/risks/cleartext) page for |
|
|
> more info. <br> <br> |
|
|
> **macOS**: you need to include a key in your `Info.plist`, follow |
|
|
> this [link](https://docs.flutter.dev/data-and-backend/networking#macos) to add the required configurations |
|
|
> |
|
|
|
|
|
## 🚀 Usage |
|
|
|
|
|
Start using the package in 3 steps: |
|
|
|
|
|
1. Be sure to follow the [Installation](#installation) section. |
|
|
2. This package already include `super_clipboard` and will be used internally in this package, to use it |
|
|
in `flutter_quill`, call this function before using any of the widgets or functionalities |
|
|
|
|
|
```dart |
|
|
FlutterQuillExtensions.useSuperClipboardPlugin(); |
|
|
``` |
|
|
|
|
|
`super_clipboard` is comprehensive plugin that provides many clipboard features for reading and writing of rich text, |
|
|
images and other formats. |
|
|
|
|
|
Executing this function will allow `flutter_quill` to use modern rich text features to paste HTML and Markdown, |
|
|
support for Gif files, and other formats. |
|
|
|
|
|
3. Set the `embedBuilders` and `embedToolbar` params in configurations of `QuillEditor` and `QuillToolbar` with the |
|
|
values provided by this repository. |
|
|
|
|
|
**Quill Toolbar**: |
|
|
```dart |
|
|
QuillToolbar( |
|
|
configurations: QuillToolbarConfigurations( |
|
|
embedButtons: FlutterQuillEmbeds.toolbarButtons(), |
|
|
), |
|
|
), |
|
|
``` |
|
|
|
|
|
**Quill Editor** |
|
|
```dart |
|
|
Expanded( |
|
|
child: QuillEditor.basic( |
|
|
configurations: QuillEditorConfigurations( |
|
|
embedBuilders: kIsWeb ? FlutterQuillEmbeds.editorWebBuilders() : FlutterQuillEmbeds.editorBuilders(), |
|
|
), |
|
|
), |
|
|
) |
|
|
``` |
|
|
|
|
|
## ⚙️ Configurations |
|
|
|
|
|
### 📦 Embed Blocks |
|
|
|
|
|
As of version [flutter_quill](https://pub.dev/packages/flutter_quill) `6.0.x`, embed blocks are not provided by default |
|
|
as part of Flutter quill. |
|
|
Instead, it provides an interface for all the users to provide their implementations for embed |
|
|
blocks. |
|
|
Implementations for image, video, and formula embed blocks are proved in this package |
|
|
|
|
|
The instructions for using the embed blocks are in the [Usage](#usage) section |
|
|
|
|
|
### 🔍 Element properties |
|
|
|
|
|
Currently, the library has limited support for the image and video properties, |
|
|
and it supports only `width`, `height`, `margin` |
|
|
|
|
|
```json |
|
|
{ |
|
|
"insert": { |
|
|
"image": "https://user-images.githubusercontent.com/122956/72955931-ccc07900-3d52-11ea-89b1-d468a6e2aa2b.png" |
|
|
}, |
|
|
"attributes": { |
|
|
"style": "width: 50px; height: 50px; margin: 10px;" |
|
|
} |
|
|
} |
|
|
``` |
|
|
|
|
|
### 🔧 Custom Element properties |
|
|
|
|
|
Doesn't apply to official Quill JS |
|
|
|
|
|
Define flutterAlignment` as follows: |
|
|
|
|
|
```json |
|
|
{ |
|
|
"insert": { |
|
|
"image": "https://user-images.githubusercontent.com/122956/72955931-ccc07900-3d52-11ea-89b1-d468a6e2aa2b.png" |
|
|
}, |
|
|
"attributes": { |
|
|
"style": "flutterAlignment: topLeft" |
|
|
} |
|
|
} |
|
|
``` |
|
|
|
|
|
This works for all platforms except Web |
|
|
|
|
|
### 🖼️ Image Assets |
|
|
|
|
|
If you want to use image assets in the Quill Editor, you need to make sure your assets folder is `assets` otherwise: |
|
|
|
|
|
```dart |
|
|
QuillEditor.basic( |
|
|
configurations: const QuillEditorConfigurations( |
|
|
// ... |
|
|
sharedConfigurations: QuillSharedConfigurations( |
|
|
extraConfigurations: { |
|
|
QuillSharedExtensionsConfigurations.key: |
|
|
QuillSharedExtensionsConfigurations( |
|
|
assetsPrefix: 'your-assets-folder-name', // Defaults to `assets` |
|
|
), |
|
|
}, |
|
|
), |
|
|
), |
|
|
); |
|
|
``` |
|
|
|
|
|
This info is needed by the package to check if its asset image to use the `AssetImage` provider |
|
|
|
|
|
### 🎯 Drag and drop feature |
|
|
|
|
|
Currently, the drag-and-drop feature is not officially supported, but you can achieve this very easily in the following |
|
|
steps: |
|
|
|
|
|
1. Drag and drop require native code, you can use any Flutter plugin you like, if you want a suggestion we |
|
|
recommend [desktop_drop](https://pub.dev/packages/desktop_drop), it was originally developed for desktop. |
|
|
It has support for the web as well as Android (that is not the case for iOS) |
|
|
2. Add the dependency in your `pubspec.yaml` using the following command: |
|
|
|
|
|
```yaml |
|
|
flutter pub add desktop_drop |
|
|
``` |
|
|
and import it with |
|
|
```dart |
|
|
import 'package:desktop_drop/desktop_drop.dart'; |
|
|
``` |
|
|
3. in the configurations of `QuillEditor`, use the `builder` to wrap the editor with `DropTarget` which comes |
|
|
from `desktop_drop` |
|
|
|
|
|
```dart |
|
|
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'; |
|
|
|
|
|
QuillEditor.basic( |
|
|
configurations: QuillEditorConfigurations( |
|
|
padding: const EdgeInsets.all(16), |
|
|
builder: (context, rawEditor) { |
|
|
return DropTarget( |
|
|
onDragDone: _onDragDone, |
|
|
child: rawEditor, |
|
|
); |
|
|
}, |
|
|
embedBuilders: kIsWeb |
|
|
? FlutterQuillEmbeds.editorWebBuilders() |
|
|
: FlutterQuillEmbeds.editorBuilders(), |
|
|
), |
|
|
) |
|
|
``` |
|
|
4. Implement the `_onDragDone`, it depends on your use case but this is just a simple example |
|
|
|
|
|
```dart |
|
|
const List<String> imageFileExtensions = [ |
|
|
'.jpeg', |
|
|
'.png', |
|
|
'.jpg', |
|
|
'.gif', |
|
|
'.webp', |
|
|
'.tif', |
|
|
'.heic' |
|
|
]; |
|
|
OnDragDoneCallback get _onDragDone { |
|
|
return (details) { |
|
|
final scaffoldMessenger = ScaffoldMessenger.of(context); |
|
|
final file = details.files.first; |
|
|
final isSupported = |
|
|
imageFileExtensions.any((ext) => file.name.endsWith(ext)); |
|
|
if (!isSupported) { |
|
|
scaffoldMessenger.showSnackBar( |
|
|
SnackBar( |
|
|
content: Text( |
|
|
'Only images are supported right now: ${file.mimeType}, ${file.name}, ${file.path}, $imageFileExtensions', |
|
|
), |
|
|
), |
|
|
); |
|
|
return; |
|
|
} |
|
|
// To get this extension function please import flutter_quill_extensions |
|
|
_controller.insertImageBlock( |
|
|
imageSource: file.path, |
|
|
); |
|
|
scaffoldMessenger.showSnackBar( |
|
|
const SnackBar( |
|
|
content: Text('Image is inserted.'), |
|
|
), |
|
|
); |
|
|
}; |
|
|
} |
|
|
``` |
|
|
|
|
|
## 💡 Features |
|
|
|
|
|
```markdown |
|
|
## Features |
|
|
|
|
|
— Easy to use and customizable |
|
|
|
|
|
- Rich text, images and other formats |
|
|
- Useful utilities and widgets |
|
|
``` |
|
|
|
|
|
## 🤝 Contributing |
|
|
|
|
|
We welcome contributions! |
|
|
|
|
|
Please follow these guidelines when contributing to our project. See [CONTRIBUTING.md](../CONTRIBUTING.md) for more |
|
|
details. |
|
|
|
|
|
## 🌟 Acknowledgments |
|
|
|
|
|
- Thanks to the [Flutter Team](https://flutter.dev/) |
|
|
- Thanks to the welcoming community, the volunteers who helped along the journey, developers, contributors |
|
|
and contributors who put time and effort into everything including making all the libraries, tools, and the |
|
|
information we rely on |
|
|
|
|
|
We are incredibly grateful to many individuals and organizations who have played a |
|
|
role in the project. This includes the welcoming community, dedicated volunteers, talented developers and |
|
|
contributors, and the creators of the open-source tools we rely on.
|
|
|
|