diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart index 253d28cecd..a28fa3060f 100755 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart @@ -1,7 +1,6 @@ import 'package:app_flowy/plugins/grid/application/field/field_cell_bloc.dart'; import 'package:app_flowy/plugins/grid/application/field/field_service.dart'; -import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart'; -import 'package:appflowy_popover/appflowy_popover.dart'; +import 'package:appflowy_popover/popover.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui_web.dart'; @@ -15,7 +14,6 @@ import '../../layout/sizes.dart'; import 'field_type_extension.dart'; import 'field_cell_action_sheet.dart'; -import 'field_editor.dart'; class GridFieldCell extends StatefulWidget { final GridFieldCellContext cellContext; @@ -26,7 +24,7 @@ class GridFieldCell extends StatefulWidget { } class _GridFieldCellState extends State { - final popover = AppFlowyPopoverController(); + final popover = PopoverController(); @override Widget build(BuildContext gridCellContext) { @@ -36,7 +34,7 @@ class _GridFieldCellState extends State { child: BlocBuilder( // buildWhen: (p, c) => p.field != c.field, builder: (context, state) { - final button = AppFlowyPopover( + final button = Popover( controller: popover, child: FieldCellButton( field: state.field, diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell_action_sheet.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell_action_sheet.dart index 6eb02a5918..c560a333a6 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell_action_sheet.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell_action_sheet.dart @@ -11,7 +11,7 @@ import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:appflowy_popover/appflowy_popover.dart'; +import 'package:appflowy_popover/popover.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; import '../../layout/sizes.dart'; @@ -61,7 +61,7 @@ class _EditFieldButton extends StatefulWidget { } class _EditFieldButtonState extends State<_EditFieldButton> { - final popover = AppFlowyPopoverController(); + final popover = PopoverController(); @override Widget build(BuildContext context) { @@ -70,7 +70,7 @@ class _EditFieldButtonState extends State<_EditFieldButton> { builder: (context, state) { return SizedBox( height: GridSize.typeOptionItemHeight, - child: AppFlowyPopover( + child: Popover( controller: popover, targetAnchor: Alignment.topRight, followerAnchor: Alignment.topLeft, diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart index cd2efb2c4e..5da201d8c3 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart @@ -10,7 +10,7 @@ import 'package:app_flowy/generated/locale_keys.g.dart'; import 'field_name_input.dart'; import 'field_type_option_editor.dart'; -class FieldEditor extends StatelessWidget with FlowyOverlayDelegate { +class FieldEditor extends StatelessWidget { final String gridId; final String fieldName; @@ -49,10 +49,6 @@ class FieldEditor extends StatelessWidget with FlowyOverlayDelegate { ); } - static String identifier() { - return (FieldEditor).toString(); - } - @override bool asBarrier() => true; } diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_type_option_editor.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_type_option_editor.dart index 11e0434054..a545a9b2b7 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_type_option_editor.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_type_option_editor.dart @@ -1,5 +1,6 @@ import 'dart:typed_data'; import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_data_controller.dart'; +import 'package:appflowy_popover/popover.dart'; import 'package:dartz/dartz.dart' show Either; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; @@ -36,6 +37,7 @@ class FieldTypeOptionEditor extends StatefulWidget { } class _FieldTypeOptionEditorState extends State { + final popover = PopoverController(); String? currentOverlayIdentifier; @override @@ -68,18 +70,33 @@ class _FieldTypeOptionEditorState extends State { final theme = context.watch(); return SizedBox( height: GridSize.typeOptionItemHeight, - child: FlowyButton( - text: FlowyText.medium(field.fieldType.title(), fontSize: 12), - margin: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), - hoverColor: theme.hover, - onTap: () { + child: Popover( + controller: popover, + offset: const Offset(20, 0), + targetAnchor: Alignment.topRight, + followerAnchor: Alignment.topLeft, + popupBuilder: (context) { final list = FieldTypeList(onSelectField: (newFieldType) { widget.dataController.switchToField(newFieldType); }); - _showOverlay(context, list); + return OverlayContainer( + constraints: BoxConstraints.loose(const Size(460, 440)), + child: list, + ); }, - leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), - rightIcon: svgWidget("grid/more", color: theme.iconColor), + child: FlowyButton( + text: FlowyText.medium(field.fieldType.title(), fontSize: 12), + margin: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), + hoverColor: theme.hover, + onHover: (bool hover) { + if (hover) { + popover.show(); + } + }, + leftIcon: + svgWidget(field.fieldType.iconName(), color: theme.iconColor), + rightIcon: svgWidget("grid/more", color: theme.iconColor), + ), ), ); } diff --git a/frontend/app_flowy/packages/appflowy_popover/example/lib/example_button.dart b/frontend/app_flowy/packages/appflowy_popover/example/lib/example_button.dart index df8b83f349..3e5699b334 100644 --- a/frontend/app_flowy/packages/appflowy_popover/example/lib/example_button.dart +++ b/frontend/app_flowy/packages/appflowy_popover/example/lib/example_button.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:appflowy_popover/appflowy_popover.dart'; +import 'package:appflowy_popover/popover.dart'; class PopoverMenu extends StatefulWidget { @override @@ -7,14 +7,14 @@ class PopoverMenu extends StatefulWidget { } class _PopoverMenuState extends State { - final AppFlowyPopoverExclusive exclusive = AppFlowyPopoverExclusive(); - late AppFlowyPopoverController firstPopover; - late AppFlowyPopoverController secondPopover; + final PopoverExclusive exclusive = PopoverExclusive(); + late PopoverController firstPopover; + late PopoverController secondPopover; @override void initState() { - firstPopover = AppFlowyPopoverController(exclusive: exclusive); - secondPopover = AppFlowyPopoverController(exclusive: exclusive); + firstPopover = PopoverController(exclusive: exclusive); + secondPopover = PopoverController(exclusive: exclusive); super.initState(); } @@ -26,7 +26,7 @@ class _PopoverMenuState extends State { decoration: const BoxDecoration(color: Colors.yellow), child: ListView(children: [ const Text("App"), - AppFlowyPopover( + Popover( controller: firstPopover, offset: const Offset(10, 0), targetAnchor: Alignment.topRight, @@ -46,7 +46,7 @@ class _PopoverMenuState extends State { child: const Text("First"), ), ), - AppFlowyPopover( + Popover( controller: secondPopover, offset: const Offset(10, 0), targetAnchor: Alignment.topRight, @@ -72,7 +72,7 @@ class _PopoverMenuState extends State { } class ExampleButton extends StatelessWidget { - final AppFlowyPopoverController _popover = AppFlowyPopoverController(); + final PopoverController _popover = PopoverController(); final String label; final Alignment targetAnchor; @@ -89,7 +89,7 @@ class ExampleButton extends StatelessWidget { @override Widget build(BuildContext context) { - return AppFlowyPopover( + return Popover( controller: _popover, targetAnchor: targetAnchor, followerAnchor: followerAnchor, diff --git a/frontend/app_flowy/packages/appflowy_popover/lib/appflowy_popover.dart b/frontend/app_flowy/packages/appflowy_popover/lib/popover.dart similarity index 82% rename from frontend/app_flowy/packages/appflowy_popover/lib/appflowy_popover.dart rename to frontend/app_flowy/packages/appflowy_popover/lib/popover.dart index ab2d1bf37b..e25ac26d56 100644 --- a/frontend/app_flowy/packages/appflowy_popover/lib/appflowy_popover.dart +++ b/frontend/app_flowy/packages/appflowy_popover/lib/popover.dart @@ -1,15 +1,16 @@ +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -class AppFlowyPopoverExclusive { - AppFlowyPopoverController? controller; +class PopoverExclusive { + PopoverController? controller; } -class AppFlowyPopoverController { - AppFlowyPopoverState? state; - AppFlowyPopoverExclusive? exclusive; +class PopoverController { + PopoverState? state; + PopoverExclusive? exclusive; - AppFlowyPopoverController({this.exclusive}); + PopoverController({this.exclusive}); close() { state?.close(); @@ -28,16 +29,16 @@ class AppFlowyPopoverController { } } -class AppFlowyPopover extends StatefulWidget { +class Popover extends StatefulWidget { final Widget child; - final AppFlowyPopoverController? controller; + final PopoverController? controller; final Offset? offset; final Decoration? maskDecoration; final Alignment targetAnchor; final Alignment followerAnchor; final Widget Function(BuildContext context) popupBuilder; - const AppFlowyPopover({ + const Popover({ Key? key, required this.child, required this.popupBuilder, @@ -49,19 +50,27 @@ class AppFlowyPopover extends StatefulWidget { }) : super(key: key); @override - State createState() => AppFlowyPopoverState(); + State createState() => PopoverState(); } -class AppFlowyPopoverState extends State { +class PopoverState extends State { final LayerLink layerLink = LayerLink(); OverlayEntry? _overlayEntry; bool hasMask = true; + late TapGestureRecognizer _recognizer; - static AppFlowyPopoverState? _popoverWithMask; + static PopoverState? _popoverWithMask; @override void initState() { widget.controller?.state = this; + _recognizer = TapGestureRecognizer(); + _recognizer.onTapDown = (details) { + debugPrint("ggg tapdown"); + }; + _recognizer.onTap = (() { + debugPrint("ggg tap"); + }); super.initState(); } @@ -121,6 +130,12 @@ class AppFlowyPopoverState extends State { super.deactivate(); } + @override + void dispose() { + _recognizer.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return CompositedTransformTarget(link: layerLink, child: widget.child); diff --git a/frontend/app_flowy/packages/appflowy_popover/test/appflowy_popover_test.dart b/frontend/app_flowy/packages/appflowy_popover/test/popover_test.dart similarity index 100% rename from frontend/app_flowy/packages/appflowy_popover/test/appflowy_popover_test.dart rename to frontend/app_flowy/packages/appflowy_popover/test/popover_test.dart diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart index 046ee8a0c1..ba2b3049af 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; class FlowyButton extends StatelessWidget { final Widget text; final VoidCallback? onTap; + final void Function(bool)? onHover; final EdgeInsets margin; final Widget? leftIcon; final Widget? rightIcon; @@ -15,6 +16,7 @@ class FlowyButton extends StatelessWidget { Key? key, required this.text, this.onTap, + this.onHover, this.margin = const EdgeInsets.symmetric(horizontal: 6, vertical: 2), this.leftIcon, this.rightIcon, @@ -27,7 +29,9 @@ class FlowyButton extends StatelessWidget { return InkWell( onTap: onTap, child: FlowyHover( - style: HoverStyle(borderRadius: BorderRadius.zero, hoverColor: hoverColor), + style: + HoverStyle(borderRadius: BorderRadius.zero, hoverColor: hoverColor), + onHover: onHover, setSelected: () => isSelected, builder: (context, onHover) => _render(), ), @@ -38,14 +42,16 @@ class FlowyButton extends StatelessWidget { List children = List.empty(growable: true); if (leftIcon != null) { - children.add(SizedBox.fromSize(size: const Size.square(16), child: leftIcon!)); + children.add( + SizedBox.fromSize(size: const Size.square(16), child: leftIcon!)); children.add(const HSpace(6)); } children.add(Expanded(child: text)); if (rightIcon != null) { - children.add(SizedBox.fromSize(size: const Size.square(16), child: rightIcon!)); + children.add( + SizedBox.fromSize(size: const Size.square(16), child: rightIcon!)); } return Padding( @@ -121,7 +127,8 @@ class FlowyTextButton extends StatelessWidget { visualDensity: VisualDensity.compact, hoverElevation: 0, highlightElevation: 0, - shape: RoundedRectangleBorder(borderRadius: radius ?? BorderRadius.circular(2)), + shape: RoundedRectangleBorder( + borderRadius: radius ?? BorderRadius.circular(2)), fillColor: fillColor, hoverColor: hoverColor ?? Colors.transparent, focusColor: Colors.transparent, diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart index b9440bf1f1..6938a2f209 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart @@ -9,6 +9,7 @@ class FlowyHover extends StatefulWidget { final HoverBuilder? builder; final Widget? child; final bool Function()? setSelected; + final void Function(bool)? onHover; final MouseCursor? cursor; const FlowyHover( @@ -17,6 +18,7 @@ class FlowyHover extends StatefulWidget { this.child, required this.style, this.setSelected, + this.onHover, this.cursor}) : super(key: key); @@ -32,8 +34,18 @@ class _FlowyHoverState extends State { return MouseRegion( cursor: widget.cursor != null ? widget.cursor! : SystemMouseCursors.click, opaque: false, - onEnter: (p) => setState(() => _onHover = true), - onExit: (p) => setState(() => _onHover = false), + onEnter: (p) { + setState(() => _onHover = true); + if (widget.onHover != null) { + widget.onHover!(true); + } + }, + onExit: (p) { + setState(() => _onHover = false); + if (widget.onHover != null) { + widget.onHover!(false); + } + }, child: renderWidget(), ); }