pull/1566/head
Ellet 1 year ago
parent 1705bff43e
commit ec2d28c1bc
No known key found for this signature in database
GPG Key ID: C488CC70BBCEF0D1
  1. 3
      CHANGELOG.md
  2. 8
      example/lib/presentation/quill/quill_editor.dart
  3. 11
      example/lib/presentation/quill/quill_screen.dart
  4. 188
      example/lib/presentation/quill/quill_toolbar.dart
  5. 3
      example/lib/presentation/simple/simple_screen.dart
  6. 22
      flutter_quill_extensions/README.md
  7. 4
      flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart
  8. 2
      flutter_quill_extensions/lib/embeds/image/editor/image_menu.dart
  9. 2
      flutter_quill_extensions/lib/embeds/image/toolbar/image_button.dart
  10. 2
      flutter_quill_extensions/lib/embeds/others/camera_button/camera_button.dart
  11. 2
      flutter_quill_extensions/lib/embeds/video/toolbar/video_button.dart
  12. 53
      flutter_quill_extensions/lib/models/config/shared_configurations.dart
  13. 2
      lib/src/extensions/quill_controller_ext.dart
  14. 8
      lib/src/models/config/editor/editor_configurations.dart
  15. 4
      lib/src/models/config/quill_shared_configurations.dart
  16. 3
      lib/src/models/config/toolbar/buttons/base_configurations.dart
  17. 6
      lib/src/models/config/toolbar/toolbar_configurations.dart
  18. 9
      lib/src/widgets/toolbar/base_toolbar.dart
  19. 64
      lib/src/widgets/toolbar/simple_toolbar.dart
  20. 6
      lib/src/widgets/utils/provider.dart

@ -2,6 +2,9 @@
All notable changes to this project will be documented in this file.
## 9.0.0-dev-6
* Move the `child` from `QuillToolbarConfigurations` into `QuillToolbar` directly
## 9.0.0-dev-5
* The `QuillToolbar` is now accepting only `child` with no configurations so you can customize everything you wants, the `QuillToolbar.simple()` or `QuillSimpleToolbar` implements a simple toolbar that is based on `QuillToolbar`, you are free to use it but it just an example and not standard
* Flutter Quill Extensions:

@ -33,6 +33,12 @@ class MyQuillEditor extends StatelessWidget {
scrollController: scrollController,
focusNode: focusNode,
configurations: configurations.copyWith(
extraConfigurations: {
QuillEditorExtensionsConfigurations.key:
const QuillEditorExtensionsConfigurations(
assetsPrefix: 'dsadsasda', // Defaults to assets
),
},
customStyles: const DefaultStyles(
h1: DefaultTextBlockStyle(
TextStyle(
@ -99,7 +105,7 @@ class MyQuillEditor extends StatelessWidget {
return getImageProviderByImageSource(
imageUrl,
imageProviderBuilder: null,
assetsPrefix: QuillSharedExtensionsConfigurations.get(
assetsPrefix: QuillEditorExtensionsConfigurations.get(
context: context)
.assetsPrefix,
);

@ -3,7 +3,7 @@ import 'dart:convert' show jsonEncode;
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart';
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart'
show FlutterQuillEmbeds, QuillSharedExtensionsConfigurations;
show FlutterQuillEmbeds;
import 'package:quill_html_converter/quill_html_converter.dart';
import 'package:share_plus/share_plus.dart' show Share;
@ -133,12 +133,7 @@ class _QuillScreenState extends State<QuillScreen> {
QuillSharedConfigurations get _sharedConfigurations {
return const QuillSharedConfigurations(
extraConfigurations: {
QuillSharedExtensionsConfigurations.key:
QuillSharedExtensionsConfigurations(
assetsPrefix: 'your-assets-folder-name', // Defaults to assets
),
},
);
// locale: Locale('en'),
);
}
}

@ -100,106 +100,106 @@ class MyQuillToolbar extends StatelessWidget {
// For more info
// https://github.com/singerdmx/flutter-quill/blob/master/doc/custom_toolbar.md
return QuillToolbar(
configurations: QuillToolbarConfigurations(
buttonOptions: const QuillToolbarButtonOptions(
configurations: const QuillToolbarConfigurations(
buttonOptions: QuillToolbarButtonOptions(
base: QuillToolbarBaseButtonOptions(
globalIconSize: 20,
globalIconButtonFactor: 1.4,
),
),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
IconButton(
onPressed: () => context
.read<SettingsCubit>()
.updateSettings(
state.copyWith(useCustomQuillToolbar: false)),
icon: const Icon(
Icons.width_normal,
),
),
QuillToolbarHistoryButton(
isUndo: true,
controller: controller,
),
QuillToolbarHistoryButton(
isUndo: false,
controller: controller,
),
QuillToolbarToggleStyleButton(
options: const QuillToolbarToggleStyleButtonOptions(),
controller: controller,
attribute: Attribute.bold,
),
QuillToolbarToggleStyleButton(
options: const QuillToolbarToggleStyleButtonOptions(),
controller: controller,
attribute: Attribute.italic,
),
QuillToolbarToggleStyleButton(
controller: controller,
attribute: Attribute.underline,
),
QuillToolbarClearFormatButton(
controller: controller,
),
const VerticalDivider(),
QuillToolbarImageButton(
controller: controller,
),
QuillToolbarCameraButton(
controller: controller,
),
QuillToolbarVideoButton(
controller: controller,
),
const VerticalDivider(),
QuillToolbarColorButton(
controller: controller,
isBackground: false,
),
QuillToolbarColorButton(
controller: controller,
isBackground: true,
),
const VerticalDivider(),
QuillToolbarSelectHeaderStyleButton(
controller: controller,
),
const VerticalDivider(),
QuillToolbarToggleCheckListButton(
controller: controller,
),
QuillToolbarToggleStyleButton(
controller: controller,
attribute: Attribute.ol,
),
QuillToolbarToggleStyleButton(
controller: controller,
attribute: Attribute.ul,
),
QuillToolbarToggleStyleButton(
controller: controller,
attribute: Attribute.inlineCode,
),
QuillToolbarToggleStyleButton(
controller: controller,
attribute: Attribute.blockQuote,
),
QuillToolbarIndentButton(
controller: controller,
isIncrease: true,
),
QuillToolbarIndentButton(
controller: controller,
isIncrease: false,
),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
IconButton(
onPressed: () => context
.read<SettingsCubit>()
.updateSettings(
state.copyWith(useCustomQuillToolbar: false)),
icon: const Icon(
Icons.width_normal,
),
const VerticalDivider(),
QuillToolbarLinkStyleButton(controller: controller),
],
),
),
QuillToolbarHistoryButton(
isUndo: true,
controller: controller,
),
QuillToolbarHistoryButton(
isUndo: false,
controller: controller,
),
QuillToolbarToggleStyleButton(
options: const QuillToolbarToggleStyleButtonOptions(),
controller: controller,
attribute: Attribute.bold,
),
QuillToolbarToggleStyleButton(
options: const QuillToolbarToggleStyleButtonOptions(),
controller: controller,
attribute: Attribute.italic,
),
QuillToolbarToggleStyleButton(
controller: controller,
attribute: Attribute.underline,
),
QuillToolbarClearFormatButton(
controller: controller,
),
const VerticalDivider(),
QuillToolbarImageButton(
controller: controller,
),
QuillToolbarCameraButton(
controller: controller,
),
QuillToolbarVideoButton(
controller: controller,
),
const VerticalDivider(),
QuillToolbarColorButton(
controller: controller,
isBackground: false,
),
QuillToolbarColorButton(
controller: controller,
isBackground: true,
),
const VerticalDivider(),
QuillToolbarSelectHeaderStyleButton(
controller: controller,
),
const VerticalDivider(),
QuillToolbarToggleCheckListButton(
controller: controller,
),
QuillToolbarToggleStyleButton(
controller: controller,
attribute: Attribute.ol,
),
QuillToolbarToggleStyleButton(
controller: controller,
attribute: Attribute.ul,
),
QuillToolbarToggleStyleButton(
controller: controller,
attribute: Attribute.inlineCode,
),
QuillToolbarToggleStyleButton(
controller: controller,
attribute: Attribute.blockQuote,
),
QuillToolbarIndentButton(
controller: controller,
isIncrease: true,
),
QuillToolbarIndentButton(
controller: controller,
isIncrease: false,
),
const VerticalDivider(),
QuillToolbarLinkStyleButton(controller: controller),
],
),
),
);

@ -18,7 +18,8 @@ class _SimpleScreenState extends State<SimpleScreen> {
body: Column(
children: [
QuillToolbar.simple(
QuillSimpleToolbarConfigurations(controller: _controller),
configurations:
QuillSimpleToolbarConfigurations(controller: _controller),
),
Expanded(
child: QuillEditor.basic(

@ -170,19 +170,17 @@ This works for all platforms except Web
If you want to use image assets in the Quill Editor, you need to make sure your assets folder is `assets` otherwise:
```dart
QuillProvider(
configurations: const QuillConfigurations(
sharedConfigurations: QuillSharedConfigurations(
extraConfigurations: {
QuillSharedExtensionsConfigurations.key:
QuillSharedExtensionsConfigurations(
assetsPrefix: 'your-assets-folder-name', // Defaults to assets
),
},
),
QuillEditor.basic(
configurations: const QuillEditorConfigurations(
// ...
extraConfigurations: {
QuillEditorExtensionsConfigurations.key:
QuillEditorExtensionsConfigurations(
assetsPrefix: 'your-assets-folder-name', // Defaults to assets
),
child: ...,
)
},
),
)
```
This info is needed by the package to check if it asset image to use the `AssetImage` provider

@ -47,12 +47,12 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder {
alignment: alignment,
height: height,
width: width,
assetsPrefix: QuillSharedExtensionsConfigurations.get(context: context)
assetsPrefix: QuillEditorExtensionsConfigurations.get(context: context)
.assetsPrefix,
);
final imageSaverService =
QuillSharedExtensionsConfigurations.get(context: context)
QuillEditorExtensionsConfigurations.get(context: context)
.imageSaverService;
return GestureDetector(
onTap: configurations.onImageClicked ??

@ -184,7 +184,7 @@ class ImageOptionsMenu extends StatelessWidget {
MaterialPageRoute(
builder: (_) => ImageTapWrapper(
assetsPrefix:
QuillSharedExtensionsConfigurations.get(context: context)
QuillEditorExtensionsConfigurations.get(context: context)
.assetsPrefix,
imageUrl: imageSource,
configurations: configurations,

@ -116,7 +116,7 @@ class QuillToolbarImageButton extends StatelessWidget {
Future<void> _onPressedHandler(BuildContext context) async {
final imagePickerService =
QuillSharedExtensionsConfigurations.get(context: context)
QuillEditorExtensionsConfigurations.get(context: context)
.imagePickerService;
final onRequestPickImage =

@ -132,7 +132,7 @@ class QuillToolbarCameraButton extends StatelessWidget {
QuillController controller,
) async {
final imagePickerService =
QuillSharedExtensionsConfigurations.get(context: context)
QuillEditorExtensionsConfigurations.get(context: context)
.imagePickerService;
final cameraAction = await _getCameraAction(context);

@ -115,7 +115,7 @@ class QuillToolbarVideoButton extends StatelessWidget {
Future<void> _onPressedHandler(BuildContext context) async {
final imagePickerService =
QuillSharedExtensionsConfigurations.get(context: context)
QuillEditorExtensionsConfigurations.get(context: context)
.imagePickerService;
final onRequestPickVideo = options.videoConfigurations.onRequestPickVideo;

@ -5,37 +5,10 @@ import 'package:meta/meta.dart' show immutable;
import '../../services/image_picker/s_image_picker.dart';
import '../../services/image_saver/s_image_saver.dart';
/// Configurations for Flutter Quill Extensions
/// that is shared between the toolbar and editor for the extensions package
///
/// Example on how to setup it:
///
/// ```dart
/// QuillProvider(
/// configurations: QuillConfigurations(
/// sharedConfigurations: const QuillSharedConfigurations(
/// extraConfigurations: {
/// QuillSharedExtensionsConfigurations.key:
/// QuillSharedExtensionsConfigurations(
/// // Feel free to explore it
/// ),
/// },
/// ),
/// controller: _controller,
/// ),
/// child: const Column(
/// children: [
/// // QuillToolbar
/// // QuillEditor
/// // ...
/// ],
// ),
/// )
/// ```
///
/// Configurations for Flutter Quill Editor Extensions
@immutable
class QuillSharedExtensionsConfigurations {
const QuillSharedExtensionsConfigurations({
class QuillEditorExtensionsConfigurations {
const QuillEditorExtensionsConfigurations({
ImagePickerService? imagePickerService,
ImageSaverService? imageSaverService,
this.assetsPrefix = 'assets',
@ -44,30 +17,28 @@ class QuillSharedExtensionsConfigurations {
/// Get the instance from the widget tree in [QuillSharedConfigurations]
/// if it doesn't exists, we will create new one with default options
factory QuillSharedExtensionsConfigurations.get({
factory QuillEditorExtensionsConfigurations.get({
required BuildContext context,
}) {
final quillSharedExtensionsConfigurations =
context.quillSharedConfigurations?.extraConfigurations[key];
if (quillSharedExtensionsConfigurations != null) {
if (quillSharedExtensionsConfigurations
is! QuillSharedExtensionsConfigurations) {
final value = context.quillEditorConfigurations?.extraConfigurations[key];
if (value != null) {
if (value is! QuillEditorExtensionsConfigurations) {
throw ArgumentError(
'The value of key `$key` should be of type '
'QuillSharedExtensionsConfigurations',
'$key',
);
}
return quillSharedExtensionsConfigurations;
return value;
}
return const QuillSharedExtensionsConfigurations();
return const QuillEditorExtensionsConfigurations();
}
/// The key to be used in the `extraConfigurations` property
/// which can be found in the [QuillSharedConfigurations]
/// which lives in the [QuillConfigurations]
///
/// which exists in the [QuillProvider]
static const String key = 'quillSharedExtensionsConfigurations';
/// which exists in the [QuillEditorConfigurations]
static const String key = 'QuillEditorExtensionsConfigurations';
/// Defaults to [ImagePickerService.defaultImpl]
final ImagePickerService? _imagePickerService;

@ -5,7 +5,7 @@ import 'quill_configurations_ext.dart';
extension QuillControllerNullableExt on QuillController? {
/// Simple logic to use the current passed controller if not null
/// if null then we will have to use the default one from [QuillProvider]
/// if null then we will have to use the default one
/// using the [context]
QuillController notNull(BuildContext context) {
final controller = this;

@ -75,10 +75,14 @@ class QuillEditorConfigurations extends Equatable {
this.builder,
this.magnifierConfiguration,
this.textInputAction = TextInputAction.newline,
this.extraConfigurations = const {},
});
final QuillSharedConfigurations sharedConfigurations;
/// Store custom configurations in here and use it in the widget tree
final Map<String, Object?> extraConfigurations;
final QuillController controller;
/// The text placeholder in the quill editor
@ -338,6 +342,8 @@ class QuillEditorConfigurations extends Equatable {
// regenerate this function using extension in vs code or plugin in intellij
QuillEditorConfigurations copyWith({
QuillSharedConfigurations? sharedConfigurations,
Map<String, Object?>? extraConfigurations,
QuillController? controller,
String? placeholder,
bool? readOnly,
@ -384,6 +390,8 @@ class QuillEditorConfigurations extends Equatable {
TextInputAction? textInputAction,
}) {
return QuillEditorConfigurations(
sharedConfigurations: sharedConfigurations ?? this.sharedConfigurations,
extraConfigurations: extraConfigurations ?? this.extraConfigurations,
controller: controller ?? this.controller,
placeholder: placeholder ?? this.placeholder,
readOnly: readOnly ?? this.readOnly,

@ -15,7 +15,6 @@ class QuillSharedConfigurations extends Equatable {
this.dialogBarrierColor = Colors.black54,
this.dialogTheme,
this.locale,
this.extraConfigurations = const {},
});
// This is just example or showcase of this major update to make the library
@ -34,9 +33,6 @@ class QuillSharedConfigurations extends Equatable {
/// `MaterialApp` or `WidgetsApp`
final Locale? locale;
/// Store custom configurations in here and use it in the widget tree
final Map<String, Object?> extraConfigurations;
@override
List<Object?> get props => [
dialogBarrierColor,

@ -1,4 +1,3 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart' show VoidCallback, immutable;
import 'package:flutter/widgets.dart' show BuildContext, IconData, Widget;
@ -82,7 +81,7 @@ class QuillToolbarBaseButtonOptions<T, I> extends Equatable {
/// If you want to dispaly a differnet widget based using a builder
final QuillToolbarButtonOptionsChildBuilder<T, I> childBuilder;
/// By default it will be from the one in [QuillProvider]
/// By default it will be from the one in [QuillEditor] or [QuillToolbar]
/// To override it you must pass not null controller
/// if you wish to use the controller in the [childBuilder], please use the
/// one from the extraOptions since it will be not null and will be the one

@ -1,5 +1,4 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'package:flutter/widgets.dart' show Widget, immutable;
import 'package:flutter/widgets.dart' show immutable;
import '../../../widgets/toolbar/base_toolbar.dart';
import 'toolbar_shared_configurations.dart';
@ -7,7 +6,6 @@ import 'toolbar_shared_configurations.dart';
@immutable
class QuillToolbarConfigurations extends QuillSharedToolbarProperties {
const QuillToolbarConfigurations({
required this.child,
super.sharedConfigurations,
/// Note this only used when you using the quill toolbar buttons like
@ -15,8 +13,6 @@ class QuillToolbarConfigurations extends QuillSharedToolbarProperties {
super.buttonOptions = const QuillToolbarButtonOptions(),
});
final Widget child;
@override
List<Object?> get props => [];
}

@ -30,17 +30,20 @@ typedef QuillBaseToolbarChildrenBuilder = List<Widget> Function(
class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
const QuillToolbar({
required this.configurations,
required this.child,
this.configurations = const QuillToolbarConfigurations(),
super.key,
});
static QuillSimpleToolbar simple(
QuillSimpleToolbarConfigurations configurations) {
{required QuillSimpleToolbarConfigurations configurations}) {
return QuillSimpleToolbar(
configurations: configurations,
);
}
final Widget child;
final QuillToolbarConfigurations configurations;
// We can't get the modified [toolbarSize] by the developer
@ -57,7 +60,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
return FlutterQuillLocalizationsWidget(
child: QuillToolbarProvider(
toolbarConfigurations: configurations,
child: configurations.child,
child: child,
),
);
}

@ -428,39 +428,39 @@ class QuillSimpleToolbar extends StatelessWidget
child: QuillToolbar(
configurations: QuillToolbarConfigurations(
buttonOptions: configurations.buttonOptions,
child: Builder(
builder: (context) {
if (configurations.multiRowsDisplay) {
return Wrap(
direction: configurations.axis,
alignment: configurations.toolbarIconAlignment,
crossAxisAlignment: configurations.toolbarIconCrossAlignment,
runSpacing: 4,
spacing: configurations.toolbarSectionSpacing,
children: childrenBuilder(context),
);
}
return Container(
decoration: configurations.decoration ??
BoxDecoration(
color:
configurations.color ?? Theme.of(context).canvasColor,
),
constraints: BoxConstraints.tightFor(
height: configurations.axis == Axis.horizontal
? configurations.toolbarSize
: null,
width: configurations.axis == Axis.vertical
? configurations.toolbarSize
: null,
),
child: QuillToolbarArrowIndicatedButtonList(
axis: configurations.axis,
buttons: childrenBuilder(context),
),
),
child: Builder(
builder: (context) {
if (configurations.multiRowsDisplay) {
return Wrap(
direction: configurations.axis,
alignment: configurations.toolbarIconAlignment,
crossAxisAlignment: configurations.toolbarIconCrossAlignment,
runSpacing: 4,
spacing: configurations.toolbarSectionSpacing,
children: childrenBuilder(context),
);
},
),
}
return Container(
decoration: configurations.decoration ??
BoxDecoration(
color:
configurations.color ?? Theme.of(context).canvasColor,
),
constraints: BoxConstraints.tightFor(
height: configurations.axis == Axis.horizontal
? configurations.toolbarSize
: null,
width: configurations.axis == Axis.vertical
? configurations.toolbarSize
: null,
),
child: QuillToolbarArrowIndicatedButtonList(
axis: configurations.axis,
buttons: childrenBuilder(context),
),
);
},
),
),
);

@ -44,7 +44,7 @@ class QuillSimpleToolbarProvider extends InheritedWidget {
'You might using QuillToolbar so make sure to'
' wrap them with the quill provider widget and setup the required '
'configurations',
'QuillProvider',
'QuillSimpleToolbarProvider',
);
}
return provider;
@ -102,7 +102,7 @@ class QuillToolbarProvider extends InheritedWidget {
'You might using QuillBaseToolbar so make sure to'
' wrap them with the quill provider widget and setup the required '
'configurations',
'QuillProvider',
'QuillToolbarProvider',
);
}
return provider;
@ -159,7 +159,7 @@ class QuillEditorProvider extends InheritedWidget {
'You might using QuillEditor so make sure to'
' wrap them with the quill provider widget and setup the required '
'configurations',
'QuillProvider',
'QuillEditorProvider',
);
}
return provider;

Loading…
Cancel
Save