Major update step 4 (#1454)

pull/1456/head
Ahmed Hnewa 1 year ago committed by GitHub
parent ac8c30d18c
commit ee19189bf4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      CHANGELOG.md
  2. 31
      README.md
  3. 30
      lib/src/models/config/others/animations.dart
  4. 10
      lib/src/models/config/shared_configurations.dart
  5. 26
      lib/src/models/config/toolbar/buttons/clear_format.dart
  6. 43
      lib/src/models/config/toolbar/buttons/color.dart
  7. 27
      lib/src/models/config/toolbar/buttons/indent.dart
  8. 58
      lib/src/models/config/toolbar/buttons/select_alignment.dart
  9. 46
      lib/src/models/config/toolbar/buttons/toggle_check_list.dart
  10. 29
      lib/src/models/config/toolbar/configurations.dart
  11. 7
      lib/src/utils/experimental.dart
  12. 27
      lib/src/widgets/style_widgets/checkbox_point.dart
  13. 15
      lib/src/widgets/text_block.dart
  14. 132
      lib/src/widgets/toolbar/buttons/clear_format.dart
  15. 130
      lib/src/widgets/toolbar/buttons/color.dart
  16. 78
      lib/src/widgets/toolbar/buttons/indent.dart
  17. 218
      lib/src/widgets/toolbar/buttons/select_alignment.dart
  18. 131
      lib/src/widgets/toolbar/buttons/toggle_check_list.dart
  19. 83
      lib/src/widgets/toolbar/enum.dart
  20. 183
      lib/src/widgets/toolbar/toolbar.dart
  21. 9
      pubspec.yaml

@ -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] ## [7.7.0]
- **Breaking change**: We have mirgrated more buttons in the toolbar configurations, you can do change them in the `QuillProvider` - **Breaking change**: We have mirgrated more buttons in the toolbar configurations, you can do change them in the `QuillProvider`

@ -42,6 +42,37 @@ Pub: [FlutterQuill]
--- ---
## Installation
```yaml
dependencies:
flutter_quill: ^<latest-version-here>
```
<p align="center">OR</p>
```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 ## Usage
See the `example` directory for a minimal example of how to use FlutterQuill. You typically just need to instantiate a controller: See the `example` directory for a minimal example of how to use FlutterQuill. You typically just need to instantiate a controller:

@ -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<Object?> get props => [];
}

@ -2,6 +2,9 @@ import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart' show Color, Colors, Locale; import 'package:flutter/material.dart' show Color, Colors, Locale;
import './editor/configurations.dart' show QuillEditorConfigurations; import './editor/configurations.dart' show QuillEditorConfigurations;
import './toolbar/configurations.dart' show QuillToolbarConfigurations; import './toolbar/configurations.dart' show QuillToolbarConfigurations;
import 'others/animations.dart';
export './others/animations.dart';
/// The shared configurations between [QuillEditorConfigurations] and /// The shared configurations between [QuillEditorConfigurations] and
/// [QuillToolbarConfigurations] so we don't duplicate things /// [QuillToolbarConfigurations] so we don't duplicate things
@ -9,6 +12,9 @@ class QuillSharedConfigurations extends Equatable {
const QuillSharedConfigurations({ const QuillSharedConfigurations({
this.dialogBarrierColor = Colors.black54, this.dialogBarrierColor = Colors.black54,
this.locale, this.locale,
this.animationConfigurations = const QuillAnimationConfigurations(
checkBoxPointItem: false,
),
}); });
// This is just example or showcase of this major update to make the library // 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 /// More https://github.com/singerdmx/flutter-quill#translation
final Locale? locale; final Locale? locale;
/// To configure which animations you want to be enabled
final QuillAnimationConfigurations animationConfigurations;
@override @override
List<Object?> get props => [ List<Object?> get props => [
dialogBarrierColor, dialogBarrierColor,
locale, locale,
animationConfigurations,
]; ];
} }

@ -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<QuillToolbarClearFormatButtonOptions,
QuillToolbarClearFormatButtonExtraOptions> {
const QuillToolbarClearFormatButtonOptions({
super.iconData,
super.afterButtonPressed,
super.childBuilder,
super.controller,
super.iconTheme,
super.tooltip,
this.iconSize,
});
final double? iconSize;
}

@ -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;
}

@ -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;
}

@ -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<IconData>? iconsData;
/// By default will use the localized tooltips
final QuillSelectAlignmentValues<String>? 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<T> {
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;
}

@ -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;
}

@ -2,15 +2,24 @@ import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/foundation.dart' show immutable;
import 'buttons/base.dart'; import 'buttons/base.dart';
import 'buttons/clear_format.dart';
import 'buttons/color.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';
import 'buttons/indent.dart';
import 'buttons/select_alignment.dart';
import 'buttons/toggle_check_list.dart';
import 'buttons/toggle_style.dart'; import 'buttons/toggle_style.dart';
export './buttons/base.dart'; export './buttons/base.dart';
export './buttons/clear_format.dart';
export './buttons/color.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';
export './buttons/select_alignment.dart';
export './buttons/toggle_check_list.dart';
export './buttons/toggle_style.dart'; export './buttons/toggle_style.dart';
/// The default size of the icon of a button. /// The default size of the icon of a button.
@ -120,6 +129,14 @@ class QuillToolbarButtonOptions extends Equatable {
this.listBullets = const QuillToolbarToggleStyleButtonOptions(), this.listBullets = const QuillToolbarToggleStyleButtonOptions(),
this.codeBlock = const QuillToolbarToggleStyleButtonOptions(), this.codeBlock = const QuillToolbarToggleStyleButtonOptions(),
this.quote = 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 /// 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 listBullets;
final QuillToolbarToggleStyleButtonOptions codeBlock; final QuillToolbarToggleStyleButtonOptions codeBlock;
final QuillToolbarToggleStyleButtonOptions quote; 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 @override
List<Object?> get props => [ List<Object?> get props => [

@ -0,0 +1,7 @@
import 'package:flutter/foundation.dart' show immutable;
@immutable
class Experimental {
const Experimental([this.reason = 'Experimental feature']);
final String reason;
}

@ -1,4 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import '../../utils/extensions/build_context.dart';
class CheckboxPoint extends StatefulWidget { class CheckboxPoint extends StatefulWidget {
const CheckboxPoint({ const CheckboxPoint({
@ -43,7 +46,7 @@ class _CheckboxPointState extends State<CheckboxPoint> {
: (widget.enabled : (widget.enabled
? theme.colorScheme.onSurface.withOpacity(0.5) ? theme.colorScheme.onSurface.withOpacity(0.5)
: theme.colorScheme.onSurface.withOpacity(0.3)); : theme.colorScheme.onSurface.withOpacity(0.3));
return Container( final child = Container(
alignment: AlignmentDirectional.centerEnd, alignment: AlignmentDirectional.centerEnd,
padding: EdgeInsetsDirectional.only(end: widget.size / 2), padding: EdgeInsetsDirectional.only(end: widget.size / 2),
child: SizedBox( child: SizedBox(
@ -61,13 +64,31 @@ class _CheckboxPointState extends State<CheckboxPoint> {
onTap: onTap:
widget.enabled ? () => widget.onChanged(!widget.value) : null, widget.enabled ? () => widget.onChanged(!widget.value) : null,
child: widget.value child: widget.value
? Icon(Icons.check, ? Icon(
size: widget.size, color: theme.colorScheme.onPrimary) Icons.check,
size: widget.size,
color: theme.colorScheme.onPrimary,
)
: null, : 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;
} }
} }

@ -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( return CheckboxPoint(
size: fontSize, size: fontSize,
value: true, value: attrs[Attribute.list.key] == Attribute.checked,
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,
enabled: !readOnly, enabled: !readOnly,
onChanged: (checked) => onCheckboxTap(line.documentOffset, checked), onChanged: (checked) => onCheckboxTap(line.documentOffset, checked),
uiBuilder: defaultStyles.lists?.checkboxUIBuilder, uiBuilder: defaultStyles.lists?.checkboxUIBuilder,

@ -1,64 +1,114 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../../translations.dart';
import '../../../models/documents/attribute.dart'; import '../../../models/documents/attribute.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 '../../controller.dart';
import '../toolbar.dart'; import '../toolbar.dart';
class QuillToolbarClearFormatButton extends StatefulWidget { class QuillToolbarClearFormatButton extends StatelessWidget {
const QuillToolbarClearFormatButton({ const QuillToolbarClearFormatButton({
required this.icon, required QuillController controller,
required this.controller, required this.options,
this.iconSize = kDefaultIconSize, super.key,
this.iconTheme, }) : _controller = controller;
this.afterButtonPressed,
this.tooltip,
Key? key,
}) : super(key: key);
final IconData icon; final QuillController _controller;
final double iconSize; final QuillToolbarClearFormatButtonOptions options;
final QuillController controller; QuillController get controller {
return options.controller ?? _controller;
}
final QuillIconTheme? iconTheme; double _iconSize(BuildContext context) {
final VoidCallback? afterButtonPressed; final baseFontSize = baseButtonExtraOptions(context).globalIconSize;
final String? tooltip; final iconSize = options.iconSize;
return iconSize ?? baseFontSize;
}
@override VoidCallback? _afterButtonPressed(BuildContext context) {
_QuillToolbarClearFormatButtonState createState() => return options.afterButtonPressed ??
_QuillToolbarClearFormatButtonState(); 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 = <Attribute>{};
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<QuillToolbarClearFormatButton> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
final iconColor = final iconTheme = _iconTheme(context);
widget.iconTheme?.iconUnselectedColor ?? theme.iconTheme.color; final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color;
final fillColor = final fillColor = iconTheme?.iconUnselectedFillColor ?? theme.canvasColor;
widget.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( return QuillToolbarIconButton(
tooltip: widget.tooltip, tooltip: tooltip,
highlightElevation: 0, highlightElevation: 0,
hoverElevation: 0, hoverElevation: 0,
size: widget.iconSize * kIconButtonFactor, size: iconSize * kIconButtonFactor,
icon: Icon(widget.icon, size: widget.iconSize, color: iconColor), icon: Icon(iconData, size: iconSize, color: iconColor),
fillColor: fillColor, fillColor: fillColor,
borderRadius: widget.iconTheme?.borderRadius ?? 2, borderRadius: iconTheme?.borderRadius ?? 2,
onPressed: () { onPressed: _sharedOnPressed,
final attrs = <Attribute>{}; afterPressed: afterButtonPressed,
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,
); );
} }
} }

@ -6,6 +6,7 @@ import '../../../models/documents/style.dart';
import '../../../models/themes/quill_icon_theme.dart'; import '../../../models/themes/quill_icon_theme.dart';
import '../../../translations/toolbar.i18n.dart'; import '../../../translations/toolbar.i18n.dart';
import '../../../utils/color.dart'; import '../../../utils/color.dart';
import '../../../utils/extensions/build_context.dart';
import '../../controller.dart'; import '../../controller.dart';
import '../toolbar.dart'; import '../toolbar.dart';
@ -15,25 +16,16 @@ import '../toolbar.dart';
/// buttons for each color. /// buttons for each color.
class QuillToolbarColorButton extends StatefulWidget { class QuillToolbarColorButton extends StatefulWidget {
const QuillToolbarColorButton({ const QuillToolbarColorButton({
required this.icon,
required this.controller, required this.controller,
required this.background, required this.isBackground,
this.iconSize = kDefaultIconSize, this.options = const QuillToolbarColorButtonOptions(),
this.iconTheme, super.key,
this.afterButtonPressed, });
this.tooltip,
this.dialogBarrierColor = Colors.black54, /// Is this background color button or font color
Key? key, final bool isBackground;
}) : super(key: key);
final IconData icon;
final double iconSize;
final bool background;
final QuillController controller; final QuillController controller;
final QuillIconTheme? iconTheme; final QuillToolbarColorButtonOptions options;
final VoidCallback? afterButtonPressed;
final String? tooltip;
final Color dialogBarrierColor;
@override @override
_QuillToolbarColorButtonState createState() => _QuillToolbarColorButtonState createState() =>
@ -103,38 +95,97 @@ class _QuillToolbarColorButtonState extends State<QuillToolbarColorButton> {
super.dispose(); 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
final iconColor = _isToggledColor && !widget.background && !_isWhite final iconColor = _isToggledColor && !widget.isBackground && !_isWhite
? stringToColor(_selectionStyle.attributes['color']!.value) ? stringToColor(_selectionStyle.attributes['color']!.value)
: (widget.iconTheme?.iconUnselectedColor ?? theme.iconTheme.color); : (iconTheme?.iconUnselectedColor ?? theme.iconTheme.color);
final iconColorBackground = final iconColorBackground =
_isToggledBackground && widget.background && !_isWhiteBackground _isToggledBackground && widget.isBackground && !_isWhiteBackground
? stringToColor(_selectionStyle.attributes['background']!.value) ? 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') ? stringToColor('#ffffff')
: (widget.iconTheme?.iconUnselectedFillColor ?? theme.canvasColor); : (iconTheme?.iconUnselectedFillColor ?? theme.canvasColor);
final fillColorBackground = final fillColorBackground =
_isToggledBackground && widget.background && _isWhiteBackground _isToggledBackground && widget.isBackground && _isWhiteBackground
? stringToColor('#ffffff') ? 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( return QuillToolbarIconButton(
tooltip: widget.tooltip, tooltip: tooltip,
highlightElevation: 0, highlightElevation: 0,
hoverElevation: 0, hoverElevation: 0,
size: widget.iconSize * kIconButtonFactor, size: iconSize * kIconButtonFactor,
icon: Icon(widget.icon, icon: Icon(iconData,
size: widget.iconSize, size: iconSize,
color: widget.background ? iconColorBackground : iconColor), color: widget.isBackground ? iconColorBackground : iconColor),
fillColor: widget.background ? fillColorBackground : fillColor, fillColor: widget.isBackground ? fillColorBackground : fillColor,
borderRadius: widget.iconTheme?.borderRadius ?? 2, borderRadius: iconTheme?.borderRadius ?? 2,
onPressed: _showColorPicker, onPressed: _showColorPicker,
afterPressed: widget.afterButtonPressed, afterPressed: afterButtonPressed,
); );
} }
@ -142,7 +193,7 @@ class _QuillToolbarColorButtonState extends State<QuillToolbarColorButton> {
var hex = colorToHex(color); var hex = colorToHex(color);
hex = '#$hex'; hex = '#$hex';
widget.controller.formatSelection( widget.controller.formatSelection(
widget.background ? BackgroundAttribute(hex) : ColorAttribute(hex)); widget.isBackground ? BackgroundAttribute(hex) : ColorAttribute(hex));
} }
void _showColorPicker() { void _showColorPicker() {
@ -151,7 +202,7 @@ class _QuillToolbarColorButtonState extends State<QuillToolbarColorButton> {
var selectedColor = Colors.black; var selectedColor = Colors.black;
if (_isToggledColor) { if (_isToggledColor) {
selectedColor = widget.background selectedColor = widget.isBackground
? hexToColor(_selectionStyle.attributes['background']?.value) ? hexToColor(_selectionStyle.attributes['background']?.value)
: hexToColor(_selectionStyle.attributes['color']?.value); : hexToColor(_selectionStyle.attributes['color']?.value);
} }
@ -160,9 +211,16 @@ class _QuillToolbarColorButtonState extends State<QuillToolbarColorButton> {
TextEditingController(text: colorToHex(selectedColor)); TextEditingController(text: colorToHex(selectedColor));
late void Function(void Function()) colorBoxSetState; 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<String>( showDialog<String>(
context: context, context: context,
barrierColor: widget.dialogBarrierColor, barrierColor: options.dialogBarrierColor ??
context.requireQuillSharedConfigurations.dialogBarrierColor,
builder: (context) => StatefulBuilder(builder: (context, dlgSetState) { builder: (context) => StatefulBuilder(builder: (context, dlgSetState) {
return AlertDialog( return AlertDialog(
title: Text('Select Color'.i18n), title: Text('Select Color'.i18n),

@ -1,29 +1,23 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../models/config/toolbar/buttons/indent.dart';
import '../../../models/themes/quill_icon_theme.dart'; import '../../../models/themes/quill_icon_theme.dart';
import '../../../translations/toolbar.i18n.dart';
import '../../../utils/extensions/build_context.dart';
import '../../controller.dart'; import '../../controller.dart';
import '../toolbar.dart'; import '../toolbar.dart';
class QuillToolbarIndentButton extends StatefulWidget { class QuillToolbarIndentButton extends StatefulWidget {
const QuillToolbarIndentButton({ const QuillToolbarIndentButton({
required this.icon,
required this.controller, required this.controller,
required this.isIncrease, required this.isIncrease,
this.iconSize = kDefaultIconSize, required this.options,
this.iconTheme, super.key,
this.afterButtonPressed, });
this.tooltip,
Key? key,
}) : super(key: key);
final IconData icon;
final double iconSize;
final QuillController controller; final QuillController controller;
final bool isIncrease; final bool isIncrease;
final VoidCallback? afterButtonPressed; final QuillToolbarIndentButtonOptions options;
final QuillIconTheme? iconTheme;
final String? tooltip;
@override @override
_QuillToolbarIndentButtonState createState() => _QuillToolbarIndentButtonState createState() =>
@ -31,26 +25,66 @@ class QuillToolbarIndentButton extends StatefulWidget {
} }
class _QuillToolbarIndentButtonState extends State<QuillToolbarIndentButton> { class _QuillToolbarIndentButtonState extends State<QuillToolbarIndentButton> {
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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
final iconColor = final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color;
widget.iconTheme?.iconUnselectedColor ?? theme.iconTheme.color;
final iconFillColor = final iconFillColor =
widget.iconTheme?.iconUnselectedFillColor ?? theme.canvasColor; iconTheme?.iconUnselectedFillColor ?? theme.canvasColor;
return QuillToolbarIconButton( return QuillToolbarIconButton(
tooltip: widget.tooltip, tooltip: tooltip,
highlightElevation: 0, highlightElevation: 0,
hoverElevation: 0, hoverElevation: 0,
size: widget.iconSize * kIconButtonFactor, size: iconSize * kIconButtonFactor,
icon: Icon(widget.icon, size: widget.iconSize, color: iconColor), icon: Icon(iconData, size: iconSize, color: iconColor),
fillColor: iconFillColor, fillColor: iconFillColor,
borderRadius: widget.iconTheme?.borderRadius ?? 2, borderRadius: iconTheme?.borderRadius ?? 2,
onPressed: () { onPressed: () {
widget.controller.indentSelection(widget.isIncrease); widget.controller.indentSelection(widget.isIncrease);
}, },
afterPressed: widget.afterButtonPressed, afterPressed: afterButtonPressed,
); );
} }
} }

@ -1,39 +1,34 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../../translations.dart';
import '../../../models/documents/attribute.dart'; import '../../../models/documents/attribute.dart';
import '../../../models/documents/style.dart'; import '../../../models/documents/style.dart';
import '../../../models/themes/quill_icon_theme.dart'; import '../../../models/themes/quill_icon_theme.dart';
import '../../../utils/extensions/build_context.dart';
import '../../../utils/widgets.dart'; import '../../../utils/widgets.dart';
import '../../controller.dart'; import '../../controller.dart';
import '../enum.dart';
import '../toolbar.dart'; import '../toolbar.dart';
class QuillToolbarSelectAlignmentButton extends StatefulWidget { class QuillToolbarSelectAlignmentButton extends StatefulWidget {
const QuillToolbarSelectAlignmentButton({ const QuillToolbarSelectAlignmentButton({
required this.controller, required this.controller,
this.iconSize = kDefaultIconSize, required this.options,
this.iconTheme,
this.showLeftAlignment, this.showLeftAlignment,
this.showCenterAlignment, this.showCenterAlignment,
this.showRightAlignment, this.showRightAlignment,
this.showJustifyAlignment, this.showJustifyAlignment,
this.afterButtonPressed,
this.tooltips = const <ToolbarButtons, String>{},
this.padding, this.padding,
Key? key, super.key,
}) : super(key: key); });
final QuillController controller; final QuillController controller;
final double iconSize; final QuillToolbarSelectAlignmentButtonOptions options;
final QuillIconTheme? iconTheme;
final bool? showLeftAlignment; final bool? showLeftAlignment;
final bool? showCenterAlignment; final bool? showCenterAlignment;
final bool? showRightAlignment; final bool? showRightAlignment;
final bool? showJustifyAlignment; final bool? showJustifyAlignment;
final VoidCallback? afterButtonPressed;
final Map<ToolbarButtons, String> tooltips;
final EdgeInsetsGeometry? padding; final EdgeInsetsGeometry? padding;
@override @override
@ -57,6 +52,113 @@ class _QuillToolbarSelectAlignmentButtonState
widget.controller.addListener(_didChangeEditingValue); 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<IconData> 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<String> 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final _valueToText = <Attribute, String>{ final _valueToText = <Attribute, String>{
@ -82,16 +184,16 @@ class _QuillToolbarSelectAlignmentButtonState
if (widget.showRightAlignment!) Attribute.rightAlignment.value!, if (widget.showRightAlignment!) Attribute.rightAlignment.value!,
if (widget.showJustifyAlignment!) Attribute.justifyAlignment.value!, if (widget.showJustifyAlignment!) Attribute.justifyAlignment.value!,
]; ];
final _valueToButtons = <Attribute, ToolbarButtons>{ // final _valueToButtons = <Attribute, ToolbarButtons>{
if (widget.showLeftAlignment!) // if (widget.showLeftAlignment!)
Attribute.leftAlignment: ToolbarButtons.leftAlignment, // Attribute.leftAlignment: ToolbarButtons.leftAlignment,
if (widget.showCenterAlignment!) // if (widget.showCenterAlignment!)
Attribute.centerAlignment: ToolbarButtons.centerAlignment, // Attribute.centerAlignment: ToolbarButtons.centerAlignment,
if (widget.showRightAlignment!) // if (widget.showRightAlignment!)
Attribute.rightAlignment: ToolbarButtons.rightAlignment, // Attribute.rightAlignment: ToolbarButtons.rightAlignment,
if (widget.showJustifyAlignment!) // if (widget.showJustifyAlignment!)
Attribute.justifyAlignment: ToolbarButtons.justifyAlignment, // Attribute.justifyAlignment: ToolbarButtons.justifyAlignment,
}; // };
final theme = Theme.of(context); final theme = Theme.of(context);
@ -100,6 +202,16 @@ class _QuillToolbarSelectAlignmentButtonState
((widget.showRightAlignment!) ? 1 : 0) + ((widget.showRightAlignment!) ? 1 : 0) +
((widget.showJustifyAlignment!) ? 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( return Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: List.generate(buttonCount, (index) { children: List.generate(buttonCount, (index) {
@ -108,46 +220,52 @@ class _QuillToolbarSelectAlignmentButtonState
const EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0), const EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0),
child: ConstrainedBox( child: ConstrainedBox(
constraints: BoxConstraints.tightFor( constraints: BoxConstraints.tightFor(
width: widget.iconSize * kIconButtonFactor, width: iconSize * kIconButtonFactor,
height: widget.iconSize * kIconButtonFactor, height: iconSize * kIconButtonFactor,
), ),
child: UtilityWidgets.maybeTooltip( 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( child: RawMaterialButton(
hoverElevation: 0, hoverElevation: 0,
highlightElevation: 0, highlightElevation: 0,
elevation: 0, elevation: 0,
visualDensity: VisualDensity.compact, visualDensity: VisualDensity.compact,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular( borderRadius:
widget.iconTheme?.borderRadius ?? 2)), BorderRadius.circular(iconTheme?.borderRadius ?? 2)),
fillColor: _valueToText[_value] == _valueString[index] fillColor: _valueToText[_value] == _valueString[index]
? (widget.iconTheme?.iconSelectedFillColor ?? ? (iconTheme?.iconSelectedFillColor ??
Theme.of(context).primaryColor) Theme.of(context).primaryColor)
: (widget.iconTheme?.iconUnselectedFillColor ?? : (iconTheme?.iconUnselectedFillColor ?? theme.canvasColor),
theme.canvasColor),
onPressed: () { onPressed: () {
_valueAttribute[index] == Attribute.leftAlignment _valueAttribute[index] == Attribute.leftAlignment
? widget.controller.formatSelection( ? widget.controller.formatSelection(
Attribute.clone(Attribute.align, null)) Attribute.clone(Attribute.align, null),
)
: widget.controller : widget.controller
.formatSelection(_valueAttribute[index]); .formatSelection(_valueAttribute[index]);
widget.afterButtonPressed?.call(); afterButtonPressed?.call();
}, },
child: Icon( child: Icon(
_valueString[index] == Attribute.leftAlignment.value _valueString[index] == Attribute.leftAlignment.value
? Icons.format_align_left ? _iconsData.leftAlignment
: _valueString[index] == Attribute.centerAlignment.value : _valueString[index] == Attribute.centerAlignment.value
? Icons.format_align_center ? _iconsData.centerAlignment
: _valueString[index] == : _valueString[index] ==
Attribute.rightAlignment.value Attribute.rightAlignment.value
? Icons.format_align_right ? _iconsData.rightAlignment
: Icons.format_align_justify, : _iconsData.justifyAlignment,
size: widget.iconSize, size: iconSize,
color: _valueToText[_value] == _valueString[index] color: _valueToText[_value] == _valueString[index]
? (widget.iconTheme?.iconSelectedColor ?? ? (iconTheme?.iconSelectedColor ??
theme.primaryIconTheme.color) theme.primaryIconTheme.color)
: (widget.iconTheme?.iconUnselectedColor ?? : (iconTheme?.iconUnselectedColor ??
theme.iconTheme.color), 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();
}
} }

@ -1,41 +1,27 @@
import 'package:flutter/material.dart'; 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/attribute.dart';
import '../../../models/documents/style.dart'; import '../../../models/documents/style.dart';
import '../../../models/themes/quill_icon_theme.dart'; import '../../../models/themes/quill_icon_theme.dart';
import '../../../utils/extensions/build_context.dart';
import '../../../utils/widgets.dart'; import '../../../utils/widgets.dart';
import '../../controller.dart'; import '../../controller.dart';
import '../toolbar.dart'; import 'toggle_style.dart';
class QuillToolbarToggleCheckListButton extends StatefulWidget { class QuillToolbarToggleCheckListButton extends StatefulWidget {
const QuillToolbarToggleCheckListButton({ const QuillToolbarToggleCheckListButton({
required this.icon, required this.options,
required this.controller, required this.controller,
required this.attribute, super.key,
this.iconSize = kDefaultIconSize, });
this.fillColor,
this.childBuilder = defaultToggleStyleButtonBuilder,
this.iconTheme,
this.afterButtonPressed,
this.tooltip,
Key? key,
}) : super(key: key);
final IconData icon; final QuillToolbarToggleCheckListButtonOptions options;
final double iconSize;
final Color? fillColor;
final QuillController controller; final QuillController controller;
final ToggleStyleButtonBuilder childBuilder;
final Attribute attribute;
final QuillIconTheme? iconTheme;
final VoidCallback? afterButtonPressed;
final String? tooltip;
@override @override
_QuillToolbarToggleCheckListButtonState createState() => _QuillToolbarToggleCheckListButtonState createState() =>
_QuillToolbarToggleCheckListButtonState(); _QuillToolbarToggleCheckListButtonState();
@ -45,6 +31,12 @@ class _QuillToolbarToggleCheckListButtonState
extends State<QuillToolbarToggleCheckListButton> { extends State<QuillToolbarToggleCheckListButton> {
bool? _isToggled; 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(); Style get _selectionStyle => widget.controller.getSelectionStyle();
void _didChangeEditingValue() { void _didChangeEditingValue() {
@ -81,43 +73,108 @@ class _QuillToolbarToggleCheckListButtonState
@override @override
void didUpdateWidget(covariant QuillToolbarToggleCheckListButton oldWidget) { void didUpdateWidget(covariant QuillToolbarToggleCheckListButton oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
if (oldWidget.controller != widget.controller) { if (oldWidget.controller != controller) {
oldWidget.controller.removeListener(_didChangeEditingValue); oldWidget.controller.removeListener(_didChangeEditingValue);
widget.controller.addListener(_didChangeEditingValue); widget.controller.addListener(_didChangeEditingValue);
_isToggled = _getIsToggled(_selectionStyle.attributes); _isToggled = _getIsToggled(_selectionStyle.attributes);
} }
} }
@override
void didChangeDependencies() {
super.didChangeDependencies();
_controller = controller;
}
@override @override
void dispose() { void dispose() {
widget.controller.removeListener(_didChangeEditingValue); _controller.removeListener(_didChangeEditingValue);
super.dispose(); 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 @override
Widget build(BuildContext context) { 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( return UtilityWidgets.maybeTooltip(
message: widget.tooltip, message: tooltip,
child: widget.childBuilder( child: defaultToggleStyleButtonBuilder(
context, context,
Attribute.unchecked, Attribute.unchecked,
widget.icon, iconData,
widget.fillColor, options.fillColor,
_isToggled, _isToggled,
_toggleAttribute, _toggleAttribute,
widget.afterButtonPressed, afterButtonPressed,
widget.iconSize, iconSize,
widget.iconTheme, iconTheme,
), ),
); );
} }
void _toggleAttribute() { void _toggleAttribute() {
// By default don't show the keybaord request as it's quite annoying controller
// We will provide the option to control this in the next major update ..skipRequestKeyboard = !options.isShouldRequestKeyboard
// See https://github.com/singerdmx/flutter-quill/issues/1440
widget.controller
..skipRequestKeyboard = true
..formatSelection( ..formatSelection(
_isToggled! _isToggled!
? Attribute.clone(Attribute.unchecked, null) ? Attribute.clone(Attribute.unchecked, null)

@ -1,33 +1,112 @@
enum ToolbarButtons { enum ToolbarButtons {
// Not needed anymore, the dev can customize this much easier now @Deprecated('Please customize the button in the QuillProvider. '
// in the toolbarConfigurations of 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, direction,
headerStyle, 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, 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, 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, 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, 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, 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, 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, indentDecrease,
link, link,
search, search,

@ -160,32 +160,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
//default button tooltips //default button tooltips
final buttonTooltips = tooltips ?? final buttonTooltips = tooltips ??
<ToolbarButtons, String>{ <ToolbarButtons, String>{
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.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.link: 'Insert URL'.i18n,
ToolbarButtons.search: 'Search'.i18n, ToolbarButtons.search: 'Search'.i18n,
}; };
@ -237,12 +212,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
options: toolbarConfigurations.buttonOptions.bold, options: toolbarConfigurations.buttonOptions.bold,
controller: toolbarConfigurations.buttonOptions.bold.controller ?? controller: toolbarConfigurations.buttonOptions.bold.controller ??
context.requireQuillController, context.requireQuillController,
// icon: Icons.format_bold,
// iconSize: toolbarIconSize,
// tooltip: buttonTooltips[ToolbarButtons.bold],
// controller: controller,
// iconTheme: iconTheme,
// afterButtonPressed: afterButtonPressed,
), ),
if (showSubscript) if (showSubscript)
QuillToolbarToggleStyleButton( QuillToolbarToggleStyleButton(
@ -251,12 +220,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
controller: controller:
toolbarConfigurations.buttonOptions.subscript.controller ?? toolbarConfigurations.buttonOptions.subscript.controller ??
context.requireQuillController, context.requireQuillController,
// icon: Icons.subscript,
// iconSize: toolbarIconSize,
// tooltip: buttonTooltips[ToolbarButtons.subscript],
// controller: controller,
// iconTheme: iconTheme,
// afterButtonPressed: afterButtonPressed,
), ),
if (showSuperscript) if (showSuperscript)
QuillToolbarToggleStyleButton( QuillToolbarToggleStyleButton(
@ -265,12 +228,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
controller: controller:
toolbarConfigurations.buttonOptions.superscript.controller ?? toolbarConfigurations.buttonOptions.superscript.controller ??
context.requireQuillController, context.requireQuillController,
// icon: Icons.superscript,
// iconSize: toolbarIconSize,
// tooltip: buttonTooltips[ToolbarButtons.superscript],
// controller: controller,
// iconTheme: iconTheme,
// afterButtonPressed: afterButtonPressed,
), ),
if (showItalicButton) if (showItalicButton)
QuillToolbarToggleStyleButton( QuillToolbarToggleStyleButton(
@ -279,12 +236,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
controller: controller:
toolbarConfigurations.buttonOptions.italic.controller ?? toolbarConfigurations.buttonOptions.italic.controller ??
context.requireQuillController, context.requireQuillController,
// icon: Icons.format_italic,
// iconSize: toolbarIconSize,
// tooltip: buttonTooltips[ToolbarButtons.italic],
// controller: controller,
// iconTheme: iconTheme,
// afterButtonPressed: afterButtonPressed,
), ),
if (showSmallButton) if (showSmallButton)
QuillToolbarToggleStyleButton( QuillToolbarToggleStyleButton(
@ -293,12 +244,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
controller: controller:
toolbarConfigurations.buttonOptions.small.controller ?? toolbarConfigurations.buttonOptions.small.controller ??
context.requireQuillController, context.requireQuillController,
// icon: Icons.format_size,
// iconSize: toolbarIconSize,
// tooltip: buttonTooltips[ToolbarButtons.small],
// controller: controller,
// iconTheme: iconTheme,
// afterButtonPressed: afterButtonPressed,
), ),
if (showUnderLineButton) if (showUnderLineButton)
QuillToolbarToggleStyleButton( QuillToolbarToggleStyleButton(
@ -307,12 +252,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
controller: controller:
toolbarConfigurations.buttonOptions.underLine.controller ?? toolbarConfigurations.buttonOptions.underLine.controller ??
context.requireQuillController, context.requireQuillController,
// icon: Icons.format_underline,
// iconSize: toolbarIconSize,
// tooltip: buttonTooltips[ToolbarButtons.underline],
// controller: controller,
// iconTheme: iconTheme,
// afterButtonPressed: afterButtonPressed,
), ),
if (showStrikeThrough) if (showStrikeThrough)
QuillToolbarToggleStyleButton( QuillToolbarToggleStyleButton(
@ -321,12 +260,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
controller: toolbarConfigurations controller: toolbarConfigurations
.buttonOptions.strikeThrough.controller ?? .buttonOptions.strikeThrough.controller ??
context.requireQuillController, context.requireQuillController,
// icon: Icons.format_strikethrough,
// iconSize: toolbarIconSize,
// tooltip: buttonTooltips[ToolbarButtons.strikeThrough],
// controller: controller,
// iconTheme: iconTheme,
// afterButtonPressed: afterButtonPressed,
), ),
if (showInlineCode) if (showInlineCode)
QuillToolbarToggleStyleButton( QuillToolbarToggleStyleButton(
@ -335,45 +268,23 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
controller: controller:
toolbarConfigurations.buttonOptions.inlineCode.controller ?? toolbarConfigurations.buttonOptions.inlineCode.controller ??
context.requireQuillController, context.requireQuillController,
// icon: Icons.code,
// iconSize: toolbarIconSize,
// tooltip: buttonTooltips[ToolbarButtons.inlineCode],
// controller: controller,
// iconTheme: iconTheme,
// afterButtonPressed: afterButtonPressed,
), ),
if (showColorButton) if (showColorButton)
QuillToolbarColorButton( QuillToolbarColorButton(
icon: Icons.color_lens,
iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.color],
controller: controller, controller: controller,
background: false, isBackground: false,
iconTheme: iconTheme, options: toolbarConfigurations.buttonOptions.color,
afterButtonPressed: afterButtonPressed,
dialogBarrierColor:
context.requireQuillSharedConfigurations.dialogBarrierColor,
), ),
if (showBackgroundColorButton) if (showBackgroundColorButton)
QuillToolbarColorButton( QuillToolbarColorButton(
icon: Icons.format_color_fill, options: toolbarConfigurations.buttonOptions.backgroundColor,
iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.backgroundColor],
controller: controller, controller: controller,
background: true, isBackground: true,
iconTheme: iconTheme,
afterButtonPressed: afterButtonPressed,
dialogBarrierColor:
context.requireQuillSharedConfigurations.dialogBarrierColor,
), ),
if (showClearFormat) if (showClearFormat)
QuillToolbarClearFormatButton( QuillToolbarClearFormatButton(
icon: Icons.format_clear,
iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.clearFormat],
controller: controller, controller: controller,
iconTheme: iconTheme, options: toolbarConfigurations.buttonOptions.clearFormat,
afterButtonPressed: afterButtonPressed,
), ),
if (embedButtons != null) if (embedButtons != null)
for (final builder in embedButtons) for (final builder in embedButtons)
@ -393,20 +304,19 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
if (showAlignmentButtons) if (showAlignmentButtons)
QuillToolbarSelectAlignmentButton( QuillToolbarSelectAlignmentButton(
controller: controller, controller: controller,
tooltips: Map.of(buttonTooltips) options:
..removeWhere((key, value) => ![ toolbarConfigurations.buttonOptions.selectAlignmentButtons,
ToolbarButtons.leftAlignment, // tooltips: Map.of(buttonTooltips)
ToolbarButtons.centerAlignment, // ..removeWhere((key, value) => ![
ToolbarButtons.rightAlignment, // ToolbarButtons.leftAlignment,
ToolbarButtons.justifyAlignment, // ToolbarButtons.centerAlignment,
].contains(key)), // ToolbarButtons.rightAlignment,
iconSize: toolbarIconSize, // ToolbarButtons.justifyAlignment,
iconTheme: iconTheme, // ].contains(key)),
showLeftAlignment: showLeftAlignment, showLeftAlignment: showLeftAlignment,
showCenterAlignment: showCenterAlignment, showCenterAlignment: showCenterAlignment,
showRightAlignment: showRightAlignment, showRightAlignment: showRightAlignment,
showJustifyAlignment: showJustifyAlignment, showJustifyAlignment: showJustifyAlignment,
afterButtonPressed: afterButtonPressed,
), ),
if (showDirection) if (showDirection)
QuillToolbarToggleStyleButton( QuillToolbarToggleStyleButton(
@ -415,12 +325,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
controller: controller:
toolbarConfigurations.buttonOptions.direction.controller ?? toolbarConfigurations.buttonOptions.direction.controller ??
context.requireQuillController, context.requireQuillController,
// tooltip: buttonTooltips[ToolbarButtons.direction],
// controller: controller,
// icon: Icons.format_textdirection_r_to_l,
// iconSize: toolbarIconSize,
// iconTheme: iconTheme,
// afterButtonPressed: afterButtonPressed,
), ),
if (showDividers && if (showDividers &&
isButtonGroupShown[1] && isButtonGroupShown[1] &&
@ -460,12 +364,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
controller: controller:
toolbarConfigurations.buttonOptions.listNumbers.controller ?? toolbarConfigurations.buttonOptions.listNumbers.controller ??
context.requireQuillController, context.requireQuillController,
// tooltip: buttonTooltips[ToolbarButtons.listNumbers],
// controller: controller,
// icon: Icons.format_list_numbered,
// iconSize: toolbarIconSize,
// iconTheme: iconTheme,
// afterButtonPressed: afterButtonPressed,
), ),
if (showListBullets) if (showListBullets)
QuillToolbarToggleStyleButton( QuillToolbarToggleStyleButton(
@ -474,22 +372,13 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
controller: controller:
toolbarConfigurations.buttonOptions.listBullets.controller ?? toolbarConfigurations.buttonOptions.listBullets.controller ??
context.requireQuillController, context.requireQuillController,
// tooltip: buttonTooltips[ToolbarButtons.listBullets],
// controller: controller,
// icon: Icons.format_list_bulleted,
// iconSize: toolbarIconSize,
// iconTheme: iconTheme,
// afterButtonPressed: afterButtonPressed,
), ),
if (showListCheck) if (showListCheck)
QuillToolbarToggleCheckListButton( QuillToolbarToggleCheckListButton(
attribute: Attribute.unchecked, options: toolbarConfigurations.buttonOptions.toggleCheckList,
tooltip: buttonTooltips[ToolbarButtons.listChecks], controller: toolbarConfigurations
controller: controller, .buttonOptions.toggleCheckList.controller ??
icon: Icons.check_box, context.requireQuillController,
iconSize: toolbarIconSize,
iconTheme: iconTheme,
afterButtonPressed: afterButtonPressed,
), ),
if (showCodeBlock) if (showCodeBlock)
QuillToolbarToggleStyleButton( QuillToolbarToggleStyleButton(
@ -498,12 +387,6 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
controller: controller:
toolbarConfigurations.buttonOptions.codeBlock.controller ?? toolbarConfigurations.buttonOptions.codeBlock.controller ??
context.requireQuillController, context.requireQuillController,
// tooltip: buttonTooltips[ToolbarButtons.codeBlock],
// controller: controller,
// icon: Icons.code,
// iconSize: toolbarIconSize,
// iconTheme: iconTheme,
// afterButtonPressed: afterButtonPressed,
), ),
if (showDividers && if (showDividers &&
isButtonGroupShown[3] && isButtonGroupShown[3] &&
@ -517,32 +400,22 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
toolbarConfigurations.buttonOptions.quote.controller ?? toolbarConfigurations.buttonOptions.quote.controller ??
context.requireQuillController, context.requireQuillController,
attribute: Attribute.blockQuote, attribute: Attribute.blockQuote,
// tooltip: buttonTooltips[ToolbarButtons.quote],
// controller: controller,
// icon: Icons.format_quote,
// iconSize: toolbarIconSize,
// iconTheme: iconTheme,
// afterButtonPressed: afterButtonPressed,
), ),
if (showIndent) if (showIndent)
QuillToolbarIndentButton( QuillToolbarIndentButton(
icon: Icons.format_indent_increase, controller: toolbarConfigurations
iconSize: toolbarIconSize, .buttonOptions.indentIncrease.controller ??
tooltip: buttonTooltips[ToolbarButtons.indentIncrease], context.requireQuillController,
controller: controller,
isIncrease: true, isIncrease: true,
iconTheme: iconTheme, options: toolbarConfigurations.buttonOptions.indentIncrease,
afterButtonPressed: afterButtonPressed,
), ),
if (showIndent) if (showIndent)
QuillToolbarIndentButton( QuillToolbarIndentButton(
icon: Icons.format_indent_decrease, controller: toolbarConfigurations
iconSize: toolbarIconSize, .buttonOptions.indentDecrease.controller ??
tooltip: buttonTooltips[ToolbarButtons.indentDecrease], context.requireQuillController,
controller: controller,
isIncrease: false, isIncrease: false,
iconTheme: iconTheme, options: toolbarConfigurations.buttonOptions.indentDecrease,
afterButtonPressed: afterButtonPressed,
), ),
if (showDividers && isButtonGroupShown[4] && isButtonGroupShown[5]) if (showDividers && isButtonGroupShown[4] && isButtonGroupShown[5])
QuillToolbarDivider(axis, QuillToolbarDivider(axis,
@ -680,10 +553,10 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
class QuillToolbarDivider extends StatelessWidget { class QuillToolbarDivider extends StatelessWidget {
const QuillToolbarDivider( const QuillToolbarDivider(
this.axis, { this.axis, {
Key? key, super.key,
this.color, this.color,
this.space, this.space,
}) : super(key: key); });
/// Provides a horizontal divider for vertical toolbar. /// Provides a horizontal divider for vertical toolbar.
const QuillToolbarDivider.horizontal({Color? color, double? space}) const QuillToolbarDivider.horizontal({Color? color, double? space})

@ -1,8 +1,14 @@
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: 7.7.0 version: 7.8.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
topics:
- ui
- effects
- widgets
- widget
- rich text editor
platforms: platforms:
android: android:
ios: ios:
@ -31,6 +37,7 @@ dependencies:
platform: ^3.1.3 platform: ^3.1.3
pasteboard: ^0.2.0 pasteboard: ^0.2.0
equatable: ^2.0.5 equatable: ^2.0.5
flutter_animate: ^4.2.0+1
flutter_test: flutter_test:
sdk: flutter sdk: flutter

Loading…
Cancel
Save