adaptive_dialog_manager 2.1.2 copy "adaptive_dialog_manager: ^2.1.2" to clipboard
adaptive_dialog_manager: ^2.1.2 copied to clipboard

A comprehensive Flutter adaptive dialog manager package that provides multi-platform dialog support with responsive design, accessibility features, and platform-specific behaviors.

Adaptive Dialog Manager #

A comprehensive Flutter package that provides adaptive, responsive dialog management across all platforms including mobile, web, desktop, and tablet with platform-specific behaviors, accessibility support, and advanced notification systems.

Pub Version License: MIT Platform Support

Features #

πŸŽ‰ New in v1.1.0: Advanced toast timing behavior with independent/dependent modes, enhanced snackbar dismissal controls, and improved debugging capabilities!

🎯 Adaptive & Responsive #

  • Multi-platform support: Android, iOS, Web, Windows, macOS, Linux
  • Responsive design: Automatic layout adaptation for mobile, tablet, and desktop
  • Platform-specific behaviors: Material, Cupertino, Fluent, and macOS design systems
  • Breakpoint-aware: Smart sizing based on screen dimensions
  • Advanced queue management: Handle multiple dialogs, snackbars, and toasts gracefully with intelligent queuing and timing control

🎨 Dialog System #

  • 25 dialog types: Alert, confirmation, input, loading, progress, bottomSheet, custom, modal, fullScreen, datePicker, timePicker, colorPicker, filePicker, search, settings, about, help, error, warning, success, info, toast, snackbar
  • Platform-specific styling: Automatic adaptation to Material, Cupertino, Fluent, and macOS design languages
  • Custom content support: Fully customizable dialog content with widget injection
  • Advanced configurations: Comprehensive dialog configuration with safe type handling

🍞 Toast System #

  • 5 toast types: Info, success, warning, error, custom
  • Flexible positioning: Top, bottom, center positioning with offset control
  • Stack and column layouts: Traditional overlapping or vertical column display
  • Column mode features: Maximum 4 visible toasts, clean vertical arrangement
  • Advanced timing management: Independent and dependent timing behaviors with intelligent pause/resume
  • Toast timing behavior: Independent (classic) or dependent (newer toasts pause older ones)
  • Real-time timer control: Automatic duration control with position-aware timing management
  • Custom content: Widget-based custom toast content with full styling control

πŸ“± Snackbar System #

  • 10 snackbar types: Info, success, warning, error, loading, action, custom, toast, banner, persistent
  • Advanced positioning: Top, bottom, center with fine-grained control (default: top)
  • Behavior types: Queue, stack, replace, skip, force, priority, custom
  • Stack layout: Display up to 5 snackbars simultaneously with stacking behavior
  • Action support: Interactive buttons with customizable callbacks
  • Priority queue: Intelligent priority-based queue management
  • Queue behaviors: Smart handling of multiple snackbars with customizable limits
  • Enhanced dismissal control: Advanced dismissible behavior with tap, swipe, auto-dismiss, and directional control
  • Smart auto-dismiss logic: Context-aware dismissal based on snackbar type and configuration
  • Animation customization: Custom animation duration, curves, directions, and platform-optimized timing

🎭 Animations & Transitions #

  • 31 animation types: None, fade, scale, slideFromBottom, slideFromTop, slideFromLeft, slideFromRight, slideUp, slideDown, elastic, bounce, rotation, flip, pop, blur, custom, plus compound animations combining multiple effects
  • Platform-optimized timing: Adaptive durations and curves
  • Performance profiles: Mobile-friendly and high-performance variants
  • Reduced motion support: Accessibility-friendly alternatives

β™Ώ Accessibility #

  • Screen reader support: Comprehensive semantic labeling
  • Keyboard navigation: Full desktop keyboard support
  • Focus management: Proper focus trapping and restoration
  • High contrast support: Theme-aware color schemes
  • Touch target sizing: Minimum accessibility requirements

πŸ”§ Developer Experience #

  • Type-safe configuration: Strongly typed models extending BaseDataModel
  • Dependency injection ready: Abstract interfaces for testability
  • State tracking: Comprehensive lifecycle monitoring with streams
  • Error handling: Robust exception management with detailed error reporting
  • Advanced debug mode: Detailed logging with real-time timer monitoring and position tracking
  • Queue monitoring: Real-time queue status and management with enhanced debugging
  • ID generation utilities: Built-in unique ID generation for toast and dialog tracking
  • Timing system debugging: Real-time timer status monitoring with pause/resume state tracking

Installation #

Add to your pubspec.yaml:

dependencies:
  adaptive_dialog_manager: ^x.y.z

Run:

flutter pub get

Platform Setup #

No additional platform-specific setup required. The package works out of the box on all supported platforms.

Quick Start #

Basic Setup #

import 'package:adaptive_dialog_manager/adaptive_dialog_manager.dart';

void main() {
  // Initialize the managers
  AdaptiveDialogManager.initialize();
  AdaptiveSnackbarManager.initialize();
  AdaptiveToastManager.initialize();

  runApp(MyApp());
}

Dialog Examples #

Simple Alert Dialog

final dialogManager = AdaptiveDialogManager.instance;

await dialogManager.showDialog(
  context,
  DialogConfig(
    dialogType: DialogType.alert,
    platformType: PlatformDetector.currentPlatform,
    title: 'Hello World',
    content: 'This is an adaptive dialog!',
  ),
);

Confirmation Dialog

final result = await dialogManager.showDialog<bool>(
  context,
  DialogConfig(
    dialogType: DialogType.confirmation,
    platformType: PlatformDetector.currentPlatform,
    title: 'Delete Item',
    content: 'Are you sure you want to delete this item?',
    actions: [
      DialogAction(
        label: 'Cancel',
        onPressed: () => Navigator.pop(context, false),
      ),
      DialogAction(
        label: 'Delete',
        isPrimary: true,
        isDestructive: true,
        onPressed: () => Navigator.pop(context, true),
      ),
    ],
  ),
);

if (result?.data == true) {
  // Handle deletion
}

Custom Dialog with Animations

final config = DialogConfig(
  dialogType: DialogType.custom,
  platformType: PlatformDetector.currentPlatform,
  animationType: AnimationType.elastic,
  animationDuration: const Duration(milliseconds: 600),
  customContent: MyCustomWidget(),
  backgroundColor: Colors.white,
  borderRadius: BorderRadius.circular(16),
);

await dialogManager.showDialog(context, config);

Snackbar Examples #

Basic Snackbars

final snackbarManager = AdaptiveSnackbarManager.instance;

// Success snackbar
await snackbarManager.showSnackbar(
  context,
  SnackbarConfig(
    snackbarType: SnackbarType.success,
    platformType: PlatformDetector.currentPlatform,
    message: 'Operation completed successfully!',
  ),
);

// Error snackbar with action and custom dismissal
await snackbarManager.showSnackbar(
  context,
  SnackbarConfig(
    snackbarType: SnackbarType.error,
    platformType: PlatformDetector.currentPlatform,
    message: 'Failed to save data',
    showAction: true,
    actionLabel: 'Retry',
    onActionPressed: () => retryOperation(),
    // Enhanced dismissal configuration
    dismissible: true,
    tapToDismiss: true,
    swipeToDismiss: true,
    dismissDirection: DismissDirection.endToStart,
    duration: const Duration(seconds: 8),
  ),
);

Advanced Snackbar Configuration

final config = SnackbarConfig(
  snackbarType: SnackbarType.custom,
  platformType: PlatformDetector.currentPlatform,
  message: 'Custom snackbar',
  position: SnackbarPosition.top, // Default position is now top
  behavior: SnackbarBehavior.floating,
  duration: const Duration(seconds: 5),
  backgroundColor: Colors.purple,
  textColor: Colors.white,
  borderRadius: BorderRadius.circular(12),
  customContent: MyCustomSnackbarContent(),
  // Enhanced dismissible and animation properties
  dismissible: true, // Can be dismissed by user interaction
  autoDismiss: true, // Auto-dismiss after duration (smart logic)
  tapToDismiss: true, // Tap to dismiss
  swipeToDismiss: true, // Swipe to dismiss
  dismissDirection: DismissDirection.horizontal, // Swipe direction
  animationDuration: const Duration(milliseconds: 400), // Custom animation timing
  animationCurve: Curves.easeInOut, // Custom animation curve
);

await snackbarManager.showSnackbar(context, config);

Loading Snackbar with Controller

// Loading snackbar with controlled dismissal
final loadingController = snackbarManager.showLoading(
  context: context,
  message: 'Processing data...',
  cancellable: true, // User can dismiss loading
  showProgress: true,
);

// Update progress and message
loadingController.updateProgress(0.5);
loadingController.updateMessage('Halfway done...');

// Complete or cancel
loadingController.complete('Processing completed!');
// or loadingController.cancel();

Multiple Snackbars with Stack Behavior

// Single stacked snackbar
await snackbarManager.showSnackbar(
  context,
  SnackbarConfig(
    snackbarType: SnackbarType.info,
    platformType: PlatformDetector.currentPlatform,
    message: 'Stacked snackbar',
    position: SnackbarPosition.bottom,
    behavior: SnackbarBehavior.stack, // Use stack behavior for multiple snackbars
    duration: const Duration(seconds: 5),
  ),
);

// Multiple snackbars stacked (max 5 visible at once)
final messages = ['Task 1 Complete', 'File Uploaded', 'Sync Finished'];
final types = [SnackbarType.success, SnackbarType.info, SnackbarType.success];

for (int i = 0; i < messages.length; i++) {
  await snackbarManager.showSnackbar(
    context,
    SnackbarConfig(
      snackbarType: types[i],
      platformType: PlatformDetector.currentPlatform,
      message: messages[i],
      position: SnackbarPosition.bottom,
      behavior: SnackbarBehavior.stack,
      duration: const Duration(seconds: 6),
      showIcon: true,
    ),
  );
}

// Customize behavior limits
snackbarManager.updateBehaviorSettings(
  maxSimultaneous: 5, // Allow up to 5 simultaneous snackbars
);

Toast Examples #

Basic Toast Notifications

final toastManager = AdaptiveToastManager.instance;

// Info toast
await toastManager.showInfo(
  context,
  message: 'This is an info message',
  title: 'Information',
);

// Success toast
await toastManager.showSuccess(
  context,
  message: 'Data saved successfully!',
  duration: const Duration(seconds: 3),
);

// Error toast
await toastManager.showError(
  context,
  message: 'Failed to load data',
  title: 'Error',
);

Custom Toast

await toastManager.showCustom(
  context,
  content: Container(
    padding: const EdgeInsets.all(16),
    decoration: BoxDecoration(
      color: Colors.blue,
      borderRadius: BorderRadius.circular(8),
    ),
    child: const Text(
      'Custom Toast Content',
      style: TextStyle(color: Colors.white),
    ),
  ),
  duration: const Duration(seconds: 4),
);

Column Layout Toast

// Show toast in column layout mode
await toastManager.showToast<String>(
  context,
  ToastConfig(
    toastType: ToastType.info,
    platformType: PlatformDetector.currentPlatform,
    message: 'Column layout toast',
    title: 'Information',
    position: ToastPosition.bottomCenter,
    layout: ToastLayout.column, // Use column layout
    duration: const Duration(seconds: 4),
  ),
);

// Multiple toasts in column - max 4 visible at once
for (int i = 1; i <= 6; i++) {
  await toastManager.showToast<String>(
    context,
    ToastConfig(
      toastType: ToastType.success,
      platformType: PlatformDetector.currentPlatform,
      message: 'Toast #$i',
      layout: ToastLayout.column,
      position: ToastPosition.topCenter,
    ),
  );
}
// Only 4 toasts will be visible at once in column mode

Advanced Toast Timing Behavior

// Independent timing (classic behavior) - each toast dismisses independently
await toastManager.showToast<String>(
  context,
  ToastConfig(
    toastType: ToastType.info,
    platformType: PlatformDetector.currentPlatform,
    message: 'Independent timing toast',
    timingBehavior: ToastTimingBehavior.independent,
    duration: const Duration(seconds: 3),
  ),
);

// Dependent timing (new feature) - older toasts pause when newer ones appear
await toastManager.showToast<String>(
  context,
  ToastConfig(
    toastType: ToastType.success,
    platformType: PlatformDetector.currentPlatform,
    message: 'Dependent timing toast',
    timingBehavior: ToastTimingBehavior.dependent, // Default
    duration: const Duration(seconds: 5),
  ),
);

// Multiple toasts with dependent timing
for (int i = 1; i <= 3; i++) {
  await toastManager.showToast<String>(
    context,
    ToastConfig(
      toastType: ToastType.warning,
      platformType: PlatformDetector.currentPlatform,
      message: 'Toast #$i - will pause when newer toast appears',
      timingBehavior: ToastTimingBehavior.dependent,
      duration: const Duration(seconds: 4),
    ),
  );
}
// Only the topmost toast will actively count down, others pause until visible

Advanced Usage #

Platform Detection & Responsive Design #

// Get current platform
final platformType = PlatformDetector.currentPlatform;

// Get responsive breakpoint
final breakpoint = ResponsiveBreakpoint.fromWidth(
  MediaQuery.of(context).size.width,
);

// Create responsive configuration
final responsiveConfig = ResponsiveConfig(
  breakpoint: breakpoint,
  maxWidth: breakpoint.isDesktop ? 600 : double.infinity,
  padding: breakpoint.isMobile
    ? const EdgeInsets.all(16)
    : const EdgeInsets.all(24),
);

Queue Management #

// Get queue status
final dialogQueue = DialogQueueManager.instance;
final snackbarQueue = SnackbarQueueManager.instance;
final toastQueue = ToastQueueManager.instance;

// Monitor queue changes
dialogQueue.stateStream.listen((dialogState) {
  print('Dialog state: ${dialogState.status}');
});

// Clear queues
await dialogQueue.clearQueue();
await snackbarQueue.clearQueue();
await toastQueue.clearQueue();

Debug Mode #

// Enable debug logging
AdaptiveDialogManager.instance.enableDebugMode();
AdaptiveSnackbarManager.instance.enableDebugMode();
AdaptiveToastManager.instance.enableDebugMode();

// View queue status
final dialogStatus = DialogQueueManager.instance.getQueueStatus();
print('Active dialogs: ${dialogStatus.activeCount}');
print('Pending dialogs: ${dialogStatus.pendingCount}');

Architecture #

Core Classes #

  • AdaptiveDialogManager - Main dialog manager singleton
  • AdaptiveSnackbarManager - Snackbar manager singleton
  • AdaptiveToastManager - Toast manager singleton
  • DialogConfig - Dialog configuration model
  • SnackbarConfig - Snackbar configuration model
  • ToastConfig - Toast configuration model with timing behavior support
  • DialogResult<T> - Type-safe dialog result
  • SnackbarResult<T> - Type-safe snackbar result
  • ToastResult<T> - Type-safe toast result
  • PlatformDetector - Platform detection utility
  • ResponsiveManager - Responsive layout manager
  • ToastTimingManager - Advanced toast timing control manager
  • IdGenerator - Utility for generating unique IDs

Enums #

  • DialogType - 25 dialog types
  • SnackbarType - 10 snackbar types
  • ToastType - 5 toast types
  • PlatformType - 7 supported platforms
  • AnimationType - 31 animation options including compound animations
  • ResponsiveBreakpoint - Screen size breakpoints
  • SnackbarPosition, SnackbarBehavior - Advanced snackbar options
  • ToastPosition, ToastLayout - Toast positioning and layout options
  • ToastTimingBehavior - Independent vs dependent timing behavior
  • ToastDisplayMode - Stack vs column display modes

Interfaces #

abstract class DialogManager {
  Future<DialogResult<T?>?> showDialog<T>(BuildContext context, DialogConfig config);
  Stream<DialogState> get stateStream;
  void enableDebugMode();
  void disableDebugMode();
}

abstract class SnackbarManager {
  Future<SnackbarResult<T?>?> showSnackbar<T>(BuildContext context, SnackbarConfig config);
  LoadingSnackbarController showLoading({required BuildContext context, String message, bool cancellable});
  Stream<SnackbarState> get stateStream;
}

abstract class ToastManager {
  Future<ToastResult<T>?> showToast<T>(BuildContext context, ToastConfig config);
  Future<ToastResult<String>?> showInfo(BuildContext context, {required String message});
  Future<ToastResult<String>?> showSuccess(BuildContext context, {required String message});
  Future<ToastResult<String>?> showWarning(BuildContext context, {required String message});
  Future<ToastResult<String>?> showError(BuildContext context, {required String message});
}

Testing #

Unit Testing #

import 'package:flutter_test/flutter_test.dart';
import 'package:adaptive_dialog_manager/adaptive_dialog_manager.dart';

void main() {
  group('DialogConfig', () {
    test('should create valid configuration', () {
      final config = DialogConfig(
        dialogType: DialogType.alert,
        platformType: PlatformType.android,
        title: 'Test',
        content: 'Test content',
      );

      expect(config.dialogType, DialogType.alert);
      expect(config.title, 'Test');
      expect(config.content, 'Test content');
    });
  });

  group('PlatformDetector', () {
    test('should detect current platform', () {
      final platform = PlatformDetector.currentPlatform;
      expect(platform, isA<PlatformType>());
    });
  });
}

Widget Testing #

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:adaptive_dialog_manager/adaptive_dialog_manager.dart';

void main() {
  setUp(() {
    AdaptiveDialogManager.initialize();
  });

  testWidgets('should show adaptive dialog', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Builder(
          builder: (context) => ElevatedButton(
            onPressed: () async {
              await AdaptiveDialogManager.instance.showDialog(
                context,
                DialogConfig(
                  dialogType: DialogType.alert,
                  platformType: PlatformDetector.currentPlatform,
                  title: 'Test Dialog',
                  content: 'Test content',
                ),
              );
            },
            child: const Text('Show Dialog'),
          ),
        ),
      ),
    );

    await tester.tap(find.text('Show Dialog'));
    await tester.pumpAndSettle();

    expect(find.text('Test Dialog'), findsOneWidget);
    expect(find.text('Test content'), findsOneWidget);
  });
}

Performance #

Optimization Features #

  • Lazy initialization: Managers initialize only when needed
  • Efficient queue management: Optimized algorithms for multiple notifications
  • Memory management: Automatic cleanup and disposal
  • Animation optimization: Mobile-friendly and high-performance variants
  • Platform-specific optimizations: Tailored behavior for each platform

Performance Profiles #

// Mobile-optimized configuration
final mobileConfig = DialogConfig(
  dialogType: DialogType.alert,
  platformType: PlatformDetector.currentPlatform,
  animationType: AnimationType.fade, // Simple animation
  animationDuration: const Duration(milliseconds: 200), // Faster
);

// Desktop-optimized configuration
final desktopConfig = DialogConfig(
  dialogType: DialogType.alert,
  platformType: PlatformDetector.currentPlatform,
  animationType: AnimationType.elastic, // Complex animation
  animationDuration: const Duration(milliseconds: 600), // Longer
);

Accessibility #

Built-in Accessibility Features #

  • Screen reader support: Comprehensive semantic labeling
  • Keyboard navigation: Full desktop keyboard support
  • Focus management: Proper focus trapping and restoration
  • High contrast support: Theme-aware color schemes
  • Touch target sizing: Minimum 48dp touch targets
  • Reduced motion: Automatic detection and adaptation

Accessibility Configuration #

final accessibleConfig = DialogConfig(
  dialogType: DialogType.alert,
  platformType: PlatformDetector.currentPlatform,
  semanticLabel: 'Important alert dialog',
  animationType: MediaQuery.of(context).accessibleNavigation
    ? AnimationType.fade
    : AnimationType.scale,
);

API Reference #

For complete API documentation, visit pub.flutter-io.cn documentation.

Contributing #

We welcome contributions! Please see our Contributing Guide for details.

Development Setup #

  1. Fork the repository
  2. Clone your fork: git clone https://github.com/yourusername/flutter-adaptive-dialog-manager.git
  3. Install dependencies: flutter pub get
  4. Run the example: cd example && flutter run
  5. Make your changes and test thoroughly
  6. Submit a pull request

License #

This project is licensed under the MIT License - see the LICENSE file for details.

Changelog #

See CHANGELOG.md for a detailed history of changes.

Support #

Author #

Bahrican Yeşil - GitHub | LinkedIn


Made with ❀️ in Turkey

0
likes
160
points
310
downloads

Publisher

unverified uploader

Weekly Downloads

A comprehensive Flutter adaptive dialog manager package that provides multi-platform dialog support with responsive design, accessibility features, and platform-specific behaviors.

Repository (GitHub)
View/report issues

Topics

#adaptive-dialog #dialog-manager #dialog #snackbar #toast

Documentation

API reference

License

MIT (license)

Dependencies

equatable, flutter, flutter_shared_utilities, universal_io

More

Packages that depend on adaptive_dialog_manager