A modal dialog component for focused content and actions.
Interactive preview
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
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.
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:
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
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,
})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
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
child → Widget?
Optional. Custom dialog content rendered after the description and before the actions. When it is the only content provided, it fills the container directly.
title → String?
Optional. The dialog title text. Either child, title, or description must be provided.
description → String?
Optional. Supporting body text rendered below the title.
actions → List<Widget>?
Optional. Action widgets rendered in the dialog actions row.
modal → bool
Optional. Whether the dialog blocks interaction with background content.
semanticLabel → String?
Optional. Accessibility label for the dialog. Defaults to the title when omitted.
style → RemixDialogStyler
Optional. The style configuration for the dialog container, title, description, and actions.
styleSpec → RemixDialogSpec?
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.