Преглед изворни кода

feat: poover anchor on the object

Vincent Chan пре 2 година
родитељ
комит
e9b215ebbd

+ 1 - 0
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart

@@ -67,6 +67,7 @@ class GridFieldCell extends StatelessWidget {
 
     FieldEditorPopOver.show(
       context,
+      anchorContext: context,
       gridId: state.gridId,
       fieldName: field.name,
       typeOptionLoader: FieldTypeOptionLoader(

+ 17 - 16
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart

@@ -113,30 +113,31 @@ class FieldEditorPopOver extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return FlowyPopover(
-      builder: (BuildContext context) {
-        return FieldEditor(
-            gridId: gridId,
-            fieldName: fieldName,
-            typeOptionLoader: typeOptionLoader,
-            key: key);
-      },
-    );
+    return FieldEditor(
+        gridId: gridId,
+        fieldName: fieldName,
+        typeOptionLoader: typeOptionLoader,
+        key: key);
   }
 
   static show(
     BuildContext context, {
+    required BuildContext anchorContext,
     required String gridId,
     required String fieldName,
     required IFieldTypeOptionLoader typeOptionLoader,
     Key? key,
   }) {
-    FlowyPopover.show(context, builder: (BuildContext context) {
-      return FieldEditorPopOver(
-          gridId: gridId,
-          fieldName: fieldName,
-          typeOptionLoader: typeOptionLoader,
-          key: key);
-    });
+    FlowyPopover.show(
+      context,
+      anchorContext: anchorContext,
+      builder: (BuildContext context) {
+        return FieldEditorPopOver(
+            gridId: gridId,
+            fieldName: fieldName,
+            typeOptionLoader: typeOptionLoader,
+            key: key);
+      },
+    );
   }
 }

+ 1 - 0
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/grid_header.dart

@@ -159,6 +159,7 @@ class CreateFieldButton extends StatelessWidget {
       hoverColor: theme.shader6,
       onTap: () => FieldEditorPopOver.show(
         context,
+        anchorContext: context,
         gridId: gridId,
         fieldName: "",
         typeOptionLoader: NewFieldTypeOptionLoader(gridId: gridId),

+ 1 - 0
frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart

@@ -171,6 +171,7 @@ class _RowDetailCell extends StatelessWidget {
   void _showFieldEditor(BuildContext context) {
     FieldEditorPopOver.show(
       context,
+      anchorContext: context,
       gridId: cellId.gridId,
       fieldName: cellId.field.name,
       typeOptionLoader: FieldTypeOptionLoader(

+ 1 - 0
frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_property.dart

@@ -121,6 +121,7 @@ class _GridPropertyCell extends StatelessWidget {
       onTap: () {
         FieldEditorPopOver.show(
           context,
+          anchorContext: context,
           gridId: gridId,
           fieldName: field.name,
           typeOptionLoader: FieldTypeOptionLoader(gridId: gridId, field: field),

+ 42 - 3
frontend/app_flowy/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_popover.dart

@@ -10,21 +10,59 @@ const _overlayContainerPadding = EdgeInsets.all(12);
 class FlowyPopover extends StatefulWidget {
   final Widget Function(BuildContext context) builder;
   final ShapeBorder? shape;
+  final Rect anchorRect;
+  final AnchorDirection? anchorDirection;
   final EdgeInsets padding;
 
   FlowyPopover({
     Key? key,
     required this.builder,
+    required this.anchorRect,
     this.shape,
     this.padding = _overlayContainerPadding,
+    this.anchorDirection,
   }) : super(key: key);
 
   static show(
     BuildContext context, {
     required Widget Function(BuildContext context) builder,
+    BuildContext? anchorContext,
+    Offset? anchorPosition,
+    AnchorDirection? anchorDirection,
+    Size? anchorSize,
+    Offset? anchorOffset,
   }) {
+    final offset = anchorOffset ?? Offset.zero;
+    Offset targetAnchorPosition = anchorPosition ?? Offset.zero;
+    Size targetAnchorSize = anchorSize ?? Size.zero;
+    if (anchorContext != null) {
+      RenderObject renderObject = anchorContext.findRenderObject()!;
+      assert(
+        renderObject is RenderBox,
+        'Unexpected non-RenderBox render object caught.',
+      );
+      final renderBox = renderObject as RenderBox;
+      targetAnchorPosition = renderBox.localToGlobal(Offset.zero);
+      targetAnchorSize = renderBox.size;
+    }
+    final anchorRect = Rect.fromLTWH(
+      targetAnchorPosition.dx + offset.dx,
+      targetAnchorPosition.dy + offset.dy,
+      targetAnchorSize.width,
+      targetAnchorSize.height,
+    );
+
     showDialog(
-        barrierColor: Colors.transparent, context: context, builder: builder);
+        barrierColor: Colors.transparent,
+        context: context,
+        builder: (BuildContext context) {
+          return FlowyPopover(
+              anchorRect: anchorRect,
+              anchorDirection: anchorDirection,
+              builder: (BuildContext context) {
+                return builder(context);
+              });
+        });
   }
 
   @override
@@ -43,8 +81,9 @@ class _FlowyPopoverState extends State<FlowyPopover> {
         type: MaterialType.transparency,
         child: CustomSingleChildLayout(
             delegate: PopoverLayoutDelegate(
-              anchorRect: const Rect.fromLTWH(0, 0, 280, 400),
-              anchorDirection: AnchorDirection.rightWithTopAligned,
+              anchorRect: widget.anchorRect,
+              anchorDirection:
+                  widget.anchorDirection ?? AnchorDirection.rightWithTopAligned,
               overlapBehaviour: OverlapBehaviour.stretch,
             ),
             child: Container(