diff --git a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/doc_page.dart b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/doc_page.dart index 4039834a9d..61f05d4cce 100644 --- a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/doc_page.dart +++ b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/doc_page.dart @@ -98,6 +98,7 @@ class _DocPageState extends State { controller: controller, focusNode: _focusNode, scrollable: true, + paintCursorAboveText: true, autoFocus: controller.document.isEmpty(), expands: false, padding: const EdgeInsets.symmetric(horizontal: 8.0), diff --git a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/check_button.dart b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/check_button.dart index dc79c77163..55f17ac558 100644 --- a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/check_button.dart +++ b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/check_button.dart @@ -8,6 +8,7 @@ class FlowyCheckListButton extends StatefulWidget { const FlowyCheckListButton({ required this.controller, required this.attribute, + required this.tooltipText, this.iconSize = defaultIconSize, this.fillColor, this.childBuilder = defaultToggleStyleButtonBuilder, @@ -24,6 +25,8 @@ class FlowyCheckListButton extends StatefulWidget { final Attribute attribute; + final String tooltipText; + @override _FlowyCheckListButtonState createState() => _FlowyCheckListButtonState(); } @@ -35,7 +38,8 @@ class _FlowyCheckListButtonState extends State { void _didChangeEditingValue() { setState(() { - _isToggled = _getIsToggled(widget.controller.getSelectionStyle().attributes); + _isToggled = + _getIsToggled(widget.controller.getSelectionStyle().attributes); }); } @@ -52,7 +56,8 @@ class _FlowyCheckListButtonState extends State { if (attribute == null) { return false; } - return attribute.value == widget.attribute.value || attribute.value == Attribute.checked.value; + return attribute.value == widget.attribute.value || + attribute.value == Attribute.checked.value; } return attrs.containsKey(widget.attribute.key); } @@ -80,10 +85,13 @@ class _FlowyCheckListButtonState extends State { width: widget.iconSize * kIconButtonFactor, iconName: 'editor/checkbox', isToggled: _isToggled ?? false, + tooltipText: widget.tooltipText, ); } void _toggleAttribute() { - widget.controller.formatSelection(_isToggled! ? Attribute.clone(Attribute.unchecked, null) : Attribute.unchecked); + widget.controller.formatSelection(_isToggled! + ? Attribute.clone(Attribute.unchecked, null) + : Attribute.unchecked); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/color_picker.dart b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/color_picker.dart index 5800fdaab8..b103ae2fc2 100644 --- a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/color_picker.dart +++ b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/color_picker.dart @@ -33,6 +33,7 @@ class _FlowyColorButtonState extends State { late bool _isWhitebackground; Style get _selectionStyle => widget.controller.getSelectionStyle(); + final tooltipText = 'Highlight'; void _didChangeEditingValue() { setState(() { @@ -91,13 +92,17 @@ class _FlowyColorButtonState extends State { ? stringToColor('#ffffff') : (widget.iconTheme?.iconUnselectedFillColor ?? theme.canvasColor); - return QuillIconButton( - highlightElevation: 0, - hoverElevation: 0, - size: widget.iconSize * kIconButtonFactor, - icon: Icon(widget.icon, size: widget.iconSize, color: theme.iconTheme.color), - fillColor: widget.background ? fillColorBackground : fillColor, - onPressed: _showColorPicker, + return Tooltip( + message: tooltipText, + showDuration: Duration.zero, + child: QuillIconButton( + highlightElevation: 0, + hoverElevation: 0, + size: widget.iconSize * kIconButtonFactor, + icon: Icon(widget.icon, size: widget.iconSize, color: theme.iconTheme.color), + fillColor: widget.background ? fillColorBackground : fillColor, + onPressed: _showColorPicker, + ), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/header_button.dart b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/header_button.dart index 762002ffc4..fce8ba6941 100644 --- a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/header_button.dart +++ b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/header_button.dart @@ -51,6 +51,7 @@ class _FlowyHeaderStyleButtonState extends State { // final child = // _valueToText[_value] == _valueString[index] ? svg('editor/H1', color: Colors.white) : svg('editor/H1'); + final headerTitle = 'Header ${index + 1}'; final _isToggled = _valueToText[_value] == _valueString[index]; return ToolbarIconButton( onPressed: () { @@ -63,6 +64,7 @@ class _FlowyHeaderStyleButtonState extends State { width: widget.iconSize * kIconButtonFactor, iconName: _attributeImageName[index], isToggled: _isToggled, + tooltipText: headerTitle, ); }), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/history_button.dart b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/history_button.dart new file mode 100644 index 0000000000..72a1ffb55e --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/history_button.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_quill/flutter_quill.dart'; + +class FlowyHistoryButton extends StatelessWidget { + final IconData icon; + final double iconSize; + final bool undo; + final QuillController controller; + final String tooltipText; + + const FlowyHistoryButton({ + required this.icon, + required this.controller, + required this.undo, + required this.tooltipText, + required this.iconSize, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Tooltip( + message: tooltipText, + showDuration: Duration.zero, + child: HistoryButton( + icon: icon, + iconSize: iconSize, + controller: controller, + undo: true, + ), + ); + } +} diff --git a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/image_button.dart b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/image_button.dart index 844422071a..1a18ef10f1 100644 --- a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/image_button.dart +++ b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/image_button.dart @@ -5,6 +5,7 @@ import 'toolbar_icon_button.dart'; class FlowyImageButton extends StatelessWidget { const FlowyImageButton({ required this.controller, + required this.tooltipText, this.iconSize = defaultIconSize, this.onImagePickCallback, this.fillColor, @@ -28,6 +29,8 @@ class FlowyImageButton extends StatelessWidget { final MediaPickSettingSelector? mediaPickSettingSelector; + final String tooltipText; + @override Widget build(BuildContext context) { return ToolbarIconButton( @@ -35,6 +38,7 @@ class FlowyImageButton extends StatelessWidget { width: iconSize * 1.77, onPressed: () => _onPressedHandler(context), isToggled: false, + tooltipText: tooltipText, ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/toggle_button.dart b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/toggle_button.dart index bb11e6557f..89fd72981d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/toggle_button.dart +++ b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/toggle_button.dart @@ -9,11 +9,13 @@ class FlowyToggleStyleButton extends StatefulWidget { final String normalIcon; final double iconSize; final QuillController controller; + final String tooltipText; const FlowyToggleStyleButton({ required this.attribute, required this.normalIcon, required this.controller, + required this.tooltipText, this.iconSize = defaultIconSize, Key? key, }) : super(key: key); @@ -39,6 +41,7 @@ class _ToggleStyleButtonState extends State { width: widget.iconSize * kIconButtonFactor, isToggled: _isToggled ?? false, iconName: widget.normalIcon, + tooltipText: widget.tooltipText, ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/tool_bar.dart b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/tool_bar.dart index bab979dbef..0e3038360c 100644 --- a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/tool_bar.dart +++ b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/tool_bar.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:math'; +import 'package:app_flowy/workspace/presentation/stack_page/doc/widget/toolbar/history_button.dart'; import 'package:flutter_quill/flutter_quill.dart'; import 'package:flutter/material.dart'; import 'package:styled_widget/styled_widget.dart'; @@ -50,41 +51,47 @@ class EditorToolbar extends StatelessWidget implements PreferredSizeWidget { key: key, toolBarHeight: toolbarIconSize * 2, children: [ - HistoryButton( + FlowyHistoryButton( icon: Icons.undo_outlined, iconSize: toolbarIconSize, controller: controller, undo: true, + tooltipText: 'Undo', ), - HistoryButton( + FlowyHistoryButton( icon: Icons.redo_outlined, iconSize: toolbarIconSize, controller: controller, undo: false, + tooltipText: 'Redo', ), FlowyToggleStyleButton( attribute: Attribute.bold, normalIcon: 'editor/bold', iconSize: toolbarIconSize, controller: controller, + tooltipText: 'Bold', ), FlowyToggleStyleButton( attribute: Attribute.italic, normalIcon: 'editor/italic', iconSize: toolbarIconSize, controller: controller, + tooltipText: 'Italic', ), FlowyToggleStyleButton( attribute: Attribute.underline, normalIcon: 'editor/underline', iconSize: toolbarIconSize, controller: controller, + tooltipText: 'Underline', ), FlowyToggleStyleButton( attribute: Attribute.strikeThrough, normalIcon: 'editor/strikethrough', iconSize: toolbarIconSize, controller: controller, + tooltipText: 'Strikethrough', ), FlowyColorButton( icon: Icons.format_color_fill, @@ -109,29 +116,34 @@ class EditorToolbar extends StatelessWidget implements PreferredSizeWidget { controller: controller, normalIcon: 'editor/numbers', iconSize: toolbarIconSize, + tooltipText: 'Numbered List', ), FlowyToggleStyleButton( attribute: Attribute.ul, controller: controller, normalIcon: 'editor/bullet_list', iconSize: toolbarIconSize, + tooltipText: 'Bulleted List', ), FlowyCheckListButton( attribute: Attribute.unchecked, controller: controller, iconSize: toolbarIconSize, + tooltipText: 'Check List', ), FlowyToggleStyleButton( attribute: Attribute.inlineCode, controller: controller, normalIcon: 'editor/inline_block', iconSize: toolbarIconSize, + tooltipText: 'Inline Code', ), FlowyToggleStyleButton( attribute: Attribute.blockQuote, controller: controller, normalIcon: 'editor/quote', iconSize: toolbarIconSize, + tooltipText: 'Quote Block', ), FlowyLinkStyleButton( controller: controller, diff --git a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/toolbar_icon_button.dart b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/toolbar_icon_button.dart index fb4ac60292..c8eb8cde72 100644 --- a/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/toolbar_icon_button.dart +++ b/frontend/app_flowy/lib/workspace/presentation/stack_page/doc/widget/toolbar/toolbar_icon_button.dart @@ -11,10 +11,16 @@ class ToolbarIconButton extends StatelessWidget { final VoidCallback? onPressed; final bool isToggled; final String iconName; + final String tooltipText; - const ToolbarIconButton( - {Key? key, required this.onPressed, required this.isToggled, required this.width, required this.iconName}) - : super(key: key); + const ToolbarIconButton({ + Key? key, + required this.onPressed, + required this.isToggled, + required this.width, + required this.iconName, + required this.tooltipText, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -23,9 +29,12 @@ class ToolbarIconButton extends StatelessWidget { iconPadding: const EdgeInsets.symmetric(horizontal: 4, vertical: 4), onPressed: onPressed, width: width, - icon: isToggled == true ? svg(iconName, color: Colors.white) : svg(iconName), + icon: isToggled == true + ? svg(iconName, color: Colors.white) + : svg(iconName), fillColor: isToggled == true ? theme.main1 : theme.shader6, hoverColor: isToggled == true ? theme.main1 : theme.shader5, + tooltipText: tooltipText, ); } } diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/icon_button.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/icon_button.dart index 2c71ed11be..0b960a7abb 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/icon_button.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/icon_button.dart @@ -12,6 +12,7 @@ class FlowyIconButton extends StatelessWidget { final Color? hoverColor; final EdgeInsets iconPadding; final BorderRadius? radius; + final String? tooltipText; const FlowyIconButton({ Key? key, @@ -22,6 +23,7 @@ class FlowyIconButton extends StatelessWidget { this.hoverColor = Colors.transparent, this.iconPadding = EdgeInsets.zero, this.radius, + this.tooltipText, required this.icon, }) : super(key: key); @@ -48,21 +50,25 @@ class FlowyIconButton extends StatelessWidget { return ConstrainedBox( constraints: BoxConstraints.tightFor(width: size.width, height: size.height), - child: RawMaterialButton( - visualDensity: VisualDensity.compact, - hoverElevation: 0, - highlightElevation: 0, - shape: RoundedRectangleBorder(borderRadius: radius ?? BorderRadius.circular(2)), - fillColor: fillColor, - hoverColor: hoverColor, - focusColor: Colors.transparent, - splashColor: Colors.transparent, - highlightColor: Colors.transparent, - elevation: 0, - onPressed: onPressed, - child: Padding( - padding: iconPadding, - child: SizedBox.fromSize(child: child, size: childSize), + child: Tooltip( + message: tooltipText ?? '', + showDuration: Duration.zero, + child: RawMaterialButton( + visualDensity: VisualDensity.compact, + hoverElevation: 0, + highlightElevation: 0, + shape: RoundedRectangleBorder(borderRadius: radius ?? BorderRadius.circular(2)), + fillColor: fillColor, + hoverColor: hoverColor, + focusColor: Colors.transparent, + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + elevation: 0, + onPressed: onPressed, + child: Padding( + padding: iconPadding, + child: SizedBox.fromSize(child: child, size: childSize), + ), ), ), );