diff --git a/CHANGELOG.md b/CHANGELOG.md index fd5a486b..e0d1cf4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## [7.8.0] +- **Important note**: this is not test release yet, it works but need more test and changes and breaking changes, we don't have development version and it will help us if you try the latest version and report the issues in Github but if you want a stable version please use `7.4.16`. this refactoring process will not take long and should be done less than three weeks with the testing. +- We managed to refactor most of the buttons configurations and customizations in the `QuillProvider`, only three lefts then will start on refactoring the toolbar configurations +- Code improvemenets + ## [7.7.0] - **Breaking change**: We have mirgrated more buttons in the toolbar configurations, you can do change them in the `QuillProvider` diff --git a/README.md b/README.md index c02f6097..47113f46 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,37 @@ Pub: [FlutterQuill] --- +## Installation + +```yaml +dependencies: + flutter_quill: ^ +``` + +

OR

+ +```yaml +dependencies: + flutter_quill: + git: https://github.com/singerdmx/flutter-quill.git +``` + +> **Important note** +> +> Currently, we're in the process of refactoring the library's configurations. We're actively working on this, and while we don't have a development version available at the moment, your feedback is essential to us. +> +> Using the latest version and reporting any issues you encounter on GitHub will greatly contribute to the improvement of the library. Your input and insights are valuable in shaping a stable and reliable version for all our users. Thank you for being part of the open-source community! +> +> if you want to use a more stable release, please use the followings: +> +> ```yaml +> flutter_quill: ^7.4.16 +> flutter_quill_extensions: ^0.5.0 +> ``` +> +> instead of the latest version +> + ## Usage See the `example` directory for a minimal example of how to use FlutterQuill. You typically just need to instantiate a controller: diff --git a/lib/src/models/config/others/animations.dart b/lib/src/models/config/others/animations.dart new file mode 100644 index 00000000..829442c5 --- /dev/null +++ b/lib/src/models/config/others/animations.dart @@ -0,0 +1,30 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/foundation.dart' show immutable; + +import '../../../utils/experimental.dart'; + +@immutable +@Experimental('This class might removed') +class QuillAnimationConfigurations extends Equatable { + const QuillAnimationConfigurations({ + required this.checkBoxPointItem, + }); + + factory QuillAnimationConfigurations.disableAll() => + const QuillAnimationConfigurations( + checkBoxPointItem: false, + ); + + factory QuillAnimationConfigurations.enableAll() => + const QuillAnimationConfigurations( + checkBoxPointItem: true, + ); + + /// This currently has issue which the whole checkbox list will rebuilt + /// and the animation will replay when some value changes + /// which is why disabled by default + final bool checkBoxPointItem; + + @override + List get props => []; +} diff --git a/lib/src/models/config/shared_configurations.dart b/lib/src/models/config/shared_configurations.dart index 8c1a9449..acf3b435 100644 --- a/lib/src/models/config/shared_configurations.dart +++ b/lib/src/models/config/shared_configurations.dart @@ -2,6 +2,9 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart' show Color, Colors, Locale; import './editor/configurations.dart' show QuillEditorConfigurations; import './toolbar/configurations.dart' show QuillToolbarConfigurations; +import 'others/animations.dart'; + +export './others/animations.dart'; /// The shared configurations between [QuillEditorConfigurations] and /// [QuillToolbarConfigurations] so we don't duplicate things @@ -9,6 +12,9 @@ class QuillSharedConfigurations extends Equatable { const QuillSharedConfigurations({ this.dialogBarrierColor = Colors.black54, this.locale, + this.animationConfigurations = const QuillAnimationConfigurations( + checkBoxPointItem: false, + ), }); // This is just example or showcase of this major update to make the library @@ -20,9 +26,13 @@ class QuillSharedConfigurations extends Equatable { /// More https://github.com/singerdmx/flutter-quill#translation final Locale? locale; + /// To configure which animations you want to be enabled + final QuillAnimationConfigurations animationConfigurations; + @override List get props => [ dialogBarrierColor, locale, + animationConfigurations, ]; } diff --git a/lib/src/models/config/toolbar/buttons/clear_format.dart b/lib/src/models/config/toolbar/buttons/clear_format.dart new file mode 100644 index 00000000..f38dd52f --- /dev/null +++ b/lib/src/models/config/toolbar/buttons/clear_format.dart @@ -0,0 +1,26 @@ +import '../../quill_configurations.dart'; + +class QuillToolbarClearFormatButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarClearFormatButtonExtraOptions({ + required super.controller, + required super.context, + required super.onPressed, + }); +} + +class QuillToolbarClearFormatButtonOptions + extends QuillToolbarBaseButtonOptions { + const QuillToolbarClearFormatButtonOptions({ + super.iconData, + super.afterButtonPressed, + super.childBuilder, + super.controller, + super.iconTheme, + super.tooltip, + this.iconSize, + }); + + final double? iconSize; +} diff --git a/lib/src/models/config/toolbar/buttons/color.dart b/lib/src/models/config/toolbar/buttons/color.dart new file mode 100644 index 00000000..19bac781 --- /dev/null +++ b/lib/src/models/config/toolbar/buttons/color.dart @@ -0,0 +1,43 @@ +import 'package:flutter/widgets.dart' show Color; +import './../../shared_configurations.dart' show QuillSharedConfigurations; + +import 'base.dart'; + +class QuillToolbarColorButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarColorButtonExtraOptions({ + required super.controller, + required super.context, + required super.onPressed, + required this.iconColor, + required this.iconColorBackground, + required this.fillColor, + required this.fillColorBackground, + }); + + final Color? iconColor; + final Color? iconColorBackground; + final Color fillColor; + final Color fillColorBackground; +} + +class QuillToolbarColorButtonOptions extends QuillToolbarBaseButtonOptions< + QuillToolbarColorButtonOptions, QuillToolbarColorButtonExtraOptions> { + const QuillToolbarColorButtonOptions({ + this.dialogBarrierColor, + this.iconSize, + super.iconData, + super.afterButtonPressed, + super.childBuilder, + super.controller, + super.globalIconSize, + super.iconTheme, + super.tooltip, + }); + + final double? iconSize; + + /// By default will use the default `dialogBarrierColor` from + /// [QuillSharedConfigurations] + final Color? dialogBarrierColor; +} diff --git a/lib/src/models/config/toolbar/buttons/indent.dart b/lib/src/models/config/toolbar/buttons/indent.dart new file mode 100644 index 00000000..30252088 --- /dev/null +++ b/lib/src/models/config/toolbar/buttons/indent.dart @@ -0,0 +1,27 @@ +import 'package:flutter/foundation.dart'; + +import 'base.dart'; + +class QuillToolbarIndentButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarIndentButtonExtraOptions({ + required super.controller, + required super.context, + required super.onPressed, + }); +} + +@immutable +class QuillToolbarIndentButtonOptions extends QuillToolbarBaseButtonOptions { + const QuillToolbarIndentButtonOptions({ + super.iconData, + super.afterButtonPressed, + super.childBuilder, + super.controller, + super.iconTheme, + super.tooltip, + this.iconSize, + }); + + final double? iconSize; +} diff --git a/lib/src/models/config/toolbar/buttons/select_alignment.dart b/lib/src/models/config/toolbar/buttons/select_alignment.dart new file mode 100644 index 00000000..3bbef892 --- /dev/null +++ b/lib/src/models/config/toolbar/buttons/select_alignment.dart @@ -0,0 +1,58 @@ +import 'package:flutter/widgets.dart' show IconData, immutable; +import 'base.dart'; + +class QuillToolbarSelectAlignmentButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarSelectAlignmentButtonExtraOptions({ + required super.controller, + required super.context, + required super.onPressed, + }); +} + +class QuillToolbarSelectAlignmentButtonOptions + extends QuillToolbarBaseButtonOptions< + QuillToolbarSelectAlignmentButtonOptions, + QuillToolbarBaseButtonExtraOptions> { + const QuillToolbarSelectAlignmentButtonOptions({ + this.iconsData, + this.tooltips, + this.iconSize, + super.afterButtonPressed, + super.childBuilder, + super.controller, + super.iconTheme, + }); + final double? iconSize; + + /// Default to + /// const QuillToolbarSelectAlignmentValues( + /// leftAlignment: Icons.format_align_left, + /// centerAlignment: Icons.format_align_center, + /// rightAlignment: Icons.format_align_right, + /// justifyAlignment: Icons.format_align_justify, + /// ) + final QuillSelectAlignmentValues? iconsData; + + /// By default will use the localized tooltips + final QuillSelectAlignmentValues? tooltips; +} + +/// A helper class which hold all the values for the alignments of the +/// [QuillToolbarSelectAlignmentButtonOptions] +/// it's not really related to the toolbar so we called it just Quill without +/// toolbar but the name might change in the future +@immutable +class QuillSelectAlignmentValues { + const QuillSelectAlignmentValues({ + required this.leftAlignment, + required this.centerAlignment, + required this.rightAlignment, + required this.justifyAlignment, + }); + + final T leftAlignment; + final T centerAlignment; + final T rightAlignment; + final T justifyAlignment; +} diff --git a/lib/src/models/config/toolbar/buttons/toggle_check_list.dart b/lib/src/models/config/toolbar/buttons/toggle_check_list.dart new file mode 100644 index 00000000..7f4e98b1 --- /dev/null +++ b/lib/src/models/config/toolbar/buttons/toggle_check_list.dart @@ -0,0 +1,46 @@ +import 'package:flutter/foundation.dart' show immutable; +import 'package:flutter/widgets.dart' show Color; + +import '../../../documents/attribute.dart'; +import '../../quill_configurations.dart'; + +class QuillToolbarToggleCheckListButtonExtraOptions + extends QuillToolbarBaseButtonExtraOptions { + const QuillToolbarToggleCheckListButtonExtraOptions({ + required super.controller, + required super.context, + required super.onPressed, + this.isToggled = false, + }); + final bool isToggled; +} + +@immutable +class QuillToolbarToggleCheckListButtonOptions + extends QuillToolbarBaseButtonOptions< + QuillToolbarToggleCheckListButtonOptions, + QuillToolbarToggleCheckListButtonExtraOptions> { + const QuillToolbarToggleCheckListButtonOptions({ + this.iconSize, + this.fillColor, + this.attribute = Attribute.unchecked, + this.isShouldRequestKeyboard = false, + super.controller, + super.iconTheme, + super.tooltip, + super.iconData, + super.afterButtonPressed, + super.childBuilder, + }); + + final double? iconSize; + + final Color? fillColor; + + final Attribute attribute; + + /// Should we request the keyboard when you press the toggle check list button + /// ? if true then we will request the keyboard, if false then we will not + /// but I think you already know that + final bool isShouldRequestKeyboard; +} diff --git a/lib/src/models/config/toolbar/configurations.dart b/lib/src/models/config/toolbar/configurations.dart index 3a814143..7a0739ed 100644 --- a/lib/src/models/config/toolbar/configurations.dart +++ b/lib/src/models/config/toolbar/configurations.dart @@ -2,15 +2,24 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart' show immutable; import 'buttons/base.dart'; +import 'buttons/clear_format.dart'; +import 'buttons/color.dart'; import 'buttons/font_family.dart'; import 'buttons/font_size.dart'; import 'buttons/history.dart'; +import 'buttons/indent.dart'; +import 'buttons/select_alignment.dart'; +import 'buttons/toggle_check_list.dart'; import 'buttons/toggle_style.dart'; export './buttons/base.dart'; +export './buttons/clear_format.dart'; +export './buttons/color.dart'; export './buttons/font_family.dart'; export './buttons/font_size.dart'; export './buttons/history.dart'; +export './buttons/select_alignment.dart'; +export './buttons/toggle_check_list.dart'; export './buttons/toggle_style.dart'; /// The default size of the icon of a button. @@ -120,6 +129,14 @@ class QuillToolbarButtonOptions extends Equatable { this.listBullets = const QuillToolbarToggleStyleButtonOptions(), this.codeBlock = const QuillToolbarToggleStyleButtonOptions(), this.quote = const QuillToolbarToggleStyleButtonOptions(), + this.toggleCheckList = const QuillToolbarToggleCheckListButtonOptions(), + this.indentIncrease = const QuillToolbarIndentButtonOptions(), + this.indentDecrease = const QuillToolbarIndentButtonOptions(), + this.color = const QuillToolbarColorButtonOptions(), + this.backgroundColor = const QuillToolbarColorButtonOptions(), + this.clearFormat = const QuillToolbarClearFormatButtonOptions(), + this.selectAlignmentButtons = + const QuillToolbarSelectAlignmentButtonOptions(), }); /// The base configurations for all the buttons which will apply to all @@ -143,6 +160,18 @@ class QuillToolbarButtonOptions extends Equatable { final QuillToolbarToggleStyleButtonOptions listBullets; final QuillToolbarToggleStyleButtonOptions codeBlock; final QuillToolbarToggleStyleButtonOptions quote; + final QuillToolbarToggleCheckListButtonOptions toggleCheckList; + final QuillToolbarIndentButtonOptions indentIncrease; + final QuillToolbarIndentButtonOptions indentDecrease; + final QuillToolbarColorButtonOptions color; + final QuillToolbarColorButtonOptions backgroundColor; + final QuillToolbarClearFormatButtonOptions clearFormat; + + /// The reason we call this buttons in the end because this is responsible + /// for all the alignment buttons and not just one, you still + /// can customize the icons and tooltips + /// and you have child builder + final QuillToolbarSelectAlignmentButtonOptions selectAlignmentButtons; @override List get props => [ diff --git a/lib/src/utils/experimental.dart b/lib/src/utils/experimental.dart new file mode 100644 index 00000000..8f24e87e --- /dev/null +++ b/lib/src/utils/experimental.dart @@ -0,0 +1,7 @@ +import 'package:flutter/foundation.dart' show immutable; + +@immutable +class Experimental { + const Experimental([this.reason = 'Experimental feature']); + final String reason; +} diff --git a/lib/src/widgets/style_widgets/checkbox_point.dart b/lib/src/widgets/style_widgets/checkbox_point.dart index 44c08158..905f00b3 100644 --- a/lib/src/widgets/style_widgets/checkbox_point.dart +++ b/lib/src/widgets/style_widgets/checkbox_point.dart @@ -1,4 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:flutter_animate/flutter_animate.dart'; + +import '../../utils/extensions/build_context.dart'; class CheckboxPoint extends StatefulWidget { const CheckboxPoint({ @@ -43,7 +46,7 @@ class _CheckboxPointState extends State { : (widget.enabled ? theme.colorScheme.onSurface.withOpacity(0.5) : theme.colorScheme.onSurface.withOpacity(0.3)); - return Container( + final child = Container( alignment: AlignmentDirectional.centerEnd, padding: EdgeInsetsDirectional.only(end: widget.size / 2), child: SizedBox( @@ -61,13 +64,31 @@ class _CheckboxPointState extends State { onTap: widget.enabled ? () => widget.onChanged(!widget.value) : null, child: widget.value - ? Icon(Icons.check, - size: widget.size, color: theme.colorScheme.onPrimary) + ? Icon( + Icons.check, + size: widget.size, + color: theme.colorScheme.onPrimary, + ) : null, ), ), ), ); + if (context.requireQuillSharedConfigurations.animationConfigurations + .checkBoxPointItem) { + return Animate( + effects: [ + const SlideEffect( + duration: Duration(milliseconds: 70), + ), + const ScaleEffect( + duration: Duration(milliseconds: 70), + ) + ], + child: child, + ); + } + return child; } } diff --git a/lib/src/widgets/text_block.dart b/lib/src/widgets/text_block.dart index f1aa5e96..4a623d9b 100644 --- a/lib/src/widgets/text_block.dart +++ b/lib/src/widgets/text_block.dart @@ -219,20 +219,11 @@ class EditableTextBlock extends StatelessWidget { ); } - if (attrs[Attribute.list.key] == Attribute.checked) { + if (attrs[Attribute.list.key] == Attribute.checked || + attrs[Attribute.list.key] == Attribute.unchecked) { return CheckboxPoint( size: fontSize, - value: true, - enabled: !readOnly, - onChanged: (checked) => onCheckboxTap(line.documentOffset, checked), - uiBuilder: defaultStyles.lists?.checkboxUIBuilder, - ); - } - - if (attrs[Attribute.list.key] == Attribute.unchecked) { - return CheckboxPoint( - size: fontSize, - value: false, + value: attrs[Attribute.list.key] == Attribute.checked, enabled: !readOnly, onChanged: (checked) => onCheckboxTap(line.documentOffset, checked), uiBuilder: defaultStyles.lists?.checkboxUIBuilder, diff --git a/lib/src/widgets/toolbar/buttons/clear_format.dart b/lib/src/widgets/toolbar/buttons/clear_format.dart index 56a4af79..f62a7354 100644 --- a/lib/src/widgets/toolbar/buttons/clear_format.dart +++ b/lib/src/widgets/toolbar/buttons/clear_format.dart @@ -1,64 +1,114 @@ import 'package:flutter/material.dart'; +import '../../../../translations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/themes/quill_icon_theme.dart'; +import '../../../utils/extensions/build_context.dart'; import '../../controller.dart'; import '../toolbar.dart'; -class QuillToolbarClearFormatButton extends StatefulWidget { +class QuillToolbarClearFormatButton extends StatelessWidget { const QuillToolbarClearFormatButton({ - required this.icon, - required this.controller, - this.iconSize = kDefaultIconSize, - this.iconTheme, - this.afterButtonPressed, - this.tooltip, - Key? key, - }) : super(key: key); + required QuillController controller, + required this.options, + super.key, + }) : _controller = controller; - final IconData icon; - final double iconSize; + final QuillController _controller; + final QuillToolbarClearFormatButtonOptions options; - final QuillController controller; + QuillController get controller { + return options.controller ?? _controller; + } - final QuillIconTheme? iconTheme; - final VoidCallback? afterButtonPressed; - final String? tooltip; + double _iconSize(BuildContext context) { + final baseFontSize = baseButtonExtraOptions(context).globalIconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize; + } - @override - _QuillToolbarClearFormatButtonState createState() => - _QuillToolbarClearFormatButtonState(); -} + 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; + } + + IconData _iconData(BuildContext context) { + return options.iconData ?? + baseButtonExtraOptions(context).iconData ?? + Icons.format_clear; + } + + String _tooltip(BuildContext context) { + return options.tooltip ?? + baseButtonExtraOptions(context).tooltip ?? + ('Clear format'.i18n); + } + + void _sharedOnPressed() { + final attrs = {}; + for (final style in controller.getAllSelectionStyles()) { + for (final attr in style.attributes.values) { + attrs.add(attr); + } + } + for (final attr in attrs) { + controller.formatSelection(Attribute.clone(attr, null)); + } + } -class _QuillToolbarClearFormatButtonState - extends State { @override Widget build(BuildContext context) { final theme = Theme.of(context); - final iconColor = - widget.iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; - final fillColor = - widget.iconTheme?.iconUnselectedFillColor ?? theme.canvasColor; + final iconTheme = _iconTheme(context); + final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; + final fillColor = iconTheme?.iconUnselectedFillColor ?? theme.canvasColor; + final tooltip = _tooltip(context); + final iconSize = _iconSize(context); + final iconData = _iconData(context); + + final childBuilder = + options.childBuilder ?? baseButtonExtraOptions(context).childBuilder; + final afterButtonPressed = _afterButtonPressed(context); + + if (childBuilder != null) { + return childBuilder( + QuillToolbarClearFormatButtonOptions( + afterButtonPressed: afterButtonPressed, + controller: controller, + iconData: iconData, + iconSize: iconSize, + iconTheme: iconTheme, + tooltip: tooltip, + ), + QuillToolbarClearFormatButtonExtraOptions( + controller: controller, + context: context, + onPressed: () { + _sharedOnPressed(); + _afterButtonPressed(context)?.call(); + }, + ), + ); + } + return QuillToolbarIconButton( - tooltip: widget.tooltip, + tooltip: tooltip, highlightElevation: 0, hoverElevation: 0, - size: widget.iconSize * kIconButtonFactor, - icon: Icon(widget.icon, size: widget.iconSize, color: iconColor), + size: iconSize * kIconButtonFactor, + icon: Icon(iconData, size: iconSize, color: iconColor), fillColor: fillColor, - borderRadius: widget.iconTheme?.borderRadius ?? 2, - onPressed: () { - final attrs = {}; - for (final style in widget.controller.getAllSelectionStyles()) { - for (final attr in style.attributes.values) { - attrs.add(attr); - } - } - for (final attr in attrs) { - widget.controller.formatSelection(Attribute.clone(attr, null)); - } - }, - afterPressed: widget.afterButtonPressed, + borderRadius: iconTheme?.borderRadius ?? 2, + onPressed: _sharedOnPressed, + afterPressed: afterButtonPressed, ); } } diff --git a/lib/src/widgets/toolbar/buttons/color.dart b/lib/src/widgets/toolbar/buttons/color.dart index e7d5e6b7..a9480edd 100644 --- a/lib/src/widgets/toolbar/buttons/color.dart +++ b/lib/src/widgets/toolbar/buttons/color.dart @@ -6,6 +6,7 @@ import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; import '../../../translations/toolbar.i18n.dart'; import '../../../utils/color.dart'; +import '../../../utils/extensions/build_context.dart'; import '../../controller.dart'; import '../toolbar.dart'; @@ -15,25 +16,16 @@ import '../toolbar.dart'; /// buttons for each color. class QuillToolbarColorButton extends StatefulWidget { const QuillToolbarColorButton({ - required this.icon, required this.controller, - required this.background, - this.iconSize = kDefaultIconSize, - this.iconTheme, - this.afterButtonPressed, - this.tooltip, - this.dialogBarrierColor = Colors.black54, - Key? key, - }) : super(key: key); - - final IconData icon; - final double iconSize; - final bool background; + required this.isBackground, + this.options = const QuillToolbarColorButtonOptions(), + super.key, + }); + + /// Is this background color button or font color + final bool isBackground; final QuillController controller; - final QuillIconTheme? iconTheme; - final VoidCallback? afterButtonPressed; - final String? tooltip; - final Color dialogBarrierColor; + final QuillToolbarColorButtonOptions options; @override _QuillToolbarColorButtonState createState() => @@ -103,38 +95,97 @@ class _QuillToolbarColorButtonState extends State { super.dispose(); } + QuillToolbarColorButtonOptions get options { + return widget.options; + } + + QuillController get controller { + return options.controller ?? widget.controller; + } + + double get iconSize { + final baseFontSize = baseButtonExtraOptions.globalIconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize; + } + + VoidCallback? get afterButtonPressed { + return options.afterButtonPressed ?? + baseButtonExtraOptions.afterButtonPressed; + } + + QuillIconTheme? get iconTheme { + return options.iconTheme ?? baseButtonExtraOptions.iconTheme; + } + + QuillToolbarBaseButtonOptions get baseButtonExtraOptions { + return context.requireQuillToolbarBaseButtonOptions; + } + + IconData get iconData { + return options.iconData ?? + baseButtonExtraOptions.iconData ?? + (widget.isBackground ? Icons.color_lens : Icons.format_color_fill); + } + + String get tooltip { + return options.tooltip ?? + baseButtonExtraOptions.tooltip ?? + (widget.isBackground ? 'Font color'.i18n : 'Background color'.i18n); + } + @override Widget build(BuildContext context) { final theme = Theme.of(context); - final iconColor = _isToggledColor && !widget.background && !_isWhite + final iconColor = _isToggledColor && !widget.isBackground && !_isWhite ? stringToColor(_selectionStyle.attributes['color']!.value) - : (widget.iconTheme?.iconUnselectedColor ?? theme.iconTheme.color); + : (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color); final iconColorBackground = - _isToggledBackground && widget.background && !_isWhiteBackground + _isToggledBackground && widget.isBackground && !_isWhiteBackground ? stringToColor(_selectionStyle.attributes['background']!.value) - : (widget.iconTheme?.iconUnselectedColor ?? theme.iconTheme.color); + : (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color); - final fillColor = _isToggledColor && !widget.background && _isWhite + final fillColor = _isToggledColor && !widget.isBackground && _isWhite ? stringToColor('#ffffff') - : (widget.iconTheme?.iconUnselectedFillColor ?? theme.canvasColor); + : (iconTheme?.iconUnselectedFillColor ?? theme.canvasColor); final fillColorBackground = - _isToggledBackground && widget.background && _isWhiteBackground + _isToggledBackground && widget.isBackground && _isWhiteBackground ? stringToColor('#ffffff') - : (widget.iconTheme?.iconUnselectedFillColor ?? theme.canvasColor); + : (iconTheme?.iconUnselectedFillColor ?? theme.canvasColor); + + final childBuilder = + options.childBuilder ?? baseButtonExtraOptions.childBuilder; + if (childBuilder != null) { + return childBuilder( + options, + QuillToolbarColorButtonExtraOptions( + controller: controller, + context: context, + onPressed: () { + _showColorPicker(); + afterButtonPressed?.call(); + }, + iconColor: iconColor, + iconColorBackground: iconColorBackground, + fillColor: fillColor, + fillColorBackground: fillColorBackground, + ), + ); + } return QuillToolbarIconButton( - tooltip: widget.tooltip, + tooltip: tooltip, highlightElevation: 0, hoverElevation: 0, - size: widget.iconSize * kIconButtonFactor, - icon: Icon(widget.icon, - size: widget.iconSize, - color: widget.background ? iconColorBackground : iconColor), - fillColor: widget.background ? fillColorBackground : fillColor, - borderRadius: widget.iconTheme?.borderRadius ?? 2, + size: iconSize * kIconButtonFactor, + icon: Icon(iconData, + size: iconSize, + color: widget.isBackground ? iconColorBackground : iconColor), + fillColor: widget.isBackground ? fillColorBackground : fillColor, + borderRadius: iconTheme?.borderRadius ?? 2, onPressed: _showColorPicker, - afterPressed: widget.afterButtonPressed, + afterPressed: afterButtonPressed, ); } @@ -142,7 +193,7 @@ class _QuillToolbarColorButtonState extends State { var hex = colorToHex(color); hex = '#$hex'; widget.controller.formatSelection( - widget.background ? BackgroundAttribute(hex) : ColorAttribute(hex)); + widget.isBackground ? BackgroundAttribute(hex) : ColorAttribute(hex)); } void _showColorPicker() { @@ -151,7 +202,7 @@ class _QuillToolbarColorButtonState extends State { var selectedColor = Colors.black; if (_isToggledColor) { - selectedColor = widget.background + selectedColor = widget.isBackground ? hexToColor(_selectionStyle.attributes['background']?.value) : hexToColor(_selectionStyle.attributes['color']?.value); } @@ -160,9 +211,16 @@ class _QuillToolbarColorButtonState extends State { TextEditingController(text: colorToHex(selectedColor)); late void Function(void Function()) colorBoxSetState; + // TODO: Please make this dialog only responsible for picking the color + // so in the future we will add an option for showing custom method + // defined by the developer for picking dialog, and it will return + // color hex + + // I won't for now to save some time for the refactoring showDialog( context: context, - barrierColor: widget.dialogBarrierColor, + barrierColor: options.dialogBarrierColor ?? + context.requireQuillSharedConfigurations.dialogBarrierColor, builder: (context) => StatefulBuilder(builder: (context, dlgSetState) { return AlertDialog( title: Text('Select Color'.i18n), diff --git a/lib/src/widgets/toolbar/buttons/indent.dart b/lib/src/widgets/toolbar/buttons/indent.dart index 835c568e..f2fa171f 100644 --- a/lib/src/widgets/toolbar/buttons/indent.dart +++ b/lib/src/widgets/toolbar/buttons/indent.dart @@ -1,29 +1,23 @@ import 'package:flutter/material.dart'; +import '../../../models/config/toolbar/buttons/indent.dart'; import '../../../models/themes/quill_icon_theme.dart'; +import '../../../translations/toolbar.i18n.dart'; +import '../../../utils/extensions/build_context.dart'; import '../../controller.dart'; import '../toolbar.dart'; class QuillToolbarIndentButton extends StatefulWidget { const QuillToolbarIndentButton({ - required this.icon, required this.controller, required this.isIncrease, - this.iconSize = kDefaultIconSize, - this.iconTheme, - this.afterButtonPressed, - this.tooltip, - Key? key, - }) : super(key: key); - - final IconData icon; - final double iconSize; + required this.options, + super.key, + }); + final QuillController controller; final bool isIncrease; - final VoidCallback? afterButtonPressed; - - final QuillIconTheme? iconTheme; - final String? tooltip; + final QuillToolbarIndentButtonOptions options; @override _QuillToolbarIndentButtonState createState() => @@ -31,26 +25,66 @@ class QuillToolbarIndentButton extends StatefulWidget { } class _QuillToolbarIndentButtonState extends State { + QuillToolbarIndentButtonOptions get options { + return widget.options; + } + + QuillController get controller { + return options.controller ?? widget.controller; + } + + double get iconSize { + final baseFontSize = baseButtonExtraOptions.globalIconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize; + } + + VoidCallback? get afterButtonPressed { + return options.afterButtonPressed ?? + baseButtonExtraOptions.afterButtonPressed; + } + + QuillIconTheme? get iconTheme { + return options.iconTheme ?? baseButtonExtraOptions.iconTheme; + } + + QuillToolbarBaseButtonOptions get baseButtonExtraOptions { + return context.requireQuillToolbarBaseButtonOptions; + } + + IconData get iconData { + return options.iconData ?? + baseButtonExtraOptions.iconData ?? + (widget.isIncrease + ? Icons.format_indent_increase + : Icons.format_indent_decrease); + } + + String get tooltip { + return options.tooltip ?? + baseButtonExtraOptions.tooltip ?? + (widget.isIncrease ? 'Increase indent'.i18n : 'Decrease indent'.i18n); + } + @override Widget build(BuildContext context) { final theme = Theme.of(context); - final iconColor = - widget.iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; + final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; final iconFillColor = - widget.iconTheme?.iconUnselectedFillColor ?? theme.canvasColor; + iconTheme?.iconUnselectedFillColor ?? theme.canvasColor; return QuillToolbarIconButton( - tooltip: widget.tooltip, + tooltip: tooltip, highlightElevation: 0, hoverElevation: 0, - size: widget.iconSize * kIconButtonFactor, - icon: Icon(widget.icon, size: widget.iconSize, color: iconColor), + size: iconSize * kIconButtonFactor, + icon: Icon(iconData, size: iconSize, color: iconColor), fillColor: iconFillColor, - borderRadius: widget.iconTheme?.borderRadius ?? 2, + borderRadius: iconTheme?.borderRadius ?? 2, onPressed: () { widget.controller.indentSelection(widget.isIncrease); }, - afterPressed: widget.afterButtonPressed, + afterPressed: afterButtonPressed, ); } } diff --git a/lib/src/widgets/toolbar/buttons/select_alignment.dart b/lib/src/widgets/toolbar/buttons/select_alignment.dart index a14a6603..f56b4d68 100644 --- a/lib/src/widgets/toolbar/buttons/select_alignment.dart +++ b/lib/src/widgets/toolbar/buttons/select_alignment.dart @@ -1,39 +1,34 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import '../../../../translations.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; +import '../../../utils/extensions/build_context.dart'; import '../../../utils/widgets.dart'; import '../../controller.dart'; -import '../enum.dart'; import '../toolbar.dart'; class QuillToolbarSelectAlignmentButton extends StatefulWidget { const QuillToolbarSelectAlignmentButton({ required this.controller, - this.iconSize = kDefaultIconSize, - this.iconTheme, + required this.options, this.showLeftAlignment, this.showCenterAlignment, this.showRightAlignment, this.showJustifyAlignment, - this.afterButtonPressed, - this.tooltips = const {}, this.padding, - Key? key, - }) : super(key: key); + super.key, + }); final QuillController controller; - final double iconSize; + final QuillToolbarSelectAlignmentButtonOptions options; - final QuillIconTheme? iconTheme; final bool? showLeftAlignment; final bool? showCenterAlignment; final bool? showRightAlignment; final bool? showJustifyAlignment; - final VoidCallback? afterButtonPressed; - final Map tooltips; final EdgeInsetsGeometry? padding; @override @@ -57,6 +52,113 @@ class _QuillToolbarSelectAlignmentButtonState widget.controller.addListener(_didChangeEditingValue); } + QuillToolbarSelectAlignmentButtonOptions get options { + return widget.options; + } + + QuillController get controller { + return options.controller ?? widget.controller; + } + + double get iconSize { + final baseFontSize = baseButtonExtraOptions.globalIconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize; + } + + VoidCallback? get afterButtonPressed { + return options.afterButtonPressed ?? + baseButtonExtraOptions.afterButtonPressed; + } + + QuillIconTheme? get iconTheme { + return options.iconTheme ?? baseButtonExtraOptions.iconTheme; + } + + QuillToolbarBaseButtonOptions get baseButtonExtraOptions { + return context.requireQuillToolbarBaseButtonOptions; + } + + QuillSelectAlignmentValues get _iconsData { + final iconsData = options.iconsData; + if (iconsData != null) { + return iconsData; + } + final baseIconData = baseButtonExtraOptions.iconData; + if (baseIconData != null) { + return QuillSelectAlignmentValues( + leftAlignment: baseIconData, + centerAlignment: baseIconData, + rightAlignment: baseIconData, + justifyAlignment: baseIconData, + ); + } + return const QuillSelectAlignmentValues( + leftAlignment: Icons.format_align_left, + centerAlignment: Icons.format_align_center, + rightAlignment: Icons.format_align_right, + justifyAlignment: Icons.format_align_justify, + ); + } + + QuillSelectAlignmentValues get _tooltips { + final tooltips = options.tooltips; + if (tooltips != null) { + return tooltips; + } + final baseToolTip = baseButtonExtraOptions.tooltip; + if (baseToolTip != null) { + return QuillSelectAlignmentValues( + leftAlignment: baseToolTip, + centerAlignment: baseToolTip, + rightAlignment: baseToolTip, + justifyAlignment: baseToolTip, + ); + } + return QuillSelectAlignmentValues( + leftAlignment: 'Align left'.i18n, + centerAlignment: 'Align center'.i18n, + rightAlignment: 'Align right'.i18n, + justifyAlignment: 'Justify win width'.i18n, + ); + } + + /// Since it's not safe to call anything related to the context in dispose + /// then we will save a reference to the [controller] + /// and update it in [didChangeDependencies] + /// and use it in dispose method + late QuillController _controller; + + void _didChangeEditingValue() { + setState(() { + _value = _selectionStyle.attributes[Attribute.align.key] ?? + Attribute.leftAlignment; + }); + } + + @override + void didUpdateWidget(covariant QuillToolbarSelectAlignmentButton oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.controller != widget.controller) { + oldWidget.controller.removeListener(_didChangeEditingValue); + widget.controller.addListener(_didChangeEditingValue); + _value = _selectionStyle.attributes[Attribute.align.key] ?? + Attribute.leftAlignment; + } + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _controller = controller; + } + + @override + void dispose() { + _controller.removeListener(_didChangeEditingValue); + super.dispose(); + } + @override Widget build(BuildContext context) { final _valueToText = { @@ -82,16 +184,16 @@ class _QuillToolbarSelectAlignmentButtonState if (widget.showRightAlignment!) Attribute.rightAlignment.value!, if (widget.showJustifyAlignment!) Attribute.justifyAlignment.value!, ]; - final _valueToButtons = { - if (widget.showLeftAlignment!) - Attribute.leftAlignment: ToolbarButtons.leftAlignment, - if (widget.showCenterAlignment!) - Attribute.centerAlignment: ToolbarButtons.centerAlignment, - if (widget.showRightAlignment!) - Attribute.rightAlignment: ToolbarButtons.rightAlignment, - if (widget.showJustifyAlignment!) - Attribute.justifyAlignment: ToolbarButtons.justifyAlignment, - }; + // final _valueToButtons = { + // if (widget.showLeftAlignment!) + // Attribute.leftAlignment: ToolbarButtons.leftAlignment, + // if (widget.showCenterAlignment!) + // Attribute.centerAlignment: ToolbarButtons.centerAlignment, + // if (widget.showRightAlignment!) + // Attribute.rightAlignment: ToolbarButtons.rightAlignment, + // if (widget.showJustifyAlignment!) + // Attribute.justifyAlignment: ToolbarButtons.justifyAlignment, + // }; final theme = Theme.of(context); @@ -100,6 +202,16 @@ class _QuillToolbarSelectAlignmentButtonState ((widget.showRightAlignment!) ? 1 : 0) + ((widget.showJustifyAlignment!) ? 1 : 0); + final childBuilder = + options.childBuilder ?? baseButtonExtraOptions.childBuilder; + + if (childBuilder != null) { + throw UnsupportedError( + 'Sorry but the `childBuilder` for the Select alignment button' + ' is not supported. Yet but we will work on that soon.', + ); + } + return Row( mainAxisSize: MainAxisSize.min, children: List.generate(buttonCount, (index) { @@ -108,46 +220,52 @@ class _QuillToolbarSelectAlignmentButtonState const EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0), child: ConstrainedBox( constraints: BoxConstraints.tightFor( - width: widget.iconSize * kIconButtonFactor, - height: widget.iconSize * kIconButtonFactor, + width: iconSize * kIconButtonFactor, + height: iconSize * kIconButtonFactor, ), child: UtilityWidgets.maybeTooltip( - message: widget.tooltips[_valueToButtons[_valueAttribute[index]]], + message: _valueString[index] == Attribute.leftAlignment.value + ? _tooltips.leftAlignment + : _valueString[index] == Attribute.centerAlignment.value + ? _tooltips.centerAlignment + : _valueString[index] == Attribute.rightAlignment.value + ? _tooltips.rightAlignment + : _tooltips.justifyAlignment, child: RawMaterialButton( hoverElevation: 0, highlightElevation: 0, elevation: 0, visualDensity: VisualDensity.compact, shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - widget.iconTheme?.borderRadius ?? 2)), + borderRadius: + BorderRadius.circular(iconTheme?.borderRadius ?? 2)), fillColor: _valueToText[_value] == _valueString[index] - ? (widget.iconTheme?.iconSelectedFillColor ?? + ? (iconTheme?.iconSelectedFillColor ?? Theme.of(context).primaryColor) - : (widget.iconTheme?.iconUnselectedFillColor ?? - theme.canvasColor), + : (iconTheme?.iconUnselectedFillColor ?? theme.canvasColor), onPressed: () { _valueAttribute[index] == Attribute.leftAlignment ? widget.controller.formatSelection( - Attribute.clone(Attribute.align, null)) + Attribute.clone(Attribute.align, null), + ) : widget.controller .formatSelection(_valueAttribute[index]); - widget.afterButtonPressed?.call(); + afterButtonPressed?.call(); }, child: Icon( _valueString[index] == Attribute.leftAlignment.value - ? Icons.format_align_left + ? _iconsData.leftAlignment : _valueString[index] == Attribute.centerAlignment.value - ? Icons.format_align_center + ? _iconsData.centerAlignment : _valueString[index] == Attribute.rightAlignment.value - ? Icons.format_align_right - : Icons.format_align_justify, - size: widget.iconSize, + ? _iconsData.rightAlignment + : _iconsData.justifyAlignment, + size: iconSize, color: _valueToText[_value] == _valueString[index] - ? (widget.iconTheme?.iconSelectedColor ?? + ? (iconTheme?.iconSelectedColor ?? theme.primaryIconTheme.color) - : (widget.iconTheme?.iconUnselectedColor ?? + : (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color), ), ), @@ -157,28 +275,4 @@ class _QuillToolbarSelectAlignmentButtonState }), ); } - - void _didChangeEditingValue() { - setState(() { - _value = _selectionStyle.attributes[Attribute.align.key] ?? - Attribute.leftAlignment; - }); - } - - @override - void didUpdateWidget(covariant QuillToolbarSelectAlignmentButton oldWidget) { - super.didUpdateWidget(oldWidget); - if (oldWidget.controller != widget.controller) { - oldWidget.controller.removeListener(_didChangeEditingValue); - widget.controller.addListener(_didChangeEditingValue); - _value = _selectionStyle.attributes[Attribute.align.key] ?? - Attribute.leftAlignment; - } - } - - @override - void dispose() { - widget.controller.removeListener(_didChangeEditingValue); - super.dispose(); - } } diff --git a/lib/src/widgets/toolbar/buttons/toggle_check_list.dart b/lib/src/widgets/toolbar/buttons/toggle_check_list.dart index d431c8b1..eec49bde 100644 --- a/lib/src/widgets/toolbar/buttons/toggle_check_list.dart +++ b/lib/src/widgets/toolbar/buttons/toggle_check_list.dart @@ -1,41 +1,27 @@ import 'package:flutter/material.dart'; +import '../../../../translations.dart'; +import '../../../models/config/toolbar/buttons/base.dart'; +import '../../../models/config/toolbar/buttons/toggle_check_list.dart'; import '../../../models/documents/attribute.dart'; import '../../../models/documents/style.dart'; import '../../../models/themes/quill_icon_theme.dart'; +import '../../../utils/extensions/build_context.dart'; import '../../../utils/widgets.dart'; import '../../controller.dart'; -import '../toolbar.dart'; +import 'toggle_style.dart'; class QuillToolbarToggleCheckListButton extends StatefulWidget { const QuillToolbarToggleCheckListButton({ - required this.icon, + required this.options, required this.controller, - required this.attribute, - this.iconSize = kDefaultIconSize, - this.fillColor, - this.childBuilder = defaultToggleStyleButtonBuilder, - this.iconTheme, - this.afterButtonPressed, - this.tooltip, - Key? key, - }) : super(key: key); + super.key, + }); - final IconData icon; - final double iconSize; - - final Color? fillColor; + final QuillToolbarToggleCheckListButtonOptions options; final QuillController controller; - final ToggleStyleButtonBuilder childBuilder; - - final Attribute attribute; - - final QuillIconTheme? iconTheme; - final VoidCallback? afterButtonPressed; - final String? tooltip; - @override _QuillToolbarToggleCheckListButtonState createState() => _QuillToolbarToggleCheckListButtonState(); @@ -45,6 +31,12 @@ class _QuillToolbarToggleCheckListButtonState extends State { bool? _isToggled; + /// Since it's not safe to call anything related to the context in dispose + /// then we will save a reference to the [controller] + /// and update it in [didChangeDependencies] + /// and use it in dispose method + late QuillController _controller; + Style get _selectionStyle => widget.controller.getSelectionStyle(); void _didChangeEditingValue() { @@ -81,43 +73,108 @@ class _QuillToolbarToggleCheckListButtonState @override void didUpdateWidget(covariant QuillToolbarToggleCheckListButton oldWidget) { super.didUpdateWidget(oldWidget); - if (oldWidget.controller != widget.controller) { + if (oldWidget.controller != controller) { oldWidget.controller.removeListener(_didChangeEditingValue); widget.controller.addListener(_didChangeEditingValue); _isToggled = _getIsToggled(_selectionStyle.attributes); } } + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _controller = controller; + } + @override void dispose() { - widget.controller.removeListener(_didChangeEditingValue); + _controller.removeListener(_didChangeEditingValue); super.dispose(); } + QuillToolbarToggleCheckListButtonOptions get options { + return widget.options; + } + + QuillController get controller { + return options.controller ?? widget.controller; + } + + double get iconSize { + final baseFontSize = baseButtonExtraOptions.globalIconSize; + final iconSize = options.iconSize; + return iconSize ?? baseFontSize; + } + + VoidCallback? get afterButtonPressed { + return options.afterButtonPressed ?? + baseButtonExtraOptions.afterButtonPressed; + } + + QuillIconTheme? get iconTheme { + return options.iconTheme ?? baseButtonExtraOptions.iconTheme; + } + + QuillToolbarBaseButtonOptions get baseButtonExtraOptions { + return context.requireQuillToolbarBaseButtonOptions; + } + + IconData get iconData { + return options.iconData ?? + baseButtonExtraOptions.iconData ?? + Icons.check_box; + } + + String get tooltip { + return options.tooltip ?? + baseButtonExtraOptions.tooltip ?? + 'Checked list'.i18n; + } + @override Widget build(BuildContext context) { + final childBuilder = + options.childBuilder ?? baseButtonExtraOptions.childBuilder; + if (childBuilder != null) { + return childBuilder( + QuillToolbarToggleCheckListButtonOptions( + afterButtonPressed: afterButtonPressed, + iconTheme: iconTheme, + controller: controller, + iconSize: iconSize, + tooltip: tooltip, + iconData: iconData, + ), + QuillToolbarToggleCheckListButtonExtraOptions( + context: context, + controller: controller, + onPressed: () { + _toggleAttribute(); + afterButtonPressed?.call(); + }, + isToggled: _isToggled ?? false, + ), + ); + } return UtilityWidgets.maybeTooltip( - message: widget.tooltip, - child: widget.childBuilder( + message: tooltip, + child: defaultToggleStyleButtonBuilder( context, Attribute.unchecked, - widget.icon, - widget.fillColor, + iconData, + options.fillColor, _isToggled, _toggleAttribute, - widget.afterButtonPressed, - widget.iconSize, - widget.iconTheme, + afterButtonPressed, + iconSize, + iconTheme, ), ); } void _toggleAttribute() { - // By default don't show the keybaord request as it's quite annoying - // We will provide the option to control this in the next major update - // See https://github.com/singerdmx/flutter-quill/issues/1440 - widget.controller - ..skipRequestKeyboard = true + controller + ..skipRequestKeyboard = !options.isShouldRequestKeyboard ..formatSelection( _isToggled! ? Attribute.clone(Attribute.unchecked, null) diff --git a/lib/src/widgets/toolbar/enum.dart b/lib/src/widgets/toolbar/enum.dart index 6e9d3ec1..dee62abf 100644 --- a/lib/src/widgets/toolbar/enum.dart +++ b/lib/src/widgets/toolbar/enum.dart @@ -1,33 +1,112 @@ enum ToolbarButtons { - // Not needed anymore, the dev can customize this much easier now - // in the toolbarConfigurations of the QuillProvider + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') undo, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') redo, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') fontFamily, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') fontSize, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') bold, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') subscript, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') superscript, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') italic, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') small, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') underline, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') strikeThrough, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') inlineCode, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') color, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') backgroundColor, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') clearFormat, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') centerAlignment, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') leftAlignment, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') rightAlignment, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') justifyAlignment, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') direction, headerStyle, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') listNumbers, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') listBullets, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') listChecks, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') codeBlock, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') quote, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') indentIncrease, + @Deprecated('Please customize the button in the QuillProvider. ' + 'You will find toolbarConfigurations and then buttons and pass a value' + ' and change what you want, the tooltip for spesefic button for example') indentDecrease, link, search, diff --git a/lib/src/widgets/toolbar/toolbar.dart b/lib/src/widgets/toolbar/toolbar.dart index f61d4390..590b4b2b 100644 --- a/lib/src/widgets/toolbar/toolbar.dart +++ b/lib/src/widgets/toolbar/toolbar.dart @@ -160,32 +160,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { //default button tooltips final buttonTooltips = tooltips ?? { - ToolbarButtons.fontFamily: 'Font family'.i18n, - ToolbarButtons.fontSize: 'Font size'.i18n, - ToolbarButtons.bold: 'Bold'.i18n, - ToolbarButtons.subscript: 'Subscript'.i18n, - ToolbarButtons.superscript: 'Superscript'.i18n, - ToolbarButtons.italic: 'Italic'.i18n, - ToolbarButtons.small: 'Small'.i18n, - ToolbarButtons.underline: 'Underline'.i18n, - ToolbarButtons.strikeThrough: 'Strike through'.i18n, - ToolbarButtons.inlineCode: 'Inline code'.i18n, - ToolbarButtons.color: 'Font color'.i18n, - ToolbarButtons.backgroundColor: 'Background color'.i18n, - ToolbarButtons.clearFormat: 'Clear format'.i18n, - ToolbarButtons.leftAlignment: 'Align left'.i18n, - ToolbarButtons.centerAlignment: 'Align center'.i18n, - ToolbarButtons.rightAlignment: 'Align right'.i18n, - ToolbarButtons.justifyAlignment: 'Justify win width'.i18n, - ToolbarButtons.direction: 'Text direction'.i18n, ToolbarButtons.headerStyle: 'Header style'.i18n, - ToolbarButtons.listNumbers: 'Numbered list'.i18n, - ToolbarButtons.listBullets: 'Bullet list'.i18n, - ToolbarButtons.listChecks: 'Checked list'.i18n, - ToolbarButtons.codeBlock: 'Code block'.i18n, - ToolbarButtons.quote: 'Quote'.i18n, - ToolbarButtons.indentIncrease: 'Increase indent'.i18n, - ToolbarButtons.indentDecrease: 'Decrease indent'.i18n, ToolbarButtons.link: 'Insert URL'.i18n, ToolbarButtons.search: 'Search'.i18n, }; @@ -237,12 +212,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { options: toolbarConfigurations.buttonOptions.bold, controller: toolbarConfigurations.buttonOptions.bold.controller ?? context.requireQuillController, - // icon: Icons.format_bold, - // iconSize: toolbarIconSize, - // tooltip: buttonTooltips[ToolbarButtons.bold], - // controller: controller, - // iconTheme: iconTheme, - // afterButtonPressed: afterButtonPressed, ), if (showSubscript) QuillToolbarToggleStyleButton( @@ -251,12 +220,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { controller: toolbarConfigurations.buttonOptions.subscript.controller ?? context.requireQuillController, - // icon: Icons.subscript, - // iconSize: toolbarIconSize, - // tooltip: buttonTooltips[ToolbarButtons.subscript], - // controller: controller, - // iconTheme: iconTheme, - // afterButtonPressed: afterButtonPressed, ), if (showSuperscript) QuillToolbarToggleStyleButton( @@ -265,12 +228,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { controller: toolbarConfigurations.buttonOptions.superscript.controller ?? context.requireQuillController, - // icon: Icons.superscript, - // iconSize: toolbarIconSize, - // tooltip: buttonTooltips[ToolbarButtons.superscript], - // controller: controller, - // iconTheme: iconTheme, - // afterButtonPressed: afterButtonPressed, ), if (showItalicButton) QuillToolbarToggleStyleButton( @@ -279,12 +236,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { controller: toolbarConfigurations.buttonOptions.italic.controller ?? context.requireQuillController, - // icon: Icons.format_italic, - // iconSize: toolbarIconSize, - // tooltip: buttonTooltips[ToolbarButtons.italic], - // controller: controller, - // iconTheme: iconTheme, - // afterButtonPressed: afterButtonPressed, ), if (showSmallButton) QuillToolbarToggleStyleButton( @@ -293,12 +244,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { controller: toolbarConfigurations.buttonOptions.small.controller ?? context.requireQuillController, - // icon: Icons.format_size, - // iconSize: toolbarIconSize, - // tooltip: buttonTooltips[ToolbarButtons.small], - // controller: controller, - // iconTheme: iconTheme, - // afterButtonPressed: afterButtonPressed, ), if (showUnderLineButton) QuillToolbarToggleStyleButton( @@ -307,12 +252,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { controller: toolbarConfigurations.buttonOptions.underLine.controller ?? context.requireQuillController, - // icon: Icons.format_underline, - // iconSize: toolbarIconSize, - // tooltip: buttonTooltips[ToolbarButtons.underline], - // controller: controller, - // iconTheme: iconTheme, - // afterButtonPressed: afterButtonPressed, ), if (showStrikeThrough) QuillToolbarToggleStyleButton( @@ -321,12 +260,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { controller: toolbarConfigurations .buttonOptions.strikeThrough.controller ?? context.requireQuillController, - // icon: Icons.format_strikethrough, - // iconSize: toolbarIconSize, - // tooltip: buttonTooltips[ToolbarButtons.strikeThrough], - // controller: controller, - // iconTheme: iconTheme, - // afterButtonPressed: afterButtonPressed, ), if (showInlineCode) QuillToolbarToggleStyleButton( @@ -335,45 +268,23 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { controller: toolbarConfigurations.buttonOptions.inlineCode.controller ?? context.requireQuillController, - // icon: Icons.code, - // iconSize: toolbarIconSize, - // tooltip: buttonTooltips[ToolbarButtons.inlineCode], - // controller: controller, - // iconTheme: iconTheme, - // afterButtonPressed: afterButtonPressed, ), if (showColorButton) QuillToolbarColorButton( - icon: Icons.color_lens, - iconSize: toolbarIconSize, - tooltip: buttonTooltips[ToolbarButtons.color], controller: controller, - background: false, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, - dialogBarrierColor: - context.requireQuillSharedConfigurations.dialogBarrierColor, + isBackground: false, + options: toolbarConfigurations.buttonOptions.color, ), if (showBackgroundColorButton) QuillToolbarColorButton( - icon: Icons.format_color_fill, - iconSize: toolbarIconSize, - tooltip: buttonTooltips[ToolbarButtons.backgroundColor], + options: toolbarConfigurations.buttonOptions.backgroundColor, controller: controller, - background: true, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, - dialogBarrierColor: - context.requireQuillSharedConfigurations.dialogBarrierColor, + isBackground: true, ), if (showClearFormat) QuillToolbarClearFormatButton( - icon: Icons.format_clear, - iconSize: toolbarIconSize, - tooltip: buttonTooltips[ToolbarButtons.clearFormat], controller: controller, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.clearFormat, ), if (embedButtons != null) for (final builder in embedButtons) @@ -393,20 +304,19 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { if (showAlignmentButtons) QuillToolbarSelectAlignmentButton( controller: controller, - tooltips: Map.of(buttonTooltips) - ..removeWhere((key, value) => ![ - ToolbarButtons.leftAlignment, - ToolbarButtons.centerAlignment, - ToolbarButtons.rightAlignment, - ToolbarButtons.justifyAlignment, - ].contains(key)), - iconSize: toolbarIconSize, - iconTheme: iconTheme, + options: + toolbarConfigurations.buttonOptions.selectAlignmentButtons, + // tooltips: Map.of(buttonTooltips) + // ..removeWhere((key, value) => ![ + // ToolbarButtons.leftAlignment, + // ToolbarButtons.centerAlignment, + // ToolbarButtons.rightAlignment, + // ToolbarButtons.justifyAlignment, + // ].contains(key)), showLeftAlignment: showLeftAlignment, showCenterAlignment: showCenterAlignment, showRightAlignment: showRightAlignment, showJustifyAlignment: showJustifyAlignment, - afterButtonPressed: afterButtonPressed, ), if (showDirection) QuillToolbarToggleStyleButton( @@ -415,12 +325,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { controller: toolbarConfigurations.buttonOptions.direction.controller ?? context.requireQuillController, - // tooltip: buttonTooltips[ToolbarButtons.direction], - // controller: controller, - // icon: Icons.format_textdirection_r_to_l, - // iconSize: toolbarIconSize, - // iconTheme: iconTheme, - // afterButtonPressed: afterButtonPressed, ), if (showDividers && isButtonGroupShown[1] && @@ -460,12 +364,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { controller: toolbarConfigurations.buttonOptions.listNumbers.controller ?? context.requireQuillController, - // tooltip: buttonTooltips[ToolbarButtons.listNumbers], - // controller: controller, - // icon: Icons.format_list_numbered, - // iconSize: toolbarIconSize, - // iconTheme: iconTheme, - // afterButtonPressed: afterButtonPressed, ), if (showListBullets) QuillToolbarToggleStyleButton( @@ -474,22 +372,13 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { controller: toolbarConfigurations.buttonOptions.listBullets.controller ?? context.requireQuillController, - // tooltip: buttonTooltips[ToolbarButtons.listBullets], - // controller: controller, - // icon: Icons.format_list_bulleted, - // iconSize: toolbarIconSize, - // iconTheme: iconTheme, - // afterButtonPressed: afterButtonPressed, ), if (showListCheck) QuillToolbarToggleCheckListButton( - attribute: Attribute.unchecked, - tooltip: buttonTooltips[ToolbarButtons.listChecks], - controller: controller, - icon: Icons.check_box, - iconSize: toolbarIconSize, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.toggleCheckList, + controller: toolbarConfigurations + .buttonOptions.toggleCheckList.controller ?? + context.requireQuillController, ), if (showCodeBlock) QuillToolbarToggleStyleButton( @@ -498,12 +387,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { controller: toolbarConfigurations.buttonOptions.codeBlock.controller ?? context.requireQuillController, - // tooltip: buttonTooltips[ToolbarButtons.codeBlock], - // controller: controller, - // icon: Icons.code, - // iconSize: toolbarIconSize, - // iconTheme: iconTheme, - // afterButtonPressed: afterButtonPressed, ), if (showDividers && isButtonGroupShown[3] && @@ -517,32 +400,22 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { toolbarConfigurations.buttonOptions.quote.controller ?? context.requireQuillController, attribute: Attribute.blockQuote, - // tooltip: buttonTooltips[ToolbarButtons.quote], - // controller: controller, - // icon: Icons.format_quote, - // iconSize: toolbarIconSize, - // iconTheme: iconTheme, - // afterButtonPressed: afterButtonPressed, ), if (showIndent) QuillToolbarIndentButton( - icon: Icons.format_indent_increase, - iconSize: toolbarIconSize, - tooltip: buttonTooltips[ToolbarButtons.indentIncrease], - controller: controller, + controller: toolbarConfigurations + .buttonOptions.indentIncrease.controller ?? + context.requireQuillController, isIncrease: true, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.indentIncrease, ), if (showIndent) QuillToolbarIndentButton( - icon: Icons.format_indent_decrease, - iconSize: toolbarIconSize, - tooltip: buttonTooltips[ToolbarButtons.indentDecrease], - controller: controller, + controller: toolbarConfigurations + .buttonOptions.indentDecrease.controller ?? + context.requireQuillController, isIncrease: false, - iconTheme: iconTheme, - afterButtonPressed: afterButtonPressed, + options: toolbarConfigurations.buttonOptions.indentDecrease, ), if (showDividers && isButtonGroupShown[4] && isButtonGroupShown[5]) QuillToolbarDivider(axis, @@ -680,10 +553,10 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { class QuillToolbarDivider extends StatelessWidget { const QuillToolbarDivider( this.axis, { - Key? key, + super.key, this.color, this.space, - }) : super(key: key); + }); /// Provides a horizontal divider for vertical toolbar. const QuillToolbarDivider.horizontal({Color? color, double? space}) diff --git a/pubspec.yaml b/pubspec.yaml index 64b4af37..afb06e53 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,8 +1,14 @@ 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. -version: 7.7.0 +version: 7.8.0 homepage: https://1o24bbs.com/c/bulletjournal/108 repository: https://github.com/singerdmx/flutter-quill +topics: + - ui + - effects + - widgets + - widget + - rich text editor platforms: android: ios: @@ -31,6 +37,7 @@ dependencies: platform: ^3.1.3 pasteboard: ^0.2.0 equatable: ^2.0.5 + flutter_animate: ^4.2.0+1 flutter_test: sdk: flutter