crisp_dialog
Production-grade Flutter dialogs with async-aware buttons, design-system theming, and a composable API.
await CrispDialog.confirm(
context: context,
title: 'Delete Record',
description: 'This cannot be undone.',
onConfirm: () async {
await api.deleteRecord(id);
},
);
When onConfirm returns a Future, the button automatically shows a spinner, disables sibling buttons, and handles errors inline — no wrapper code needed.
Features
- Async-aware buttons — return a
Futurefrom any callback and the dialog handles loading/error states automatically. - Design-system theming — global styling via
ThemeExtension. Set once inMaterialApp, applied everywhere. - Composable API — named static methods (
confirm,info,warning,error,success,custom) instead of a single god-object constructor. - Zero dependencies — no Lottie, no Rive, no animation libs. Headers are widget slots — bring your own.
- Inline error display — async failures show an error message inside the dialog. No crash, no auto-dismiss. Users can retry.
- Light & dark presets —
CrispDialogTheme.light()and.dark()for quick setup.
Installation
dependencies:
crisp_dialog: ^0.1.0
import 'package:crisp_dialog/crisp_dialog.dart';
Dialog Types
Confirm
Two-button dialog for confirm/cancel flows.
await CrispDialog.confirm(
context: context,
title: 'Submit Payment',
description: 'Process \$49.99 charge?',
confirmText: 'Pay Now',
cancelText: 'Cancel',
onConfirm: () async {
await paymentService.charge(amount);
},
);
Info
Single-button informational dialog.
await CrispDialog.info(
context: context,
title: 'App Updated',
description: 'Version 2.4.0 installed.',
);
Warning
Confirm/cancel with warning styling.
await CrispDialog.warning(
context: context,
title: 'Unsaved Changes',
description: 'Leaving will discard your work.',
confirmText: 'Discard',
);
Error
Single dismiss button with error styling.
await CrispDialog.error(
context: context,
title: 'Upload Failed',
description: 'File exceeds the 25 MB limit.',
);
Success
Auto-dismisses after a duration, or shows a button.
await CrispDialog.success(
context: context,
title: 'Appointment Booked',
autoDismiss: const Duration(seconds: 2),
);
Custom
Full control — bring your own body and actions.
await CrispDialog.custom(
context: context,
title: 'Rate This App',
body: StarRatingWidget(),
actions: [
CrispDialogAction(label: 'Submit', onPressed: () async { ... }),
CrispDialogAction(label: 'Later', style: CrispActionStyle.secondary),
],
);
Async Button Behavior
When any action callback returns a Future:
- The button shows a
CircularProgressIndicatorin place of its label. - All sibling buttons are disabled.
- On success → dialog auto-dismisses (if
autoDismiss: true). - On failure → an inline error message appears below the buttons. The dialog stays open so the user can retry.
- The error is clearable with a tap.
Theming
Global Theme (recommended)
MaterialApp(
theme: ThemeData(
extensions: [
CrispDialogTheme(
borderRadius: BorderRadius.circular(20),
animationType: CrispAnimationType.slideUp,
primaryButtonTheme: CrispButtonTheme(
backgroundColor: Color(0xFF0057FF),
),
),
],
),
);
Presets
// Light preset
ThemeData(extensions: [CrispDialogTheme.light()])
// Dark preset
ThemeData(extensions: [CrispDialogTheme.dark()])
Per-Dialog Override
await CrispDialog.confirm(
context: context,
title: 'Override',
theme: CrispDialogTheme(
animationType: CrispAnimationType.fade,
),
);
Theme resolution order: per-dialog override → global ThemeExtension → built-in defaults.
Animation Types
| Type | Description |
|---|---|
CrispAnimationType.scale |
Scale up from center (default) |
CrispAnimationType.slideUp |
Slide up from bottom |
CrispAnimationType.slideRight |
Slide in from left |
CrispAnimationType.fade |
Fade in |
Custom Headers
The header is a widget slot — pass any widget you want:
await CrispDialog.success(
context: context,
title: 'Booked!',
header: LottieBuilder.asset('assets/success.json'),
);
Requirements
- Flutter >= 3.10.0
- Dart >= 3.0.0
- Zero runtime dependencies
License
MIT
Libraries
- crisp_dialog
- Production-grade Flutter dialogs with async-aware buttons, design-system theming, and a composable API.