mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: use popover in property field
This commit is contained in:
parent
8bab4cce61
commit
d79a7cb194
@ -3,7 +3,6 @@ import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
|||||||
import 'package:appflowy_popover/popover.dart';
|
import 'package:appflowy_popover/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_web.dart';
|
|
||||||
import 'package:flowy_infra_ui/style_widget/button.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/hover.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
@ -44,11 +43,8 @@ class _GridFieldCellState extends State<GridFieldCell> {
|
|||||||
followerAnchor: Alignment.topLeft,
|
followerAnchor: Alignment.topLeft,
|
||||||
offset: const Offset(0, 10),
|
offset: const Offset(0, 10),
|
||||||
popupBuilder: (BuildContext context) {
|
popupBuilder: (BuildContext context) {
|
||||||
return OverlayContainer(
|
return GridFieldCellActionSheet(
|
||||||
constraints: BoxConstraints.loose(const Size(240, 200)),
|
cellContext: widget.cellContext,
|
||||||
child: GridFieldCellActionSheet(
|
|
||||||
cellContext: widget.cellContext,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -11,92 +11,85 @@ import 'package:flowy_infra_ui/widget/spacing.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:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:appflowy_popover/popover.dart';
|
|
||||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||||
|
|
||||||
import '../../layout/sizes.dart';
|
import '../../layout/sizes.dart';
|
||||||
|
|
||||||
class GridFieldCellActionSheet extends StatelessWidget
|
class GridFieldCellActionSheet extends StatefulWidget {
|
||||||
with FlowyOverlayDelegate {
|
|
||||||
final GridFieldCellContext cellContext;
|
final GridFieldCellContext cellContext;
|
||||||
const GridFieldCellActionSheet({required this.cellContext, Key? key})
|
const GridFieldCellActionSheet({required this.cellContext, Key? key})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _GridFieldCellActionSheetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _GridFieldCellActionSheetState extends State<GridFieldCellActionSheet> {
|
||||||
|
bool _showFieldEditor = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
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(
|
return BlocProvider(
|
||||||
create: (context) => getIt<FieldActionSheetBloc>(param1: cellContext),
|
create: (context) =>
|
||||||
child: SingleChildScrollView(
|
getIt<FieldActionSheetBloc>(param1: widget.cellContext),
|
||||||
child: Column(
|
child: OverlayContainer(
|
||||||
children: [
|
constraints: BoxConstraints.loose(const Size(240, 200)),
|
||||||
_EditFieldButton(
|
child: SingleChildScrollView(
|
||||||
cellContext: cellContext,
|
child: Column(
|
||||||
),
|
children: [
|
||||||
const VSpace(6),
|
_EditFieldButton(
|
||||||
_FieldOperationList(cellContext,
|
cellContext: widget.cellContext,
|
||||||
() => FlowyOverlay.of(context).remove(identifier())),
|
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;
|
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);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
|
||||||
State<StatefulWidget> createState() => _EditFieldButtonState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _EditFieldButtonState extends State<_EditFieldButton> {
|
|
||||||
final popover = PopoverController();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = context.watch<AppTheme>();
|
final theme = context.watch<AppTheme>();
|
||||||
|
|
||||||
return BlocBuilder<FieldActionSheetBloc, FieldActionSheetState>(
|
return BlocBuilder<FieldActionSheetBloc, FieldActionSheetState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: GridSize.typeOptionItemHeight,
|
height: GridSize.typeOptionItemHeight,
|
||||||
child: Popover(
|
child: FlowyButton(
|
||||||
controller: popover,
|
text: FlowyText.medium(
|
||||||
targetAnchor: Alignment.topRight,
|
LocaleKeys.grid_field_editProperty.tr(),
|
||||||
followerAnchor: Alignment.topLeft,
|
fontSize: 12,
|
||||||
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(),
|
|
||||||
),
|
),
|
||||||
|
hoverColor: theme.hover,
|
||||||
|
onTap: onTap,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -70,7 +70,7 @@ class DateTypeOptionWidget extends TypeOptionWidget {
|
|||||||
targetAnchor: Alignment.topRight,
|
targetAnchor: Alignment.topRight,
|
||||||
followerAnchor: Alignment.topLeft,
|
followerAnchor: Alignment.topLeft,
|
||||||
offset: const Offset(20, 0),
|
offset: const Offset(20, 0),
|
||||||
popupBuilder: (context) {
|
popupBuilder: (popoverContext) {
|
||||||
return OverlayContainer(
|
return OverlayContainer(
|
||||||
constraints: BoxConstraints.loose(const Size(460, 440)),
|
constraints: BoxConstraints.loose(const Size(460, 440)),
|
||||||
child: DateFormatList(
|
child: DateFormatList(
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
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/presentation/widgets/header/field_editor.dart';
|
||||||
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: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';
|
||||||
@ -16,9 +18,8 @@ import 'package:styled_widget/styled_widget.dart';
|
|||||||
|
|
||||||
import '../../../application/field/field_cache.dart';
|
import '../../../application/field/field_cache.dart';
|
||||||
import '../../layout/sizes.dart';
|
import '../../layout/sizes.dart';
|
||||||
import '../header/field_editor.dart';
|
|
||||||
|
|
||||||
class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate {
|
class GridPropertyList extends StatelessWidget {
|
||||||
final String gridId;
|
final String gridId;
|
||||||
final GridFieldCache fieldCache;
|
final GridFieldCache fieldCache;
|
||||||
const GridPropertyList({
|
const GridPropertyList({
|
||||||
@ -27,20 +28,6 @@ class GridPropertyList extends StatelessWidget with FlowyOverlayDelegate {
|
|||||||
Key? key,
|
Key? key,
|
||||||
}) : super(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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
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 {
|
class _GridPropertyCell extends StatelessWidget {
|
||||||
@ -113,19 +93,27 @@ class _GridPropertyCell extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
FlowyButton _editFieldButton(AppTheme theme, BuildContext context) {
|
Widget _editFieldButton(AppTheme theme, BuildContext context) {
|
||||||
return FlowyButton(
|
return Popover(
|
||||||
text: FlowyText.medium(field.name, fontSize: 12),
|
triggerActions: PopoverTriggerActionFlags.click,
|
||||||
hoverColor: theme.hover,
|
targetAnchor: Alignment.topRight,
|
||||||
leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor),
|
followerAnchor: Alignment.topLeft,
|
||||||
onTap: () {
|
offset: const Offset(20, 0),
|
||||||
// FieldEditorPopOver.show(
|
child: FlowyButton(
|
||||||
// context,
|
text: FlowyText.medium(field.name, fontSize: 12),
|
||||||
// anchorContext: context,
|
hoverColor: theme.hover,
|
||||||
// gridId: gridId,
|
leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor),
|
||||||
// fieldName: field.name,
|
),
|
||||||
// typeOptionLoader: FieldTypeOptionLoader(gridId: gridId, field: field),
|
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),
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:app_flowy/plugins/grid/application/setting/setting_bloc.dart';
|
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: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';
|
||||||
@ -32,37 +33,6 @@ class GridSettingList extends StatelessWidget {
|
|||||||
{required this.settingContext, required this.onAction, Key? key})
|
{required this.settingContext, required this.onAction, Key? key})
|
||||||
: super(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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
|
@ -65,30 +65,47 @@ class _SettingButton extends StatelessWidget {
|
|||||||
.padding(horizontal: 3, vertical: 3),
|
.padding(horizontal: 3, vertical: 3),
|
||||||
),
|
),
|
||||||
popupBuilder: (BuildContext context) {
|
popupBuilder: (BuildContext context) {
|
||||||
return OverlayContainer(
|
return _GridSettingListPopover(settingContext: settingContext);
|
||||||
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 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;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user