mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge pull request #1097 from AppFlowy-IO/refactor/appflowy_overlay
Refactor/appflowy overlay
This commit is contained in:
commit
56e68d1346
@ -2,7 +2,7 @@ import 'package:app_flowy/plugins/board/application/card/board_select_option_cel
|
|||||||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||||
import 'package:app_flowy/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart';
|
import 'package:app_flowy/plugins/grid/presentation/widgets/cell/select_option_cell/extension.dart';
|
||||||
import 'package:app_flowy/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart';
|
import 'package:app_flowy/plugins/grid/presentation/widgets/cell/select_option_cell/select_option_editor.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:app_flowy/plugins/board/application/card/card_bloc.dart';
|
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/board/application/card/card_data_controller.dart';
|
||||||
import 'package:app_flowy/plugins/grid/presentation/widgets/row/row_action_sheet.dart';
|
import 'package:app_flowy/plugins/grid/presentation/widgets/row/row_action_sheet.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
@ -4,7 +4,7 @@ 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/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_group.dart';
|
||||||
import 'package:app_flowy/plugins/grid/presentation/widgets/toolbar/grid_property.dart';
|
import 'package:app_flowy/plugins/grid/presentation/widgets/toolbar/grid_property.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
@ -65,7 +65,7 @@ class _SettingButtonState extends State<_SettingButton> {
|
|||||||
return AppFlowyPopover(
|
return AppFlowyPopover(
|
||||||
controller: popoverController,
|
controller: popoverController,
|
||||||
constraints: BoxConstraints.loose(const Size(260, 400)),
|
constraints: BoxConstraints.loose(const Size(260, 400)),
|
||||||
triggerActions: PopoverTriggerActionFlags.click,
|
triggerActions: PopoverTriggerFlags.click,
|
||||||
child: FlowyIconButton(
|
child: FlowyIconButton(
|
||||||
hoverColor: theme.hover,
|
hoverColor: theme.hover,
|
||||||
width: 22,
|
width: 22,
|
||||||
|
@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
|
|
||||||
import '../cell_builder.dart';
|
import '../cell_builder.dart';
|
||||||
import 'date_editor.dart';
|
import 'date_editor.dart';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/cell/date_cal_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/date_cal_bloc.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
@ -300,8 +300,7 @@ class _DateTypeOptionButton extends StatelessWidget {
|
|||||||
selector: (state) => state.dateTypeOptionPB,
|
selector: (state) => state.dateTypeOptionPB,
|
||||||
builder: (context, dateTypeOptionPB) {
|
builder: (context, dateTypeOptionPB) {
|
||||||
return AppFlowyPopover(
|
return AppFlowyPopover(
|
||||||
triggerActions:
|
triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
|
||||||
PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,
|
|
||||||
offset: const Offset(20, 0),
|
offset: const Offset(20, 0),
|
||||||
constraints: BoxConstraints.loose(const Size(140, 100)),
|
constraints: BoxConstraints.loose(const Size(140, 100)),
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
@ -340,36 +339,30 @@ class _CalDateTimeSettingState extends State<_CalDateTimeSetting> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List<Widget> children = [
|
List<Widget> children = [
|
||||||
Popover(
|
AppFlowyPopover(
|
||||||
mutex: _popoverMutex,
|
mutex: _popoverMutex,
|
||||||
triggerActions:
|
asBarrier: true,
|
||||||
PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,
|
triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
|
||||||
offset: const Offset(20, 0),
|
offset: const Offset(20, 0),
|
||||||
popupBuilder: (BuildContext context) {
|
popupBuilder: (BuildContext context) {
|
||||||
return OverlayContainer(
|
return DateFormatList(
|
||||||
constraints: BoxConstraints.loose(const Size(460, 440)),
|
selectedFormat: widget.dateTypeOptionPB.dateFormat,
|
||||||
child: DateFormatList(
|
onSelected: (format) =>
|
||||||
selectedFormat: widget.dateTypeOptionPB.dateFormat,
|
widget.onEvent(DateCalEvent.setDateFormat(format)),
|
||||||
onSelected: (format) =>
|
|
||||||
widget.onEvent(DateCalEvent.setDateFormat(format)),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: const DateFormatButton(),
|
child: const DateFormatButton(),
|
||||||
),
|
),
|
||||||
Popover(
|
AppFlowyPopover(
|
||||||
mutex: _popoverMutex,
|
mutex: _popoverMutex,
|
||||||
triggerActions:
|
asBarrier: true,
|
||||||
PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,
|
triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
|
||||||
offset: const Offset(20, 0),
|
offset: const Offset(20, 0),
|
||||||
popupBuilder: (BuildContext context) {
|
popupBuilder: (BuildContext context) {
|
||||||
return OverlayContainer(
|
return TimeFormatList(
|
||||||
constraints: BoxConstraints.loose(const Size(460, 440)),
|
selectedFormat: widget.dateTypeOptionPB.timeFormat,
|
||||||
child: TimeFormatList(
|
onSelected: (format) =>
|
||||||
selectedFormat: widget.dateTypeOptionPB.timeFormat,
|
widget.onEvent(DateCalEvent.setTimeFormat(format)),
|
||||||
onSelected: (format) =>
|
|
||||||
widget.onEvent(DateCalEvent.setTimeFormat(format)),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: TimeFormatButton(timeFormat: widget.dateTypeOptionPB.timeFormat),
|
child: TimeFormatButton(timeFormat: widget.dateTypeOptionPB.timeFormat),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
|
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/cell/select_option_editor_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/select_option_editor_bloc.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
|
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
@ -243,6 +243,7 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
|
|||||||
return AppFlowyPopover(
|
return AppFlowyPopover(
|
||||||
controller: _popoverController,
|
controller: _popoverController,
|
||||||
offset: const Offset(20, 0),
|
offset: const Offset(20, 0),
|
||||||
|
asBarrier: true,
|
||||||
constraints: BoxConstraints.loose(const Size(200, 300)),
|
constraints: BoxConstraints.loose(const Size(200, 300)),
|
||||||
mutex: widget.popoverMutex,
|
mutex: widget.popoverMutex,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
|
@ -2,7 +2,7 @@ import 'dart:async';
|
|||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/cell/url_cell_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/cell/url_cell_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/home/toast.dart';
|
import 'package:app_flowy/workspace/presentation/home/toast.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
@ -220,7 +220,7 @@ class _EditURLAccessoryState extends State<_EditURLAccessory>
|
|||||||
constraints: BoxConstraints.loose(const Size(300, 160)),
|
constraints: BoxConstraints.loose(const Size(300, 160)),
|
||||||
controller: _popoverController,
|
controller: _popoverController,
|
||||||
direction: PopoverDirection.bottomWithLeftAligned,
|
direction: PopoverDirection.bottomWithLeftAligned,
|
||||||
triggerActions: PopoverTriggerActionFlags.click,
|
triggerActions: PopoverTriggerFlags.click,
|
||||||
offset: const Offset(0, 20),
|
offset: const Offset(0, 20),
|
||||||
child: svgWidget("editor/edit", color: theme.iconColor),
|
child: svgWidget("editor/edit", color: theme.iconColor),
|
||||||
popupBuilder: (BuildContext popoverContext) {
|
popupBuilder: (BuildContext popoverContext) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:app_flowy/plugins/grid/application/field/field_cell_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_cell_bloc.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
@ -33,7 +33,7 @@ class GridFieldCell extends StatelessWidget {
|
|||||||
final button = AppFlowyPopover(
|
final button = AppFlowyPopover(
|
||||||
constraints: BoxConstraints.loose(const Size(240, 840)),
|
constraints: BoxConstraints.loose(const Size(240, 840)),
|
||||||
direction: PopoverDirection.bottomWithLeftAligned,
|
direction: PopoverDirection.bottomWithLeftAligned,
|
||||||
triggerActions: PopoverTriggerActionFlags.click,
|
triggerActions: PopoverTriggerFlags.click,
|
||||||
offset: const Offset(0, 10),
|
offset: const Offset(0, 10),
|
||||||
popupBuilder: (BuildContext context) {
|
popupBuilder: (BuildContext context) {
|
||||||
return GridFieldCellActionSheet(
|
return GridFieldCellActionSheet(
|
||||||
|
@ -3,7 +3,7 @@ import 'package:app_flowy/plugins/grid/presentation/widgets/header/field_editor.
|
|||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:app_flowy/plugins/grid/application/field/field_editor_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_editor_bloc.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
@ -244,7 +244,7 @@ class _DeleteFieldButton extends StatelessWidget {
|
|||||||
|
|
||||||
Widget _wrapPopover(Widget widget) {
|
Widget _wrapPopover(Widget widget) {
|
||||||
return AppFlowyPopover(
|
return AppFlowyPopover(
|
||||||
triggerActions: PopoverTriggerActionFlags.click,
|
triggerActions: PopoverTriggerFlags.click,
|
||||||
constraints: BoxConstraints.loose(const Size(400, 240)),
|
constraints: BoxConstraints.loose(const Size(400, 240)),
|
||||||
mutex: popoverMutex,
|
mutex: popoverMutex,
|
||||||
direction: PopoverDirection.center,
|
direction: PopoverDirection.center,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_data_controller.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_data_controller.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:dartz/dartz.dart' show Either;
|
import 'package:dartz/dartz.dart' show Either;
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
@ -66,8 +66,8 @@ class FieldTypeOptionEditor extends StatelessWidget {
|
|||||||
height: GridSize.typeOptionItemHeight,
|
height: GridSize.typeOptionItemHeight,
|
||||||
child: AppFlowyPopover(
|
child: AppFlowyPopover(
|
||||||
constraints: BoxConstraints.loose(const Size(460, 440)),
|
constraints: BoxConstraints.loose(const Size(460, 440)),
|
||||||
triggerActions:
|
asBarrier: true,
|
||||||
PopoverTriggerActionFlags.click | PopoverTriggerActionFlags.hover,
|
triggerActions: PopoverTriggerFlags.click | PopoverTriggerFlags.hover,
|
||||||
mutex: popoverMutex,
|
mutex: popoverMutex,
|
||||||
offset: const Offset(20, 0),
|
offset: const Offset(20, 0),
|
||||||
popupBuilder: (context) {
|
popupBuilder: (context) {
|
||||||
|
@ -4,7 +4,7 @@ import 'package:app_flowy/plugins/grid/application/field/type_option/type_option
|
|||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
@ -177,9 +177,10 @@ class CreateFieldButton extends StatelessWidget {
|
|||||||
final theme = context.watch<AppTheme>();
|
final theme = context.watch<AppTheme>();
|
||||||
|
|
||||||
return AppFlowyPopover(
|
return AppFlowyPopover(
|
||||||
triggerActions: PopoverTriggerActionFlags.click,
|
triggerActions: PopoverTriggerFlags.click,
|
||||||
direction: PopoverDirection.bottomWithRightAligned,
|
direction: PopoverDirection.bottomWithRightAligned,
|
||||||
constraints: BoxConstraints.loose(const Size(240, 200)),
|
asBarrier: true,
|
||||||
|
constraints: BoxConstraints.loose(const Size(240, 600)),
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
text: FlowyText.medium(
|
text: FlowyText.medium(
|
||||||
LocaleKeys.grid_field_newColumn.tr(),
|
LocaleKeys.grid_field_newColumn.tr(),
|
||||||
|
@ -3,7 +3,7 @@ import 'dart:typed_data';
|
|||||||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_data_controller.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_data_controller.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-grid/multi_select_type_option.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/multi_select_type_option.pb.dart';
|
||||||
|
@ -11,7 +11,7 @@ import 'package:flowy_infra_ui/widget/spacing.dart';
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import '../../../layout/sizes.dart';
|
import '../../../layout/sizes.dart';
|
||||||
import '../field_type_option_editor.dart';
|
import '../field_type_option_editor.dart';
|
||||||
import 'builder.dart';
|
import 'builder.dart';
|
||||||
@ -64,8 +64,7 @@ class DateTypeOptionWidget extends TypeOptionWidget {
|
|||||||
Widget _renderDateFormatButton(BuildContext context, DateFormat dataFormat) {
|
Widget _renderDateFormatButton(BuildContext context, DateFormat dataFormat) {
|
||||||
return AppFlowyPopover(
|
return AppFlowyPopover(
|
||||||
mutex: popoverMutex,
|
mutex: popoverMutex,
|
||||||
triggerActions:
|
triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
|
||||||
PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,
|
|
||||||
offset: const Offset(20, 0),
|
offset: const Offset(20, 0),
|
||||||
constraints: BoxConstraints.loose(const Size(460, 440)),
|
constraints: BoxConstraints.loose(const Size(460, 440)),
|
||||||
popupBuilder: (popoverContext) {
|
popupBuilder: (popoverContext) {
|
||||||
@ -86,8 +85,7 @@ class DateTypeOptionWidget extends TypeOptionWidget {
|
|||||||
Widget _renderTimeFormatButton(BuildContext context, TimeFormat timeFormat) {
|
Widget _renderTimeFormatButton(BuildContext context, TimeFormat timeFormat) {
|
||||||
return AppFlowyPopover(
|
return AppFlowyPopover(
|
||||||
mutex: popoverMutex,
|
mutex: popoverMutex,
|
||||||
triggerActions:
|
triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
|
||||||
PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,
|
|
||||||
offset: const Offset(20, 0),
|
offset: const Offset(20, 0),
|
||||||
constraints: BoxConstraints.loose(const Size(460, 440)),
|
constraints: BoxConstraints.loose(const Size(460, 440)),
|
||||||
popupBuilder: (BuildContext popoverContext) {
|
popupBuilder: (BuildContext popoverContext) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:app_flowy/plugins/grid/application/field/type_option/multi_select_type_option.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/multi_select_type_option.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
|
|
||||||
import '../field_type_option_editor.dart';
|
import '../field_type_option_editor.dart';
|
||||||
import 'builder.dart';
|
import 'builder.dart';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:app_flowy/plugins/grid/application/field/type_option/number_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/number_bloc.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/field/type_option/number_format_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/number_format_bloc.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
@ -57,8 +57,8 @@ class NumberTypeOptionWidget extends TypeOptionWidget {
|
|||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return AppFlowyPopover(
|
return AppFlowyPopover(
|
||||||
mutex: popoverMutex,
|
mutex: popoverMutex,
|
||||||
triggerActions: PopoverTriggerActionFlags.hover |
|
triggerActions:
|
||||||
PopoverTriggerActionFlags.click,
|
PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
|
||||||
offset: const Offset(20, 0),
|
offset: const Offset(20, 0),
|
||||||
constraints: BoxConstraints.loose(const Size(460, 440)),
|
constraints: BoxConstraints.loose(const Size(460, 440)),
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:app_flowy/plugins/grid/application/field/type_option/select_option_type_option_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/select_option_type_option_bloc.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
@ -184,6 +184,7 @@ class _OptionCellState extends State<_OptionCell> {
|
|||||||
controller: _popoverController,
|
controller: _popoverController,
|
||||||
mutex: widget.popoverMutex,
|
mutex: widget.popoverMutex,
|
||||||
offset: const Offset(20, 0),
|
offset: const Offset(20, 0),
|
||||||
|
asBarrier: true,
|
||||||
constraints: BoxConstraints.loose(const Size(460, 440)),
|
constraints: BoxConstraints.loose(const Size(460, 440)),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: GridSize.typeOptionItemHeight,
|
height: GridSize.typeOptionItemHeight,
|
||||||
|
@ -2,7 +2,7 @@ import 'package:app_flowy/plugins/grid/application/field/type_option/single_sele
|
|||||||
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
|
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../field_type_option_editor.dart';
|
import '../field_type_option_editor.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'builder.dart';
|
import 'builder.dart';
|
||||||
import 'select_option.dart';
|
import 'select_option.dart';
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
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_cache.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/row/row_data_controller.dart';
|
import 'package:app_flowy/plugins/grid/application/row/row_data_controller.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
@ -15,7 +15,7 @@ import 'package:app_flowy/generated/locale_keys.g.dart';
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
|
|
||||||
import '../../layout/sizes.dart';
|
import '../../layout/sizes.dart';
|
||||||
import '../cell/cell_accessory.dart';
|
import '../cell/cell_accessory.dart';
|
||||||
@ -197,7 +197,7 @@ class _CreateFieldButtonState extends State<_CreateFieldButton> {
|
|||||||
return AppFlowyPopover(
|
return AppFlowyPopover(
|
||||||
constraints: BoxConstraints.loose(const Size(240, 200)),
|
constraints: BoxConstraints.loose(const Size(240, 200)),
|
||||||
controller: popoverController,
|
controller: popoverController,
|
||||||
triggerActions: PopoverTriggerActionFlags.click,
|
triggerActions: PopoverTriggerFlags.click,
|
||||||
direction: PopoverDirection.topWithLeftAligned,
|
direction: PopoverDirection.topWithLeftAligned,
|
||||||
onClose: widget.onClosed,
|
onClose: widget.onClosed,
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -274,7 +274,7 @@ class _RowDetailCellState extends State<_RowDetailCell> {
|
|||||||
offset: const Offset(20, 0),
|
offset: const Offset(20, 0),
|
||||||
popupBuilder: (popoverContext) {
|
popupBuilder: (popoverContext) {
|
||||||
return OverlayContainer(
|
return OverlayContainer(
|
||||||
constraints: BoxConstraints.loose(const Size(240, 200)),
|
constraints: BoxConstraints.loose(const Size(240, 600)),
|
||||||
child: FieldEditor(
|
child: FieldEditor(
|
||||||
gridId: widget.cellId.gridId,
|
gridId: widget.cellId.gridId,
|
||||||
fieldName: widget.cellId.fieldContext.field.name,
|
fieldName: widget.cellId.fieldContext.field.name,
|
||||||
|
@ -3,7 +3,7 @@ import 'package:app_flowy/plugins/grid/presentation/widgets/header/field_editor.
|
|||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/setting/property_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/setting/property_bloc.dart';
|
||||||
import 'package:app_flowy/plugins/grid/presentation/widgets/header/field_type_extension.dart';
|
import 'package:app_flowy/plugins/grid/presentation/widgets/header/field_type_extension.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
@ -118,7 +118,7 @@ class _GridPropertyCell extends StatelessWidget {
|
|||||||
Widget _editFieldButton(AppTheme theme, BuildContext context) {
|
Widget _editFieldButton(AppTheme theme, BuildContext context) {
|
||||||
return AppFlowyPopover(
|
return AppFlowyPopover(
|
||||||
mutex: popoverMutex,
|
mutex: popoverMutex,
|
||||||
triggerActions: PopoverTriggerActionFlags.click,
|
triggerActions: PopoverTriggerFlags.click,
|
||||||
offset: const Offset(20, 0),
|
offset: const Offset(20, 0),
|
||||||
constraints: BoxConstraints.loose(const Size(240, 200)),
|
constraints: BoxConstraints.loose(const Size(240, 200)),
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:app_flowy/plugins/grid/application/setting/setting_bloc.dart';
|
import 'package:app_flowy/plugins/grid/application/setting/setting_bloc.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
@ -55,7 +55,7 @@ class _SettingButton extends StatelessWidget {
|
|||||||
final theme = context.watch<AppTheme>();
|
final theme = context.watch<AppTheme>();
|
||||||
return AppFlowyPopover(
|
return AppFlowyPopover(
|
||||||
constraints: BoxConstraints.loose(const Size(260, 400)),
|
constraints: BoxConstraints.loose(const Size(260, 400)),
|
||||||
triggerActions: PopoverTriggerActionFlags.click,
|
triggerActions: PopoverTriggerFlags.click,
|
||||||
offset: const Offset(0, 10),
|
offset: const Offset(0, 10),
|
||||||
child: FlowyIconButton(
|
child: FlowyIconButton(
|
||||||
width: 22,
|
width: 22,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
|
|
||||||
class PopoverMenu extends StatefulWidget {
|
class PopoverMenu extends StatefulWidget {
|
||||||
const PopoverMenu({Key? key}) : super(key: key);
|
const PopoverMenu({Key? key}) : super(key: key);
|
||||||
@ -41,8 +41,8 @@ class _PopoverMenuState extends State<PopoverMenu> {
|
|||||||
decoration: null)),
|
decoration: null)),
|
||||||
),
|
),
|
||||||
Popover(
|
Popover(
|
||||||
triggerActions: PopoverTriggerActionFlags.hover |
|
triggerActions:
|
||||||
PopoverTriggerActionFlags.click,
|
PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
|
||||||
mutex: popOverMutex,
|
mutex: popOverMutex,
|
||||||
offset: const Offset(10, 0),
|
offset: const Offset(10, 0),
|
||||||
popupBuilder: (BuildContext context) {
|
popupBuilder: (BuildContext context) {
|
||||||
@ -54,8 +54,8 @@ class _PopoverMenuState extends State<PopoverMenu> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Popover(
|
Popover(
|
||||||
triggerActions: PopoverTriggerActionFlags.hover |
|
triggerActions:
|
||||||
PopoverTriggerActionFlags.click,
|
PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
|
||||||
mutex: popOverMutex,
|
mutex: popOverMutex,
|
||||||
offset: const Offset(10, 0),
|
offset: const Offset(10, 0),
|
||||||
popupBuilder: (BuildContext context) {
|
popupBuilder: (BuildContext context) {
|
||||||
@ -86,7 +86,7 @@ class ExampleButton extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Popover(
|
return Popover(
|
||||||
triggerActions: PopoverTriggerActionFlags.click,
|
triggerActions: PopoverTriggerFlags.click,
|
||||||
offset: offset,
|
offset: offset,
|
||||||
direction: direction ?? PopoverDirection.rightWithTopAligned,
|
direction: direction ?? PopoverDirection.rightWithTopAligned,
|
||||||
child: TextButton(child: Text(label), onPressed: () {}),
|
child: TextButton(child: Text(label), onPressed: () {}),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import "./example_button.dart";
|
import "./example_button.dart";
|
||||||
|
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
/// AppFlowyBoard library
|
||||||
|
library appflowy_popover;
|
||||||
|
|
||||||
|
export 'src/mutex.dart';
|
||||||
|
export 'src/popover.dart';
|
@ -1,345 +0,0 @@
|
|||||||
import 'package:appflowy_popover/layout.dart';
|
|
||||||
import 'package:flutter/gestures.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
|
|
||||||
/// If multiple popovers are exclusive,
|
|
||||||
/// pass the same mutex to them.
|
|
||||||
class PopoverMutex {
|
|
||||||
final ValueNotifier<PopoverState?> _stateNotifier = ValueNotifier(null);
|
|
||||||
PopoverMutex();
|
|
||||||
|
|
||||||
void removePopoverStateListener(VoidCallback listener) {
|
|
||||||
_stateNotifier.removeListener(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
VoidCallback listenOnPopoverStateChanged(VoidCallback callback) {
|
|
||||||
listenerCallback() {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
_stateNotifier.addListener(listenerCallback);
|
|
||||||
return listenerCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void close() {
|
|
||||||
_stateNotifier.value?.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
PopoverState? get state => _stateNotifier.value;
|
|
||||||
|
|
||||||
set state(PopoverState? newState) {
|
|
||||||
if (_stateNotifier.value != null && _stateNotifier.value != newState) {
|
|
||||||
_stateNotifier.value?.close();
|
|
||||||
}
|
|
||||||
_stateNotifier.value = newState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _removeState() {
|
|
||||||
_stateNotifier.value = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dispose() {
|
|
||||||
_stateNotifier.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PopoverController {
|
|
||||||
PopoverState? state;
|
|
||||||
|
|
||||||
close() {
|
|
||||||
state?.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
show() {
|
|
||||||
state?.showOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PopoverTriggerActionFlags {
|
|
||||||
static int click = 0x01;
|
|
||||||
static int hover = 0x02;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum PopoverDirection {
|
|
||||||
// Corner aligned with a corner of the SourceWidget
|
|
||||||
topLeft,
|
|
||||||
topRight,
|
|
||||||
bottomLeft,
|
|
||||||
bottomRight,
|
|
||||||
center,
|
|
||||||
|
|
||||||
// Edge aligned with a edge of the SourceWidget
|
|
||||||
topWithLeftAligned,
|
|
||||||
topWithCenterAligned,
|
|
||||||
topWithRightAligned,
|
|
||||||
rightWithTopAligned,
|
|
||||||
rightWithCenterAligned,
|
|
||||||
rightWithBottomAligned,
|
|
||||||
bottomWithLeftAligned,
|
|
||||||
bottomWithCenterAligned,
|
|
||||||
bottomWithRightAligned,
|
|
||||||
leftWithTopAligned,
|
|
||||||
leftWithCenterAligned,
|
|
||||||
leftWithBottomAligned,
|
|
||||||
|
|
||||||
custom,
|
|
||||||
}
|
|
||||||
|
|
||||||
class Popover extends StatefulWidget {
|
|
||||||
final PopoverController? controller;
|
|
||||||
|
|
||||||
final Offset? offset;
|
|
||||||
|
|
||||||
final Decoration? maskDecoration;
|
|
||||||
|
|
||||||
/// The function used to build the popover.
|
|
||||||
final Widget? Function(BuildContext context) popupBuilder;
|
|
||||||
|
|
||||||
final int triggerActions;
|
|
||||||
|
|
||||||
/// If multiple popovers are exclusive,
|
|
||||||
/// pass the same mutex to them.
|
|
||||||
final PopoverMutex? mutex;
|
|
||||||
|
|
||||||
/// The direction of the popover
|
|
||||||
final PopoverDirection direction;
|
|
||||||
|
|
||||||
final void Function()? onClose;
|
|
||||||
|
|
||||||
/// The content area of the popover.
|
|
||||||
final Widget child;
|
|
||||||
|
|
||||||
const Popover({
|
|
||||||
Key? key,
|
|
||||||
required this.child,
|
|
||||||
required this.popupBuilder,
|
|
||||||
this.controller,
|
|
||||||
this.offset,
|
|
||||||
this.maskDecoration,
|
|
||||||
this.triggerActions = 0,
|
|
||||||
this.direction = PopoverDirection.rightWithTopAligned,
|
|
||||||
this.mutex,
|
|
||||||
this.onClose,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<Popover> createState() => PopoverState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class PopoverState extends State<Popover> {
|
|
||||||
final PopoverLink popoverLink = PopoverLink();
|
|
||||||
OverlayEntry? _overlayEntry;
|
|
||||||
bool hasMask = true;
|
|
||||||
|
|
||||||
static PopoverState? _popoverWithMask;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
widget.controller?.state = this;
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
showOverlay() {
|
|
||||||
close();
|
|
||||||
|
|
||||||
if (widget.mutex != null) {
|
|
||||||
widget.mutex?.state = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_popoverWithMask == null) {
|
|
||||||
_popoverWithMask = this;
|
|
||||||
} else {
|
|
||||||
hasMask = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final newEntry = OverlayEntry(builder: (context) {
|
|
||||||
final children = <Widget>[];
|
|
||||||
|
|
||||||
if (hasMask) {
|
|
||||||
children.add(_PopoverMask(
|
|
||||||
decoration: widget.maskDecoration,
|
|
||||||
onTap: () => close(),
|
|
||||||
onExit: () => close(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
children.add(PopoverContainer(
|
|
||||||
direction: widget.direction,
|
|
||||||
popoverLink: popoverLink,
|
|
||||||
offset: widget.offset ?? Offset.zero,
|
|
||||||
popupBuilder: widget.popupBuilder,
|
|
||||||
onClose: () => close(),
|
|
||||||
onCloseAll: () => closeAll(),
|
|
||||||
));
|
|
||||||
|
|
||||||
return Stack(children: children);
|
|
||||||
});
|
|
||||||
|
|
||||||
_overlayEntry = newEntry;
|
|
||||||
|
|
||||||
Overlay.of(context)?.insert(newEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
close() {
|
|
||||||
if (_overlayEntry != null) {
|
|
||||||
_overlayEntry!.remove();
|
|
||||||
_overlayEntry = null;
|
|
||||||
if (_popoverWithMask == this) {
|
|
||||||
_popoverWithMask = null;
|
|
||||||
}
|
|
||||||
if (widget.onClose != null) {
|
|
||||||
widget.onClose!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (widget.mutex?.state == this) {
|
|
||||||
widget.mutex?._removeState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closeAll() {
|
|
||||||
_popoverWithMask?.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void deactivate() {
|
|
||||||
close();
|
|
||||||
super.deactivate();
|
|
||||||
}
|
|
||||||
|
|
||||||
_handleTargetPointerDown(PointerDownEvent event) {
|
|
||||||
if (widget.triggerActions & PopoverTriggerActionFlags.click != 0) {
|
|
||||||
showOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_handleTargetPointerEnter(PointerEnterEvent event) {
|
|
||||||
if (widget.triggerActions & PopoverTriggerActionFlags.hover != 0) {
|
|
||||||
showOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_buildContent(BuildContext context) {
|
|
||||||
if (widget.triggerActions == 0) {
|
|
||||||
return widget.child;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MouseRegion(
|
|
||||||
onEnter: _handleTargetPointerEnter,
|
|
||||||
child: Listener(
|
|
||||||
onPointerDown: _handleTargetPointerDown,
|
|
||||||
child: widget.child,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return PopoverTarget(
|
|
||||||
link: popoverLink,
|
|
||||||
child: _buildContent(context),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _PopoverMask extends StatefulWidget {
|
|
||||||
final void Function() onTap;
|
|
||||||
final void Function()? onExit;
|
|
||||||
final Decoration? decoration;
|
|
||||||
|
|
||||||
const _PopoverMask(
|
|
||||||
{Key? key, required this.onTap, this.onExit, this.decoration})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<StatefulWidget> createState() => _PopoverMaskState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _PopoverMaskState extends State<_PopoverMask> {
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
HardwareKeyboard.instance.addHandler(_handleGlobalKeyEvent);
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _handleGlobalKeyEvent(KeyEvent event) {
|
|
||||||
if (event.logicalKey == LogicalKeyboardKey.escape) {
|
|
||||||
if (widget.onExit != null) {
|
|
||||||
widget.onExit!();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void deactivate() {
|
|
||||||
HardwareKeyboard.instance.removeHandler(_handleGlobalKeyEvent);
|
|
||||||
super.deactivate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: widget.onTap,
|
|
||||||
child: Container(
|
|
||||||
// decoration: widget.decoration,
|
|
||||||
decoration: widget.decoration ??
|
|
||||||
const BoxDecoration(
|
|
||||||
color: Color.fromARGB(0, 244, 67, 54),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PopoverContainer extends StatefulWidget {
|
|
||||||
final Widget? Function(BuildContext context) popupBuilder;
|
|
||||||
final PopoverDirection direction;
|
|
||||||
final PopoverLink popoverLink;
|
|
||||||
final Offset offset;
|
|
||||||
final void Function() onClose;
|
|
||||||
final void Function() onCloseAll;
|
|
||||||
|
|
||||||
const PopoverContainer({
|
|
||||||
Key? key,
|
|
||||||
required this.popupBuilder,
|
|
||||||
required this.direction,
|
|
||||||
required this.popoverLink,
|
|
||||||
required this.offset,
|
|
||||||
required this.onClose,
|
|
||||||
required this.onCloseAll,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<StatefulWidget> 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<PopoverContainerState>();
|
|
||||||
return result!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PopoverContainerState extends State<PopoverContainer> {
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return CustomSingleChildLayout(
|
|
||||||
delegate: PopoverLayoutDelegate(
|
|
||||||
direction: widget.direction,
|
|
||||||
link: widget.popoverLink,
|
|
||||||
offset: widget.offset,
|
|
||||||
),
|
|
||||||
child: widget.popupBuilder(context),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
close() => widget.onClose();
|
|
||||||
|
|
||||||
closeAll() => widget.onCloseAll();
|
|
||||||
}
|
|
116
frontend/app_flowy/packages/appflowy_popover/lib/src/mask.dart
Normal file
116
frontend/app_flowy/packages/appflowy_popover/lib/src/mask.dart
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import 'dart:collection';
|
||||||
|
|
||||||
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
typedef EntryMap = LinkedHashMap<PopoverState, OverlayEntryContext>;
|
||||||
|
|
||||||
|
class RootOverlayEntry {
|
||||||
|
final EntryMap _entries = EntryMap();
|
||||||
|
RootOverlayEntry();
|
||||||
|
|
||||||
|
void addEntry(
|
||||||
|
BuildContext context,
|
||||||
|
PopoverState newState,
|
||||||
|
OverlayEntry entry,
|
||||||
|
bool asBarrier,
|
||||||
|
) {
|
||||||
|
_entries[newState] = OverlayEntryContext(entry, newState, asBarrier);
|
||||||
|
Overlay.of(context)?.insert(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains(PopoverState oldState) {
|
||||||
|
return _entries.containsKey(oldState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeEntry(PopoverState oldState) {
|
||||||
|
if (_entries.isEmpty) return;
|
||||||
|
|
||||||
|
final removedEntry = _entries.remove(oldState);
|
||||||
|
removedEntry?.overlayEntry.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get isEmpty => _entries.isEmpty;
|
||||||
|
|
||||||
|
bool get isNotEmpty => _entries.isNotEmpty;
|
||||||
|
|
||||||
|
bool hasEntry() {
|
||||||
|
return _entries.isNotEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
PopoverState? popEntry() {
|
||||||
|
if (_entries.isEmpty) return null;
|
||||||
|
|
||||||
|
final lastEntry = _entries.values.last;
|
||||||
|
_entries.remove(lastEntry.popoverState);
|
||||||
|
lastEntry.overlayEntry.remove();
|
||||||
|
lastEntry.popoverState.widget.onClose?.call();
|
||||||
|
|
||||||
|
if (lastEntry.asBarrier) {
|
||||||
|
return lastEntry.popoverState;
|
||||||
|
} else {
|
||||||
|
return popEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OverlayEntryContext {
|
||||||
|
final bool asBarrier;
|
||||||
|
final PopoverState popoverState;
|
||||||
|
final OverlayEntry overlayEntry;
|
||||||
|
|
||||||
|
OverlayEntryContext(
|
||||||
|
this.overlayEntry,
|
||||||
|
this.popoverState,
|
||||||
|
this.asBarrier,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class PopoverMask extends StatefulWidget {
|
||||||
|
final void Function() onTap;
|
||||||
|
final void Function()? onExit;
|
||||||
|
final Decoration? decoration;
|
||||||
|
|
||||||
|
const PopoverMask(
|
||||||
|
{Key? key, required this.onTap, this.onExit, this.decoration})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _PopoverMaskState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PopoverMaskState extends State<PopoverMask> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
HardwareKeyboard.instance.addHandler(_handleGlobalKeyEvent);
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _handleGlobalKeyEvent(KeyEvent event) {
|
||||||
|
if (event.logicalKey == LogicalKeyboardKey.escape) {
|
||||||
|
if (widget.onExit != null) {
|
||||||
|
widget.onExit!();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void deactivate() {
|
||||||
|
HardwareKeyboard.instance.removeHandler(_handleGlobalKeyEvent);
|
||||||
|
super.deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: widget.onTap,
|
||||||
|
child: Container(
|
||||||
|
decoration: widget.decoration,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'popover.dart';
|
||||||
|
|
||||||
|
/// If multiple popovers are exclusive,
|
||||||
|
/// pass the same mutex to them.
|
||||||
|
class PopoverMutex {
|
||||||
|
final ValueNotifier<PopoverState?> _stateNotifier = ValueNotifier(null);
|
||||||
|
PopoverMutex();
|
||||||
|
|
||||||
|
void removePopoverStateListener(VoidCallback listener) {
|
||||||
|
_stateNotifier.removeListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
VoidCallback listenOnPopoverStateChanged(VoidCallback callback) {
|
||||||
|
listenerCallback() {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
_stateNotifier.addListener(listenerCallback);
|
||||||
|
return listenerCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void close() {
|
||||||
|
_stateNotifier.value?.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
PopoverState? get state => _stateNotifier.value;
|
||||||
|
|
||||||
|
set state(PopoverState? newState) {
|
||||||
|
if (_stateNotifier.value != null && _stateNotifier.value != newState) {
|
||||||
|
_stateNotifier.value?.close();
|
||||||
|
}
|
||||||
|
_stateNotifier.value = newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeState() {
|
||||||
|
_stateNotifier.value = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
_stateNotifier.dispose();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,248 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'package:appflowy_popover/src/layout.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'mask.dart';
|
||||||
|
import 'mutex.dart';
|
||||||
|
|
||||||
|
class PopoverController {
|
||||||
|
PopoverState? _state;
|
||||||
|
|
||||||
|
close() {
|
||||||
|
_state?.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
_state?.showOverlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PopoverTriggerFlags {
|
||||||
|
static int click = 0x01;
|
||||||
|
static int hover = 0x02;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PopoverDirection {
|
||||||
|
// Corner aligned with a corner of the SourceWidget
|
||||||
|
topLeft,
|
||||||
|
topRight,
|
||||||
|
bottomLeft,
|
||||||
|
bottomRight,
|
||||||
|
center,
|
||||||
|
|
||||||
|
// Edge aligned with a edge of the SourceWidget
|
||||||
|
topWithLeftAligned,
|
||||||
|
topWithCenterAligned,
|
||||||
|
topWithRightAligned,
|
||||||
|
rightWithTopAligned,
|
||||||
|
rightWithCenterAligned,
|
||||||
|
rightWithBottomAligned,
|
||||||
|
bottomWithLeftAligned,
|
||||||
|
bottomWithCenterAligned,
|
||||||
|
bottomWithRightAligned,
|
||||||
|
leftWithTopAligned,
|
||||||
|
leftWithCenterAligned,
|
||||||
|
leftWithBottomAligned,
|
||||||
|
|
||||||
|
custom,
|
||||||
|
}
|
||||||
|
|
||||||
|
class Popover extends StatefulWidget {
|
||||||
|
final PopoverController? controller;
|
||||||
|
|
||||||
|
final Offset? offset;
|
||||||
|
|
||||||
|
final Decoration? maskDecoration;
|
||||||
|
|
||||||
|
/// The function used to build the popover.
|
||||||
|
final Widget? Function(BuildContext context) popupBuilder;
|
||||||
|
|
||||||
|
final int triggerActions;
|
||||||
|
|
||||||
|
/// If multiple popovers are exclusive,
|
||||||
|
/// pass the same mutex to them.
|
||||||
|
final PopoverMutex? mutex;
|
||||||
|
|
||||||
|
/// The direction of the popover
|
||||||
|
final PopoverDirection direction;
|
||||||
|
|
||||||
|
final void Function()? onClose;
|
||||||
|
|
||||||
|
final bool asBarrier;
|
||||||
|
|
||||||
|
/// The content area of the popover.
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const Popover({
|
||||||
|
Key? key,
|
||||||
|
required this.child,
|
||||||
|
required this.popupBuilder,
|
||||||
|
this.controller,
|
||||||
|
this.offset,
|
||||||
|
this.maskDecoration = const BoxDecoration(
|
||||||
|
color: Color.fromARGB(0, 244, 67, 54),
|
||||||
|
),
|
||||||
|
this.triggerActions = 0,
|
||||||
|
this.direction = PopoverDirection.rightWithTopAligned,
|
||||||
|
this.mutex,
|
||||||
|
this.onClose,
|
||||||
|
this.asBarrier = false,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<Popover> createState() => PopoverState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class PopoverState extends State<Popover> {
|
||||||
|
static final RootOverlayEntry _rootEntry = RootOverlayEntry();
|
||||||
|
final PopoverLink popoverLink = PopoverLink();
|
||||||
|
Timer? _debounceEnterRegionAction;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
widget.controller?._state = this;
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void showOverlay() {
|
||||||
|
close();
|
||||||
|
|
||||||
|
if (widget.mutex != null) {
|
||||||
|
widget.mutex?.state = this;
|
||||||
|
}
|
||||||
|
final shouldAddMask = _rootEntry.isEmpty;
|
||||||
|
final newEntry = OverlayEntry(builder: (context) {
|
||||||
|
final children = <Widget>[];
|
||||||
|
if (shouldAddMask) {
|
||||||
|
children.add(
|
||||||
|
PopoverMask(
|
||||||
|
decoration: widget.maskDecoration,
|
||||||
|
onTap: () => _removeRootOverlay(),
|
||||||
|
onExit: () => _removeRootOverlay(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
children.add(
|
||||||
|
PopoverContainer(
|
||||||
|
direction: widget.direction,
|
||||||
|
popoverLink: popoverLink,
|
||||||
|
offset: widget.offset ?? Offset.zero,
|
||||||
|
popupBuilder: widget.popupBuilder,
|
||||||
|
onClose: () => close(),
|
||||||
|
onCloseAll: () => _removeRootOverlay(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return Stack(children: children);
|
||||||
|
});
|
||||||
|
|
||||||
|
_rootEntry.addEntry(context, this, newEntry, widget.asBarrier);
|
||||||
|
}
|
||||||
|
|
||||||
|
void close() {
|
||||||
|
if (_rootEntry.contains(this)) {
|
||||||
|
_rootEntry.removeEntry(this);
|
||||||
|
widget.onClose?.call();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _removeRootOverlay() {
|
||||||
|
_rootEntry.popEntry();
|
||||||
|
|
||||||
|
if (widget.mutex?.state == this) {
|
||||||
|
widget.mutex?.removeState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void deactivate() {
|
||||||
|
close();
|
||||||
|
super.deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return PopoverTarget(
|
||||||
|
link: popoverLink,
|
||||||
|
child: _buildChild(context),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildChild(BuildContext context) {
|
||||||
|
if (widget.triggerActions == 0) {
|
||||||
|
return widget.child;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MouseRegion(
|
||||||
|
onEnter: (event) {
|
||||||
|
_debounceEnterRegionAction =
|
||||||
|
Timer(const Duration(milliseconds: 200), () {
|
||||||
|
if (widget.triggerActions & PopoverTriggerFlags.hover != 0) {
|
||||||
|
showOverlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onExit: (event) {
|
||||||
|
_debounceEnterRegionAction?.cancel();
|
||||||
|
_debounceEnterRegionAction = null;
|
||||||
|
},
|
||||||
|
child: Listener(
|
||||||
|
child: widget.child,
|
||||||
|
onPointerDown: (PointerDownEvent event) {
|
||||||
|
if (widget.triggerActions & PopoverTriggerFlags.click != 0) {
|
||||||
|
showOverlay();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PopoverContainer extends StatefulWidget {
|
||||||
|
final Widget? Function(BuildContext context) popupBuilder;
|
||||||
|
final PopoverDirection direction;
|
||||||
|
final PopoverLink popoverLink;
|
||||||
|
final Offset offset;
|
||||||
|
final void Function() onClose;
|
||||||
|
final void Function() onCloseAll;
|
||||||
|
|
||||||
|
const PopoverContainer({
|
||||||
|
Key? key,
|
||||||
|
required this.popupBuilder,
|
||||||
|
required this.direction,
|
||||||
|
required this.popoverLink,
|
||||||
|
required this.offset,
|
||||||
|
required this.onClose,
|
||||||
|
required this.onCloseAll,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> 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<PopoverContainerState>();
|
||||||
|
return result!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PopoverContainerState extends State<PopoverContainer> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return CustomSingleChildLayout(
|
||||||
|
delegate: PopoverLayoutDelegate(
|
||||||
|
direction: widget.direction,
|
||||||
|
link: widget.popoverLink,
|
||||||
|
offset: widget.offset,
|
||||||
|
),
|
||||||
|
child: widget.popupBuilder(context),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
close() => widget.onClose();
|
||||||
|
|
||||||
|
closeAll() => widget.onCloseAll();
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class AppFlowyPopover extends StatelessWidget {
|
class AppFlowyPopover extends StatelessWidget {
|
||||||
@ -12,6 +12,7 @@ class AppFlowyPopover extends StatelessWidget {
|
|||||||
final void Function()? onClose;
|
final void Function()? onClose;
|
||||||
final PopoverMutex? mutex;
|
final PopoverMutex? mutex;
|
||||||
final Offset? offset;
|
final Offset? offset;
|
||||||
|
final bool asBarrier;
|
||||||
|
|
||||||
const AppFlowyPopover({
|
const AppFlowyPopover({
|
||||||
Key? key,
|
Key? key,
|
||||||
@ -24,6 +25,7 @@ class AppFlowyPopover extends StatelessWidget {
|
|||||||
this.triggerActions = 0,
|
this.triggerActions = 0,
|
||||||
this.offset,
|
this.offset,
|
||||||
this.controller,
|
this.controller,
|
||||||
|
this.asBarrier = false,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -33,6 +35,7 @@ class AppFlowyPopover extends StatelessWidget {
|
|||||||
onClose: onClose,
|
onClose: onClose,
|
||||||
direction: direction,
|
direction: direction,
|
||||||
mutex: mutex,
|
mutex: mutex,
|
||||||
|
asBarrier: asBarrier,
|
||||||
triggerActions: triggerActions,
|
triggerActions: triggerActions,
|
||||||
popupBuilder: (context) {
|
popupBuilder: (context) {
|
||||||
final child = popupBuilder(context);
|
final child = popupBuilder(context);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user