mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: field action sheet use popover
This commit is contained in:
@ -1,8 +1,10 @@
|
|||||||
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: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/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_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';
|
||||||
@ -15,21 +17,42 @@ import 'field_type_extension.dart';
|
|||||||
import 'field_cell_action_sheet.dart';
|
import 'field_cell_action_sheet.dart';
|
||||||
import 'field_editor.dart';
|
import 'field_editor.dart';
|
||||||
|
|
||||||
class GridFieldCell extends StatelessWidget {
|
class GridFieldCell extends StatefulWidget {
|
||||||
final GridFieldCellContext cellContext;
|
final GridFieldCellContext cellContext;
|
||||||
const GridFieldCell(this.cellContext, {Key? key}) : super(key: key);
|
const GridFieldCell(this.cellContext, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
State<StatefulWidget> createState() => _GridFieldCellState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _GridFieldCellState extends State<GridFieldCell> {
|
||||||
|
final popover = AppFlowyPopoverController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext gridCellContext) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => FieldCellBloc(cellContext: cellContext)
|
create: (context) => FieldCellBloc(cellContext: widget.cellContext)
|
||||||
..add(const FieldCellEvent.initial()),
|
..add(const FieldCellEvent.initial()),
|
||||||
child: BlocBuilder<FieldCellBloc, FieldCellState>(
|
child: BlocBuilder<FieldCellBloc, FieldCellState>(
|
||||||
// buildWhen: (p, c) => p.field != c.field,
|
// buildWhen: (p, c) => p.field != c.field,
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final button = FieldCellButton(
|
final button = AppFlowyPopover(
|
||||||
|
controller: popover,
|
||||||
|
child: FieldCellButton(
|
||||||
field: state.field,
|
field: state.field,
|
||||||
onTap: () => _showActionSheet(context),
|
onTap: () => popover.show(),
|
||||||
|
),
|
||||||
|
targetAnchor: Alignment.bottomLeft,
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const line = Positioned(
|
const line = Positioned(
|
||||||
@ -51,32 +74,6 @@ class GridFieldCell extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showActionSheet(BuildContext context) {
|
|
||||||
final state = context.read<FieldCellBloc>().state;
|
|
||||||
GridFieldCellActionSheetPopover.show(
|
|
||||||
context,
|
|
||||||
cellContext:
|
|
||||||
GridFieldCellContext(gridId: state.gridId, field: state.field),
|
|
||||||
onEdited: () => _showFieldEditor(context),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _showFieldEditor(BuildContext context) {
|
|
||||||
final state = context.read<FieldCellBloc>().state;
|
|
||||||
final field = state.field;
|
|
||||||
|
|
||||||
FieldEditorPopOver.show(
|
|
||||||
context,
|
|
||||||
anchorContext: context,
|
|
||||||
gridId: state.gridId,
|
|
||||||
fieldName: field.name,
|
|
||||||
typeOptionLoader: FieldTypeOptionLoader(
|
|
||||||
gridId: state.gridId,
|
|
||||||
field: field,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _GridHeaderCellContainer extends StatelessWidget {
|
class _GridHeaderCellContainer extends StatelessWidget {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
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/prelude.dart';
|
import 'package:app_flowy/plugins/grid/application/prelude.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
@ -9,6 +11,7 @@ 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/appflowy_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';
|
||||||
@ -16,9 +19,7 @@ import '../../layout/sizes.dart';
|
|||||||
class GridFieldCellActionSheet extends StatelessWidget
|
class GridFieldCellActionSheet extends StatelessWidget
|
||||||
with FlowyOverlayDelegate {
|
with FlowyOverlayDelegate {
|
||||||
final GridFieldCellContext cellContext;
|
final GridFieldCellContext cellContext;
|
||||||
final VoidCallback onEdited;
|
const GridFieldCellActionSheet({required this.cellContext, Key? key})
|
||||||
const GridFieldCellActionSheet(
|
|
||||||
{required this.cellContext, required this.onEdited, Key? key})
|
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -29,10 +30,7 @@ class GridFieldCellActionSheet extends StatelessWidget
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
_EditFieldButton(
|
_EditFieldButton(
|
||||||
onEdited: () {
|
cellContext: cellContext,
|
||||||
FlowyOverlay.of(context).remove(identifier());
|
|
||||||
onEdited();
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
const VSpace(6),
|
const VSpace(6),
|
||||||
_FieldOperationList(cellContext,
|
_FieldOperationList(cellContext,
|
||||||
@ -53,9 +51,17 @@ class GridFieldCellActionSheet extends StatelessWidget
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _EditFieldButton extends StatelessWidget {
|
class _EditFieldButton extends StatefulWidget {
|
||||||
final Function() onEdited;
|
final GridFieldCellContext cellContext;
|
||||||
const _EditFieldButton({required this.onEdited, Key? key}) : super(key: key);
|
const _EditFieldButton({required this.cellContext, Key? key})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _EditFieldButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EditFieldButtonState extends State<_EditFieldButton> {
|
||||||
|
final popover = AppFlowyPopoverController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -64,11 +70,33 @@ class _EditFieldButton extends StatelessWidget {
|
|||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: GridSize.typeOptionItemHeight,
|
height: GridSize.typeOptionItemHeight,
|
||||||
|
child: AppFlowyPopover(
|
||||||
|
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(
|
child: FlowyButton(
|
||||||
text: FlowyText.medium(LocaleKeys.grid_field_editProperty.tr(),
|
text: FlowyText.medium(
|
||||||
fontSize: 12),
|
LocaleKeys.grid_field_editProperty.tr(),
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
hoverColor: theme.hover,
|
hoverColor: theme.hover,
|
||||||
onTap: onEdited,
|
onTap: () => popover.show(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -200,20 +228,3 @@ extension _FieldActionExtension on FieldAction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridFieldCellActionSheetPopover {
|
|
||||||
static show(
|
|
||||||
BuildContext context, {
|
|
||||||
required GridFieldCellContext cellContext,
|
|
||||||
required VoidCallback onEdited,
|
|
||||||
}) {
|
|
||||||
FlowyPopover.show(context,
|
|
||||||
anchorContext: context,
|
|
||||||
anchorDirection: AnchorDirection.bottomWithLeftAligned,
|
|
||||||
constraints: BoxConstraints.loose(const Size(240, 200)),
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return GridFieldCellActionSheet(
|
|
||||||
cellContext: cellContext, onEdited: onEdited);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -36,6 +36,13 @@ packages:
|
|||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "0.0.2"
|
version: "0.0.2"
|
||||||
|
appflowy_popover:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "packages/appflowy_popover"
|
||||||
|
relative: true
|
||||||
|
source: path
|
||||||
|
version: "0.0.1"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1480,5 +1487,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "8.1.0"
|
version: "8.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.17.0 <3.0.0"
|
dart: ">=2.17.6 <3.0.0"
|
||||||
flutter: ">=3.0.0"
|
flutter: ">=3.0.0"
|
||||||
|
@ -41,6 +41,8 @@ dependencies:
|
|||||||
path: packages/appflowy_board
|
path: packages/appflowy_board
|
||||||
appflowy_editor:
|
appflowy_editor:
|
||||||
path: packages/appflowy_editor
|
path: packages/appflowy_editor
|
||||||
|
appflowy_popover:
|
||||||
|
path: packages/appflowy_popover
|
||||||
flutter_quill:
|
flutter_quill:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/appflowy/flutter-quill.git
|
url: https://github.com/appflowy/flutter-quill.git
|
||||||
|
Reference in New Issue
Block a user