diff --git a/frontend/app_flowy/packages/appflowy_popover/README.md b/frontend/app_flowy/packages/appflowy_popover/README.md index 8b55e735b5..ce545e5339 100644 --- a/frontend/app_flowy/packages/appflowy_popover/README.md +++ b/frontend/app_flowy/packages/appflowy_popover/README.md @@ -1,39 +1,39 @@ - +# AppFlowy Popover + TODO: Put a short description of the package here that helps potential users know whether this package might be useful for them. ## Features -TODO: List what your package can do. Maybe include images, gifs, or videos. +> A popover is a transient view that appears above other content onscreen when you tap a control or in an area. Typically, a popover includes an arrow pointing to the location from which it emerged. Popovers can be nonmodal or modal. A nonmodal popover is dismissed by tapping another part of the screen or a button on the popover. A modal popover is dismissed by tapping a Cancel or other button on the popover. -## Getting started +Source: [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/ios/views/popovers/). -TODO: List prerequisites and provide or point to information on how to -start using the package. +- Basic popover style +- Nested popover support +- Exclusive popover API -## Usage - -TODO: Include short and useful examples for package users. Add longer examples -to `/example` folder. +## Example ```dart -const like = 'sample'; +Popover( + triggerActions: PopoverTriggerActionFlags.click, + child: TextButton(child: Text("Popover"), onPressed: () {}), + popupBuilder(BuildContext context) { + return PopoverMenu(); + }, +); ``` - -## Additional information - -TODO: Tell users more about the package: where to find more information, how to -contribute to the package, how to file issues, what response they can expect -from the package authors, and more. diff --git a/frontend/app_flowy/packages/appflowy_popover/example/lib/example_button.dart b/frontend/app_flowy/packages/appflowy_popover/example/lib/example_button.dart index 173baf823c..36f57f57fa 100644 --- a/frontend/app_flowy/packages/appflowy_popover/example/lib/example_button.dart +++ b/frontend/app_flowy/packages/appflowy_popover/example/lib/example_button.dart @@ -50,15 +50,13 @@ class _PopoverMenuState extends State { class ExampleButton extends StatelessWidget { final String label; - final Alignment targetAnchor; - final Alignment followerAnchor; final Offset? offset; + final PopoverDirection? direction; const ExampleButton({ Key? key, required this.label, - this.targetAnchor = Alignment.topLeft, - this.followerAnchor = Alignment.topLeft, + this.direction, this.offset = Offset.zero, }) : super(key: key); @@ -67,6 +65,7 @@ class ExampleButton extends StatelessWidget { return Popover( triggerActions: PopoverTriggerActionFlags.click, offset: offset, + direction: direction ?? PopoverDirection.rightWithTopAligned, child: TextButton(child: Text(label), onPressed: () {}), popupBuilder: (BuildContext context) { return PopoverMenu(); diff --git a/frontend/app_flowy/packages/appflowy_popover/example/lib/main.dart b/frontend/app_flowy/packages/appflowy_popover/example/lib/main.dart index 7ce7798acb..178b075ee6 100644 --- a/frontend/app_flowy/packages/appflowy_popover/example/lib/main.dart +++ b/frontend/app_flowy/packages/appflowy_popover/example/lib/main.dart @@ -1,3 +1,4 @@ +import 'package:appflowy_popover/popover.dart'; import 'package:flutter/material.dart'; import "./example_button.dart"; @@ -65,65 +66,60 @@ class _MyHomePageState extends State { ), body: Row(children: [ Column(children: [ - ExampleButton( + const ExampleButton( label: "Left top", - targetAnchor: Alignment.bottomLeft, - offset: const Offset(0, 10), + offset: Offset(0, 10), + direction: PopoverDirection.bottomWithLeftAligned, ), Expanded(child: Container()), - ExampleButton( + const ExampleButton( label: "Left bottom", - followerAnchor: Alignment.bottomLeft, - offset: const Offset(0, -10), + offset: Offset(0, -10), + direction: PopoverDirection.topWithLeftAligned, ), ]), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - ExampleButton( + const ExampleButton( label: "Top", - targetAnchor: Alignment.bottomCenter, - followerAnchor: Alignment.topCenter, - offset: const Offset(0, 10), + offset: Offset(0, 10), + direction: PopoverDirection.bottomWithCenterAligned, ), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, - children: [ + children: const [ ExampleButton( label: "Central", - targetAnchor: Alignment.bottomCenter, - followerAnchor: Alignment.topCenter, - offset: const Offset(0, 10), + offset: Offset(0, 10), + direction: PopoverDirection.bottomWithCenterAligned, ), ], ), ), - ExampleButton( + const ExampleButton( label: "Bottom", - targetAnchor: Alignment.topCenter, - followerAnchor: Alignment.bottomCenter, - offset: const Offset(0, -10), + offset: Offset(0, -10), + direction: PopoverDirection.topWithCenterAligned, ), ], ), ), Column( children: [ - ExampleButton( + const ExampleButton( label: "Right top", - targetAnchor: Alignment.bottomRight, - followerAnchor: Alignment.topRight, - offset: const Offset(0, 10), + offset: Offset(0, 10), + direction: PopoverDirection.bottomWithRightAligned, ), Expanded(child: Container()), - ExampleButton( + const ExampleButton( label: "Right bottom", - targetAnchor: Alignment.topRight, - followerAnchor: Alignment.bottomRight, - offset: const Offset(0, -10), + offset: Offset(0, -10), + direction: PopoverDirection.topWithRightAligned, ), ], ) diff --git a/frontend/app_flowy/packages/appflowy_popover/lib/popover.dart b/frontend/app_flowy/packages/appflowy_popover/lib/popover.dart index 1854a74998..2fc26aeb0c 100644 --- a/frontend/app_flowy/packages/appflowy_popover/lib/popover.dart +++ b/frontend/app_flowy/packages/appflowy_popover/lib/popover.dart @@ -3,6 +3,8 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +/// If multiple popovers are exclusive, +/// pass the same mutex to them. class PopoverMutex { PopoverState? state; } @@ -50,16 +52,29 @@ enum PopoverDirection { } class Popover extends StatefulWidget { - final Widget child; final PopoverController? controller; + final Offset? offset; + final Decoration? maskDecoration; + + /// The function used to build the popover. final Widget Function(BuildContext context) popupBuilder; + final int triggerActions; + + /// If multiple popovers are exclusive, + /// pass the same mutex to them. final PopoverMutex? mutex; + + /// The direction of the popover final PopoverDirection direction; + final void Function()? onClose; + /// The content area of the popover. + final Widget child; + const Popover({ Key? key, required this.child, @@ -174,17 +189,25 @@ class PopoverState extends State { } } + _buildContent(BuildContext context) { + if (widget.triggerActions == 0) { + return widget.child; + } + + return MouseRegion( + onEnter: _handleTargetPointerEnter, + child: Listener( + onPointerDown: _handleTargetPointerDown, + child: widget.child, + ), + ); + } + @override Widget build(BuildContext context) { return PopoverTarget( link: popoverLink, - child: MouseRegion( - onEnter: _handleTargetPointerEnter, - child: Listener( - onPointerDown: _handleTargetPointerDown, - child: widget.child, - ), - ), + child: _buildContent(context), ); } }