defaultDialog<T> method

Future<T?> defaultDialog<T>({
  1. String title = "Alert",
  2. EdgeInsetsGeometry? titlePadding,
  3. TextStyle? titleStyle,
  4. Widget? content,
  5. String? id,
  6. EdgeInsetsGeometry? contentPadding,
  7. VoidCallback? onConfirm,
  8. VoidCallback? onCancel,
  9. VoidCallback? onCustom,
  10. Color? cancelTextColor,
  11. Color? confirmTextColor,
  12. String? textConfirm,
  13. String? textCancel,
  14. String? textCustom,
  15. Widget? confirm,
  16. Widget? cancel,
  17. Widget? custom,
  18. Color? backgroundColor,
  19. bool barrierDismissible = true,
  20. Color? buttonColor,
  21. String middleText = "\n",
  22. TextStyle? middleTextStyle,
  23. double radius = 20.0,
  24. List<Widget>? actions,
  25. PopInvokedWithResultCallback<T>? onWillPop,
  26. bool canPop = true,
  27. GlobalKey<NavigatorState>? navigatorKey,
  28. Offset? anchorPoint,
  29. TraversalEdgeBehavior? traversalEdgeBehavior,
  30. bool scrollable = false,
})

Custom UI Dialog.

Besides the cancel and confirm buttons, a third action can be added: pass custom to render your own action widget, or use textCustom and/or onCustom to render a default-styled button labeled textCustom (defaults to "Custom") that invokes onCustom when tapped. Like the confirm button, the custom button does not close the dialog by itself; close it from your callback if desired. For custom body content use content instead.

Set canPop to false to block the system back gesture/button from dismissing the dialog; it can then only be closed programmatically (e.g. Get.back() from one of its actions). onWillPop is still invoked for every pop attempt, with didPop false when the pop was blocked.

Implementation

Future<T?> defaultDialog<T>({
  String title = "Alert",
  EdgeInsetsGeometry? titlePadding,
  TextStyle? titleStyle,
  Widget? content,
  String? id,
  EdgeInsetsGeometry? contentPadding,
  VoidCallback? onConfirm,
  VoidCallback? onCancel,
  VoidCallback? onCustom,
  Color? cancelTextColor,
  Color? confirmTextColor,
  String? textConfirm,
  String? textCancel,
  String? textCustom,
  Widget? confirm,
  Widget? cancel,
  Widget? custom,
  Color? backgroundColor,
  bool barrierDismissible = true,
  Color? buttonColor,
  String middleText = "\n",
  TextStyle? middleTextStyle,
  double radius = 20.0,
  List<Widget>? actions,
  PopInvokedWithResultCallback<T>? onWillPop,
  bool canPop = true,
  GlobalKey<NavigatorState>? navigatorKey,
  Offset? anchorPoint,
  TraversalEdgeBehavior? traversalEdgeBehavior,
  bool scrollable = false,
}) {
  var leanCancel = onCancel != null || textCancel != null;
  var leanConfirm = onConfirm != null || textConfirm != null;
  var leanCustom = onCustom != null || textCustom != null;
  actions ??= [];

  if (cancel != null) {
    actions.add(cancel);
  } else {
    if (leanCancel) {
      actions.add(
        TextButton(
          style: TextButton.styleFrom(
            tapTargetSize: MaterialTapTargetSize.shrinkWrap,
            padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
            shape: RoundedRectangleBorder(
              side: BorderSide(
                color: buttonColor ?? theme.colorScheme.secondary,
                width: 2,
                style: BorderStyle.solid,
              ),
              borderRadius: BorderRadius.circular(radius),
            ),
          ),
          onPressed: () {
            if (onCancel == null) {
              closeAllDialogs();
            } else {
              onCancel.call();
            }
          },
          child: Text(
            textCancel ?? "Cancel",
            style: TextStyle(
              color: cancelTextColor ?? theme.colorScheme.secondary,
            ),
          ),
        ),
      );
    }
  }
  if (confirm != null) {
    actions.add(confirm);
  } else {
    if (leanConfirm) {
      actions.add(
        TextButton(
          style: TextButton.styleFrom(
            tapTargetSize: MaterialTapTargetSize.shrinkWrap,
            backgroundColor: buttonColor ?? theme.colorScheme.secondary,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(radius),
            ),
          ),
          child: Text(
            textConfirm ?? "Ok",
            style: TextStyle(
              color: confirmTextColor ?? theme.colorScheme.surface,
            ),
          ),
          onPressed: () {
            onConfirm?.call();
          },
        ),
      );
    }
  }
  if (custom != null) {
    actions.add(custom);
  } else {
    if (leanCustom) {
      actions.add(
        TextButton(
          style: TextButton.styleFrom(
            tapTargetSize: MaterialTapTargetSize.shrinkWrap,
            backgroundColor: buttonColor ?? theme.colorScheme.secondary,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(radius),
            ),
          ),
          child: Text(
            textCustom ?? "Custom",
            style: TextStyle(
              color: confirmTextColor ?? theme.colorScheme.surface,
            ),
          ),
          onPressed: () {
            onCustom?.call();
          },
        ),
      );
    }
  }

  Widget baseAlertDialog = Builder(
    builder: (context) {
      return AlertDialog(
        titlePadding: titlePadding ?? const EdgeInsets.all(8),
        contentPadding: contentPadding ?? const EdgeInsets.all(8),
        scrollable: scrollable,

        backgroundColor:
            backgroundColor ?? DialogTheme.of(context).backgroundColor,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.all(Radius.circular(radius)),
        ),
        title: Text(title, textAlign: TextAlign.center, style: titleStyle),
        content: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisSize: MainAxisSize.min,
          children: [
            content ??
                Text(
                  middleText,
                  textAlign: TextAlign.center,
                  style: middleTextStyle,
                ),
            const SizedBox(height: 16),
            ButtonTheme(
              minWidth: 78.0,
              height: 34.0,
              child: Wrap(
                alignment: WrapAlignment.center,
                spacing: 8,
                runSpacing: 8,
                children: actions!,
              ),
            ),
          ],
        ),
        // actions: actions, // ?? <Widget>[cancelButton, confirmButton],
        buttonPadding: EdgeInsets.zero,
      );
    },
  );

  return dialog<T>(
    (onWillPop != null || !canPop)
        ? PopScope<T>(
            canPop: canPop,
            onPopInvokedWithResult: (didPop, result) =>
                onWillPop?.call(didPop, result),
            child: baseAlertDialog,
          )
        : baseAlertDialog,
    barrierDismissible: barrierDismissible,
    navigatorKey: navigatorKey,
    anchorPoint: anchorPoint,
    traversalEdgeBehavior: traversalEdgeBehavior,
    id: id,
  );
}