diff --git a/frontend/app_flowy/lib/plugins/board/presentation/toolbar/board_setting.dart b/frontend/app_flowy/lib/plugins/board/presentation/toolbar/board_setting.dart index 6bf06c39b9..a64df31cc4 100644 --- a/frontend/app_flowy/lib/plugins/board/presentation/toolbar/board_setting.dart +++ b/frontend/app_flowy/lib/plugins/board/presentation/toolbar/board_setting.dart @@ -2,11 +2,12 @@ import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:app_flowy/plugins/board/application/toolbar/board_setting_bloc.dart'; import 'package:app_flowy/plugins/grid/application/field/field_controller.dart'; import 'package:app_flowy/plugins/grid/presentation/layout/sizes.dart'; +import 'package:app_flowy/plugins/grid/presentation/widgets/toolbar/grid_group.dart'; import 'package:app_flowy/plugins/grid/presentation/widgets/toolbar/grid_property.dart'; +import 'package:appflowy_popover/popover.dart'; import 'package:easy_localization/easy_localization.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'; @@ -141,10 +142,12 @@ extension _GridSettingExtension on BoardSettingAction { } class BoardSettingListPopover extends StatefulWidget { + final PopoverController popoverController; final BoardSettingContext settingContext; const BoardSettingListPopover({ Key? key, + required this.popoverController, required this.settingContext, }) : super(key: key); @@ -153,36 +156,33 @@ class BoardSettingListPopover extends StatefulWidget { } class _BoardSettingListPopoverState extends State { - bool _showGridPropertyList = false; + BoardSettingAction? _action; @override Widget build(BuildContext context) { - if (_showGridPropertyList) { - return OverlayContainer( - constraints: BoxConstraints.loose(const Size(260, 400)), - child: GridPropertyList( - gridId: widget.settingContext.viewId, - fieldController: widget.settingContext.fieldController, - ), - ); + if (_action != null) { + switch (_action!) { + case BoardSettingAction.groups: + return GridGroupList( + viewId: widget.settingContext.viewId, + fieldController: widget.settingContext.fieldController, + onDismissed: () { + widget.popoverController.close(); + }, + ); + case BoardSettingAction.properties: + return GridPropertyList( + gridId: widget.settingContext.viewId, + fieldController: widget.settingContext.fieldController, + ); + } } - return OverlayContainer( - constraints: BoxConstraints.loose(const Size(140, 400)), - child: BoardSettingList( - settingContext: widget.settingContext, - onAction: (action, settingContext) { - switch (action) { - case BoardSettingAction.groups: - break; - case BoardSettingAction.properties: - setState(() { - _showGridPropertyList = true; - }); - break; - } - }, - ), + return BoardSettingList( + settingContext: widget.settingContext, + onAction: (action, settingContext) { + setState(() => _action = action); + }, ); } } diff --git a/frontend/app_flowy/lib/plugins/board/presentation/toolbar/board_toolbar.dart b/frontend/app_flowy/lib/plugins/board/presentation/toolbar/board_toolbar.dart index f8cc0d30ca..27a59c69a6 100644 --- a/frontend/app_flowy/lib/plugins/board/presentation/toolbar/board_toolbar.dart +++ b/frontend/app_flowy/lib/plugins/board/presentation/toolbar/board_toolbar.dart @@ -2,6 +2,7 @@ import 'package:app_flowy/plugins/grid/application/field/field_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/widgets.dart'; import 'package:provider/provider.dart'; @@ -40,15 +41,30 @@ class BoardToolbar extends StatelessWidget { } } -class _SettingButton extends StatelessWidget { +class _SettingButton extends StatefulWidget { final BoardSettingContext settingContext; const _SettingButton({required this.settingContext, Key? key}) : super(key: key); + @override + State<_SettingButton> createState() => _SettingButtonState(); +} + +class _SettingButtonState extends State<_SettingButton> { + late PopoverController popoverController; + + @override + void initState() { + popoverController = PopoverController(); + super.initState(); + } + @override Widget build(BuildContext context) { final theme = context.read(); - return Popover( + return AppFlowyStylePopover( + controller: popoverController, + constraints: BoxConstraints.loose(const Size(260, 400)), triggerActions: PopoverTriggerActionFlags.click, child: FlowyIconButton( hoverColor: theme.hover, @@ -61,7 +77,8 @@ class _SettingButton extends StatelessWidget { ), popupBuilder: (BuildContext popoverContext) { return BoardSettingListPopover( - settingContext: settingContext, + settingContext: widget.settingContext, + popoverController: popoverController, ); }, ); diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_cell.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_cell.dart index 2a5c79b2f0..7b289d4a21 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_cell.dart +++ b/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 { value: _cellBloc, child: BlocBuilder( 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, diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart index 9c57e7ed3b..1fe45f60c8 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart @@ -64,12 +64,9 @@ class _DateCellEditor extends State { 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( 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().add(event), - ), + return _CalDateTimeSetting( + dateTypeOptionPB: dateTypeOptionPB, + onEvent: (event) => context.read().add(event), ); }, ); diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_cell.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_cell.dart index df7ddb0d9e..2e65226289 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_cell.dart +++ b/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 { 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 { 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); + }, ), ); }, diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart index 897b6f81c3..1c0cad85b1 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart +++ b/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(); - 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() - .add(SelectOptionEditorEvent.deleteOption(widget.option)); - }, - onUpdated: (updatedOption) { - context - .read() - .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() + .add(SelectOptionEditorEvent.deleteOption(widget.option)); + }, + onUpdated: (updatedOption) { + context + .read() + .add(SelectOptionEditorEvent.updateOption(updatedOption)); + }, + key: ValueKey(widget.option + .id), // Use ValueKey to refresh the UI, otherwise, it will remain the old value. ); }, ); diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/url_cell/cell_editor.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/url_cell/cell_editor.dart index e390104187..17a899f3a1 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/url_cell/cell_editor.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/url_cell/cell_editor.dart @@ -1,6 +1,5 @@ import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart'; import 'package:app_flowy/plugins/grid/application/cell/url_cell_editor_bloc.dart'; -import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'dart:async'; @@ -79,15 +78,12 @@ class URLEditorPopover extends StatelessWidget { @override Widget build(BuildContext context) { - return OverlayContainer( - constraints: BoxConstraints.loose(const Size(300, 160)), - child: SizedBox( - width: 200, - child: Padding( - padding: const EdgeInsets.all(6), - child: URLCellEditor( - cellController: cellController, - ), + return SizedBox( + width: 200, + child: Padding( + padding: const EdgeInsets.all(6), + child: URLCellEditor( + cellController: cellController, ), ), ); diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/url_cell/url_cell.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/url_cell/url_cell.dart index 27e7d4433c..155a75cae3 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/url_cell/url_cell.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/url_cell/url_cell.dart @@ -6,6 +6,7 @@ import 'package:appflowy_popover/popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -129,8 +130,9 @@ class _GridURLCellState extends GridCellState { ), ); - return Popover( + return AppFlowyStylePopover( controller: _popoverController, + constraints: BoxConstraints.loose(const Size(300, 160)), direction: PopoverDirection.bottomWithLeftAligned, offset: const Offset(0, 20), child: SizedBox.expand( @@ -214,7 +216,8 @@ class _EditURLAccessoryState extends State<_EditURLAccessory> @override Widget build(BuildContext context) { final theme = context.watch(); - return Popover( + return AppFlowyStylePopover( + constraints: BoxConstraints.loose(const Size(300, 160)), controller: _popoverController, direction: PopoverDirection.bottomWithLeftAligned, triggerActions: PopoverTriggerActionFlags.click, 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 6a3c2d8d5c..cc836809b8 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 @@ -163,22 +163,20 @@ class _DeleteFieldButton extends StatelessWidget { } Widget _wrapPopover(Widget widget) { - return Popover( + return AppFlowyStylePopover( triggerActions: PopoverTriggerActionFlags.click, + constraints: BoxConstraints.loose(const Size(400, 240)), mutex: popoverMutex, direction: PopoverDirection.center, popupBuilder: (popupContext) { - return OverlayContainer( - constraints: BoxConstraints.loose(const Size(400, 240)), - child: PopoverAlertView( - title: LocaleKeys.grid_field_deleteFieldPromptMessage.tr(), - cancel: () => popoverMutex.state?.close(), - confirm: () { - onDeleted?.call(); - popoverMutex.state?.close(); - }, - popoverMutex: popoverMutex, - ), + return PopoverAlertView( + title: LocaleKeys.grid_field_deleteFieldPromptMessage.tr(), + cancel: () => popoverMutex.state?.close(), + confirm: () { + onDeleted?.call(); + popoverMutex.state?.close(); + }, + popoverMutex: popoverMutex, ); }, child: widget, diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_type_list.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_type_list.dart index de9b3a809f..0cb18d411b 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_type_list.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_type_list.dart @@ -1,3 +1,4 @@ +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'; @@ -25,7 +26,7 @@ class FieldTypeList extends StatelessWidget with FlowyOverlayDelegate { fieldType: fieldType, onSelectField: (fieldType) { onSelectField(fieldType); - FlowyOverlay.of(context).remove(FieldTypeList.identifier()); + PopoverContainer.of(context).closeAll(); }, ); }).toList(); 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 b8da4f3b71..f541335844 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 @@ -64,18 +64,15 @@ class FieldTypeOptionEditor extends StatelessWidget { final theme = context.watch(); return SizedBox( height: GridSize.typeOptionItemHeight, - child: Popover( + child: AppFlowyStylePopover( + constraints: BoxConstraints.loose(const Size(460, 440)), triggerActions: 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), diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/grid_header.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/grid_header.dart index 154919d019..f9656e8dcc 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/grid_header.dart @@ -7,7 +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_web.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/text.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; @@ -176,9 +176,10 @@ class CreateFieldButton extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch(); - 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(), @@ -192,13 +193,10 @@ class CreateFieldButton extends StatelessWidget { ), ), 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), ); }, ); diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/date.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/date.dart index ae3dcf8682..e8cbb00fba 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/date.dart +++ b/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() - .add(DateTypeOptionEvent.didSelectDateFormat(format)); - PopoverContainerState.of(popoverContext).closeAll(); - }, - ), + return DateFormatList( + selectedFormat: dataFormat, + onSelected: (format) { + context + .read() + .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() - .add(DateTypeOptionEvent.didSelectTimeFormat(format)); - PopoverContainerState.of(popoverContext).closeAll(); - }), + return TimeFormatList( + selectedFormat: timeFormat, + onSelected: (format) { + context + .read() + .add(DateTypeOptionEvent.didSelectTimeFormat(format)); + PopoverContainer.of(popoverContext).closeAll(); + }, ); }, child: TimeFormatButton(timeFormat: timeFormat), diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/multi_select.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/multi_select.dart index 75ac6eeaa0..2dc804111d 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/multi_select.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/multi_select.dart @@ -41,7 +41,7 @@ class MultiSelectTypeOptionWidget extends TypeOptionWidget { return SelectOptionTypeOptionWidget( options: selectOptionAction.typeOption.options, beginEdit: () { - PopoverContainerState.of(context).closeAll(); + PopoverContainer.of(context).closeAll(); }, popoverMutex: popoverMutex, typeOptionAction: selectOptionAction, diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/number.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/number.dart index f2de4b6337..80627d062d 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/number.dart +++ b/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() - .add(NumberTypeOptionEvent.didSelectFormat(format)); - PopoverContainerState.of(popoverContext).closeAll(); - }, - selectedFormat: state.typeOption.format, - ), + return NumberFormatList( + onSelected: (format) { + context + .read() + .add(NumberTypeOptionEvent.didSelectFormat(format)); + PopoverContainer.of(popoverContext).closeAll(); + }, + selectedFormat: state.typeOption.format, ); }, ); diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/select_option.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/select_option.dart index 7b0be75515..f8cf09d076 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/select_option.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/select_option.dart @@ -2,7 +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_web.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/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; @@ -180,10 +180,11 @@ class _OptionCellState extends State<_OptionCell> { Widget build(BuildContext context) { final theme = context.watch(); - 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 +201,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() - .add(SelectOptionTypeOptionEvent.deleteOption(widget.option)); - PopoverContainerState.of(popoverContext).closeAll(); - }, - onUpdated: (updatedOption) { - context - .read() - .add(SelectOptionTypeOptionEvent.updateOption(updatedOption)); - PopoverContainerState.of(popoverContext).closeAll(); - }, - key: ValueKey(widget.option.id), - ), + return SelectOptionTypeOptionEditor( + option: widget.option, + onDeleted: () { + context + .read() + .add(SelectOptionTypeOptionEvent.deleteOption(widget.option)); + PopoverContainer.of(popoverContext).closeAll(); + }, + onUpdated: (updatedOption) { + context + .read() + .add(SelectOptionTypeOptionEvent.updateOption(updatedOption)); + PopoverContainer.of(popoverContext).closeAll(); + }, + key: ValueKey(widget.option.id), ); }, ); diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/single_select.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/single_select.dart index 27ffabb286..477e573ff2 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/single_select.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/single_select.dart @@ -40,7 +40,7 @@ class SingleSelectTypeOptionWidget extends TypeOptionWidget { return SelectOptionTypeOptionWidget( options: selectOptionAction.typeOption.options, beginEdit: () { - PopoverContainerState.of(context).closeAll(); + PopoverContainer.of(context).closeAll(); }, popoverMutex: popoverMutex, typeOptionAction: selectOptionAction, diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart index 9620f7aa33..a1d65f89ae 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart @@ -146,18 +146,15 @@ class _PropertyList extends StatelessWidget { }); }, onOpened: (controller) { - return OverlayContainer( - constraints: BoxConstraints.loose(const Size(240, 200)), - child: FieldEditor( - gridId: viewId, - typeOptionLoader: NewFieldTypeOptionLoader(gridId: viewId), - onDeleted: (fieldId) { - controller.close(); - context - .read() - .add(RowDetailEvent.deleteField(fieldId)); - }, - ), + return FieldEditor( + gridId: viewId, + typeOptionLoader: NewFieldTypeOptionLoader(gridId: viewId), + onDeleted: (fieldId) { + controller.close(); + context + .read() + .add(RowDetailEvent.deleteField(fieldId)); + }, ); }, ), @@ -168,28 +165,41 @@ class _PropertyList extends StatelessWidget { } } -class _CreateFieldButton extends StatelessWidget { +class _CreateFieldButton extends StatefulWidget { final String viewId; final Widget Function(PopoverController) onOpened; final VoidCallback onClosed; - final PopoverController popoverController = PopoverController(); - _CreateFieldButton({ + const _CreateFieldButton({ required this.viewId, required this.onOpened, required this.onClosed, Key? key, }) : super(key: key); + @override + State<_CreateFieldButton> createState() => _CreateFieldButtonState(); +} + +class _CreateFieldButtonState extends State<_CreateFieldButton> { + late PopoverController popoverController; + + @override + void initState() { + popoverController = PopoverController(); + super.initState(); + } + @override Widget build(BuildContext context) { final theme = context.read(); - return Popover( + return AppFlowyStylePopover( + constraints: BoxConstraints.loose(const Size(240, 200)), controller: popoverController, triggerActions: PopoverTriggerActionFlags.click, direction: PopoverDirection.topWithLeftAligned, - onClose: onClosed, + onClose: widget.onClosed, child: Container( height: 40, decoration: _makeBoxDecoration(context), @@ -203,7 +213,8 @@ class _CreateFieldButton extends StatelessWidget { leftIcon: svgWidget("home/add"), ), ), - popupBuilder: (BuildContext context) => onOpened(popoverController), + popupBuilder: (BuildContext context) => + widget.onOpened(popoverController), ); } diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_group.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_group.dart index b400cda0fe..8709cd3ea3 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_group.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_group.dart @@ -3,7 +3,6 @@ import 'package:app_flowy/plugins/grid/presentation/layout/sizes.dart'; import 'package:app_flowy/plugins/grid/presentation/widgets/header/field_type_extension.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/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; @@ -15,9 +14,11 @@ import 'package:flutter_bloc/flutter_bloc.dart'; class GridGroupList extends StatelessWidget { final String viewId; final GridFieldController fieldController; + final VoidCallback onDismissed; const GridGroupList({ required this.viewId, required this.fieldController, + required this.onDismissed, Key? key, }) : super(key: key); @@ -33,6 +34,7 @@ class GridGroupList extends StatelessWidget { final cells = state.fieldContexts.map((fieldContext) { Widget cell = _GridGroupCell( fieldContext: fieldContext, + onSelected: () => onDismissed(), key: ValueKey(fieldContext.id), ); @@ -56,29 +58,16 @@ class GridGroupList extends StatelessWidget { ), ); } - - void show(BuildContext context) { - FlowyOverlay.of(context).insertWithAnchor( - widget: OverlayContainer( - constraints: BoxConstraints.loose(const Size(260, 400)), - child: this, - ), - identifier: identifier(), - anchorContext: context, - anchorDirection: AnchorDirection.bottomRight, - style: FlowyOverlayStyle(blur: false), - ); - } - - static String identifier() { - return (GridGroupList).toString(); - } } class _GridGroupCell extends StatelessWidget { + final VoidCallback onSelected; final GridFieldContext fieldContext; - const _GridGroupCell({required this.fieldContext, Key? key}) - : super(key: key); + const _GridGroupCell({ + required this.fieldContext, + required this.onSelected, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -97,8 +86,10 @@ class _GridGroupCell extends StatelessWidget { child: FlowyButton( text: FlowyText.medium(fieldContext.name, fontSize: 12), hoverColor: theme.hover, - leftIcon: svgWidget(fieldContext.fieldType.iconName(), - color: theme.iconColor), + leftIcon: svgWidget( + fieldContext.fieldType.iconName(), + color: theme.iconColor, + ), rightIcon: rightIcon, onTap: () { context.read().add( @@ -107,7 +98,8 @@ class _GridGroupCell extends StatelessWidget { fieldContext.fieldType, ), ); - FlowyOverlay.of(context).remove(GridGroupList.identifier()); + onSelected(); + // FlowyOverlay.of(context).remove(GridGroupList.identifier()); }, ), ); diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_property.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_property.dart index 5e38efd9cb..724ec74cc1 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_property.dart +++ b/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), ); }, ); diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_toolbar.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_toolbar.dart index f5893c892f..7675eda943 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_toolbar.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_toolbar.dart @@ -53,7 +53,8 @@ class _SettingButton extends StatelessWidget { @override Widget build(BuildContext context) { final theme = context.watch(); - return Popover( + return AppFlowyStylePopover( + constraints: BoxConstraints.loose(const Size(260, 400)), triggerActions: PopoverTriggerActionFlags.click, offset: const Offset(0, 10), child: FlowyIconButton( @@ -87,25 +88,19 @@ class _GridSettingListPopoverState extends State<_GridSettingListPopover> { @override Widget build(BuildContext context) { if (_action == GridSettingAction.properties) { - return OverlayContainer( - constraints: BoxConstraints.loose(const Size(260, 400)), - child: GridPropertyList( - gridId: widget.settingContext.gridId, - fieldController: widget.settingContext.fieldController, - ), + return GridPropertyList( + gridId: widget.settingContext.gridId, + fieldController: widget.settingContext.fieldController, ); } - return OverlayContainer( - constraints: BoxConstraints.loose(const Size(140, 400)), - child: GridSettingList( - settingContext: widget.settingContext, - onAction: (action, settingContext) { - setState(() { - _action = action; - }); - }, - ), + return GridSettingList( + settingContext: widget.settingContext, + onAction: (action, settingContext) { + setState(() { + _action = action; + }); + }, ); } } diff --git a/frontend/app_flowy/packages/appflowy_popover/lib/popover.dart b/frontend/app_flowy/packages/appflowy_popover/lib/popover.dart index 8b5bb101fa..6f9f4e9f33 100644 --- a/frontend/app_flowy/packages/appflowy_popover/lib/popover.dart +++ b/frontend/app_flowy/packages/appflowy_popover/lib/popover.dart @@ -284,6 +284,15 @@ class PopoverContainer extends StatefulWidget { @override State createState() => PopoverContainerState(); + + static PopoverContainerState of(BuildContext context) { + if (context is StatefulElement && context.state is PopoverContainerState) { + return context.state as PopoverContainerState; + } + final PopoverContainerState? result = + context.findAncestorStateOfType(); + return result!; + } } class PopoverContainerState extends State { @@ -302,13 +311,4 @@ class PopoverContainerState extends State { close() => widget.onClose(); closeAll() => widget.onCloseAll(); - - static PopoverContainerState of(BuildContext context) { - if (context is StatefulElement && context.state is PopoverContainerState) { - return context.state as PopoverContainerState; - } - final PopoverContainerState? result = - context.findAncestorStateOfType(); - return result!; - } } diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/flowy_infra_ui.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/flowy_infra_ui.dart index a656077eb5..adc7dd1f9b 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/flowy_infra_ui.dart +++ b/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'; diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/appflowy_stype_popover.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/appflowy_stype_popover.dart new file mode 100644 index 0000000000..663a8c0646 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/appflowy_stype_popover.dart @@ -0,0 +1,48 @@ +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) { + final child = popupBuilder(context); + debugPrint('$child popover'); + return OverlayContainer( + constraints: constraints, + child: popupBuilder(context), + ); + }, + child: child, + ); + } +} diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_popover.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_popover.dart deleted file mode 100644 index d1a52e50d9..0000000000 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_popover.dart +++ /dev/null @@ -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 createState() => _FlowyPopoverState(); -} - -class _FlowyPopoverState extends State { - final preRenderKey = GlobalKey(); - Size? size; - - @override - Widget build(BuildContext context) { - final theme = - context.watch() ?? 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), - ))); - } -} diff --git a/frontend/app_flowy/packages/flowy_infra_ui/pubspec.yaml b/frontend/app_flowy/packages/flowy_infra_ui/pubspec.yaml index c95ba1119e..9d9b25efab 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/pubspec.yaml +++ b/frontend/app_flowy/packages/flowy_infra_ui/pubspec.yaml @@ -27,6 +27,8 @@ dependencies: path: flowy_infra_ui_platform_interface flowy_infra_ui_web: path: flowy_infra_ui_web + appflowy_popover: + path: ../appflowy_popover # Flowy packages flowy_infra: