diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b08161..d9fa7c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [2.1.0] - 04/03/2025 + +- **BREAKING CHANGES!**: added dialog context to `confirmBtnTap` and `cancelBtnTap` functions. Signatures now are: +```dart +void Function(BuildContext context); +``` +- Added `PopScope` widget with `canPop` to prevent unwanted navigation while dialog is showing. +- Updated README + ## [2.0.1] - 06/03/2023 - Updated README diff --git a/README.md b/README.md index 905ce20..2c3e5c0 100644 --- a/README.md +++ b/README.md @@ -22,37 +22,56 @@ CoolAlert.show( ); ``` - ### CoolAlert Class +| Attribute | Data type | Description | Default Value | +|:---------------------|:-----------------------------|:---------------------------------------------------------------------------------|:-------------------------------------------------------------------------:| +| context | BuildContext | @required | Null | +| type | CoolAlertType | @required - Type of alert dialog, ex: CoolAlertType.success for success dialogs | Null | +| title | String | Set a custom title for dialog | Based on the CoolAlertType selected | +| text | String | Set the description text of the dialog. | Null | +| widget | Widget | Set any you expect widget of the dialog. | Null | +| confirmBtnText | String | Text of confirm button | 'Ok' | +| confirmBtnTap | void Function(BuildContext)? | Function that handle click of confirm button, provides dialog context parameter. | (c) => Navigator.pop(c) | +| confirmBtnColor | Color | Color of confirm Button | Theme.of(context).primaryColor | +| cancelBtnText | String | Text of cancel button | 'Cancel' | +| cancelBtnTap | void Function(BuildContext)? | Function that handle click of cancel button, provides dialog context parameter. | (c) => Navigator.pop(c) | +| barrierDismissible | bool | Dismiss dialog on touch overlay | true | +| animType | CoolAlertAnimType | Type of dialogue enter animation | CoolAlertAnimType.scale | +| backgroundColor | Color | Background color of the animation | Color(0xFF515C6F) | +| confirmBtnTextStyle | TextStyle | Confirm button text theme | TextStyle(color: Colors.white, fontWeight:FontWeight.w600,fontSize: 18.0) | +| cancelBtnTextStyle | TextStyle | Cancel button text theme | TextStyle(color: Colors.grey, fontWeight:FontWeight.w600,fontSize: 18.0) | +| flareAsset | String | Custom flare asset | "animation.flr" | +| flareAnimationName | String | The name of the flare animation to play | "play" | +| lottieAsset | String | Custom lottie asset | "animation.json" | +| autoCloseDuration | Duration | Determines how long the dialog stays open for before closing | Null | +| width | double | Dialog width | MediaQuery.of(context).size.width | +| loopAnimation | boolean | Determines if the animation should loop or not | false | +| closeOnConfirmBtnTap | boolean | Detemines if dialog closes when the confirm button is tapped | true | +| reverseBtnOrder | boolean | Reverse the order of the buttons | false | +| canPop | boolean | Prevents undesired navigation unless explicitly desired. | true | +| onPopInvoked | void Function(bool)? | Notifies of whether the context was popped with `didPop` parameter | Null | + +### Popping the dialog + +To pop the dialog from one of the buttons, you have the following options. + +1. Using `closeOnConfirmBtnTap: true` will automatically pop the dialog when the confirm button is tapped. +2. Using `confirmBtnTap` or `cancelBtnTap` functions to pop the dialog manually. This should be done with the context provided (see notes below) +```dart +CoolAlert.show( + context: context, + type: CoolAlertType.success, + text: "Your transaction was successful!", + confirmBtnTap: (dialogContext) { + Navigator.pop(dialogContext); + } +); +``` +**Notes:** -| Attribute | Data type | Description | Default Value | -|:----------------------|:-------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------:| -| context| BuildContext | @required | Null | -| type | CoolAlertType | @required - Type of alert dialog, ex: CoolAlertType.success for success dialogs | Null -title| String | Set a custom title for dialog | Based on the CoolAlertType selected| | -| text| String | Set the description text of the dialog. | Null | -| widget| Widget | Set any you expect widget of the dialog. | Null | -| confirmBtnText | String | Text of confirm button | 'Ok' | | -| confirmBtnTap| Function | Function that handle click of confirm button | () => Navigator.pop(context)| -| confirmBtnColor| Color | Color of confirm Button | Theme.of(context).primaryColor | | -| cancelBtnText| String | Text of cancel button | 'Cancel' | -| cancelBtnTap| Function | Function that handle click of cancel button | () => Navigator.pop(context) -| barrierDismissible| bool | Dismiss dialog on touch overlay | true -| animType | CoolAlertAnimType| Type of dialogue enter animation | CoolAlertAnimType.scale| -| backgroundColor | Color| Background color of the animation | Color(0xFF515C6F)| -| confirmBtnTextStyle | TextStyle | Confirm button text theme | TextStyle(color: Colors.white, fontWeight:FontWeight.w600,fontSize: 18.0)| -| cancelBtnTextStyle | TextStyle | Cancel button text theme | TextStyle(color: Colors.grey, fontWeight:FontWeight.w600,fontSize: 18.0)| -| flareAsset | String | Custom flare asset | "animation.flr" | -| flareAnimationName | String | The name of the flare animation to play | "play" | -| lottieAsset | String | Custom lottie asset | "animation.json" | -|autoCloseDuration|Duration|Determines how long the dialog stays open for before closing|Null| -|width|double|Dialog width|MediaQuery.of(context).size.width| -|loopAnimation|boolean|Determines if the animation should loop or not|false| -|closeOnConfirmBtnTap|boolean|Detemines if dialog closes when the confirm button is tapped|true| -|reverseBtnOrder|boolean|Reverse the order of the buttons|false| - - +- if you have have `closeOnConfirmBtnTap: true` while calling `Navigator.pop(dialogContext)` in the above example, you'll pop twice and may run into some issues. Have either one or the other. +- If you have `autoCloseDuration` set, this is a wrapper for `Navigator.pop(coolAlertParentContext, rootNavigator: true)` after the duration is up. In the above example, if the user taps "confirm" and the dialog auto closes, it will pop twice and you may run into issues. diff --git a/example/lib/main.dart b/example/lib/main.dart index 0e5bccb..174925b 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -138,7 +138,7 @@ class _MyHomePageState extends State { onChanged: (value) => message = value, ), closeOnConfirmBtnTap: false, - onConfirmBtnTap: () async { + onConfirmBtnTap: (_) async { if (message.length < 5) { await CoolAlert.show( context: context, @@ -163,6 +163,33 @@ class _MyHomePageState extends State { color: Colors.orange, ); + final unpoppableAlert = _buildButton( + onTap: () { + CoolAlert.show( + context: context, + type: CoolAlertType.custom, + text: 'You cannot pop this alert except with Navigator(root) pop', + // closeOnConfirmBtnTap: false, + canPop: false, + closeOnConfirmBtnTap: false, + onPopInvoked: (didPop) { + print('Pop invoked, has page been popped? $didPop'); + }, + confirmBtnText: "Pop with dialog context", + onConfirmBtnTap: (context) { + print("Confirm tapped"); + }, + showCancelBtn: true, + cancelBtnText: "Pop with root context", + onCancelBtnTap: (context) { + Navigator.of(context).pop(); + }, + ); + }, + text: 'Unpoppable', + color: Colors.blue, + ); + return Scaffold( appBar: AppBar( title: Text(widget.title), @@ -179,6 +206,7 @@ class _MyHomePageState extends State { confirmAlert, loadingAlert, customAlert, + unpoppableAlert, ], ), ), diff --git a/lib/cool_alert.dart b/lib/cool_alert.dart index a4c6589..a8ca473 100644 --- a/lib/cool_alert.dart +++ b/lib/cool_alert.dart @@ -43,11 +43,11 @@ class CoolAlert { /// Barrier Dissmisable bool barrierDismissible = true, - // Triggered when confirm button is tapped - VoidCallback? onConfirmBtnTap, + /// Triggered when confirm button is tapped, [BuildContext] parameter is scoped to the dialog + void Function(BuildContext)? onConfirmBtnTap, - /// Triggered when cancel button is tapped - VoidCallback? onCancelBtnTap, + /// Triggered when cancel button is tapped, [BuildContext] parameter is scoped to the dialog + void Function(BuildContext)? onCancelBtnTap, /// Confirmation button text String confirmBtnText = 'Ok', @@ -105,6 +105,14 @@ class CoolAlert { /// When it is false, you will have to close it manually by using Navigator.of(context).pop(); bool closeOnConfirmBtnTap = true, + /// Determines if the dialog can be popped, a wrapper for [PopScope.canPop]. + /// If false, the dialog will not be popped. + bool canPop = true, + + /// Triggered when the dialog is popped, a wrapper for [PopScope.onPopInvoked]. + /// [bool] parameter indicates if the dialog has been popped. + void Function(bool)? onPopInvoked, + /// Reverse the order of the buttons bool reverseBtnOrder = false, }) { @@ -143,7 +151,7 @@ class CoolAlert { reverseBtnOrder: reverseBtnOrder, ); - final child = AlertDialog( + final dialog = AlertDialog( contentPadding: EdgeInsets.zero, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(borderRadius), @@ -153,6 +161,12 @@ class CoolAlert { ), ); + final child = PopScope( + canPop: canPop, + onPopInvoked: onPopInvoked, + child: dialog, + ); + return showGeneralDialog( barrierColor: Colors.black.withOpacity(0.5), transitionBuilder: (context, anim1, __, widget) { diff --git a/lib/src/models/cool_alert_options.dart b/lib/src/models/cool_alert_options.dart index 94a82a3..541eeb5 100644 --- a/lib/src/models/cool_alert_options.dart +++ b/lib/src/models/cool_alert_options.dart @@ -8,8 +8,8 @@ class CoolAlertOptions { CoolAlertType type; CoolAlertAnimType? animType; bool? barrierDismissible = false; - VoidCallback? onConfirmBtnTap; - VoidCallback? onCancelBtnTap; + void Function(BuildContext)? onConfirmBtnTap; + void Function(BuildContext)? onCancelBtnTap; String? confirmBtnText; String? cancelBtnText; Color? confirmBtnColor; diff --git a/lib/src/widgets/cool_alert_buttons.dart b/lib/src/widgets/cool_alert_buttons.dart index 75a16bd..967cdda 100644 --- a/lib/src/widgets/cool_alert_buttons.dart +++ b/lib/src/widgets/cool_alert_buttons.dart @@ -38,7 +38,7 @@ class CoolAlertButtons extends StatelessWidget { isOkayBtn: true, text: options.confirmBtnText!, onTap: () { - options.onConfirmBtnTap?.call(); + options.onConfirmBtnTap?.call(context); // If autoCloseDuration is NOT null, it means the dialg will be auto closed, so disable confirm button tap if (options.autoCloseDuration != null) { @@ -66,7 +66,7 @@ class CoolAlertButtons extends StatelessWidget { isOkayBtn: false, text: options.cancelBtnText!, onTap: () { - options.onCancelBtnTap?.call(); + options.onCancelBtnTap?.call(context); Navigator.pop(context); }, );