Browse Source

fix: open GridRowActionSheet with appflowy overlay

appflowy 2 years ago
parent
commit
53cc0fff9d
25 changed files with 250 additions and 186 deletions
  1. 1 1
      frontend/app_flowy/lib/plugins/board/presentation/card/board_select_option_cell.dart
  2. 63 27
      frontend/app_flowy/lib/plugins/board/presentation/card/card.dart
  3. 74 0
      frontend/app_flowy/lib/plugins/board/presentation/card/container/accessory.dart
  4. 21 68
      frontend/app_flowy/lib/plugins/board/presentation/card/container/card_container.dart
  5. 1 1
      frontend/app_flowy/lib/plugins/board/presentation/toolbar/board_toolbar.dart
  6. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_cell.dart
  7. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart
  8. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_cell.dart
  9. 2 6
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart
  10. 2 2
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/url_cell/url_cell.dart
  11. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart
  12. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart
  13. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_type_option_editor.dart
  14. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/grid_header.dart
  15. 2 2
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/date.dart
  16. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/number.dart
  17. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/select_option.dart
  18. 68 30
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/grid_row.dart
  19. 2 33
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_action_sheet.dart
  20. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart
  21. 0 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_group.dart
  22. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_property.dart
  23. 0 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_setting.dart
  24. 1 1
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_toolbar.dart
  25. 2 2
      frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/appflowy_stype_popover.dart

+ 1 - 1
frontend/app_flowy/lib/plugins/board/presentation/card/board_select_option_cell.dart

@@ -87,7 +87,7 @@ class _BoardSelectOptionCellState extends State<BoardSelectOptionCell> {
       SelectOptionCellEditor.editorPanelWidth,
       300,
     ));
-    return AppFlowyStylePopover(
+    return AppFlowyPopover(
       controller: _popover,
       constraints: constraints,
       direction: PopoverDirection.bottomWithLeftAligned,

+ 63 - 27
frontend/app_flowy/lib/plugins/board/presentation/card/card.dart

@@ -1,15 +1,17 @@
 import 'package:app_flowy/plugins/board/application/card/card_bloc.dart';
 import 'package:app_flowy/plugins/board/application/card/card_data_controller.dart';
 import 'package:app_flowy/plugins/grid/presentation/widgets/row/row_action_sheet.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';
+import 'package:flowy_infra_ui/flowy_infra_ui.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'board_cell.dart';
 import 'card_cell_builder.dart';
-import 'card_container.dart';
+import 'container/accessory.dart';
+import 'container/card_container.dart';
 
 class BoardCard extends StatefulWidget {
   final String gridId;
@@ -38,6 +40,8 @@ class BoardCard extends StatefulWidget {
 class _BoardCardState extends State<BoardCard> {
   late BoardCardBloc _cardBloc;
   late EditableRowNotifier rowNotifier;
+  late PopoverController popoverController;
+  AccessoryType? accessoryType;
 
   @override
   void initState() {
@@ -54,6 +58,7 @@ class _BoardCardState extends State<BoardCard> {
       _cardBloc.add(BoardCardEvent.setIsEditing(rowNotifier.isEditing.value));
     });
 
+    popoverController = PopoverController();
     super.initState();
   }
 
@@ -64,32 +69,42 @@ class _BoardCardState extends State<BoardCard> {
       child: BlocBuilder<BoardCardBloc, BoardCardState>(
         buildWhen: (previous, current) {
           // Rebuild when:
-          // 1.If the lenght of the cells is not the same
+          // 1.If the length of the cells is not the same
           // 2.isEditing changed
           if (previous.cells.length != current.cells.length ||
               previous.isEditing != current.isEditing) {
             return true;
           }
 
-          // 3.Compare the content of the cells. The cells consisits of
+          // 3.Compare the content of the cells. The cells consists of
           // list of [BoardCellEquatable] that extends the [Equatable].
           return !listEquals(previous.cells, current.cells);
         },
         builder: (context, state) {
-          return BoardCardContainer(
-            buildAccessoryWhen: () => state.isEditing == false,
-            accessoryBuilder: (context) {
-              return [
-                _CardEditOption(rowNotifier: rowNotifier),
-                const _CardMoreOption(),
-              ];
-            },
-            onTap: (context) => widget.openCard(context),
-            child: _CellColumn(
-              groupId: widget.groupId,
-              rowNotifier: rowNotifier,
-              cellBuilder: widget.cellBuilder,
-              cells: state.cells,
+          return AppFlowyPopover(
+            controller: popoverController,
+            constraints: BoxConstraints.loose(const Size(140, 200)),
+            direction: PopoverDirection.rightWithCenterAligned,
+            popupBuilder: (popoverContext) => _handlePopoverBuilder(
+              context,
+              popoverContext,
+            ),
+            child: BoardCardContainer(
+              buildAccessoryWhen: () => state.isEditing == false,
+              accessoryBuilder: (context) {
+                return [
+                  _CardEditOption(rowNotifier: rowNotifier),
+                  _CardMoreOption(),
+                ];
+              },
+              openAccessory: _handleOpenAccessory,
+              openCard: (context) => widget.openCard(context),
+              child: _CellColumn(
+                groupId: widget.groupId,
+                rowNotifier: rowNotifier,
+                cellBuilder: widget.cellBuilder,
+                cells: state.cells,
+              ),
             ),
           );
         },
@@ -97,6 +112,30 @@ class _BoardCardState extends State<BoardCard> {
     );
   }
 
+  void _handleOpenAccessory(AccessoryType newAccessoryType) {
+    accessoryType = newAccessoryType;
+    switch (newAccessoryType) {
+      case AccessoryType.edit:
+        break;
+      case AccessoryType.more:
+        popoverController.show();
+        break;
+    }
+  }
+
+  Widget _handlePopoverBuilder(
+    BuildContext context,
+    BuildContext popoverContext,
+  ) {
+    switch (accessoryType!) {
+      case AccessoryType.edit:
+        throw UnimplementedError();
+      case AccessoryType.more:
+        return GridRowActionSheet(
+            rowData: context.read<BoardCardBloc>().rowInfo());
+    }
+  }
+
   @override
   Future<void> dispose() async {
     rowNotifier.dispose();
@@ -163,7 +202,7 @@ class _CellColumn extends StatelessWidget {
 }
 
 class _CardMoreOption extends StatelessWidget with CardAccessory {
-  const _CardMoreOption({Key? key}) : super(key: key);
+  _CardMoreOption({Key? key}) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
@@ -175,11 +214,7 @@ class _CardMoreOption extends StatelessWidget with CardAccessory {
   }
 
   @override
-  void onTap(BuildContext context) {
-    GridRowActionSheet(
-      rowData: context.read<BoardCardBloc>().rowInfo(),
-    ).show(context, direction: AnchorDirection.bottomWithCenterAligned);
-  }
+  AccessoryType get type => AccessoryType.more;
 }
 
 class _CardEditOption extends StatelessWidget with CardAccessory {
@@ -201,7 +236,8 @@ class _CardEditOption extends StatelessWidget with CardAccessory {
   }
 
   @override
-  void onTap(BuildContext context) {
-    rowNotifier.becomeFirstResponder();
-  }
+  void onTap(BuildContext context) => rowNotifier.becomeFirstResponder();
+
+  @override
+  AccessoryType get type => AccessoryType.edit;
 }

+ 74 - 0
frontend/app_flowy/lib/plugins/board/presentation/card/container/accessory.dart

@@ -0,0 +1,74 @@
+import 'package:flowy_infra/theme.dart';
+import 'package:flowy_infra_ui/style_widget/hover.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+enum AccessoryType {
+  edit,
+  more,
+}
+
+abstract class CardAccessory implements Widget {
+  AccessoryType get type;
+  void onTap(BuildContext context) {}
+}
+
+typedef CardAccessoryBuilder = List<CardAccessory> Function(
+  BuildContext buildContext,
+);
+
+class CardAccessoryContainer extends StatelessWidget {
+  final void Function(AccessoryType) onTapAccessory;
+  final List<CardAccessory> accessories;
+  const CardAccessoryContainer({
+    required this.accessories,
+    required this.onTapAccessory,
+    Key? key,
+  }) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    final theme = context.read<AppTheme>();
+    final children = accessories.map((accessory) {
+      return GestureDetector(
+        behavior: HitTestBehavior.opaque,
+        onTap: () {
+          accessory.onTap(context);
+          onTapAccessory(accessory.type);
+        },
+        child: _wrapHover(theme, accessory),
+      );
+    }).toList();
+    return _wrapDecoration(context, Row(children: children));
+  }
+
+  FlowyHover _wrapHover(AppTheme theme, CardAccessory accessory) {
+    return FlowyHover(
+      style: HoverStyle(
+        hoverColor: theme.hover,
+        backgroundColor: theme.surface,
+        borderRadius: BorderRadius.zero,
+      ),
+      builder: (_, onHover) => SizedBox(
+        width: 24,
+        height: 24,
+        child: accessory,
+      ),
+    );
+  }
+
+  Widget _wrapDecoration(BuildContext context, Widget child) {
+    final theme = context.read<AppTheme>();
+    final borderSide = BorderSide(color: theme.shader6, width: 1.0);
+    final decoration = BoxDecoration(
+      color: Colors.transparent,
+      border: Border.fromBorderSide(borderSide),
+      borderRadius: const BorderRadius.all(Radius.circular(4)),
+    );
+    return Container(
+      clipBehavior: Clip.hardEdge,
+      decoration: decoration,
+      child: child,
+    );
+  }
+}

+ 21 - 68
frontend/app_flowy/lib/plugins/board/presentation/card/card_container.dart → frontend/app_flowy/lib/plugins/board/presentation/card/container/card_container.dart

@@ -1,17 +1,19 @@
-import 'package:flowy_infra/theme.dart';
-import 'package:flowy_infra_ui/style_widget/hover.dart';
 import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
 import 'package:styled_widget/styled_widget.dart';
 
+import 'accessory.dart';
+
 class BoardCardContainer extends StatelessWidget {
   final Widget child;
   final CardAccessoryBuilder? accessoryBuilder;
   final bool Function()? buildAccessoryWhen;
-  final void Function(BuildContext) onTap;
+  final void Function(BuildContext) openCard;
+  final void Function(AccessoryType) openAccessory;
   const BoardCardContainer({
     required this.child,
-    required this.onTap,
+    required this.openCard,
+    required this.openAccessory,
     this.accessoryBuilder,
     this.buildAccessoryWhen,
     Key? key,
@@ -34,13 +36,14 @@ class BoardCardContainer extends StatelessWidget {
             if (accessories.isNotEmpty) {
               container = _CardEnterRegion(
                 accessories: accessories,
+                onTapAccessory: openAccessory,
                 child: container,
               );
             }
           }
 
           return GestureDetector(
-            onTap: () => onTap(context),
+            onTap: () => openCard(context),
             child: Padding(
               padding: const EdgeInsets.all(8),
               child: ConstrainedBox(
@@ -55,69 +58,16 @@ class BoardCardContainer extends StatelessWidget {
   }
 }
 
-abstract class CardAccessory implements Widget {
-  void onTap(BuildContext context);
-}
-
-typedef CardAccessoryBuilder = List<CardAccessory> Function(
-  BuildContext buildContext,
-);
-
-class CardAccessoryContainer extends StatelessWidget {
-  final List<CardAccessory> accessories;
-  const CardAccessoryContainer({required this.accessories, Key? key})
-      : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    final theme = context.read<AppTheme>();
-    final children = accessories.map((accessory) {
-      return GestureDetector(
-        behavior: HitTestBehavior.opaque,
-        onTap: () => accessory.onTap(context),
-        child: _wrapHover(theme, accessory),
-      );
-    }).toList();
-    return _wrapDecoration(context, Row(children: children));
-  }
-
-  FlowyHover _wrapHover(AppTheme theme, CardAccessory accessory) {
-    return FlowyHover(
-      style: HoverStyle(
-        hoverColor: theme.hover,
-        backgroundColor: theme.surface,
-        borderRadius: BorderRadius.zero,
-      ),
-      builder: (_, onHover) => SizedBox(
-        width: 24,
-        height: 24,
-        child: accessory,
-      ),
-    );
-  }
-
-  Widget _wrapDecoration(BuildContext context, Widget child) {
-    final theme = context.read<AppTheme>();
-    final borderSide = BorderSide(color: theme.shader6, width: 1.0);
-    final decoration = BoxDecoration(
-      color: Colors.transparent,
-      border: Border.fromBorderSide(borderSide),
-      borderRadius: const BorderRadius.all(Radius.circular(4)),
-    );
-    return Container(
-      clipBehavior: Clip.hardEdge,
-      decoration: decoration,
-      child: child,
-    );
-  }
-}
-
 class _CardEnterRegion extends StatelessWidget {
   final Widget child;
   final List<CardAccessory> accessories;
-  const _CardEnterRegion(
-      {required this.child, required this.accessories, Key? key})
-      : super(key: key);
+  final void Function(AccessoryType) onTapAccessory;
+  const _CardEnterRegion({
+    required this.child,
+    required this.accessories,
+    required this.onTapAccessory,
+    Key? key,
+  }) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
@@ -126,9 +76,12 @@ class _CardEnterRegion extends StatelessWidget {
       builder: (context, onEnter, _) {
         List<Widget> children = [child];
         if (onEnter) {
-          children.add(CardAccessoryContainer(
-            accessories: accessories,
-          ).positioned(right: 0));
+          children.add(
+            CardAccessoryContainer(
+              accessories: accessories,
+              onTapAccessory: onTapAccessory,
+            ).positioned(right: 0),
+          );
         }
 
         return MouseRegion(

+ 1 - 1
frontend/app_flowy/lib/plugins/board/presentation/toolbar/board_toolbar.dart

@@ -62,7 +62,7 @@ class _SettingButtonState extends State<_SettingButton> {
   @override
   Widget build(BuildContext context) {
     final theme = context.read<AppTheme>();
-    return AppFlowyStylePopover(
+    return AppFlowyPopover(
       controller: popoverController,
       constraints: BoxConstraints.loose(const Size(260, 400)),
       triggerActions: PopoverTriggerActionFlags.click,

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_cell.dart

@@ -63,7 +63,7 @@ class _DateCellState extends GridCellState<GridDateCell> {
       value: _cellBloc,
       child: BlocBuilder<DateCellBloc, DateCellState>(
         builder: (context, state) {
-          return AppFlowyStylePopover(
+          return AppFlowyPopover(
             controller: _popover,
             offset: const Offset(0, 20),
             direction: PopoverDirection.bottomWithLeftAligned,

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart

@@ -299,7 +299,7 @@ class _DateTypeOptionButton extends StatelessWidget {
     return BlocSelector<DateCalBloc, DateCalState, DateTypeOptionPB>(
       selector: (state) => state.dateTypeOptionPB,
       builder: (context, dateTypeOptionPB) {
-        return AppFlowyStylePopover(
+        return AppFlowyPopover(
           triggerActions:
               PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,
           offset: const Offset(20, 0),

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_cell.dart

@@ -181,7 +181,7 @@ class _SelectOptionWrapState extends State<SelectOptionWrap> {
       SelectOptionCellEditor.editorPanelWidth,
       300,
     ));
-    return AppFlowyStylePopover(
+    return AppFlowyPopover(
       controller: _popover,
       constraints: constraints,
       direction: PopoverDirection.bottomWithLeftAligned,

+ 2 - 6
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart

@@ -148,11 +148,7 @@ class _TextField extends StatelessWidget {
             selectedOptionMap: optionMap,
             distanceToText: _editorPanelWidth * 0.7,
             tagController: _tagController,
-            onClick: () {
-              popoverMutex.close();
-              // FlowyOverlay.of(context)
-              //     .remove(SelectOptionTypeOptionEditor.identifier);
-            },
+            onClick: () => popoverMutex.close(),
             newText: (text) {
               context
                   .read<SelectOptionCellEditorBloc>()
@@ -244,7 +240,7 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
   @override
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
-    return AppFlowyStylePopover(
+    return AppFlowyPopover(
       controller: _popoverController,
       offset: const Offset(20, 0),
       constraints: BoxConstraints.loose(const Size(200, 300)),

+ 2 - 2
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/url_cell/url_cell.dart

@@ -130,7 +130,7 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
             ),
           );
 
-          return AppFlowyStylePopover(
+          return AppFlowyPopover(
             controller: _popoverController,
             constraints: BoxConstraints.loose(const Size(300, 160)),
             direction: PopoverDirection.bottomWithLeftAligned,
@@ -216,7 +216,7 @@ class _EditURLAccessoryState extends State<_EditURLAccessory>
   @override
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
-    return AppFlowyStylePopover(
+    return AppFlowyPopover(
       constraints: BoxConstraints.loose(const Size(300, 160)),
       controller: _popoverController,
       direction: PopoverDirection.bottomWithLeftAligned,

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart

@@ -30,7 +30,7 @@ class GridFieldCell extends StatelessWidget {
       },
       child: BlocBuilder<FieldCellBloc, FieldCellState>(
         builder: (context, state) {
-          final button = AppFlowyStylePopover(
+          final button = AppFlowyPopover(
             constraints: BoxConstraints.loose(const Size(240, 840)),
             direction: PopoverDirection.bottomWithLeftAligned,
             triggerActions: PopoverTriggerActionFlags.click,

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart

@@ -243,7 +243,7 @@ class _DeleteFieldButton extends StatelessWidget {
   }
 
   Widget _wrapPopover(Widget widget) {
-    return AppFlowyStylePopover(
+    return AppFlowyPopover(
       triggerActions: PopoverTriggerActionFlags.click,
       constraints: BoxConstraints.loose(const Size(400, 240)),
       mutex: popoverMutex,

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_type_option_editor.dart

@@ -64,7 +64,7 @@ class FieldTypeOptionEditor extends StatelessWidget {
     final theme = context.watch<AppTheme>();
     return SizedBox(
       height: GridSize.typeOptionItemHeight,
-      child: AppFlowyStylePopover(
+      child: AppFlowyPopover(
         constraints: BoxConstraints.loose(const Size(460, 440)),
         triggerActions:
             PopoverTriggerActionFlags.click | PopoverTriggerActionFlags.hover,

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/grid_header.dart

@@ -176,7 +176,7 @@ class CreateFieldButton extends StatelessWidget {
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
 
-    return AppFlowyStylePopover(
+    return AppFlowyPopover(
       triggerActions: PopoverTriggerActionFlags.click,
       direction: PopoverDirection.bottomWithRightAligned,
       constraints: BoxConstraints.loose(const Size(240, 200)),

+ 2 - 2
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/date.dart

@@ -62,7 +62,7 @@ class DateTypeOptionWidget extends TypeOptionWidget {
   }
 
   Widget _renderDateFormatButton(BuildContext context, DateFormat dataFormat) {
-    return AppFlowyStylePopover(
+    return AppFlowyPopover(
       mutex: popoverMutex,
       triggerActions:
           PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,
@@ -84,7 +84,7 @@ class DateTypeOptionWidget extends TypeOptionWidget {
   }
 
   Widget _renderTimeFormatButton(BuildContext context, TimeFormat timeFormat) {
-    return AppFlowyStylePopover(
+    return AppFlowyPopover(
       mutex: popoverMutex,
       triggerActions:
           PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/number.dart

@@ -55,7 +55,7 @@ class NumberTypeOptionWidget extends TypeOptionWidget {
           listener: (context, state) =>
               typeOptionContext.typeOption = state.typeOption,
           builder: (context, state) {
-            return AppFlowyStylePopover(
+            return AppFlowyPopover(
               mutex: popoverMutex,
               triggerActions: PopoverTriggerActionFlags.hover |
                   PopoverTriggerActionFlags.click,

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/select_option.dart

@@ -180,7 +180,7 @@ class _OptionCellState extends State<_OptionCell> {
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
 
-    return AppFlowyStylePopover(
+    return AppFlowyPopover(
       controller: _popoverController,
       mutex: widget.popoverMutex,
       offset: const Offset(20, 0),

+ 68 - 30
frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/grid_row.dart

@@ -1,8 +1,10 @@
 import 'package:app_flowy/plugins/grid/application/prelude.dart';
 import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
 import 'package:app_flowy/plugins/grid/application/row/row_data_controller.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.dart';
 import 'package:flowy_infra_ui/style_widget/icon_button.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
@@ -56,20 +58,21 @@ class _GridRowWidgetState extends State<GridRowWidget> {
         child: BlocBuilder<RowBloc, RowState>(
           buildWhen: (p, c) => p.rowInfo.rowPB.height != c.rowInfo.rowPB.height,
           builder: (context, state) {
-            final children = [
-              const _RowLeading(),
-              Expanded(
-                child: RowContent(
-                  builder: widget.cellBuilder,
-                  onExpand: () => widget.openDetailPage(
-                    context,
-                    widget.cellBuilder,
-                  ),
+            final content = Expanded(
+              child: RowContent(
+                builder: widget.cellBuilder,
+                onExpand: () => widget.openDetailPage(
+                  context,
+                  widget.cellBuilder,
                 ),
               ),
+            );
+
+            return Row(children: [
+              const _RowLeading(),
+              content,
               const _RowTrailing(),
-            ];
-            return Row(children: children);
+            ]);
           },
         ),
       ),
@@ -83,26 +86,51 @@ class _GridRowWidgetState extends State<GridRowWidget> {
   }
 }
 
-class _RowLeading extends StatelessWidget {
+class _RowLeading extends StatefulWidget {
   const _RowLeading({Key? key}) : super(key: key);
 
+  @override
+  State<_RowLeading> createState() => _RowLeadingState();
+}
+
+class _RowLeadingState extends State<_RowLeading> {
+  late PopoverController popoverController;
+
+  @override
+  void initState() {
+    popoverController = PopoverController();
+    super.initState();
+  }
+
   @override
   Widget build(BuildContext context) {
-    return Consumer<RegionStateNotifier>(
-      builder: (context, state, _) {
-        return SizedBox(
-            width: GridSize.leadingHeaderPadding,
-            child: state.onEnter ? _activeWidget() : null);
+    return AppFlowyPopover(
+      controller: popoverController,
+      constraints: BoxConstraints.loose(const Size(140, 200)),
+      direction: PopoverDirection.rightWithCenterAligned,
+      popupBuilder: (BuildContext popoverContext) {
+        return GridRowActionSheet(
+            rowData: context.read<RowBloc>().state.rowInfo);
       },
+      child: Consumer<RegionStateNotifier>(
+        builder: (context, state, _) {
+          return SizedBox(
+            width: GridSize.leadingHeaderPadding,
+            child: state.onEnter ? _activeWidget() : null,
+          );
+        },
+      ),
     );
   }
 
   Widget _activeWidget() {
     return Row(
       mainAxisAlignment: MainAxisAlignment.center,
-      children: const [
-        _InsertRowButton(),
-        _DeleteRowButton(),
+      children: [
+        const _InsertButton(),
+        _MenuButton(openMenu: () {
+          popoverController.show();
+        }),
       ],
     );
   }
@@ -117,8 +145,8 @@ class _RowTrailing extends StatelessWidget {
   }
 }
 
-class _InsertRowButton extends StatelessWidget {
-  const _InsertRowButton({Key? key}) : super(key: key);
+class _InsertButton extends StatelessWidget {
+  const _InsertButton({Key? key}) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
@@ -128,17 +156,29 @@ class _InsertRowButton extends StatelessWidget {
       hoverColor: theme.hover,
       width: 20,
       height: 30,
-      onPressed: () => context.read<RowBloc>().add(
-            const RowEvent.createRow(),
-          ),
+      onPressed: () => context.read<RowBloc>().add(const RowEvent.createRow()),
       iconPadding: const EdgeInsets.all(3),
       icon: svgWidget("home/add"),
     );
   }
 }
 
-class _DeleteRowButton extends StatelessWidget {
-  const _DeleteRowButton({Key? key}) : super(key: key);
+class _MenuButton extends StatefulWidget {
+  final VoidCallback openMenu;
+  const _MenuButton({
+    required this.openMenu,
+    Key? key,
+  }) : super(key: key);
+
+  @override
+  State<_MenuButton> createState() => _MenuButtonState();
+}
+
+class _MenuButtonState extends State<_MenuButton> {
+  @override
+  void initState() {
+    super.initState();
+  }
 
   @override
   Widget build(BuildContext context) {
@@ -148,9 +188,7 @@ class _DeleteRowButton extends StatelessWidget {
       hoverColor: theme.hover,
       width: 20,
       height: 30,
-      onPressed: () => GridRowActionSheet(
-        rowData: context.read<RowBloc>().state.rowInfo,
-      ).show(context),
+      onPressed: () => widget.openMenu(),
       iconPadding: const EdgeInsets.all(3),
       icon: svgWidget("editor/details"),
     );

+ 2 - 33
frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_action_sheet.dart

@@ -3,7 +3,6 @@ import 'package:easy_localization/easy_localization.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
-import 'package:flowy_infra_ui/flowy_infra_ui.dart';
 import 'package:flowy_infra_ui/style_widget/button.dart';
 import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
@@ -27,10 +26,7 @@ class GridRowActionSheet extends StatelessWidget {
           final cells = _RowAction.values
               .where((value) => value.enable())
               .map(
-                (action) => _RowActionCell(
-                  action: action,
-                  onDismissed: () => remove(context),
-                ),
+                (action) => _RowActionCell(action: action),
               )
               .toList();
 
@@ -52,37 +48,11 @@ class GridRowActionSheet extends StatelessWidget {
       ),
     );
   }
-
-  void show(
-    BuildContext overlayContext, {
-    AnchorDirection direction = AnchorDirection.leftWithCenterAligned,
-  }) {
-    FlowyOverlay.of(overlayContext).insertWithAnchor(
-      widget: OverlayContainer(
-        constraints: BoxConstraints.loose(const Size(140, 200)),
-        child: this,
-      ),
-      identifier: GridRowActionSheet.identifier(),
-      anchorContext: overlayContext,
-      anchorDirection: direction,
-    );
-  }
-
-  void remove(BuildContext overlayContext) {
-    FlowyOverlay.of(overlayContext).remove(GridRowActionSheet.identifier());
-  }
-
-  static String identifier() {
-    return (GridRowActionSheet).toString();
-  }
 }
 
 class _RowActionCell extends StatelessWidget {
   final _RowAction action;
-  final VoidCallback onDismissed;
-  const _RowActionCell(
-      {required this.action, required this.onDismissed, Key? key})
-      : super(key: key);
+  const _RowActionCell({required this.action, Key? key}) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
@@ -101,7 +71,6 @@ class _RowActionCell extends StatelessWidget {
           if (action.enable()) {
             action.performAction(context);
           }
-          onDismissed();
         },
         leftIcon: svgWidget(action.iconName(), color: theme.iconColor),
       ),

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart

@@ -194,7 +194,7 @@ class _CreateFieldButtonState extends State<_CreateFieldButton> {
   Widget build(BuildContext context) {
     final theme = context.read<AppTheme>();
 
-    return AppFlowyStylePopover(
+    return AppFlowyPopover(
       constraints: BoxConstraints.loose(const Size(240, 200)),
       controller: popoverController,
       triggerActions: PopoverTriggerActionFlags.click,

+ 0 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_group.dart

@@ -99,7 +99,6 @@ class _GridGroupCell extends StatelessWidget {
                 ),
               );
           onSelected();
-          // FlowyOverlay.of(context).remove(GridGroupList.identifier());
         },
       ),
     );

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_property.dart

@@ -116,7 +116,7 @@ class _GridPropertyCell extends StatelessWidget {
   }
 
   Widget _editFieldButton(AppTheme theme, BuildContext context) {
-    return AppFlowyStylePopover(
+    return AppFlowyPopover(
       mutex: popoverMutex,
       triggerActions: PopoverTriggerActionFlags.click,
       offset: const Offset(20, 0),

+ 0 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_setting.dart

@@ -40,7 +40,6 @@ class GridSettingList extends StatelessWidget {
             previous.selectedAction != current.selectedAction,
         listener: (context, state) {
           state.selectedAction.foldLeft(null, (_, action) {
-            FlowyOverlay.of(context).remove(identifier());
             onAction(action, settingContext);
           });
         },

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_toolbar.dart

@@ -53,7 +53,7 @@ class _SettingButton extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
-    return AppFlowyStylePopover(
+    return AppFlowyPopover(
       constraints: BoxConstraints.loose(const Size(260, 400)),
       triggerActions: PopoverTriggerActionFlags.click,
       offset: const Offset(0, 10),

+ 2 - 2
frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/appflowy_stype_popover.dart

@@ -2,7 +2,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
 import 'package:appflowy_popover/popover.dart';
 import 'package:flutter/material.dart';
 
-class AppFlowyStylePopover extends StatelessWidget {
+class AppFlowyPopover extends StatelessWidget {
   final Widget child;
   final PopoverController? controller;
   final Widget Function(BuildContext context) popupBuilder;
@@ -13,7 +13,7 @@ class AppFlowyStylePopover extends StatelessWidget {
   final PopoverMutex? mutex;
   final Offset? offset;
 
-  const AppFlowyStylePopover({
+  const AppFlowyPopover({
     Key? key,
     required this.child,
     required this.popupBuilder,