quick_popup_manager 0.0.3
quick_popup_manager: ^0.0.3 copied to clipboard
Global popup system for Flutter without BuildContext.
🚀 Quick Popup Manager #
A powerful, global popup system for Flutter that works without BuildContext
Quick Popup Manager is a comprehensive Flutter package that provides a unified, global popup system supporting Toasts, Snackbars, Banners, Dialogs, and Bottom Sheets - all without requiring BuildContext. Perfect for use in services, controllers, background callbacks, Firebase handlers, and any framework (GetX, Bloc, Provider, etc.).
✨ Key Features #
🌍 Global System (No BuildContext Required) #
- Works from anywhere: Services, controllers, callbacks, Firebase handlers
- Framework-agnostic: Compatible with GetX, Bloc, Provider, Riverpod, and vanilla Flutter
- Simple initialization: Just add
QuickPopupNavigatorObserver()to your MaterialApp
🎨 Complete Customization #
- Colors: Background, text, icons, borders, shadows
- Typography: Title, message, subtitle, button text styles
- Layout: Padding, margin, width, height, border radius
- Buttons: Colors, padding, border radius, borders, text styles
- Borders: Width, color, style, custom borders
- Gradients: Background gradients support
- And more: Every aspect is customizable!
📱 Popup Types #
🍞 Toast Notifications
- Top, center, or bottom positioning
- Short/long duration
- Stackable toasts
- Custom animations (fade, slide, scale, spring)
- Success/Error/Warning/Info presets
🍔 Advanced Snackbars
- Top or bottom positioning
- Floating or attached modes
- Swipe to dismiss
- Queue system (one after another)
- Replace current snackbar
- Icon + title + subtitle support
🚩 Banners
- Top or bottom banners
- Auto-dismiss with custom duration
- SafeArea aware
- Close button customization
💬 Dialogs
- Standard dialogs with custom content
- Loading dialogs (global, non-blocking)
- Destructive action dialogs
- Non-dismissible dialogs
- Custom button styles
📄 Bottom Sheets
- Full height, half height, or custom height
- Drag to dismiss
- Keyboard-aware
- SafeArea aware
- Scrollable content support
- Sheet stacking support
🎭 Animation System #
- Fade - Smooth fade in/out
- Slide - From top, bottom, left, or right
- Scale - Zoom in/out effect
- Spring - Bouncy spring animation
- Custom animation curves and durations
🎨 Preset Styles #
- Success (green) - Light & dark themes
- Error (red) - Light & dark themes
- Warning (orange) - Light & dark themes
- Info (blue) - Light & dark themes
📦 Installation #
Add this to your package's pubspec.yaml file:
dependencies:
quick_popup_manager: ^0.0.1
Then import the package:
import 'package:quick_popup_manager/quick_popup_manager.dart';
🚀 Quick Start #
1. Initialize in MaterialApp #
import 'package:flutter/material.dart';
import 'package:quick_popup_manager/quick_popup_manager.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
// IMPORTANT: Add the navigator observer
navigatorObservers: [QuickPopupNavigatorObserver()],
home: HomePage(),
);
}
}
2. Use Anywhere (No BuildContext!) #
// In a service, controller, or anywhere!
class ApiService {
void handleApiResponse() {
// Show toast - no BuildContext needed!
QuickPopupManager().showSuccessToast(
message: 'Data loaded successfully!',
position: PopupPosition.top,
);
}
void handleError() {
QuickPopupManager().showErrorToast(
message: 'Failed to load data',
title: 'Error',
);
}
}
📖 Usage Examples #
Toast Notifications #
// Simple toast
QuickPopupManager().showToast(
message: 'Operation completed!',
position: PopupPosition.bottom,
);
// Success toast with preset
QuickPopupManager().showSuccessToast(
message: 'Saved successfully!',
title: 'Success',
position: PopupPosition.top,
);
// Custom styled toast
QuickPopupManager().showToast(
message: 'Custom toast!',
title: 'Custom',
icon: Icons.star,
style: PopupStyle(
backgroundColor: Colors.purple,
borderRadius: 20,
titleStyle: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
messageStyle: TextStyle(color: Colors.white),
),
animation: AnimationConfig.spring(),
);
Snackbars #
// Bottom snackbar
QuickPopupManager().showSnackbar(
message: 'Item added to cart',
title: 'Success',
icon: Icons.shopping_cart,
position: SnackbarPosition.bottom,
behavior: SnackbarBehavior.floating,
);
// Top snackbar with subtitle
QuickPopupManager().showSnackbar(
message: 'Message sent',
title: 'Notification',
subtitle: 'Your message has been delivered',
position: SnackbarPosition.top,
behavior: SnackbarBehavior.attached,
);
// Replace current snackbar
QuickPopupManager().showSnackbar(
message: 'This replaced the previous one!',
replaceCurrent: true,
);
Banners #
// Top banner
QuickPopupManager().showBanner(
message: 'New update available!',
title: 'Update',
icon: Icons.system_update,
position: PopupPosition.top,
style: PopupStyle.info(),
);
// Bottom banner with custom duration
QuickPopupManager().showBanner(
message: 'Connection restored',
position: PopupPosition.bottom,
duration: Duration(seconds: 4),
);
Dialogs #
// Simple dialog
QuickPopupManager().showDialogPopup(
title: 'Confirm Action',
message: 'Are you sure you want to proceed?',
onConfirm: () {
QuickPopupManager().showSuccessToast(message: 'Confirmed!');
},
onCancel: () {},
);
// Loading dialog
final loadingId = QuickPopupManager().showLoadingDialog(
message: 'Processing...',
);
// ... do work ...
QuickPopupManager().hideLoadingDialog(loadingId);
// Destructive dialog
QuickPopupManager().showDestructiveDialog(
title: 'Delete Item',
message: 'This action cannot be undone.',
onConfirm: () {
// Delete logic
},
confirmText: 'Delete',
);
// Custom dialog with custom content
QuickPopupManager().showDialogPopup(
title: 'Custom Dialog',
content: Column(
children: [
TextField(decoration: InputDecoration(labelText: 'Name')),
// ... more widgets
],
),
style: PopupStyle(
backgroundColor: Colors.purple.shade100,
borderRadius: 20,
padding: EdgeInsets.all(24),
),
);
Bottom Sheets #
// Half height sheet
QuickPopupManager().showBottomSheet(
title: 'Options',
message: 'Choose an option',
height: 300,
onConfirm: () {},
);
// Full height scrollable sheet
QuickPopupManager().showBottomSheet(
title: 'Items',
isScrollControlled: true,
enableDrag: true,
content: ListView.builder(
itemCount: 100,
itemBuilder: (context, index) => ListTile(
title: Text('Item $index'),
),
),
);
// Selection sheet
QuickPopupManager().showBottomSheet(
title: 'Choose an option',
content: StatefulBuilder(
builder: (context, setState) {
return Column(
children: [
RadioListTile(
title: Text('Option A'),
value: 0,
groupValue: selectedIndex,
onChanged: (value) => setState(() => selectedIndex = value),
),
// ... more options
],
);
},
),
onConfirm: () {
QuickPopupManager().showSuccessToast(
message: 'Selected: Option $selectedIndex',
);
},
);
🎨 Complete Customization #
Full Style Customization #
final customStyle = PopupStyle(
// Background & Colors
backgroundColor: Colors.purple.shade100,
backgroundGradient: LinearGradient(
colors: [Colors.purple, Colors.blue],
),
shadowColor: Colors.purple.shade200,
elevation: 12,
// Border & Shape
borderRadius: 20,
borderWidth: 2,
borderColor: Colors.purple,
borderStyle: BorderStyle.solid,
// Spacing
padding: EdgeInsets.all(24),
margin: EdgeInsets.symmetric(horizontal: 20),
width: 400,
maxWidth: 500,
// Text Styles
titleStyle: TextStyle(
color: Colors.purple.shade900,
fontSize: 24,
fontWeight: FontWeight.bold,
),
messageStyle: TextStyle(
color: Colors.purple.shade700,
fontSize: 16,
),
// Button Styles
confirmButtonColor: Colors.purple,
confirmButtonTextColor: Colors.white,
confirmButtonBorderRadius: 10,
confirmButtonPadding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
cancelButtonColor: Colors.grey.shade200,
cancelButtonTextColor: Colors.black87,
// Icon
iconColor: Colors.purple,
iconSize: 28,
);
QuickPopupManager().showDialogPopup(
title: 'Fully Customized',
message: 'Every aspect is customizable!',
style: customStyle,
);
Using copyWith for Easy Modifications #
// Start with a preset
final style = PopupStyle.success();
// Modify specific properties
final modifiedStyle = style.copyWith(
borderRadius: 20,
padding: EdgeInsets.all(32),
titleStyle: TextStyle(fontSize: 28),
);
QuickPopupManager().showToast(
message: 'Modified success style!',
style: modifiedStyle,
);
🎭 Animation Examples #
// Fade animation
QuickPopupManager().showToast(
message: 'Fade animation',
animation: AnimationConfig.fade(),
);
// Slide from top
QuickPopupManager().showToast(
message: 'Slides from top',
position: PopupPosition.top,
animation: AnimationConfig.slideFromTop(),
);
// Scale animation
QuickPopupManager().showDialogPopup(
title: 'Scale Dialog',
animation: AnimationConfig.scale(),
);
// Spring animation
QuickPopupManager().showToast(
message: 'Bouncy spring!',
animation: AnimationConfig.spring(),
);
// Custom animation
QuickPopupManager().showToast(
message: 'Custom curve',
animation: AnimationConfig(
type: AnimationType.slideFromBottom,
duration: Duration(milliseconds: 500),
curve: Curves.bounceOut,
),
);
🎯 Use Cases #
API Responses #
class ApiService {
Future<void> fetchData() async {
try {
final data = await api.getData();
QuickPopupManager().showSuccessToast(
message: 'Data loaded successfully!',
);
} catch (e) {
QuickPopupManager().showErrorToast(
message: 'Failed to load data: ${e.toString()}',
);
}
}
}
Payment Status #
void handlePaymentResult(PaymentResult result) {
if (result.success) {
QuickPopupManager().showSuccessToast(
message: 'Payment successful!',
title: 'Success',
);
} else {
QuickPopupManager().showErrorToast(
message: 'Payment failed',
title: 'Error',
);
}
}
Push Notifications #
void onPushNotificationReceived(NotificationData data) {
QuickPopupManager().showBanner(
message: data.message,
title: data.title,
icon: Icons.notifications,
position: PopupPosition.top,
);
}
Background Tasks #
void processBackgroundTask() {
final loadingId = QuickPopupManager().showLoadingDialog(
message: 'Processing...',
);
// Do work in background
processData().then((_) {
QuickPopupManager().hideLoadingDialog(loadingId);
QuickPopupManager().showSuccessToast(
message: 'Processing complete!',
);
});
}
📚 API Reference #
QuickPopupManager Methods #
Toast Methods
showToast()- Show a custom toastshowSuccessToast()- Show success toast (green)showErrorToast()- Show error toast (red)showWarningToast()- Show warning toast (orange)showInfoToast()- Show info toast (blue)
Snackbar Methods
showSnackbar()- Show a snackbar with full customization
Banner Methods
showBanner()- Show a banner notification
Dialog Methods
showDialogPopup()- Show a standard dialogshowLoadingDialog()- Show a loading dialog (returns ID)hideLoadingDialog()- Hide loading dialog by IDshowDestructiveDialog()- Show a destructive action dialog
Bottom Sheet Methods
showBottomSheet()- Show a bottom sheet with full customization
PopupStyle Properties #
See the complete customization section above for all available properties.
AnimationConfig #
AnimationConfig.fade()- Fade animationAnimationConfig.slideFromTop()- Slide from topAnimationConfig.slideFromBottom()- Slide from bottomAnimationConfig.slideFromLeft()- Slide from leftAnimationConfig.slideFromRight()- Slide from rightAnimationConfig.scale()- Scale animationAnimationConfig.spring()- Spring animationAnimationConfig()- Custom animation with full control
🔧 Advanced Features #
Queue System (Snackbars) #
// Show multiple snackbars one after another
QuickPopupManager().showSnackbar(
message: 'First message',
queue: true, // Default
);
QuickPopupManager().showSnackbar(
message: 'Second message (shows after first)',
queue: true,
);
Replace Current (Snackbars) #
QuickPopupManager().showSnackbar(
message: 'First snackbar',
);
// Replace immediately
QuickPopupManager().showSnackbar(
message: 'This replaces the first one',
replaceCurrent: true,
);
Non-Dismissible Dialogs #
QuickPopupManager().showDialogPopup(
title: 'Important',
message: 'Cannot dismiss by tapping outside',
barrierDismissible: false,
onConfirm: () {},
);
Custom Height Bottom Sheets #
QuickPopupManager().showBottomSheet(
title: 'Custom Height',
height: 400, // Exact height
content: YourCustomWidget(),
);
🎨 Preset Styles #
// Success (green)
PopupStyle.success(isDark: false)
// Error (red)
PopupStyle.error(isDark: false)
// Warning (orange)
PopupStyle.warning(isDark: false)
// Info (blue)
PopupStyle.info(isDark: false)
// Dark theme variants
PopupStyle.success(isDark: true)
PopupStyle.error(isDark: true)
// ... etc
🏗️ Architecture #
- Framework-agnostic: Works with any state management solution
- Global overlay system: Uses Flutter's overlay system for context-free operation
- Automatic initialization: Via
QuickPopupNavigatorObserver - Type-safe: Full Dart type safety
- Performant: Lightweight and optimized
🤝 Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
📝 License #
This project is licensed under the MIT License.
🙏 Acknowledgments #
Built with ❤️ for the Flutter community.
Made with Flutter 💙