back_stack 0.2.6 copy "back_stack: ^0.2.6" to clipboard
back_stack: ^0.2.6 copied to clipboard

You own the back stack. Navigation is a list you push and pop — type-safe, observable, no route graph.

0.2.6 #

Convenience additions inspired by other routers — all built as plain list ops / pure functions / one widget, so the core model is unchanged (no codegen, no dependencies).

  • NavStack.moveToTop(test) / pushOrMoveToTop(key) — reuse a screen that's already open instead of stacking a duplicate (singleTop/clearTop).
  • combineRedirects([...]) — compose several redirect rules (auth, onboarding, flags) into one redirect, each a pure proposed → RedirectStep (ContinueRedirect / RedirectTo(stack, stop:)). Same once-per-change, loop-proof semantics as a single redirect.
  • BackStackInspector<K> — a zero-dep in-app widget that lists the live stack (current entry marked), for debugging without any DevTools plumbing.

Not added, on purpose: a string query-parameter bag (typed key fields already carry a destination's arguments — a stringly-typed side channel would work against that) and a route-file code generator (back_stack stays codegen-free).

0.2.5 #

  • BackStackApp<K> — deep links in one function. A single widget bundles the MaterialApp.router + NavStackRouterDelegate + parser wiring; you supply only onLink: (Uri) => [destinations]. Optional toLink projects the stack back onto the web address bar, onLinkFallback handles bad links, and restorationScopeId is set by default. Zero new dependencies — it drives Flutter's own Router.
  • BackStack.parentOf<K>(context) (and maybeParentOf) — reach the stack one level up from a nested child when parent and child share the same key type, so a child screen can BackStack.parentOf<AppKey>(context).pop() the outer flow. (Distinct key subtypes + BackStack.of<ParentKey> remain the more type-safe default.)
  • example/lib/multi_file/ now uses BackStackApp — the simplest example also demonstrates deep links (/product/7).

0.2.4 #

  • Docs: the README hero snippet is corrected and no longer uses a switch — it leads with NavEntries (..on<Home>(...), builder: entries.call) over a non-sealed AppKey, so it compiles as shown and mirrors a multi-file app. (The previous snippet declared a sealed base with no const constructor and inferred NavStack<Home>, so it didn't compile.)
  • Adds example/lib/multi_file/ — the simplest multi-file layout: app_key.dart
    • one file per feature (home_feature.dart, product_feature.dart) each with its own destination, screen and register* call, collected in main.dart. No switch, no central list.

0.2.3 #

  • Fix: a pop(result) that is vetoed by guard (or collapsed to a no-op by redirect) no longer completes the destination's pushForResult future or returns true. Previously the awaiter received the result while the screen was still on top — now the result is delivered, and pop returns true, only when the entry actually leaves the stack. (popGuard was already safe.)
  • Docs: NavEntryDecorator.onRemoved notes that it runs during the display's build (defer any rebuild-triggering work with addPostFrameCallback); NavEntries documents that it matches by exact runtime type, not subtype.
  • Adds example/lib/modular_demo.dart (also on GitHub): three feature modules register their own NavEntries into one map, and a single NavEntryDecorator wraps every screen and logs teardown on onRemoved.

0.2.2 #

  • The main example (example/lib/main.dart, the one shown on the package page) now demonstrates NavEntries (as the builder) and NavEntryDecorator (a screen_view log + teardown hook) — so both APIs are visible on pub.dev's Example tab. No library code changed.

0.2.1 #

  • Add NavEntries<K> — a registrable destination-type → screen map (..on<Home>(...)), Compose Nav3's entryProvider. Pass builder: entries.call to NavDisplay. Composes across feature files/modules instead of one big switch. The switch stays the default (compile-time exhaustive); this is the modular option.
  • Add NavEntryDecorator<K> — Nav3's NavEntryDecorator. decorate wraps every screen (providers/DI scopes/tracing; first decorator is outermost) and onRemoved fires when an entry leaves the stack (or the display is disposed) so you can tear down a Bloc/controller/scope tied to a destination. Wire via the new decorators: on NavDisplay — also forwarded by MultiNavDisplay, NavSceneHost, NavListDetail, NavStackRouterDelegate and MultiNavStackRouterDelegate.

0.2.0 #

  • Add NavStackCodec.of(encode:, decode:, fallback:) — build a deep-link codec inline from two functions instead of subclassing NavStackCodec.
  • Add NavStackCodec.fallbackFor(uri) — the stack shown when a link is malformed or unknown (defaults to decoding /; supply fallback: or override to route to a NotFound screen).
  • Harden the deep-link boundary: NavStackRouterDelegate now decodes without ever throwing — a decode that throws or returns empty falls back instead of crashing the app, so codecs can parse optimistically.
  • Fix: pushForResult no longer hangs (and leaks its awaiter) when the push is blocked by guard or collapsed to a no-op by redirect — the future now resolves null, like every other way a screen can leave the stack.
  • Web + tabs: MultiNavStackRouterDelegate + MultiNavStackCodec bring URL sync, deep links and OS back to a MultiNavStack (per-tab history) — the multi-tab equivalents of NavStackRouterDelegate / NavStackCodec.
  • Restoration + tabs: RestorableMultiNavStack persists every tab's stack and the active tab across process death. Both restorable widgets now survive a corrupt/incompatible snapshot by keeping the freshly created stack instead of crashing on cold start.
  • MultiNavDisplay gains lazy (build a tab only once first selected; default false, unchanged behavior) and observers. observers is also now forwarded by NavSceneHost, NavListDetail and NavStackRouterDelegate — a clean NavigatorObserver seam for screen_view analytics.
  • NavListDetail now preserves pane State across the breakpoint. Rotating or resizing between the two-pane and stacked layouts keeps each screen's scroll position and controllers — every entry gets a stable GlobalKey, so Flutter reparents the live screen instead of rebuilding it.
  • Add MultiBackStack.of(context) (and MultiNavStackScope) — reach the MultiNavStack host from any tab screen to switch tabs / read the active index, without passing the host down by hand.

0.1.1 #

  • Docs: the demo GIF now uses an absolute URL so it renders on the pub.dev package page (a relative path inside a raw <img> tag wasn't rewritten).

0.1.0 #

  • Fix: Hero (shared-element) transitions now animate inside a nested NavDisplay — e.g. under NavListDetail or MaterialApp(home:). Each display drives its own HeroController via a HeroControllerScope, so a sprite flies between screens instead of snapping. Previously only the root/Router display inherited one. Regression-tested.

0.0.1 #

  • Adaptive layout: NavListDetail (one stack → two-pane on wide, animated stack on narrow) and the general NavSceneHost + NavSceneStrategy engine (listDetailScene, supportingPaneScene) — Compose Nav3 "scenes" over one list.
  • Multi-stack: MultiNavStack + MultiNavDisplay give a bottom-nav persistent per-tab back stack (IndexedStack), with innermost-first system back.
  • Custom pages: TransitionPage (.fade/.slideUp/.scale/.none), DialogPage, SheetPage, and a per-key NavPage mixin so a destination declares its own transition.
  • ConfirmPopScope: async confirm-before-leave covering the Android system back.
  • RestorableBackStack + NavKeyCodec: full-stack restoration across process death without a URL.
  • NavDisplay.nested flag routes the system back gesture into a nested stack.
  • Minimal rebuilds: pages are memoized by entry id, so one push rebuilds exactly one screen regardless of stack depth (see benchmark/).
  • popGuard (sync pop veto) and refreshListenable (re-run redirect on auth change) on NavStack.
  • NavStack: the back stack you own. push / pop / replaceTop / replaceAll / popUntil / edit. BackStack.of(context) reaches it from a screen (auto-provided by NavDisplay).
  • Auth gating: redirect (pure transform, applied once — loop-proof) and guard (veto).
  • NavDisplay: renders the stack via the Pages API; system / predictive / hardware back sync into the list automatically (onDidRemovePage).
  • NavKey: type-safe destinations as plain Dart objects. EquatableNavKey mixin gives them value equality so a URL re-decode reuses the live screen.
  • Identity & State preservation: stable unique id per entry (unique page key); duplicate destinations are independent; replaceAll/edit reconcile so survivors keep their State and only changed screens rebuild.
  • Result passing: pushForResult<T>() -> Future<T?>, completed by pop([result]) or null on any other removal / dispose (never hangs/leaks).
  • Router integration: NavStackRouterDelegate + NavStackRouteInformationParser
    • a NavStackCodec (Uri <-> List<NavKey>): web URL sync, deep links (you choose layer-vs-replace), browser/OS/predictive back, and state restoration.
  • Leak-safe: leaving the stack disposes the route (proven by test); suite runs under leak_tracker_flutter_testing. 42 tests + benchmarks, analyze clean under very_good_analysis (strict casts/inference/raw-types).
  • Docs: doc/PHILOSOPHY.md maps Flutter's model + the nav leak/caveat catalog.
5
likes
0
points
1.02k
downloads

Publisher

verified publisherandroidpoet.dev

Weekly Downloads

You own the back stack. Navigation is a list you push and pop — type-safe, observable, no route graph.

Repository (GitHub)
View/report issues

Topics

#navigation #router #navigator #routing

License

unknown (license)

Dependencies

flutter

More

Packages that depend on back_stack