fossui
Components

Dialog

A modal surface with a title, description, body, and stacked actions, as a bottom sheet or centered card.

Try it live

A dialog interrupts the flow to confirm an action or show a short message. Open it with showFossDialog, which resolves to the value you pass to Navigator.pop. The scrim, focus trap, and focus restoration come from the framework, and colors, type, radius, and shadow come from the theme.

Dialog
import 'package:fossui/fossui.dart';

final ok = await showFossDialog<bool>(
  context: context,
  builder: (context) => FossDialog(
    title: const Text('Delete project'),
    description: const Text('This cannot be undone.'),
    actions: [
      FossButton(
        variant: FossButtonVariant.ghost,
        onPressed: () => Navigator.pop(context, false),
        child: const Text('Cancel'),
      ),
      FossButton(
        onPressed: () => Navigator.pop(context, true),
        child: const Text('Delete'),
      ),
    ],
  ),
);

Slots

title and description form the header, content is the scrollable body, and actions fill the footer. Each is optional: a dialog can be a header alone, or a header with a body and no footer.

Dialog slots
showFossDialog<void>(
  context: context,
  builder: (context) => const FossDialog(
    title: Text('Saved'),
    description: Text('Your changes are live.'),
  ),
);

Actions

actions reuse FossButton and sit in a trailing-aligned row on the footer. An empty list hides the footer entirely.

Dialog actions
FossDialog(
  title: const Text('Unsaved changes'),
  description: const Text('Leave without saving?'),
  actions: [
    FossButton(
      variant: FossButtonVariant.ghost,
      onPressed: () => Navigator.pop(context),
      child: const Text('Stay'),
    ),
    FossButton(
      variant: FossButtonVariant.destructive,
      onPressed: () => Navigator.pop(context, true),
      child: const Text('Leave'),
    ),
  ],
);

footerVariant sets the footer treatment. The default bare places the actions on the plain surface; filled draws a bordered bar tinted with the muted role behind them.

Dialog filled footer
FossDialog(
  title: const Text('Invite sent'),
  footerVariant: FossDialogFooterVariant.filled,
  actions: [
    FossButton(
      onPressed: () => Navigator.pop(context),
      child: const Text('Done'),
    ),
  ],
);

Close affordance

A ghost close button sits in the top corner by default. Set showCloseButton: false to remove it, or pass closeIcon to replace the painted glyph with your own widget.

FossDialog(
  title: const Text('Terms'),
  showCloseButton: false,
  content: const TermsBody(),
);

Required action

Pass barrierDismissible: false to showFossDialog so a tap outside the surface does not close it, forcing the user to choose an action.

showFossDialog<bool>(
  context: context,
  barrierDismissible: false,
  builder: (context) => FossDialog(
    title: const Text('Confirm payment'),
    actions: [
      FossButton(
        onPressed: () => Navigator.pop(context, true),
        child: const Text('Pay'),
      ),
    ],
  ),
);

Presentation

By default the dialog opens as a full-width bottom sheet, the mobile-first choice. Pass presentation: FossDialogPresentation.centered to show a centered card clamped to a max width instead.

showFossDialog<bool>(
  context: context,
  presentation: FossDialogPresentation.centered,
  builder: (context) => FossDialog(
    title: const Text('Rename file'),
    content: const RenameForm(),
  ),
);

API

showFossDialog

PropTypeDefaultDescription
contextBuildContextrequiredThe context used to find the navigator.
builderWidgetBuilderrequiredBuilds the dialog, typically a FossDialog.
presentationFossDialogPresentationbottomSheetWhether the dialog rides up as a bottom sheet or opens as a centered card.
barrierDismissiblebooltrueWhether a tap outside the surface dismisses it.
barrierLabelString?nullAccessibility label for the scrim.
useRootNavigatorbooltrueWhether to push onto the root navigator.

Returns a Future<T?> that resolves to the value passed to Navigator.pop.

FossDialog

PropTypeDefaultDescription
titleWidget?nullThe title, rendered at the top of the header.
descriptionWidget?nullThe description, rendered below the title.
contentWidget?nullThe scrollable body between the header and the footer.
actionsList<Widget>[]The footer actions; empty hides the footer.
footerVariantFossDialogFooterVariantfilledThe footer treatment.
showCloseButtonbooltrueWhether to show the close affordance in the top corner.
closeIconWidget?nullOverrides the default painted close glyph.
closeLabelString'Close'Accessibility label for the close affordance.
semanticLabelString?nullNames the route for assistive tech. Defaults to the title text.
presentationFossDialogPresentation?nullOverrides the presentation set by the show function.
styleFossDialogStyle?nullPer-instance overrides on the theme.

FossDialogFooterVariant

bare, filled.

FossDialogPresentation

bottomSheet, centered.

Live demo

Open the interactive gallery to try slots, actions, and footer variant with live knobs.

On this page