pop_up_action.dart 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import 'package:flowy_infra/theme.dart';
  2. import 'package:flowy_infra_ui/flowy_infra_ui.dart';
  3. import 'package:flowy_infra_ui/style_widget/hover.dart';
  4. import 'package:flowy_infra_ui/style_widget/text.dart';
  5. import 'package:flowy_infra_ui/widget/spacing.dart';
  6. import 'package:flutter/material.dart';
  7. import 'package:provider/provider.dart';
  8. import 'package:styled_widget/styled_widget.dart';
  9. import 'package:dartz/dartz.dart' as dartz;
  10. abstract class ActionList<T extends ActionItemData> {
  11. List<T> get items;
  12. String get identifier => toString();
  13. double get maxWidth => 162;
  14. void Function(dartz.Option<T>) get selectCallback;
  15. FlowyOverlayDelegate? get delegate;
  16. void show(BuildContext buildContext, BuildContext anchorContext,
  17. {AnchorDirection anchorDirection = AnchorDirection.bottomRight}) {
  18. final widgets = items
  19. .map((action) => ActionItem<T>(
  20. action: action,
  21. onSelected: (action) {
  22. FlowyOverlay.of(buildContext).remove(identifier);
  23. selectCallback(dartz.some(action));
  24. }))
  25. .toList();
  26. double totalHeight = widgets.length * (ActionListSizes.itemHeight + ActionListSizes.padding * 2);
  27. ListOverlay.showWithAnchor(
  28. buildContext,
  29. identifier: identifier,
  30. itemCount: widgets.length,
  31. itemBuilder: (context, index) => widgets[index],
  32. anchorContext: anchorContext,
  33. anchorDirection: anchorDirection,
  34. maxWidth: maxWidth,
  35. maxHeight: totalHeight,
  36. delegate: delegate,
  37. );
  38. }
  39. }
  40. abstract class ActionItemData {
  41. Widget? get icon;
  42. String get name;
  43. }
  44. class ActionListSizes {
  45. static double itemHPadding = 10;
  46. static double itemHeight = 16;
  47. static double padding = 6;
  48. }
  49. class ActionItem<T extends ActionItemData> extends StatelessWidget {
  50. final T action;
  51. final Function(T) onSelected;
  52. const ActionItem({
  53. Key? key,
  54. required this.action,
  55. required this.onSelected,
  56. }) : super(key: key);
  57. @override
  58. Widget build(BuildContext context) {
  59. final theme = context.watch<AppTheme>();
  60. return FlowyHover(
  61. config: HoverDisplayConfig(hoverColor: theme.hover),
  62. builder: (context, onHover) {
  63. return GestureDetector(
  64. behavior: HitTestBehavior.opaque,
  65. onTap: () => onSelected(action),
  66. child: SizedBox(
  67. height: ActionListSizes.itemHeight,
  68. child: Row(
  69. children: [
  70. if (action.icon != null) action.icon!,
  71. HSpace(ActionListSizes.itemHPadding),
  72. FlowyText.medium(
  73. action.name,
  74. fontSize: 12,
  75. ),
  76. ],
  77. ),
  78. ).padding(
  79. horizontal: ActionListSizes.padding,
  80. vertical: ActionListSizes.padding,
  81. ),
  82. );
  83. },
  84. );
  85. }
  86. }