showSnackbar static method

void showSnackbar({
  1. BuildContext? context,
  2. String? text,
  3. IconData? prefixIcon,
  4. bool showCloseIcon = true,
  5. Color? backgroundColor,
  6. Color textColor = Colors.white,
  7. Color iconColor = Colors.white,
  8. ModalWidgetBuilder? builder,
  9. Alignment position = Alignment.topCenter,
  10. Duration? duration = const Duration(seconds: 4),
  11. bool isDismissible = true,
  12. bool blockBackgroundInteraction = false,
  13. Color barrierColor = Colors.transparent,
  14. SnackbarDisplayMode displayMode = SnackbarDisplayMode.replace,
  15. String? id,
  16. int? stackLevel,
  17. double? width,
  18. Offset? offset,
  19. int maxStackedSnackbars = 3,
  20. Function? onDismissed,
  21. VoidCallback? onTap,
  22. bool showDurationTimer = true,
  23. Color? durationTimerColor,
  24. DurationIndicatorDirection durationTimerDirection = DurationIndicatorDirection.leftToRight,
  25. bool handleDurationTimerManually = false,
})

Shows a snackbar with support for multiple stacked snackbars

This method handles snackbar display differently than regular modals. Depending on the displayMode parameter, snackbars can be:

  • staggered: Multiple snackbars stack vertically with staggered animation
  • queued: Only one snackbar shows at a time, others wait in queue
  • notificationBubble: Snackbars collapse into a bubble showing count
  • replace: New snackbar replaces current one (like show)

Parameters:

  • content: The snackbar ModalContent to display
  • displayMode: How to display when snackbars are already active Defaults to SnackbarDisplayMode.replace

Example:

// Show a snackbar that stacks with others
Modal.showSnackbar(
  ModalBuilder.snackbar(
    child: Text('Notification 1'),
    displayMode: SnackbarDisplayMode.staggered,
  ),
);

// Show another snackbar - it will appear above the first
Modal.showSnackbar(
  ModalBuilder.snackbar(
    child: Text('Notification 2'),
    displayMode: SnackbarDisplayMode.staggered,
  ),
);

Shows a snackbar with flexible parameters

Can be called with simplified inline parameters for quick snackbars:

Modal.showSnackbar(
  text: 'Item saved!',
  prefixIcon: Icons.check_circle,
  backgroundColor: Colors.green,
);

Or with a custom builder for full control:

Modal.showSnackbar(
  builder: () => Container(
    decoration: BoxDecoration(...),
    child: Row(children: [...]),
  ),
  position: Alignment.topCenter,
);

Implementation

static void showSnackbar({
  BuildContext? context,
  // Simplified API parameters
  String? text,
  IconData? prefixIcon,
  bool showCloseIcon = true,
  Color? backgroundColor,
  Color textColor = Colors.white,
  Color iconColor = Colors.white,

  // Custom builder API
  ModalWidgetBuilder? builder,

  // Common parameters
  Alignment position = Alignment.topCenter,
  Duration? duration = const Duration(seconds: 4),
  bool isDismissible = true,
  bool blockBackgroundInteraction = false,
  Color barrierColor = Colors.transparent,
  SnackbarDisplayMode displayMode = SnackbarDisplayMode.replace,
  String? id,
  int? stackLevel,
  double? width,
  Offset? offset,
  int maxStackedSnackbars = 3,
  Function? onDismissed,
  VoidCallback? onTap,
  bool showDurationTimer = true,
  Color? durationTimerColor,
  DurationIndicatorDirection durationTimerDirection =
      DurationIndicatorDirection.leftToRight,
  bool handleDurationTimerManually = false,
}) {
  if (_showDebugPrints) {
    debugPrint(
        'Modal.showSnackbar called: text=$text, id=$id, position=$position');
  }

  // For staggered and notificationBubble modes, snackbars have infinite duration
  // Only queued and replace modes have auto-dismiss duration
  final effectiveDuration = (displayMode == SnackbarDisplayMode.staggered ||
          displayMode == SnackbarDisplayMode.notificationBubble)
      ? null
      : duration;

  // Check if a snackbar with this ID already exists (active or in queue)
  if (id != null && Modal.isModalActiveById(id)) {
    // debugPrint(
    //     'Modal.showSnackbar: Found existing snackbar with ID=$id, updating params');
    Modal.updateParams(
      id: id,
      // Update content if provided
      builder: builder ??
          (text != null
              ? ([_]) => _ModalContent.defaultSnackbar(
                    text: text,
                    prefixIcon: prefixIcon,
                    showSuffixIcon: showCloseIcon,
                    backgroundColor: backgroundColor,
                    textColor: textColor,
                    iconColor: iconColor,
                    position: position,
                    duration: effectiveDuration,
                    isDismissible: isDismissible,
                    barrierColor: barrierColor,
                    blockBackgroundInteraction: blockBackgroundInteraction,
                    id: id,
                    stackLevel: stackLevel,
                    width: width,
                    offset: offset,
                    displayMode: displayMode,
                    maxStackedSnackbars: maxStackedSnackbars,
                    showDurationTimer: showDurationTimer,
                    durationTimerColor: durationTimerColor,
                    durationTimerDirection: durationTimerDirection,
                  ).buildContent()
              : null),
      // Update other params
      modalPosition: position,
      autoDismissDuration: effectiveDuration,
      isDismissable: isDismissible,
      snackbarDisplayMode: displayMode,
      maxStackedSnackbars: maxStackedSnackbars,
      snackbarWidth: width,
      backgroundColor: backgroundColor,
      barrierColor: barrierColor,
      blockBackgroundInteraction: blockBackgroundInteraction,
      offset: offset,
      stackLevel: stackLevel,
    );
    return;
  }

  // Determine which API is being used
  if (text != null && builder == null) {
    // Simplified inline API
    final content = _ModalContent.defaultSnackbar(
      text: text,
      prefixIcon: prefixIcon,
      showSuffixIcon: showCloseIcon,
      backgroundColor: backgroundColor,
      textColor: textColor,
      iconColor: iconColor,
      position: position,
      duration: effectiveDuration,
      isDismissible: isDismissible,
      barrierColor: barrierColor,
      blockBackgroundInteraction: blockBackgroundInteraction,
      id: id,
      stackLevel: stackLevel,
      width: width,
      offset: offset,
      displayMode: displayMode,
      maxStackedSnackbars: maxStackedSnackbars,
      onDismissed: onDismissed,
      onTap: onTap,
      showDurationTimer: showDurationTimer,
      durationTimerColor: durationTimerColor,
      durationTimerDirection: durationTimerDirection,
    );
    _showSnackbarContent(content, displayMode);
  } else if (builder != null && text == null) {
    // Custom builder API
    final snackbarId = _generateModalId(id);

    // Wrap the builder with duration indicator if not handling manually
    final effectiveBuilder = (showDurationTimer &&
            !handleDurationTimerManually &&
            effectiveDuration != null)
        ? () => _wrapWithDurationIndicator(
              builder(),
              effectiveDuration,
              durationTimerColor,
              durationTimerDirection,
              snackbarId,
            )
        : builder;

    final content = _ModalContent(
      builder: effectiveBuilder,
      modalType: ModalType.snackbar,
      modalPosition: position,
      autoDismissDuration: effectiveDuration,
      isDismissable: isDismissible,
      // For snackbars, isSwipeable is controlled by isDismissible
      isSwipeable: isDismissible,
      snackbarDisplayMode: displayMode,
      maxStackedSnackbars: maxStackedSnackbars,
      id: snackbarId,
      stackLevel: stackLevel,
      snackbarWidth: width,
      barrierColor: barrierColor,
      blockBackgroundInteraction: blockBackgroundInteraction,
      offset: offset,
      onDismissed: onDismissed,
      onTap: onTap,
    );
    _showSnackbarContent(content, displayMode);
  } else if (builder != null && text != null) {
    throw ArgumentError(
      'Cannot specify both text and builder. Use text for simple snackbars or builder for custom UI.',
    );
  } else {
    throw ArgumentError('Must specify either text or builder parameter.');
  }
}