showCustom<T> static method

Future<T?> showCustom<T>({
  1. required BuildContext context,
  2. required String headerTitle,
  3. required Widget child,
  4. Color? headerColor,
  5. Color? headerTextColor,
  6. String? primaryButtonText,
  7. String? secondaryButtonText,
  8. VoidCallback? onPrimaryPressed,
  9. VoidCallback? onSecondaryPressed,
  10. Color? primaryButtonColor,
  11. Color? secondaryButtonColor,
  12. bool showCloseButton = true,
  13. VoidCallback? onClose,
  14. bool barrierDismissible = true,
  15. DialogAnimationDirection? startAnimation,
  16. DialogAnimationDirection? endAnimation,
  17. double? blur,
  18. ImageFilter? backdropFilter,
})

Shows a custom dialog with header bar and close button outside the box.

This dialog style features:

  • Close button positioned outside (top-left) the dialog
  • A colored header with title
  • Custom content area (your widget)
  • Primary and optional secondary action buttons

Example:

SavePointsDialog.showCustom(
  context,
  headerTitle: 'Payment Details',
  headerColor: Colors.deepPurple,
  primaryButtonText: 'Confirm',
  secondaryButtonText: 'Cancel',
  child: YourCustomContent(),
);

Implementation

static Future<T?> showCustom<T>({
  required BuildContext context,
  required String headerTitle,
  required Widget child,
  Color? headerColor,
  Color? headerTextColor,
  String? primaryButtonText,
  String? secondaryButtonText,
  VoidCallback? onPrimaryPressed,
  VoidCallback? onSecondaryPressed,
  Color? primaryButtonColor,
  Color? secondaryButtonColor,
  bool showCloseButton = true,
  VoidCallback? onClose,
  bool barrierDismissible = true,
  DialogAnimationDirection? startAnimation,
  DialogAnimationDirection? endAnimation,
  double? blur,
  ImageFilter? backdropFilter,
}) {
  // Dismiss keyboard when showing dialog
  _dismissKeyboard(context);

  final theme = Theme.of(context);
  final isDark = theme.brightness == Brightness.dark;

  final ImageFilter? barrierFilter =
      backdropFilter ??
      (blur != null && blur <= 0
          ? null
          : ImageFilter.blur(sigmaX: blur ?? 20.0, sigmaY: blur ?? 20.0));
  final useBarrierBlur = barrierFilter != null;

  return showGeneralDialog<T>(
    context: context,
    barrierDismissible: barrierDismissible,
    barrierLabel: 'Close dialog',
    barrierColor: useBarrierBlur ? Colors.transparent : Colors.black54,
    transitionDuration: const Duration(milliseconds: 350),
    pageBuilder: (_, _, _) => const SizedBox.shrink(),
    transitionBuilder: (context, animation, secondaryAnimation, _) {
      final dialog = HeaderDialog(
        headerTitle: headerTitle,
        headerColor: headerColor,
        headerTextColor: headerTextColor,
        primaryButtonText: primaryButtonText,
        secondaryButtonText: secondaryButtonText,
        onPrimaryPressed: onPrimaryPressed,
        onSecondaryPressed: onSecondaryPressed,
        primaryButtonColor: primaryButtonColor,
        secondaryButtonColor: secondaryButtonColor,
        showCloseButton: showCloseButton,
        onClose: onClose,
        isDark: isDark,
        blur: blur,
        backdropFilter: backdropFilter,
        child: child,
      );

      final transitionedDialog = DialogTransitionBuilder(
        animation: animation,
        startAnimation: startAnimation,
        endAnimation: endAnimation,
        dialog: dialog,
      );

      if (useBarrierBlur) {
        return Stack(
          fit: StackFit.expand,
          children: [
            RepaintBoundary(
              child: AnimatedBuilder(
                animation: animation,
                builder: (context, child) {
                  return Opacity(opacity: animation.value, child: child);
                },
                child: GestureDetector(
                  onTap: barrierDismissible
                      ? () => Navigator.of(context).pop()
                      : null,
                  child: ClipRect(
                    child: BackdropFilter(
                      filter: barrierFilter,
                      child: Container(color: const Color(0x40000000)),
                    ),
                  ),
                ),
              ),
            ),
            Center(child: transitionedDialog),
          ],
        );
      }

      return Center(child: transitionedDialog);
    },
  );
}