feat: use popover in property field

This commit is contained in:
Vincent Chan 2022-08-31 11:04:07 +08:00
parent 8bab4cce61
commit d79a7cb194
6 changed files with 119 additions and 155 deletions

View File

@ -3,7 +3,6 @@ import 'package:app_flowy/plugins/grid/application/field/field_service.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/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
@ -44,11 +43,8 @@ class _GridFieldCellState extends State<GridFieldCell> {
followerAnchor: Alignment.topLeft,
offset: const Offset(0, 10),
popupBuilder: (BuildContext context) {
return OverlayContainer(
constraints: BoxConstraints.loose(const Size(240, 200)),
child: GridFieldCellActionSheet(
cellContext: widget.cellContext,
),
return GridFieldCellActionSheet(
cellContext: widget.cellContext,
);
},
);

View File

@ -11,92 +11,85 @@ import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:appflowy_popover/popover.dart';
import 'package:app_flowy/generated/locale_keys.g.dart';
import '../../layout/sizes.dart';
class GridFieldCellActionSheet extends StatelessWidget
with FlowyOverlayDelegate {
class GridFieldCellActionSheet extends StatefulWidget {
final GridFieldCellContext cellContext;
const GridFieldCellActionSheet({required this.cellContext, Key? key})
: super(key: key);
@override
State<StatefulWidget> createState() => _GridFieldCellActionSheetState();
}
class _GridFieldCellActionSheetState extends State<GridFieldCellActionSheet> {
bool _showFieldEditor = false;
@override
Widget build(BuildContext context) {
if (_showFieldEditor) {
final field = widget.cellContext.field;
return OverlayContainer(
constraints: BoxConstraints.loose(const Size(240, 200)),
child: FieldEditor(
gridId: widget.cellContext.gridId,
fieldName: field.name,
typeOptionLoader: FieldTypeOptionLoader(
gridId: widget.cellContext.gridId,
field: field,
),
),
);
}
return BlocProvider(
create: (context) => getIt<FieldActionSheetBloc>(param1: cellContext),
child: SingleChildScrollView(
child: Column(
children: [
_EditFieldButton(
cellContext: cellContext,
),
const VSpace(6),
_FieldOperationList(cellContext,
() => FlowyOverlay.of(context).remove(identifier())),
],
create: (context) =>
getIt<FieldActionSheetBloc>(param1: widget.cellContext),
child: OverlayContainer(
constraints: BoxConstraints.loose(const Size(240, 200)),
child: SingleChildScrollView(
child: Column(
children: [
_EditFieldButton(
cellContext: widget.cellContext,
onTap: () {
setState(() {
_showFieldEditor = true;
});
},
),
const VSpace(6),
_FieldOperationList(widget.cellContext, () {}),
],
),
),
),
);
}
static String identifier() {
return (GridFieldCellActionSheet).toString();
}
@override
bool asBarrier() {
return true;
}
}
class _EditFieldButton extends StatefulWidget {
class _EditFieldButton extends StatelessWidget {
final GridFieldCellContext cellContext;
const _EditFieldButton({required this.cellContext, Key? key})
final void Function()? onTap;
const _EditFieldButton({required this.cellContext, Key? key, this.onTap})
: super(key: key);
@override
State<StatefulWidget> createState() => _EditFieldButtonState();
}
class _EditFieldButtonState extends State<_EditFieldButton> {
final popover = PopoverController();
@override
Widget build(BuildContext context) {
final theme = context.watch<AppTheme>();
return BlocBuilder<FieldActionSheetBloc, FieldActionSheetState>(
builder: (context, state) {
return SizedBox(
height: GridSize.typeOptionItemHeight,
child: Popover(
controller: popover,
targetAnchor: Alignment.topRight,
followerAnchor: Alignment.topLeft,
offset: const Offset(20, 0),
popupBuilder: (context) {
final field = widget.cellContext.field;
return OverlayContainer(
constraints: BoxConstraints.loose(const Size(240, 200)),
child: FieldEditor(
gridId: widget.cellContext.gridId,
fieldName: field.name,
typeOptionLoader: FieldTypeOptionLoader(
gridId: widget.cellContext.gridId,
field: field,
),
),
);
},
child: FlowyButton(
text: FlowyText.medium(
LocaleKeys.grid_field_editProperty.tr(),
fontSize: 12,
),
hoverColor: theme.hover,
onTap: () => popover.show(),
child: FlowyButton(
text: FlowyText.medium(
LocaleKeys.grid_field_editProperty.tr(),
fontSize: 12,
),
hoverColor: theme.hover,
onTap: onTap,
),
);
},

View File

@ -70,7 +70,7 @@ class DateTypeOptionWidget extends TypeOptionWidget {
targetAnchor: Alignment.topRight,
followerAnchor: Alignment.topLeft,
offset: const Offset(20, 0),
popupBuilder: (context) {
popupBuilder: (popoverContext) {
return OverlayContainer(
constraints: BoxConstraints.loose(const Size(460, 440)),
child: DateFormatList(

View File

@ -1,7 +1,9 @@
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
import 'package:app_flowy/plugins/grid/presentation/widgets/header/field_editor.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/presentation/widgets/header/field_type_extension.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';
@ -16,9 +18,8 @@ import 'package:styled_widget/styled_widget.dart';
import '../../../application/field/field_cache.dart';
import '../../layout/sizes.dart';
import '../header/field_editor.dart';
class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate {
class GridPropertyList extends StatelessWidget {
final String gridId;
final GridFieldCache fieldCache;
const GridPropertyList({
@ -27,20 +28,6 @@ class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate {
Key? key,
}) : super(key: key);
void show(BuildContext context) {
FlowyOverlay.of(context).insertWithAnchor(
widget: OverlayContainer(
child: this,
constraints: BoxConstraints.loose(const Size(260, 400)),
),
identifier: identifier(),
anchorContext: context,
anchorDirection: AnchorDirection.bottomRight,
style: FlowyOverlayStyle(blur: false),
delegate: this,
);
}
@override
Widget build(BuildContext context) {
return BlocProvider(
@ -68,13 +55,6 @@ class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate {
),
);
}
String identifier() {
return (GridPropertyList).toString();
}
@override
bool asBarrier() => true;
}
class _GridPropertyCell extends StatelessWidget {
@ -113,19 +93,27 @@ class _GridPropertyCell extends StatelessWidget {
);
}
FlowyButton _editFieldButton(AppTheme theme, BuildContext context) {
return FlowyButton(
text: FlowyText.medium(field.name, fontSize: 12),
hoverColor: theme.hover,
leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor),
onTap: () {
// FieldEditorPopOver.show(
// context,
// anchorContext: context,
// gridId: gridId,
// fieldName: field.name,
// typeOptionLoader: FieldTypeOptionLoader(gridId: gridId, field: field),
// );
Widget _editFieldButton(AppTheme theme, BuildContext context) {
return Popover(
triggerActions: PopoverTriggerActionFlags.click,
targetAnchor: Alignment.topRight,
followerAnchor: Alignment.topLeft,
offset: const Offset(20, 0),
child: FlowyButton(
text: FlowyText.medium(field.name, fontSize: 12),
hoverColor: theme.hover,
leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor),
),
popupBuilder: (BuildContext context) {
return OverlayContainer(
constraints: BoxConstraints.loose(const Size(240, 200)),
child: FieldEditor(
gridId: gridId,
fieldName: field.name,
typeOptionLoader:
FieldTypeOptionLoader(gridId: gridId, field: field),
),
);
},
);
}

View File

@ -1,4 +1,5 @@
import 'package:app_flowy/plugins/grid/application/setting/setting_bloc.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';
@ -32,37 +33,6 @@ class GridSettingList extends StatelessWidget {
{required this.settingContext, required this.onAction, Key? key})
: super(key: key);
static void show(BuildContext context, GridSettingContext settingContext) {
final list = GridSettingList(
settingContext: settingContext,
onAction: (action, settingContext) {
switch (action) {
case GridSettingAction.filter:
break;
case GridSettingAction.sortBy:
break;
case GridSettingAction.properties:
GridPropertyList(
gridId: settingContext.gridId,
fieldCache: settingContext.fieldCache)
.show(context);
break;
}
},
);
FlowyOverlay.of(context).insertWithAnchor(
widget: OverlayContainer(
child: list,
constraints: BoxConstraints.loose(const Size(140, 400)),
),
identifier: list.identifier(),
anchorContext: context,
anchorDirection: AnchorDirection.bottomRight,
style: FlowyOverlayStyle(blur: false),
);
}
@override
Widget build(BuildContext context) {
return BlocProvider(

View File

@ -65,30 +65,47 @@ class _SettingButton extends StatelessWidget {
.padding(horizontal: 3, vertical: 3),
),
popupBuilder: (BuildContext context) {
return OverlayContainer(
constraints: BoxConstraints.loose(const Size(140, 400)),
child: GridSettingList(
settingContext: settingContext,
onAction: (action, settingContext) {
switch (action) {
case GridSettingAction.filter:
break;
case GridSettingAction.sortBy:
break;
case GridSettingAction.properties:
GridPropertyList(
gridId: settingContext.gridId,
fieldCache: settingContext.fieldCache)
.show(context);
break;
}
},
),
);
return _GridSettingListPopover(settingContext: settingContext);
},
);
// return FlowyIconButton(
// onPressed: () => GridSettingList.show(context, settingContext),
// );
}
}
class _GridSettingListPopover extends StatefulWidget {
final GridSettingContext settingContext;
const _GridSettingListPopover({Key? key, required this.settingContext})
: super(key: key);
@override
State<StatefulWidget> createState() => _GridSettingListPopoverState();
}
class _GridSettingListPopoverState extends State<_GridSettingListPopover> {
GridSettingAction? _action;
@override
Widget build(BuildContext context) {
if (_action == GridSettingAction.properties) {
return OverlayContainer(
constraints: BoxConstraints.loose(const Size(260, 400)),
child: GridPropertyList(
gridId: widget.settingContext.gridId,
fieldCache: widget.settingContext.fieldCache,
),
);
}
return OverlayContainer(
constraints: BoxConstraints.loose(const Size(140, 400)),
child: GridSettingList(
settingContext: widget.settingContext,
onAction: (action, settingContext) {
setState(() {
_action = action;
});
},
),
);
}
}