crisp_dialog 0.1.0
crisp_dialog: ^0.1.0 copied to clipboard
Production-grade Flutter dialogs with async-aware buttons, design-system theming, and a composable API.
example/lib/main.dart
import 'package:crisp_dialog/crisp_dialog.dart';
import 'package:flutter/material.dart';
void main() => runApp(const CrispDialogExampleApp());
class CrispDialogExampleApp extends StatelessWidget {
const CrispDialogExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'crisp_dialog Example',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorSchemeSeed: const Color(0xFF0057FF),
useMaterial3: true,
extensions: const [
CrispDialogTheme(
animationType: CrispAnimationType.scale,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
],
),
home: const ExamplePage(),
);
}
}
class ExamplePage extends StatelessWidget {
const ExamplePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('crisp_dialog')),
body: ListView(
padding: const EdgeInsets.all(24),
children: [
_DemoButton(
label: 'Confirm Dialog',
onPressed: () => CrispDialog.confirm(
context: context,
title: 'Delete Record',
description: 'This action cannot be undone. Are you sure?',
onConfirm: () async {
// Simulates an async operation
await Future.delayed(const Duration(seconds: 2));
},
),
),
_DemoButton(
label: 'Confirm (async error)',
onPressed: () => CrispDialog.confirm(
context: context,
title: 'Submit Payment',
description: 'Process \$49.99 charge?',
confirmText: 'Pay Now',
onConfirm: () async {
await Future.delayed(const Duration(seconds: 1));
throw Exception('Network timeout — please try again.');
},
),
),
_DemoButton(
label: 'Info Dialog',
onPressed: () => CrispDialog.info(
context: context,
title: 'App Updated',
description: 'Version 2.4.0 is now installed with new features.',
),
),
_DemoButton(
label: 'Warning Dialog',
onPressed: () => CrispDialog.warning(
context: context,
title: 'Unsaved Changes',
description:
'You have unsaved changes. Leaving now will discard them.',
confirmText: 'Discard',
onConfirm: () {},
),
),
_DemoButton(
label: 'Error Dialog',
onPressed: () => CrispDialog.error(
context: context,
title: 'Upload Failed',
description: 'The file exceeds the 25 MB size limit.',
),
),
_DemoButton(
label: 'Success (auto-dismiss)',
onPressed: () => CrispDialog.success(
context: context,
title: 'Appointment Booked',
description: 'You will receive a confirmation email shortly.',
autoDismiss: const Duration(seconds: 2),
),
),
_DemoButton(
label: 'Custom Dialog',
onPressed: () => CrispDialog.custom(
context: context,
title: 'Rate This App',
body: const Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.star, color: Colors.amber, size: 32),
Icon(Icons.star, color: Colors.amber, size: 32),
Icon(Icons.star, color: Colors.amber, size: 32),
Icon(Icons.star, color: Colors.amber, size: 32),
Icon(Icons.star_border, color: Colors.amber, size: 32),
],
),
actions: [
CrispDialogAction(
label: 'Submit',
onPressed: () async {
await Future.delayed(const Duration(seconds: 1));
},
),
CrispDialogAction(
label: 'Not Now',
style: CrispActionStyle.secondary,
),
],
),
),
],
),
);
}
}
class _DemoButton extends StatelessWidget {
final String label;
final VoidCallback onPressed;
const _DemoButton({required this.label, required this.onPressed});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: FilledButton(
onPressed: onPressed,
child: Text(label),
),
);
}
}