flex_toast 1.0.1
flex_toast: ^1.0.1 copied to clipboard
A flexible toast library for Flutter with pluggable policies, layouts, transitions, and pre-built cards.
flex_toast #
A flexible, performant toast library for Flutter. Compose policies, layouts, and animations independently — or use sensible presets and pre-built cards out of the box.
Contents #
- Features
- Installation
- Quick Start
- Configuration Presets
- Theming
- Named Instances
- Custom Toasts and Policies
- Policy Reference
- API Overview
- Example
- Links
- License
- Publisher
Features #
- Pluggable Policies —
stack,replace,chain,sequential, or custom - Multiple Layouts — column, row, overlap, carousel
- Enter/Exit Transitions — fade, slide, scale, compose your own
- Position Transitions — FLIP-based slide, spring, and staggered animations
- Named Instances — separate toast channels (e.g. alerts vs. downloads)
- Pre-built Cards — filled, flat, flat-colored, and simple styles with variant constructors
- Theming —
FlexToastThemeas aThemeExtension - Safe area aware — configurable
marginapplied on top of system insets - Accessibility — 40 px minimum close-button tap targets
Installation #
Add flex_toast to your pubspec.yaml:
dependencies:
flex_toast: ^1.0.1
Then run:
flutter pub get
Quick Start #
Wrap your app with ToastProvider exactly once — typically in
MaterialApp.builder so toasts render above the navigator. Without it,
FlexToast.show() returns ToastId.invalid in release mode (and throws an
assertion in debug mode).
import 'package:flex_toast/flex_toast.dart';
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
builder: (context, child) => ToastProvider(child: child!),
home: const HomePage(),
);
}
}
Show a Toast #
FlexToast.instance.show(
const FlexToastCardFilled.success('Saved!'),
);
Dismiss Manually #
final id = FlexToast.instance.show(const Text('Working…'));
// …later
FlexToast.instance.dismiss(id);
// Or dismiss every toast on this instance:
FlexToast.instance.dismissAll();
Configuration Presets #
Each preset pairs a ToastPolicy with a matching default layout:
// All toasts visible, all timers run at once (default)
FlexToast.instance.show(toast);
// New toast replaces the current one (overlap + fade-in; previous exits instantly by default)
final status = FlexToast.configure('status', const ToastConfig.replace());
// All visible, only the oldest auto-dismisses at a time
final queue = FlexToast.configure('queue', const ToastConfig.chain());
// One toast at a time; the rest wait hidden
final alerts = FlexToast.configure('alerts', const ToastConfig.sequential());
Customize freely by composing any policy with any layout and transitions:
FlexToast.configure(
'custom',
ToastConfig(
policy: const ToastPolicy.chain(),
layout: const CarouselToastLayout(),
alignment: Alignment.bottomCenter,
enterTransition: const SlideToastTransition.fromTop(),
positionTransition: const StaggeredPositionTransition(),
),
);
Theming #
Register FlexToastTheme in ThemeData.extensions to remap variant colors
globally. Variant constructors (FlexToastCardFilled.success, .error,
.loading, etc.) resolve colors at build time. Loading styling varies by card
family:
- Filled — background uses
neutral, spinner usesforeground - Flat / FlatColored — accent bar/tint uses
neutral, spinner usesneutral - Simple — spinner uses
neutral
MaterialApp(
theme: ThemeData(
extensions: const [
FlexToastTheme(
success: Color(0xFF2E7D32),
foreground: Colors.white,
),
],
),
builder: (context, child) => ToastProvider(child: child!),
home: const HomePage(),
);
Explicit constructor colors always take precedence over the theme.
Named Instances #
final downloads = FlexToast.configure(
'downloads',
const ToastConfig.stack(alignment: Alignment.bottomRight),
);
downloads.show(const FlexToastCardFilled.info('Downloading file.zip'));
// Retrieve a configured instance later
final same = FlexToast.getInstance('downloads');
// Update config on the same instance (active toasts exit first)
FlexToast.getInstance('downloads').updateConfig(
const ToastConfig.stack(alignment: Alignment.bottomCenter),
);
// Default instance works the same way:
FlexToast.instance.updateConfig(
const ToastConfig.stack(alignment: Alignment.bottomCenter),
);
Custom Toasts and Policies #
Pass any Widget as toast content. Subclass ToastPolicy to control admission,
dismissal, and timer sequencing:
class MaxThreePolicy extends ToastPolicy {
const MaxThreePolicy();
@override
List<ToastEntry> onShow(List<ToastEntry> entries, ToastEntry newEntry) {
if (entries.length >= 3) {
return [...entries, newEntry.copyWith(state: ToastState.queued)];
}
return [...entries, newEntry];
}
}
See the example/ app for custom cards, layouts, position transitions, and
policies.
Policy Reference #
| Policy | Behavior | Default Layout |
|---|---|---|
stack |
All toasts visible; all timers run simultaneously | Column |
replace |
New toast dismisses active ones (instant exit + fade-in) | Overlap |
chain |
All visible; only the oldest auto-dismisses at a time | Column |
sequential |
One toast visible; others wait hidden until the current exits | Overlap |
API Overview #
| Type | Role |
|---|---|
FlexToast |
Show / dismiss / dismissAll; singleton + named instances via configure, getInstance, updateConfig |
ToastId |
Handle returned by show() for manual dismissal |
ToastProvider |
Renders toasts above app content (required once) |
ToastConfig |
Layout, alignment, margin, transitions, duration, policy |
ToastPolicy |
How multiple toasts coexist |
ToastLayout |
Visual arrangement of simultaneous toasts |
ToastTransition |
Enter / exit animation |
ToastPositionTransition |
Animation when stack position changes |
FlexToastTheme |
Global variant color palette |
FlexToastScope |
Lets pre-built card close buttons dismiss their toast |
| Pre-built cards | FlexToastCardFilled, FlexToastCardFlat, FlexToastCardFlatColored, FlexToastCardSimple |
Example #
Interactive playground with live configuration:
cd example && flutter run
Links #
License #
This project is licensed under the MIT License — see the LICENSE file for details.
Publisher #
Published by krajna.dev