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

Global popup system for Flutter without BuildContext.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:quick_popup_manager/quick_popup_manager.dart';

void main() {
  runApp(const MyApp());
}

/// ------------------------------
/// APP ROOT
/// ------------------------------
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();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final overlay = _navigatorKey.currentState?.overlay;
      if (overlay != null) QuickPopupManager().initialize(overlay);
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Quick Popup Manager Demo',
      debugShowCheckedModeBanner: false,
      navigatorKey: _navigatorKey,
      navigatorObservers: [QuickPopupNavigatorObserver()],
      theme: ThemeData(
        useMaterial3: true,
        brightness: Brightness.dark,
        fontFamily: 'Google Sans',
        scaffoldBackgroundColor: const Color(0xFF0F0F10),
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.deepPurple,
          brightness: Brightness.dark,
        ),
        appBarTheme: const AppBarTheme(
          elevation: 0,
          backgroundColor: Color(0xFF0F0F10),
          foregroundColor: Colors.white,
          titleTextStyle: TextStyle(
            fontSize: 22,
            fontWeight: FontWeight.bold,
            fontFamily: 'Google Sans',
            color: Colors.white,
          ),
        ),
      ),
      builder: (context, child) {
        final navigator = Navigator.maybeOf(context, rootNavigator: true);
        if (navigator?.overlay != null) {
          QuickPopupManager().initialize(navigator!.overlay!);
        }
        return child ?? const SizedBox();
      },
      home: const HomePage(),
    );
  }
}

/// ------------------------------
/// HOME PAGE
/// ------------------------------
class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Quick Popup Manager')),
      body: ListView(
        padding: const EdgeInsets.all(20),
        children: [
          // 🍞 Toasts
          _section(
            title: '🍞 Toast Notifications',
            subtitle: 'No BuildContext needed!',
            children: [
              ActionTile(
                icon: Icons.check_circle,
                color: Colors.green,
                title: 'Success Toast (Top)',
                onTap: () => QuickPopupManager().showSuccessToast(
                  title: 'Success',
                  message: 'Operation completed successfully!',
                  position: PopupPosition.top,
                ),
              ),
              ActionTile(
                icon: Icons.error,
                color: Colors.red,
                title: 'Error Toast (Bottom)',
                onTap: () => QuickPopupManager().showErrorToast(
                  title: 'Error',
                  message: 'Something went wrong!',
                  position: PopupPosition.bottom,
                ),
              ),
              ActionTile(
                icon: Icons.warning,
                color: Colors.orange,
                title: 'Warning Toast (Center)',
                onTap: () => QuickPopupManager().showWarningToast(
                  title: 'Warning',
                  message: 'Please check your input',
                  position: PopupPosition.center,
                ),
              ),
              ActionTile(
                icon: Icons.info,
                color: Colors.blue,
                title: 'Info Toast',
                onTap: () => QuickPopupManager().showInfoToast(
                  message: 'New features available',
                  title: 'Info',
                ),
              ),
              ActionTile(
                icon: Icons.star,
                color: Colors.purple,
                title: 'Custom Toast',
                onTap: () => 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(),
                ),
              ),
            ],
          ),

          // 🍔 Snackbars
          _section(
            title: '🍔 Snackbars',
            subtitle: 'Top/Bottom, Floating/Attached, Swipe to dismiss',
            children: [
              ActionTile(
                icon: Icons.message,
                color: Colors.blue,
                title: 'Bottom Snackbar (Floating)',
                onTap: () => QuickPopupManager().showSnackbar(
                  message: 'Item added to cart',
                  title: 'Success',
                  icon: Icons.shopping_cart,
                  position: SnackbarPosition.bottom,
                  behavior: SnackbarBehavior.floating,
                ),
              ),
              ActionTile(
                icon: Icons.arrow_upward,
                color: Colors.teal,
                title: 'Top Snackbar (Attached)',
                onTap: () => QuickPopupManager().showSnackbar(
                  message: 'Message sent',
                  title: 'Notification',
                  subtitle: 'Your message has been delivered',
                  icon: Icons.send,
                  position: SnackbarPosition.top,
                  behavior: SnackbarBehavior.attached,
                ),
              ),
              ActionTile(
                icon: Icons.palette,
                color: Colors.pink,
                title: 'Snackbar with Preset',
                onTap: () => QuickPopupManager().showSnackbar(
                  message: 'Profile updated',
                  title: 'Success',
                  icon: Icons.person,
                  style: PopupStyle.success(),
                  position: SnackbarPosition.bottom,
                ),
              ),
              ActionTile(
                icon: Icons.swap_horiz,
                color: Colors.indigo,
                title: 'Replace Current Snackbar',
                onTap: () {
                  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,
                    );
                  });
                },
              ),
            ],
          ),

          // 🚩 Banners
          _section(
            title: '🚩 Banners',
            subtitle: 'Top/Bottom banners with auto-dismiss',
            children: [
              ActionTile(
                icon: Icons.flag,
                color: Colors.orange,
                title: 'Top Banner',
                onTap: () => QuickPopupManager().showBanner(
                  message: 'New update available!',
                  title: 'Update',
                  icon: Icons.system_update,
                  position: PopupPosition.top,
                  style: PopupStyle.info(),
                ),
              ),
              ActionTile(
                icon: Icons.arrow_downward,
                color: Colors.deepPurple,
                title: 'Bottom Banner',
                onTap: () => QuickPopupManager().showBanner(
                  message: 'Connection restored',
                  title: 'Network',
                  icon: Icons.wifi,
                  position: PopupPosition.bottom,
                  style: PopupStyle.success(),
                ),
              ),
              ActionTile(
                icon: Icons.error_outline,
                color: Colors.red,
                title: 'Error Banner',
                onTap: () => 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),
                ),
              ),
            ],
          ),

          // 💬 Dialogs
          _section(
            title: '💬 Dialogs',
            subtitle: 'Regular, Loading, Destructive, Custom',
            children: [
              ActionTile(
                icon: Icons.chat_bubble,
                color: Colors.blue,
                title: 'Simple Dialog',
                onTap: () => 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',
                    );
                  },
                ),
              ),
              ActionTile(
                icon: Icons.hourglass_empty,
                color: Colors.amber,
                title: 'Loading Dialog',
                onTap: () async {
                  final loadingId = QuickPopupManager().showLoadingDialog(
                    message: 'Processing...',
                  );
                  await Future.delayed(const Duration(seconds: 2));
                  QuickPopupManager().hideLoadingDialog(loadingId);
                  QuickPopupManager().showSuccessToast(
                    message: 'Processing complete!',
                  );
                },
              ),
              ActionTile(
                icon: Icons.delete,
                color: Colors.red,
                title: 'Destructive Dialog',
                onTap: () => QuickPopupManager().showDestructiveDialog(
                  title: 'Delete Item',
                  message: 'This action cannot be undone. Are you sure?',
                  onConfirm: () {
                    QuickPopupManager().showErrorToast(
                      message: 'Item deleted',
                    );
                  },
                  confirmText: 'Delete',
                ),
              ),
              ActionTile(
                icon: Icons.tune,
                color: Colors.purple,
                title: 'Custom Dialog',
                onTap: () => 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',
                    );
                  },
                ),
              ),
              ActionTile(
                icon: Icons.lock,
                color: Colors.grey,
                title: 'Non-Dismissible Dialog',
                onTap: () => QuickPopupManager().showDialogPopup(
                  title: 'Important',
                  message: 'You cannot dismiss this by tapping outside',
                  barrierDismissible: false,
                  onConfirm: () {
                    QuickPopupManager().showInfoToast(
                      message: 'Dialog closed',
                    );
                  },
                ),
              ),
            ],
          ),

          // 📄 Bottom Sheets
          _section(
            title: '📄 Bottom Sheets',
            subtitle: 'Half, Full, Selection, Form',
            children: [
              ActionTile(
                icon: Icons.vertical_align_center,
                color: Colors.teal,
                title: 'Half Height Sheet',
                onTap: () => QuickPopupManager().showBottomSheet(
                  title: 'Half Height Sheet',
                  message: 'This is a half-height bottom sheet',
                  height: 300,
                  onConfirm: () {
                    QuickPopupManager().showInfoToast(
                      message: 'Sheet confirmed',
                    );
                  },
                ),
              ),
              ActionTile(
                icon: Icons.fullscreen,
                color: Colors.indigo,
                title: 'Full Height Sheet',
                onTap: () => 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),
                    ),
                  ),
                ),
              ),
              ActionTile(
                icon: Icons.list,
                color: Colors.pink,
                title: 'Selection Sheet',
                onTap: () {
                  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]}',
                      );
                    },
                  );
                },
              ),
              ActionTile(
                icon: Icons.edit,
                color: Colors.blue,
                title: 'Form Sheet',
                onTap: () => 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!',
                    );
                  },
                ),
              ),
            ],
          ),

          // 🎨 Animation Examples
          _section(
            title: '🎨 Animation Examples',
            subtitle: 'Fade, Slide, Scale, Spring',
            children: [
              ActionTile(
                icon: Icons.visibility,
                color: Colors.cyan,
                title: 'Fade Animation',
                onTap: () => QuickPopupManager().showToast(
                  message: 'Fade animation',
                  animation: const AnimationConfig.fade(),
                ),
              ),
              ActionTile(
                icon: Icons.arrow_downward,
                color: Colors.blue,
                title: 'Slide from Top',
                onTap: () => QuickPopupManager().showToast(
                  message: 'Slides from top',
                  position: PopupPosition.top,
                  animation: const AnimationConfig.slideFromTop(),
                ),
              ),
              ActionTile(
                icon: Icons.zoom_in,
                color: Colors.purple,
                title: 'Scale Animation',
                onTap: () => QuickPopupManager().showDialogPopup(
                  title: 'Scale Dialog',
                  message: 'This dialog uses scale animation',
                  animation: const AnimationConfig.scale(),
                ),
              ),
              ActionTile(
                icon: Icons.animation,
                color: Colors.orange,
                title: 'Spring Animation',
                onTap: () => QuickPopupManager().showToast(
                  message: 'Spring animation!',
                  animation: const AnimationConfig.spring(),
                ),
              ),
            ],
          ),

          // 🎯 Preset Styles
          _section(
            title: '🎯 Preset Styles',
            subtitle: 'Success, Error, Warning, Info with themes',
            children: [
              ActionTile(
                icon: Icons.check_circle,
                color: Colors.green,
                title: 'Success Preset',
                onTap: () => QuickPopupManager().showSnackbar(
                  message: 'Operation successful',
                  style: PopupStyle.success(),
                ),
              ),
              ActionTile(
                icon: Icons.error,
                color: Colors.red,
                title: 'Error Preset',
                onTap: () => QuickPopupManager().showSnackbar(
                  message: 'An error occurred',
                  style: PopupStyle.error(),
                ),
              ),
              ActionTile(
                icon: Icons.warning,
                color: Colors.orange,
                title: 'Warning Preset',
                onTap: () => QuickPopupManager().showSnackbar(
                  message: 'Please be careful',
                  style: PopupStyle.warning(),
                ),
              ),
              ActionTile(
                icon: Icons.info,
                color: Colors.blue,
                title: 'Info Preset',
                onTap: () => QuickPopupManager().showSnackbar(
                  message: 'Here is some information',
                  style: PopupStyle.info(),
                ),
              ),
            ],
          ),

          const SizedBox(height: 32),
          const Center(
            child: Text(
              '✨ All popups work without BuildContext!',
              style: TextStyle(
                fontSize: 13,
                color: Colors.grey,
                fontStyle: FontStyle.italic,
              ),
            ),
          ),
          const SizedBox(height: 24),
        ],
      ),
    );
  }

  /// ------------------------------
  /// SECTION COMPONENT
  /// ------------------------------
  Widget _section({
    required String title,
    required String subtitle,
    required List<Widget> children,
  }) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 28),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            title,
            style: const TextStyle(
              fontSize: 20,
              fontWeight: FontWeight.bold,
              fontFamily: 'Google Sans',
              color: Colors.white,
            ),
          ),
          const SizedBox(height: 4),
          Text(
            subtitle,
            style: const TextStyle(
              fontSize: 13,
              color: Colors.white60,
              fontFamily: 'Google Sans',
            ),
          ),
          const SizedBox(height: 16),
          ...children,
        ],
      ),
    );
  }
}

/// ------------------------------
/// ACTION TILE COMPONENT
/// ------------------------------
class ActionTile extends StatelessWidget {
  final IconData icon;
  final Color color;
  final String title;
  final VoidCallback onTap;

  const ActionTile({
    super.key,
    required this.icon,
    required this.color,
    required this.title,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 12),
      child: Material(
        elevation: 0,
        color: const Color(0xFF1C1C1E),
        borderRadius: BorderRadius.circular(16),
        child: InkWell(
          borderRadius: BorderRadius.circular(16),
          onTap: onTap,
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Row(
              children: [
                CircleAvatar(
                  radius: 22,
                  backgroundColor: color.withOpacity(0.15),
                  child: Icon(icon, color: color),
                ),
                const SizedBox(width: 16),
                Expanded(
                  child: Text(
                    title,
                    style: const TextStyle(
                      fontSize: 15,
                      fontWeight: FontWeight.w500,
                      fontFamily: 'Google Sans',
                      color: Colors.white,
                    ),
                  ),
                ),
                const Icon(Icons.arrow_forward_ios, size: 18, color: Colors.grey),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
8
likes
0
points
444
downloads

Publisher

verified publishergreelogix.com

Weekly Downloads

Global popup system for Flutter without BuildContext.

Homepage

License

unknown (license)

Dependencies

flutter

More

Packages that depend on quick_popup_manager