Add tooltips for toolbar buttons. (#1175)

* Add `UtilityWidgets`

* Implement tooltips for toolbar buttons

* Add `tooltip` to `QuillCustomButton`

* Add `ToolbarButtons`

* Update `EmbedButtonBuilder` with `tooltip`

* Implement tooltips in `QuillToolbar`

* Add tooltip property to embed buttons (for future)

* Update version of flutter_quill in pubspec.yaml

* Restore `EmbedButtonBuilder`

* Update english translations

* Implement translations for tooltips

* Update translations for `en-us`

* Make `tooltips` nullable to hide tooltips.

* Remove `tooltips` property from `QuillToolbar`
pull/1177/head
BambinoUA 2 years ago committed by GitHub
parent e90e6eb70d
commit 539357bc63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      flutter_quill_extensions/lib/embeds/toolbar/camera_button.dart
  2. 2
      flutter_quill_extensions/lib/embeds/toolbar/formula_button.dart
  3. 2
      flutter_quill_extensions/lib/embeds/toolbar/image_button.dart
  4. 2
      flutter_quill_extensions/lib/embeds/toolbar/video_button.dart
  5. 6
      flutter_quill_extensions/pubspec.yaml
  6. 9
      lib/src/models/themes/quill_custom_button.dart
  7. 52
      lib/src/translations/toolbar.i18n.dart
  8. 11
      lib/src/utils/widgets.dart
  9. 80
      lib/src/widgets/toolbar.dart
  10. 3
      lib/src/widgets/toolbar/clear_format_button.dart
  11. 3
      lib/src/widgets/toolbar/color_button.dart
  12. 30
      lib/src/widgets/toolbar/enum.dart
  13. 3
      lib/src/widgets/toolbar/history_button.dart
  14. 3
      lib/src/widgets/toolbar/indent_button.dart
  15. 3
      lib/src/widgets/toolbar/link_style_button.dart
  16. 34
      lib/src/widgets/toolbar/quill_font_family_button.dart
  17. 34
      lib/src/widgets/toolbar/quill_font_size_button.dart
  18. 33
      lib/src/widgets/toolbar/quill_icon_button.dart
  19. 3
      lib/src/widgets/toolbar/search_button.dart
  20. 87
      lib/src/widgets/toolbar/select_alignment_button.dart
  21. 62
      lib/src/widgets/toolbar/select_header_style_button.dart
  22. 26
      lib/src/widgets/toolbar/toggle_check_list_button.dart
  23. 26
      lib/src/widgets/toolbar/toggle_style_button.dart

@ -19,6 +19,7 @@ class CameraButton extends StatelessWidget {
this.webVideoPickImpl, this.webVideoPickImpl,
this.cameraPickSettingSelector, this.cameraPickSettingSelector,
this.iconTheme, this.iconTheme,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -42,6 +43,7 @@ class CameraButton extends StatelessWidget {
final MediaPickSettingSelector? cameraPickSettingSelector; final MediaPickSettingSelector? cameraPickSettingSelector;
final QuillIconTheme? iconTheme; final QuillIconTheme? iconTheme;
final String? tooltip;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

@ -9,6 +9,7 @@ class FormulaButton extends StatelessWidget {
this.fillColor, this.fillColor,
this.iconTheme, this.iconTheme,
this.dialogTheme, this.dialogTheme,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -23,6 +24,7 @@ class FormulaButton extends StatelessWidget {
final QuillIconTheme? iconTheme; final QuillIconTheme? iconTheme;
final QuillDialogTheme? dialogTheme; final QuillDialogTheme? dialogTheme;
final String? tooltip;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

@ -17,6 +17,7 @@ class ImageButton extends StatelessWidget {
this.mediaPickSettingSelector, this.mediaPickSettingSelector,
this.iconTheme, this.iconTheme,
this.dialogTheme, this.dialogTheme,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -38,6 +39,7 @@ class ImageButton extends StatelessWidget {
final QuillIconTheme? iconTheme; final QuillIconTheme? iconTheme;
final QuillDialogTheme? dialogTheme; final QuillDialogTheme? dialogTheme;
final String? tooltip;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

@ -17,6 +17,7 @@ class VideoButton extends StatelessWidget {
this.mediaPickSettingSelector, this.mediaPickSettingSelector,
this.iconTheme, this.iconTheme,
this.dialogTheme, this.dialogTheme,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -38,6 +39,7 @@ class VideoButton extends StatelessWidget {
final QuillIconTheme? iconTheme; final QuillIconTheme? iconTheme;
final QuillDialogTheme? dialogTheme; final QuillDialogTheme? dialogTheme;
final String? tooltip;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

@ -12,7 +12,7 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
flutter_quill: ^7.0.2 flutter_quill: ^7.1.4
image_picker: ^0.8.5+3 image_picker: ^0.8.5+3
photo_view: ^0.14.0 photo_view: ^0.14.0
@ -23,10 +23,6 @@ dependencies:
string_validator: ^1.0.0 string_validator: ^1.0.0
url_launcher: ^6.1.9 url_launcher: ^6.1.9
# dependency_overrides:
# flutter_quill:
# path: ../
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter

@ -1,11 +1,18 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class QuillCustomButton { class QuillCustomButton {
const QuillCustomButton({this.icon, this.onTap}); const QuillCustomButton({
this.icon,
this.onTap,
this.tooltip,
});
///The icon widget ///The icon widget
final IconData? icon; final IconData? icon;
///The function when the icon is tapped ///The function when the icon is tapped
final VoidCallback? onTap; final VoidCallback? onTap;
/// The button tooltip.
final String? tooltip;
} }

@ -35,6 +35,32 @@ extension Localization on String {
'Next': 'Next', 'Next': 'Next',
'Camera': 'Camera', 'Camera': 'Camera',
'Video': 'Video', 'Video': 'Video',
'Undo': 'Undo',
'Redo': 'Redo',
'Font family': 'Font family',
'Font size': 'Font size',
'Bold': 'Bold',
'Italic': 'Italic',
'Underline': 'Underline',
'Strike through': 'Strike through',
'Inline code': 'Inline code',
'Font color': 'Font color',
'Background color': 'Background color',
'Clear format': 'Clear format',
'Align left': 'Align left',
'Align center': 'Align center',
'Align right': 'Align right',
'Justify win width': 'Justify win width',
'Text direction': 'Text direction',
'Header style': 'Header style',
'Numbered list': 'Numbered list',
'Bullet list': 'Bullet list',
'Checked list': 'Checked list',
'Code block': 'Code block',
'Quote': 'Quote',
'Increase indent': 'Increase indent',
'Decrease indent': 'Decrease indent',
'Insert URL': 'Insert URL',
}, },
'en_us': { 'en_us': {
'Paste a link': 'Paste a link', 'Paste a link': 'Paste a link',
@ -68,6 +94,32 @@ extension Localization on String {
'Next': 'Next', 'Next': 'Next',
'Camera': 'Camera', 'Camera': 'Camera',
'Video': 'Video', 'Video': 'Video',
'Undo': 'Undo',
'Redo': 'Redo',
'Font family': 'Font family',
'Font size': 'Font size',
'Bold': 'Bold',
'Italic': 'Italic',
'Underline': 'Underline',
'Strike through': 'Strike through',
'Inline code': 'Inline code',
'Font color': 'Font color',
'Background color': 'Background color',
'Clear format': 'Clear format',
'Align left': 'Align left',
'Align center': 'Align center',
'Align right': 'Align right',
'Justify win width': 'Justify win width',
'Text direction': 'Text direction',
'Header style': 'Header style',
'Numbered list': 'Numbered list',
'Bullet list': 'Bullet list',
'Checked list': 'Checked list',
'Code block': 'Code block',
'Quote': 'Quote',
'Increase indent': 'Increase indent',
'Decrease indent': 'Decrease indent',
'Insert URL': 'Insert URL',
}, },
'ar': { 'ar': {
'Paste a link': 'نسخ الرابط', 'Paste a link': 'نسخ الرابط',

@ -0,0 +1,11 @@
import 'package:flutter/material.dart';
/// Provides utiulity widgets.
abstract class UtilityWidgets {
/// Conditionally wraps the [child] with [Tooltip] widget if [message]
/// is not null and not empty.
static Widget maybeTooltip({required Widget child, String? message}) =>
(message ?? '').isNotEmpty
? Tooltip(message: message!, child: child)
: child;
}

@ -12,6 +12,7 @@ import 'embeds.dart';
import 'toolbar/arrow_indicated_button_list.dart'; import 'toolbar/arrow_indicated_button_list.dart';
import 'toolbar/clear_format_button.dart'; import 'toolbar/clear_format_button.dart';
import 'toolbar/color_button.dart'; import 'toolbar/color_button.dart';
import 'toolbar/enum.dart';
import 'toolbar/history_button.dart'; import 'toolbar/history_button.dart';
import 'toolbar/indent_button.dart'; import 'toolbar/indent_button.dart';
import 'toolbar/link_style_button.dart'; import 'toolbar/link_style_button.dart';
@ -117,6 +118,20 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
/// Is called after whatever logic the button performs has run. /// Is called after whatever logic the button performs has run.
VoidCallback? afterButtonPressed, VoidCallback? afterButtonPressed,
///Map of tooltips for toolbar buttons
///
///The example is:
///```dart
/// tooltips = <ToolbarButtons, String>{
/// ToolbarButtons.undo: 'Undo',
/// ToolbarButtons.redo: 'Redo',
/// }
///
///```
///
/// To disable tooltips just pass empty map as well.
Map<ToolbarButtons, String>? tooltips,
/// The locale to use for the editor toolbar, defaults to system locale /// The locale to use for the editor toolbar, defaults to system locale
/// More at https://github.com/singerdmx/flutter-quill#translation /// More at https://github.com/singerdmx/flutter-quill#translation
Locale? locale, Locale? locale,
@ -172,6 +187,39 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
'Clear'.i18n: 'Clear' 'Clear'.i18n: 'Clear'
}; };
//default button tooltips
final buttonTooltips = tooltips ??
<ToolbarButtons, String>{
ToolbarButtons.undo: 'Undo'.i18n,
ToolbarButtons.redo: 'Redo'.i18n,
ToolbarButtons.fontFamily: 'Font family'.i18n,
ToolbarButtons.fontSize: 'Font size'.i18n,
ToolbarButtons.bold: 'Bold'.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,
};
return QuillToolbar( return QuillToolbar(
key: key, key: key,
axis: axis, axis: axis,
@ -189,6 +237,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
HistoryButton( HistoryButton(
icon: Icons.undo_outlined, icon: Icons.undo_outlined,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.undo],
controller: controller, controller: controller,
undo: true, undo: true,
iconTheme: iconTheme, iconTheme: iconTheme,
@ -198,6 +247,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
HistoryButton( HistoryButton(
icon: Icons.redo_outlined, icon: Icons.redo_outlined,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.redo],
controller: controller, controller: controller,
undo: false, undo: false,
iconTheme: iconTheme, iconTheme: iconTheme,
@ -207,6 +257,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
QuillFontFamilyButton( QuillFontFamilyButton(
iconTheme: iconTheme, iconTheme: iconTheme,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.fontFamily],
attribute: Attribute.font, attribute: Attribute.font,
controller: controller, controller: controller,
items: [ items: [
@ -231,6 +282,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
QuillFontSizeButton( QuillFontSizeButton(
iconTheme: iconTheme, iconTheme: iconTheme,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.fontSize],
attribute: Attribute.size, attribute: Attribute.size,
controller: controller, controller: controller,
items: [ items: [
@ -255,6 +307,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
attribute: Attribute.bold, attribute: Attribute.bold,
icon: Icons.format_bold, icon: Icons.format_bold,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.bold],
controller: controller, controller: controller,
iconTheme: iconTheme, iconTheme: iconTheme,
afterButtonPressed: afterButtonPressed, afterButtonPressed: afterButtonPressed,
@ -264,6 +317,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
attribute: Attribute.italic, attribute: Attribute.italic,
icon: Icons.format_italic, icon: Icons.format_italic,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.italic],
controller: controller, controller: controller,
iconTheme: iconTheme, iconTheme: iconTheme,
afterButtonPressed: afterButtonPressed, afterButtonPressed: afterButtonPressed,
@ -273,6 +327,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
attribute: Attribute.small, attribute: Attribute.small,
icon: Icons.format_size, icon: Icons.format_size,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.small],
controller: controller, controller: controller,
iconTheme: iconTheme, iconTheme: iconTheme,
afterButtonPressed: afterButtonPressed, afterButtonPressed: afterButtonPressed,
@ -282,6 +337,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
attribute: Attribute.underline, attribute: Attribute.underline,
icon: Icons.format_underline, icon: Icons.format_underline,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.underline],
controller: controller, controller: controller,
iconTheme: iconTheme, iconTheme: iconTheme,
afterButtonPressed: afterButtonPressed, afterButtonPressed: afterButtonPressed,
@ -291,6 +347,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
attribute: Attribute.strikeThrough, attribute: Attribute.strikeThrough,
icon: Icons.format_strikethrough, icon: Icons.format_strikethrough,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.strikeThrough],
controller: controller, controller: controller,
iconTheme: iconTheme, iconTheme: iconTheme,
afterButtonPressed: afterButtonPressed, afterButtonPressed: afterButtonPressed,
@ -300,6 +357,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
attribute: Attribute.inlineCode, attribute: Attribute.inlineCode,
icon: Icons.code, icon: Icons.code,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.inlineCode],
controller: controller, controller: controller,
iconTheme: iconTheme, iconTheme: iconTheme,
afterButtonPressed: afterButtonPressed, afterButtonPressed: afterButtonPressed,
@ -308,6 +366,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
ColorButton( ColorButton(
icon: Icons.color_lens, icon: Icons.color_lens,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.color],
controller: controller, controller: controller,
background: false, background: false,
iconTheme: iconTheme, iconTheme: iconTheme,
@ -317,6 +376,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
ColorButton( ColorButton(
icon: Icons.format_color_fill, icon: Icons.format_color_fill,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.backgroundColor],
controller: controller, controller: controller,
background: true, background: true,
iconTheme: iconTheme, iconTheme: iconTheme,
@ -326,6 +386,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
ClearFormatButton( ClearFormatButton(
icon: Icons.format_clear, icon: Icons.format_clear,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.clearFormat],
controller: controller, controller: controller,
iconTheme: iconTheme, iconTheme: iconTheme,
afterButtonPressed: afterButtonPressed, afterButtonPressed: afterButtonPressed,
@ -344,6 +405,13 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
if (showAlignmentButtons) if (showAlignmentButtons)
SelectAlignmentButton( SelectAlignmentButton(
controller: controller, controller: controller,
tooltips: Map.of(buttonTooltips)
..removeWhere((key, value) => ![
ToolbarButtons.leftAlignment,
ToolbarButtons.centerAlignment,
ToolbarButtons.rightAlignment,
ToolbarButtons.justifyAlignment,
].contains(key)),
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
iconTheme: iconTheme, iconTheme: iconTheme,
showLeftAlignment: showLeftAlignment, showLeftAlignment: showLeftAlignment,
@ -355,6 +423,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
if (showDirection) if (showDirection)
ToggleStyleButton( ToggleStyleButton(
attribute: Attribute.rtl, attribute: Attribute.rtl,
tooltip: buttonTooltips[ToolbarButtons.direction],
controller: controller, controller: controller,
icon: Icons.format_textdirection_r_to_l, icon: Icons.format_textdirection_r_to_l,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
@ -370,6 +439,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
_dividerOnAxis(axis), _dividerOnAxis(axis),
if (showHeaderStyle) if (showHeaderStyle)
SelectHeaderStyleButton( SelectHeaderStyleButton(
tooltip: buttonTooltips[ToolbarButtons.headerStyle],
controller: controller, controller: controller,
axis: axis, axis: axis,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
@ -386,6 +456,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
if (showListNumbers) if (showListNumbers)
ToggleStyleButton( ToggleStyleButton(
attribute: Attribute.ol, attribute: Attribute.ol,
tooltip: buttonTooltips[ToolbarButtons.listNumbers],
controller: controller, controller: controller,
icon: Icons.format_list_numbered, icon: Icons.format_list_numbered,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
@ -395,6 +466,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
if (showListBullets) if (showListBullets)
ToggleStyleButton( ToggleStyleButton(
attribute: Attribute.ul, attribute: Attribute.ul,
tooltip: buttonTooltips[ToolbarButtons.listBullets],
controller: controller, controller: controller,
icon: Icons.format_list_bulleted, icon: Icons.format_list_bulleted,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
@ -404,6 +476,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
if (showListCheck) if (showListCheck)
ToggleCheckListButton( ToggleCheckListButton(
attribute: Attribute.unchecked, attribute: Attribute.unchecked,
tooltip: buttonTooltips[ToolbarButtons.listChecks],
controller: controller, controller: controller,
icon: Icons.check_box, icon: Icons.check_box,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
@ -413,6 +486,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
if (showCodeBlock) if (showCodeBlock)
ToggleStyleButton( ToggleStyleButton(
attribute: Attribute.codeBlock, attribute: Attribute.codeBlock,
tooltip: buttonTooltips[ToolbarButtons.codeBlock],
controller: controller, controller: controller,
icon: Icons.code, icon: Icons.code,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
@ -426,6 +500,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
if (showQuote) if (showQuote)
ToggleStyleButton( ToggleStyleButton(
attribute: Attribute.blockQuote, attribute: Attribute.blockQuote,
tooltip: buttonTooltips[ToolbarButtons.quote],
controller: controller, controller: controller,
icon: Icons.format_quote, icon: Icons.format_quote,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
@ -436,6 +511,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
IndentButton( IndentButton(
icon: Icons.format_indent_increase, icon: Icons.format_indent_increase,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.indentIncrease],
controller: controller, controller: controller,
isIncrease: true, isIncrease: true,
iconTheme: iconTheme, iconTheme: iconTheme,
@ -445,6 +521,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
IndentButton( IndentButton(
icon: Icons.format_indent_decrease, icon: Icons.format_indent_decrease,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.indentDecrease],
controller: controller, controller: controller,
isIncrease: false, isIncrease: false,
iconTheme: iconTheme, iconTheme: iconTheme,
@ -454,6 +531,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
_dividerOnAxis(axis), _dividerOnAxis(axis),
if (showLink) if (showLink)
LinkStyleButton( LinkStyleButton(
tooltip: buttonTooltips[ToolbarButtons.link],
controller: controller, controller: controller,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
iconTheme: iconTheme, iconTheme: iconTheme,
@ -464,6 +542,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
SearchButton( SearchButton(
icon: Icons.search, icon: Icons.search,
iconSize: toolbarIconSize, iconSize: toolbarIconSize,
tooltip: buttonTooltips[ToolbarButtons.search],
controller: controller, controller: controller,
iconTheme: iconTheme, iconTheme: iconTheme,
dialogTheme: dialogTheme, dialogTheme: dialogTheme,
@ -477,6 +556,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
hoverElevation: 0, hoverElevation: 0,
size: toolbarIconSize * kIconButtonFactor, size: toolbarIconSize * kIconButtonFactor,
icon: Icon(customButton.icon, size: toolbarIconSize), icon: Icon(customButton.icon, size: toolbarIconSize),
tooltip: customButton.tooltip,
borderRadius: iconTheme?.borderRadius ?? 2, borderRadius: iconTheme?.borderRadius ?? 2,
onPressed: customButton.onTap, onPressed: customButton.onTap,
afterPressed: afterButtonPressed, afterPressed: afterButtonPressed,

@ -12,6 +12,7 @@ class ClearFormatButton extends StatefulWidget {
this.iconSize = kDefaultIconSize, this.iconSize = kDefaultIconSize,
this.iconTheme, this.iconTheme,
this.afterButtonPressed, this.afterButtonPressed,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -22,6 +23,7 @@ class ClearFormatButton extends StatefulWidget {
final QuillIconTheme? iconTheme; final QuillIconTheme? iconTheme;
final VoidCallback? afterButtonPressed; final VoidCallback? afterButtonPressed;
final String? tooltip;
@override @override
_ClearFormatButtonState createState() => _ClearFormatButtonState(); _ClearFormatButtonState createState() => _ClearFormatButtonState();
@ -36,6 +38,7 @@ class _ClearFormatButtonState extends State<ClearFormatButton> {
final fillColor = final fillColor =
widget.iconTheme?.iconUnselectedFillColor ?? theme.canvasColor; widget.iconTheme?.iconUnselectedFillColor ?? theme.canvasColor;
return QuillIconButton( return QuillIconButton(
tooltip: widget.tooltip,
highlightElevation: 0, highlightElevation: 0,
hoverElevation: 0, hoverElevation: 0,
size: widget.iconSize * kIconButtonFactor, size: widget.iconSize * kIconButtonFactor,

@ -21,6 +21,7 @@ class ColorButton extends StatefulWidget {
this.iconSize = kDefaultIconSize, this.iconSize = kDefaultIconSize,
this.iconTheme, this.iconTheme,
this.afterButtonPressed, this.afterButtonPressed,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -30,6 +31,7 @@ class ColorButton extends StatefulWidget {
final QuillController controller; final QuillController controller;
final QuillIconTheme? iconTheme; final QuillIconTheme? iconTheme;
final VoidCallback? afterButtonPressed; final VoidCallback? afterButtonPressed;
final String? tooltip;
@override @override
_ColorButtonState createState() => _ColorButtonState(); _ColorButtonState createState() => _ColorButtonState();
@ -119,6 +121,7 @@ class _ColorButtonState extends State<ColorButton> {
: (widget.iconTheme?.iconUnselectedFillColor ?? theme.canvasColor); : (widget.iconTheme?.iconUnselectedFillColor ?? theme.canvasColor);
return QuillIconButton( return QuillIconButton(
tooltip: widget.tooltip,
highlightElevation: 0, highlightElevation: 0,
hoverElevation: 0, hoverElevation: 0,
size: widget.iconSize * kIconButtonFactor, size: widget.iconSize * kIconButtonFactor,

@ -0,0 +1,30 @@
enum ToolbarButtons {
undo,
redo,
fontFamily,
fontSize,
bold,
italic,
small,
underline,
strikeThrough,
inlineCode,
color,
backgroundColor,
clearFormat,
centerAlignment,
leftAlignment,
rightAlignment,
justifyAlignment,
direction,
headerStyle,
listNumbers,
listBullets,
listChecks,
codeBlock,
quote,
indentIncrease,
indentDecrease,
link,
search,
}

@ -12,6 +12,7 @@ class HistoryButton extends StatefulWidget {
this.iconSize = kDefaultIconSize, this.iconSize = kDefaultIconSize,
this.iconTheme, this.iconTheme,
this.afterButtonPressed, this.afterButtonPressed,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -21,6 +22,7 @@ class HistoryButton extends StatefulWidget {
final QuillController controller; final QuillController controller;
final QuillIconTheme? iconTheme; final QuillIconTheme? iconTheme;
final VoidCallback? afterButtonPressed; final VoidCallback? afterButtonPressed;
final String? tooltip;
@override @override
_HistoryButtonState createState() => _HistoryButtonState(); _HistoryButtonState createState() => _HistoryButtonState();
@ -41,6 +43,7 @@ class _HistoryButtonState extends State<HistoryButton> {
_setIconColor(); _setIconColor();
}); });
return QuillIconButton( return QuillIconButton(
tooltip: widget.tooltip,
highlightElevation: 0, highlightElevation: 0,
hoverElevation: 0, hoverElevation: 0,
size: widget.iconSize * 1.77, size: widget.iconSize * 1.77,

@ -12,6 +12,7 @@ class IndentButton extends StatefulWidget {
this.iconSize = kDefaultIconSize, this.iconSize = kDefaultIconSize,
this.iconTheme, this.iconTheme,
this.afterButtonPressed, this.afterButtonPressed,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -22,6 +23,7 @@ class IndentButton extends StatefulWidget {
final VoidCallback? afterButtonPressed; final VoidCallback? afterButtonPressed;
final QuillIconTheme? iconTheme; final QuillIconTheme? iconTheme;
final String? tooltip;
@override @override
_IndentButtonState createState() => _IndentButtonState(); _IndentButtonState createState() => _IndentButtonState();
@ -37,6 +39,7 @@ class _IndentButtonState extends State<IndentButton> {
final iconFillColor = final iconFillColor =
widget.iconTheme?.iconUnselectedFillColor ?? theme.canvasColor; widget.iconTheme?.iconUnselectedFillColor ?? theme.canvasColor;
return QuillIconButton( return QuillIconButton(
tooltip: widget.tooltip,
highlightElevation: 0, highlightElevation: 0,
hoverElevation: 0, hoverElevation: 0,
size: widget.iconSize * 1.77, size: widget.iconSize * 1.77,

@ -17,6 +17,7 @@ class LinkStyleButton extends StatefulWidget {
this.iconTheme, this.iconTheme,
this.dialogTheme, this.dialogTheme,
this.afterButtonPressed, this.afterButtonPressed,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -26,6 +27,7 @@ class LinkStyleButton extends StatefulWidget {
final QuillIconTheme? iconTheme; final QuillIconTheme? iconTheme;
final QuillDialogTheme? dialogTheme; final QuillDialogTheme? dialogTheme;
final VoidCallback? afterButtonPressed; final VoidCallback? afterButtonPressed;
final String? tooltip;
@override @override
_LinkStyleButtonState createState() => _LinkStyleButtonState(); _LinkStyleButtonState createState() => _LinkStyleButtonState();
@ -63,6 +65,7 @@ class _LinkStyleButtonState extends State<LinkStyleButton> {
final isToggled = _getLinkAttributeValue() != null; final isToggled = _getLinkAttributeValue() != null;
final pressedHandler = () => _openLinkDialog(context); final pressedHandler = () => _openLinkDialog(context);
return QuillIconButton( return QuillIconButton(
tooltip: widget.tooltip,
highlightElevation: 0, highlightElevation: 0,
hoverElevation: 0, hoverElevation: 0,
size: widget.iconSize * kIconButtonFactor, size: widget.iconSize * kIconButtonFactor,

@ -4,6 +4,7 @@ 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 '../../translations/toolbar.i18n.dart'; import '../../translations/toolbar.i18n.dart';
import '../../utils/widgets.dart';
import '../controller.dart'; import '../controller.dart';
class QuillFontFamilyButton extends StatefulWidget { class QuillFontFamilyButton extends StatefulWidget {
@ -19,6 +20,7 @@ class QuillFontFamilyButton extends StatefulWidget {
this.highlightElevation = 1, this.highlightElevation = 1,
this.iconTheme, this.iconTheme,
this.afterButtonPressed, this.afterButtonPressed,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -33,6 +35,7 @@ class QuillFontFamilyButton extends StatefulWidget {
final Attribute attribute; final Attribute attribute;
final QuillController controller; final QuillController controller;
final VoidCallback? afterButtonPressed; final VoidCallback? afterButtonPressed;
final String? tooltip;
@override @override
_QuillFontFamilyButtonState createState() => _QuillFontFamilyButtonState(); _QuillFontFamilyButtonState createState() => _QuillFontFamilyButtonState();
@ -88,20 +91,23 @@ class _QuillFontFamilyButtonState extends State<QuillFontFamilyButton> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ConstrainedBox( return ConstrainedBox(
constraints: BoxConstraints.tightFor(height: widget.iconSize * 1.81), constraints: BoxConstraints.tightFor(height: widget.iconSize * 1.81),
child: RawMaterialButton( child: UtilityWidgets.maybeTooltip(
visualDensity: VisualDensity.compact, message: widget.tooltip,
shape: RoundedRectangleBorder( child: RawMaterialButton(
borderRadius: visualDensity: VisualDensity.compact,
BorderRadius.circular(widget.iconTheme?.borderRadius ?? 2)), shape: RoundedRectangleBorder(
fillColor: widget.fillColor, borderRadius:
elevation: 0, BorderRadius.circular(widget.iconTheme?.borderRadius ?? 2)),
hoverElevation: widget.hoverElevation, fillColor: widget.fillColor,
highlightElevation: widget.hoverElevation, elevation: 0,
onPressed: () { hoverElevation: widget.hoverElevation,
_showMenu(); highlightElevation: widget.hoverElevation,
widget.afterButtonPressed?.call(); onPressed: () {
}, _showMenu();
child: _buildContent(context), widget.afterButtonPressed?.call();
},
child: _buildContent(context),
),
), ),
); );
} }

@ -5,6 +5,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/font.dart'; import '../../utils/font.dart';
import '../../utils/widgets.dart';
import '../controller.dart'; import '../controller.dart';
class QuillFontSizeButton extends StatefulWidget { class QuillFontSizeButton extends StatefulWidget {
@ -20,6 +21,7 @@ class QuillFontSizeButton extends StatefulWidget {
this.highlightElevation = 1, this.highlightElevation = 1,
this.iconTheme, this.iconTheme,
this.afterButtonPressed, this.afterButtonPressed,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -34,6 +36,7 @@ class QuillFontSizeButton extends StatefulWidget {
final Attribute attribute; final Attribute attribute;
final QuillController controller; final QuillController controller;
final VoidCallback? afterButtonPressed; final VoidCallback? afterButtonPressed;
final String? tooltip;
@override @override
_QuillFontSizeButtonState createState() => _QuillFontSizeButtonState(); _QuillFontSizeButtonState createState() => _QuillFontSizeButtonState();
@ -89,20 +92,23 @@ class _QuillFontSizeButtonState extends State<QuillFontSizeButton> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ConstrainedBox( return ConstrainedBox(
constraints: BoxConstraints.tightFor(height: widget.iconSize * 1.81), constraints: BoxConstraints.tightFor(height: widget.iconSize * 1.81),
child: RawMaterialButton( child: UtilityWidgets.maybeTooltip(
visualDensity: VisualDensity.compact, message: widget.tooltip,
shape: RoundedRectangleBorder( child: RawMaterialButton(
borderRadius: visualDensity: VisualDensity.compact,
BorderRadius.circular(widget.iconTheme?.borderRadius ?? 2)), shape: RoundedRectangleBorder(
fillColor: widget.fillColor, borderRadius:
elevation: 0, BorderRadius.circular(widget.iconTheme?.borderRadius ?? 2)),
hoverElevation: widget.hoverElevation, fillColor: widget.fillColor,
highlightElevation: widget.hoverElevation, elevation: 0,
onPressed: () { hoverElevation: widget.hoverElevation,
_showMenu(); highlightElevation: widget.hoverElevation,
widget.afterButtonPressed?.call(); onPressed: () {
}, _showMenu();
child: _buildContent(context), widget.afterButtonPressed?.call();
},
child: _buildContent(context),
),
), ),
); );
} }

@ -1,5 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../utils/widgets.dart';
class QuillIconButton extends StatelessWidget { class QuillIconButton extends StatelessWidget {
const QuillIconButton({ const QuillIconButton({
required this.onPressed, required this.onPressed,
@ -10,6 +12,7 @@ class QuillIconButton extends StatelessWidget {
this.hoverElevation = 1, this.hoverElevation = 1,
this.highlightElevation = 1, this.highlightElevation = 1,
this.borderRadius = 2, this.borderRadius = 2,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -21,24 +24,28 @@ class QuillIconButton extends StatelessWidget {
final double hoverElevation; final double hoverElevation;
final double highlightElevation; final double highlightElevation;
final double borderRadius; final double borderRadius;
final String? tooltip;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ConstrainedBox( return ConstrainedBox(
constraints: BoxConstraints.tightFor(width: size, height: size), constraints: BoxConstraints.tightFor(width: size, height: size),
child: RawMaterialButton( child: UtilityWidgets.maybeTooltip(
visualDensity: VisualDensity.compact, message: tooltip,
shape: RoundedRectangleBorder( child: RawMaterialButton(
borderRadius: BorderRadius.circular(borderRadius)), visualDensity: VisualDensity.compact,
fillColor: fillColor, shape: RoundedRectangleBorder(
elevation: 0, borderRadius: BorderRadius.circular(borderRadius)),
hoverElevation: hoverElevation, fillColor: fillColor,
highlightElevation: hoverElevation, elevation: 0,
onPressed: () { hoverElevation: hoverElevation,
onPressed?.call(); highlightElevation: hoverElevation,
afterPressed?.call(); onPressed: () {
}, onPressed?.call();
child: icon, afterPressed?.call();
},
child: icon,
),
), ),
); );
} }

@ -15,6 +15,7 @@ class SearchButton extends StatelessWidget {
this.iconTheme, this.iconTheme,
this.dialogTheme, this.dialogTheme,
this.afterButtonPressed, this.afterButtonPressed,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -27,6 +28,7 @@ class SearchButton extends StatelessWidget {
final QuillDialogTheme? dialogTheme; final QuillDialogTheme? dialogTheme;
final VoidCallback? afterButtonPressed; final VoidCallback? afterButtonPressed;
final String? tooltip;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -37,6 +39,7 @@ class SearchButton extends StatelessWidget {
iconTheme?.iconUnselectedFillColor ?? (fillColor ?? theme.canvasColor); iconTheme?.iconUnselectedFillColor ?? (fillColor ?? theme.canvasColor);
return QuillIconButton( return QuillIconButton(
tooltip: tooltip,
icon: Icon(icon, size: iconSize, color: iconColor), icon: Icon(icon, size: iconSize, color: iconColor),
highlightElevation: 0, highlightElevation: 0,
hoverElevation: 0, hoverElevation: 0,

@ -4,8 +4,10 @@ import 'package:flutter/material.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/widgets.dart';
import '../controller.dart'; import '../controller.dart';
import '../toolbar.dart'; import '../toolbar.dart';
import 'enum.dart';
class SelectAlignmentButton extends StatefulWidget { class SelectAlignmentButton extends StatefulWidget {
const SelectAlignmentButton({ const SelectAlignmentButton({
@ -17,6 +19,7 @@ class SelectAlignmentButton extends StatefulWidget {
this.showRightAlignment, this.showRightAlignment,
this.showJustifyAlignment, this.showJustifyAlignment,
this.afterButtonPressed, this.afterButtonPressed,
this.tooltips = const <ToolbarButtons, String>{},
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -29,6 +32,7 @@ class SelectAlignmentButton extends StatefulWidget {
final bool? showRightAlignment; final bool? showRightAlignment;
final bool? showJustifyAlignment; final bool? showJustifyAlignment;
final VoidCallback? afterButtonPressed; final VoidCallback? afterButtonPressed;
final Map<ToolbarButtons, String> tooltips;
@override @override
_SelectAlignmentButtonState createState() => _SelectAlignmentButtonState(); _SelectAlignmentButtonState createState() => _SelectAlignmentButtonState();
@ -74,6 +78,16 @@ class _SelectAlignmentButtonState extends State<SelectAlignmentButton> {
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>{
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); final theme = Theme.of(context);
@ -93,40 +107,45 @@ class _SelectAlignmentButtonState extends State<SelectAlignmentButton> {
width: widget.iconSize * kIconButtonFactor, width: widget.iconSize * kIconButtonFactor,
height: widget.iconSize * kIconButtonFactor, height: widget.iconSize * kIconButtonFactor,
), ),
child: RawMaterialButton( child: UtilityWidgets.maybeTooltip(
hoverElevation: 0, message: widget.tooltips[_valueToButtons[_valueAttribute[index]]],
highlightElevation: 0, child: RawMaterialButton(
elevation: 0, hoverElevation: 0,
visualDensity: VisualDensity.compact, highlightElevation: 0,
shape: RoundedRectangleBorder( elevation: 0,
borderRadius: BorderRadius.circular( visualDensity: VisualDensity.compact,
widget.iconTheme?.borderRadius ?? 2)), shape: RoundedRectangleBorder(
fillColor: _valueToText[_value] == _valueString[index] borderRadius: BorderRadius.circular(
? (widget.iconTheme?.iconSelectedFillColor ?? widget.iconTheme?.borderRadius ?? 2)),
Theme.of(context).primaryColor) fillColor: _valueToText[_value] == _valueString[index]
: (widget.iconTheme?.iconUnselectedFillColor ?? ? (widget.iconTheme?.iconSelectedFillColor ??
theme.canvasColor), Theme.of(context).primaryColor)
onPressed: () { : (widget.iconTheme?.iconUnselectedFillColor ??
_valueAttribute[index] == Attribute.leftAlignment theme.canvasColor),
? widget.controller onPressed: () {
.formatSelection(Attribute.clone(Attribute.align, null)) _valueAttribute[index] == Attribute.leftAlignment
: widget.controller.formatSelection(_valueAttribute[index]); ? widget.controller.formatSelection(
widget.afterButtonPressed?.call(); Attribute.clone(Attribute.align, null))
}, : widget.controller
child: Icon( .formatSelection(_valueAttribute[index]);
_valueString[index] == Attribute.leftAlignment.value widget.afterButtonPressed?.call();
? Icons.format_align_left },
: _valueString[index] == Attribute.centerAlignment.value child: Icon(
? Icons.format_align_center _valueString[index] == Attribute.leftAlignment.value
: _valueString[index] == Attribute.rightAlignment.value ? Icons.format_align_left
? Icons.format_align_right : _valueString[index] == Attribute.centerAlignment.value
: Icons.format_align_justify, ? Icons.format_align_center
size: widget.iconSize, : _valueString[index] ==
color: _valueToText[_value] == _valueString[index] Attribute.rightAlignment.value
? (widget.iconTheme?.iconSelectedColor ?? ? Icons.format_align_right
theme.primaryIconTheme.color) : Icons.format_align_justify,
: (widget.iconTheme?.iconUnselectedColor ?? size: widget.iconSize,
theme.iconTheme.color), color: _valueToText[_value] == _valueString[index]
? (widget.iconTheme?.iconSelectedColor ??
theme.primaryIconTheme.color)
: (widget.iconTheme?.iconUnselectedColor ??
theme.iconTheme.color),
),
), ),
), ),
), ),

@ -4,6 +4,7 @@ import 'package:flutter/material.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/widgets.dart';
import '../controller.dart'; import '../controller.dart';
import '../toolbar.dart'; import '../toolbar.dart';
@ -20,6 +21,7 @@ class SelectHeaderStyleButton extends StatefulWidget {
Attribute.h3, Attribute.h3,
], ],
this.afterButtonPressed, this.afterButtonPressed,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -29,6 +31,7 @@ class SelectHeaderStyleButton extends StatefulWidget {
final QuillIconTheme? iconTheme; final QuillIconTheme? iconTheme;
final List<Attribute> attributes; final List<Attribute> attributes;
final VoidCallback? afterButtonPressed; final VoidCallback? afterButtonPressed;
final String? tooltip;
@override @override
_SelectHeaderStyleButtonState createState() => _SelectHeaderStyleButtonState createState() =>
@ -79,34 +82,37 @@ class _SelectHeaderStyleButtonState extends State<SelectHeaderStyleButton> {
width: widget.iconSize * kIconButtonFactor, width: widget.iconSize * kIconButtonFactor,
height: widget.iconSize * kIconButtonFactor, height: widget.iconSize * kIconButtonFactor,
), ),
child: RawMaterialButton( child: UtilityWidgets.maybeTooltip(
hoverElevation: 0, message: widget.tooltip,
highlightElevation: 0, child: RawMaterialButton(
elevation: 0, hoverElevation: 0,
visualDensity: VisualDensity.compact, highlightElevation: 0,
shape: RoundedRectangleBorder( elevation: 0,
borderRadius: visualDensity: VisualDensity.compact,
BorderRadius.circular(widget.iconTheme?.borderRadius ?? 2)), shape: RoundedRectangleBorder(
fillColor: isSelected borderRadius: BorderRadius.circular(
? (widget.iconTheme?.iconSelectedFillColor ?? widget.iconTheme?.borderRadius ?? 2)),
Theme.of(context).primaryColor) fillColor: isSelected
: (widget.iconTheme?.iconUnselectedFillColor ?? ? (widget.iconTheme?.iconSelectedFillColor ??
theme.canvasColor), Theme.of(context).primaryColor)
onPressed: () { : (widget.iconTheme?.iconUnselectedFillColor ??
final _attribute = _selectedAttribute == attribute theme.canvasColor),
? Attribute.header onPressed: () {
: attribute; final _attribute = _selectedAttribute == attribute
widget.controller.formatSelection(_attribute); ? Attribute.header
widget.afterButtonPressed?.call(); : attribute;
}, widget.controller.formatSelection(_attribute);
child: Text( widget.afterButtonPressed?.call();
_valueToText[attribute] ?? '', },
style: style.copyWith( child: Text(
color: isSelected _valueToText[attribute] ?? '',
? (widget.iconTheme?.iconSelectedColor ?? style: style.copyWith(
theme.primaryIconTheme.color) color: isSelected
: (widget.iconTheme?.iconUnselectedColor ?? ? (widget.iconTheme?.iconSelectedColor ??
theme.iconTheme.color), theme.primaryIconTheme.color)
: (widget.iconTheme?.iconUnselectedColor ??
theme.iconTheme.color),
),
), ),
), ),
), ),

@ -3,6 +3,7 @@ import 'package:flutter/material.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/widgets.dart';
import '../controller.dart'; import '../controller.dart';
import '../toolbar.dart'; import '../toolbar.dart';
@ -16,6 +17,7 @@ class ToggleCheckListButton extends StatefulWidget {
this.childBuilder = defaultToggleStyleButtonBuilder, this.childBuilder = defaultToggleStyleButtonBuilder,
this.iconTheme, this.iconTheme,
this.afterButtonPressed, this.afterButtonPressed,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -32,6 +34,7 @@ class ToggleCheckListButton extends StatefulWidget {
final QuillIconTheme? iconTheme; final QuillIconTheme? iconTheme;
final VoidCallback? afterButtonPressed; final VoidCallback? afterButtonPressed;
final String? tooltip;
@override @override
_ToggleCheckListButtonState createState() => _ToggleCheckListButtonState(); _ToggleCheckListButtonState createState() => _ToggleCheckListButtonState();
@ -91,16 +94,19 @@ class _ToggleCheckListButtonState extends State<ToggleCheckListButton> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return widget.childBuilder( return UtilityWidgets.maybeTooltip(
context, message: widget.tooltip,
Attribute.unchecked, child: widget.childBuilder(
widget.icon, context,
widget.fillColor, Attribute.unchecked,
_isToggled, widget.icon,
_toggleAttribute, widget.fillColor,
widget.afterButtonPressed, _isToggled,
widget.iconSize, _toggleAttribute,
widget.iconTheme, widget.afterButtonPressed,
widget.iconSize,
widget.iconTheme,
),
); );
} }

@ -3,6 +3,7 @@ import 'package:flutter/material.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/widgets.dart';
import '../controller.dart'; import '../controller.dart';
import '../toolbar.dart'; import '../toolbar.dart';
@ -28,6 +29,7 @@ class ToggleStyleButton extends StatefulWidget {
this.childBuilder = defaultToggleStyleButtonBuilder, this.childBuilder = defaultToggleStyleButtonBuilder,
this.iconTheme, this.iconTheme,
this.afterButtonPressed, this.afterButtonPressed,
this.tooltip,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -46,6 +48,7 @@ class ToggleStyleButton extends StatefulWidget {
final QuillIconTheme? iconTheme; final QuillIconTheme? iconTheme;
final VoidCallback? afterButtonPressed; final VoidCallback? afterButtonPressed;
final String? tooltip;
@override @override
_ToggleStyleButtonState createState() => _ToggleStyleButtonState(); _ToggleStyleButtonState createState() => _ToggleStyleButtonState();
@ -65,16 +68,19 @@ class _ToggleStyleButtonState extends State<ToggleStyleButton> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return widget.childBuilder( return UtilityWidgets.maybeTooltip(
context, message: widget.tooltip,
widget.attribute, child: widget.childBuilder(
widget.icon, context,
widget.fillColor, widget.attribute,
_isToggled, widget.icon,
_toggleAttribute, widget.fillColor,
widget.afterButtonPressed, _isToggled,
widget.iconSize, _toggleAttribute,
widget.iconTheme, widget.afterButtonPressed,
widget.iconSize,
widget.iconTheme,
),
); );
} }

Loading…
Cancel
Save