Skip to Content

A modal dialog component for focused content and actions.

Interactive preview

Resolving preview metadata...

When to use this

  • Confirmations: Ask users to confirm destructive or important actions
  • Focused forms: Collect a small amount of information without leaving the current screen
  • Alerts: Present information that needs immediate attention
  • Custom modal content: Render a fully custom body inside Remix dialog chrome

Basic implementation

Basic implementation
import 'package:flutter/material.dart'; import 'package:remix/remix.dart'; class DialogExample extends StatelessWidget { const DialogExample({super.key}); @override Widget build(BuildContext context) { return FortalButton( label: 'Open dialog', onPressed: () { showRemixDialog( context: context, builder: (context) => Center( child: FortalDialog( title: 'Revoke access', description: 'This application will no longer be accessible.', actions: [ FortalButton.ghost( label: 'Cancel', onPressed: () => Navigator.pop(context), ), FortalButton( label: 'Revoke access', onPressed: () => Navigator.pop(context), ), ], ), ), ); }, ); } }

Alert dialogs

Use showRemixAlertDialog for urgent or destructive confirmations. It requires a localized semantic label, keeps barrier dismissal disabled by default, moves focus into the alert, and lets Escape or platform Back cancel safely. A nested RemixDialog automatically reuses the alert semantics wrapper, so no additional configuration is needed.

Destructive alert
showRemixAlertDialog<void>( context: context, semanticLabel: 'Delete project confirmation', builder: (context) => Center( child: FortalDialog( title: 'Delete project?', description: 'This permanently deletes the project and all of its data.', actions: [ FortalButton.ghost( label: 'Cancel', onPressed: () => Navigator.pop(context), ), FortalButton( label: 'Delete project', onPressed: () => Navigator.pop(context), ), ], ), ), );

Fortal widgets

Remix includes a generated Fortal-themed widget for this component:

Fortal widget
import 'package:flutter/material.dart'; import 'package:remix/remix.dart'; class FortalDialogExample extends StatelessWidget { const FortalDialogExample({super.key}); @override Widget build(BuildContext context) { return FortalDialog( title: 'Confirm changes', description: 'Save these settings before leaving?', actions: [ FortalButton.ghost( label: 'Cancel', onPressed: () => Navigator.pop(context), ), FortalButton( label: 'Save', onPressed: () => Navigator.pop(context), ), ], ); } }

See the fortalDialogStyler source code  for all available options.

Show function

showRemixDialog
Future<T?> showRemixDialog<T>({ required BuildContext context, required WidgetBuilder builder, Color? barrierColor, bool barrierDismissible = true, String? barrierLabel, bool useRootNavigator = true, RouteSettings? routeSettings, Offset? anchorPoint, Duration transitionDuration = const Duration(milliseconds: 400), RouteTransitionsBuilder? transitionBuilder, bool requestFocus = true, TraversalEdgeBehavior? traversalEdgeBehavior, })
showRemixAlertDialog
Future<T?> showRemixAlertDialog<T>({ required BuildContext context, required WidgetBuilder builder, required String semanticLabel, Color? barrierColor, String? barrierLabel, bool barrierDismissible = false, bool useRootNavigator = true, RouteSettings? routeSettings, Offset? anchorPoint, Duration transitionDuration = const Duration(milliseconds: 400), RouteTransitionsBuilder? transitionBuilder, FocusNode? initialFocusNode, })

semanticLabel must be a non-empty, localized description of the alert. barrierColor defaults to Colors.black54. If barrierDismissible is enabled, provide a non-empty localized barrierLabel as well.

An initialFocusNode remains owned by the caller and should be attached to a focusable widget inside the alert. If it is omitted, focus uses an autofocus request or the first traversable descendant. Escape and platform Back dismiss the alert with a null result.

Constructor

Constructor
const RemixDialog({ Key? key, Widget? child, String? title, String? description, List<Widget>? actions, bool modal = true, String? semanticLabel, RemixDialogStyler style = const RemixDialogStyler.create(), RemixDialogSpec? styleSpec, })

Properties

Widget Properties

childWidget?

Optional. Custom dialog content rendered after the description and before the actions. When it is the only content provided, it fills the container directly.

titleString?

Optional. The dialog title text. Either child, title, or description must be provided.

descriptionString?

Optional. Supporting body text rendered below the title.

actionsList<Widget>?

Optional. Action widgets rendered in the dialog actions row.

Optional. Whether the dialog blocks interaction with background content.

semanticLabelString?

Optional. Accessibility label for the dialog. Defaults to the title when omitted.

styleRemixDialogStyler

Optional. The style configuration for the dialog container, title, description, and actions.

styleSpecRemixDialogSpec?

Optional. A raw resolved style spec that bypasses fluent style resolution.

Style Methods

container(BoxStyler value)

Configures the dialog container style.

title(TextStyler value)

Configures the title text style.

description(TextStyler value)

Configures the description text style.

actions(FlexBoxStyler value)

Configures the actions row style.

backgroundColor(Color value)

Sets the dialog container background color.

padding(EdgeInsetsGeometryMix value)

Sets dialog container padding.

borderRadius(BorderRadiusGeometryMix radius)

Sets dialog container border radius.

shadow(BoxShadowMix value)

Sets dialog container shadow.

wrap(WidgetModifierConfig value)

Applies widget modifiers such as clipping, opacity, or scaling.

call({Key? key, Widget? child, String? title, String? description, List<Widget>? actions, bool modal = true, String? semanticLabel})

Creates a RemixDialog widget with this style applied.

Last updated on