Update QuillCustomButton (#1517)

* Update QuillCustomButton
* Update README.md
pull/1518/head
Ellet 1 year ago committed by GitHub
parent 905512e8e4
commit e7e71f1cb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      CHANGELOG.md
  2. 34
      README.md
  3. 23
      example/lib/pages/home_page.dart
  4. 3
      flutter_quill_test/CHANGELOG.md
  5. 2
      flutter_quill_test/pubspec.yaml
  6. 3
      lib/src/models/config/toolbar/base_configurations.dart
  7. 32
      lib/src/models/config/toolbar/buttons/custom_button.dart
  8. 10
      lib/src/models/config/toolbar/configurations.dart
  9. 38
      lib/src/models/themes/quill_custom_button.dart
  10. 97
      lib/src/widgets/toolbar/buttons/custom_button.dart
  11. 71
      lib/src/widgets/toolbar/toolbar.dart
  12. 2
      pubspec.yaml
  13. 8
      test/bug_fix_test.dart

@ -1,3 +1,9 @@
## [8.4.0]
- **Breaking change**: Update the `QuillCustomButton` to have `QuillCustomButtonOptions`. We moved everything that is in the `QuillCustomButton` to `QuillCustomButtonOptions` but replaced the `iconData` with `icon` widget for more customizations
- **Breaking change**: the `customButtons` in the `QuillToolbarConfigurations` is now of type `List<QuillToolbarCustomButtonOptions>`
- Bug fixes with the new `8.0.0` update
- Update `README.md`
## [8.3.0] ## [8.3.0]
- Added a `iconButtonFactor` property to `QuillToolbarBaseButtonOptions` to customise how big the button is compared to its icon size (defaults to `kIconButtonFactor` which is the same as previous releases) - Added a `iconButtonFactor` property to `QuillToolbarBaseButtonOptions` to customise how big the button is compared to its icon size (defaults to `kIconButtonFactor` which is the same as previous releases)

@ -199,17 +199,17 @@ To use your own fonts, update your [assets folder](https://github.com/singerdmx/
### Custom Buttons ### Custom Buttons
You may add custom buttons to the _end_ of the toolbar, via the `customButtons` option, which is a `List` of `QuillCustomButton`. You may add custom buttons to the _end_ of the toolbar, via the `customButtons` option, which is a `List` of `QuillToolbarCustomButtonOptions`.
To add an Icon, we should use a new QuillCustomButton class To add an Icon, we should use a new `QuillToolbarCustomButtonOptions` class
```dart ```dart
QuillCustomButton( QuillToolbarCustomButtonOptions(
iconData: Icons.ac_unit, icon: const Icon(Icons.ac_unit),
onTap: () { tooltip: '',
debugPrint('snowflake'); onPressed: () {},
} afterButtonPressed: () {},
), ),
``` ```
Each `QuillCustomButton` is used as part of the `customButtons` option as follows: Each `QuillCustomButton` is used as part of the `customButtons` option as follows:
@ -218,21 +218,21 @@ Each `QuillCustomButton` is used as part of the `customButtons` option as follow
QuillToolbar( QuillToolbar(
configurations: QuillToolbarConfigurations( configurations: QuillToolbarConfigurations(
customButtons: [ customButtons: [
QuillCustomButton( QuillToolbarCustomButtonOptions(
iconData: Icons.ac_unit, icon: const Icon(Icons.ac_unit),
onTap: () { onPressed: () {
debugPrint('snowflake1'); debugPrint('snowflake1');
}, },
), ),
QuillCustomButton( QuillToolbarCustomButtonOptions(
iconData: Icons.ac_unit, icon: const Icon(Icons.ac_unit),
onTap: () { onPressed: () {
debugPrint('snowflake2'); debugPrint('snowflake2');
}, },
), ),
QuillCustomButton( QuillToolbarCustomButtonOptions(
iconData: Icons.ac_unit, icon: const Icon(Icons.ac_unit),
onTap: () { onPressed: () {
debugPrint('snowflake3'); debugPrint('snowflake3');
}, },
), ),

@ -457,9 +457,30 @@ class _HomePageState extends State<HomePage> {
} }
QuillToolbar get quillToolbar { QuillToolbar get quillToolbar {
final customButtons = [
QuillToolbarCustomButtonOptions(
icon: const Icon(Icons.ac_unit),
onPressed: () {
debugPrint('snowflake1');
},
),
QuillToolbarCustomButtonOptions(
icon: const Icon(Icons.ac_unit),
onPressed: () {
debugPrint('snowflake2');
},
),
QuillToolbarCustomButtonOptions(
icon: const Icon(Icons.ac_unit),
onPressed: () {
debugPrint('snowflake3');
},
),
];
if (kIsWeb) { if (kIsWeb) {
return QuillToolbar( return QuillToolbar(
configurations: QuillToolbarConfigurations( configurations: QuillToolbarConfigurations(
customButtons: customButtons,
embedButtons: FlutterQuillEmbeds.toolbarButtons( embedButtons: FlutterQuillEmbeds.toolbarButtons(
imageButtonOptions: QuillToolbarImageButtonOptions( imageButtonOptions: QuillToolbarImageButtonOptions(
imageButtonConfigurations: QuillToolbarImageConfigurations( imageButtonConfigurations: QuillToolbarImageConfigurations(
@ -482,6 +503,7 @@ class _HomePageState extends State<HomePage> {
if (isDesktop()) { if (isDesktop()) {
return QuillToolbar( return QuillToolbar(
configurations: QuillToolbarConfigurations( configurations: QuillToolbarConfigurations(
customButtons: customButtons,
embedButtons: FlutterQuillEmbeds.toolbarButtons( embedButtons: FlutterQuillEmbeds.toolbarButtons(
imageButtonOptions: QuillToolbarImageButtonOptions( imageButtonOptions: QuillToolbarImageButtonOptions(
imageButtonConfigurations: QuillToolbarImageConfigurations( imageButtonConfigurations: QuillToolbarImageConfigurations(
@ -502,6 +524,7 @@ class _HomePageState extends State<HomePage> {
} }
return QuillToolbar( return QuillToolbar(
configurations: QuillToolbarConfigurations( configurations: QuillToolbarConfigurations(
customButtons: customButtons,
embedButtons: FlutterQuillEmbeds.toolbarButtons( embedButtons: FlutterQuillEmbeds.toolbarButtons(
videoButtonOptions: QuillToolbarVideoButtonOptions( videoButtonOptions: QuillToolbarVideoButtonOptions(
videoConfigurations: QuillToolbarVideoConfigurations( videoConfigurations: QuillToolbarVideoConfigurations(

@ -1,3 +1,6 @@
## 0.0.4+1
* Update `README.md`
## 0.0.4 ## 0.0.4
* Update `README.md` * Update `README.md`
* Documentation comments. * Documentation comments.

@ -1,6 +1,6 @@
name: flutter_quill_test name: flutter_quill_test
description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases. description: Test utilities for flutter_quill which includes methods to simplify interacting with the editor in test cases.
version: 0.0.4 version: 0.0.4+1
homepage: https://1o24bbs.com/c/bulletjournal/108 homepage: https://1o24bbs.com/c/bulletjournal/108
repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test repository: https://github.com/singerdmx/flutter-quill/tree/master/flutter_quill_test

@ -4,7 +4,6 @@ import 'package:flutter/widgets.dart'
import '../../../widgets/toolbar/base_toolbar.dart'; import '../../../widgets/toolbar/base_toolbar.dart';
import '../../structs/link_dialog_action.dart'; import '../../structs/link_dialog_action.dart';
import '../../themes/quill_custom_button.dart';
@immutable @immutable
class QuillBaseToolbarConfigurations extends Equatable { class QuillBaseToolbarConfigurations extends Equatable {
@ -41,7 +40,7 @@ class QuillBaseToolbarConfigurations extends Equatable {
final Color? color; final Color? color;
/// List of custom buttons /// List of custom buttons
final List<QuillCustomButton> customButtons; final List<QuillToolbarCustomButtonOptions> customButtons;
/// The color to use when painting the toolbar section divider. /// The color to use when painting the toolbar section divider.
/// ///

@ -0,0 +1,32 @@
import 'package:flutter/widgets.dart' show VoidCallback, Widget;
import 'base.dart';
class QuillToolbarCustomButtonExtraOptions
extends QuillToolbarBaseButtonExtraOptions {
const QuillToolbarCustomButtonExtraOptions({
required super.controller,
required super.context,
required super.onPressed,
});
}
class QuillToolbarCustomButtonOptions extends QuillToolbarBaseButtonOptions<
QuillToolbarBaseButtonOptions, QuillToolbarCustomButtonExtraOptions> {
const QuillToolbarCustomButtonOptions({
this.icon,
this.iconButtonFactor,
this.iconSize,
super.afterButtonPressed,
super.tooltip,
super.iconTheme,
super.childBuilder,
super.controller,
this.onPressed,
});
final double? iconButtonFactor;
final double? iconSize;
final VoidCallback? onPressed;
final Widget? icon;
}

@ -2,15 +2,15 @@ import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/foundation.dart' show immutable;
import 'package:flutter/widgets.dart' import 'package:flutter/widgets.dart'
show Axis, Color, Decoration, Widget, WrapAlignment, WrapCrossAlignment; show Axis, Color, Decoration, Widget, WrapAlignment, WrapCrossAlignment;
import '../../../widgets/embeds.dart';
import '../../../widgets/embeds.dart';
import '../../structs/link_dialog_action.dart'; import '../../structs/link_dialog_action.dart';
import '../../themes/quill_custom_button.dart';
import '../../themes/quill_dialog_theme.dart'; import '../../themes/quill_dialog_theme.dart';
import '../../themes/quill_icon_theme.dart'; import '../../themes/quill_icon_theme.dart';
import 'buttons/base.dart'; import 'buttons/base.dart';
import 'buttons/clear_format.dart'; import 'buttons/clear_format.dart';
import 'buttons/color.dart'; import 'buttons/color.dart';
import 'buttons/custom_button.dart';
import 'buttons/font_family.dart'; import 'buttons/font_family.dart';
import 'buttons/font_size.dart'; import 'buttons/font_size.dart';
import 'buttons/history.dart'; import 'buttons/history.dart';
@ -26,6 +26,7 @@ export './../../../widgets/toolbar/buttons/search/search_dialog.dart';
export './buttons/base.dart'; export './buttons/base.dart';
export './buttons/clear_format.dart'; export './buttons/clear_format.dart';
export './buttons/color.dart'; export './buttons/color.dart';
export './buttons/custom_button.dart';
export './buttons/font_family.dart'; export './buttons/font_family.dart';
export './buttons/font_size.dart'; export './buttons/font_size.dart';
export './buttons/history.dart'; export './buttons/history.dart';
@ -211,7 +212,7 @@ class QuillToolbarConfigurations extends Equatable {
final bool showSearchButton; final bool showSearchButton;
final bool showSubscript; final bool showSubscript;
final bool showSuperscript; final bool showSuperscript;
final List<QuillCustomButton> customButtons; final List<QuillToolbarCustomButtonOptions> customButtons;
/// The decoration to use for the toolbar. /// The decoration to use for the toolbar.
final Decoration? decoration; final Decoration? decoration;
@ -284,6 +285,7 @@ class QuillToolbarButtonOptions extends Equatable {
this.selectHeaderStyleButtons = this.selectHeaderStyleButtons =
const QuillToolbarSelectHeaderStyleButtonsOptions(), const QuillToolbarSelectHeaderStyleButtonsOptions(),
this.linkStyle = const QuillToolbarLinkStyleButtonOptions(), this.linkStyle = const QuillToolbarLinkStyleButtonOptions(),
this.customButtons = const QuillToolbarCustomButtonOptions(),
}); });
/// The base configurations for all the buttons which will apply to all /// The base configurations for all the buttons which will apply to all
@ -329,6 +331,8 @@ class QuillToolbarButtonOptions extends Equatable {
final QuillToolbarLinkStyleButtonOptions linkStyle; final QuillToolbarLinkStyleButtonOptions linkStyle;
final QuillToolbarCustomButtonOptions customButtons;
@override @override
List<Object?> get props => [ List<Object?> get props => [
base, base,

@ -1,26 +1,22 @@
import 'package:flutter/material.dart'; // import 'package:flutter/material.dart';
import '../../widgets/toolbar/base_toolbar.dart'; // import '../../widgets/toolbar/base_toolbar.dart';
class QuillCustomButton extends QuillToolbarBaseButtonOptions { // class QuillCustomButton extends QuillToolbarBaseButtonOptions {
const QuillCustomButton({ // const QuillCustomButton({
super.iconData, // this.icon,
this.iconColor, // this.onTap,
this.onTap, // super.tooltip,
super.tooltip, // this.child,
this.iconSize, // super.iconTheme,
this.child, // });
super.iconTheme,
});
///The icon color; // /// The icon widget
final Color? iconColor; // final Widget? icon;
///The function when the icon is tapped // /// The function when the icon is tapped
final VoidCallback? onTap; // final VoidCallback? onTap;
///The customButton placeholder // /// The customButton placeholder
final Widget? child; // final Widget? child;
// }
final double? iconSize;
}

@ -1,43 +1,92 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../models/themes/quill_icon_theme.dart'; import '../../../models/themes/quill_icon_theme.dart';
import '../../../utils/extensions/build_context.dart';
import '../../controller.dart';
import '../base_toolbar.dart'; import '../base_toolbar.dart';
class CustomButton extends StatelessWidget { class QuillToolbarCustomButton extends StatelessWidget {
const CustomButton({ const QuillToolbarCustomButton({
required this.onPressed, required this.options,
required this.icon, required this.controller,
this.iconColor,
this.iconSize = kDefaultIconSize,
this.iconButtonFactor = kIconButtonFactor,
this.iconTheme,
this.afterButtonPressed,
this.tooltip,
super.key, super.key,
}); });
final VoidCallback? onPressed; final QuillController controller;
final IconData? icon; final QuillToolbarCustomButtonOptions options;
final Color? iconColor;
final double iconSize; double _iconSize(BuildContext context) {
final double iconButtonFactor; final baseFontSize = baseButtonExtraOptions(context).globalIconSize;
final QuillIconTheme? iconTheme; final iconSize = options.iconSize;
final VoidCallback? afterButtonPressed; return iconSize ?? baseFontSize;
final String? tooltip; }
double _iconButtonFactor(BuildContext context) {
final baseIconFactor =
baseButtonExtraOptions(context).globalIconButtonFactor;
final iconButtonFactor = options.iconButtonFactor;
return iconButtonFactor ?? baseIconFactor;
}
VoidCallback? _afterButtonPressed(BuildContext context) {
return options.afterButtonPressed ??
baseButtonExtraOptions(context).afterButtonPressed;
}
QuillIconTheme? _iconTheme(BuildContext context) {
return options.iconTheme ?? baseButtonExtraOptions(context).iconTheme;
}
QuillToolbarBaseButtonOptions baseButtonExtraOptions(BuildContext context) {
return context.requireQuillToolbarBaseButtonOptions;
}
String? _tooltip(BuildContext context) {
return options.tooltip ?? baseButtonExtraOptions(context).tooltip;
}
void _onPressed(BuildContext context) {
options.onPressed?.call();
_afterButtonPressed(context)?.call();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final iconTheme = _iconTheme(context);
final tooltip = _tooltip(context);
final iconSize = _iconSize(context);
final iconButtonFactor = _iconButtonFactor(context);
final childBuilder =
options.childBuilder ?? baseButtonExtraOptions(context).childBuilder;
final afterButtonPressed = _afterButtonPressed(context);
final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; if (childBuilder != null) {
return childBuilder(
QuillToolbarCustomButtonOptions(
iconButtonFactor: iconButtonFactor,
iconSize: iconSize,
afterButtonPressed: afterButtonPressed,
controller: controller,
iconTheme: iconTheme,
tooltip: tooltip,
icon: options.icon,
),
QuillToolbarCustomButtonExtraOptions(
context: context,
controller: controller,
onPressed: () => _onPressed(context),
),
);
}
final theme = Theme.of(context);
return QuillToolbarIconButton( return QuillToolbarIconButton(
highlightElevation: 0,
hoverElevation: 0,
size: iconSize * iconButtonFactor, size: iconSize * iconButtonFactor,
icon: Icon(icon, size: iconSize, color: iconColor), icon: options.icon,
tooltip: tooltip, tooltip: tooltip,
borderRadius: iconTheme?.borderRadius ?? 2, borderRadius: iconTheme?.borderRadius ?? 2,
onPressed: onPressed, onPressed: () => _onPressed(context),
afterPressed: afterButtonPressed, afterPressed: afterButtonPressed,
fillColor: iconTheme?.iconUnselectedFillColor ?? theme.canvasColor, fillColor: iconTheme?.iconUnselectedFillColor ?? theme.canvasColor,
); );

@ -59,8 +59,6 @@ class QuillToolbar extends StatelessWidget {
sectionDividerSpace: configurations.sectionDividerSpace, sectionDividerSpace: configurations.sectionDividerSpace,
toolbarSize: configurations.toolbarSize, toolbarSize: configurations.toolbarSize,
childrenBuilder: (context) { childrenBuilder: (context) {
final controller = context.requireQuillController;
final toolbarConfigurations = final toolbarConfigurations =
context.requireQuillToolbarConfigurations; context.requireQuillToolbarConfigurations;
@ -192,7 +190,9 @@ class QuillToolbar extends StatelessWidget {
], ],
if (configurations.showColorButton) ...[ if (configurations.showColorButton) ...[
QuillToolbarColorButton( QuillToolbarColorButton(
controller: controller, controller:
toolbarConfigurations.buttonOptions.color.controller ??
globalController,
isBackground: false, isBackground: false,
options: toolbarConfigurations.buttonOptions.color, options: toolbarConfigurations.buttonOptions.color,
), ),
@ -201,14 +201,18 @@ class QuillToolbar extends StatelessWidget {
if (configurations.showBackgroundColorButton) ...[ if (configurations.showBackgroundColorButton) ...[
QuillToolbarColorButton( QuillToolbarColorButton(
options: toolbarConfigurations.buttonOptions.backgroundColor, options: toolbarConfigurations.buttonOptions.backgroundColor,
controller: controller, controller:
toolbarConfigurations.buttonOptions.color.controller ??
globalController,
isBackground: true, isBackground: true,
), ),
spacerWidget, spacerWidget,
], ],
if (configurations.showClearFormat) ...[ if (configurations.showClearFormat) ...[
QuillToolbarClearFormatButton( QuillToolbarClearFormatButton(
controller: controller, controller: toolbarConfigurations
.buttonOptions.clearFormat.controller ??
globalController,
options: toolbarConfigurations.buttonOptions.clearFormat, options: toolbarConfigurations.buttonOptions.clearFormat,
), ),
spacerWidget, spacerWidget,
@ -216,7 +220,7 @@ class QuillToolbar extends StatelessWidget {
if (theEmbedButtons != null) if (theEmbedButtons != null)
for (final builder in theEmbedButtons) for (final builder in theEmbedButtons)
builder( builder(
controller, globalController,
globalIconSize, globalIconSize,
context.requireQuillToolbarBaseButtonOptions.iconTheme, context.requireQuillToolbarBaseButtonOptions.iconTheme,
configurations.dialogTheme), configurations.dialogTheme),
@ -234,7 +238,9 @@ class QuillToolbar extends StatelessWidget {
), ),
if (configurations.showAlignmentButtons) ...[ if (configurations.showAlignmentButtons) ...[
QuillToolbarSelectAlignmentButton( QuillToolbarSelectAlignmentButton(
controller: controller, controller: toolbarConfigurations
.buttonOptions.selectAlignmentButtons.controller ??
globalController,
options: toolbarConfigurations options: toolbarConfigurations
.buttonOptions.selectAlignmentButtons, .buttonOptions.selectAlignmentButtons,
// tooltips: Map.of(buttonTooltips) // tooltips: Map.of(buttonTooltips)
@ -274,7 +280,9 @@ class QuillToolbar extends StatelessWidget {
), ),
if (configurations.showHeaderStyle) ...[ if (configurations.showHeaderStyle) ...[
QuillToolbarSelectHeaderStyleButtons( QuillToolbarSelectHeaderStyleButtons(
controller: controller, controller: toolbarConfigurations
.buttonOptions.selectHeaderStyleButtons.controller ??
globalController,
options: toolbarConfigurations options: toolbarConfigurations
.buttonOptions.selectHeaderStyleButtons, .buttonOptions.selectHeaderStyleButtons,
), ),
@ -379,14 +387,18 @@ class QuillToolbar extends StatelessWidget {
), ),
if (configurations.showLink) ...[ if (configurations.showLink) ...[
QuillToolbarLinkStyleButton( QuillToolbarLinkStyleButton(
controller: controller, controller: toolbarConfigurations
.buttonOptions.linkStyle.controller ??
globalController,
options: toolbarConfigurations.buttonOptions.linkStyle, options: toolbarConfigurations.buttonOptions.linkStyle,
), ),
spacerWidget, spacerWidget,
], ],
if (configurations.showSearchButton) ...[ if (configurations.showSearchButton) ...[
QuillToolbarSearchButton( QuillToolbarSearchButton(
controller: controller, controller:
toolbarConfigurations.buttonOptions.search.controller ??
globalController,
options: toolbarConfigurations.buttonOptions.search, options: toolbarConfigurations.buttonOptions.search,
), ),
spacerWidget, spacerWidget,
@ -399,27 +411,24 @@ class QuillToolbar extends StatelessWidget {
space: configurations.sectionDividerSpace, space: configurations.sectionDividerSpace,
), ),
for (final customButton in configurations.customButtons) for (final customButton in configurations.customButtons)
if (customButton.child != null) ...[ QuillToolbarCustomButton(
InkWell( options: customButton,
onTap: customButton.onTap, controller: customButton.controller ?? globalController,
child: customButton.child, ),
), // if (customButton.child != null) ...[
] else ...[ // InkWell(
CustomButton( // onTap: customButton.onTap,
onPressed: customButton.onTap, // child: customButton.child,
icon: customButton.iconData ?? // ),
context.quillToolbarBaseButtonOptions?.iconData, // ] else ...[
iconColor: customButton.iconColor, // QuillToolbarCustomButton(
iconSize: customButton.iconSize ?? globalIconSize, // options:
iconTheme: context // toolbarConfigurations.buttonOptions.customButtons,
.requireQuillToolbarBaseButtonOptions.iconTheme, // controller: toolbarConfigurations
afterButtonPressed: customButton.afterButtonPressed ?? // .buttonOptions.customButtons.controller ??
context.quillToolbarBaseButtonOptions // globalController,
?.afterButtonPressed, // ),
tooltip: customButton.tooltip ?? // ],
context.quillToolbarBaseButtonOptions?.tooltip,
),
],
spacerWidget, spacerWidget,
], ],
]; ];

@ -1,6 +1,6 @@
name: flutter_quill name: flutter_quill
description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter. description: A rich text editor built for the modern Android, iOS, web and desktop platforms. It is the WYSIWYG editor and a Quill component for Flutter.
version: 8.3.0 version: 8.4.0
homepage: https://1o24bbs.com/c/bulletjournal/108 homepage: https://1o24bbs.com/c/bulletjournal/108
repository: https://github.com/singerdmx/flutter-quill repository: https://github.com/singerdmx/flutter-quill

@ -12,17 +12,21 @@ void main() {
(tester) async { (tester) async {
const tooltip = 'custom button'; const tooltip = 'custom button';
final controller = QuillController.basic();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: QuillProvider( home: QuillProvider(
configurations: QuillConfigurations( configurations: QuillConfigurations(
controller: QuillController.basic(), controller: controller,
), ),
child: const QuillToolbar( child: const QuillToolbar(
configurations: QuillToolbarConfigurations( configurations: QuillToolbarConfigurations(
showRedo: false, showRedo: false,
customButtons: [ customButtons: [
QuillCustomButton(tooltip: tooltip), QuillToolbarCustomButtonOptions(
tooltip: tooltip,
)
], ],
), ),
), ),

Loading…
Cancel
Save