context_show 0.3.2
context_show: ^0.3.2 copied to clipboard
A lightweight and flexible Flutter package for showing custom overlays, banners, toasts and dialogs with simple, context-based extension. Highly customizable and easy to use.
0.3.2 #
This release fixes safe area insets being lost when an overlay is shown from a page that rebuilt in the same turn.
π Bug Fixes #
- Safe area insets are no longer lost when the page rebuilds in the same turn as
show- The downward search for a
Scaffoldbailed out whenever the context wasdirty, which only means a rebuild is scheduled β the element still holds its previous children and walks fine. - Any page that changed state in the same turn it showed an overlay β a dialog flipping a flag, a provider landing β lost the app bar height and dropped the banner back onto the status bar.
- The guard is now keyed on
debugDoingBuild, the condition that actually makes the child list unsafe to walk. That signal is debug-only, so the walk is wrapped in aFlutterErrorcatch to keep release builds on theMediaQueryfallback rather than crashing.
- The downward search for a
0.3.1 #
This release fixes how overlays position themselves against the surrounding chrome, and stops closers from outliving the overlays they belong to.
π Bug Fixes #
- Safe area insets are now correct when
showis called from above theScaffold- A page showing an overlay from its own
build/Statecontext previously got the status bar height instead of the app bar height, so top banners painted over the app bar and hid the back button. Scaffold.maybeOfonly walks upwards; the lookup now falls back to a breadth-first search downwards when there is noScaffoldabove.- Nested
Scaffolds resolve to the outer one, which owns the chrome the overlay appears over. - Applies to both
AppBarHeightandBottomBarHeight.
- A page showing an overlay from its own
- An unrecognised
bottomNavigationBarno longer reports a negative inset. close()no longer hangs on an overlay whose tree was destroyed- It awaited the exit animation, but a torn-down tree has no ticker to drive
it, so the future never completed β leaving the closer registered and its
AnimationControllerundisposed for the rest of the process. - The animation is now skipped when the entry is already gone.
- It awaited the exit animation, but a torn-down tree has no ticker to drive
it, so the future never completed β leaving the closer registered and its
- Stale closers are pruned
- A closer whose overlay was destroyed without
close()stayed selectable byOverlays.all()forever. Eachshownow drops them. - An overlay that outlives its route is not stale: routes are entries in
one shared
Overlay, so a banner shown from a page deliberately survives apop. Callclose()explicitly if you want it gone with the page.
- A closer whose overlay was destroyed without
TransitionBuilders.sizeno longer uses the deprecatedSizeTransition.axisAlignment. Its ownaxisAlignmentargument is unchanged and is translated toalignmentinternally.- Overlays in a nested
Navigatorno longer clear the chrome twice- Insets are measured against the screen, but an
OverlayEntryis positioned against theOverlayit is inserted into, which does not have to start at the top of the screen. - With a nested
Navigatorinside aScaffoldbody (a per-tab navigator, for example) the overlay already begins below the app bar, so the full inset was applied on top of an origin that had cleared it β leaving a gap the height of the app bar. shownow measures the insets against the overlay the entry lands in, andoverlay.safeAreareports them in that overlay's coordinates.
- Insets are measured against the screen, but an
π Documentation #
- Documented the positioning modes in the README: safe area (default),
safeArea: falsefor edge-to-edge over the app bar, explicitmarginfor anything in between, per-edge insets viaoverlay.safeArea, and full-bleed backgrounds viabackgroundMargin. - Removed a docstring for a
fullScreenparameter that does not exist; the equivalent issafeArea: false.
ποΈ API #
OverlayController,OverlaySafeAreaandOverlayCloserare now exported frompackage:context_show/context_show.dart. They already appeared in public signatures, but could not be named without a direct import.OverlaySafeAreacan express its insets against a different surfaceOverlaySafeArea.oftakes an optionalsurface, and the newOverlaySafeArea.forSurfacere-expresses existing insets relative to a givenBuildContext.- Both subtract only what the surface already covers, and never go negative.
OverlayClosergained anisStale()method, reporting whether its overlay was torn down withoutclose()being called. The constructor takes an optional trailing callback backing it; existing three-argument calls are unaffected.AppBarHeight.maybeOfandBottomBarHeight.maybeOfnow resolve theScaffoldthrough the newScaffoldFinder, so they work from a context above theScaffoldas well as inside it.AppBarHeight.maybeOfdocuments that its result already includes the status bar β do not addMediaQuery.padding.topto it.
0.3.0 #
This release improves the context.close() API with flexible parameter ordering and includes CI/CD workflow improvements.
π₯ Breaking Changes #
context.close()signature changed to support flexible parameter ordering- Parameters can now be passed in any order:
(selector, result)or(result, selector) - Automatic detection of parameter types for improved developer experience
- This change may affect code that explicitly relies on positional parameter ordering
- Parameters can now be passed in any order:
// Both parameter orders now work
context.close(Overlays.first(), 'result_value');
context.close('result_value', Overlays.first());
// With custom selectors
context.close((overlays) => overlays.byId('myId'), 'result_value');
context.close('result_value', (overlays) => overlays.byId('myId'));
β¨ New Features #
- Flexible parameter ordering for
context.close()- Pass parameters in any order for better ergonomics
- Support for closing with selector, result, or both
- Enhanced documentation and examples
- Add comprehensive test suite for
context.close()functionality - Simplify CI workflows and add streamlined testing, formatting, and release automation
0.2.0 #
This release introduces a major API refactoring to provide more granular control over overlay layouts and improve flexibility.
π₯ Breaking Changes #
The context.show() method has been significantly refactored. The following parameters have been changed or removed:
fullScreenis removed.- To control whether the overlay respects the safe area, use the new
safeAreaparameter. - To show an overlay over the entire screen (including the app bar), use
rootOverlay: true.
- To control whether the overlay respects the safe area, use the new
alignmentdefault behavior is changed.- The default alignment is now
Alignment.center, in 0.1.0 default alignment wasAlignment.bottomCenter
- The default alignment is now
β¨ New Features #
Granular Layout & Behavior Control
| Parameter | Type | Description |
|---|---|---|
safeArea |
bool |
If true (default), the overlay respects all safe insets β including the system status bar, device notches, as well as Scaffold elements like AppBar and BottomNavigationBar. Ignored if margin (for content) or backgroundMargin (for background) is manually provided. |
margin |
EdgeInsets? |
Applies custom padding around the main content. Overrides safeArea for the content area. |
backgroundMargin |
EdgeInsets? |
Applies custom padding around the background layer. Overrides safeArea for the background. |
clipper |
Widget Function(Widget child)? |
Wraps the main content with any Flutter clipping widget (ClipRect, ClipRRect, ClipOval, etc.). |
backgroundClipper |
Widget Function(Widget child)? |
Same as clipper, but applied to the background widget. |
π§± Examples
Using a rectangular clip on the main content:
context.show(
(overlay) => MyOverlay(),
clipper: (child) => ClipRect(child: child),
);
Circular overlay background with custom margin (ignores safeArea):
context.show(
(overlay) => MyOverlay(),
background: (overlay) => Container(color: Colors.black54),
backgroundClipper: (child) => ClipOval(child: child),
backgroundMargin: EdgeInsets.all(16), // safeArea ignored for background
);
rootOverlay
A new boolean parameter that controls which Navigatorβs overlay is used:
rootOverlay: trueβ Inserts into the top-level Navigator (use when inside nested navigationrootOverlay: false(default) β Inserts into the closest local Navigator
Migration Guide #
Hereβs how to migrate your code from v0.1.0 to v0.2.0.
Replacement for fullScreen: true
In v0.2.0, the fullScreen parameter has been removed.
To achieve the same effect, use:
safeArea: falseβ disables padding around system UI (status bar, navigation bar, etc.)rootOverlay: trueβ ensures the overlay is inserted into the root navigator (recommended for nested navigation apps)
-context.show(
- (overlay) => MyOverlay(),
- fullScreen: true,
-);
+context.show(
+ (overlay) => MyOverlay(),
+ safeArea: false,
+ rootOverlay: true, // Optional: only needed in nested navigation contexts
+);
Default Alignment Change (Alignment.center)
In v0.2.0, the default alignment for context.show() is now Alignment.center.
You can remove the explicit parameter:
-context.show(
- (overlay) => MyOverlay(),
- alignment: Alignment.center,
-);
+context.show(
+ (overlay) => MyOverlay(),
+);
New Usage for Alignment.bottomCenter
If you now want to explicitly position your overlay at the bottom center:
context.show(
(overlay) => MyOverlay(),
-);
+ alignment: Alignment.bottomCenter,
+);
0.1.0 #
Initial release π
