quick_popup_manager 0.0.1 copy "quick_popup_manager: ^0.0.1" to clipboard
quick_popup_manager: ^0.0.1 copied to clipboard

A powerful, global popup system for Flutter that works without BuildContext. Supports Toasts, Snackbars, Banners, Dialogs, and Bottom Sheets with comprehensive customization, animations, and framework [...]

example/lib/main.dart

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> {
  final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();

  @override
  void initState() {
    super.initState();
    // Initialize after first frame
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (_navigatorKey.currentState != null && 
          _navigatorKey.currentState!.overlay != null) {
        QuickPopupManager().initialize(_navigatorKey.currentState!.overlay!);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Quick Popup Manager Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      // IMPORTANT: Add the navigator observer to enable global popups
      navigatorObservers: [QuickPopupNavigatorObserver()],
      navigatorKey: _navigatorKey,
      builder: (context, child) {
        // Ensure initialization on every build (synchronously)
        final navigator = Navigator.maybeOf(context, rootNavigator: true);
        if (navigator != null && navigator.overlay != null) {
          QuickPopupManager().initialize(navigator.overlay!);
        }
        return child ?? const SizedBox();
      },
      home: const HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Quick Popup Manager'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          _buildSection(
            title: '🍞 Toast Notifications',
            description: 'No BuildContext needed!',
            children: [
              _buildButton(
                'Success Toast (Top)',
                Icons.check_circle,
                Colors.green,
                () => QuickPopupManager().showSuccessToast(

                  message: 'Operation completed successfully!',
                  title: 'Success',
                  position: PopupPosition.top,
                ),
              ),
              _buildButton(
                'Error Toast (Bottom)',
                Icons.error,
                Colors.red,
                () => QuickPopupManager().showErrorToast(
                  message: 'Something went wrong!',
                  title: 'Error',
                  position: PopupPosition.bottom,
                ),
              ),
              _buildButton(
                'Warning Toast (Center)',
                Icons.warning,
                Colors.orange,
                () => QuickPopupManager().showWarningToast(
                  message: 'Please check your input',
                  title: 'Warning',
                  position: PopupPosition.center,
                ),
              ),
              _buildButton(
                'Info Toast',
                Icons.info,
                Colors.blue,
                () => QuickPopupManager().showInfoToast(
                  message: 'New features available',
                  title: 'Info',
                ),
              ),
              _buildButton(
                'Custom Toast',
                Icons.star,
                Colors.purple,
                () => QuickPopupManager().showToast(
                  message: 'Custom styled toast!',
                  title: 'Custom',
                  icon: Icons.star,
                  position: PopupPosition.top,
                  style: PopupStyle(
                    backgroundColor: Colors.purple,
                    borderRadius: 20,
                    titleStyle: const TextStyle(
                      color: Colors.white,
                      fontWeight: FontWeight.bold,
                    ),
                    messageStyle: const TextStyle(color: Colors.white),
                  ),
                  animation: const AnimationConfig.spring(),
                ),
              ),
            ],
          ),
          const SizedBox(height: 24),
          _buildSection(
            title: '🍔 Snackbars',
            description: 'Top/Bottom, Floating/Attached, Swipe to dismiss',
            children: [
              _buildButton(
                'Bottom Snackbar (Floating)',
                Icons.message,
                Colors.blue,
                () => QuickPopupManager().showSnackbar(
                  message: 'Item added to cart',
                  title: 'Success',
                  icon: Icons.shopping_cart,
                  position: SnackbarPosition.bottom,
                  behavior: SnackbarBehavior.floating,
                ),
              ),
              _buildButton(
                'Top Snackbar (Attached)',
                Icons.arrow_upward,
                Colors.teal,
                () => QuickPopupManager().showSnackbar(
                  message: 'Message sent',
                  title: 'Notification',
                  subtitle: 'Your message has been delivered',
                  icon: Icons.send,
                  position: SnackbarPosition.top,
                  behavior: SnackbarBehavior.attached,
                ),
              ),
              _buildButton(
                'Snackbar with Preset',
                Icons.palette,
                Colors.pink,
                () => QuickPopupManager().showSnackbar(
                  message: 'Profile updated',
                  title: 'Success',
                  icon: Icons.person,
                  style: PopupStyle.success(),
                  position: SnackbarPosition.bottom,
                ),
              ),
              _buildButton(
                'Replace Current Snackbar',
                Icons.swap_horiz,
                Colors.indigo,
                () {
                  QuickPopupManager().showSnackbar(
                    message: 'First snackbar',
                    position: SnackbarPosition.bottom,
                  );
                  Future.delayed(const Duration(milliseconds: 500), () {
                    QuickPopupManager().showSnackbar(
                      message: 'This replaced the previous one!',
                      replaceCurrent: true,
                      position: SnackbarPosition.bottom,
                    );
                  });
                },
              ),
            ],
          ),
          const SizedBox(height: 24),
          _buildSection(
            title: '🚩 Banners',
            description: 'Top/Bottom banners with auto-dismiss',
            children: [
              _buildButton(
                'Top Banner',
                Icons.flag,
                Colors.orange,
                () => QuickPopupManager().showBanner(
                  message: 'New update available!',
                  title: 'Update',
                  icon: Icons.system_update,
                  position: PopupPosition.top,
                  style: PopupStyle.info(),
                ),
              ),
              _buildButton(
                'Bottom Banner',
                Icons.arrow_downward,
                Colors.deepPurple,
                () => QuickPopupManager().showBanner(
                  message: 'Connection restored',
                  title: 'Network',
                  icon: Icons.wifi,
                  position: PopupPosition.bottom,
                  style: PopupStyle.success(),
                ),
              ),
              _buildButton(
                'Error Banner',
                Icons.error_outline,
                Colors.red,
                () => QuickPopupManager().showBanner(
                  message: 'Failed to sync data',
                  title: 'Sync Error',
                  icon: Icons.sync_problem,
                  position: PopupPosition.top,
                  style: PopupStyle.error(),
                  duration: const Duration(seconds: 4),
                ),
              ),
            ],
          ),
          const SizedBox(height: 24),
          _buildSection(
            title: '💬 Dialogs',
            description: 'Regular, Loading, Destructive',
            children: [
              _buildButton(
                'Simple Dialog',
                Icons.chat_bubble,
                Colors.blue,
                () => QuickPopupManager().showDialogPopup(
                  title: 'Confirm Action',
                  message: 'Are you sure you want to proceed?',
                  onConfirm: () {
                    QuickPopupManager().showSuccessToast(
                      message: 'Action confirmed!',
                    );
                  },
                  onCancel: () {
                    QuickPopupManager().showInfoToast(
                      message: 'Action cancelled',
                    );
                  },
                ),
              ),
              _buildButton(
                'Loading Dialog',
                Icons.hourglass_empty,
                Colors.amber,
                () async {
                  final loadingId = QuickPopupManager().showLoadingDialog(
                    message: 'Processing...',
                  );
                  // Simulate work
                  await Future.delayed(const Duration(seconds: 2));
                  QuickPopupManager().hideLoadingDialog(loadingId);
                  QuickPopupManager().showSuccessToast(
                    message: 'Processing complete!',
                  );
                },
              ),
              _buildButton(
                'Destructive Dialog',
                Icons.delete,
                Colors.red,
                () => QuickPopupManager().showDestructiveDialog(
                  title: 'Delete Item',
                  message: 'This action cannot be undone. Are you sure?',
                  onConfirm: () {
                    QuickPopupManager().showErrorToast(
                      message: 'Item deleted',
                    );
                  },
                  confirmText: 'Delete',
                ),
              ),
              _buildButton(
                'Custom Dialog',
                Icons.tune,
                Colors.purple,
                () => QuickPopupManager().showDialogPopup(
                  title: 'Custom Dialog',
                  content: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      const TextField(
                        decoration: InputDecoration(
                          labelText: 'Enter your name',
                          border: OutlineInputBorder(),
                        ),
                      ),
                      const SizedBox(height: 16),
                      const Text('This is custom content!'),
                    ],
                  ),
                  style: PopupStyle(
                    backgroundColor: Colors.white,
                    borderRadius: 16,
                  ),
                  onConfirm: () {
                    QuickPopupManager().showInfoToast(
                      message: 'Custom dialog confirmed',
                    );
                  },
                ),
              ),
              _buildButton(
                'Non-Dismissible Dialog',
                Icons.lock,
                Colors.grey,
                () => QuickPopupManager().showDialogPopup(
                  title: 'Important',
                  message: 'You cannot dismiss this by tapping outside',
                  barrierDismissible: false,
                  onConfirm: () {
                    QuickPopupManager().showInfoToast(
                      message: 'Dialog closed',
                    );
                  },
                ),
              ),
            ],
          ),
          const SizedBox(height: 24),
          _buildSection(
            title: '📄 Bottom Sheets',
            description: 'Drag to dismiss, Custom heights, Keyboard-aware',
            children: [
              _buildButton(
                'Half Height Sheet',
                Icons.vertical_align_center,
                Colors.teal,
                () => QuickPopupManager().showBottomSheet(
                  title: 'Half Height Sheet',
                  message: 'This is a half-height bottom sheet',
                  height: 300,
                  onConfirm: () {
                    QuickPopupManager().showInfoToast(
                      message: 'Sheet confirmed',
                    );
                  },
                ),
              ),
              _buildButton(
                'Full Height Sheet',
                Icons.fullscreen,
                Colors.indigo,
                () => QuickPopupManager().showBottomSheet(
                  title: 'Full Height Sheet',
                  message: 'Drag down to dismiss',
                  isScrollControlled: true,
                  enableDrag: true,
                  content: ListView.builder(
                    itemCount: 20,
                    itemBuilder: (context, index) => ListTile(
                      title: Text('Item ${index + 1}'),
                      leading: const Icon(Icons.star),
                    ),
                  ),
                ),
              ),
              _buildButton(
                'Selection Sheet',
                Icons.list,
                Colors.pink,
                () {
                  final options = ['Option A', 'Option B', 'Option C', 'Option D'];
                  int selectedIndex = 0;
                  
                  QuickPopupManager().showBottomSheet(
                    title: 'Choose an option',
                    content: StatefulBuilder(
                      builder: (context, setState) {
                        return Column(
                          mainAxisSize: MainAxisSize.min,
                          children: options.asMap().entries.map((entry) {
                            final index = entry.key;
                            final option = entry.value;
                            return RadioListTile<int>(
                              title: Text(option),
                              value: index,
                              groupValue: selectedIndex,
                              onChanged: (value) {
                                if (value != null) {
                                  setState(() {
                                    selectedIndex = value;
                                  });
                                }
                              },
                            );
                          }).toList(),
                        );
                      },
                    ),
                    onConfirm: () {
                      QuickPopupManager().showSuccessToast(
                        message: 'Selected: ${options[selectedIndex]}',
                      );
                    },
                  );
                },
              ),
              _buildButton(
                'Form Sheet',
                Icons.edit,
                Colors.blue,
                () => QuickPopupManager().showBottomSheet(
                  title: 'Enter Details',
                  content: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      const TextField(
                        decoration: InputDecoration(
                          labelText: 'Name',
                          border: OutlineInputBorder(),
                        ),
                      ),
                      const SizedBox(height: 16),
                      const TextField(
                        decoration: InputDecoration(
                          labelText: 'Email',
                          border: OutlineInputBorder(),
                        ),
                      ),
                      const SizedBox(height: 16),
                      const TextField(
                        decoration: InputDecoration(
                          labelText: 'Phone',
                          border: OutlineInputBorder(),
                        ),
                      ),
                    ],
                  ),
                  isScrollControlled: true,
                  onConfirm: () {
                    QuickPopupManager().showSuccessToast(
                      message: 'Form submitted!',
                    );
                  },
                ),
              ),
            ],
          ),
          const SizedBox(height: 24),
          _buildSection(
            title: '🎨 Animation Examples',
            description: 'Different animation styles',
            children: [
              _buildButton(
                'Fade Animation',
                Icons.visibility,
                Colors.cyan,
                () => QuickPopupManager().showToast(
                  message: 'Fade animation',
                  animation: const AnimationConfig.fade(),
                ),
              ),
              _buildButton(
                'Slide from Top',
                Icons.arrow_downward,
                Colors.blue,
                () => QuickPopupManager().showToast(
                  message: 'Slides from top',
                  position: PopupPosition.top,
                  animation: const AnimationConfig.slideFromTop(),
                ),
              ),
              _buildButton(
                'Scale Animation',
                Icons.zoom_in,
                Colors.purple,
                () => QuickPopupManager().showDialogPopup(
                  title: 'Scale Dialog',
                  message: 'This dialog uses scale animation',
                  animation: const AnimationConfig.scale(),
                ),
              ),
              _buildButton(
                'Spring Animation',
                Icons.animation,
                Colors.orange,
                () => QuickPopupManager().showToast(
                  message: 'Spring animation!',
                  animation: const AnimationConfig.spring(),
                ),
              ),
            ],
          ),
          const SizedBox(height: 24),
          _buildSection(
            title: '🎯 Preset Styles',
            description: 'Success, Error, Warning, Info with themes',
            children: [
              _buildButton(
                'Success Preset',
                Icons.check_circle,
                Colors.green,
                () => QuickPopupManager().showSnackbar(
                  message: 'Operation successful',
                  style: PopupStyle.success(),
                ),
              ),
              _buildButton(
                'Error Preset',
                Icons.error,
                Colors.red,
                () => QuickPopupManager().showSnackbar(
                  message: 'An error occurred',
                  style: PopupStyle.error(),
                ),
              ),
              _buildButton(
                'Warning Preset',
                Icons.warning,
                Colors.orange,
                () => QuickPopupManager().showSnackbar(
                  message: 'Please be careful',
                  style: PopupStyle.warning(),
                ),
              ),
              _buildButton(
                'Info Preset',
                Icons.info,
                Colors.blue,
                () => QuickPopupManager().showSnackbar(
                  message: 'Here is some information',
                  style: PopupStyle.info(),
                ),
              ),
            ],
          ),
          const SizedBox(height: 32),
          Center(
            child: Text(
              'All popups work without BuildContext!',
              style: Theme.of(context).textTheme.bodySmall?.copyWith(
                    fontStyle: FontStyle.italic,
                    color: Colors.grey,
                  ),
            ),
          ),
          const SizedBox(height: 16),
        ],
      ),
    );
  }

  Widget _buildSection({
    required String title,
    required String description,
    required List<Widget> children,
  }) {
    return Card(
      elevation: 2,
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              title,
              style: const TextStyle(
                fontSize: 20,
                fontWeight: FontWeight.bold,
              ),
            ),
            const SizedBox(height: 4),
            Text(
              description,
              style: TextStyle(
                fontSize: 12,
                color: Colors.grey[600],
              ),
            ),
            const SizedBox(height: 16),
            ...children,
          ],
        ),
      ),
    );
  }

  Widget _buildButton(
    String label,
    IconData icon,
    Color color,
    VoidCallback onPressed,
  ) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 8),
      child: ElevatedButton.icon(
        onPressed: onPressed,
        icon: Icon(icon),
        label: Text(label),
        style: ElevatedButton.styleFrom(
          backgroundColor: color,
          foregroundColor: Colors.white,
          minimumSize: const Size(double.infinity, 48),
        ),
      ),
    );
  }
}
5
likes
0
points
150
downloads

Publisher

verified publishergreelogix.com

Weekly Downloads

A powerful, global popup system for Flutter that works without BuildContext. Supports Toasts, Snackbars, Banners, Dialogs, and Bottom Sheets with comprehensive customization, animations, and framework-agnostic design.

Homepage

License

unknown (license)

Dependencies

flutter

More

Packages that depend on quick_popup_manager