Flutter Overlay Support

pub package license

A lightweight, powerful, and intelligent overlay support package for Flutter. Build premium notifications, toasts, and popovers with a high-level declarative API.


🚀 Key Features in Depth

📥 Smart Overlay Queue

Intelligent management of multiple overlays. Most packages show overlays immediately, causing them to overlap and clutter the screen.

  • Prioritization: 5 levels (low, normal, high, urgent, critical). Critical items jump to the front.
  • Deduplication: Use id and QueueStrategy to replace or ignore duplicate notifications.
  • Serialization: Overlays wait for the previous one to finish before showing.
  • Control: Pause, resume, or clear the queue at any time.

⚓ Widget Anchoring

Go beyond fixed top/bottom notifications. Attach overlays directly to any widget in your tree.

  • GlobalKey Tracking: Pass a targetKey and the overlay will automatically find its position.
  • Dynamic Following: The overlay stays attached to the widget even as the user scrolls.
  • Auto-Flipping: If an overlay is set to show at the top but hits the screen edge, it automatically flips to the bottom.
  • Arrow Support: Built-in arrows that point exactly to the target widget.

⚡ Future & Progress API

Declarative way to handle asynchronous operations.

  • showFuture: Handles the full lifecycle of a Future. Shows a loader, then automatically replaces it with a success or error notification.
  • showProgress: Returns a handle that you can use to push live updates (e.g., "Downloading 45%...") without flickering.

🎨 Adaptive UI & Themes

Automatically looks "correct" on every platform.

  • Platform Awareness: Native look for Android (Material 3), iOS/macOS (Cupertino), and Windows (Fluent).
  • Premium Factories: Quickly apply glassmorphism(), neon(), or minimal() styles globally.
  • Glassmorphism: Built-in support for real-time background blurring that respects light/dark modes.

🎮 Lifecycle & Control

Complete programmatic control over every overlay.

  • Entry Handles: Capture an OverlaySupportEntry to manually dismiss() or update() an active overlay.
  • Event Hooks: Use onShow, onDismiss, and onTap to trigger app logic when users interact with notifications.

🔍 Debug Inspector

During development, show the OverlayInspector to visualize all active/queued overlays and their keys. Never lose track of "leaked" overlays again.


🔥 Why use Flutter Overlay Support?

Feature Standard SnackBars Other Packages Flutter Overlay Support
Queue Management ❌ None ⚠️ Simple Smart Priority Queue
Overlap Prevention ❌ No ⚠️ Sometimes Built-in & Automatic
Widget Anchoring ❌ No ❌ No Dynamic Follow & Flip
Future/Async API ❌ Manual ❌ Manual Declarative showFuture
Adaptive Design ❌ Static ❌ Static Platform-Aware UI
Dependencies ✅ None ⚠️ Often many Pure Flutter (Zero)

🛠 Getting Started

Installation

Add this to your pubspec.yaml:

dependencies:
  flutter_overlay_support: ^1.0.0

Import

import 'package:flutter_overlay_support/flutter_overlay_support.dart';

The easiest way to use the library is to wrap your MaterialApp with OverlaySupport.global. This enables the global API (toast, showSimpleNotification, etc.) to work from anywhere in your code without needing a BuildContext.

OverlaySupport.global(
  theme: OverlaySupportThemeData.material3(),
  child: MaterialApp(
    home: HomePage(),
  ),
)

Alternative (Scoped): If you don't want to wrap your entire app, you can use OverlaySupport.local to limit overlays to a specific subtree, or pass a context to every API call:

showSimpleNotification(Text("Hello"), context: context);

📖 Usage Examples

Using the Intelligent Queue

showSimpleNotification(
  Text("Critical Update"),
  useQueue: true,
  priority: OverlayPriority.critical,
  id: "update_notice",
  strategy: QueueStrategy.replace, // Replace if already in queue
);

Anchoring to a Button

final anchorKey = GlobalKey();

ElevatedButton(key: anchorKey, child: Text("Menu"), ...);

showAnchorOverlay(
  targetKey: anchorKey,
  preferredAlignment: AnchorAlignment.bottomCenter,
  child: MyCustomMenu(),
);

Declarative Future API

// The loader shows automatically, then disappears when the future finishes.
await showFuture(
  future: myApiCall(),
  loading: "Saving...",
  success: "Saved!",
  error: "Error occurred",
);

Live Progress Updates

final progress = showProgress(0, message: "Downloading...");

// Update from anywhere
progress.update(0.5, message: "Halfway there...");

// Complete with a final message (auto-dismisses after 1s)
progress.complete(message: "Download Finished!");

Global Group Control

// Tag notifications with a group
showSimpleNotification(Text("File 1 uploaded"), group: "uploads");
showSimpleNotification(Text("File 2 uploaded"), group: "uploads");

// Dismiss only the upload notifications
dismissOverlayGroup("uploads");

Lifecycle Hooks & Manual Control

final entry = showSimpleNotification(
  Text("Interactive Notification"),
  onTap: () => print("Tapped!"),
  onDismiss: () => print("Gone!"),
  autoDismiss: false,
);

// Later in your logic
entry.dismiss();

Debugging with Inspector

// Show a list of all active overlays during development
showModalBottomSheet(
  context: context,
  builder: (context) => const OverlayInspector(),
);

🛠 API Reference

Notifications & Toasts

  • toast(message, {duration, context}): Quick, simple text toast.
  • showSimpleNotification(content, {leading, subtitle, trailing, background, foreground, position, useQueue, ...}): High-level API for standard notifications.
  • showOverlayNotification(builder, {duration, position, useQueue, ...}): Show any custom widget as a sliding notification.

Specialized Overlays

  • showAnchorOverlay({targetKey, child, preferredAlignment, showArrow, ...}): Attach an overlay to a specific widget.
  • showFuture({future, loading, success, error, ...}): Declarative way to handle async operation lifecycles.
  • showProgress(initialValue, {message, ...}): Returns a ProgressEntry handle for live updates.
  • showLoading({message, indicator, ...}): Show a manual loading overlay.
  • showOverlay(builder, {curve, duration, useQueue, id, strategy, ...}): The base API for full control over any overlay.

Global & Group Controls

  • dismissAllOverlays({animate, context}): Instantly clear all active overlays.
  • dismissOverlayGroup(group, {animate, context}): Dismiss all overlays belonging to a specific group.
  • pauseOverlayQueue(): Temporarily stop showing new queued overlays.
  • resumeOverlayQueue(): Resume processing and showing items in the queue.

Overlay Handles (OverlaySupportEntry)

Captured when you show any overlay:

  • entry.dismiss({animate}): Manually remove the overlay.
  • entry.complete(): Alias for dismiss (Promise-like API).
  • entry.update(): Trigger a rebuild of the overlay content.
  • entry.dismissed: A Future that completes when the overlay is gone.

📜 License

MIT License. See LICENSE for details.