show<T> static method

Future<T?> show<T>(
  1. BuildContext context, {
  2. required WidgetBuilder builder,
  3. String? title,
  4. List<Widget> actions = const [],
  5. PresentationStyle presentation = PresentationStyle.adaptive,
  6. bool barrierDismissible = true,
  7. Color? barrierColor,
  8. bool useSafeArea = true,
  9. RouteSettings? routeSettings,
  10. ShapeBorder? shape,
  11. double? maxWidth,
  12. bool useRootNavigator = true,
})

Shows an adaptive dialog and resolves with the value the content popped with, or null if it was dismissed.

presentation controls when a bottom sheet is used instead of a centered dialog (see PresentationStyle.adaptive for the default behavior). All remaining parameters map to the underlying showDialog / showModalBottomSheet calls.

Implementation

static Future<T?> show<T>(
  BuildContext context, {
  required WidgetBuilder builder,
  String? title,
  List<Widget> actions = const [],
  PresentationStyle presentation = PresentationStyle.adaptive,
  bool barrierDismissible = true,
  Color? barrierColor,
  bool useSafeArea = true,
  RouteSettings? routeSettings,
  ShapeBorder? shape,
  double? maxWidth,
  bool useRootNavigator = true,
}) {
  final width = MediaQuery.sizeOf(context).width;
  final breakpoint = PrismBreakpoint.resolve(width);
  final asBottomSheet = switch (presentation) {
    PresentationStyle.dialog => false,
    PresentationStyle.bottomSheet => true,
    PresentationStyle.adaptive => breakpoint == PrismBreakpoint.compact,
  };

  final theme = Theme.of(context);
  final resolvedBarrierColor =
      barrierColor ?? theme.colorScheme.scrim.withValues(alpha: 0.4);

  Widget content(BuildContext innerContext) => Column(
    mainAxisSize: MainAxisSize.min,
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      if (title != null)
        Padding(
          padding: EdgeInsets.only(
            bottom: context.prismTokens.spaceSm + context.prismTokens.spaceXs,
          ),
          child: Text(title, style: theme.textTheme.titleLarge),
        ),
      Flexible(child: builder(innerContext)),
      if (actions.isNotEmpty)
        Padding(
          padding: EdgeInsets.only(top: context.prismTokens.spaceMd),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              for (final action in actions)
                Padding(
                  padding: EdgeInsets.only(left: context.prismTokens.spaceSm),
                  child: action,
                ),
            ],
          ),
        ),
    ],
  );

  if (asBottomSheet) {
    return showModalBottomSheet<T>(
      context: context,
      isDismissible: barrierDismissible,
      barrierColor: resolvedBarrierColor,
      useSafeArea: useSafeArea,
      routeSettings: routeSettings,
      useRootNavigator: useRootNavigator,
      isScrollControlled: true,
      shape:
          shape ??
          const RoundedRectangleBorder(
            borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
          ),
      builder: (innerContext) => Padding(
        padding: EdgeInsets.fromLTRB(
          context.prismTokens.spaceLg - context.prismTokens.spaceXs,
          context.prismTokens.spaceLg - context.prismTokens.spaceXs,
          context.prismTokens.spaceLg - context.prismTokens.spaceXs,
          context.prismTokens.spaceLg,
        ),
        child: content(innerContext),
      ),
    );
  }

  return showDialog<T>(
    context: context,
    barrierDismissible: barrierDismissible,
    barrierColor: resolvedBarrierColor,
    useSafeArea: useSafeArea,
    routeSettings: routeSettings,
    useRootNavigator: useRootNavigator,
    builder: (innerContext) => Dialog(
      shape:
          shape ??
          RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(context.prismTokens.radiusLg),
          ),
      child: ConstrainedBox(
        constraints: BoxConstraints(maxWidth: maxWidth ?? 420),
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: content(innerContext),
        ),
      ),
    ),
  );
}