Prechádzať zdrojové kódy

feat: wrap appflowy style popover

Vincent Chan 2 rokov pred
rodič
commit
7bde75ee2f

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

@@ -1,3 +1,4 @@
+import 'package:flowy_infra_ui/flowy_infra_ui.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flutter/widgets.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
@@ -62,10 +63,11 @@ class _DateCellState extends GridCellState<GridDateCell> {
       value: _cellBloc,
       child: BlocBuilder<DateCellBloc, DateCellState>(
         builder: (context, state) {
-          return Popover(
+          return AppFlowyStylePopover(
             controller: _popover,
             offset: const Offset(0, 20),
             direction: PopoverDirection.bottomWithLeftAligned,
+            constraints: BoxConstraints.loose(const Size(320, 500)),
             child: SizedBox.expand(
               child: GestureDetector(
                 behavior: HitTestBehavior.opaque,

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

@@ -64,12 +64,9 @@ class _DateCellEditor extends State<DateCellEditor> {
       return Container();
     }
 
-    return OverlayContainer(
-      constraints: BoxConstraints.loose(const Size(320, 500)),
-      child: _CellCalendarWidget(
-        cellContext: widget.cellController,
-        dateTypeOptionPB: _dateTypeOptionPB!,
-      ),
+    return _CellCalendarWidget(
+      cellContext: widget.cellController,
+      dateTypeOptionPB: _dateTypeOptionPB!,
     );
   }
 }
@@ -302,10 +299,11 @@ class _DateTypeOptionButton extends StatelessWidget {
     return BlocSelector<DateCalBloc, DateCalState, DateTypeOptionPB>(
       selector: (state) => state.dateTypeOptionPB,
       builder: (context, dateTypeOptionPB) {
-        return Popover(
+        return AppFlowyStylePopover(
           triggerActions:
               PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,
           offset: const Offset(20, 0),
+          constraints: BoxConstraints.loose(const Size(140, 100)),
           child: FlowyButton(
             text: FlowyText.medium(title, fontSize: 12),
             hoverColor: theme.hover,
@@ -313,12 +311,9 @@ class _DateTypeOptionButton extends StatelessWidget {
             rightIcon: svgWidget("grid/more", color: theme.iconColor),
           ),
           popupBuilder: (BuildContext popContext) {
-            return OverlayContainer(
-              constraints: BoxConstraints.loose(const Size(140, 100)),
-              child: _CalDateTimeSetting(
-                dateTypeOptionPB: dateTypeOptionPB,
-                onEvent: (event) => context.read<DateCalBloc>().add(event),
-              ),
+            return _CalDateTimeSetting(
+              dateTypeOptionPB: dateTypeOptionPB,
+              onEvent: (event) => context.read<DateCalBloc>().add(event),
             );
           },
         );

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

@@ -3,7 +3,7 @@ import 'package:app_flowy/plugins/grid/application/prelude.dart';
 import 'package:appflowy_popover/popover.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:flowy_infra_ui/style_widget/text.dart';
 // ignore: unused_import
 import 'package:flowy_sdk/log.dart';
@@ -194,8 +194,10 @@ class _SelectOptionWrapState extends State<SelectOptionWrap> {
       alignment: AlignmentDirectional.center,
       fit: StackFit.expand,
       children: [
-        Popover(
+        AppFlowyStylePopover(
           controller: _popover,
+          constraints: BoxConstraints.loose(
+              Size(SelectOptionCellEditor.editorPanelWidth, 300)),
           offset: const Offset(0, 20),
           direction: PopoverDirection.bottomWithLeftAligned,
           // triggerActions: PopoverTriggerActionFlags.c,
@@ -203,18 +205,14 @@ class _SelectOptionWrapState extends State<SelectOptionWrap> {
             WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
               widget.onFocus?.call(true);
             });
-            return OverlayContainer(
-              constraints: BoxConstraints.loose(
-                  Size(SelectOptionCellEditor.editorPanelWidth, 300)),
-              child: SizedBox(
-                width: SelectOptionCellEditor.editorPanelWidth,
-                child: SelectOptionCellEditor(
-                  cellController: widget.cellControllerBuilder.build()
-                      as GridSelectOptionCellController,
-                  onDismissed: () {
-                    widget.onFocus?.call(false);
-                  },
-                ),
+            return SizedBox(
+              width: SelectOptionCellEditor.editorPanelWidth,
+              child: SelectOptionCellEditor(
+                cellController: widget.cellControllerBuilder.build()
+                    as GridSelectOptionCellController,
+                onDismissed: () {
+                  widget.onFocus?.call(false);
+                },
               ),
             );
           },

+ 16 - 18
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart

@@ -251,9 +251,10 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
   @override
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
-    return Popover(
+    return AppFlowyStylePopover(
       controller: _popoverController,
       offset: const Offset(20, 0),
+      constraints: BoxConstraints.loose(const Size(200, 300)),
       child: SizedBox(
         height: GridSize.typeOptionItemHeight,
         child: Row(
@@ -286,23 +287,20 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
         ),
       ),
       popupBuilder: (BuildContext popoverContext) {
-        return OverlayContainer(
-          constraints: BoxConstraints.loose(const Size(200, 300)),
-          child: SelectOptionTypeOptionEditor(
-            option: widget.option,
-            onDeleted: () {
-              context
-                  .read<SelectOptionCellEditorBloc>()
-                  .add(SelectOptionEditorEvent.deleteOption(widget.option));
-            },
-            onUpdated: (updatedOption) {
-              context
-                  .read<SelectOptionCellEditorBloc>()
-                  .add(SelectOptionEditorEvent.updateOption(updatedOption));
-            },
-            key: ValueKey(widget.option
-                .id), // Use ValueKey to refresh the UI, otherwise, it will remain the old value.
-          ),
+        return SelectOptionTypeOptionEditor(
+          option: widget.option,
+          onDeleted: () {
+            context
+                .read<SelectOptionCellEditorBloc>()
+                .add(SelectOptionEditorEvent.deleteOption(widget.option));
+          },
+          onUpdated: (updatedOption) {
+            context
+                .read<SelectOptionCellEditorBloc>()
+                .add(SelectOptionEditorEvent.updateOption(updatedOption));
+          },
+          key: ValueKey(widget.option
+              .id), // Use ValueKey to refresh the UI, otherwise, it will remain the old value.
         );
       },
     );

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

@@ -64,19 +64,16 @@ class FieldTypeOptionEditor extends StatelessWidget {
     final theme = context.watch<AppTheme>();
     return SizedBox(
       height: GridSize.typeOptionItemHeight,
-      child: Popover(
+      child: AppFlowyStylePopover(
+        constraints: BoxConstraints.loose(const Size(460, 440)),
         triggerActions:
             PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,
         mutex: popoverMutex,
         offset: const Offset(20, 0),
         popupBuilder: (context) {
-          final list = FieldTypeList(onSelectField: (newFieldType) {
+          return FieldTypeList(onSelectField: (newFieldType) {
             dataController.switchToField(newFieldType);
           });
-          return OverlayContainer(
-            constraints: BoxConstraints.loose(const Size(460, 440)),
-            child: list,
-          );
         },
         child: FlowyButton(
           text: FlowyText.medium(field.fieldType.title(), fontSize: 12),

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

@@ -7,6 +7,7 @@ import 'package:easy_localization/easy_localization.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/flowy_infra_ui_web.dart';
 import 'package:flowy_infra_ui/style_widget/button.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
@@ -176,9 +177,10 @@ class CreateFieldButton extends StatelessWidget {
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
 
-    return Popover(
+    return AppFlowyStylePopover(
       triggerActions: PopoverTriggerActionFlags.click,
       direction: PopoverDirection.bottomWithRightAligned,
+      constraints: BoxConstraints.loose(const Size(240, 200)),
       child: FlowyButton(
         text: FlowyText.medium(
           LocaleKeys.grid_field_newColumn.tr(),
@@ -189,13 +191,10 @@ class CreateFieldButton extends StatelessWidget {
         leftIcon: svgWidget("home/add"),
       ),
       popupBuilder: (BuildContext popover) {
-        return OverlayContainer(
-          constraints: BoxConstraints.loose(const Size(240, 200)),
-          child: FieldEditor(
-            gridId: gridId,
-            fieldName: "",
-            typeOptionLoader: NewFieldTypeOptionLoader(gridId: gridId),
-          ),
+        return FieldEditor(
+          gridId: gridId,
+          fieldName: "",
+          typeOptionLoader: NewFieldTypeOptionLoader(gridId: gridId),
         );
       },
     );

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

@@ -62,23 +62,21 @@ class DateTypeOptionWidget extends TypeOptionWidget {
   }
 
   Widget _renderDateFormatButton(BuildContext context, DateFormat dataFormat) {
-    return Popover(
+    return AppFlowyStylePopover(
       mutex: popoverMutex,
       triggerActions:
           PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,
       offset: const Offset(20, 0),
+      constraints: BoxConstraints.loose(const Size(460, 440)),
       popupBuilder: (popoverContext) {
-        return OverlayContainer(
-          constraints: BoxConstraints.loose(const Size(460, 440)),
-          child: DateFormatList(
-            selectedFormat: dataFormat,
-            onSelected: (format) {
-              context
-                  .read<DateTypeOptionBloc>()
-                  .add(DateTypeOptionEvent.didSelectDateFormat(format));
-              PopoverContainer.of(popoverContext).closeAll();
-            },
-          ),
+        return DateFormatList(
+          selectedFormat: dataFormat,
+          onSelected: (format) {
+            context
+                .read<DateTypeOptionBloc>()
+                .add(DateTypeOptionEvent.didSelectDateFormat(format));
+            PopoverContainer.of(popoverContext).closeAll();
+          },
         );
       },
       child: const DateFormatButton(),
@@ -86,22 +84,21 @@ class DateTypeOptionWidget extends TypeOptionWidget {
   }
 
   Widget _renderTimeFormatButton(BuildContext context, TimeFormat timeFormat) {
-    return Popover(
+    return AppFlowyStylePopover(
       mutex: popoverMutex,
       triggerActions:
           PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,
       offset: const Offset(20, 0),
+      constraints: BoxConstraints.loose(const Size(460, 440)),
       popupBuilder: (BuildContext popoverContext) {
-        return OverlayContainer(
-          constraints: BoxConstraints.loose(const Size(460, 440)),
-          child: TimeFormatList(
-              selectedFormat: timeFormat,
-              onSelected: (format) {
-                context
-                    .read<DateTypeOptionBloc>()
-                    .add(DateTypeOptionEvent.didSelectTimeFormat(format));
-                PopoverContainer.of(popoverContext).closeAll();
-              }),
+        return TimeFormatList(
+          selectedFormat: timeFormat,
+          onSelected: (format) {
+            context
+                .read<DateTypeOptionBloc>()
+                .add(DateTypeOptionEvent.didSelectTimeFormat(format));
+            PopoverContainer.of(popoverContext).closeAll();
+          },
         );
       },
       child: TimeFormatButton(timeFormat: timeFormat),

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

@@ -55,11 +55,12 @@ class NumberTypeOptionWidget extends TypeOptionWidget {
           listener: (context, state) =>
               typeOptionContext.typeOption = state.typeOption,
           builder: (context, state) {
-            return Popover(
+            return AppFlowyStylePopover(
               mutex: popoverMutex,
               triggerActions: PopoverTriggerActionFlags.hover |
                   PopoverTriggerActionFlags.click,
               offset: const Offset(20, 0),
+              constraints: BoxConstraints.loose(const Size(460, 440)),
               child: FlowyButton(
                 margin: GridSize.typeOptionContentInsets,
                 hoverColor: theme.hover,
@@ -76,17 +77,14 @@ class NumberTypeOptionWidget extends TypeOptionWidget {
                 ),
               ),
               popupBuilder: (BuildContext popoverContext) {
-                return OverlayContainer(
-                  constraints: BoxConstraints.loose(const Size(460, 440)),
-                  child: NumberFormatList(
-                    onSelected: (format) {
-                      context
-                          .read<NumberTypeOptionBloc>()
-                          .add(NumberTypeOptionEvent.didSelectFormat(format));
-                      PopoverContainer.of(popoverContext).closeAll();
-                    },
-                    selectedFormat: state.typeOption.format,
-                  ),
+                return NumberFormatList(
+                  onSelected: (format) {
+                    context
+                        .read<NumberTypeOptionBloc>()
+                        .add(NumberTypeOptionEvent.didSelectFormat(format));
+                    PopoverContainer.of(popoverContext).closeAll();
+                  },
+                  selectedFormat: state.typeOption.format,
                 );
               },
             );

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

@@ -2,6 +2,7 @@ import 'package:app_flowy/plugins/grid/application/field/type_option/select_opti
 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/flowy_infra_ui_web.dart';
 import 'package:flowy_infra_ui/style_widget/button.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
@@ -180,10 +181,11 @@ class _OptionCellState extends State<_OptionCell> {
   Widget build(BuildContext context) {
     final theme = context.watch<AppTheme>();
 
-    return Popover(
+    return AppFlowyStylePopover(
       controller: _popoverController,
       mutex: widget.popoverMutex,
       offset: const Offset(20, 0),
+      constraints: BoxConstraints.loose(const Size(460, 440)),
       child: SizedBox(
         height: GridSize.typeOptionItemHeight,
         child: SelectOptionTagCell(
@@ -200,24 +202,21 @@ class _OptionCellState extends State<_OptionCell> {
         ),
       ),
       popupBuilder: (BuildContext popoverContext) {
-        return OverlayContainer(
-          constraints: BoxConstraints.loose(const Size(460, 440)),
-          child: SelectOptionTypeOptionEditor(
-            option: widget.option,
-            onDeleted: () {
-              context
-                  .read<SelectOptionTypeOptionBloc>()
-                  .add(SelectOptionTypeOptionEvent.deleteOption(widget.option));
-              PopoverContainer.of(popoverContext).closeAll();
-            },
-            onUpdated: (updatedOption) {
-              context
-                  .read<SelectOptionTypeOptionBloc>()
-                  .add(SelectOptionTypeOptionEvent.updateOption(updatedOption));
-              PopoverContainer.of(popoverContext).closeAll();
-            },
-            key: ValueKey(widget.option.id),
-          ),
+        return SelectOptionTypeOptionEditor(
+          option: widget.option,
+          onDeleted: () {
+            context
+                .read<SelectOptionTypeOptionBloc>()
+                .add(SelectOptionTypeOptionEvent.deleteOption(widget.option));
+            PopoverContainer.of(popoverContext).closeAll();
+          },
+          onUpdated: (updatedOption) {
+            context
+                .read<SelectOptionTypeOptionBloc>()
+                .add(SelectOptionTypeOptionEvent.updateOption(updatedOption));
+            PopoverContainer.of(popoverContext).closeAll();
+          },
+          key: ValueKey(widget.option.id),
         );
       },
     );

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

@@ -116,10 +116,11 @@ class _GridPropertyCell extends StatelessWidget {
   }
 
   Widget _editFieldButton(AppTheme theme, BuildContext context) {
-    return Popover(
+    return AppFlowyStylePopover(
       mutex: popoverMutex,
       triggerActions: PopoverTriggerActionFlags.click,
       offset: const Offset(20, 0),
+      constraints: BoxConstraints.loose(const Size(240, 200)),
       child: FlowyButton(
         text: FlowyText.medium(fieldContext.name, fontSize: 12),
         hoverColor: theme.hover,
@@ -127,14 +128,11 @@ class _GridPropertyCell extends StatelessWidget {
             color: theme.iconColor),
       ),
       popupBuilder: (BuildContext context) {
-        return OverlayContainer(
-          constraints: BoxConstraints.loose(const Size(240, 200)),
-          child: FieldEditor(
-            gridId: gridId,
-            fieldName: fieldContext.name,
-            typeOptionLoader: FieldTypeOptionLoader(
-                gridId: gridId, field: fieldContext.field),
-          ),
+        return FieldEditor(
+          gridId: gridId,
+          fieldName: fieldContext.name,
+          typeOptionLoader:
+              FieldTypeOptionLoader(gridId: gridId, field: fieldContext.field),
         );
       },
     );

+ 1 - 1
frontend/app_flowy/packages/flowy_infra_ui/lib/flowy_infra_ui.dart

@@ -9,4 +9,4 @@ export 'src/flowy_overlay/flowy_overlay.dart';
 export 'src/flowy_overlay/list_overlay.dart';
 export 'src/flowy_overlay/option_overlay.dart';
 export 'src/flowy_overlay/flowy_dialog.dart';
-export 'src/flowy_overlay/flowy_popover.dart';
+export 'src/flowy_overlay/appflowy_stype_popover.dart';

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

@@ -0,0 +1,46 @@
+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 {
+  final Widget child;
+  final PopoverController? controller;
+  final Widget Function(BuildContext context) popupBuilder;
+  final PopoverDirection direction;
+  final int triggerActions;
+  final BoxConstraints? constraints;
+  final void Function()? onClose;
+  final PopoverMutex? mutex;
+  final Offset? offset;
+
+  const AppFlowyStylePopover({
+    Key? key,
+    required this.child,
+    required this.popupBuilder,
+    this.direction = PopoverDirection.rightWithTopAligned,
+    this.onClose,
+    this.constraints,
+    this.mutex,
+    this.triggerActions = 0,
+    this.offset,
+    this.controller,
+  }) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Popover(
+      controller: controller,
+      onClose: onClose,
+      direction: direction,
+      mutex: mutex,
+      triggerActions: triggerActions,
+      popupBuilder: (context) {
+        return OverlayContainer(
+          constraints: constraints,
+          child: popupBuilder(context),
+        );
+      },
+      child: child,
+    );
+  }
+}

+ 0 - 59
frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_popover.dart

@@ -1,59 +0,0 @@
-import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
-import 'package:flowy_infra_ui/style_widget/decoration.dart';
-import 'package:flowy_infra/theme.dart';
-import 'package:provider/provider.dart';
-import 'package:flutter/material.dart';
-import './flowy_popover_layout.dart';
-
-const _overlayContainerPadding = EdgeInsets.all(12);
-
-class FlowyPopover extends StatefulWidget {
-  final Widget Function(BuildContext context) builder;
-  final ShapeBorder? shape;
-  final Rect anchorRect;
-  final AnchorDirection? anchorDirection;
-  final EdgeInsets padding;
-  final BoxConstraints? constraints;
-
-  const FlowyPopover({
-    Key? key,
-    required this.builder,
-    required this.anchorRect,
-    this.shape,
-    this.padding = _overlayContainerPadding,
-    this.anchorDirection,
-    this.constraints,
-  }) : super(key: key);
-
-  @override
-  State<FlowyPopover> createState() => _FlowyPopoverState();
-}
-
-class _FlowyPopoverState extends State<FlowyPopover> {
-  final preRenderKey = GlobalKey();
-  Size? size;
-
-  @override
-  Widget build(BuildContext context) {
-    final theme =
-        context.watch<AppTheme?>() ?? AppTheme.fromType(ThemeType.light);
-    return Material(
-        type: MaterialType.transparency,
-        child: CustomSingleChildLayout(
-            delegate: PopoverLayoutDelegate(
-              anchorRect: widget.anchorRect,
-              anchorDirection:
-                  widget.anchorDirection ?? AnchorDirection.rightWithTopAligned,
-              overlapBehaviour: OverlapBehaviour.stretch,
-            ),
-            child: Container(
-              padding: widget.padding,
-              constraints: widget.constraints ??
-                  BoxConstraints.loose(const Size(280, 400)),
-              decoration: FlowyDecoration.decoration(
-                  theme.surface, theme.shadowColor.withOpacity(0.15)),
-              key: preRenderKey,
-              child: widget.builder(context),
-            )));
-  }
-}