ngx-stack 22.0.0 → 22.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -14
- package/fesm2022/ngx-stack.mjs +9 -0
- package/fesm2022/ngx-stack.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ngx-stack.d.ts +11 -9
package/README.md
CHANGED
|
@@ -589,20 +589,41 @@ matters for more than the back button: `hasSystemBackGesture` keys off `isNative
|
|
|
589
589
|
**Cordova** app doesn't needlessly concede the first 16px of the screen edge to a gesture its
|
|
590
590
|
webview doesn't have.
|
|
591
591
|
|
|
592
|
-
## The iOS
|
|
593
|
-
|
|
594
|
-
In **iOS Safari and iOS PWAs** — not Capacitor — WebKit
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
592
|
+
## The iOS Safari caveat, honestly
|
|
593
|
+
|
|
594
|
+
In **iOS Safari and iOS PWAs** — not Capacitor — WebKit runs its own interactive edge-swipe back
|
|
595
|
+
navigation, and it will win over this library's. This is a real, long-standing WebKit limitation,
|
|
596
|
+
not something the library is failing to work around.
|
|
597
|
+
|
|
598
|
+
**What actually gives that gesture something to grab is browser history.** The system swipe navigates
|
|
599
|
+
`history.back()`. This library is built on the Angular Router and every push is a _real_ history
|
|
600
|
+
entry — that is what makes deep links, reload, share, and the browser's own back button work. The
|
|
601
|
+
cost is that WebKit's edge swipe then has a real target, and at the very edge it navigates before our
|
|
602
|
+
gesture arms.
|
|
603
|
+
|
|
604
|
+
Worth being precise about, because it is tempting to think otherwise: **nothing web-side reliably
|
|
605
|
+
disables that gesture.** Not `overscroll-behavior`, not `touch-action`, and not `preventDefault` on
|
|
606
|
+
touchstart. Frameworks that appear to "block" it (Framework7, for instance) do so by _not writing to
|
|
607
|
+
browser history at all_ — with no previous entry, the swipe has nowhere to go and fires inertly. That
|
|
608
|
+
is a different trade than this library makes, and it costs you real URLs.
|
|
609
|
+
|
|
610
|
+
So, honestly:
|
|
611
|
+
|
|
612
|
+
- **Capacitor / Cordova is the clean answer.** Their WKWebView has `allowsBackForwardNavigationGestures`
|
|
613
|
+
off, so there is no system gesture and ours simply works. This is the target the library is built
|
|
614
|
+
for.
|
|
615
|
+
- **In iOS Safari**, the settings below only _reduce the overlap_ — they do not defeat the system
|
|
616
|
+
gesture:
|
|
617
|
+
|
|
618
|
+
| `systemGesture` | What it does |
|
|
619
|
+
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
620
|
+
| `'inset'` | **Default.** Start our zone `systemEdgeInset` px (16) inland, so a drag that begins past the very edge is ours. WebKit still owns the outermost pixels; when _it_ navigates we detect `hasUAVisualTransition` and skip our animation rather than double-animating. |
|
|
621
|
+
| `'suppress'` | `preventDefault()` the touchstart in the edge zone. Helps in some embedded WebViews, but **does not stop mobile Safari's system navigation** — and it suppresses the synthetic `click` for touches starting there. Rarely worth it. |
|
|
622
|
+
| `'ignore'` | Do nothing; let both gestures coexist. |
|
|
623
|
+
|
|
624
|
+
If winning the gesture in iOS Safari matters more to you than real URLs, the way to get there is the
|
|
625
|
+
Framework7 trade — drive the stack without back-navigable history entries (`replaceState` instead of
|
|
626
|
+
`pushState`). The library doesn't do that today; open an issue if you want it as a mode.
|
|
606
627
|
|
|
607
628
|
## Page lifecycle
|
|
608
629
|
|
package/fesm2022/ngx-stack.mjs
CHANGED
|
@@ -1604,6 +1604,15 @@ const CSS = `
|
|
|
1604
1604
|
height: 100%;
|
|
1605
1605
|
overflow: hidden;
|
|
1606
1606
|
|
|
1607
|
+
/* Stop Chrome/Android turning a horizontal drag that is not an armed swipe into its own overscroll
|
|
1608
|
+
back-navigation, which would fire underneath the gesture and fight it. This is the one thing web
|
|
1609
|
+
content genuinely can do about a system gesture, and only on Android: iOS Safari's edge swipe is
|
|
1610
|
+
drawn by WebKit and no CSS or preventDefault suppresses it (that is what systemGesture is for,
|
|
1611
|
+
and why native shells are the easy target). Framework7 ships the same line for the same reason. */
|
|
1612
|
+
overscroll-behavior: none;
|
|
1613
|
+
/* Kills the 300ms double-tap-zoom delay without touching the pan/scroll the gesture relies on. */
|
|
1614
|
+
touch-action: manipulation;
|
|
1615
|
+
|
|
1607
1616
|
/* Notches, home indicators, and the Android navigation bar. Declared here so pages can just
|
|
1608
1617
|
use var(--ngx-stack-safe-top) without every one of them repeating the env() dance — and so
|
|
1609
1618
|
they still resolve to 0px on a browser that has never heard of a notch. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngx-stack.mjs","sources":["../../../projects/ngx-stack/src/lib/config.ts","../../../projects/ngx-stack/src/lib/platform/platform.ts","../../../projects/ngx-stack/src/lib/router/parent-url.ts","../../../projects/ngx-stack/src/lib/router/route-reuse-strategy.ts","../../../projects/ngx-stack/src/lib/router/stack-history.ts","../../../projects/ngx-stack/src/lib/router/stack-nav.ts","../../../projects/ngx-stack/src/lib/provide.ts","../../../projects/ngx-stack/src/lib/gesture/velocity-tracker.ts","../../../projects/ngx-stack/src/lib/gesture/swipe-back-gesture.ts","../../../projects/ngx-stack/src/lib/gesture/swipe-service.ts","../../../projects/ngx-stack/src/lib/animation/rise.ts","../../../projects/ngx-stack/src/lib/animation/android-transition.ts","../../../projects/ngx-stack/src/lib/animation/transition.ts","../../../projects/ngx-stack/src/lib/animation/slide.ts","../../../projects/ngx-stack/src/lib/animation/ios-transition.ts","../../../projects/ngx-stack/src/lib/animation/web-transition.ts","../../../projects/ngx-stack/src/lib/animation/transition-player.ts","../../../projects/ngx-stack/src/lib/core/announcer.ts","../../../projects/ngx-stack/src/lib/core/stack-entry.ts","../../../projects/ngx-stack/src/lib/core/stack-controller.ts","../../../projects/ngx-stack/src/lib/core/styles.ts","../../../projects/ngx-stack/src/lib/core/stack-host.ts","../../../projects/ngx-stack/src/lib/platform/system-transition.ts","../../../projects/ngx-stack/src/lib/router/tab-url.ts","../../../projects/ngx-stack/src/lib/router/stack-outlet.ts","../../../projects/ngx-stack/src/lib/nav/ngx-stack.ts","../../../projects/ngx-stack/src/lib/router/stack-tabs.ts","../../../projects/ngx-stack/src/lib/animation/none-transition.ts","../../../projects/ngx-stack/src/public-api.ts","../../../projects/ngx-stack/src/ngx-stack.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport type { StackTransition } from './animation/transition';\nimport type { StackPlatformKind } from './platform/platform';\n\n/** A transition per platform. Anything you leave out keeps the built-in for that platform. */\nexport interface StackTransitionMap {\n ios?: StackTransition;\n android?: StackTransition;\n web?: StackTransition;\n}\n\n/**\n * What to do about the browser's *own* edge-swipe back gesture.\n *\n * Only relevant on iOS Safari and iOS standalone PWAs — WebKit reserves the screen edge for\n * its own interactive back navigation and gives you no way to turn it off. Under Capacitor\n * the webview has no such gesture, so this setting does nothing there.\n */\nexport type SystemGesturePolicy =\n /**\n * Start our gesture zone a few px inland so the two don't fight over the same pixels. The\n * system still owns the outermost `systemEdgeInset` px; when it fires we notice and skip\n * our own animation rather than drawing a second one on top of WebKit's.\n */\n | 'inset'\n /**\n * `preventDefault()` the touchstart inside the edge zone, which stops WebKit starting its\n * gesture. Reliable, but it also suppresses the synthetic `click` for touches beginning\n * there — don't use it if you have tappable UI within `swipeEdgeWidth` px of the edge.\n */\n | 'suppress'\n /** Do nothing, and let both gestures coexist. */\n | 'ignore';\n\n/**\n * What to do when the page on top has a `canDeactivate` guard.\n *\n * The gesture animates the page away *before* the navigation runs, so a guard that later says\n * no leaves us with nothing to do but snap the page back — a visible, ugly bounce. Guards can\n * also be async, and a touch handler cannot wait for a promise.\n */\nexport type GuardPolicy =\n /**\n * **Default.** A route with a `canDeactivate` guard is not swipeable, unless its component\n * implements `ngxCanSwipeBack()` — which is synchronous, so the gesture can simply not start.\n * Your back button still runs the guard normally, and that's where a confirm dialog belongs.\n */\n | 'block'\n /**\n * Let the gesture run and take the bounce if the guard refuses. Pick this only when you know\n * your guards effectively always pass.\n */\n | 'allow';\n\nexport interface NgxStackConfig {\n /** Force a platform instead of detecting it. Handy for testing an iOS build on a laptop. */\n platform?: StackPlatformKind | 'auto';\n\n /**\n * Writing direction. `'auto'` reads the computed `direction` off the host element, so an\n * app that sets `<html dir=\"rtl\">` mirrors everything with no configuration: the transitions\n * come from the other side and the swipe lives on the right edge.\n */\n direction?: 'auto' | 'ltr' | 'rtl';\n\n /**\n * The page transition. Pass one function to use it everywhere, or a\n * {@link StackTransitionMap} to vary it by platform.\n */\n transitions?: StackTransition | StackTransitionMap;\n\n /**\n * Base duration in ms. Built-in transitions scale this to taste (Android and web run shorter\n * than iOS). A custom transition returns its own duration and can ignore it.\n */\n duration?: number;\n\n /**\n * The tabs, as URL path prefixes: `['home', 'search', 'profile']`.\n *\n * Set this and each one gets its own independent stack. Switching tabs unwinds nothing and\n * destroys nothing — the tab you left keeps its pages mounted, exactly where you were, and comes\n * back that way. Leave it unset and there's a single stack, which is the common case.\n *\n * It has to be declared, because nothing in a route config distinguishes \"these are siblings you\n * switch between, each keeping its own history\" from \"these are just different URLs\". `/settings`\n * is a tab and `/settings/sheet` is a page inside it; only you know that.\n *\n * It isn't repeated anywhere, though — {@link NgxStackTabs} exposes it as `tabs()`, so the same\n * declaration also renders your tab bar. And a route whose URL doesn't happen to start with its\n * tab's name can say where it belongs with `data: { tab: 'search' }`.\n */\n tabs?: string[];\n\n /**\n * Rebuild the pages that *should* have been underneath, when the app opens partway in — a push\n * notification, a shared link, a refresh three screens deep.\n *\n * Without this the router lands you on the detail page with a stack of exactly one: nothing for a\n * swipe to drag into view. (The back *button* is a separate matter and always works — declare\n * `data: { parent: '/inbox' }` on the route.)\n *\n * - `true` — work the ancestors out from the route config: `data: { parent }` where you've\n * declared one, otherwise the URL's own nesting (`/inbox/item/12/notes` → `/inbox/item/12` →\n * `/inbox`).\n * - a function — your own `(url) => parentUrl | null`, applied repeatedly to build a chain. For a\n * URL scheme whose nesting doesn't reflect the screens, or routes behind `loadChildren`, whose\n * children can't be inspected without loading them.\n *\n * Nothing else to set up: the first navigation is intercepted before anything is built, so the\n * deep page is still constructed exactly once — at the end, on top of its ancestors.\n *\n * The cost is real, though: the ancestors are built and **their resolvers run**, for pages the\n * user may never look at. If your list page does something expensive on load, leave this off and\n * let the first back be a tap.\n */\n deepLinks?: boolean | ((url: string) => string | null);\n\n /**\n * Cap on how many pages one stack keeps mounted. `0` (the default) means no cap.\n *\n * Pages are cheap but not free, and a stack you can descend forever — a chat, a wiki, a file\n * browser — will happily hold fifty live components. With a cap, pages that fall off the\n * bottom are destroyed. Going back past that horizon still works: the page is rebuilt from\n * its URL and still animates as a *back*, so nothing looks wrong. It just lost its state,\n * which is the trade you asked for.\n */\n maxDepth?: number;\n\n /**\n * Move focus into the page that just entered, and announce it to screen readers. Default\n * `true`. Without this, a screen-reader user gets no signal that the page changed and their\n * focus stays on a control that has now slid off the screen.\n */\n manageFocus?: boolean;\n\n /** See {@link GuardPolicy}. */\n guardPolicy?: GuardPolicy;\n\n /**\n * Interactive swipe-to-go-back. `'auto'` arms it on iOS only — Android's back gesture belongs\n * to the OS, and the default web transition is too subtle to scrub usefully.\n *\n * Only the starting value; {@link NgxStackSwipe} changes it at runtime.\n */\n swipeBack?: boolean | 'auto';\n\n /** Width of the edge zone, in px, in which a swipe can begin. Mirrored in RTL. */\n swipeEdgeWidth?: number;\n\n /** Progress in `[0, 1]` past which releasing the finger completes the pop. */\n swipeThreshold?: number;\n\n /** px/ms. A flick faster than this decides on its own, whatever the progress. */\n swipeVelocityThreshold?: number;\n\n /** See {@link SystemGesturePolicy}. */\n systemGesture?: SystemGesturePolicy;\n\n /** With `systemGesture: 'inset'`, how many px at the very edge to concede to the browser. */\n systemEdgeInset?: number;\n\n /** Also allow dragging with a mouse. For developing the gesture in a desktop browser. */\n swipeWithMouse?: boolean;\n\n /** Animate the very first page pushed onto an empty stack. */\n animateRoot?: boolean;\n\n /**\n * Honour `prefers-reduced-motion: reduce` by making transitions instant. Default `true`.\n *\n * The swipe-back keeps its animation regardless, on purpose: motion the user is dragging with\n * their own finger is direct manipulation, which the guidance exempts — and a swipe with no\n * visual response isn't reduced motion, it's a broken gesture.\n */\n respectReducedMotion?: boolean;\n}\n\nexport type ResolvedStackConfig = Required<Omit<NgxStackConfig, 'transitions' | 'tabs'>> &\n Pick<NgxStackConfig, 'transitions' | 'tabs'>;\n\nexport const NGX_STACK_DEFAULTS: ResolvedStackConfig = {\n platform: 'auto',\n direction: 'auto',\n duration: 420,\n deepLinks: false,\n maxDepth: 0,\n manageFocus: true,\n guardPolicy: 'block',\n swipeBack: 'auto',\n swipeEdgeWidth: 50,\n swipeThreshold: 0.5,\n swipeVelocityThreshold: 0.35,\n systemGesture: 'inset',\n systemEdgeInset: 16,\n swipeWithMouse: false,\n animateRoot: false,\n respectReducedMotion: true,\n};\n\nexport const NGX_STACK_CONFIG = new InjectionToken<ResolvedStackConfig>('ngx-stack.config', {\n providedIn: 'root',\n factory: () => NGX_STACK_DEFAULTS,\n});\n","import { InjectionToken, inject } from '@angular/core';\nimport { DOCUMENT } from '@angular/core';\n\n/** The three surfaces that get their own transition. */\nexport type StackPlatformKind = 'ios' | 'android' | 'web';\n\nexport interface StackPlatform {\n /** Which transition this device gets by default. Decided by OS, not by browser vs native. */\n readonly kind: StackPlatformKind;\n readonly isIos: boolean;\n readonly isAndroid: boolean;\n /** Running inside a Capacitor native webview. */\n readonly isCapacitor: boolean;\n /** Running inside a Cordova / PhoneGap native webview. */\n readonly isCordova: boolean;\n /** Either of the above: a native webview shell rather than a real browser. */\n readonly isNative: boolean;\n /** Installed to the home screen and running without browser chrome. */\n readonly isStandalonePwa: boolean;\n /**\n * True when the browser runs its own interactive back gesture at the screen edge, so we have to\n * share (or fight over) those pixels.\n *\n * That means iOS Safari and iOS PWAs. Native shells — Capacitor and Cordova alike — leave\n * `allowsBackForwardNavigationGestures` off in their WKWebView, so the edge is ours alone. Which\n * is why native is the easy target and the browser is the awkward one.\n */\n readonly hasSystemBackGesture: boolean;\n}\n\nexport function detectPlatform(win: Window & typeof globalThis): StackPlatform {\n const nav = win.navigator;\n const ua = nav?.userAgent ?? '';\n\n // iPadOS 13+ reports itself as a Mac, so a Mac with a touchscreen is really an iPad.\n const isIos =\n /iPad|iPhone|iPod/.test(ua) || (/Macintosh/.test(ua) && (nav?.maxTouchPoints ?? 0) > 1);\n const isAndroid = /Android/.test(ua);\n\n const shell = win as unknown as {\n Capacitor?: { isNativePlatform?: () => boolean };\n cordova?: unknown;\n };\n\n const isCapacitor = !!shell.Capacitor?.isNativePlatform?.();\n const isCordova = !isCapacitor && shell.cordova !== undefined;\n const isNative = isCapacitor || isCordova;\n\n const isStandalonePwa =\n (nav as unknown as { standalone?: boolean })?.standalone === true ||\n win.matchMedia?.('(display-mode: standalone)').matches === true;\n\n return {\n kind: isIos ? 'ios' : isAndroid ? 'android' : 'web',\n isIos,\n isAndroid,\n isCapacitor,\n isCordova,\n isNative,\n isStandalonePwa,\n // Note this keys off `isNative`, not `isCapacitor`. Getting that wrong would make an iOS\n // Cordova app needlessly concede the first 16px of the screen edge to a gesture its webview\n // does not have.\n hasSystemBackGesture: isIos && !isNative,\n };\n}\n\nexport const NGX_STACK_PLATFORM = new InjectionToken<StackPlatform>('ngx-stack.platform', {\n providedIn: 'root',\n factory: () => {\n const doc = inject(DOCUMENT);\n const win = doc.defaultView;\n if (!win) {\n // SSR / no DOM: nothing animates anyway, so report the dullest possible platform.\n return {\n kind: 'web',\n isIos: false,\n isAndroid: false,\n isCapacitor: false,\n isCordova: false,\n isNative: false,\n isStandalonePwa: false,\n hasSystemBackGesture: false,\n };\n }\n return detectPlatform(win as Window & typeof globalThis);\n },\n});\n","import type { Route, Routes } from '@angular/router';\n\n/** Split a URL into path segments, dropping the query and fragment. */\nfunction segmentsOf(url: string): string[] {\n return url.split(/[?#]/, 1)[0].split('/').filter(Boolean);\n}\n\n/**\n * Find the route a set of URL segments would land on.\n *\n * A deliberately small re-implementation of route matching, because Angular's recogniser is not\n * public and we need an answer *before* any navigation has happened. It understands static\n * segments, `:params`, and children — which is what a URL hierarchy is made of.\n *\n * What it does not understand is `loadChildren`: the child routes are behind a dynamic import and\n * simply don't exist yet. Rather than guess, it declines to match into a lazy subtree, so pages in\n * one won't have a parent derived for them. Say so explicitly with `data: { parent }`.\n */\nexport function findRoute(routes: Routes | undefined, segments: string[]): Route | null {\n if (!routes) return null;\n\n for (const route of routes) {\n // A redirect isn't a page, and `**` matches everything — it would happily claim to be the\n // parent of anything, which is worse than having no parent at all.\n if (route.redirectTo !== undefined || route.path === '**') continue;\n\n const path = (route.path ?? '').split('/').filter(Boolean);\n if (segments.length < path.length) continue;\n\n const consumed = path.every((part, i) => part.startsWith(':') || part === segments[i]);\n if (!consumed) continue;\n\n const rest = segments.slice(path.length);\n\n if (rest.length === 0) {\n if (route.component || route.loadComponent) return route;\n // A componentless wrapper: the page is its empty-path child.\n const child = findRoute(route.children, []);\n if (child) return child;\n continue;\n }\n\n const child = findRoute(route.children, rest);\n if (child) return child;\n }\n\n return null;\n}\n\n/**\n * Where a page sits, when it's the first thing the app opened.\n *\n * Two sources, in order:\n *\n * 1. **`data: { parent: '/inbox' }`** on the route. The same declaration the back button uses, so\n * you write it once and it drives both. Necessary whenever the URL doesn't tell the truth about\n * the hierarchy — flat routes like `/item/42`, or a detail page reachable from two places.\n *\n * 2. **The URL's own nesting.** `/inbox/item/12/notes` → `/inbox/item/12` → `/inbox`: drop\n * segments until what's left is a real page. Costs nothing to set up and is right most of the\n * time, because most apps already nest their URLs the way their screens nest.\n */\nexport function deriveParentUrl(routes: Routes, url: string): string | null {\n const segments = segmentsOf(url);\n if (segments.length === 0) return null;\n\n const declared = findRoute(routes, segments)?.data?.['parent'];\n if (typeof declared === 'string') return declared;\n\n for (let length = segments.length - 1; length > 0; length--) {\n const candidate = segments.slice(0, length);\n const route = findRoute(routes, candidate);\n\n if (route?.component || route?.loadComponent) {\n return `/${candidate.join('/')}`;\n }\n }\n\n return null;\n}\n","import { Injectable } from '@angular/core';\nimport type {\n ActivatedRouteSnapshot,\n DetachedRouteHandle,\n RouteReuseStrategy,\n} from '@angular/router';\n\n/**\n * Turns off Angular's own route store/detach machinery, because the stack does that job\n * instead — and better, for this purpose: Angular's version stores a detached view and\n * gives it back on request, while the stack keeps every page mounted and on screen, which\n * is what lets a swipe reveal the page underneath before any navigation has happened.\n *\n * The one thing we do care about is `shouldReuseRoute`. Angular's default reuses a route\n * whose config matches, so `/item/1 → /item/2` would recycle the same component instance.\n * On a stack those are two different pages, and going back from one to the other has to\n * work, so a change of params means a new page.\n */\n@Injectable()\nexport class NgxStackRouteReuseStrategy implements RouteReuseStrategy {\n shouldDetach(): boolean {\n return false;\n }\n\n shouldAttach(): boolean {\n return false;\n }\n\n store(): void {\n // no-op\n }\n\n retrieve(): DetachedRouteHandle | null {\n return null;\n }\n\n shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {\n if (future.routeConfig !== curr.routeConfig) return false;\n\n const futureParams = future.params;\n const currParams = curr.params;\n const futureKeys = Object.keys(futureParams);\n if (futureKeys.length !== Object.keys(currParams).length) return false;\n\n return futureKeys.every((key) => futureParams[key] === currParams[key]);\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NavigationEnd, NavigationStart, Router } from '@angular/router';\n\n/**\n * A shadow copy of where we are in the browser's history.\n *\n * The browser will not tell you what `history.back()` would land on, and with tabs we have to\n * know. History is one linear thread; tabs are several independent stacks. Drill into Inbox,\n * switch to Search, drill in there — now the entry behind you is an *Inbox* page, and going\n * \"back\" in Search must not take you to it. So we keep our own list and cursor, and whoever is\n * popping can ask whether plain `history.back()` happens to do the right thing.\n */\n@Injectable({ providedIn: 'root' })\nexport class NgxStackHistory {\n private readonly router = inject(Router);\n\n private entries: string[] = [];\n private cursor = -1;\n\n private trigger: 'imperative' | 'popstate' | 'hashchange' = 'imperative';\n private replacing = false;\n\n constructor() {\n this.router.events.pipe(takeUntilDestroyed()).subscribe((event) => {\n if (event instanceof NavigationStart) {\n this.trigger = event.navigationTrigger ?? 'imperative';\n this.replacing = this.router.getCurrentNavigation()?.extras.replaceUrl === true;\n return;\n }\n if (event instanceof NavigationEnd) {\n this.record(event.urlAfterRedirects);\n }\n });\n }\n\n /** Where `history.back()` would actually land, or `null` if there's nothing behind us. */\n previousUrl(): string | null {\n return this.cursor > 0 ? this.entries[this.cursor - 1] : null;\n }\n\n private record(url: string): void {\n if (this.trigger === 'popstate') {\n // The browser moved the cursor. Work out which way by looking either side of it.\n if (this.cursor > 0 && this.entries[this.cursor - 1] === url) {\n this.cursor--;\n return;\n }\n if (this.cursor + 1 < this.entries.length && this.entries[this.cursor + 1] === url) {\n this.cursor++;\n return;\n }\n // A jump of more than one step, or into history from before the app loaded. We can't map\n // it, so drop what we think we know rather than answer confidently and wrongly.\n this.entries = [url];\n this.cursor = 0;\n return;\n }\n\n if (this.replacing && this.cursor >= 0) {\n this.entries[this.cursor] = url;\n return;\n }\n\n // A fresh navigation discards anything ahead of the cursor, exactly as the browser does.\n this.entries = this.entries.slice(0, this.cursor + 1);\n this.entries.push(url);\n this.cursor = this.entries.length - 1;\n }\n}\n","import { Location } from '@angular/common';\nimport { Injectable, inject } from '@angular/core';\nimport { Router, type NavigationExtras } from '@angular/router';\n\nimport { NgxStackHistory } from './stack-history';\n\n/** Key we tuck the intent under in `NavigationExtras.state`. */\nexport const NGX_STACK_DIRECTION = '__ngxStackDirection';\n\n/** Lets a caller force a transition to be instant, e.g. while rebuilding a stack at startup. */\nexport const NGX_STACK_ANIMATED = '__ngxStackAnimated';\n\nexport type StackNavHint = 'forward' | 'back' | 'root';\n\n/** Where a \"back\" would actually go. */\nexport interface BackTarget {\n url: string;\n /**\n * Whether that URL is a page we already have mounted beneath the current one. When it isn't —\n * a cold deep link, where there is nothing underneath — going back has to build it.\n */\n mounted: boolean;\n}\n\n/** Implemented by the outlet, so `back()` knows what is actually beneath the current page. */\nexport interface StackBackTarget {\n backTarget(): BackTarget | null;\n}\n\n/**\n * Navigation with an explicit stack intent.\n *\n * You don't have to use this for pushing — plain `router.navigate()` works, and the outlet infers\n * the direction by checking whether the target URL is already on the stack. It's for the cases\n * where that inference is wrong, and for going back, which is subtler than it looks.\n */\n@Injectable({ providedIn: 'root' })\nexport class NgxStackNav {\n private readonly router = inject(Router);\n private readonly location = inject(Location);\n private readonly history = inject(NgxStackHistory);\n\n private target: StackBackTarget | null = null;\n\n /** @internal Called by `NgxStackOutlet`. */\n registerStack(target: StackBackTarget): void {\n this.target = target;\n }\n\n /** @internal */\n unregisterStack(target: StackBackTarget): void {\n if (this.target === target) this.target = null;\n }\n\n /**\n * Is there anywhere to go back to *within the app*?\n *\n * Ask this, not the shell. Capacitor and Cordova both report whether the *webview* can go back,\n * which is a statement about history — and history is a single linear thread while tabs are\n * several stacks, so it says yes when the only thing behind you is a different tab.\n */\n canGoBack(): boolean {\n return (this.target?.backTarget() ?? null) !== null;\n }\n\n /** Push a page on top, even if its URL is already somewhere on the stack. */\n forward(commands: unknown[] | string, extras?: NavigationExtras): Promise<boolean> {\n return this.navigate(commands, extras, 'forward');\n }\n\n /**\n * Go back one page. This is what the swipe gesture commits to, and what a back button should\n * call. There are three quite different situations behind that one word, and this picks between\n * them:\n *\n * 1. **There's a page below, and it's also the previous history entry.** The easy case. Use a\n * real `history.back()`, so the URL, the browser's back button and the stack all keep telling\n * the same story.\n *\n * 2. **There's a page below, but history disagrees.** This is what tabs do to you: history is a\n * single linear thread, tabs are several stacks, and switching tabs leaves an unrelated page\n * sitting behind you. `history.back()` would jump sideways out of the stack you're in, so\n * navigate to the page we actually mean instead, replacing the current entry so that popping\n * doesn't inflate history.\n *\n * 3. **There's nothing below at all.** A cold deep link — a push notification, a shared URL, a\n * refresh three screens in. `history.back()` here walks out of the app entirely, which is\n * almost never what the user meant by tapping a back arrow inside it. If the route declares\n * where it sits (`data: { parent: '/inbox' }`) we build that page and animate to it as a back,\n * exactly as though it had been there all along.\n */\n back(commands?: unknown[] | string, extras?: NavigationExtras): Promise<boolean> {\n if (commands !== undefined) {\n return this.navigate(commands, extras, 'back');\n }\n\n const target = this.target?.backTarget() ?? null;\n\n if (!target) {\n // Genuinely nowhere to go: no page below, no declared parent. Defer to the browser, which\n // may well leave the app — the honest outcome of there being nothing to go back to.\n this.location.back();\n return Promise.resolve(true);\n }\n\n if (target.mounted && this.history.previousUrl() === target.url) {\n this.location.back();\n return Promise.resolve(true);\n }\n\n return this.navigate(target.url, { ...extras, replaceUrl: true }, 'back');\n }\n\n /** Throw every stack away and start again from this page. */\n root(commands: unknown[] | string, extras?: NavigationExtras): Promise<boolean> {\n return this.navigate(commands, { ...extras, replaceUrl: true }, 'root');\n }\n\n private navigate(\n commands: unknown[] | string,\n extras: NavigationExtras | undefined,\n hint: StackNavHint,\n ): Promise<boolean> {\n const merged: NavigationExtras = {\n ...extras,\n state: { ...(extras?.state ?? {}), [NGX_STACK_DIRECTION]: hint },\n };\n return Array.isArray(commands)\n ? this.router.navigate(commands, merged)\n : this.router.navigateByUrl(commands, merged);\n }\n}\n\n/**\n * Read the intent off the navigation currently in flight.\n *\n * Only honoured for imperative navigations. A `popstate` carries the history entry's *stored*\n * state, which still holds whatever hint was set when that entry was first pushed — so trusting\n * it would make pressing Back re-read an old `'forward'` and push a duplicate page. For history\n * traversal the outlet works the direction out from the stack instead, which is unambiguous.\n */\nexport function readDirectionHint(router: Router): StackNavHint | null {\n const navigation = router.getCurrentNavigation();\n if (!navigation || navigation.trigger !== 'imperative') return null;\n\n const state = navigation.extras.state as Record<string, unknown> | undefined;\n const hint = state?.[NGX_STACK_DIRECTION];\n return hint === 'forward' || hint === 'back' || hint === 'root' ? hint : null;\n}\n\n/** `false` when the caller wants this navigation to land with no transition at all. */\nexport function readAnimatedHint(router: Router): boolean | null {\n const navigation = router.getCurrentNavigation();\n if (!navigation || navigation.trigger !== 'imperative') return null;\n\n const state = navigation.extras.state as Record<string, unknown> | undefined;\n const animated = state?.[NGX_STACK_ANIMATED];\n return typeof animated === 'boolean' ? animated : null;\n}\n","import {\n DestroyRef,\n DOCUMENT,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n inject,\n type EnvironmentProviders,\n} from '@angular/core';\nimport { NavigationStart, RouteReuseStrategy, Router } from '@angular/router';\n\nimport { NGX_STACK_CONFIG, NGX_STACK_DEFAULTS, type NgxStackConfig } from './config';\nimport { NGX_STACK_PLATFORM } from './platform/platform';\nimport { deriveParentUrl } from './router/parent-url';\nimport { NgxStackRouteReuseStrategy } from './router/route-reuse-strategy';\nimport { NgxStackNav, NGX_STACK_ANIMATED, NGX_STACK_DIRECTION } from './router/stack-nav';\n\n/**\n * Wire up the stack. One call, everything in it.\n *\n * ```ts\n * bootstrapApplication(App, {\n * providers: [\n * provideRouter(routes),\n * provideNgxStack({\n * transitions: { ios: iosTransition, android: androidTransition, web: noneTransition },\n * tabs: ['inbox', 'search'],\n * deepLinks: true, // needs withDisabledInitialNavigation() — see below\n * }),\n * ],\n * });\n * ```\n *\n * Installs {@link NgxStackRouteReuseStrategy}, which is required — Angular's default strategy\n * recycles a component when only the route params change, which would quietly merge `/item/1` and\n * `/item/2` into one page instead of two.\n */\nexport function provideNgxStack(config: NgxStackConfig = {}): EnvironmentProviders {\n const resolved = { ...NGX_STACK_DEFAULTS, ...config };\n\n return makeEnvironmentProviders([\n { provide: NGX_STACK_CONFIG, useValue: resolved },\n { provide: RouteReuseStrategy, useClass: NgxStackRouteReuseStrategy },\n\n ...(resolved.deepLinks ? [rebuildDeepLinks(resolved.deepLinks)] : []),\n ]);\n}\n\n/** Guards against a `parentOf` that never terminates. Ten screens is already an absurd stack. */\nconst MAX_ANCESTORS = 10;\n\n/**\n * Build the pages that *should* have been underneath, when the app opens partway in.\n *\n * A push notification, a shared link, a refresh three screens deep: the router lands you on the\n * detail page and the stack has exactly one entry. Nothing is beneath it, so there is nothing for a\n * swipe to drag into view.\n *\n * The gesture needs the page below to be mounted and painted *before* the finger touches the\n * screen, and the only honest way to get it there is to have navigated to it. So that's what this\n * does: it rebuilds the ancestor chain at startup, silently, before the app is shown.\n */\nfunction rebuildDeepLinks(\n deepLinks: true | ((url: string) => string | null),\n): EnvironmentProviders {\n return provideEnvironmentInitializer(() => {\n const router = inject(Router);\n const destroyRef = inject(DestroyRef);\n\n const findParent =\n deepLinks === true ? (url: string) => deriveParentUrl(router.config, url) : deepLinks;\n\n let handled = false;\n\n // We intercept the very first navigation rather than letting it land and then correcting\n // ourselves, and the timing is the whole point: NavigationStart fires before anything is\n // recognised or activated, so nothing has been built yet. Asking the router for a different URL\n // here supersedes the one in flight — it is cancelled where it stands and never activates. The\n // deep page therefore gets constructed exactly once, at the end, on top of its ancestors.\n //\n // (Doing this after NavigationEnd would work too, and would build the deep page, throw it away,\n // and build it again — running its resolvers twice for the privilege.)\n const subscription = router.events.subscribe((event) => {\n if (handled || !(event instanceof NavigationStart)) return;\n handled = true;\n subscription.unsubscribe();\n\n const target = event.url;\n\n // Walk up from the target, collecting ancestors outermost-first.\n const chain: string[] = [];\n const seen = new Set<string>([target]);\n let current = target;\n\n while (chain.length < MAX_ANCESTORS) {\n const parent = findParent(current);\n if (!parent || seen.has(parent)) break;\n seen.add(parent);\n chain.unshift(parent);\n current = parent;\n }\n\n // Nothing above it — it *is* a root page. Let the navigation Angular already started proceed.\n if (chain.length === 0) return;\n\n void (async () => {\n // Root the stack at the outermost ancestor, replacing the history entry the browser already\n // has for the deep URL…\n await router.navigateByUrl(chain[0], {\n replaceUrl: true,\n state: { [NGX_STACK_DIRECTION]: 'root', [NGX_STACK_ANIMATED]: false },\n });\n\n // …then walk back down, pushing each page. The stack and the history end up exactly as they\n // would have been if the user had tapped their way here — which is the whole point.\n for (const url of [...chain.slice(1), target]) {\n await router.navigateByUrl(url, {\n state: { [NGX_STACK_DIRECTION]: 'forward', [NGX_STACK_ANIMATED]: false },\n });\n }\n })();\n });\n\n destroyRef.onDestroy(() => subscription.unsubscribe());\n });\n}\n\n/** The slice of `@capacitor/app` we need. Structural, so there is no dependency on Capacitor. */\nexport interface CapacitorAppLike {\n addListener(\n eventName: 'backButton',\n listenerFunc: (event: { canGoBack: boolean }) => void,\n ): Promise<unknown>;\n exitApp(): Promise<void>;\n}\n\n/**\n * Route the Android hardware back button (and the Android system back gesture, which Capacitor\n * reports through the same event) into the stack.\n *\n * Pass the plugin in rather than having the library import it, so `@capacitor/app` stays out of the\n * dependency graph of anyone shipping only to the web:\n *\n * ```ts\n * import { App } from '@capacitor/app';\n * provideCapacitorBack(App)\n * ```\n *\n * At the root of the stack this calls `exitApp()`, which is what Android users expect — back on the\n * first screen closes the app rather than doing nothing.\n *\n * The event's own `canGoBack` is deliberately ignored. It describes the *webview's* history, and\n * history is a single linear thread while tabs are several stacks — so it says yes when the only\n * thing behind you is a different tab. We ask the stack instead.\n */\nexport function provideCapacitorBack(app: CapacitorAppLike): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideEnvironmentInitializer(() => {\n const platform = inject(NGX_STACK_PLATFORM);\n if (!platform.isCapacitor) return;\n\n const nav = inject(NgxStackNav);\n void app.addListener('backButton', () => {\n if (nav.canGoBack()) {\n void nav.back();\n } else {\n void app.exitApp();\n }\n });\n }),\n ]);\n}\n\n/**\n * The same, for Cordova / PhoneGap.\n *\n * Cordova is a WKWebView (iOS) or WebView (Android) with plugins bolted on, so everything else in\n * this library already works there unchanged — the swipe, the transitions, the stacks, the tabs.\n * The one thing that isn't web is the Android hardware back button, which Cordova delivers as a\n * `backbutton` event on `document` once `deviceready` has fired.\n *\n * ```ts\n * provideCordovaBack()\n * ```\n *\n * Nothing to pass in: unlike Capacitor, Cordova's API is a global. At the root of the stack this\n * calls `navigator.app.exitApp()`.\n */\nexport function provideCordovaBack(): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideEnvironmentInitializer(() => {\n const platform = inject(NGX_STACK_PLATFORM);\n if (!platform.isCordova) return;\n\n const nav = inject(NgxStackNav);\n const doc = inject(DOCUMENT);\n const destroyRef = inject(DestroyRef);\n\n const onBackButton = (event: Event): void => {\n event.preventDefault();\n\n if (nav.canGoBack()) {\n void nav.back();\n return;\n }\n\n const exitApp = (\n doc.defaultView?.navigator as unknown as { app?: { exitApp?: () => void } }\n )?.app?.exitApp;\n exitApp?.();\n };\n\n // Cordova only starts firing `backbutton` after `deviceready`, so subscribing this early is\n // safe — the event simply cannot arrive before then.\n doc.addEventListener('backbutton', onBackButton);\n\n // An app is normally torn down by the OS, not by us — but a test harness, or a micro-frontend\n // that destroys and recreates the Angular app, would otherwise leave this listener holding a\n // reference to a dead injector and stealing the back button from whatever replaced it.\n destroyRef.onDestroy(() => doc.removeEventListener('backbutton', onBackButton));\n }),\n ]);\n}\n","interface Sample {\n t: number;\n x: number;\n}\n\n/** How far back to look. Older samples describe a gesture the finger has already left. */\nconst WINDOW_MS = 100;\n\n/** Horizontal speed of a drag, in px/ms. Positive means moving right. */\nexport class VelocityTracker {\n private samples: Sample[] = [];\n\n reset(x: number, t: number): void {\n this.samples = [{ x, t }];\n }\n\n add(x: number, t: number): void {\n this.samples.push({ x, t });\n const cutoff = t - WINDOW_MS;\n while (this.samples.length > 2 && this.samples[0].t < cutoff) {\n this.samples.shift();\n }\n }\n\n velocity(): number {\n if (this.samples.length < 2) return 0;\n const first = this.samples[0];\n const last = this.samples[this.samples.length - 1];\n const dt = last.t - first.t;\n if (dt <= 0) return 0;\n return (last.x - first.x) / dt;\n }\n}\n","import type { ResolvedStackConfig } from '../config';\nimport type { InteractiveBack } from '../core/stack-controller';\nimport type { StackPlatform } from '../platform/platform';\nimport { VelocityTracker } from './velocity-tracker';\n\n/** Travel along the axis, in px, before we commit to a swipe rather than a scroll or a tap. */\nconst DIRECTION_LOCK_PX = 10;\n\nconst MIN_SETTLE_MS = 90;\nconst MAX_SETTLE_MS = 380;\n\n/** Below this speed the flick is treated as a release, not a throw. */\nconst IDLE_SPEED = 0.05;\n\nexport interface SwipeBackHost {\n readonly hostEl: HTMLElement;\n /**\n * May a swipe start right now? Asked on every touch that lands in the edge zone, so it is free\n * to depend on live state. The single gate: whether the gesture is enabled at all, whether\n * there is anything to go back to, and whether the current page objects.\n */\n canSwipeBack(): boolean;\n /** Right-to-left, so the gesture lives on the right edge and pulls the other way. */\n isRtl(): boolean;\n /** Build the scrubbable back transition, or return null to refuse. */\n beginSwipeBack(): InteractiveBack | null;\n /** The user let go past the threshold. Finish the animation over `ms`, then pop for real. */\n commitSwipeBack(back: InteractiveBack, ms: number): void;\n /** The user let go short of the threshold. Put everything back over `ms`. */\n abortSwipeBack(back: InteractiveBack, ms: number): void;\n}\n\ntype GestureState = 'idle' | 'pending' | 'dragging';\n\n/**\n * Edge-drag-to-go-back.\n *\n * Uses touch events rather than pointer events on purpose. On iOS a `touchmove` can be\n * `preventDefault()`-ed to stop the page scrolling out from under the drag, and a `touchstart`\n * can be prevented to stop WebKit starting its own back-navigation gesture. Pointer events give\n * us neither — once WebKit decides the touch is a scroll or a system gesture, we just get a\n * `pointercancel` and the drag dies.\n *\n * Everything horizontal is expressed against a `sign`: +1 in LTR, -1 in RTL. The gesture starts\n * at the *inline start* edge and pulls towards the *inline end*, which in Arabic and Hebrew means\n * starting at the right and dragging left.\n */\nexport class SwipeBackGesture {\n private state: GestureState = 'idle';\n private startX = 0;\n private startY = 0;\n private width = 1;\n private sign: 1 | -1 = 1;\n private touchId: number | null = null;\n private back: InteractiveBack | null = null;\n\n private readonly velocity = new VelocityTracker();\n private readonly teardown: (() => void)[] = [];\n\n constructor(\n private readonly host: SwipeBackHost,\n private readonly config: ResolvedStackConfig,\n private readonly platform: StackPlatform,\n ) {\n const el = host.hostEl;\n\n // Non-passive: both handlers need to be able to preventDefault.\n this.listen(el, 'touchstart', this.onTouchStart as EventListener, { passive: false });\n this.listen(el, 'touchmove', this.onTouchMove as EventListener, { passive: false });\n this.listen(el, 'touchend', this.onTouchEnd as EventListener);\n this.listen(el, 'touchcancel', this.onTouchEnd as EventListener);\n\n if (config.swipeWithMouse) {\n this.listen(el, 'mousedown', this.onMouseDown as EventListener);\n this.listen(el.ownerDocument, 'mousemove', this.onMouseMove as EventListener);\n this.listen(el.ownerDocument, 'mouseup', this.onMouseUp as EventListener);\n }\n }\n\n private listen(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: AddEventListenerOptions,\n ): void {\n target.addEventListener(type, handler, options);\n this.teardown.push(() => target.removeEventListener(type, handler, options));\n }\n\n // ---------------------------------------------------------------------------\n // Touch\n // ---------------------------------------------------------------------------\n\n private readonly onTouchStart = (event: TouchEvent): void => {\n if (this.state !== 'idle' || event.touches.length !== 1) return;\n\n const touch = event.touches[0];\n if (!this.arm(touch.clientX, touch.clientY)) return;\n\n this.touchId = touch.identifier;\n\n // Stacks nest: an <ngx-stack> inside a page of an <ngx-stack-outlet> sits inside the outer\n // stack's host element, so this touch is on its way there too. Claim it, or both stacks\n // would go back at once. Listeners fire innermost-first, and arming already required\n // something to go back to — so the innermost stack that *can* go back wins, and one sitting\n // at its own root declines and lets the swipe fall through to its parent.\n event.stopPropagation();\n\n if (this.suppressesSystemGesture() && event.cancelable) {\n // Stops WebKit from starting its own interactive back navigation on this touch. The cost\n // is that this touch will not produce a synthetic `click`, which is why the default policy\n // is `inset` rather than `suppress`.\n event.preventDefault();\n }\n };\n\n private readonly onTouchMove = (event: TouchEvent): void => {\n if (this.state === 'idle') return;\n const touch = this.trackedTouch(event);\n if (!touch) return;\n this.drag(touch.clientX, touch.clientY, event);\n };\n\n private readonly onTouchEnd = (): void => {\n this.release();\n };\n\n /** A second finger landing must not hijack a drag the first one started. */\n private trackedTouch(event: TouchEvent): Touch | null {\n return Array.from(event.touches).find((touch) => touch.identifier === this.touchId) ?? null;\n }\n\n // ---------------------------------------------------------------------------\n // Mouse (development convenience only — `swipeWithMouse`)\n // ---------------------------------------------------------------------------\n\n private readonly onMouseDown = (event: MouseEvent): void => {\n if (this.state !== 'idle' || event.button !== 0) return;\n // See onTouchStart: the innermost stack that can go back claims the drag.\n if (this.arm(event.clientX, event.clientY)) event.stopPropagation();\n };\n\n private readonly onMouseMove = (event: MouseEvent): void => {\n if (this.state === 'idle') return;\n this.drag(event.clientX, event.clientY, event);\n };\n\n private readonly onMouseUp = (): void => {\n this.release();\n };\n\n // ---------------------------------------------------------------------------\n\n private arm(x: number, y: number): boolean {\n this.sign = this.host.isRtl() ? -1 : 1;\n\n if (!this.inEdgeZone(x)) return false;\n if (!this.host.canSwipeBack()) return false;\n\n this.state = 'pending';\n this.startX = x;\n this.startY = y;\n this.width = Math.max(this.host.hostEl.clientWidth, 1);\n this.velocity.reset(x, performance.now());\n return true;\n }\n\n private drag(x: number, y: number, event: Event): void {\n // Travel *away from* the starting edge, so this is positive whichever way the app reads.\n const travel = (x - this.startX) * this.sign;\n\n if (this.state === 'pending') {\n const dy = y - this.startY;\n\n // A vertical drag is a scroll, and scrolling wins outright — bail rather than fight it.\n if (Math.abs(dy) > DIRECTION_LOCK_PX && Math.abs(dy) >= Math.abs(travel)) {\n this.reset();\n return;\n }\n if (travel < DIRECTION_LOCK_PX) return;\n\n const back = this.host.beginSwipeBack();\n if (!back) {\n this.reset();\n return;\n }\n this.back = back;\n this.state = 'dragging';\n }\n\n if (!this.back) return;\n\n // Keep the page underneath from scrolling while the finger is dragging it sideways.\n if (event.cancelable) event.preventDefault();\n\n this.velocity.add(x, performance.now());\n this.back.player.seek(travel / this.width);\n }\n\n private release(): void {\n const back = this.back;\n const wasDragging = this.state === 'dragging';\n const sign = this.sign;\n this.reset();\n\n if (!wasDragging || !back) return;\n\n const progress = back.player.progress;\n // Positive means \"still moving away from the starting edge\", i.e. towards completing.\n const velocity = this.velocity.velocity() * sign;\n const threshold = this.config.swipeVelocityThreshold;\n\n // A fast flick decides on its own: outwards completes even from barely anywhere, back\n // towards the edge cancels even from past the halfway mark. Otherwise distance decides.\n const complete =\n velocity > threshold || (velocity > -threshold && progress > this.config.swipeThreshold);\n\n const remaining = complete ? 1 - progress : progress;\n const ms = this.settleDuration(remaining, Math.abs(velocity));\n\n if (complete) {\n this.host.commitSwipeBack(back, ms);\n } else {\n this.host.abortSwipeBack(back, ms);\n }\n }\n\n /** Carry the finger's speed into the settle, so the page doesn't change pace on release. */\n private settleDuration(remainingProgress: number, speed: number): number {\n const distance = remainingProgress * this.width;\n const ms = speed > IDLE_SPEED ? distance / speed : this.config.duration * remainingProgress;\n return Math.min(Math.max(ms, MIN_SETTLE_MS), MAX_SETTLE_MS);\n }\n\n private reset(): void {\n this.state = 'idle';\n this.back = null;\n this.touchId = null;\n }\n\n /** The zone hugs the *inline start* edge: the left in LTR, the right in RTL. */\n private inEdgeZone(x: number): boolean {\n const rect = this.host.hostEl.getBoundingClientRect();\n const fromEdge = this.sign === 1 ? x - rect.left : rect.right - x;\n const start = this.systemInset();\n\n return fromEdge >= start && fromEdge <= start + this.config.swipeEdgeWidth;\n }\n\n /** Pixels at the very edge we concede to the browser's own gesture. */\n private systemInset(): number {\n return this.platform.hasSystemBackGesture && this.config.systemGesture === 'inset'\n ? this.config.systemEdgeInset\n : 0;\n }\n\n private suppressesSystemGesture(): boolean {\n return this.platform.hasSystemBackGesture && this.config.systemGesture === 'suppress';\n }\n\n destroy(): void {\n if (this.back) {\n this.host.abortSwipeBack(this.back, 0);\n }\n this.reset();\n for (const off of this.teardown) off();\n this.teardown.length = 0;\n }\n}\n","import { Injectable, inject, signal, type Signal } from '@angular/core';\n\nimport { NGX_STACK_CONFIG } from '../config';\nimport { NGX_STACK_PLATFORM } from '../platform/platform';\n\n/**\n * The master switch for swipe-to-go-back.\n *\n * `provideNgxStack({ swipeBack })` only sets the *starting* value — this is what you reach\n * for when the answer changes while the app is running. A modal is open, a map is eating the\n * drag, a form has unsaved edits, a payment is in flight: turn it off, turn it back on after.\n *\n * ```ts\n * const swipe = inject(NgxStackSwipe);\n * swipe.disable();\n * // …later\n * swipe.reset(); // back to whatever the config said\n * ```\n *\n * This is the global layer. Two narrower ones sit on top of it, and either can veto:\n * `<ngx-stack-outlet [swipeBack]=\"…\">` for one stack, and `ngxCanSwipeBack()` or\n * `data: { swipeBack: false }` for one page. See {@link NgxStackPage}.\n */\n@Injectable({ providedIn: 'root' })\nexport class NgxStackSwipe {\n private readonly config = inject(NGX_STACK_CONFIG);\n private readonly platform = inject(NGX_STACK_PLATFORM);\n\n private readonly _enabled = signal(this.fromConfig());\n\n /** Read it in a template or a computed; it's a signal. */\n readonly enabled: Signal<boolean> = this._enabled.asReadonly();\n\n enable(): void {\n this._enabled.set(true);\n }\n\n disable(): void {\n this._enabled.set(false);\n }\n\n set(enabled: boolean): void {\n this._enabled.set(enabled);\n }\n\n /** Go back to what the config asked for, whatever that resolved to on this device. */\n reset(): void {\n this._enabled.set(this.fromConfig());\n }\n\n private fromConfig(): boolean {\n const setting = this.config.swipeBack;\n if (setting !== 'auto') return setting;\n\n // 'auto' means iOS only. Honour a forced `platform`, so an iOS build under test on a\n // laptop still arms the gesture.\n const kind = this.config.platform === 'auto' ? this.platform.kind : this.config.platform;\n return kind === 'ios';\n }\n}\n","import type { ElementAnimation, StackTransition, TransitionSpec } from './transition';\n\nexport interface RiseOptions {\n /** How far the incoming page rises through, in px. Material moves a short distance, quickly. */\n travel: number;\n\n easing: string;\n\n /** Multiplier on the configured duration. */\n durationScale: number;\n}\n\n/**\n * The Material shape: the incoming page rises a short distance and fades in over the outgoing one,\n * which stays exactly where it is and is simply covered.\n *\n * The counterpart to {@link slideTransition}. `androidTransition` and `webTransition` are both\n * instances of this, with the same numbers — but they remain two separate transitions you can point\n * at different things, because \"what Android does\" and \"what a browser does\" are two decisions that\n * merely happen to agree today.\n *\n * Note there is no horizontal component, and that has a consequence: an edge swipe would drag\n * sideways while the page moved vertically. That is why `swipeBack: 'auto'` only arms the gesture on\n * iOS. For a swipe on Android or the web, give that platform a {@link slideTransition} instead.\n */\nexport function riseTransition(options: RiseOptions): StackTransition {\n return (ctx): TransitionSpec => {\n const forward = ctx.direction === 'forward';\n\n // The page riding on top. Going back, that's the one leaving.\n const overEl = forward ? ctx.enteringEl : ctx.leavingEl;\n\n const animations: ElementAnimation[] = [];\n\n if (overEl) {\n const away: Keyframe = { transform: `translateY(${options.travel}px)`, opacity: '0' };\n const home: Keyframe = { transform: 'translateY(0)', opacity: '1' };\n\n animations.push({ el: overEl, keyframes: forward ? [away, home] : [home, away] });\n }\n\n return {\n duration: Math.round(ctx.duration * options.durationScale),\n easing: options.easing,\n animations,\n };\n };\n}\n","import { riseTransition } from './rise';\n\n/**\n * The Material push: the incoming page rises and fades in over the outgoing one, which stays where\n * it is. Shorter and flatter than iOS — Material moves things a short distance quickly rather than a\n * long distance smoothly.\n *\n * Deliberately has no horizontal component, which is why `swipeBack: 'auto'` doesn't arm the gesture\n * here: a finger dragging sideways would scrub a page moving vertically. On Android the back gesture\n * belongs to the OS anyway. If you do want an edge swipe, give this platform a `slideTransition()`.\n */\nexport const androidTransition = riseTransition({\n travel: 12,\n easing: 'cubic-bezier(0.05, 0.7, 0.1, 1)',\n durationScale: 0.65,\n});\n","/** Which way the stack is moving. */\nexport type StackDirection = 'forward' | 'back';\n\nexport interface TransitionContext {\n /**\n * The page that will be on top of the stack once the transition finishes. On `forward` this is\n * the newly created page; on `back` it is the page being uncovered.\n */\n enteringEl: HTMLElement;\n\n /**\n * The page that was on top when the transition started, or `null` when the stack was empty\n * (the root page).\n */\n leavingEl: HTMLElement | null;\n\n /** The element both pages live in. */\n hostEl: HTMLElement;\n\n direction: StackDirection;\n\n /**\n * The app is running right-to-left. Everything horizontal mirrors: \"forward\" arrives from the\n * left rather than the right, and the swipe-back lives on the right edge. A transition that\n * ignores this will feel backwards in Arabic and Hebrew — the new page will appear to come\n * from where the user just came *from*.\n */\n rtl: boolean;\n\n /** Host width in px, for transitions that want absolute distances. */\n width: number;\n\n /** Requested duration in ms, from the config. */\n duration: number;\n}\n\nexport interface ElementAnimation {\n el: HTMLElement;\n /**\n * The first keyframe is the state at progress 0, the last at progress 1. A swipe-back gesture\n * seeks between them, so keyframes must be continuous and reversible — avoid discrete steps or\n * properties that can't be interpolated.\n */\n keyframes: Keyframe[];\n /** Overrides the spec-level easing for this element. */\n easing?: string;\n}\n\nexport interface TransitionSpec {\n duration: number;\n easing: string;\n animations: ElementAnimation[];\n}\n\n/**\n * Describes how two pages swap places. Called once per transition, and also at the start of a\n * swipe-back — in that case the resulting animation is seeked by the finger rather than played,\n * so it must be a pure function of progress.\n */\nexport type StackTransition = (ctx: TransitionContext) => TransitionSpec;\n\n/** The dim overlay that sits on top of a page while it is covered by another. */\nexport function scrimOf(pageEl: HTMLElement): HTMLElement | null {\n return pageEl.querySelector<HTMLElement>(':scope > .ngx-stack-scrim');\n}\n","import {\n scrimOf,\n type ElementAnimation,\n type StackTransition,\n type TransitionSpec,\n} from './transition';\n\nexport interface SlideOptions {\n /** How far the page riding on top travels, as a % of the host's width. */\n travel: number;\n\n /** How far the page underneath drifts the other way. Less than `travel` is what makes a parallax. */\n parallax: number;\n\n /** Peak opacity of the dim overlay on the covered page. `0` to skip it. */\n scrim: number;\n\n /** Fade the travelling page as well as moving it. iOS doesn't; a shorter web slide needs to. */\n fade: boolean;\n\n easing: string;\n\n /** Multiplier on the configured duration. */\n durationScale: number;\n}\n\n/**\n * The shape both horizontal transitions share: one page rides in over another, which drifts the\n * other way more slowly and dims underneath it.\n *\n * iOS and web are the same animation with different numbers — a full-width slide with a heavy\n * parallax, versus a short drift carried mostly by opacity. Writing that twice invites them to\n * quietly diverge, and the interesting parts here are subtle enough already:\n *\n * - `forward` and `back` are the same keyframes with the roles swapped. That symmetry is what makes\n * a swipe scrubbable at all — the gesture just seeks the `back` spec.\n * - everything horizontal is signed by `rtl`, so a page pushed \"forward\" in Arabic arrives from the\n * left, which is the direction the language reads towards.\n */\nexport function slideTransition(options: SlideOptions): StackTransition {\n return (ctx): TransitionSpec => {\n const forward = ctx.direction === 'forward';\n const sign = ctx.rtl ? -1 : 1;\n\n const offMain = `translateX(${options.travel * sign}%)`;\n const offUnder = `translateX(${-options.parallax * sign}%)`;\n const center = 'translateX(0)';\n\n // The page riding on top, sliding in from (or out to) the edge.\n const overEl = forward ? ctx.enteringEl : ctx.leavingEl;\n // The page underneath, parallaxing and dimming.\n const underEl = forward ? ctx.leavingEl : ctx.enteringEl;\n\n const animations: ElementAnimation[] = [];\n\n if (overEl) {\n const away: Keyframe = { transform: offMain, ...(options.fade ? { opacity: '0' } : {}) };\n const home: Keyframe = { transform: center, ...(options.fade ? { opacity: '1' } : {}) };\n animations.push({ el: overEl, keyframes: forward ? [away, home] : [home, away] });\n }\n\n if (underEl) {\n animations.push({\n el: underEl,\n keyframes: forward\n ? [{ transform: center }, { transform: offUnder }]\n : [{ transform: offUnder }, { transform: center }],\n });\n\n const scrim = options.scrim > 0 ? scrimOf(underEl) : null;\n if (scrim) {\n const clear: Keyframe = { opacity: '0' };\n const dim: Keyframe = { opacity: `${options.scrim}` };\n animations.push({ el: scrim, keyframes: forward ? [clear, dim] : [dim, clear] });\n }\n }\n\n return {\n duration: Math.round(ctx.duration * options.durationScale),\n easing: options.easing,\n animations,\n };\n };\n}\n","import { slideTransition } from './slide';\n\n/**\n * The iOS navigation-controller push/pop.\n *\n * The incoming page slides the full width of the screen over the outgoing one, which drifts the\n * other way at a third of the speed and dims underneath it — the parallax that makes a UIKit stack\n * feel like sheets of paper rather than slides.\n *\n * The easing is UIKit's own: almost no acceleration, and a very long tail.\n */\nexport const iosTransition = slideTransition({\n travel: 100,\n parallax: 33,\n scrim: 0.16,\n fade: false,\n easing: 'cubic-bezier(0.32, 0.72, 0, 1)',\n durationScale: 1,\n});\n","import { riseTransition } from './rise';\n\n/**\n * The browser default — the same rise-and-fade as Android, and identical to `androidTransition` down\n * to the numbers.\n *\n * They are still two transitions rather than one, and that is the point: \"what a phone does\" and\n * \"what a browser does\" are two separate decisions that merely happen to agree today. Retuning the\n * web here changes nothing on Android, and vice versa. If they were the same object, the first person\n * to want a different feel on the desktop would have to change both.\n *\n * Why Material rather than the iOS slide: a full-width slide says *\"this screen came from over\n * there\"*, which is true of something you swiped into view and not of something you clicked — and on\n * a wide monitor it is a great many pixels moving for no reason.\n */\nexport const webTransition = riseTransition({\n travel: 12,\n easing: 'cubic-bezier(0.05, 0.7, 0.1, 1)',\n durationScale: 0.65,\n});\n","import type { TransitionSpec } from './transition';\n\nconst clamp01 = (n: number): number => (n < 0 ? 0 : n > 1 ? 1 : n);\n\n/** Keyframe keys that carry timing rather than style. */\nconst META_KEYS = new Set(['offset', 'easing', 'composite']);\n\nfunction styleKeysOf(keyframes: Keyframe[]): string[] {\n const keys = new Set<string>();\n for (const frame of keyframes) {\n for (const key of Object.keys(frame)) {\n if (!META_KEYS.has(key)) keys.add(key);\n }\n }\n return [...keys];\n}\n\n/** The element's current rendered value for each animated property. */\nfunction snapshotOf(el: HTMLElement, keys: string[]): Keyframe {\n const frame: Record<string, string> = {};\n\n // A page destroyed mid-swipe — a navigation cancelled under the finger — has no defaultView. An\n // assertion here would throw inside a touch handler, taking the gesture down with it, when the\n // honest answer is simply that there is nothing left to animate from.\n const view = el.ownerDocument.defaultView;\n if (!view) return frame as Keyframe;\n\n const computed = view.getComputedStyle(el);\n for (const key of keys) {\n frame[key] = (computed as unknown as Record<string, string>)[key];\n }\n return frame as Keyframe;\n}\n\nfunction styleOnly(frame: Keyframe): Keyframe {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(frame)) {\n if (!META_KEYS.has(key)) out[key] = value;\n }\n return out as Keyframe;\n}\n\n/**\n * A page transition that can be either played or scrubbed.\n *\n * This is the whole reason the library exists. A CSS transition or a View Transition is\n * fire-and-forget: it runs to completion on its own clock. A swipe-back is the opposite —\n * the finger owns the clock, the transition has to follow it, and the user may change\n * their mind halfway and drag right back.\n *\n * So a transition is built as a set of paused Web Animations with `fill: 'both'`. Paused at\n * `currentTime = 0` they hold their first keyframe; the gesture then writes `currentTime`\n * directly on every touch move.\n */\nexport class TransitionPlayer {\n private animations: Animation[];\n private duration: number;\n private disposed = false;\n\n /**\n * @param interactive Build for scrubbing. Timing easing is forced to linear so that\n * seeking to progress `p` puts the page at exactly `p` of the way across — otherwise\n * the iOS curve makes the page lead and then lag the finger, which is precisely the\n * tell that separates a native-feeling swipe from a web one. The real curve is applied\n * later, by `settle()`.\n */\n constructor(\n private readonly spec: TransitionSpec,\n interactive = false,\n ) {\n this.duration = Math.max(spec.duration, 1);\n const easing = interactive ? 'linear' : spec.easing;\n\n this.animations = spec.animations.map((animation) => {\n const handle = animation.el.animate(animation.keyframes, {\n duration: this.duration,\n easing: interactive ? 'linear' : (animation.easing ?? easing),\n fill: 'both',\n });\n handle.pause();\n handle.currentTime = 0;\n return handle;\n });\n }\n\n /** Where the transition currently sits, in `[0, 1]`. */\n get progress(): number {\n const first = this.animations[0];\n if (!first) return 0;\n return clamp01(Number(first.currentTime ?? 0) / this.duration);\n }\n\n /** Jump to a progress in `[0, 1]`. Called on every touch move during a swipe. */\n seek(progress: number): void {\n if (this.disposed) return;\n const time = clamp01(progress) * this.duration;\n for (const animation of this.animations) {\n animation.currentTime = time;\n }\n }\n\n /** Run to progress 1 on the transition's own clock. */\n play(): Promise<void> {\n return this.run(1);\n }\n\n /**\n * Hand the clock back to the browser after a scrub, carrying on to `target`.\n *\n * Deliberately *not* a continuation of the scrub timeline. Re-applying the easing curve\n * to a timeline that is already part-way through would snap the page to `easing(t)`, a\n * visible jump at the exact moment the user lets go. Instead we snapshot what is\n * currently on screen and animate from there to the target with the real curve, which is\n * continuous by construction.\n *\n * @param ms How long the remaining distance should take. Scale this by the distance left\n * so a release near the end is quick and one near the start is not.\n */\n settle(target: 0 | 1, ms: number, easing = this.spec.easing): Promise<void> {\n if (this.disposed || this.animations.length === 0) return Promise.resolve();\n\n const from = this.spec.animations.map((animation) => ({\n el: animation.el,\n frame: snapshotOf(animation.el, styleKeysOf(animation.keyframes)),\n }));\n const to = this.spec.animations.map((animation) =>\n styleOnly(\n target === 1 ? animation.keyframes[animation.keyframes.length - 1] : animation.keyframes[0],\n ),\n );\n\n for (const animation of this.animations) {\n animation.cancel();\n }\n\n this.duration = Math.max(ms, 1);\n this.animations = from.map((source, index) =>\n source.el.animate([source.frame, to[index]], {\n duration: this.duration,\n easing,\n fill: 'both',\n }),\n );\n\n return this.settled();\n }\n\n private run(direction: 1): Promise<void> {\n if (this.disposed || this.animations.length === 0) return Promise.resolve();\n\n // `Animation.play()` auto-rewinds: playing forward from the very end snaps back to the\n // start. Short-circuit when there is no distance left to cover.\n if (this.progress >= 0.999) {\n this.seek(1);\n return Promise.resolve();\n }\n\n for (const animation of this.animations) {\n animation.playbackRate = direction;\n animation.play();\n }\n return this.settled();\n }\n\n private settled(): Promise<void> {\n return Promise.all(\n // `finished` rejects when an animation is cancelled mid-flight, which is what happens\n // whenever a newer navigation interrupts this one. Not an error for us.\n this.animations.map((animation) => animation.finished.catch(() => undefined)),\n ).then(() => undefined);\n }\n\n /** Snap to the end state with no animation. */\n finish(): void {\n this.seek(1);\n }\n\n /** Drop the animations, reverting the elements to the styles they had before. */\n destroy(): void {\n if (this.disposed) return;\n for (const animation of this.animations) {\n animation.cancel();\n }\n this.disposed = true;\n }\n}\n","const ANNOUNCER_ID = 'ngx-stack-announcer';\n\n/**\n * Say a page's name out loud, once, to whoever is listening with a screen reader.\n *\n * A stack navigation is invisible to assistive tech: no document load, no focus change it can\n * infer meaning from — the DOM just quietly rearranges. A polite live region is the standard way\n * to give that back, and it's the same thing Angular's own `RouterOutlet` does not do for you.\n */\nexport function announce(doc: Document, message: string): void {\n let region = doc.getElementById(ANNOUNCER_ID);\n\n if (!region) {\n region = doc.createElement('div');\n region.id = ANNOUNCER_ID;\n region.setAttribute('aria-live', 'polite');\n region.setAttribute('aria-atomic', 'true');\n region.className = 'ngx-stack-announcer';\n doc.body.appendChild(region);\n }\n\n // Re-announcing the same string is a no-op for most screen readers, because the region's\n // content didn't change. Clearing first forces it to speak.\n region.textContent = '';\n region.textContent = message;\n}\n","import type { ComponentRef } from '@angular/core';\nimport type { ActivatedRoute, OutletContext } from '@angular/router';\n\n/** One page living on the stack. */\nexport interface StackEntry {\n readonly id: number;\n\n /**\n * Serialized URL that owns this page, used to recognise it again on a later navigation.\n * Empty for imperative stacks, which have no URL of their own.\n */\n url: string;\n\n /**\n * Which tab's stack this page belongs to, or `''` when the app has no tabs. Pages of\n * inactive tabs stay mounted — that is the entire point of tabs having their own stacks.\n */\n readonly tab: string;\n\n /** The wrapper we transform. Not the component's own host element — that lives inside. */\n readonly element: HTMLElement;\n\n /** The dim overlay shown while this page is covered. */\n readonly scrim: HTMLElement;\n\n readonly ref: ComponentRef<unknown>;\n\n route: ActivatedRoute | null;\n\n /**\n * Child outlet contexts captured when this page was navigated away from, so that any nested\n * `<router-outlet>` inside it comes back alive rather than empty when we return.\n */\n savedContexts?: Map<string, OutletContext>;\n}\n\n/**\n * Lifecycle callbacks for a page on the stack.\n *\n * Stacked pages are *not* destroyed when you navigate away from them — that's the point, it's\n * what preserves their state and lets the swipe reveal them instantly. Which also means\n * `ngOnDestroy` no longer means \"the user left this page\". These hooks do.\n */\nexport interface NgxStackPage {\n /** The page is about to become the top of the stack. Fires before the transition. */\n ngxViewWillEnter?(): void;\n /** The page is now the top of the stack and the transition has finished. */\n ngxViewDidEnter?(): void;\n /** The page is about to stop being the top of the stack. */\n ngxViewWillLeave?(): void;\n /** The page is no longer the top of the stack. It stays alive unless it was popped. */\n ngxViewDidLeave?(): void;\n\n /**\n * Veto the swipe-back gesture while this page is on top. Consulted on every touch, so it can\n * depend on live state — an open modal, a dirty form, an in-flight payment.\n *\n * A veto only. It cannot turn the gesture *on* where `NgxStackSwipe` or the outlet have\n * turned it off. For a page that is simply never swipeable, `data: { swipeBack: false }` on\n * the route says the same thing without any code.\n *\n * This is also how a route with a `canDeactivate` guard opts back into the gesture — see\n * `guardPolicy`.\n */\n ngxCanSwipeBack?(): boolean;\n}\n\ntype LifecycleHook = Exclude<keyof NgxStackPage, 'ngxCanSwipeBack'>;\n\nexport function callLifecycle(entry: StackEntry | null, hook: LifecycleHook): void {\n const instance = entry?.ref.instance as NgxStackPage | undefined;\n instance?.[hook]?.();\n}\n\n/**\n * Does the page on top object to being swiped away? Two ways to say so, both vetoes:\n * `data: { swipeBack: false }` on the route for a page that never allows it, and\n * `ngxCanSwipeBack()` on the component for one that decides in the moment.\n *\n * @param guardPolicy When `'block'`, a route carrying a `canDeactivate` guard refuses the\n * gesture unless its component implements `ngxCanSwipeBack()`. The guard would otherwise run\n * only *after* the page had already animated away, and refusing at that point can do nothing\n * but bounce it back.\n */\nexport function pageAllowsSwipeBack(\n entry: StackEntry | null,\n guardPolicy: 'block' | 'allow' = 'allow',\n): boolean {\n if (!entry) return false;\n\n const snapshot = entry.route?.snapshot;\n if (snapshot?.data['swipeBack'] === false) return false;\n\n const page = entry.ref.instance as NgxStackPage | undefined;\n const answer = page?.ngxCanSwipeBack?.();\n\n if (answer !== undefined) return answer;\n\n if (guardPolicy === 'block' && (snapshot?.routeConfig?.canDeactivate?.length ?? 0) > 0) {\n return false;\n }\n\n return true;\n}\n","import { computed, signal, type ComponentRef, type Signal } from '@angular/core';\nimport type { ActivatedRoute } from '@angular/router';\n\nimport { androidTransition } from '../animation/android-transition';\nimport { iosTransition } from '../animation/ios-transition';\nimport { webTransition } from '../animation/web-transition';\nimport type { StackDirection, StackTransition } from '../animation/transition';\nimport { TransitionPlayer } from '../animation/transition-player';\nimport type { ResolvedStackConfig } from '../config';\nimport type { StackPlatform, StackPlatformKind } from '../platform/platform';\nimport { announce } from './announcer';\nimport { callLifecycle, type StackEntry } from './stack-entry';\n\nconst BUILT_IN: Record<StackPlatformKind, StackTransition> = {\n ios: iosTransition,\n android: androidTransition,\n // Its own transition, which today happens to be identical to Android's — see web-transition.ts for\n // why they stay two things.\n web: webTransition,\n};\n\n/** A swipe-back in progress: the pages involved, and the transition the finger is scrubbing. */\nexport interface InteractiveBack {\n readonly player: TransitionPlayer;\n /** The page being uncovered — the one that will be on top if the swipe completes. */\n readonly entering: StackEntry;\n /** The page being dragged off — the current top. */\n readonly leaving: StackEntry;\n}\n\n/** Emitted around every transition, including the ones a finger is driving. */\nexport interface StackTransitionEvent {\n direction: StackDirection;\n entering: StackEntry;\n leaving: StackEntry | null;\n /** The tab this happened in, or `''` in a single-stack app. */\n tab: string;\n /** False when the pages simply swapped, e.g. a tab switch or reduced motion. */\n animated: boolean;\n /** True when a swipe-back drove it rather than a navigation. */\n interactive: boolean;\n}\n\nexport type StackOp =\n /** Mount `entering` on top of `tab`'s stack. */\n | { kind: 'push'; tab: string; entering: StackEntry; animated: boolean }\n /**\n * Swap the top page for `entering`. What `router.navigate(…, { replaceUrl: true })` means for a\n * stack: history didn't grow, so neither should the stack.\n */\n | { kind: 'replace'; tab: string; entering: StackEntry; animated: boolean }\n /** Unwind `tab`'s stack to `toIndex`, destroying everything above it. */\n | { kind: 'pop'; tab: string; toIndex: number; animated: boolean; player?: TransitionPlayer }\n /** Replace *every* stack with this one page. */\n | { kind: 'root'; tab: string; entering: StackEntry; animated: boolean }\n /**\n * Rebuild a page that fell off the bottom of a capped stack, and make it the new bottom.\n * Everything currently in that stack sat above it, so all of it goes.\n */\n | { kind: 'restore'; tab: string; entering: StackEntry; animated: boolean };\n\ninterface RunningTransition {\n player: TransitionPlayer | null;\n entering: StackEntry;\n leaving: StackEntry | null;\n /** Pages removed from the stack whose DOM must survive until the animation ends. */\n removed: StackEntry[];\n event: StackTransitionEvent;\n}\n\ntype Stacks = Record<string, readonly StackEntry[]>;\n\n/**\n * Owns the pages of a stack — their DOM, their order, and the transitions between them.\n *\n * Deliberately free of framework plumbing: it knows nothing about the Router or about\n * imperative pushes. Both `NgxStackOutlet` and `NgxStack` drive this same class, which is why\n * a swipe-back behaves identically whether the stack is fed by URLs or by `push()`.\n *\n * With `tabs` configured it holds one stack *per tab* and shows the active one. Tabs are not a\n * feature bolted on top — they're the reason the pages live in a map keyed by tab rather than a\n * flat array. Switching tabs mounts nothing and destroys nothing; it just changes which stack's\n * top page is on screen, so the tab you left is still exactly where you left it.\n */\nexport class StackController {\n private readonly stacks = signal<Stacks>({});\n private readonly active = signal('');\n\n /** URLs evicted by `maxDepth`, per tab. Remembered so we still know they're *behind* us. */\n private readonly pruned = new Map<string, Set<string>>();\n\n /** The active tab's pages, bottom first. */\n readonly pages: Signal<readonly StackEntry[]> = computed(\n () => this.stacks()[this.active()] ?? [],\n );\n readonly depth = computed(() => this.pages().length);\n readonly canGoBack = computed(() => this.pages().length > 1 || this.hasPrunedPages());\n readonly activeTab: Signal<string> = this.active.asReadonly();\n\n private readonly _animating = signal(false);\n readonly animating: Signal<boolean> = this._animating.asReadonly();\n\n /** Set by the host so it can re-emit these as component outputs. */\n onTransitionStart?: (event: StackTransitionEvent) => void;\n onTransitionEnd?: (event: StackTransitionEvent) => void;\n\n private nextId = 0;\n private running: RunningTransition | null = null;\n private readonly doc: Document;\n\n constructor(\n private readonly hostEl: HTMLElement,\n private readonly config: ResolvedStackConfig,\n private readonly platform: StackPlatform,\n ) {\n this.doc = hostEl.ownerDocument;\n }\n\n // ---------------------------------------------------------------------------\n // Reading the stack\n // ---------------------------------------------------------------------------\n\n stackOf(tab: string): readonly StackEntry[] {\n return this.stacks()[tab] ?? [];\n }\n\n top(tab = this.active()): StackEntry | null {\n const stack = this.stackOf(tab);\n return stack.length ? stack[stack.length - 1] : null;\n }\n\n at(index: number, tab = this.active()): StackEntry | null {\n return this.stackOf(tab)[index] ?? null;\n }\n\n findByUrl(url: string, tab = this.active()): number {\n return this.stackOf(tab).findIndex((entry) => entry.url === url);\n }\n\n /** Was this URL evicted by `maxDepth`? If so it's behind us, not ahead of us. */\n wasPruned(url: string, tab = this.active()): boolean {\n return this.pruned.get(tab)?.has(url) ?? false;\n }\n\n private hasPrunedPages(): boolean {\n return (this.pruned.get(this.active())?.size ?? 0) > 0;\n }\n\n // ---------------------------------------------------------------------------\n // Building pages\n // ---------------------------------------------------------------------------\n\n /** Wrap a freshly created component in a page element and put it in the host. */\n adopt(\n ref: ComponentRef<unknown>,\n url: string,\n route: ActivatedRoute | null,\n tab = '',\n ): StackEntry {\n const element = this.doc.createElement('div');\n // Starts invisible so it can't paint at its resting position for a frame before the\n // transition's first keyframe applies.\n element.className = 'ngx-stack-page ngx-stack-page--invisible';\n\n const scrim = this.doc.createElement('div');\n scrim.className = 'ngx-stack-scrim';\n\n // `createComponent` already put the host element in the DOM at the view container's anchor.\n // Relocating the node is fine — Angular tracks the view, not its position.\n element.appendChild(ref.location.nativeElement as HTMLElement);\n element.appendChild(scrim);\n this.hostEl.appendChild(element);\n\n return { id: this.nextId++, url, tab, element, scrim, ref, route };\n }\n\n // ---------------------------------------------------------------------------\n // Transitions\n // ---------------------------------------------------------------------------\n\n /**\n * Apply a stack operation. The stacks are updated *synchronously* so a navigation arriving\n * mid-animation still sees the correct top; only the visuals and the destruction of popped\n * pages wait for the transition.\n */\n run(op: StackOp): Promise<void> {\n // A new transition while one is still running: snap the old one to its end state rather\n // than letting two animations fight over the same transforms.\n if (this.running) this.settle(this.running);\n\n // The page currently on screen — which, on a tab switch, belongs to the tab we're leaving.\n const leaving = this.top(this.active());\n\n const stacks: Stacks = { ...this.stacks() };\n const before = stacks[op.tab] ?? [];\n\n let entering: StackEntry;\n let removed: StackEntry[] = [];\n let direction: StackDirection;\n\n switch (op.kind) {\n case 'push':\n entering = op.entering;\n direction = 'forward';\n stacks[op.tab] = this.prune(op.tab, [...before, entering], (dropped) =>\n removed.push(...dropped),\n );\n break;\n\n case 'replace':\n entering = op.entering;\n direction = 'forward';\n // Only the top goes; everything below it stays, so back still works the same way.\n removed = before.length ? [before[before.length - 1]] : [];\n stacks[op.tab] = [...before.slice(0, -1), entering];\n break;\n\n case 'pop': {\n const target = before[op.toIndex];\n if (!target) return Promise.resolve();\n entering = target;\n direction = 'back';\n removed = before.slice(op.toIndex + 1);\n stacks[op.tab] = before.slice(0, op.toIndex + 1);\n break;\n }\n\n case 'restore':\n entering = op.entering;\n direction = 'back';\n // Everything in this stack sat above the page we're restoring, so all of it goes.\n removed = [...before];\n stacks[op.tab] = [entering];\n this.pruned.get(op.tab)?.delete(entering.url);\n break;\n\n case 'root':\n entering = op.entering;\n direction = 'forward';\n // Root wipes every tab, not just this one — it's \"start the app again\".\n removed = Object.values(stacks).flat();\n for (const key of Object.keys(stacks)) delete stacks[key];\n stacks[op.tab] = [entering];\n this.pruned.clear();\n break;\n }\n\n this.stacks.set(stacks);\n this.active.set(op.tab);\n\n if (entering === leaving) {\n this.applyStates();\n return Promise.resolve();\n }\n\n return this.transition(entering, leaving, direction, removed, op, this.playerOf(op));\n }\n\n /** Enforce `maxDepth` by dropping pages off the bottom, remembering that they existed. */\n private prune(\n tab: string,\n stack: readonly StackEntry[],\n onDropped: (dropped: StackEntry[]) => void,\n ): readonly StackEntry[] {\n const max = this.config.maxDepth;\n if (max <= 0 || stack.length <= max) return stack;\n\n const dropped = stack.slice(0, stack.length - max);\n let urls = this.pruned.get(tab);\n if (!urls) {\n urls = new Set();\n this.pruned.set(tab, urls);\n }\n for (const entry of dropped) {\n if (entry.url) urls.add(entry.url);\n }\n onDropped(dropped);\n\n return stack.slice(dropped.length);\n }\n\n private playerOf(op: StackOp): TransitionPlayer | undefined {\n return op.kind === 'pop' ? op.player : undefined;\n }\n\n private async transition(\n entering: StackEntry,\n leaving: StackEntry | null,\n direction: StackDirection,\n removed: StackEntry[],\n op: StackOp,\n existingPlayer?: TransitionPlayer,\n ): Promise<void> {\n const isRoot = leaving === null;\n const shouldAnimate =\n op.animated && (!isRoot || this.config.animateRoot) && !this.prefersReducedMotion();\n\n this.reveal(entering);\n if (leaving) this.reveal(leaving);\n\n callLifecycle(leaving, 'ngxViewWillLeave');\n callLifecycle(entering, 'ngxViewWillEnter');\n\n // A gesture hands us a player it has already scrubbed to the end; otherwise build one.\n const player =\n existingPlayer ?? (shouldAnimate ? this.buildPlayer(entering, leaving, direction) : null);\n\n // Safe now: with `fill: 'both'` the player is already holding its first keyframe, so\n // un-hiding cannot show the page at the wrong position.\n entering.element.classList.remove('ngx-stack-page--invisible');\n\n const event: StackTransitionEvent = {\n direction,\n entering,\n leaving,\n tab: op.tab,\n animated: player !== null,\n interactive: existingPlayer !== undefined,\n };\n\n const run: RunningTransition = { player, entering, leaving, removed, event };\n this.running = run;\n this._animating.set(true);\n this.onTransitionStart?.(event);\n\n if (player) {\n entering.element.classList.add('ngx-stack-page--animating');\n leaving?.element.classList.add('ngx-stack-page--animating');\n await player.play();\n }\n\n // A newer navigation may have settled this transition while we were awaiting.\n if (this.running !== run) return;\n\n this.finish(run);\n }\n\n /** Tear down a transition: drop popped pages, fix up classes, fire the `did` hooks. */\n private finish(run: RunningTransition): void {\n this.applyStates();\n // Cancelling reverts elements to their CSS-defined transforms. Do it *after* `applyStates`\n // has hidden everything below the top, so nothing flashes back to centre.\n run.player?.destroy();\n\n for (const entry of run.removed) {\n this.destroyEntry(entry);\n }\n\n callLifecycle(run.leaving, 'ngxViewDidLeave');\n callLifecycle(run.entering, 'ngxViewDidEnter');\n\n this.running = null;\n this._animating.set(false);\n\n if (this.config.manageFocus) this.moveFocus(run.entering);\n this.onTransitionEnd?.(run.event);\n }\n\n /** Jump an in-flight transition straight to its end state. */\n private settle(run: RunningTransition): void {\n run.player?.finish();\n this.finish(run);\n }\n\n // ---------------------------------------------------------------------------\n // Swipe-back\n // ---------------------------------------------------------------------------\n\n /**\n * Set up a back transition and hand it to the gesture, paused at progress 0.\n *\n * Deliberately fires no lifecycle hooks: a swipe is a *peek* until the user releases, and\n * pages should not be told they entered somewhere the user may drag right back out of. The\n * hooks fire when the pop actually commits, through `run()`.\n */\n beginInteractiveBack(): InteractiveBack | null {\n if (this.running) return null;\n\n const stack = this.pages();\n if (stack.length < 2) return null;\n\n const leaving = stack[stack.length - 1];\n const entering = stack[stack.length - 2];\n\n this.reveal(entering);\n const player = this.buildPlayer(entering, leaving, 'back', true);\n entering.element.classList.remove('ngx-stack-page--invisible');\n entering.element.classList.add('ngx-stack-page--animating');\n leaving.element.classList.add('ngx-stack-page--animating');\n\n return { player, entering, leaving };\n }\n\n /** The user let go without going far enough: run the transition back to where it started. */\n async abortInteractiveBack(back: InteractiveBack, ms: number): Promise<void> {\n await back.player.settle(0, ms);\n this.applyStates();\n back.player.destroy();\n }\n\n private buildPlayer(\n entering: StackEntry,\n leaving: StackEntry | null,\n direction: StackDirection,\n interactive = false,\n ): TransitionPlayer {\n const spec = this.transitionFn()({\n enteringEl: entering.element,\n leavingEl: leaving?.element ?? null,\n hostEl: this.hostEl,\n direction,\n rtl: this.isRtl(),\n width: this.hostEl.clientWidth || 1,\n duration: this.config.duration,\n });\n return new TransitionPlayer(spec, interactive);\n }\n\n // ---------------------------------------------------------------------------\n // Resolution\n // ---------------------------------------------------------------------------\n\n /** Which platform's look we're using, honouring a `platform` override in the config. */\n platformKind(): StackPlatformKind {\n return this.config.platform === 'auto' ? this.platform.kind : this.config.platform;\n }\n\n /** One function for every platform, a per-platform override, or the built-in. */\n transitionFn(): StackTransition {\n const configured = this.config.transitions;\n if (typeof configured === 'function') return configured;\n\n const kind = this.platformKind();\n return configured?.[kind] ?? BUILT_IN[kind];\n }\n\n /**\n * Read from the DOM rather than cached, so an app that flips `dir` at runtime — which is what\n * a language switcher does — mirrors on the very next transition without a reload.\n */\n isRtl(): boolean {\n if (this.config.direction !== 'auto') return this.config.direction === 'rtl';\n const view = this.doc.defaultView;\n return view ? view.getComputedStyle(this.hostEl).direction === 'rtl' : false;\n }\n\n /**\n * Only gates the *automatic* transitions. A swipe-back still animates: the user is dragging it\n * themselves, and direct manipulation is exempt — a gesture that doesn't visibly follow the\n * finger isn't reduced motion, it's a broken gesture.\n */\n private prefersReducedMotion(): boolean {\n if (!this.config.respectReducedMotion) return false;\n return this.doc.defaultView?.matchMedia('(prefers-reduced-motion: reduce)').matches ?? false;\n }\n\n // ---------------------------------------------------------------------------\n // DOM state\n // ---------------------------------------------------------------------------\n\n private reveal(entry: StackEntry): void {\n entry.element.classList.remove('ngx-stack-page--hidden');\n }\n\n /**\n * The definitive resting state. Exactly one page is visible: the top of the active tab's\n * stack. Everything else — buried pages, and every page of every inactive tab — is hidden and\n * inert but still mounted.\n */\n private applyStates(): void {\n const stacks = this.stacks();\n const activeTab = this.active();\n\n for (const [tab, stack] of Object.entries(stacks)) {\n const lastIndex = stack.length - 1;\n\n stack.forEach((entry, index) => {\n const isTop = tab === activeTab && index === lastIndex;\n\n entry.element.classList.toggle('ngx-stack-page--hidden', !isTop);\n entry.element.classList.remove('ngx-stack-page--invisible', 'ngx-stack-page--animating');\n entry.element.inert = !isTop;\n\n if (isTop) {\n entry.element.style.transform = '';\n entry.scrim.style.opacity = '';\n }\n });\n }\n }\n\n /**\n * Put focus in the page that just arrived, and say its name out loud.\n *\n * Without this a screen-reader user gets no signal that anything happened, and keyboard focus\n * stays on whatever control they activated — which has now slid off the screen and been marked\n * `inert`, leaving focus nowhere at all.\n */\n private moveFocus(entry: StackEntry): void {\n const explicit = entry.element.querySelector<HTMLElement>('[ngxStackAutofocus]');\n const target = explicit ?? entry.element;\n\n if (!explicit) {\n // A page container isn't focusable by default; -1 makes it programmatically focusable\n // without adding it to the tab order.\n target.setAttribute('tabindex', '-1');\n }\n target.focus({ preventScroll: true });\n\n const title = entry.route?.snapshot.title ?? this.doc.title;\n if (title) announce(this.doc, title);\n }\n\n private destroyEntry(entry: StackEntry): void {\n entry.ref.destroy();\n entry.element.remove();\n }\n\n destroy(): void {\n if (this.running) {\n this.running.player?.destroy();\n this.running = null;\n }\n for (const stack of Object.values(this.stacks())) {\n for (const entry of stack) this.destroyEntry(entry);\n }\n this.stacks.set({});\n this.pruned.clear();\n }\n}\n","const STYLE_ID = 'ngx-stack-styles';\n\n/**\n * Page wrappers are created imperatively, outside any component template, so Angular's\n * style encapsulation can't reach them. These rules go in the document once instead.\n * Everything is driven by CSS custom properties so apps can restyle without `!important`.\n */\nconst CSS = `\n.ngx-stack-host {\n display: block;\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n\n /* Notches, home indicators, and the Android navigation bar. Declared here so pages can just\n use var(--ngx-stack-safe-top) without every one of them repeating the env() dance — and so\n they still resolve to 0px on a browser that has never heard of a notch. */\n --ngx-stack-safe-top: env(safe-area-inset-top, 0px);\n --ngx-stack-safe-bottom: env(safe-area-inset-bottom, 0px);\n --ngx-stack-safe-left: env(safe-area-inset-left, 0px);\n --ngx-stack-safe-right: env(safe-area-inset-right, 0px);\n}\n\n/* Where page titles are announced to screen readers. Visually gone, but not display:none —\n which would take it out of the accessibility tree along with everything we're trying to say. */\n.ngx-stack-announcer {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n.ngx-stack-page {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n transform: translateX(0);\n background: var(--ngx-stack-page-background, #fff);\n /* Only ever visible while the page is translated, i.e. mid-transition. */\n box-shadow: var(--ngx-stack-page-shadow, -6px 0 20px rgb(0 0 0 / 12%));\n}\n\n/* The routed component fills the wrapper and scrolls; the scrim sits on top of it.\n Wrapped in :where() so this weighs nothing: a page component only has to say\n \":host { display: flex }\" to take the layout over, with no !important and no fight. */\n:where(.ngx-stack-page > :not(.ngx-stack-scrim)) {\n flex: 1 1 auto;\n min-height: 0;\n display: block;\n overflow: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n/* Set while a page is being created, so it can't flash at its final position for a frame\n before the transition's first keyframe lands. */\n.ngx-stack-page--invisible {\n opacity: 0;\n}\n\n.ngx-stack-page--animating {\n will-change: transform;\n}\n\n/* Buried pages — and, with tabs, every page of every inactive tab. content-visibility:hidden\n skips their rendering while preserving internal state (crucially, scroll offsets), so coming\n back to a page finds it exactly where you left it with no scroll-restoration bookkeeping on\n our side. They stay in the DOM: that is what makes a tab switch instant and a swipe possible. */\n.ngx-stack-page--hidden {\n visibility: hidden;\n pointer-events: none;\n content-visibility: hidden;\n}\n\n/* Focused programmatically after a transition; never show a ring for it. */\n.ngx-stack-page:focus {\n outline: none;\n}\n\n.ngx-stack-scrim {\n position: absolute;\n inset: 0;\n z-index: 10;\n opacity: 0;\n pointer-events: none;\n background: var(--ngx-stack-scrim-color, #000);\n}\n`;\n\n/** Idempotent: safe to call from every outlet on every init. */\nexport function ensureStackStyles(doc: Document): void {\n if (doc.getElementById(STYLE_ID)) return;\n const style = doc.createElement('style');\n style.id = STYLE_ID;\n style.textContent = CSS;\n doc.head.appendChild(style);\n}\n","import {\n ChangeDetectorRef,\n DOCUMENT,\n Directive,\n ElementRef,\n EnvironmentInjector,\n type Injector,\n ViewContainerRef,\n inject,\n output,\n type ComponentRef,\n type OnDestroy,\n type Signal,\n type Type,\n} from '@angular/core';\n\nimport { NGX_STACK_CONFIG, type GuardPolicy } from '../config';\nimport { SwipeBackGesture, type SwipeBackHost } from '../gesture/swipe-back-gesture';\nimport { NgxStackSwipe } from '../gesture/swipe-service';\nimport { NGX_STACK_PLATFORM } from '../platform/platform';\nimport {\n StackController,\n type InteractiveBack,\n type StackTransitionEvent,\n} from './stack-controller';\nimport { pageAllowsSwipeBack, type StackEntry } from './stack-entry';\nimport { ensureStackStyles } from './styles';\n\n/**\n * Everything the two kinds of stack have in common — which is almost everything.\n *\n * `NgxStackOutlet` is fed by the Router and `NgxStack` by `push()`, and that difference is real but\n * shallow: it only decides *where the next page comes from*. Once a page exists, holding it,\n * transitioning to it, dragging it around with a finger and tearing it down are identical jobs, and\n * a swipe-back must behave the same in both. Keeping that in one place is the only way it stays that\n * way.\n *\n * So a subclass supplies three things — how strict to be about guards, whether it overrides the\n * app-wide swipe switch, and what a committed swipe should actually *do* — and inherits the rest.\n */\n@Directive()\nexport abstract class StackHostBase implements SwipeBackHost, OnDestroy {\n /** Fires as a transition begins — including one a finger is about to scrub. */\n readonly transitionStart = output<StackTransitionEvent>();\n /** Fires once the pages have settled and any popped page has been destroyed. */\n readonly transitionEnd = output<StackTransitionEvent>();\n\n protected readonly config = inject(NGX_STACK_CONFIG);\n protected readonly platform = inject(NGX_STACK_PLATFORM);\n protected readonly swipe = inject(NgxStackSwipe);\n protected readonly viewContainer = inject(ViewContainerRef);\n protected readonly environmentInjector = inject(EnvironmentInjector);\n protected readonly changeDetector = inject(ChangeDetectorRef);\n\n readonly hostEl: HTMLElement = inject(ElementRef<HTMLElement>).nativeElement;\n\n protected readonly controller = new StackController(this.hostEl, this.config, this.platform);\n\n private gesture: SwipeBackGesture | null = null;\n\n /** The active stack's pages, bottom first. */\n readonly pages: Signal<readonly StackEntry[]> = this.controller.pages;\n readonly depth: Signal<number> = this.controller.depth;\n readonly animating: Signal<boolean> = this.controller.animating;\n\n constructor() {\n ensureStackStyles(inject(DOCUMENT));\n this.controller.onTransitionStart = (event) => this.transitionStart.emit(event);\n this.controller.onTransitionEnd = (event) => this.transitionEnd.emit(event);\n }\n\n /** Arm the gesture. Subclasses call this once they are ready to be swiped. */\n protected startGesture(): void {\n this.gesture = new SwipeBackGesture(this, this.config, this.platform);\n }\n\n // ---------------------------------------------------------------------------\n // Creating pages\n // ---------------------------------------------------------------------------\n\n /**\n * Instantiate a page component and hand it to the controller to be wrapped and mounted.\n *\n * The `markForCheck` matters and is easy to lose: both hosts are OnPush with an empty template of\n * their own, so nothing would ever dirty the view and the freshly inserted page would sit there\n * un-checked until something unrelated happened to trigger a pass.\n */\n protected createPage<T>(\n component: Type<T>,\n options: { injector: Injector; environmentInjector?: EnvironmentInjector },\n ): ComponentRef<T> {\n const ref = this.viewContainer.createComponent(component, {\n index: this.viewContainer.length,\n injector: options.injector,\n environmentInjector: options.environmentInjector ?? this.environmentInjector,\n });\n\n this.changeDetector.markForCheck();\n return ref;\n }\n\n // ---------------------------------------------------------------------------\n // SwipeBackHost\n // ---------------------------------------------------------------------------\n\n /**\n * Three layers, narrowest last, each able to veto: the app-wide switch, this stack, and the page\n * currently on top. Re-evaluated on every touch, so all three can change at runtime.\n */\n canSwipeBack(): boolean {\n // An explicit value on the stack overrides the app-wide one, in both directions.\n if (!(this.swipeBackOverride() ?? this.swipe.enabled())) return false;\n\n // Deliberately `depth()`, not `canGoBack()`: the latter counts pages evicted by `maxDepth` and\n // parents that were never built, which no longer exist and so cannot be dragged into view. A\n // button can still take you there; a finger can't drag what isn't on screen.\n if (this.controller.depth() < 2 || this.controller.animating()) return false;\n\n return pageAllowsSwipeBack(this.controller.top(), this.guardPolicy());\n }\n\n isRtl(): boolean {\n return this.controller.isRtl();\n }\n\n beginSwipeBack(): InteractiveBack | null {\n return this.controller.beginInteractiveBack();\n }\n\n abortSwipeBack(back: InteractiveBack, ms: number): void {\n void this.controller.abortInteractiveBack(back, ms);\n }\n\n /** The user let go past the threshold. The animation is done; make the pop real. */\n abstract commitSwipeBack(back: InteractiveBack, ms: number): void;\n\n /** `null` to defer to the app-wide {@link NgxStackSwipe}. */\n protected abstract swipeBackOverride(): boolean | null;\n\n /** Only routed pages can carry a `canDeactivate` guard, so only they need a policy for one. */\n protected abstract guardPolicy(): GuardPolicy;\n\n // ---------------------------------------------------------------------------\n\n ngOnDestroy(): void {\n this.gesture?.destroy();\n this.controller.destroy();\n }\n}\n","/**\n * Notices when the *browser* has already animated a navigation.\n *\n * On iOS Safari and iOS PWAs, an edge swipe triggers WebKit's own back navigation, and\n * WebKit draws its own page slide for it. We still get the resulting `popstate`, so without\n * this we would helpfully animate the same navigation a second time.\n *\n * The Navigation API's `hasUAVisualTransition` is exactly the flag for this. Where the API\n * isn't available we simply animate — a double animation is worse than no information, but\n * only slightly, and `systemGesture: 'suppress'` avoids the situation entirely.\n */\ninterface NavigateEventLike extends Event {\n readonly hasUAVisualTransition?: boolean;\n}\n\ninterface NavigationLike extends EventTarget {\n addEventListener(type: 'navigate', listener: (event: NavigateEventLike) => void): void;\n removeEventListener(type: 'navigate', listener: (event: NavigateEventLike) => void): void;\n}\n\nexport class SystemTransitionWatcher {\n private uaAnimated = false;\n private readonly detach: () => void;\n\n constructor(win: Window) {\n const navigation = (win as unknown as { navigation?: NavigationLike }).navigation;\n\n if (!navigation?.addEventListener) {\n this.detach = () => undefined;\n return;\n }\n\n const onNavigate = (event: NavigateEventLike): void => {\n this.uaAnimated = event.hasUAVisualTransition === true;\n };\n\n navigation.addEventListener('navigate', onNavigate);\n this.detach = () => navigation.removeEventListener('navigate', onNavigate);\n }\n\n /** Did the browser animate the navigation we are about to handle? Reads and clears. */\n consume(): boolean {\n const value = this.uaAnimated;\n this.uaAnimated = false;\n return value;\n }\n\n destroy(): void {\n this.detach();\n }\n}\n","import type { ActivatedRouteSnapshot } from '@angular/router';\n\n/**\n * Which tab a URL belongs to, or `''` when the app has no tabs — or when the URL belongs to none of\n * them, which is what a login screen or a full-screen modal route looks like. Those get their own\n * stack, outside the tab bar, which is almost always what you want.\n */\nexport function tabOfUrl(url: string, tabs: readonly string[] | undefined): string {\n if (!tabs?.length) return '';\n\n // Strip the leading slash, query and fragment, then take the first segment.\n const path = url.replace(/^\\/+/, '').split(/[?#]/, 1)[0];\n const first = path.split('/', 1)[0];\n\n return tabs.includes(first) ? first : '';\n}\n\n/**\n * `data: { tab: 'search' }` — for a page that belongs to a tab its URL doesn't name.\n *\n * Most apps nest their URLs by tab and never need this. But a flat route, or a tab whose pages live\n * under a different prefix, has no way to say where it belongs otherwise, and would silently land in\n * the no-tab stack: mounted, outside the tab bar, and stranded the moment you switch tabs.\n */\nexport function tabOfRouteData(\n data: Record<string, unknown> | undefined,\n tabs: readonly string[] | undefined,\n): string | null {\n const tab = data?.['tab'];\n if (typeof tab !== 'string') return null;\n\n if (tabs?.length && !tabs.includes(tab)) {\n throw new Error(\n `[ngx-stack] A route declares data: { tab: '${tab}' }, but '${tab}' is not one of the ` +\n `configured tabs [${tabs.join(', ')}]. Its pages would go to a stack no tab can reach.`,\n );\n }\n\n return tab;\n}\n\n/** Structural, so the helpers stay testable without a router. */\ninterface RouteSnapshotLike {\n routeConfig: { data?: Record<string, unknown> } | null;\n}\n\n/**\n * The tab a route belongs to, asking it and then every route it is nested inside.\n *\n * The point of walking the ancestors: with nested routes you declare the tab **once**, on the tab's\n * root, and every page under it inherits — rather than repeating `data: { tab }` on each one.\n *\n * Deliberately reads `routeConfig.data` rather than the snapshot's own `data`. The snapshot's\n * version already merges in inherited data, but only from ancestors Angular considers inheritable\n * (componentless ones, unless you change `paramsInheritanceStrategy`). Walking the configs ourselves\n * means a tab root works whether or not it happens to have a component.\n */\nexport function tabOfRouteTree(\n pathFromRoot: readonly RouteSnapshotLike[],\n tabs: readonly string[] | undefined,\n): string | null {\n // Innermost first, so a page can override the tab it is nested in.\n for (let i = pathFromRoot.length - 1; i >= 0; i--) {\n const tab = tabOfRouteData(pathFromRoot[i].routeConfig?.data, tabs);\n if (tab) return tab;\n }\n return null;\n}\n\n/**\n * Which stack a page belongs on: what the route tree says, and failing that, what its URL implies.\n *\n * The single place that answers this, so the outlet (which files the page) and `NgxStackTabs` (which\n * lights up the tab bar) can never disagree about where a page went.\n */\nexport function tabOfRoute(\n snapshot: ActivatedRouteSnapshot,\n url: string,\n tabs: readonly string[] | undefined,\n): string {\n return tabOfRouteTree(snapshot.pathFromRoot, tabs) ?? tabOfUrl(url, tabs);\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DOCUMENT,\n type EnvironmentInjector,\n EventEmitter,\n type Injector,\n ViewEncapsulation,\n computed,\n inject,\n input,\n type ComponentRef,\n type OnDestroy,\n type OnInit,\n type Signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport {\n ActivatedRoute,\n ChildrenOutletContexts,\n NavigationCancel,\n NavigationError,\n PRIMARY_OUTLET,\n Router,\n type Data,\n type RouterOutletContract,\n} from '@angular/router';\n\nimport type { GuardPolicy } from '../config';\nimport type { InteractiveBack } from '../core/stack-controller';\nimport type { StackEntry } from '../core/stack-entry';\nimport { StackHostBase } from '../core/stack-host';\nimport { SystemTransitionWatcher } from '../platform/system-transition';\nimport { deriveParentUrl } from './parent-url';\nimport {\n NgxStackNav,\n readAnimatedHint,\n readDirectionHint,\n type BackTarget,\n type StackBackTarget,\n} from './stack-nav';\nimport { tabOfRoute } from './tab-url';\n\n/** What Angular's own `OutletInjector` does: hand routed components their route and contexts. */\nclass StackOutletInjector implements Injector {\n constructor(\n private readonly route: ActivatedRoute,\n private readonly childContexts: ChildrenOutletContexts,\n private readonly parent: Injector,\n ) {}\n\n get(token: unknown, notFoundValue?: unknown, options?: unknown): unknown {\n if (token === ActivatedRoute) return this.route;\n if (token === ChildrenOutletContexts) return this.childContexts;\n return (this.parent as { get: (...args: unknown[]) => unknown }).get(\n token,\n notFoundValue,\n options,\n );\n }\n}\n\n/**\n * A `<router-outlet>` that keeps a stack instead of a single page.\n *\n * The stock outlet destroys the outgoing component the moment you navigate. That is the right\n * default and completely incompatible with a swipe-back: the page you are swiping back to has to\n * already be on screen, mounted and painted, *before* the navigation that reveals it happens —\n * otherwise there is nothing to drag into view.\n *\n * So pages here are mounted once and stay. Which one you are looking at is decided by where you are\n * in the history, and the direction of each transition is inferred by asking whether the incoming\n * URL is already on the stack (going back) or not (going forward).\n *\n * With `tabs` configured, one outlet holds one stack per tab and shows the active one.\n */\n@Component({\n selector: 'ngx-stack-outlet',\n template: '',\n host: { class: 'ngx-stack-host' },\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n exportAs: 'ngxStackOutlet',\n})\nexport class NgxStackOutlet\n extends StackHostBase\n implements OnInit, OnDestroy, RouterOutletContract, StackBackTarget\n{\n /** Matches `<router-outlet name>`, for named outlets. */\n readonly name = input(PRIMARY_OUTLET);\n\n /**\n * Swipe-back for this stack specifically. `null` (the default) defers to `NgxStackSwipe`, the\n * app-wide switch; `true` or `false` overrides it here.\n */\n readonly swipeBack = input<boolean | null>(null);\n\n private readonly parentContexts = inject(ChildrenOutletContexts);\n private readonly router = inject(Router);\n private readonly nav = inject(NgxStackNav);\n private readonly document = inject(DOCUMENT);\n\n private systemTransition: SystemTransitionWatcher | null = null;\n\n private activatedRouteRef: ActivatedRoute | null = null;\n private current: StackEntry | null = null;\n private initialized = false;\n\n /** A committed swipe, animated to the end, waiting for the router to catch up. */\n private pendingSwipe: InteractiveBack | null = null;\n\n // Required by RouterOutletContract, which predates `output()` and types these as EventEmitters.\n readonly activateEvents = new EventEmitter<unknown>();\n readonly deactivateEvents = new EventEmitter<unknown>();\n readonly attachEvents = new EventEmitter<unknown>();\n readonly detachEvents = new EventEmitter<unknown>();\n\n readonly activeTab: Signal<string> = this.controller.activeTab;\n\n /**\n * Is there anywhere to go back to? Show your back button on this.\n *\n * True even with a single page on the stack, if that page has a parent it could go up to — which\n * is exactly the cold-deep-link case, where nothing is beneath but obviously something should be.\n */\n readonly canGoBack: Signal<boolean> = computed(\n () => this.controller.canGoBack() || this.parentOfTop() !== null,\n );\n\n constructor() {\n super();\n\n // If a navigation dies after a swipe has already animated the page away, put it back.\n this.router.events.pipe(takeUntilDestroyed()).subscribe((event) => {\n if (event instanceof NavigationCancel || event instanceof NavigationError) {\n this.rollBackPendingSwipe();\n }\n });\n }\n\n ngOnInit(): void {\n if (this.initialized) return;\n this.initialized = true;\n\n this.parentContexts.onChildOutletCreated(this.name(), this);\n\n // The route can be activated before the outlet exists — e.g. it sits inside an `@if` that only\n // just became true. Pick up whatever is already waiting for us.\n const context = this.parentContexts.getContext(this.name());\n if (context?.route) {\n this.activateWith(context.route, context.injector);\n }\n\n this.startGesture();\n this.nav.registerStack(this);\n\n const win = this.document.defaultView;\n if (win) this.systemTransition = new SystemTransitionWatcher(win);\n }\n\n // ---------------------------------------------------------------------------\n // RouterOutletContract\n // ---------------------------------------------------------------------------\n\n get isActivated(): boolean {\n return this.current !== null;\n }\n\n get component(): object | null {\n return (this.current?.ref.instance as object) ?? null;\n }\n\n get activatedRoute(): ActivatedRoute | null {\n return this.activatedRouteRef;\n }\n\n get activatedRouteData(): Data {\n return this.activatedRouteRef?.snapshot.data ?? {};\n }\n\n activateWith(route: ActivatedRoute, environmentInjector: EnvironmentInjector): void {\n const url = this.urlOf(route);\n const tab = tabOfRoute(route.snapshot, url, this.config.tabs);\n const hint = readDirectionHint(this.router);\n\n // If the browser already drew its own back animation, drawing ours would double it up.\n let animated = !(this.systemTransition?.consume() ?? false);\n\n // A caller rebuilding a stack at startup wants the pages to just *be* there, not to watch them\n // fly in one after another.\n if (readAnimatedHint(this.router) === false) animated = false;\n\n // Changing tabs is not a push and not a pop — it's a cut. Nothing is created, nothing destroyed,\n // the other tab's stack simply comes back on screen exactly as it was. Sliding it in would imply\n // a relationship between the two tabs that doesn't exist.\n if (tab !== this.controller.activeTab() && hint !== 'root') animated = false;\n\n const existingIndex = this.controller.findByUrl(url, tab);\n\n const swipe = this.pendingSwipe;\n this.pendingSwipe = null;\n\n if (swipe) {\n // The swipe already ran the whole animation. Hand its player to the controller so it finalises\n // instead of transitioning a second time — but only if history actually took us where the\n // swipe aimed. If something else intervened, throw the gesture's work away.\n const aimedAt =\n existingIndex >= 0 && this.controller.at(existingIndex, tab) === swipe.entering;\n\n if (aimedAt) {\n this.adopt(swipe.entering, route);\n void this.controller.run({\n kind: 'pop',\n tab,\n toIndex: existingIndex,\n animated: true,\n player: swipe.player,\n });\n return;\n }\n swipe.player.destroy();\n }\n\n const goingBack = hint !== 'forward' && hint !== 'root';\n\n // Already on the stack: unwind to it.\n if (goingBack && existingIndex >= 0) {\n this.adopt(this.controller.at(existingIndex, tab)!, route);\n void this.controller.run({ kind: 'pop', tab, toIndex: existingIndex, animated });\n return;\n }\n\n // Going back to a page that isn't mounted. Two ways that happens, wanting the same handling:\n // `maxDepth` evicted it, or we deep-linked into the middle of the app and are walking up to a\n // parent that was never built. Either way, rebuild it and animate as a *back*, because that is\n // what actually happened — whatever the DOM currently remembers about it.\n if (hint === 'back' || (goingBack && this.controller.wasPruned(url, tab))) {\n const entry = this.createEntry(route, environmentInjector, url, tab);\n this.adopt(entry, route);\n void this.controller.run({ kind: 'restore', tab, entering: entry, animated });\n this.activateEvents.emit(entry.ref.instance);\n return;\n }\n\n const entry = this.createEntry(route, environmentInjector, url, tab);\n this.adopt(entry, route);\n\n // `replaceUrl: true` says the history entry was overwritten rather than added. The stack has to\n // agree: swap the top page rather than stack a second one on it, or the stack grows while\n // history doesn't and a back button starts skipping pages.\n const replacing =\n this.router.getCurrentNavigation()?.extras.replaceUrl === true && this.controller.depth() > 0;\n\n void this.controller.run(\n hint === 'root'\n ? { kind: 'root', tab, entering: entry, animated }\n : replacing\n ? { kind: 'replace', tab, entering: entry, animated }\n : { kind: 'push', tab, entering: entry, animated },\n );\n this.activateEvents.emit(entry.ref.instance);\n }\n\n deactivate(): void {\n const entry = this.current;\n if (entry) {\n const context = this.parentContexts.getContext(this.name());\n if (context) {\n // Hold on to this page's nested outlets, so coming back to it doesn't find them empty.\n entry.savedContexts = context.children.onOutletDeactivated();\n }\n this.deactivateEvents.emit(entry.ref.instance);\n }\n\n // Note what we do *not* do here: destroy the component. It stays on the stack. If it is being\n // popped, the controller destroys it once the transition has played out.\n this.current = null;\n this.activatedRouteRef = null;\n }\n\n detach(): ComponentRef<unknown> {\n throw new Error(\n '[ngx-stack] detach() is not supported. <ngx-stack-outlet> manages page lifetime itself; a ' +\n 'RouteReuseStrategy that returns shouldDetach: true will fight it. provideNgxStack() ' +\n 'installs NgxStackRouteReuseStrategy for exactly this reason.',\n );\n }\n\n attach(): void {\n throw new Error('[ngx-stack] attach() is not supported. See detach().');\n }\n\n // ---------------------------------------------------------------------------\n // StackHostBase / BackTarget\n // ---------------------------------------------------------------------------\n\n protected swipeBackOverride(): boolean | null {\n return this.swipeBack();\n }\n\n protected guardPolicy(): GuardPolicy {\n return this.config.guardPolicy;\n }\n\n commitSwipeBack(back: InteractiveBack, ms: number): void {\n void back.player.settle(1, ms).then(() => {\n this.pendingSwipe = back;\n // Go back for real, so the URL and the browser's back button stay honest. The animation is\n // already finished; `activateWith` will adopt the player and just tidy up.\n void this.nav.back();\n });\n }\n\n /**\n * Where a \"back\" should actually go.\n *\n * Usually the page beneath the top of the *active* stack — which, with tabs, is emphatically not\n * whatever the browser happens to have behind us in history. When nothing is beneath, we fall back\n * to the page this one sits under. That page isn't mounted, so it has to be built; `mounted` is\n * how {@link NgxStackNav.back} tells the two apart, because only one of them can be served by a\n * plain `history.back()`.\n */\n backTarget(): BackTarget | null {\n const stack = this.controller.pages();\n if (stack.length >= 2) {\n return { url: stack[stack.length - 2].url, mounted: true };\n }\n\n const parent = this.parentOfTop();\n return parent ? { url: parent, mounted: false } : null;\n }\n\n private rollBackPendingSwipe(): void {\n const swipe = this.pendingSwipe;\n if (!swipe) return;\n this.pendingSwipe = null;\n void this.controller.abortInteractiveBack(swipe, this.config.duration);\n }\n\n // ---------------------------------------------------------------------------\n\n /**\n * Where the top page sits, when nothing is mounted underneath it.\n *\n * Nobody normally has to say: `/inbox/item/12` obviously sits under `/inbox`, and the route config\n * already knows it. `data: { parent }` is only for URLs that don't tell the truth.\n */\n private parentOfTop(): string | null {\n const url = this.controller.top()?.url;\n return url ? deriveParentUrl(this.router.config, url) : null;\n }\n\n private createEntry(\n route: ActivatedRoute,\n environmentInjector: EnvironmentInjector,\n url: string,\n tab: string,\n ): StackEntry {\n const component = route.snapshot.routeConfig?.component;\n if (!component) {\n throw new Error(\n `[ngx-stack] Route \"${url}\" has no component. <ngx-stack-outlet> can only host component ` +\n 'routes — loadComponent is fine, but redirects and componentless routes are not.',\n );\n }\n\n const childContexts = this.parentContexts.getOrCreateContext(this.name()).children;\n const injector = new StackOutletInjector(route, childContexts, this.viewContainer.injector);\n\n const ref = this.createPage(component, { injector, environmentInjector });\n return this.controller.adopt(ref, url, route, tab);\n }\n\n /** Make `entry` the outlet's current page and give it back its nested outlets. */\n private adopt(entry: StackEntry, route: ActivatedRoute): void {\n entry.route = route;\n this.current = entry;\n this.activatedRouteRef = route;\n\n const context = this.parentContexts.getContext(this.name());\n if (context && entry.savedContexts) {\n context.children.onOutletReAttached(entry.savedContexts);\n entry.savedContexts = undefined;\n }\n }\n\n private urlOf(route: ActivatedRoute): string {\n return this.router.serializeUrl(this.router.createUrlTree(['.'], { relativeTo: route }));\n }\n\n override ngOnDestroy(): void {\n this.systemTransition?.destroy();\n this.nav.unregisterStack(this);\n this.parentContexts.onChildOutletDestroyed(this.name());\n super.ngOnDestroy();\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n Injector,\n ViewEncapsulation,\n inject,\n input,\n type OnInit,\n type Signal,\n type Type,\n} from '@angular/core';\n\nimport type { GuardPolicy } from '../config';\nimport type { InteractiveBack } from '../core/stack-controller';\nimport type { StackEntry } from '../core/stack-entry';\nimport { StackHostBase } from '../core/stack-host';\n\n/** Imperative stacks have no URLs, so all their pages live in the one unnamed stack. */\nconst NO_TAB = '';\n\n/**\n * A self-contained page stack with no URLs — the escape hatch for navigation that has no business\n * being in the address bar.\n *\n * A multi-step filter sheet, a wizard inside a modal, a drill-down in one tab of a tab bar: these\n * are all stacks, they all want the same push/pop transition and the same swipe-back, and none of\n * them should push history entries that the browser's back button then has to unwind one at a time.\n *\n * ```html\n * <ngx-stack [root]=\"FilterStep1\" #filters />\n * ```\n * ```ts\n * filters.push(FilterStep2, { category: 'shoes' });\n * ```\n *\n * Pages reach the stack they are standing on with `inject(NgxStack)`. For anything the user should\n * be able to link to, bookmark or reload, use `<ngx-stack-outlet>` instead.\n */\n@Component({\n selector: 'ngx-stack',\n template: '',\n host: { class: 'ngx-stack-host' },\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n exportAs: 'ngxStack',\n})\nexport class NgxStack extends StackHostBase implements OnInit {\n /** The bottom page. Mounted on init; use `setRoot()` to change it afterwards. */\n readonly root = input<Type<unknown> | null>(null);\n\n /** Inputs for the root page, applied with `setInput`. */\n readonly rootInputs = input<Record<string, unknown>>();\n\n /**\n * Swipe-back for this stack specifically. `null` (the default) defers to `NgxStackSwipe`, the\n * app-wide switch; `true` or `false` overrides it here.\n */\n readonly swipeBack = input<boolean | null>(null);\n\n /** The stack's own node injector, so pages can `inject(NgxStack)` and push further. */\n private readonly pageInjector = inject(Injector);\n\n readonly canGoBack: Signal<boolean> = this.controller.canGoBack;\n\n ngOnInit(): void {\n const root = this.root();\n if (root) {\n const entry = this.mount(root, this.rootInputs());\n void this.controller.run({ kind: 'push', tab: NO_TAB, entering: entry, animated: false });\n }\n this.startGesture();\n }\n\n /** Push a page on top. Resolves when the transition has finished. */\n push<T>(component: Type<T>, inputs?: Record<string, unknown>): Promise<void> {\n const entry = this.mount(component, inputs);\n return this.controller.run({ kind: 'push', tab: NO_TAB, entering: entry, animated: true });\n }\n\n /** Pop the top page. A no-op at the root, so it is safe to call blindly. */\n pop(): Promise<void> {\n return this.popTo(this.controller.depth() - 2);\n }\n\n /** Unwind to the page at `index` (0 is the root), destroying everything above it. */\n popTo(index: number): Promise<void> {\n if (index < 0 || index >= this.controller.depth() - 1) return Promise.resolve();\n return this.controller.run({ kind: 'pop', tab: NO_TAB, toIndex: index, animated: true });\n }\n\n popToRoot(): Promise<void> {\n return this.popTo(0);\n }\n\n /** Throw the stack away and start again from `component`. */\n setRoot<T>(component: Type<T>, inputs?: Record<string, unknown>): Promise<void> {\n const entry = this.mount(component, inputs);\n return this.controller.run({ kind: 'root', tab: NO_TAB, entering: entry, animated: true });\n }\n\n // ---------------------------------------------------------------------------\n // StackHostBase\n // ---------------------------------------------------------------------------\n\n protected swipeBackOverride(): boolean | null {\n return this.swipeBack();\n }\n\n /** No routes here, so no `canDeactivate` guards to be careful about. */\n protected guardPolicy(): GuardPolicy {\n return 'allow';\n }\n\n commitSwipeBack(back: InteractiveBack, ms: number): void {\n void back.player.settle(1, ms).then(() => {\n const index = this.controller.pages().indexOf(back.entering);\n if (index < 0) return;\n\n // Hand the finished player over so the pop finalises rather than animating a second time.\n void this.controller.run({\n kind: 'pop',\n tab: NO_TAB,\n toIndex: index,\n animated: true,\n player: back.player,\n });\n });\n }\n\n // ---------------------------------------------------------------------------\n\n private mount<T>(component: Type<T>, inputs?: Record<string, unknown>): StackEntry {\n const ref = this.createPage(component, { injector: this.pageInjector });\n\n for (const [name, value] of Object.entries(inputs ?? {})) {\n ref.setInput(name, value);\n }\n\n return this.controller.adopt(ref, '', null, NO_TAB);\n }\n}\n","import { Injectable, computed, inject, signal, type Signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NavigationEnd, Router, type ActivatedRouteSnapshot } from '@angular/router';\n\nimport { NGX_STACK_CONFIG } from '../config';\nimport { tabOfRoute } from './tab-url';\n\n/**\n * Remembers where you were in each tab.\n *\n * The stacks themselves are `NgxStackOutlet`'s job — configure `tabs` and it keeps one per tab,\n * mounted and untouched while you're elsewhere. This is the other half: tapping \"Search\" should\n * take you back to the search result you were reading three screens deep, not dump you at the\n * search tab's front page. So we watch navigations, note the current URL of each tab, and\n * `select()` returns you to it.\n *\n * The tab *bar* is yours to draw — the library ships no visual design. All you need from us:\n *\n * ```ts\n * const tabs = inject(NgxStackTabs);\n * ```\n * ```html\n * @for (tab of ['home', 'search', 'profile']; track tab) {\n * <button [class.active]=\"tabs.active() === tab\" (click)=\"tabs.select(tab)\">{{ tab }}</button>\n * }\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class NgxStackTabs {\n private readonly router = inject(Router);\n private readonly config = inject(NGX_STACK_CONFIG);\n\n private readonly urls = signal<Record<string, string>>({});\n private readonly _active = signal('');\n\n /** The tab currently on screen, or `''` before the first navigation into one. */\n readonly active: Signal<string> = this._active.asReadonly();\n\n /** The tabs you configured, in order. */\n readonly tabs: Signal<readonly string[]> = computed(() => this.config.tabs ?? []);\n\n constructor() {\n this.router.events.pipe(takeUntilDestroyed()).subscribe((event) => {\n if (!(event instanceof NavigationEnd)) return;\n\n const url = event.urlAfterRedirects;\n\n // Exactly the rule the outlet uses to file the page, so the bar and the stacks can't disagree.\n const tab = tabOfRoute(this.leaf(), url, this.config.tabs);\n if (!tab) return;\n\n this._active.set(tab);\n this.urls.update((urls) => ({ ...urls, [tab]: url }));\n });\n }\n\n /** The page that actually landed. */\n private leaf(): ActivatedRouteSnapshot {\n let route = this.router.routerState.snapshot.root;\n while (route.firstChild) route = route.firstChild;\n return route;\n }\n\n /** Where `tab` was last seen, or its front page if it hasn't been visited yet. */\n urlOf(tab: string): string {\n return this.urls()[tab] ?? `/${tab}`;\n }\n\n /**\n * Switch to `tab`, landing back on whatever page you last had open there.\n *\n * Tapping the tab you're already on takes you to its root, which is what every native tab bar\n * does — it's the standard way back out of a deep drill-down.\n */\n select(tab: string): Promise<boolean> {\n if (tab === this._active()) {\n return this.router.navigateByUrl(`/${tab}`);\n }\n return this.router.navigateByUrl(this.urlOf(tab));\n }\n}\n","import type { StackTransition, TransitionSpec } from './transition';\n\n/**\n * Pages swap instantly.\n *\n * Give it to a platform you'd rather not animate — `transitions: { web: noneTransition }` is a\n * common choice, since a page slide on a desktop monitor mostly just moves a lot of pixels.\n *\n * Note this also disarms the swipe on that platform in practice: there are no keyframes for a finger\n * to scrub, so a drag has nothing to follow.\n */\nexport const noneTransition: StackTransition = (): TransitionSpec => ({\n duration: 0,\n easing: 'linear',\n animations: [],\n});\n","/*\n * ngx-stack — native-feeling page stacks for Angular.\n */\n\n// Setup\nexport {\n provideNgxStack,\n provideCapacitorBack,\n provideCordovaBack,\n type CapacitorAppLike,\n} from './lib/provide';\nexport {\n type GuardPolicy,\n type NgxStackConfig,\n type StackTransitionMap,\n type SystemGesturePolicy,\n} from './lib/config';\n\n// The two ways to hold a stack\nexport { NgxStackOutlet } from './lib/router/stack-outlet';\nexport { NgxStack } from './lib/nav/ngx-stack';\n\n// Navigation\nexport { NgxStackNav } from './lib/router/stack-nav';\nexport { NgxStackTabs } from './lib/router/stack-tabs';\nexport { NgxStackSwipe } from './lib/gesture/swipe-service';\n\n// Required by provideNgxStack, and exported so an app composing its own strategy can defer to it.\nexport { NgxStackRouteReuseStrategy } from './lib/router/route-reuse-strategy';\n\n// Pages\nexport type { NgxStackPage, StackEntry } from './lib/core/stack-entry';\nexport type { StackTransitionEvent } from './lib/core/stack-controller';\n\n// Transitions\nexport { iosTransition } from './lib/animation/ios-transition';\nexport { androidTransition } from './lib/animation/android-transition';\nexport { webTransition } from './lib/animation/web-transition';\nexport { noneTransition } from './lib/animation/none-transition';\n// The two shapes the built-ins are made of. Build your own by re-tuning either.\nexport { slideTransition, type SlideOptions } from './lib/animation/slide';\nexport { riseTransition, type RiseOptions } from './lib/animation/rise';\nexport { scrimOf } from './lib/animation/transition';\nexport type {\n ElementAnimation,\n StackDirection,\n StackTransition,\n TransitionContext,\n TransitionSpec,\n} from './lib/animation/transition';\n\n// Deep links — for composing with a custom `deepLinks` function.\nexport { deriveParentUrl } from './lib/router/parent-url';\n\n// Platform\nexport { NGX_STACK_PLATFORM } from './lib/platform/platform';\nexport type { StackPlatform, StackPlatformKind } from './lib/platform/platform';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngx-stack.mjs","sources":["../../../projects/ngx-stack/src/lib/config.ts","../../../projects/ngx-stack/src/lib/platform/platform.ts","../../../projects/ngx-stack/src/lib/router/parent-url.ts","../../../projects/ngx-stack/src/lib/router/route-reuse-strategy.ts","../../../projects/ngx-stack/src/lib/router/stack-history.ts","../../../projects/ngx-stack/src/lib/router/stack-nav.ts","../../../projects/ngx-stack/src/lib/provide.ts","../../../projects/ngx-stack/src/lib/gesture/velocity-tracker.ts","../../../projects/ngx-stack/src/lib/gesture/swipe-back-gesture.ts","../../../projects/ngx-stack/src/lib/gesture/swipe-service.ts","../../../projects/ngx-stack/src/lib/animation/rise.ts","../../../projects/ngx-stack/src/lib/animation/android-transition.ts","../../../projects/ngx-stack/src/lib/animation/transition.ts","../../../projects/ngx-stack/src/lib/animation/slide.ts","../../../projects/ngx-stack/src/lib/animation/ios-transition.ts","../../../projects/ngx-stack/src/lib/animation/web-transition.ts","../../../projects/ngx-stack/src/lib/animation/transition-player.ts","../../../projects/ngx-stack/src/lib/core/announcer.ts","../../../projects/ngx-stack/src/lib/core/stack-entry.ts","../../../projects/ngx-stack/src/lib/core/stack-controller.ts","../../../projects/ngx-stack/src/lib/core/styles.ts","../../../projects/ngx-stack/src/lib/core/stack-host.ts","../../../projects/ngx-stack/src/lib/platform/system-transition.ts","../../../projects/ngx-stack/src/lib/router/tab-url.ts","../../../projects/ngx-stack/src/lib/router/stack-outlet.ts","../../../projects/ngx-stack/src/lib/nav/ngx-stack.ts","../../../projects/ngx-stack/src/lib/router/stack-tabs.ts","../../../projects/ngx-stack/src/lib/animation/none-transition.ts","../../../projects/ngx-stack/src/public-api.ts","../../../projects/ngx-stack/src/ngx-stack.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport type { StackTransition } from './animation/transition';\nimport type { StackPlatformKind } from './platform/platform';\n\n/** A transition per platform. Anything you leave out keeps the built-in for that platform. */\nexport interface StackTransitionMap {\n ios?: StackTransition;\n android?: StackTransition;\n web?: StackTransition;\n}\n\n/**\n * What to do about the browser's *own* edge-swipe back gesture.\n *\n * Only relevant on iOS Safari and iOS standalone PWAs — WebKit runs its own interactive back\n * navigation at the screen edge, and on a Router-based stack (real history entries) it will win over\n * ours. Nothing web-side reliably disables it, so these options only *reduce the overlap*; the clean\n * answer is a native shell (Capacitor/Cordova), whose WKWebView has the gesture off. See the \"iOS\n * Safari caveat\" in the README.\n */\nexport type SystemGesturePolicy =\n /**\n * Start our gesture zone a few px inland so the two don't fight over the same pixels. The system\n * still owns the outermost `systemEdgeInset` px; when it fires we notice via `hasUAVisualTransition`\n * and skip our own animation rather than drawing a second one on top of WebKit's.\n */\n | 'inset'\n /**\n * `preventDefault()` the touchstart inside the edge zone. Helps in some embedded WebViews, but does\n * **not** stop mobile Safari's system navigation — `preventDefault` doesn't reach it. It also\n * suppresses the synthetic `click` for touches beginning there, so rarely worth it.\n */\n | 'suppress'\n /** Do nothing, and let both gestures coexist. */\n | 'ignore';\n\n/**\n * What to do when the page on top has a `canDeactivate` guard.\n *\n * The gesture animates the page away *before* the navigation runs, so a guard that later says\n * no leaves us with nothing to do but snap the page back — a visible, ugly bounce. Guards can\n * also be async, and a touch handler cannot wait for a promise.\n */\nexport type GuardPolicy =\n /**\n * **Default.** A route with a `canDeactivate` guard is not swipeable, unless its component\n * implements `ngxCanSwipeBack()` — which is synchronous, so the gesture can simply not start.\n * Your back button still runs the guard normally, and that's where a confirm dialog belongs.\n */\n | 'block'\n /**\n * Let the gesture run and take the bounce if the guard refuses. Pick this only when you know\n * your guards effectively always pass.\n */\n | 'allow';\n\nexport interface NgxStackConfig {\n /** Force a platform instead of detecting it. Handy for testing an iOS build on a laptop. */\n platform?: StackPlatformKind | 'auto';\n\n /**\n * Writing direction. `'auto'` reads the computed `direction` off the host element, so an\n * app that sets `<html dir=\"rtl\">` mirrors everything with no configuration: the transitions\n * come from the other side and the swipe lives on the right edge.\n */\n direction?: 'auto' | 'ltr' | 'rtl';\n\n /**\n * The page transition. Pass one function to use it everywhere, or a\n * {@link StackTransitionMap} to vary it by platform.\n */\n transitions?: StackTransition | StackTransitionMap;\n\n /**\n * Base duration in ms. Built-in transitions scale this to taste (Android and web run shorter\n * than iOS). A custom transition returns its own duration and can ignore it.\n */\n duration?: number;\n\n /**\n * The tabs, as URL path prefixes: `['home', 'search', 'profile']`.\n *\n * Set this and each one gets its own independent stack. Switching tabs unwinds nothing and\n * destroys nothing — the tab you left keeps its pages mounted, exactly where you were, and comes\n * back that way. Leave it unset and there's a single stack, which is the common case.\n *\n * It has to be declared, because nothing in a route config distinguishes \"these are siblings you\n * switch between, each keeping its own history\" from \"these are just different URLs\". `/settings`\n * is a tab and `/settings/sheet` is a page inside it; only you know that.\n *\n * It isn't repeated anywhere, though — {@link NgxStackTabs} exposes it as `tabs()`, so the same\n * declaration also renders your tab bar. And a route whose URL doesn't happen to start with its\n * tab's name can say where it belongs with `data: { tab: 'search' }`.\n */\n tabs?: string[];\n\n /**\n * Rebuild the pages that *should* have been underneath, when the app opens partway in — a push\n * notification, a shared link, a refresh three screens deep.\n *\n * Without this the router lands you on the detail page with a stack of exactly one: nothing for a\n * swipe to drag into view. (The back *button* is a separate matter and always works — declare\n * `data: { parent: '/inbox' }` on the route.)\n *\n * - `true` — work the ancestors out from the route config: `data: { parent }` where you've\n * declared one, otherwise the URL's own nesting (`/inbox/item/12/notes` → `/inbox/item/12` →\n * `/inbox`).\n * - a function — your own `(url) => parentUrl | null`, applied repeatedly to build a chain. For a\n * URL scheme whose nesting doesn't reflect the screens, or routes behind `loadChildren`, whose\n * children can't be inspected without loading them.\n *\n * Nothing else to set up: the first navigation is intercepted before anything is built, so the\n * deep page is still constructed exactly once — at the end, on top of its ancestors.\n *\n * The cost is real, though: the ancestors are built and **their resolvers run**, for pages the\n * user may never look at. If your list page does something expensive on load, leave this off and\n * let the first back be a tap.\n */\n deepLinks?: boolean | ((url: string) => string | null);\n\n /**\n * Cap on how many pages one stack keeps mounted. `0` (the default) means no cap.\n *\n * Pages are cheap but not free, and a stack you can descend forever — a chat, a wiki, a file\n * browser — will happily hold fifty live components. With a cap, pages that fall off the\n * bottom are destroyed. Going back past that horizon still works: the page is rebuilt from\n * its URL and still animates as a *back*, so nothing looks wrong. It just lost its state,\n * which is the trade you asked for.\n */\n maxDepth?: number;\n\n /**\n * Move focus into the page that just entered, and announce it to screen readers. Default\n * `true`. Without this, a screen-reader user gets no signal that the page changed and their\n * focus stays on a control that has now slid off the screen.\n */\n manageFocus?: boolean;\n\n /** See {@link GuardPolicy}. */\n guardPolicy?: GuardPolicy;\n\n /**\n * Interactive swipe-to-go-back. `'auto'` arms it on iOS only — Android's back gesture belongs\n * to the OS, and the default web transition is too subtle to scrub usefully.\n *\n * Only the starting value; {@link NgxStackSwipe} changes it at runtime.\n */\n swipeBack?: boolean | 'auto';\n\n /** Width of the edge zone, in px, in which a swipe can begin. Mirrored in RTL. */\n swipeEdgeWidth?: number;\n\n /** Progress in `[0, 1]` past which releasing the finger completes the pop. */\n swipeThreshold?: number;\n\n /** px/ms. A flick faster than this decides on its own, whatever the progress. */\n swipeVelocityThreshold?: number;\n\n /** See {@link SystemGesturePolicy}. */\n systemGesture?: SystemGesturePolicy;\n\n /** With `systemGesture: 'inset'`, how many px at the very edge to concede to the browser. */\n systemEdgeInset?: number;\n\n /** Also allow dragging with a mouse. For developing the gesture in a desktop browser. */\n swipeWithMouse?: boolean;\n\n /** Animate the very first page pushed onto an empty stack. */\n animateRoot?: boolean;\n\n /**\n * Honour `prefers-reduced-motion: reduce` by making transitions instant. Default `true`.\n *\n * The swipe-back keeps its animation regardless, on purpose: motion the user is dragging with\n * their own finger is direct manipulation, which the guidance exempts — and a swipe with no\n * visual response isn't reduced motion, it's a broken gesture.\n */\n respectReducedMotion?: boolean;\n}\n\nexport type ResolvedStackConfig = Required<Omit<NgxStackConfig, 'transitions' | 'tabs'>> &\n Pick<NgxStackConfig, 'transitions' | 'tabs'>;\n\nexport const NGX_STACK_DEFAULTS: ResolvedStackConfig = {\n platform: 'auto',\n direction: 'auto',\n duration: 420,\n deepLinks: false,\n maxDepth: 0,\n manageFocus: true,\n guardPolicy: 'block',\n swipeBack: 'auto',\n swipeEdgeWidth: 50,\n swipeThreshold: 0.5,\n swipeVelocityThreshold: 0.35,\n systemGesture: 'inset',\n systemEdgeInset: 16,\n swipeWithMouse: false,\n animateRoot: false,\n respectReducedMotion: true,\n};\n\nexport const NGX_STACK_CONFIG = new InjectionToken<ResolvedStackConfig>('ngx-stack.config', {\n providedIn: 'root',\n factory: () => NGX_STACK_DEFAULTS,\n});\n","import { InjectionToken, inject } from '@angular/core';\nimport { DOCUMENT } from '@angular/core';\n\n/** The three surfaces that get their own transition. */\nexport type StackPlatformKind = 'ios' | 'android' | 'web';\n\nexport interface StackPlatform {\n /** Which transition this device gets by default. Decided by OS, not by browser vs native. */\n readonly kind: StackPlatformKind;\n readonly isIos: boolean;\n readonly isAndroid: boolean;\n /** Running inside a Capacitor native webview. */\n readonly isCapacitor: boolean;\n /** Running inside a Cordova / PhoneGap native webview. */\n readonly isCordova: boolean;\n /** Either of the above: a native webview shell rather than a real browser. */\n readonly isNative: boolean;\n /** Installed to the home screen and running without browser chrome. */\n readonly isStandalonePwa: boolean;\n /**\n * True when the browser runs its own interactive back gesture at the screen edge, so we have to\n * share (or fight over) those pixels.\n *\n * That means iOS Safari and iOS PWAs. Native shells — Capacitor and Cordova alike — leave\n * `allowsBackForwardNavigationGestures` off in their WKWebView, so the edge is ours alone. Which\n * is why native is the easy target and the browser is the awkward one.\n */\n readonly hasSystemBackGesture: boolean;\n}\n\nexport function detectPlatform(win: Window & typeof globalThis): StackPlatform {\n const nav = win.navigator;\n const ua = nav?.userAgent ?? '';\n\n // iPadOS 13+ reports itself as a Mac, so a Mac with a touchscreen is really an iPad.\n const isIos =\n /iPad|iPhone|iPod/.test(ua) || (/Macintosh/.test(ua) && (nav?.maxTouchPoints ?? 0) > 1);\n const isAndroid = /Android/.test(ua);\n\n const shell = win as unknown as {\n Capacitor?: { isNativePlatform?: () => boolean };\n cordova?: unknown;\n };\n\n const isCapacitor = !!shell.Capacitor?.isNativePlatform?.();\n const isCordova = !isCapacitor && shell.cordova !== undefined;\n const isNative = isCapacitor || isCordova;\n\n const isStandalonePwa =\n (nav as unknown as { standalone?: boolean })?.standalone === true ||\n win.matchMedia?.('(display-mode: standalone)').matches === true;\n\n return {\n kind: isIos ? 'ios' : isAndroid ? 'android' : 'web',\n isIos,\n isAndroid,\n isCapacitor,\n isCordova,\n isNative,\n isStandalonePwa,\n // Note this keys off `isNative`, not `isCapacitor`. Getting that wrong would make an iOS\n // Cordova app needlessly concede the first 16px of the screen edge to a gesture its webview\n // does not have.\n hasSystemBackGesture: isIos && !isNative,\n };\n}\n\nexport const NGX_STACK_PLATFORM = new InjectionToken<StackPlatform>('ngx-stack.platform', {\n providedIn: 'root',\n factory: () => {\n const doc = inject(DOCUMENT);\n const win = doc.defaultView;\n if (!win) {\n // SSR / no DOM: nothing animates anyway, so report the dullest possible platform.\n return {\n kind: 'web',\n isIos: false,\n isAndroid: false,\n isCapacitor: false,\n isCordova: false,\n isNative: false,\n isStandalonePwa: false,\n hasSystemBackGesture: false,\n };\n }\n return detectPlatform(win as Window & typeof globalThis);\n },\n});\n","import type { Route, Routes } from '@angular/router';\n\n/** Split a URL into path segments, dropping the query and fragment. */\nfunction segmentsOf(url: string): string[] {\n return url.split(/[?#]/, 1)[0].split('/').filter(Boolean);\n}\n\n/**\n * Find the route a set of URL segments would land on.\n *\n * A deliberately small re-implementation of route matching, because Angular's recogniser is not\n * public and we need an answer *before* any navigation has happened. It understands static\n * segments, `:params`, and children — which is what a URL hierarchy is made of.\n *\n * What it does not understand is `loadChildren`: the child routes are behind a dynamic import and\n * simply don't exist yet. Rather than guess, it declines to match into a lazy subtree, so pages in\n * one won't have a parent derived for them. Say so explicitly with `data: { parent }`.\n */\nexport function findRoute(routes: Routes | undefined, segments: string[]): Route | null {\n if (!routes) return null;\n\n for (const route of routes) {\n // A redirect isn't a page, and `**` matches everything — it would happily claim to be the\n // parent of anything, which is worse than having no parent at all.\n if (route.redirectTo !== undefined || route.path === '**') continue;\n\n const path = (route.path ?? '').split('/').filter(Boolean);\n if (segments.length < path.length) continue;\n\n const consumed = path.every((part, i) => part.startsWith(':') || part === segments[i]);\n if (!consumed) continue;\n\n const rest = segments.slice(path.length);\n\n if (rest.length === 0) {\n if (route.component || route.loadComponent) return route;\n // A componentless wrapper: the page is its empty-path child.\n const child = findRoute(route.children, []);\n if (child) return child;\n continue;\n }\n\n const child = findRoute(route.children, rest);\n if (child) return child;\n }\n\n return null;\n}\n\n/**\n * Where a page sits, when it's the first thing the app opened.\n *\n * Two sources, in order:\n *\n * 1. **`data: { parent: '/inbox' }`** on the route. The same declaration the back button uses, so\n * you write it once and it drives both. Necessary whenever the URL doesn't tell the truth about\n * the hierarchy — flat routes like `/item/42`, or a detail page reachable from two places.\n *\n * 2. **The URL's own nesting.** `/inbox/item/12/notes` → `/inbox/item/12` → `/inbox`: drop\n * segments until what's left is a real page. Costs nothing to set up and is right most of the\n * time, because most apps already nest their URLs the way their screens nest.\n */\nexport function deriveParentUrl(routes: Routes, url: string): string | null {\n const segments = segmentsOf(url);\n if (segments.length === 0) return null;\n\n const declared = findRoute(routes, segments)?.data?.['parent'];\n if (typeof declared === 'string') return declared;\n\n for (let length = segments.length - 1; length > 0; length--) {\n const candidate = segments.slice(0, length);\n const route = findRoute(routes, candidate);\n\n if (route?.component || route?.loadComponent) {\n return `/${candidate.join('/')}`;\n }\n }\n\n return null;\n}\n","import { Injectable } from '@angular/core';\nimport type {\n ActivatedRouteSnapshot,\n DetachedRouteHandle,\n RouteReuseStrategy,\n} from '@angular/router';\n\n/**\n * Turns off Angular's own route store/detach machinery, because the stack does that job\n * instead — and better, for this purpose: Angular's version stores a detached view and\n * gives it back on request, while the stack keeps every page mounted and on screen, which\n * is what lets a swipe reveal the page underneath before any navigation has happened.\n *\n * The one thing we do care about is `shouldReuseRoute`. Angular's default reuses a route\n * whose config matches, so `/item/1 → /item/2` would recycle the same component instance.\n * On a stack those are two different pages, and going back from one to the other has to\n * work, so a change of params means a new page.\n */\n@Injectable()\nexport class NgxStackRouteReuseStrategy implements RouteReuseStrategy {\n shouldDetach(): boolean {\n return false;\n }\n\n shouldAttach(): boolean {\n return false;\n }\n\n store(): void {\n // no-op\n }\n\n retrieve(): DetachedRouteHandle | null {\n return null;\n }\n\n shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {\n if (future.routeConfig !== curr.routeConfig) return false;\n\n const futureParams = future.params;\n const currParams = curr.params;\n const futureKeys = Object.keys(futureParams);\n if (futureKeys.length !== Object.keys(currParams).length) return false;\n\n return futureKeys.every((key) => futureParams[key] === currParams[key]);\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NavigationEnd, NavigationStart, Router } from '@angular/router';\n\n/**\n * A shadow copy of where we are in the browser's history.\n *\n * The browser will not tell you what `history.back()` would land on, and with tabs we have to\n * know. History is one linear thread; tabs are several independent stacks. Drill into Inbox,\n * switch to Search, drill in there — now the entry behind you is an *Inbox* page, and going\n * \"back\" in Search must not take you to it. So we keep our own list and cursor, and whoever is\n * popping can ask whether plain `history.back()` happens to do the right thing.\n */\n@Injectable({ providedIn: 'root' })\nexport class NgxStackHistory {\n private readonly router = inject(Router);\n\n private entries: string[] = [];\n private cursor = -1;\n\n private trigger: 'imperative' | 'popstate' | 'hashchange' = 'imperative';\n private replacing = false;\n\n constructor() {\n this.router.events.pipe(takeUntilDestroyed()).subscribe((event) => {\n if (event instanceof NavigationStart) {\n this.trigger = event.navigationTrigger ?? 'imperative';\n this.replacing = this.router.getCurrentNavigation()?.extras.replaceUrl === true;\n return;\n }\n if (event instanceof NavigationEnd) {\n this.record(event.urlAfterRedirects);\n }\n });\n }\n\n /** Where `history.back()` would actually land, or `null` if there's nothing behind us. */\n previousUrl(): string | null {\n return this.cursor > 0 ? this.entries[this.cursor - 1] : null;\n }\n\n private record(url: string): void {\n if (this.trigger === 'popstate') {\n // The browser moved the cursor. Work out which way by looking either side of it.\n if (this.cursor > 0 && this.entries[this.cursor - 1] === url) {\n this.cursor--;\n return;\n }\n if (this.cursor + 1 < this.entries.length && this.entries[this.cursor + 1] === url) {\n this.cursor++;\n return;\n }\n // A jump of more than one step, or into history from before the app loaded. We can't map\n // it, so drop what we think we know rather than answer confidently and wrongly.\n this.entries = [url];\n this.cursor = 0;\n return;\n }\n\n if (this.replacing && this.cursor >= 0) {\n this.entries[this.cursor] = url;\n return;\n }\n\n // A fresh navigation discards anything ahead of the cursor, exactly as the browser does.\n this.entries = this.entries.slice(0, this.cursor + 1);\n this.entries.push(url);\n this.cursor = this.entries.length - 1;\n }\n}\n","import { Location } from '@angular/common';\nimport { Injectable, inject } from '@angular/core';\nimport { Router, type NavigationExtras } from '@angular/router';\n\nimport { NgxStackHistory } from './stack-history';\n\n/** Key we tuck the intent under in `NavigationExtras.state`. */\nexport const NGX_STACK_DIRECTION = '__ngxStackDirection';\n\n/** Lets a caller force a transition to be instant, e.g. while rebuilding a stack at startup. */\nexport const NGX_STACK_ANIMATED = '__ngxStackAnimated';\n\nexport type StackNavHint = 'forward' | 'back' | 'root';\n\n/** Where a \"back\" would actually go. */\nexport interface BackTarget {\n url: string;\n /**\n * Whether that URL is a page we already have mounted beneath the current one. When it isn't —\n * a cold deep link, where there is nothing underneath — going back has to build it.\n */\n mounted: boolean;\n}\n\n/** Implemented by the outlet, so `back()` knows what is actually beneath the current page. */\nexport interface StackBackTarget {\n backTarget(): BackTarget | null;\n}\n\n/**\n * Navigation with an explicit stack intent.\n *\n * You don't have to use this for pushing — plain `router.navigate()` works, and the outlet infers\n * the direction by checking whether the target URL is already on the stack. It's for the cases\n * where that inference is wrong, and for going back, which is subtler than it looks.\n */\n@Injectable({ providedIn: 'root' })\nexport class NgxStackNav {\n private readonly router = inject(Router);\n private readonly location = inject(Location);\n private readonly history = inject(NgxStackHistory);\n\n private target: StackBackTarget | null = null;\n\n /** @internal Called by `NgxStackOutlet`. */\n registerStack(target: StackBackTarget): void {\n this.target = target;\n }\n\n /** @internal */\n unregisterStack(target: StackBackTarget): void {\n if (this.target === target) this.target = null;\n }\n\n /**\n * Is there anywhere to go back to *within the app*?\n *\n * Ask this, not the shell. Capacitor and Cordova both report whether the *webview* can go back,\n * which is a statement about history — and history is a single linear thread while tabs are\n * several stacks, so it says yes when the only thing behind you is a different tab.\n */\n canGoBack(): boolean {\n return (this.target?.backTarget() ?? null) !== null;\n }\n\n /** Push a page on top, even if its URL is already somewhere on the stack. */\n forward(commands: unknown[] | string, extras?: NavigationExtras): Promise<boolean> {\n return this.navigate(commands, extras, 'forward');\n }\n\n /**\n * Go back one page. This is what the swipe gesture commits to, and what a back button should\n * call. There are three quite different situations behind that one word, and this picks between\n * them:\n *\n * 1. **There's a page below, and it's also the previous history entry.** The easy case. Use a\n * real `history.back()`, so the URL, the browser's back button and the stack all keep telling\n * the same story.\n *\n * 2. **There's a page below, but history disagrees.** This is what tabs do to you: history is a\n * single linear thread, tabs are several stacks, and switching tabs leaves an unrelated page\n * sitting behind you. `history.back()` would jump sideways out of the stack you're in, so\n * navigate to the page we actually mean instead, replacing the current entry so that popping\n * doesn't inflate history.\n *\n * 3. **There's nothing below at all.** A cold deep link — a push notification, a shared URL, a\n * refresh three screens in. `history.back()` here walks out of the app entirely, which is\n * almost never what the user meant by tapping a back arrow inside it. If the route declares\n * where it sits (`data: { parent: '/inbox' }`) we build that page and animate to it as a back,\n * exactly as though it had been there all along.\n */\n back(commands?: unknown[] | string, extras?: NavigationExtras): Promise<boolean> {\n if (commands !== undefined) {\n return this.navigate(commands, extras, 'back');\n }\n\n const target = this.target?.backTarget() ?? null;\n\n if (!target) {\n // Genuinely nowhere to go: no page below, no declared parent. Defer to the browser, which\n // may well leave the app — the honest outcome of there being nothing to go back to.\n this.location.back();\n return Promise.resolve(true);\n }\n\n if (target.mounted && this.history.previousUrl() === target.url) {\n this.location.back();\n return Promise.resolve(true);\n }\n\n return this.navigate(target.url, { ...extras, replaceUrl: true }, 'back');\n }\n\n /** Throw every stack away and start again from this page. */\n root(commands: unknown[] | string, extras?: NavigationExtras): Promise<boolean> {\n return this.navigate(commands, { ...extras, replaceUrl: true }, 'root');\n }\n\n private navigate(\n commands: unknown[] | string,\n extras: NavigationExtras | undefined,\n hint: StackNavHint,\n ): Promise<boolean> {\n const merged: NavigationExtras = {\n ...extras,\n state: { ...(extras?.state ?? {}), [NGX_STACK_DIRECTION]: hint },\n };\n return Array.isArray(commands)\n ? this.router.navigate(commands, merged)\n : this.router.navigateByUrl(commands, merged);\n }\n}\n\n/**\n * Read the intent off the navigation currently in flight.\n *\n * Only honoured for imperative navigations. A `popstate` carries the history entry's *stored*\n * state, which still holds whatever hint was set when that entry was first pushed — so trusting\n * it would make pressing Back re-read an old `'forward'` and push a duplicate page. For history\n * traversal the outlet works the direction out from the stack instead, which is unambiguous.\n */\nexport function readDirectionHint(router: Router): StackNavHint | null {\n const navigation = router.getCurrentNavigation();\n if (!navigation || navigation.trigger !== 'imperative') return null;\n\n const state = navigation.extras.state as Record<string, unknown> | undefined;\n const hint = state?.[NGX_STACK_DIRECTION];\n return hint === 'forward' || hint === 'back' || hint === 'root' ? hint : null;\n}\n\n/** `false` when the caller wants this navigation to land with no transition at all. */\nexport function readAnimatedHint(router: Router): boolean | null {\n const navigation = router.getCurrentNavigation();\n if (!navigation || navigation.trigger !== 'imperative') return null;\n\n const state = navigation.extras.state as Record<string, unknown> | undefined;\n const animated = state?.[NGX_STACK_ANIMATED];\n return typeof animated === 'boolean' ? animated : null;\n}\n","import {\n DestroyRef,\n DOCUMENT,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n inject,\n type EnvironmentProviders,\n} from '@angular/core';\nimport { NavigationStart, RouteReuseStrategy, Router } from '@angular/router';\n\nimport { NGX_STACK_CONFIG, NGX_STACK_DEFAULTS, type NgxStackConfig } from './config';\nimport { NGX_STACK_PLATFORM } from './platform/platform';\nimport { deriveParentUrl } from './router/parent-url';\nimport { NgxStackRouteReuseStrategy } from './router/route-reuse-strategy';\nimport { NgxStackNav, NGX_STACK_ANIMATED, NGX_STACK_DIRECTION } from './router/stack-nav';\n\n/**\n * Wire up the stack. One call, everything in it.\n *\n * ```ts\n * bootstrapApplication(App, {\n * providers: [\n * provideRouter(routes),\n * provideNgxStack({\n * transitions: { ios: iosTransition, android: androidTransition, web: noneTransition },\n * tabs: ['inbox', 'search'],\n * deepLinks: true, // needs withDisabledInitialNavigation() — see below\n * }),\n * ],\n * });\n * ```\n *\n * Installs {@link NgxStackRouteReuseStrategy}, which is required — Angular's default strategy\n * recycles a component when only the route params change, which would quietly merge `/item/1` and\n * `/item/2` into one page instead of two.\n */\nexport function provideNgxStack(config: NgxStackConfig = {}): EnvironmentProviders {\n const resolved = { ...NGX_STACK_DEFAULTS, ...config };\n\n return makeEnvironmentProviders([\n { provide: NGX_STACK_CONFIG, useValue: resolved },\n { provide: RouteReuseStrategy, useClass: NgxStackRouteReuseStrategy },\n\n ...(resolved.deepLinks ? [rebuildDeepLinks(resolved.deepLinks)] : []),\n ]);\n}\n\n/** Guards against a `parentOf` that never terminates. Ten screens is already an absurd stack. */\nconst MAX_ANCESTORS = 10;\n\n/**\n * Build the pages that *should* have been underneath, when the app opens partway in.\n *\n * A push notification, a shared link, a refresh three screens deep: the router lands you on the\n * detail page and the stack has exactly one entry. Nothing is beneath it, so there is nothing for a\n * swipe to drag into view.\n *\n * The gesture needs the page below to be mounted and painted *before* the finger touches the\n * screen, and the only honest way to get it there is to have navigated to it. So that's what this\n * does: it rebuilds the ancestor chain at startup, silently, before the app is shown.\n */\nfunction rebuildDeepLinks(\n deepLinks: true | ((url: string) => string | null),\n): EnvironmentProviders {\n return provideEnvironmentInitializer(() => {\n const router = inject(Router);\n const destroyRef = inject(DestroyRef);\n\n const findParent =\n deepLinks === true ? (url: string) => deriveParentUrl(router.config, url) : deepLinks;\n\n let handled = false;\n\n // We intercept the very first navigation rather than letting it land and then correcting\n // ourselves, and the timing is the whole point: NavigationStart fires before anything is\n // recognised or activated, so nothing has been built yet. Asking the router for a different URL\n // here supersedes the one in flight — it is cancelled where it stands and never activates. The\n // deep page therefore gets constructed exactly once, at the end, on top of its ancestors.\n //\n // (Doing this after NavigationEnd would work too, and would build the deep page, throw it away,\n // and build it again — running its resolvers twice for the privilege.)\n const subscription = router.events.subscribe((event) => {\n if (handled || !(event instanceof NavigationStart)) return;\n handled = true;\n subscription.unsubscribe();\n\n const target = event.url;\n\n // Walk up from the target, collecting ancestors outermost-first.\n const chain: string[] = [];\n const seen = new Set<string>([target]);\n let current = target;\n\n while (chain.length < MAX_ANCESTORS) {\n const parent = findParent(current);\n if (!parent || seen.has(parent)) break;\n seen.add(parent);\n chain.unshift(parent);\n current = parent;\n }\n\n // Nothing above it — it *is* a root page. Let the navigation Angular already started proceed.\n if (chain.length === 0) return;\n\n void (async () => {\n // Root the stack at the outermost ancestor, replacing the history entry the browser already\n // has for the deep URL…\n await router.navigateByUrl(chain[0], {\n replaceUrl: true,\n state: { [NGX_STACK_DIRECTION]: 'root', [NGX_STACK_ANIMATED]: false },\n });\n\n // …then walk back down, pushing each page. The stack and the history end up exactly as they\n // would have been if the user had tapped their way here — which is the whole point.\n for (const url of [...chain.slice(1), target]) {\n await router.navigateByUrl(url, {\n state: { [NGX_STACK_DIRECTION]: 'forward', [NGX_STACK_ANIMATED]: false },\n });\n }\n })();\n });\n\n destroyRef.onDestroy(() => subscription.unsubscribe());\n });\n}\n\n/** The slice of `@capacitor/app` we need. Structural, so there is no dependency on Capacitor. */\nexport interface CapacitorAppLike {\n addListener(\n eventName: 'backButton',\n listenerFunc: (event: { canGoBack: boolean }) => void,\n ): Promise<unknown>;\n exitApp(): Promise<void>;\n}\n\n/**\n * Route the Android hardware back button (and the Android system back gesture, which Capacitor\n * reports through the same event) into the stack.\n *\n * Pass the plugin in rather than having the library import it, so `@capacitor/app` stays out of the\n * dependency graph of anyone shipping only to the web:\n *\n * ```ts\n * import { App } from '@capacitor/app';\n * provideCapacitorBack(App)\n * ```\n *\n * At the root of the stack this calls `exitApp()`, which is what Android users expect — back on the\n * first screen closes the app rather than doing nothing.\n *\n * The event's own `canGoBack` is deliberately ignored. It describes the *webview's* history, and\n * history is a single linear thread while tabs are several stacks — so it says yes when the only\n * thing behind you is a different tab. We ask the stack instead.\n */\nexport function provideCapacitorBack(app: CapacitorAppLike): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideEnvironmentInitializer(() => {\n const platform = inject(NGX_STACK_PLATFORM);\n if (!platform.isCapacitor) return;\n\n const nav = inject(NgxStackNav);\n void app.addListener('backButton', () => {\n if (nav.canGoBack()) {\n void nav.back();\n } else {\n void app.exitApp();\n }\n });\n }),\n ]);\n}\n\n/**\n * The same, for Cordova / PhoneGap.\n *\n * Cordova is a WKWebView (iOS) or WebView (Android) with plugins bolted on, so everything else in\n * this library already works there unchanged — the swipe, the transitions, the stacks, the tabs.\n * The one thing that isn't web is the Android hardware back button, which Cordova delivers as a\n * `backbutton` event on `document` once `deviceready` has fired.\n *\n * ```ts\n * provideCordovaBack()\n * ```\n *\n * Nothing to pass in: unlike Capacitor, Cordova's API is a global. At the root of the stack this\n * calls `navigator.app.exitApp()`.\n */\nexport function provideCordovaBack(): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideEnvironmentInitializer(() => {\n const platform = inject(NGX_STACK_PLATFORM);\n if (!platform.isCordova) return;\n\n const nav = inject(NgxStackNav);\n const doc = inject(DOCUMENT);\n const destroyRef = inject(DestroyRef);\n\n const onBackButton = (event: Event): void => {\n event.preventDefault();\n\n if (nav.canGoBack()) {\n void nav.back();\n return;\n }\n\n const exitApp = (\n doc.defaultView?.navigator as unknown as { app?: { exitApp?: () => void } }\n )?.app?.exitApp;\n exitApp?.();\n };\n\n // Cordova only starts firing `backbutton` after `deviceready`, so subscribing this early is\n // safe — the event simply cannot arrive before then.\n doc.addEventListener('backbutton', onBackButton);\n\n // An app is normally torn down by the OS, not by us — but a test harness, or a micro-frontend\n // that destroys and recreates the Angular app, would otherwise leave this listener holding a\n // reference to a dead injector and stealing the back button from whatever replaced it.\n destroyRef.onDestroy(() => doc.removeEventListener('backbutton', onBackButton));\n }),\n ]);\n}\n","interface Sample {\n t: number;\n x: number;\n}\n\n/** How far back to look. Older samples describe a gesture the finger has already left. */\nconst WINDOW_MS = 100;\n\n/** Horizontal speed of a drag, in px/ms. Positive means moving right. */\nexport class VelocityTracker {\n private samples: Sample[] = [];\n\n reset(x: number, t: number): void {\n this.samples = [{ x, t }];\n }\n\n add(x: number, t: number): void {\n this.samples.push({ x, t });\n const cutoff = t - WINDOW_MS;\n while (this.samples.length > 2 && this.samples[0].t < cutoff) {\n this.samples.shift();\n }\n }\n\n velocity(): number {\n if (this.samples.length < 2) return 0;\n const first = this.samples[0];\n const last = this.samples[this.samples.length - 1];\n const dt = last.t - first.t;\n if (dt <= 0) return 0;\n return (last.x - first.x) / dt;\n }\n}\n","import type { ResolvedStackConfig } from '../config';\nimport type { InteractiveBack } from '../core/stack-controller';\nimport type { StackPlatform } from '../platform/platform';\nimport { VelocityTracker } from './velocity-tracker';\n\n/** Travel along the axis, in px, before we commit to a swipe rather than a scroll or a tap. */\nconst DIRECTION_LOCK_PX = 10;\n\nconst MIN_SETTLE_MS = 90;\nconst MAX_SETTLE_MS = 380;\n\n/** Below this speed the flick is treated as a release, not a throw. */\nconst IDLE_SPEED = 0.05;\n\nexport interface SwipeBackHost {\n readonly hostEl: HTMLElement;\n /**\n * May a swipe start right now? Asked on every touch that lands in the edge zone, so it is free\n * to depend on live state. The single gate: whether the gesture is enabled at all, whether\n * there is anything to go back to, and whether the current page objects.\n */\n canSwipeBack(): boolean;\n /** Right-to-left, so the gesture lives on the right edge and pulls the other way. */\n isRtl(): boolean;\n /** Build the scrubbable back transition, or return null to refuse. */\n beginSwipeBack(): InteractiveBack | null;\n /** The user let go past the threshold. Finish the animation over `ms`, then pop for real. */\n commitSwipeBack(back: InteractiveBack, ms: number): void;\n /** The user let go short of the threshold. Put everything back over `ms`. */\n abortSwipeBack(back: InteractiveBack, ms: number): void;\n}\n\ntype GestureState = 'idle' | 'pending' | 'dragging';\n\n/**\n * Edge-drag-to-go-back.\n *\n * Uses touch events rather than pointer events on purpose. On iOS a `touchmove` can be\n * `preventDefault()`-ed to stop the page scrolling out from under the drag, and a `touchstart`\n * can be prevented to stop WebKit starting its own back-navigation gesture. Pointer events give\n * us neither — once WebKit decides the touch is a scroll or a system gesture, we just get a\n * `pointercancel` and the drag dies.\n *\n * Everything horizontal is expressed against a `sign`: +1 in LTR, -1 in RTL. The gesture starts\n * at the *inline start* edge and pulls towards the *inline end*, which in Arabic and Hebrew means\n * starting at the right and dragging left.\n */\nexport class SwipeBackGesture {\n private state: GestureState = 'idle';\n private startX = 0;\n private startY = 0;\n private width = 1;\n private sign: 1 | -1 = 1;\n private touchId: number | null = null;\n private back: InteractiveBack | null = null;\n\n private readonly velocity = new VelocityTracker();\n private readonly teardown: (() => void)[] = [];\n\n constructor(\n private readonly host: SwipeBackHost,\n private readonly config: ResolvedStackConfig,\n private readonly platform: StackPlatform,\n ) {\n const el = host.hostEl;\n\n // Non-passive: both handlers need to be able to preventDefault.\n this.listen(el, 'touchstart', this.onTouchStart as EventListener, { passive: false });\n this.listen(el, 'touchmove', this.onTouchMove as EventListener, { passive: false });\n this.listen(el, 'touchend', this.onTouchEnd as EventListener);\n this.listen(el, 'touchcancel', this.onTouchEnd as EventListener);\n\n if (config.swipeWithMouse) {\n this.listen(el, 'mousedown', this.onMouseDown as EventListener);\n this.listen(el.ownerDocument, 'mousemove', this.onMouseMove as EventListener);\n this.listen(el.ownerDocument, 'mouseup', this.onMouseUp as EventListener);\n }\n }\n\n private listen(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: AddEventListenerOptions,\n ): void {\n target.addEventListener(type, handler, options);\n this.teardown.push(() => target.removeEventListener(type, handler, options));\n }\n\n // ---------------------------------------------------------------------------\n // Touch\n // ---------------------------------------------------------------------------\n\n private readonly onTouchStart = (event: TouchEvent): void => {\n if (this.state !== 'idle' || event.touches.length !== 1) return;\n\n const touch = event.touches[0];\n if (!this.arm(touch.clientX, touch.clientY)) return;\n\n this.touchId = touch.identifier;\n\n // Stacks nest: an <ngx-stack> inside a page of an <ngx-stack-outlet> sits inside the outer\n // stack's host element, so this touch is on its way there too. Claim it, or both stacks\n // would go back at once. Listeners fire innermost-first, and arming already required\n // something to go back to — so the innermost stack that *can* go back wins, and one sitting\n // at its own root declines and lets the swipe fall through to its parent.\n event.stopPropagation();\n\n if (this.suppressesSystemGesture() && event.cancelable) {\n // Stops WebKit from starting its own interactive back navigation on this touch. The cost\n // is that this touch will not produce a synthetic `click`, which is why the default policy\n // is `inset` rather than `suppress`.\n event.preventDefault();\n }\n };\n\n private readonly onTouchMove = (event: TouchEvent): void => {\n if (this.state === 'idle') return;\n const touch = this.trackedTouch(event);\n if (!touch) return;\n this.drag(touch.clientX, touch.clientY, event);\n };\n\n private readonly onTouchEnd = (): void => {\n this.release();\n };\n\n /** A second finger landing must not hijack a drag the first one started. */\n private trackedTouch(event: TouchEvent): Touch | null {\n return Array.from(event.touches).find((touch) => touch.identifier === this.touchId) ?? null;\n }\n\n // ---------------------------------------------------------------------------\n // Mouse (development convenience only — `swipeWithMouse`)\n // ---------------------------------------------------------------------------\n\n private readonly onMouseDown = (event: MouseEvent): void => {\n if (this.state !== 'idle' || event.button !== 0) return;\n // See onTouchStart: the innermost stack that can go back claims the drag.\n if (this.arm(event.clientX, event.clientY)) event.stopPropagation();\n };\n\n private readonly onMouseMove = (event: MouseEvent): void => {\n if (this.state === 'idle') return;\n this.drag(event.clientX, event.clientY, event);\n };\n\n private readonly onMouseUp = (): void => {\n this.release();\n };\n\n // ---------------------------------------------------------------------------\n\n private arm(x: number, y: number): boolean {\n this.sign = this.host.isRtl() ? -1 : 1;\n\n if (!this.inEdgeZone(x)) return false;\n if (!this.host.canSwipeBack()) return false;\n\n this.state = 'pending';\n this.startX = x;\n this.startY = y;\n this.width = Math.max(this.host.hostEl.clientWidth, 1);\n this.velocity.reset(x, performance.now());\n return true;\n }\n\n private drag(x: number, y: number, event: Event): void {\n // Travel *away from* the starting edge, so this is positive whichever way the app reads.\n const travel = (x - this.startX) * this.sign;\n\n if (this.state === 'pending') {\n const dy = y - this.startY;\n\n // A vertical drag is a scroll, and scrolling wins outright — bail rather than fight it.\n if (Math.abs(dy) > DIRECTION_LOCK_PX && Math.abs(dy) >= Math.abs(travel)) {\n this.reset();\n return;\n }\n if (travel < DIRECTION_LOCK_PX) return;\n\n const back = this.host.beginSwipeBack();\n if (!back) {\n this.reset();\n return;\n }\n this.back = back;\n this.state = 'dragging';\n }\n\n if (!this.back) return;\n\n // Keep the page underneath from scrolling while the finger is dragging it sideways.\n if (event.cancelable) event.preventDefault();\n\n this.velocity.add(x, performance.now());\n this.back.player.seek(travel / this.width);\n }\n\n private release(): void {\n const back = this.back;\n const wasDragging = this.state === 'dragging';\n const sign = this.sign;\n this.reset();\n\n if (!wasDragging || !back) return;\n\n const progress = back.player.progress;\n // Positive means \"still moving away from the starting edge\", i.e. towards completing.\n const velocity = this.velocity.velocity() * sign;\n const threshold = this.config.swipeVelocityThreshold;\n\n // A fast flick decides on its own: outwards completes even from barely anywhere, back\n // towards the edge cancels even from past the halfway mark. Otherwise distance decides.\n const complete =\n velocity > threshold || (velocity > -threshold && progress > this.config.swipeThreshold);\n\n const remaining = complete ? 1 - progress : progress;\n const ms = this.settleDuration(remaining, Math.abs(velocity));\n\n if (complete) {\n this.host.commitSwipeBack(back, ms);\n } else {\n this.host.abortSwipeBack(back, ms);\n }\n }\n\n /** Carry the finger's speed into the settle, so the page doesn't change pace on release. */\n private settleDuration(remainingProgress: number, speed: number): number {\n const distance = remainingProgress * this.width;\n const ms = speed > IDLE_SPEED ? distance / speed : this.config.duration * remainingProgress;\n return Math.min(Math.max(ms, MIN_SETTLE_MS), MAX_SETTLE_MS);\n }\n\n private reset(): void {\n this.state = 'idle';\n this.back = null;\n this.touchId = null;\n }\n\n /** The zone hugs the *inline start* edge: the left in LTR, the right in RTL. */\n private inEdgeZone(x: number): boolean {\n const rect = this.host.hostEl.getBoundingClientRect();\n const fromEdge = this.sign === 1 ? x - rect.left : rect.right - x;\n const start = this.systemInset();\n\n return fromEdge >= start && fromEdge <= start + this.config.swipeEdgeWidth;\n }\n\n /** Pixels at the very edge we concede to the browser's own gesture. */\n private systemInset(): number {\n return this.platform.hasSystemBackGesture && this.config.systemGesture === 'inset'\n ? this.config.systemEdgeInset\n : 0;\n }\n\n private suppressesSystemGesture(): boolean {\n return this.platform.hasSystemBackGesture && this.config.systemGesture === 'suppress';\n }\n\n destroy(): void {\n if (this.back) {\n this.host.abortSwipeBack(this.back, 0);\n }\n this.reset();\n for (const off of this.teardown) off();\n this.teardown.length = 0;\n }\n}\n","import { Injectable, inject, signal, type Signal } from '@angular/core';\n\nimport { NGX_STACK_CONFIG } from '../config';\nimport { NGX_STACK_PLATFORM } from '../platform/platform';\n\n/**\n * The master switch for swipe-to-go-back.\n *\n * `provideNgxStack({ swipeBack })` only sets the *starting* value — this is what you reach\n * for when the answer changes while the app is running. A modal is open, a map is eating the\n * drag, a form has unsaved edits, a payment is in flight: turn it off, turn it back on after.\n *\n * ```ts\n * const swipe = inject(NgxStackSwipe);\n * swipe.disable();\n * // …later\n * swipe.reset(); // back to whatever the config said\n * ```\n *\n * This is the global layer. Two narrower ones sit on top of it, and either can veto:\n * `<ngx-stack-outlet [swipeBack]=\"…\">` for one stack, and `ngxCanSwipeBack()` or\n * `data: { swipeBack: false }` for one page. See {@link NgxStackPage}.\n */\n@Injectable({ providedIn: 'root' })\nexport class NgxStackSwipe {\n private readonly config = inject(NGX_STACK_CONFIG);\n private readonly platform = inject(NGX_STACK_PLATFORM);\n\n private readonly _enabled = signal(this.fromConfig());\n\n /** Read it in a template or a computed; it's a signal. */\n readonly enabled: Signal<boolean> = this._enabled.asReadonly();\n\n enable(): void {\n this._enabled.set(true);\n }\n\n disable(): void {\n this._enabled.set(false);\n }\n\n set(enabled: boolean): void {\n this._enabled.set(enabled);\n }\n\n /** Go back to what the config asked for, whatever that resolved to on this device. */\n reset(): void {\n this._enabled.set(this.fromConfig());\n }\n\n private fromConfig(): boolean {\n const setting = this.config.swipeBack;\n if (setting !== 'auto') return setting;\n\n // 'auto' means iOS only. Honour a forced `platform`, so an iOS build under test on a\n // laptop still arms the gesture.\n const kind = this.config.platform === 'auto' ? this.platform.kind : this.config.platform;\n return kind === 'ios';\n }\n}\n","import type { ElementAnimation, StackTransition, TransitionSpec } from './transition';\n\nexport interface RiseOptions {\n /** How far the incoming page rises through, in px. Material moves a short distance, quickly. */\n travel: number;\n\n easing: string;\n\n /** Multiplier on the configured duration. */\n durationScale: number;\n}\n\n/**\n * The Material shape: the incoming page rises a short distance and fades in over the outgoing one,\n * which stays exactly where it is and is simply covered.\n *\n * The counterpart to {@link slideTransition}. `androidTransition` and `webTransition` are both\n * instances of this, with the same numbers — but they remain two separate transitions you can point\n * at different things, because \"what Android does\" and \"what a browser does\" are two decisions that\n * merely happen to agree today.\n *\n * Note there is no horizontal component, and that has a consequence: an edge swipe would drag\n * sideways while the page moved vertically. That is why `swipeBack: 'auto'` only arms the gesture on\n * iOS. For a swipe on Android or the web, give that platform a {@link slideTransition} instead.\n */\nexport function riseTransition(options: RiseOptions): StackTransition {\n return (ctx): TransitionSpec => {\n const forward = ctx.direction === 'forward';\n\n // The page riding on top. Going back, that's the one leaving.\n const overEl = forward ? ctx.enteringEl : ctx.leavingEl;\n\n const animations: ElementAnimation[] = [];\n\n if (overEl) {\n const away: Keyframe = { transform: `translateY(${options.travel}px)`, opacity: '0' };\n const home: Keyframe = { transform: 'translateY(0)', opacity: '1' };\n\n animations.push({ el: overEl, keyframes: forward ? [away, home] : [home, away] });\n }\n\n return {\n duration: Math.round(ctx.duration * options.durationScale),\n easing: options.easing,\n animations,\n };\n };\n}\n","import { riseTransition } from './rise';\n\n/**\n * The Material push: the incoming page rises and fades in over the outgoing one, which stays where\n * it is. Shorter and flatter than iOS — Material moves things a short distance quickly rather than a\n * long distance smoothly.\n *\n * Deliberately has no horizontal component, which is why `swipeBack: 'auto'` doesn't arm the gesture\n * here: a finger dragging sideways would scrub a page moving vertically. On Android the back gesture\n * belongs to the OS anyway. If you do want an edge swipe, give this platform a `slideTransition()`.\n */\nexport const androidTransition = riseTransition({\n travel: 12,\n easing: 'cubic-bezier(0.05, 0.7, 0.1, 1)',\n durationScale: 0.65,\n});\n","/** Which way the stack is moving. */\nexport type StackDirection = 'forward' | 'back';\n\nexport interface TransitionContext {\n /**\n * The page that will be on top of the stack once the transition finishes. On `forward` this is\n * the newly created page; on `back` it is the page being uncovered.\n */\n enteringEl: HTMLElement;\n\n /**\n * The page that was on top when the transition started, or `null` when the stack was empty\n * (the root page).\n */\n leavingEl: HTMLElement | null;\n\n /** The element both pages live in. */\n hostEl: HTMLElement;\n\n direction: StackDirection;\n\n /**\n * The app is running right-to-left. Everything horizontal mirrors: \"forward\" arrives from the\n * left rather than the right, and the swipe-back lives on the right edge. A transition that\n * ignores this will feel backwards in Arabic and Hebrew — the new page will appear to come\n * from where the user just came *from*.\n */\n rtl: boolean;\n\n /** Host width in px, for transitions that want absolute distances. */\n width: number;\n\n /** Requested duration in ms, from the config. */\n duration: number;\n}\n\nexport interface ElementAnimation {\n el: HTMLElement;\n /**\n * The first keyframe is the state at progress 0, the last at progress 1. A swipe-back gesture\n * seeks between them, so keyframes must be continuous and reversible — avoid discrete steps or\n * properties that can't be interpolated.\n */\n keyframes: Keyframe[];\n /** Overrides the spec-level easing for this element. */\n easing?: string;\n}\n\nexport interface TransitionSpec {\n duration: number;\n easing: string;\n animations: ElementAnimation[];\n}\n\n/**\n * Describes how two pages swap places. Called once per transition, and also at the start of a\n * swipe-back — in that case the resulting animation is seeked by the finger rather than played,\n * so it must be a pure function of progress.\n */\nexport type StackTransition = (ctx: TransitionContext) => TransitionSpec;\n\n/** The dim overlay that sits on top of a page while it is covered by another. */\nexport function scrimOf(pageEl: HTMLElement): HTMLElement | null {\n return pageEl.querySelector<HTMLElement>(':scope > .ngx-stack-scrim');\n}\n","import {\n scrimOf,\n type ElementAnimation,\n type StackTransition,\n type TransitionSpec,\n} from './transition';\n\nexport interface SlideOptions {\n /** How far the page riding on top travels, as a % of the host's width. */\n travel: number;\n\n /** How far the page underneath drifts the other way. Less than `travel` is what makes a parallax. */\n parallax: number;\n\n /** Peak opacity of the dim overlay on the covered page. `0` to skip it. */\n scrim: number;\n\n /** Fade the travelling page as well as moving it. iOS doesn't; a shorter web slide needs to. */\n fade: boolean;\n\n easing: string;\n\n /** Multiplier on the configured duration. */\n durationScale: number;\n}\n\n/**\n * The shape both horizontal transitions share: one page rides in over another, which drifts the\n * other way more slowly and dims underneath it.\n *\n * iOS and web are the same animation with different numbers — a full-width slide with a heavy\n * parallax, versus a short drift carried mostly by opacity. Writing that twice invites them to\n * quietly diverge, and the interesting parts here are subtle enough already:\n *\n * - `forward` and `back` are the same keyframes with the roles swapped. That symmetry is what makes\n * a swipe scrubbable at all — the gesture just seeks the `back` spec.\n * - everything horizontal is signed by `rtl`, so a page pushed \"forward\" in Arabic arrives from the\n * left, which is the direction the language reads towards.\n */\nexport function slideTransition(options: SlideOptions): StackTransition {\n return (ctx): TransitionSpec => {\n const forward = ctx.direction === 'forward';\n const sign = ctx.rtl ? -1 : 1;\n\n const offMain = `translateX(${options.travel * sign}%)`;\n const offUnder = `translateX(${-options.parallax * sign}%)`;\n const center = 'translateX(0)';\n\n // The page riding on top, sliding in from (or out to) the edge.\n const overEl = forward ? ctx.enteringEl : ctx.leavingEl;\n // The page underneath, parallaxing and dimming.\n const underEl = forward ? ctx.leavingEl : ctx.enteringEl;\n\n const animations: ElementAnimation[] = [];\n\n if (overEl) {\n const away: Keyframe = { transform: offMain, ...(options.fade ? { opacity: '0' } : {}) };\n const home: Keyframe = { transform: center, ...(options.fade ? { opacity: '1' } : {}) };\n animations.push({ el: overEl, keyframes: forward ? [away, home] : [home, away] });\n }\n\n if (underEl) {\n animations.push({\n el: underEl,\n keyframes: forward\n ? [{ transform: center }, { transform: offUnder }]\n : [{ transform: offUnder }, { transform: center }],\n });\n\n const scrim = options.scrim > 0 ? scrimOf(underEl) : null;\n if (scrim) {\n const clear: Keyframe = { opacity: '0' };\n const dim: Keyframe = { opacity: `${options.scrim}` };\n animations.push({ el: scrim, keyframes: forward ? [clear, dim] : [dim, clear] });\n }\n }\n\n return {\n duration: Math.round(ctx.duration * options.durationScale),\n easing: options.easing,\n animations,\n };\n };\n}\n","import { slideTransition } from './slide';\n\n/**\n * The iOS navigation-controller push/pop.\n *\n * The incoming page slides the full width of the screen over the outgoing one, which drifts the\n * other way at a third of the speed and dims underneath it — the parallax that makes a UIKit stack\n * feel like sheets of paper rather than slides.\n *\n * The easing is UIKit's own: almost no acceleration, and a very long tail.\n */\nexport const iosTransition = slideTransition({\n travel: 100,\n parallax: 33,\n scrim: 0.16,\n fade: false,\n easing: 'cubic-bezier(0.32, 0.72, 0, 1)',\n durationScale: 1,\n});\n","import { riseTransition } from './rise';\n\n/**\n * The browser default — the same rise-and-fade as Android, and identical to `androidTransition` down\n * to the numbers.\n *\n * They are still two transitions rather than one, and that is the point: \"what a phone does\" and\n * \"what a browser does\" are two separate decisions that merely happen to agree today. Retuning the\n * web here changes nothing on Android, and vice versa. If they were the same object, the first person\n * to want a different feel on the desktop would have to change both.\n *\n * Why Material rather than the iOS slide: a full-width slide says *\"this screen came from over\n * there\"*, which is true of something you swiped into view and not of something you clicked — and on\n * a wide monitor it is a great many pixels moving for no reason.\n */\nexport const webTransition = riseTransition({\n travel: 12,\n easing: 'cubic-bezier(0.05, 0.7, 0.1, 1)',\n durationScale: 0.65,\n});\n","import type { TransitionSpec } from './transition';\n\nconst clamp01 = (n: number): number => (n < 0 ? 0 : n > 1 ? 1 : n);\n\n/** Keyframe keys that carry timing rather than style. */\nconst META_KEYS = new Set(['offset', 'easing', 'composite']);\n\nfunction styleKeysOf(keyframes: Keyframe[]): string[] {\n const keys = new Set<string>();\n for (const frame of keyframes) {\n for (const key of Object.keys(frame)) {\n if (!META_KEYS.has(key)) keys.add(key);\n }\n }\n return [...keys];\n}\n\n/** The element's current rendered value for each animated property. */\nfunction snapshotOf(el: HTMLElement, keys: string[]): Keyframe {\n const frame: Record<string, string> = {};\n\n // A page destroyed mid-swipe — a navigation cancelled under the finger — has no defaultView. An\n // assertion here would throw inside a touch handler, taking the gesture down with it, when the\n // honest answer is simply that there is nothing left to animate from.\n const view = el.ownerDocument.defaultView;\n if (!view) return frame as Keyframe;\n\n const computed = view.getComputedStyle(el);\n for (const key of keys) {\n frame[key] = (computed as unknown as Record<string, string>)[key];\n }\n return frame as Keyframe;\n}\n\nfunction styleOnly(frame: Keyframe): Keyframe {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(frame)) {\n if (!META_KEYS.has(key)) out[key] = value;\n }\n return out as Keyframe;\n}\n\n/**\n * A page transition that can be either played or scrubbed.\n *\n * This is the whole reason the library exists. A CSS transition or a View Transition is\n * fire-and-forget: it runs to completion on its own clock. A swipe-back is the opposite —\n * the finger owns the clock, the transition has to follow it, and the user may change\n * their mind halfway and drag right back.\n *\n * So a transition is built as a set of paused Web Animations with `fill: 'both'`. Paused at\n * `currentTime = 0` they hold their first keyframe; the gesture then writes `currentTime`\n * directly on every touch move.\n */\nexport class TransitionPlayer {\n private animations: Animation[];\n private duration: number;\n private disposed = false;\n\n /**\n * @param interactive Build for scrubbing. Timing easing is forced to linear so that\n * seeking to progress `p` puts the page at exactly `p` of the way across — otherwise\n * the iOS curve makes the page lead and then lag the finger, which is precisely the\n * tell that separates a native-feeling swipe from a web one. The real curve is applied\n * later, by `settle()`.\n */\n constructor(\n private readonly spec: TransitionSpec,\n interactive = false,\n ) {\n this.duration = Math.max(spec.duration, 1);\n const easing = interactive ? 'linear' : spec.easing;\n\n this.animations = spec.animations.map((animation) => {\n const handle = animation.el.animate(animation.keyframes, {\n duration: this.duration,\n easing: interactive ? 'linear' : (animation.easing ?? easing),\n fill: 'both',\n });\n handle.pause();\n handle.currentTime = 0;\n return handle;\n });\n }\n\n /** Where the transition currently sits, in `[0, 1]`. */\n get progress(): number {\n const first = this.animations[0];\n if (!first) return 0;\n return clamp01(Number(first.currentTime ?? 0) / this.duration);\n }\n\n /** Jump to a progress in `[0, 1]`. Called on every touch move during a swipe. */\n seek(progress: number): void {\n if (this.disposed) return;\n const time = clamp01(progress) * this.duration;\n for (const animation of this.animations) {\n animation.currentTime = time;\n }\n }\n\n /** Run to progress 1 on the transition's own clock. */\n play(): Promise<void> {\n return this.run(1);\n }\n\n /**\n * Hand the clock back to the browser after a scrub, carrying on to `target`.\n *\n * Deliberately *not* a continuation of the scrub timeline. Re-applying the easing curve\n * to a timeline that is already part-way through would snap the page to `easing(t)`, a\n * visible jump at the exact moment the user lets go. Instead we snapshot what is\n * currently on screen and animate from there to the target with the real curve, which is\n * continuous by construction.\n *\n * @param ms How long the remaining distance should take. Scale this by the distance left\n * so a release near the end is quick and one near the start is not.\n */\n settle(target: 0 | 1, ms: number, easing = this.spec.easing): Promise<void> {\n if (this.disposed || this.animations.length === 0) return Promise.resolve();\n\n const from = this.spec.animations.map((animation) => ({\n el: animation.el,\n frame: snapshotOf(animation.el, styleKeysOf(animation.keyframes)),\n }));\n const to = this.spec.animations.map((animation) =>\n styleOnly(\n target === 1 ? animation.keyframes[animation.keyframes.length - 1] : animation.keyframes[0],\n ),\n );\n\n for (const animation of this.animations) {\n animation.cancel();\n }\n\n this.duration = Math.max(ms, 1);\n this.animations = from.map((source, index) =>\n source.el.animate([source.frame, to[index]], {\n duration: this.duration,\n easing,\n fill: 'both',\n }),\n );\n\n return this.settled();\n }\n\n private run(direction: 1): Promise<void> {\n if (this.disposed || this.animations.length === 0) return Promise.resolve();\n\n // `Animation.play()` auto-rewinds: playing forward from the very end snaps back to the\n // start. Short-circuit when there is no distance left to cover.\n if (this.progress >= 0.999) {\n this.seek(1);\n return Promise.resolve();\n }\n\n for (const animation of this.animations) {\n animation.playbackRate = direction;\n animation.play();\n }\n return this.settled();\n }\n\n private settled(): Promise<void> {\n return Promise.all(\n // `finished` rejects when an animation is cancelled mid-flight, which is what happens\n // whenever a newer navigation interrupts this one. Not an error for us.\n this.animations.map((animation) => animation.finished.catch(() => undefined)),\n ).then(() => undefined);\n }\n\n /** Snap to the end state with no animation. */\n finish(): void {\n this.seek(1);\n }\n\n /** Drop the animations, reverting the elements to the styles they had before. */\n destroy(): void {\n if (this.disposed) return;\n for (const animation of this.animations) {\n animation.cancel();\n }\n this.disposed = true;\n }\n}\n","const ANNOUNCER_ID = 'ngx-stack-announcer';\n\n/**\n * Say a page's name out loud, once, to whoever is listening with a screen reader.\n *\n * A stack navigation is invisible to assistive tech: no document load, no focus change it can\n * infer meaning from — the DOM just quietly rearranges. A polite live region is the standard way\n * to give that back, and it's the same thing Angular's own `RouterOutlet` does not do for you.\n */\nexport function announce(doc: Document, message: string): void {\n let region = doc.getElementById(ANNOUNCER_ID);\n\n if (!region) {\n region = doc.createElement('div');\n region.id = ANNOUNCER_ID;\n region.setAttribute('aria-live', 'polite');\n region.setAttribute('aria-atomic', 'true');\n region.className = 'ngx-stack-announcer';\n doc.body.appendChild(region);\n }\n\n // Re-announcing the same string is a no-op for most screen readers, because the region's\n // content didn't change. Clearing first forces it to speak.\n region.textContent = '';\n region.textContent = message;\n}\n","import type { ComponentRef } from '@angular/core';\nimport type { ActivatedRoute, OutletContext } from '@angular/router';\n\n/** One page living on the stack. */\nexport interface StackEntry {\n readonly id: number;\n\n /**\n * Serialized URL that owns this page, used to recognise it again on a later navigation.\n * Empty for imperative stacks, which have no URL of their own.\n */\n url: string;\n\n /**\n * Which tab's stack this page belongs to, or `''` when the app has no tabs. Pages of\n * inactive tabs stay mounted — that is the entire point of tabs having their own stacks.\n */\n readonly tab: string;\n\n /** The wrapper we transform. Not the component's own host element — that lives inside. */\n readonly element: HTMLElement;\n\n /** The dim overlay shown while this page is covered. */\n readonly scrim: HTMLElement;\n\n readonly ref: ComponentRef<unknown>;\n\n route: ActivatedRoute | null;\n\n /**\n * Child outlet contexts captured when this page was navigated away from, so that any nested\n * `<router-outlet>` inside it comes back alive rather than empty when we return.\n */\n savedContexts?: Map<string, OutletContext>;\n}\n\n/**\n * Lifecycle callbacks for a page on the stack.\n *\n * Stacked pages are *not* destroyed when you navigate away from them — that's the point, it's\n * what preserves their state and lets the swipe reveal them instantly. Which also means\n * `ngOnDestroy` no longer means \"the user left this page\". These hooks do.\n */\nexport interface NgxStackPage {\n /** The page is about to become the top of the stack. Fires before the transition. */\n ngxViewWillEnter?(): void;\n /** The page is now the top of the stack and the transition has finished. */\n ngxViewDidEnter?(): void;\n /** The page is about to stop being the top of the stack. */\n ngxViewWillLeave?(): void;\n /** The page is no longer the top of the stack. It stays alive unless it was popped. */\n ngxViewDidLeave?(): void;\n\n /**\n * Veto the swipe-back gesture while this page is on top. Consulted on every touch, so it can\n * depend on live state — an open modal, a dirty form, an in-flight payment.\n *\n * A veto only. It cannot turn the gesture *on* where `NgxStackSwipe` or the outlet have\n * turned it off. For a page that is simply never swipeable, `data: { swipeBack: false }` on\n * the route says the same thing without any code.\n *\n * This is also how a route with a `canDeactivate` guard opts back into the gesture — see\n * `guardPolicy`.\n */\n ngxCanSwipeBack?(): boolean;\n}\n\ntype LifecycleHook = Exclude<keyof NgxStackPage, 'ngxCanSwipeBack'>;\n\nexport function callLifecycle(entry: StackEntry | null, hook: LifecycleHook): void {\n const instance = entry?.ref.instance as NgxStackPage | undefined;\n instance?.[hook]?.();\n}\n\n/**\n * Does the page on top object to being swiped away? Two ways to say so, both vetoes:\n * `data: { swipeBack: false }` on the route for a page that never allows it, and\n * `ngxCanSwipeBack()` on the component for one that decides in the moment.\n *\n * @param guardPolicy When `'block'`, a route carrying a `canDeactivate` guard refuses the\n * gesture unless its component implements `ngxCanSwipeBack()`. The guard would otherwise run\n * only *after* the page had already animated away, and refusing at that point can do nothing\n * but bounce it back.\n */\nexport function pageAllowsSwipeBack(\n entry: StackEntry | null,\n guardPolicy: 'block' | 'allow' = 'allow',\n): boolean {\n if (!entry) return false;\n\n const snapshot = entry.route?.snapshot;\n if (snapshot?.data['swipeBack'] === false) return false;\n\n const page = entry.ref.instance as NgxStackPage | undefined;\n const answer = page?.ngxCanSwipeBack?.();\n\n if (answer !== undefined) return answer;\n\n if (guardPolicy === 'block' && (snapshot?.routeConfig?.canDeactivate?.length ?? 0) > 0) {\n return false;\n }\n\n return true;\n}\n","import { computed, signal, type ComponentRef, type Signal } from '@angular/core';\nimport type { ActivatedRoute } from '@angular/router';\n\nimport { androidTransition } from '../animation/android-transition';\nimport { iosTransition } from '../animation/ios-transition';\nimport { webTransition } from '../animation/web-transition';\nimport type { StackDirection, StackTransition } from '../animation/transition';\nimport { TransitionPlayer } from '../animation/transition-player';\nimport type { ResolvedStackConfig } from '../config';\nimport type { StackPlatform, StackPlatformKind } from '../platform/platform';\nimport { announce } from './announcer';\nimport { callLifecycle, type StackEntry } from './stack-entry';\n\nconst BUILT_IN: Record<StackPlatformKind, StackTransition> = {\n ios: iosTransition,\n android: androidTransition,\n // Its own transition, which today happens to be identical to Android's — see web-transition.ts for\n // why they stay two things.\n web: webTransition,\n};\n\n/** A swipe-back in progress: the pages involved, and the transition the finger is scrubbing. */\nexport interface InteractiveBack {\n readonly player: TransitionPlayer;\n /** The page being uncovered — the one that will be on top if the swipe completes. */\n readonly entering: StackEntry;\n /** The page being dragged off — the current top. */\n readonly leaving: StackEntry;\n}\n\n/** Emitted around every transition, including the ones a finger is driving. */\nexport interface StackTransitionEvent {\n direction: StackDirection;\n entering: StackEntry;\n leaving: StackEntry | null;\n /** The tab this happened in, or `''` in a single-stack app. */\n tab: string;\n /** False when the pages simply swapped, e.g. a tab switch or reduced motion. */\n animated: boolean;\n /** True when a swipe-back drove it rather than a navigation. */\n interactive: boolean;\n}\n\nexport type StackOp =\n /** Mount `entering` on top of `tab`'s stack. */\n | { kind: 'push'; tab: string; entering: StackEntry; animated: boolean }\n /**\n * Swap the top page for `entering`. What `router.navigate(…, { replaceUrl: true })` means for a\n * stack: history didn't grow, so neither should the stack.\n */\n | { kind: 'replace'; tab: string; entering: StackEntry; animated: boolean }\n /** Unwind `tab`'s stack to `toIndex`, destroying everything above it. */\n | { kind: 'pop'; tab: string; toIndex: number; animated: boolean; player?: TransitionPlayer }\n /** Replace *every* stack with this one page. */\n | { kind: 'root'; tab: string; entering: StackEntry; animated: boolean }\n /**\n * Rebuild a page that fell off the bottom of a capped stack, and make it the new bottom.\n * Everything currently in that stack sat above it, so all of it goes.\n */\n | { kind: 'restore'; tab: string; entering: StackEntry; animated: boolean };\n\ninterface RunningTransition {\n player: TransitionPlayer | null;\n entering: StackEntry;\n leaving: StackEntry | null;\n /** Pages removed from the stack whose DOM must survive until the animation ends. */\n removed: StackEntry[];\n event: StackTransitionEvent;\n}\n\ntype Stacks = Record<string, readonly StackEntry[]>;\n\n/**\n * Owns the pages of a stack — their DOM, their order, and the transitions between them.\n *\n * Deliberately free of framework plumbing: it knows nothing about the Router or about\n * imperative pushes. Both `NgxStackOutlet` and `NgxStack` drive this same class, which is why\n * a swipe-back behaves identically whether the stack is fed by URLs or by `push()`.\n *\n * With `tabs` configured it holds one stack *per tab* and shows the active one. Tabs are not a\n * feature bolted on top — they're the reason the pages live in a map keyed by tab rather than a\n * flat array. Switching tabs mounts nothing and destroys nothing; it just changes which stack's\n * top page is on screen, so the tab you left is still exactly where you left it.\n */\nexport class StackController {\n private readonly stacks = signal<Stacks>({});\n private readonly active = signal('');\n\n /** URLs evicted by `maxDepth`, per tab. Remembered so we still know they're *behind* us. */\n private readonly pruned = new Map<string, Set<string>>();\n\n /** The active tab's pages, bottom first. */\n readonly pages: Signal<readonly StackEntry[]> = computed(\n () => this.stacks()[this.active()] ?? [],\n );\n readonly depth = computed(() => this.pages().length);\n readonly canGoBack = computed(() => this.pages().length > 1 || this.hasPrunedPages());\n readonly activeTab: Signal<string> = this.active.asReadonly();\n\n private readonly _animating = signal(false);\n readonly animating: Signal<boolean> = this._animating.asReadonly();\n\n /** Set by the host so it can re-emit these as component outputs. */\n onTransitionStart?: (event: StackTransitionEvent) => void;\n onTransitionEnd?: (event: StackTransitionEvent) => void;\n\n private nextId = 0;\n private running: RunningTransition | null = null;\n private readonly doc: Document;\n\n constructor(\n private readonly hostEl: HTMLElement,\n private readonly config: ResolvedStackConfig,\n private readonly platform: StackPlatform,\n ) {\n this.doc = hostEl.ownerDocument;\n }\n\n // ---------------------------------------------------------------------------\n // Reading the stack\n // ---------------------------------------------------------------------------\n\n stackOf(tab: string): readonly StackEntry[] {\n return this.stacks()[tab] ?? [];\n }\n\n top(tab = this.active()): StackEntry | null {\n const stack = this.stackOf(tab);\n return stack.length ? stack[stack.length - 1] : null;\n }\n\n at(index: number, tab = this.active()): StackEntry | null {\n return this.stackOf(tab)[index] ?? null;\n }\n\n findByUrl(url: string, tab = this.active()): number {\n return this.stackOf(tab).findIndex((entry) => entry.url === url);\n }\n\n /** Was this URL evicted by `maxDepth`? If so it's behind us, not ahead of us. */\n wasPruned(url: string, tab = this.active()): boolean {\n return this.pruned.get(tab)?.has(url) ?? false;\n }\n\n private hasPrunedPages(): boolean {\n return (this.pruned.get(this.active())?.size ?? 0) > 0;\n }\n\n // ---------------------------------------------------------------------------\n // Building pages\n // ---------------------------------------------------------------------------\n\n /** Wrap a freshly created component in a page element and put it in the host. */\n adopt(\n ref: ComponentRef<unknown>,\n url: string,\n route: ActivatedRoute | null,\n tab = '',\n ): StackEntry {\n const element = this.doc.createElement('div');\n // Starts invisible so it can't paint at its resting position for a frame before the\n // transition's first keyframe applies.\n element.className = 'ngx-stack-page ngx-stack-page--invisible';\n\n const scrim = this.doc.createElement('div');\n scrim.className = 'ngx-stack-scrim';\n\n // `createComponent` already put the host element in the DOM at the view container's anchor.\n // Relocating the node is fine — Angular tracks the view, not its position.\n element.appendChild(ref.location.nativeElement as HTMLElement);\n element.appendChild(scrim);\n this.hostEl.appendChild(element);\n\n return { id: this.nextId++, url, tab, element, scrim, ref, route };\n }\n\n // ---------------------------------------------------------------------------\n // Transitions\n // ---------------------------------------------------------------------------\n\n /**\n * Apply a stack operation. The stacks are updated *synchronously* so a navigation arriving\n * mid-animation still sees the correct top; only the visuals and the destruction of popped\n * pages wait for the transition.\n */\n run(op: StackOp): Promise<void> {\n // A new transition while one is still running: snap the old one to its end state rather\n // than letting two animations fight over the same transforms.\n if (this.running) this.settle(this.running);\n\n // The page currently on screen — which, on a tab switch, belongs to the tab we're leaving.\n const leaving = this.top(this.active());\n\n const stacks: Stacks = { ...this.stacks() };\n const before = stacks[op.tab] ?? [];\n\n let entering: StackEntry;\n let removed: StackEntry[] = [];\n let direction: StackDirection;\n\n switch (op.kind) {\n case 'push':\n entering = op.entering;\n direction = 'forward';\n stacks[op.tab] = this.prune(op.tab, [...before, entering], (dropped) =>\n removed.push(...dropped),\n );\n break;\n\n case 'replace':\n entering = op.entering;\n direction = 'forward';\n // Only the top goes; everything below it stays, so back still works the same way.\n removed = before.length ? [before[before.length - 1]] : [];\n stacks[op.tab] = [...before.slice(0, -1), entering];\n break;\n\n case 'pop': {\n const target = before[op.toIndex];\n if (!target) return Promise.resolve();\n entering = target;\n direction = 'back';\n removed = before.slice(op.toIndex + 1);\n stacks[op.tab] = before.slice(0, op.toIndex + 1);\n break;\n }\n\n case 'restore':\n entering = op.entering;\n direction = 'back';\n // Everything in this stack sat above the page we're restoring, so all of it goes.\n removed = [...before];\n stacks[op.tab] = [entering];\n this.pruned.get(op.tab)?.delete(entering.url);\n break;\n\n case 'root':\n entering = op.entering;\n direction = 'forward';\n // Root wipes every tab, not just this one — it's \"start the app again\".\n removed = Object.values(stacks).flat();\n for (const key of Object.keys(stacks)) delete stacks[key];\n stacks[op.tab] = [entering];\n this.pruned.clear();\n break;\n }\n\n this.stacks.set(stacks);\n this.active.set(op.tab);\n\n if (entering === leaving) {\n this.applyStates();\n return Promise.resolve();\n }\n\n return this.transition(entering, leaving, direction, removed, op, this.playerOf(op));\n }\n\n /** Enforce `maxDepth` by dropping pages off the bottom, remembering that they existed. */\n private prune(\n tab: string,\n stack: readonly StackEntry[],\n onDropped: (dropped: StackEntry[]) => void,\n ): readonly StackEntry[] {\n const max = this.config.maxDepth;\n if (max <= 0 || stack.length <= max) return stack;\n\n const dropped = stack.slice(0, stack.length - max);\n let urls = this.pruned.get(tab);\n if (!urls) {\n urls = new Set();\n this.pruned.set(tab, urls);\n }\n for (const entry of dropped) {\n if (entry.url) urls.add(entry.url);\n }\n onDropped(dropped);\n\n return stack.slice(dropped.length);\n }\n\n private playerOf(op: StackOp): TransitionPlayer | undefined {\n return op.kind === 'pop' ? op.player : undefined;\n }\n\n private async transition(\n entering: StackEntry,\n leaving: StackEntry | null,\n direction: StackDirection,\n removed: StackEntry[],\n op: StackOp,\n existingPlayer?: TransitionPlayer,\n ): Promise<void> {\n const isRoot = leaving === null;\n const shouldAnimate =\n op.animated && (!isRoot || this.config.animateRoot) && !this.prefersReducedMotion();\n\n this.reveal(entering);\n if (leaving) this.reveal(leaving);\n\n callLifecycle(leaving, 'ngxViewWillLeave');\n callLifecycle(entering, 'ngxViewWillEnter');\n\n // A gesture hands us a player it has already scrubbed to the end; otherwise build one.\n const player =\n existingPlayer ?? (shouldAnimate ? this.buildPlayer(entering, leaving, direction) : null);\n\n // Safe now: with `fill: 'both'` the player is already holding its first keyframe, so\n // un-hiding cannot show the page at the wrong position.\n entering.element.classList.remove('ngx-stack-page--invisible');\n\n const event: StackTransitionEvent = {\n direction,\n entering,\n leaving,\n tab: op.tab,\n animated: player !== null,\n interactive: existingPlayer !== undefined,\n };\n\n const run: RunningTransition = { player, entering, leaving, removed, event };\n this.running = run;\n this._animating.set(true);\n this.onTransitionStart?.(event);\n\n if (player) {\n entering.element.classList.add('ngx-stack-page--animating');\n leaving?.element.classList.add('ngx-stack-page--animating');\n await player.play();\n }\n\n // A newer navigation may have settled this transition while we were awaiting.\n if (this.running !== run) return;\n\n this.finish(run);\n }\n\n /** Tear down a transition: drop popped pages, fix up classes, fire the `did` hooks. */\n private finish(run: RunningTransition): void {\n this.applyStates();\n // Cancelling reverts elements to their CSS-defined transforms. Do it *after* `applyStates`\n // has hidden everything below the top, so nothing flashes back to centre.\n run.player?.destroy();\n\n for (const entry of run.removed) {\n this.destroyEntry(entry);\n }\n\n callLifecycle(run.leaving, 'ngxViewDidLeave');\n callLifecycle(run.entering, 'ngxViewDidEnter');\n\n this.running = null;\n this._animating.set(false);\n\n if (this.config.manageFocus) this.moveFocus(run.entering);\n this.onTransitionEnd?.(run.event);\n }\n\n /** Jump an in-flight transition straight to its end state. */\n private settle(run: RunningTransition): void {\n run.player?.finish();\n this.finish(run);\n }\n\n // ---------------------------------------------------------------------------\n // Swipe-back\n // ---------------------------------------------------------------------------\n\n /**\n * Set up a back transition and hand it to the gesture, paused at progress 0.\n *\n * Deliberately fires no lifecycle hooks: a swipe is a *peek* until the user releases, and\n * pages should not be told they entered somewhere the user may drag right back out of. The\n * hooks fire when the pop actually commits, through `run()`.\n */\n beginInteractiveBack(): InteractiveBack | null {\n if (this.running) return null;\n\n const stack = this.pages();\n if (stack.length < 2) return null;\n\n const leaving = stack[stack.length - 1];\n const entering = stack[stack.length - 2];\n\n this.reveal(entering);\n const player = this.buildPlayer(entering, leaving, 'back', true);\n entering.element.classList.remove('ngx-stack-page--invisible');\n entering.element.classList.add('ngx-stack-page--animating');\n leaving.element.classList.add('ngx-stack-page--animating');\n\n return { player, entering, leaving };\n }\n\n /** The user let go without going far enough: run the transition back to where it started. */\n async abortInteractiveBack(back: InteractiveBack, ms: number): Promise<void> {\n await back.player.settle(0, ms);\n this.applyStates();\n back.player.destroy();\n }\n\n private buildPlayer(\n entering: StackEntry,\n leaving: StackEntry | null,\n direction: StackDirection,\n interactive = false,\n ): TransitionPlayer {\n const spec = this.transitionFn()({\n enteringEl: entering.element,\n leavingEl: leaving?.element ?? null,\n hostEl: this.hostEl,\n direction,\n rtl: this.isRtl(),\n width: this.hostEl.clientWidth || 1,\n duration: this.config.duration,\n });\n return new TransitionPlayer(spec, interactive);\n }\n\n // ---------------------------------------------------------------------------\n // Resolution\n // ---------------------------------------------------------------------------\n\n /** Which platform's look we're using, honouring a `platform` override in the config. */\n platformKind(): StackPlatformKind {\n return this.config.platform === 'auto' ? this.platform.kind : this.config.platform;\n }\n\n /** One function for every platform, a per-platform override, or the built-in. */\n transitionFn(): StackTransition {\n const configured = this.config.transitions;\n if (typeof configured === 'function') return configured;\n\n const kind = this.platformKind();\n return configured?.[kind] ?? BUILT_IN[kind];\n }\n\n /**\n * Read from the DOM rather than cached, so an app that flips `dir` at runtime — which is what\n * a language switcher does — mirrors on the very next transition without a reload.\n */\n isRtl(): boolean {\n if (this.config.direction !== 'auto') return this.config.direction === 'rtl';\n const view = this.doc.defaultView;\n return view ? view.getComputedStyle(this.hostEl).direction === 'rtl' : false;\n }\n\n /**\n * Only gates the *automatic* transitions. A swipe-back still animates: the user is dragging it\n * themselves, and direct manipulation is exempt — a gesture that doesn't visibly follow the\n * finger isn't reduced motion, it's a broken gesture.\n */\n private prefersReducedMotion(): boolean {\n if (!this.config.respectReducedMotion) return false;\n return this.doc.defaultView?.matchMedia('(prefers-reduced-motion: reduce)').matches ?? false;\n }\n\n // ---------------------------------------------------------------------------\n // DOM state\n // ---------------------------------------------------------------------------\n\n private reveal(entry: StackEntry): void {\n entry.element.classList.remove('ngx-stack-page--hidden');\n }\n\n /**\n * The definitive resting state. Exactly one page is visible: the top of the active tab's\n * stack. Everything else — buried pages, and every page of every inactive tab — is hidden and\n * inert but still mounted.\n */\n private applyStates(): void {\n const stacks = this.stacks();\n const activeTab = this.active();\n\n for (const [tab, stack] of Object.entries(stacks)) {\n const lastIndex = stack.length - 1;\n\n stack.forEach((entry, index) => {\n const isTop = tab === activeTab && index === lastIndex;\n\n entry.element.classList.toggle('ngx-stack-page--hidden', !isTop);\n entry.element.classList.remove('ngx-stack-page--invisible', 'ngx-stack-page--animating');\n entry.element.inert = !isTop;\n\n if (isTop) {\n entry.element.style.transform = '';\n entry.scrim.style.opacity = '';\n }\n });\n }\n }\n\n /**\n * Put focus in the page that just arrived, and say its name out loud.\n *\n * Without this a screen-reader user gets no signal that anything happened, and keyboard focus\n * stays on whatever control they activated — which has now slid off the screen and been marked\n * `inert`, leaving focus nowhere at all.\n */\n private moveFocus(entry: StackEntry): void {\n const explicit = entry.element.querySelector<HTMLElement>('[ngxStackAutofocus]');\n const target = explicit ?? entry.element;\n\n if (!explicit) {\n // A page container isn't focusable by default; -1 makes it programmatically focusable\n // without adding it to the tab order.\n target.setAttribute('tabindex', '-1');\n }\n target.focus({ preventScroll: true });\n\n const title = entry.route?.snapshot.title ?? this.doc.title;\n if (title) announce(this.doc, title);\n }\n\n private destroyEntry(entry: StackEntry): void {\n entry.ref.destroy();\n entry.element.remove();\n }\n\n destroy(): void {\n if (this.running) {\n this.running.player?.destroy();\n this.running = null;\n }\n for (const stack of Object.values(this.stacks())) {\n for (const entry of stack) this.destroyEntry(entry);\n }\n this.stacks.set({});\n this.pruned.clear();\n }\n}\n","const STYLE_ID = 'ngx-stack-styles';\n\n/**\n * Page wrappers are created imperatively, outside any component template, so Angular's\n * style encapsulation can't reach them. These rules go in the document once instead.\n * Everything is driven by CSS custom properties so apps can restyle without `!important`.\n */\nconst CSS = `\n.ngx-stack-host {\n display: block;\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n\n /* Stop Chrome/Android turning a horizontal drag that is not an armed swipe into its own overscroll\n back-navigation, which would fire underneath the gesture and fight it. This is the one thing web\n content genuinely can do about a system gesture, and only on Android: iOS Safari's edge swipe is\n drawn by WebKit and no CSS or preventDefault suppresses it (that is what systemGesture is for,\n and why native shells are the easy target). Framework7 ships the same line for the same reason. */\n overscroll-behavior: none;\n /* Kills the 300ms double-tap-zoom delay without touching the pan/scroll the gesture relies on. */\n touch-action: manipulation;\n\n /* Notches, home indicators, and the Android navigation bar. Declared here so pages can just\n use var(--ngx-stack-safe-top) without every one of them repeating the env() dance — and so\n they still resolve to 0px on a browser that has never heard of a notch. */\n --ngx-stack-safe-top: env(safe-area-inset-top, 0px);\n --ngx-stack-safe-bottom: env(safe-area-inset-bottom, 0px);\n --ngx-stack-safe-left: env(safe-area-inset-left, 0px);\n --ngx-stack-safe-right: env(safe-area-inset-right, 0px);\n}\n\n/* Where page titles are announced to screen readers. Visually gone, but not display:none —\n which would take it out of the accessibility tree along with everything we're trying to say. */\n.ngx-stack-announcer {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n.ngx-stack-page {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n transform: translateX(0);\n background: var(--ngx-stack-page-background, #fff);\n /* Only ever visible while the page is translated, i.e. mid-transition. */\n box-shadow: var(--ngx-stack-page-shadow, -6px 0 20px rgb(0 0 0 / 12%));\n}\n\n/* The routed component fills the wrapper and scrolls; the scrim sits on top of it.\n Wrapped in :where() so this weighs nothing: a page component only has to say\n \":host { display: flex }\" to take the layout over, with no !important and no fight. */\n:where(.ngx-stack-page > :not(.ngx-stack-scrim)) {\n flex: 1 1 auto;\n min-height: 0;\n display: block;\n overflow: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n/* Set while a page is being created, so it can't flash at its final position for a frame\n before the transition's first keyframe lands. */\n.ngx-stack-page--invisible {\n opacity: 0;\n}\n\n.ngx-stack-page--animating {\n will-change: transform;\n}\n\n/* Buried pages — and, with tabs, every page of every inactive tab. content-visibility:hidden\n skips their rendering while preserving internal state (crucially, scroll offsets), so coming\n back to a page finds it exactly where you left it with no scroll-restoration bookkeeping on\n our side. They stay in the DOM: that is what makes a tab switch instant and a swipe possible. */\n.ngx-stack-page--hidden {\n visibility: hidden;\n pointer-events: none;\n content-visibility: hidden;\n}\n\n/* Focused programmatically after a transition; never show a ring for it. */\n.ngx-stack-page:focus {\n outline: none;\n}\n\n.ngx-stack-scrim {\n position: absolute;\n inset: 0;\n z-index: 10;\n opacity: 0;\n pointer-events: none;\n background: var(--ngx-stack-scrim-color, #000);\n}\n`;\n\n/** Idempotent: safe to call from every outlet on every init. */\nexport function ensureStackStyles(doc: Document): void {\n if (doc.getElementById(STYLE_ID)) return;\n const style = doc.createElement('style');\n style.id = STYLE_ID;\n style.textContent = CSS;\n doc.head.appendChild(style);\n}\n","import {\n ChangeDetectorRef,\n DOCUMENT,\n Directive,\n ElementRef,\n EnvironmentInjector,\n type Injector,\n ViewContainerRef,\n inject,\n output,\n type ComponentRef,\n type OnDestroy,\n type Signal,\n type Type,\n} from '@angular/core';\n\nimport { NGX_STACK_CONFIG, type GuardPolicy } from '../config';\nimport { SwipeBackGesture, type SwipeBackHost } from '../gesture/swipe-back-gesture';\nimport { NgxStackSwipe } from '../gesture/swipe-service';\nimport { NGX_STACK_PLATFORM } from '../platform/platform';\nimport {\n StackController,\n type InteractiveBack,\n type StackTransitionEvent,\n} from './stack-controller';\nimport { pageAllowsSwipeBack, type StackEntry } from './stack-entry';\nimport { ensureStackStyles } from './styles';\n\n/**\n * Everything the two kinds of stack have in common — which is almost everything.\n *\n * `NgxStackOutlet` is fed by the Router and `NgxStack` by `push()`, and that difference is real but\n * shallow: it only decides *where the next page comes from*. Once a page exists, holding it,\n * transitioning to it, dragging it around with a finger and tearing it down are identical jobs, and\n * a swipe-back must behave the same in both. Keeping that in one place is the only way it stays that\n * way.\n *\n * So a subclass supplies three things — how strict to be about guards, whether it overrides the\n * app-wide swipe switch, and what a committed swipe should actually *do* — and inherits the rest.\n */\n@Directive()\nexport abstract class StackHostBase implements SwipeBackHost, OnDestroy {\n /** Fires as a transition begins — including one a finger is about to scrub. */\n readonly transitionStart = output<StackTransitionEvent>();\n /** Fires once the pages have settled and any popped page has been destroyed. */\n readonly transitionEnd = output<StackTransitionEvent>();\n\n protected readonly config = inject(NGX_STACK_CONFIG);\n protected readonly platform = inject(NGX_STACK_PLATFORM);\n protected readonly swipe = inject(NgxStackSwipe);\n protected readonly viewContainer = inject(ViewContainerRef);\n protected readonly environmentInjector = inject(EnvironmentInjector);\n protected readonly changeDetector = inject(ChangeDetectorRef);\n\n readonly hostEl: HTMLElement = inject(ElementRef<HTMLElement>).nativeElement;\n\n protected readonly controller = new StackController(this.hostEl, this.config, this.platform);\n\n private gesture: SwipeBackGesture | null = null;\n\n /** The active stack's pages, bottom first. */\n readonly pages: Signal<readonly StackEntry[]> = this.controller.pages;\n readonly depth: Signal<number> = this.controller.depth;\n readonly animating: Signal<boolean> = this.controller.animating;\n\n constructor() {\n ensureStackStyles(inject(DOCUMENT));\n this.controller.onTransitionStart = (event) => this.transitionStart.emit(event);\n this.controller.onTransitionEnd = (event) => this.transitionEnd.emit(event);\n }\n\n /** Arm the gesture. Subclasses call this once they are ready to be swiped. */\n protected startGesture(): void {\n this.gesture = new SwipeBackGesture(this, this.config, this.platform);\n }\n\n // ---------------------------------------------------------------------------\n // Creating pages\n // ---------------------------------------------------------------------------\n\n /**\n * Instantiate a page component and hand it to the controller to be wrapped and mounted.\n *\n * The `markForCheck` matters and is easy to lose: both hosts are OnPush with an empty template of\n * their own, so nothing would ever dirty the view and the freshly inserted page would sit there\n * un-checked until something unrelated happened to trigger a pass.\n */\n protected createPage<T>(\n component: Type<T>,\n options: { injector: Injector; environmentInjector?: EnvironmentInjector },\n ): ComponentRef<T> {\n const ref = this.viewContainer.createComponent(component, {\n index: this.viewContainer.length,\n injector: options.injector,\n environmentInjector: options.environmentInjector ?? this.environmentInjector,\n });\n\n this.changeDetector.markForCheck();\n return ref;\n }\n\n // ---------------------------------------------------------------------------\n // SwipeBackHost\n // ---------------------------------------------------------------------------\n\n /**\n * Three layers, narrowest last, each able to veto: the app-wide switch, this stack, and the page\n * currently on top. Re-evaluated on every touch, so all three can change at runtime.\n */\n canSwipeBack(): boolean {\n // An explicit value on the stack overrides the app-wide one, in both directions.\n if (!(this.swipeBackOverride() ?? this.swipe.enabled())) return false;\n\n // Deliberately `depth()`, not `canGoBack()`: the latter counts pages evicted by `maxDepth` and\n // parents that were never built, which no longer exist and so cannot be dragged into view. A\n // button can still take you there; a finger can't drag what isn't on screen.\n if (this.controller.depth() < 2 || this.controller.animating()) return false;\n\n return pageAllowsSwipeBack(this.controller.top(), this.guardPolicy());\n }\n\n isRtl(): boolean {\n return this.controller.isRtl();\n }\n\n beginSwipeBack(): InteractiveBack | null {\n return this.controller.beginInteractiveBack();\n }\n\n abortSwipeBack(back: InteractiveBack, ms: number): void {\n void this.controller.abortInteractiveBack(back, ms);\n }\n\n /** The user let go past the threshold. The animation is done; make the pop real. */\n abstract commitSwipeBack(back: InteractiveBack, ms: number): void;\n\n /** `null` to defer to the app-wide {@link NgxStackSwipe}. */\n protected abstract swipeBackOverride(): boolean | null;\n\n /** Only routed pages can carry a `canDeactivate` guard, so only they need a policy for one. */\n protected abstract guardPolicy(): GuardPolicy;\n\n // ---------------------------------------------------------------------------\n\n ngOnDestroy(): void {\n this.gesture?.destroy();\n this.controller.destroy();\n }\n}\n","/**\n * Notices when the *browser* has already animated a navigation.\n *\n * On iOS Safari and iOS PWAs, an edge swipe triggers WebKit's own back navigation, and\n * WebKit draws its own page slide for it. We still get the resulting `popstate`, so without\n * this we would helpfully animate the same navigation a second time.\n *\n * The Navigation API's `hasUAVisualTransition` is exactly the flag for this. Where the API\n * isn't available we simply animate — a double animation is worse than no information, but\n * only slightly, and `systemGesture: 'suppress'` avoids the situation entirely.\n */\ninterface NavigateEventLike extends Event {\n readonly hasUAVisualTransition?: boolean;\n}\n\ninterface NavigationLike extends EventTarget {\n addEventListener(type: 'navigate', listener: (event: NavigateEventLike) => void): void;\n removeEventListener(type: 'navigate', listener: (event: NavigateEventLike) => void): void;\n}\n\nexport class SystemTransitionWatcher {\n private uaAnimated = false;\n private readonly detach: () => void;\n\n constructor(win: Window) {\n const navigation = (win as unknown as { navigation?: NavigationLike }).navigation;\n\n if (!navigation?.addEventListener) {\n this.detach = () => undefined;\n return;\n }\n\n const onNavigate = (event: NavigateEventLike): void => {\n this.uaAnimated = event.hasUAVisualTransition === true;\n };\n\n navigation.addEventListener('navigate', onNavigate);\n this.detach = () => navigation.removeEventListener('navigate', onNavigate);\n }\n\n /** Did the browser animate the navigation we are about to handle? Reads and clears. */\n consume(): boolean {\n const value = this.uaAnimated;\n this.uaAnimated = false;\n return value;\n }\n\n destroy(): void {\n this.detach();\n }\n}\n","import type { ActivatedRouteSnapshot } from '@angular/router';\n\n/**\n * Which tab a URL belongs to, or `''` when the app has no tabs — or when the URL belongs to none of\n * them, which is what a login screen or a full-screen modal route looks like. Those get their own\n * stack, outside the tab bar, which is almost always what you want.\n */\nexport function tabOfUrl(url: string, tabs: readonly string[] | undefined): string {\n if (!tabs?.length) return '';\n\n // Strip the leading slash, query and fragment, then take the first segment.\n const path = url.replace(/^\\/+/, '').split(/[?#]/, 1)[0];\n const first = path.split('/', 1)[0];\n\n return tabs.includes(first) ? first : '';\n}\n\n/**\n * `data: { tab: 'search' }` — for a page that belongs to a tab its URL doesn't name.\n *\n * Most apps nest their URLs by tab and never need this. But a flat route, or a tab whose pages live\n * under a different prefix, has no way to say where it belongs otherwise, and would silently land in\n * the no-tab stack: mounted, outside the tab bar, and stranded the moment you switch tabs.\n */\nexport function tabOfRouteData(\n data: Record<string, unknown> | undefined,\n tabs: readonly string[] | undefined,\n): string | null {\n const tab = data?.['tab'];\n if (typeof tab !== 'string') return null;\n\n if (tabs?.length && !tabs.includes(tab)) {\n throw new Error(\n `[ngx-stack] A route declares data: { tab: '${tab}' }, but '${tab}' is not one of the ` +\n `configured tabs [${tabs.join(', ')}]. Its pages would go to a stack no tab can reach.`,\n );\n }\n\n return tab;\n}\n\n/** Structural, so the helpers stay testable without a router. */\ninterface RouteSnapshotLike {\n routeConfig: { data?: Record<string, unknown> } | null;\n}\n\n/**\n * The tab a route belongs to, asking it and then every route it is nested inside.\n *\n * The point of walking the ancestors: with nested routes you declare the tab **once**, on the tab's\n * root, and every page under it inherits — rather than repeating `data: { tab }` on each one.\n *\n * Deliberately reads `routeConfig.data` rather than the snapshot's own `data`. The snapshot's\n * version already merges in inherited data, but only from ancestors Angular considers inheritable\n * (componentless ones, unless you change `paramsInheritanceStrategy`). Walking the configs ourselves\n * means a tab root works whether or not it happens to have a component.\n */\nexport function tabOfRouteTree(\n pathFromRoot: readonly RouteSnapshotLike[],\n tabs: readonly string[] | undefined,\n): string | null {\n // Innermost first, so a page can override the tab it is nested in.\n for (let i = pathFromRoot.length - 1; i >= 0; i--) {\n const tab = tabOfRouteData(pathFromRoot[i].routeConfig?.data, tabs);\n if (tab) return tab;\n }\n return null;\n}\n\n/**\n * Which stack a page belongs on: what the route tree says, and failing that, what its URL implies.\n *\n * The single place that answers this, so the outlet (which files the page) and `NgxStackTabs` (which\n * lights up the tab bar) can never disagree about where a page went.\n */\nexport function tabOfRoute(\n snapshot: ActivatedRouteSnapshot,\n url: string,\n tabs: readonly string[] | undefined,\n): string {\n return tabOfRouteTree(snapshot.pathFromRoot, tabs) ?? tabOfUrl(url, tabs);\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DOCUMENT,\n type EnvironmentInjector,\n EventEmitter,\n type Injector,\n ViewEncapsulation,\n computed,\n inject,\n input,\n type ComponentRef,\n type OnDestroy,\n type OnInit,\n type Signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport {\n ActivatedRoute,\n ChildrenOutletContexts,\n NavigationCancel,\n NavigationError,\n PRIMARY_OUTLET,\n Router,\n type Data,\n type RouterOutletContract,\n} from '@angular/router';\n\nimport type { GuardPolicy } from '../config';\nimport type { InteractiveBack } from '../core/stack-controller';\nimport type { StackEntry } from '../core/stack-entry';\nimport { StackHostBase } from '../core/stack-host';\nimport { SystemTransitionWatcher } from '../platform/system-transition';\nimport { deriveParentUrl } from './parent-url';\nimport {\n NgxStackNav,\n readAnimatedHint,\n readDirectionHint,\n type BackTarget,\n type StackBackTarget,\n} from './stack-nav';\nimport { tabOfRoute } from './tab-url';\n\n/** What Angular's own `OutletInjector` does: hand routed components their route and contexts. */\nclass StackOutletInjector implements Injector {\n constructor(\n private readonly route: ActivatedRoute,\n private readonly childContexts: ChildrenOutletContexts,\n private readonly parent: Injector,\n ) {}\n\n get(token: unknown, notFoundValue?: unknown, options?: unknown): unknown {\n if (token === ActivatedRoute) return this.route;\n if (token === ChildrenOutletContexts) return this.childContexts;\n return (this.parent as { get: (...args: unknown[]) => unknown }).get(\n token,\n notFoundValue,\n options,\n );\n }\n}\n\n/**\n * A `<router-outlet>` that keeps a stack instead of a single page.\n *\n * The stock outlet destroys the outgoing component the moment you navigate. That is the right\n * default and completely incompatible with a swipe-back: the page you are swiping back to has to\n * already be on screen, mounted and painted, *before* the navigation that reveals it happens —\n * otherwise there is nothing to drag into view.\n *\n * So pages here are mounted once and stay. Which one you are looking at is decided by where you are\n * in the history, and the direction of each transition is inferred by asking whether the incoming\n * URL is already on the stack (going back) or not (going forward).\n *\n * With `tabs` configured, one outlet holds one stack per tab and shows the active one.\n */\n@Component({\n selector: 'ngx-stack-outlet',\n template: '',\n host: { class: 'ngx-stack-host' },\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n exportAs: 'ngxStackOutlet',\n})\nexport class NgxStackOutlet\n extends StackHostBase\n implements OnInit, OnDestroy, RouterOutletContract, StackBackTarget\n{\n /** Matches `<router-outlet name>`, for named outlets. */\n readonly name = input(PRIMARY_OUTLET);\n\n /**\n * Swipe-back for this stack specifically. `null` (the default) defers to `NgxStackSwipe`, the\n * app-wide switch; `true` or `false` overrides it here.\n */\n readonly swipeBack = input<boolean | null>(null);\n\n private readonly parentContexts = inject(ChildrenOutletContexts);\n private readonly router = inject(Router);\n private readonly nav = inject(NgxStackNav);\n private readonly document = inject(DOCUMENT);\n\n private systemTransition: SystemTransitionWatcher | null = null;\n\n private activatedRouteRef: ActivatedRoute | null = null;\n private current: StackEntry | null = null;\n private initialized = false;\n\n /** A committed swipe, animated to the end, waiting for the router to catch up. */\n private pendingSwipe: InteractiveBack | null = null;\n\n // Required by RouterOutletContract, which predates `output()` and types these as EventEmitters.\n readonly activateEvents = new EventEmitter<unknown>();\n readonly deactivateEvents = new EventEmitter<unknown>();\n readonly attachEvents = new EventEmitter<unknown>();\n readonly detachEvents = new EventEmitter<unknown>();\n\n readonly activeTab: Signal<string> = this.controller.activeTab;\n\n /**\n * Is there anywhere to go back to? Show your back button on this.\n *\n * True even with a single page on the stack, if that page has a parent it could go up to — which\n * is exactly the cold-deep-link case, where nothing is beneath but obviously something should be.\n */\n readonly canGoBack: Signal<boolean> = computed(\n () => this.controller.canGoBack() || this.parentOfTop() !== null,\n );\n\n constructor() {\n super();\n\n // If a navigation dies after a swipe has already animated the page away, put it back.\n this.router.events.pipe(takeUntilDestroyed()).subscribe((event) => {\n if (event instanceof NavigationCancel || event instanceof NavigationError) {\n this.rollBackPendingSwipe();\n }\n });\n }\n\n ngOnInit(): void {\n if (this.initialized) return;\n this.initialized = true;\n\n this.parentContexts.onChildOutletCreated(this.name(), this);\n\n // The route can be activated before the outlet exists — e.g. it sits inside an `@if` that only\n // just became true. Pick up whatever is already waiting for us.\n const context = this.parentContexts.getContext(this.name());\n if (context?.route) {\n this.activateWith(context.route, context.injector);\n }\n\n this.startGesture();\n this.nav.registerStack(this);\n\n const win = this.document.defaultView;\n if (win) this.systemTransition = new SystemTransitionWatcher(win);\n }\n\n // ---------------------------------------------------------------------------\n // RouterOutletContract\n // ---------------------------------------------------------------------------\n\n get isActivated(): boolean {\n return this.current !== null;\n }\n\n get component(): object | null {\n return (this.current?.ref.instance as object) ?? null;\n }\n\n get activatedRoute(): ActivatedRoute | null {\n return this.activatedRouteRef;\n }\n\n get activatedRouteData(): Data {\n return this.activatedRouteRef?.snapshot.data ?? {};\n }\n\n activateWith(route: ActivatedRoute, environmentInjector: EnvironmentInjector): void {\n const url = this.urlOf(route);\n const tab = tabOfRoute(route.snapshot, url, this.config.tabs);\n const hint = readDirectionHint(this.router);\n\n // If the browser already drew its own back animation, drawing ours would double it up.\n let animated = !(this.systemTransition?.consume() ?? false);\n\n // A caller rebuilding a stack at startup wants the pages to just *be* there, not to watch them\n // fly in one after another.\n if (readAnimatedHint(this.router) === false) animated = false;\n\n // Changing tabs is not a push and not a pop — it's a cut. Nothing is created, nothing destroyed,\n // the other tab's stack simply comes back on screen exactly as it was. Sliding it in would imply\n // a relationship between the two tabs that doesn't exist.\n if (tab !== this.controller.activeTab() && hint !== 'root') animated = false;\n\n const existingIndex = this.controller.findByUrl(url, tab);\n\n const swipe = this.pendingSwipe;\n this.pendingSwipe = null;\n\n if (swipe) {\n // The swipe already ran the whole animation. Hand its player to the controller so it finalises\n // instead of transitioning a second time — but only if history actually took us where the\n // swipe aimed. If something else intervened, throw the gesture's work away.\n const aimedAt =\n existingIndex >= 0 && this.controller.at(existingIndex, tab) === swipe.entering;\n\n if (aimedAt) {\n this.adopt(swipe.entering, route);\n void this.controller.run({\n kind: 'pop',\n tab,\n toIndex: existingIndex,\n animated: true,\n player: swipe.player,\n });\n return;\n }\n swipe.player.destroy();\n }\n\n const goingBack = hint !== 'forward' && hint !== 'root';\n\n // Already on the stack: unwind to it.\n if (goingBack && existingIndex >= 0) {\n this.adopt(this.controller.at(existingIndex, tab)!, route);\n void this.controller.run({ kind: 'pop', tab, toIndex: existingIndex, animated });\n return;\n }\n\n // Going back to a page that isn't mounted. Two ways that happens, wanting the same handling:\n // `maxDepth` evicted it, or we deep-linked into the middle of the app and are walking up to a\n // parent that was never built. Either way, rebuild it and animate as a *back*, because that is\n // what actually happened — whatever the DOM currently remembers about it.\n if (hint === 'back' || (goingBack && this.controller.wasPruned(url, tab))) {\n const entry = this.createEntry(route, environmentInjector, url, tab);\n this.adopt(entry, route);\n void this.controller.run({ kind: 'restore', tab, entering: entry, animated });\n this.activateEvents.emit(entry.ref.instance);\n return;\n }\n\n const entry = this.createEntry(route, environmentInjector, url, tab);\n this.adopt(entry, route);\n\n // `replaceUrl: true` says the history entry was overwritten rather than added. The stack has to\n // agree: swap the top page rather than stack a second one on it, or the stack grows while\n // history doesn't and a back button starts skipping pages.\n const replacing =\n this.router.getCurrentNavigation()?.extras.replaceUrl === true && this.controller.depth() > 0;\n\n void this.controller.run(\n hint === 'root'\n ? { kind: 'root', tab, entering: entry, animated }\n : replacing\n ? { kind: 'replace', tab, entering: entry, animated }\n : { kind: 'push', tab, entering: entry, animated },\n );\n this.activateEvents.emit(entry.ref.instance);\n }\n\n deactivate(): void {\n const entry = this.current;\n if (entry) {\n const context = this.parentContexts.getContext(this.name());\n if (context) {\n // Hold on to this page's nested outlets, so coming back to it doesn't find them empty.\n entry.savedContexts = context.children.onOutletDeactivated();\n }\n this.deactivateEvents.emit(entry.ref.instance);\n }\n\n // Note what we do *not* do here: destroy the component. It stays on the stack. If it is being\n // popped, the controller destroys it once the transition has played out.\n this.current = null;\n this.activatedRouteRef = null;\n }\n\n detach(): ComponentRef<unknown> {\n throw new Error(\n '[ngx-stack] detach() is not supported. <ngx-stack-outlet> manages page lifetime itself; a ' +\n 'RouteReuseStrategy that returns shouldDetach: true will fight it. provideNgxStack() ' +\n 'installs NgxStackRouteReuseStrategy for exactly this reason.',\n );\n }\n\n attach(): void {\n throw new Error('[ngx-stack] attach() is not supported. See detach().');\n }\n\n // ---------------------------------------------------------------------------\n // StackHostBase / BackTarget\n // ---------------------------------------------------------------------------\n\n protected swipeBackOverride(): boolean | null {\n return this.swipeBack();\n }\n\n protected guardPolicy(): GuardPolicy {\n return this.config.guardPolicy;\n }\n\n commitSwipeBack(back: InteractiveBack, ms: number): void {\n void back.player.settle(1, ms).then(() => {\n this.pendingSwipe = back;\n // Go back for real, so the URL and the browser's back button stay honest. The animation is\n // already finished; `activateWith` will adopt the player and just tidy up.\n void this.nav.back();\n });\n }\n\n /**\n * Where a \"back\" should actually go.\n *\n * Usually the page beneath the top of the *active* stack — which, with tabs, is emphatically not\n * whatever the browser happens to have behind us in history. When nothing is beneath, we fall back\n * to the page this one sits under. That page isn't mounted, so it has to be built; `mounted` is\n * how {@link NgxStackNav.back} tells the two apart, because only one of them can be served by a\n * plain `history.back()`.\n */\n backTarget(): BackTarget | null {\n const stack = this.controller.pages();\n if (stack.length >= 2) {\n return { url: stack[stack.length - 2].url, mounted: true };\n }\n\n const parent = this.parentOfTop();\n return parent ? { url: parent, mounted: false } : null;\n }\n\n private rollBackPendingSwipe(): void {\n const swipe = this.pendingSwipe;\n if (!swipe) return;\n this.pendingSwipe = null;\n void this.controller.abortInteractiveBack(swipe, this.config.duration);\n }\n\n // ---------------------------------------------------------------------------\n\n /**\n * Where the top page sits, when nothing is mounted underneath it.\n *\n * Nobody normally has to say: `/inbox/item/12` obviously sits under `/inbox`, and the route config\n * already knows it. `data: { parent }` is only for URLs that don't tell the truth.\n */\n private parentOfTop(): string | null {\n const url = this.controller.top()?.url;\n return url ? deriveParentUrl(this.router.config, url) : null;\n }\n\n private createEntry(\n route: ActivatedRoute,\n environmentInjector: EnvironmentInjector,\n url: string,\n tab: string,\n ): StackEntry {\n const component = route.snapshot.routeConfig?.component;\n if (!component) {\n throw new Error(\n `[ngx-stack] Route \"${url}\" has no component. <ngx-stack-outlet> can only host component ` +\n 'routes — loadComponent is fine, but redirects and componentless routes are not.',\n );\n }\n\n const childContexts = this.parentContexts.getOrCreateContext(this.name()).children;\n const injector = new StackOutletInjector(route, childContexts, this.viewContainer.injector);\n\n const ref = this.createPage(component, { injector, environmentInjector });\n return this.controller.adopt(ref, url, route, tab);\n }\n\n /** Make `entry` the outlet's current page and give it back its nested outlets. */\n private adopt(entry: StackEntry, route: ActivatedRoute): void {\n entry.route = route;\n this.current = entry;\n this.activatedRouteRef = route;\n\n const context = this.parentContexts.getContext(this.name());\n if (context && entry.savedContexts) {\n context.children.onOutletReAttached(entry.savedContexts);\n entry.savedContexts = undefined;\n }\n }\n\n private urlOf(route: ActivatedRoute): string {\n return this.router.serializeUrl(this.router.createUrlTree(['.'], { relativeTo: route }));\n }\n\n override ngOnDestroy(): void {\n this.systemTransition?.destroy();\n this.nav.unregisterStack(this);\n this.parentContexts.onChildOutletDestroyed(this.name());\n super.ngOnDestroy();\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n Injector,\n ViewEncapsulation,\n inject,\n input,\n type OnInit,\n type Signal,\n type Type,\n} from '@angular/core';\n\nimport type { GuardPolicy } from '../config';\nimport type { InteractiveBack } from '../core/stack-controller';\nimport type { StackEntry } from '../core/stack-entry';\nimport { StackHostBase } from '../core/stack-host';\n\n/** Imperative stacks have no URLs, so all their pages live in the one unnamed stack. */\nconst NO_TAB = '';\n\n/**\n * A self-contained page stack with no URLs — the escape hatch for navigation that has no business\n * being in the address bar.\n *\n * A multi-step filter sheet, a wizard inside a modal, a drill-down in one tab of a tab bar: these\n * are all stacks, they all want the same push/pop transition and the same swipe-back, and none of\n * them should push history entries that the browser's back button then has to unwind one at a time.\n *\n * ```html\n * <ngx-stack [root]=\"FilterStep1\" #filters />\n * ```\n * ```ts\n * filters.push(FilterStep2, { category: 'shoes' });\n * ```\n *\n * Pages reach the stack they are standing on with `inject(NgxStack)`. For anything the user should\n * be able to link to, bookmark or reload, use `<ngx-stack-outlet>` instead.\n */\n@Component({\n selector: 'ngx-stack',\n template: '',\n host: { class: 'ngx-stack-host' },\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n exportAs: 'ngxStack',\n})\nexport class NgxStack extends StackHostBase implements OnInit {\n /** The bottom page. Mounted on init; use `setRoot()` to change it afterwards. */\n readonly root = input<Type<unknown> | null>(null);\n\n /** Inputs for the root page, applied with `setInput`. */\n readonly rootInputs = input<Record<string, unknown>>();\n\n /**\n * Swipe-back for this stack specifically. `null` (the default) defers to `NgxStackSwipe`, the\n * app-wide switch; `true` or `false` overrides it here.\n */\n readonly swipeBack = input<boolean | null>(null);\n\n /** The stack's own node injector, so pages can `inject(NgxStack)` and push further. */\n private readonly pageInjector = inject(Injector);\n\n readonly canGoBack: Signal<boolean> = this.controller.canGoBack;\n\n ngOnInit(): void {\n const root = this.root();\n if (root) {\n const entry = this.mount(root, this.rootInputs());\n void this.controller.run({ kind: 'push', tab: NO_TAB, entering: entry, animated: false });\n }\n this.startGesture();\n }\n\n /** Push a page on top. Resolves when the transition has finished. */\n push<T>(component: Type<T>, inputs?: Record<string, unknown>): Promise<void> {\n const entry = this.mount(component, inputs);\n return this.controller.run({ kind: 'push', tab: NO_TAB, entering: entry, animated: true });\n }\n\n /** Pop the top page. A no-op at the root, so it is safe to call blindly. */\n pop(): Promise<void> {\n return this.popTo(this.controller.depth() - 2);\n }\n\n /** Unwind to the page at `index` (0 is the root), destroying everything above it. */\n popTo(index: number): Promise<void> {\n if (index < 0 || index >= this.controller.depth() - 1) return Promise.resolve();\n return this.controller.run({ kind: 'pop', tab: NO_TAB, toIndex: index, animated: true });\n }\n\n popToRoot(): Promise<void> {\n return this.popTo(0);\n }\n\n /** Throw the stack away and start again from `component`. */\n setRoot<T>(component: Type<T>, inputs?: Record<string, unknown>): Promise<void> {\n const entry = this.mount(component, inputs);\n return this.controller.run({ kind: 'root', tab: NO_TAB, entering: entry, animated: true });\n }\n\n // ---------------------------------------------------------------------------\n // StackHostBase\n // ---------------------------------------------------------------------------\n\n protected swipeBackOverride(): boolean | null {\n return this.swipeBack();\n }\n\n /** No routes here, so no `canDeactivate` guards to be careful about. */\n protected guardPolicy(): GuardPolicy {\n return 'allow';\n }\n\n commitSwipeBack(back: InteractiveBack, ms: number): void {\n void back.player.settle(1, ms).then(() => {\n const index = this.controller.pages().indexOf(back.entering);\n if (index < 0) return;\n\n // Hand the finished player over so the pop finalises rather than animating a second time.\n void this.controller.run({\n kind: 'pop',\n tab: NO_TAB,\n toIndex: index,\n animated: true,\n player: back.player,\n });\n });\n }\n\n // ---------------------------------------------------------------------------\n\n private mount<T>(component: Type<T>, inputs?: Record<string, unknown>): StackEntry {\n const ref = this.createPage(component, { injector: this.pageInjector });\n\n for (const [name, value] of Object.entries(inputs ?? {})) {\n ref.setInput(name, value);\n }\n\n return this.controller.adopt(ref, '', null, NO_TAB);\n }\n}\n","import { Injectable, computed, inject, signal, type Signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NavigationEnd, Router, type ActivatedRouteSnapshot } from '@angular/router';\n\nimport { NGX_STACK_CONFIG } from '../config';\nimport { tabOfRoute } from './tab-url';\n\n/**\n * Remembers where you were in each tab.\n *\n * The stacks themselves are `NgxStackOutlet`'s job — configure `tabs` and it keeps one per tab,\n * mounted and untouched while you're elsewhere. This is the other half: tapping \"Search\" should\n * take you back to the search result you were reading three screens deep, not dump you at the\n * search tab's front page. So we watch navigations, note the current URL of each tab, and\n * `select()` returns you to it.\n *\n * The tab *bar* is yours to draw — the library ships no visual design. All you need from us:\n *\n * ```ts\n * const tabs = inject(NgxStackTabs);\n * ```\n * ```html\n * @for (tab of ['home', 'search', 'profile']; track tab) {\n * <button [class.active]=\"tabs.active() === tab\" (click)=\"tabs.select(tab)\">{{ tab }}</button>\n * }\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class NgxStackTabs {\n private readonly router = inject(Router);\n private readonly config = inject(NGX_STACK_CONFIG);\n\n private readonly urls = signal<Record<string, string>>({});\n private readonly _active = signal('');\n\n /** The tab currently on screen, or `''` before the first navigation into one. */\n readonly active: Signal<string> = this._active.asReadonly();\n\n /** The tabs you configured, in order. */\n readonly tabs: Signal<readonly string[]> = computed(() => this.config.tabs ?? []);\n\n constructor() {\n this.router.events.pipe(takeUntilDestroyed()).subscribe((event) => {\n if (!(event instanceof NavigationEnd)) return;\n\n const url = event.urlAfterRedirects;\n\n // Exactly the rule the outlet uses to file the page, so the bar and the stacks can't disagree.\n const tab = tabOfRoute(this.leaf(), url, this.config.tabs);\n if (!tab) return;\n\n this._active.set(tab);\n this.urls.update((urls) => ({ ...urls, [tab]: url }));\n });\n }\n\n /** The page that actually landed. */\n private leaf(): ActivatedRouteSnapshot {\n let route = this.router.routerState.snapshot.root;\n while (route.firstChild) route = route.firstChild;\n return route;\n }\n\n /** Where `tab` was last seen, or its front page if it hasn't been visited yet. */\n urlOf(tab: string): string {\n return this.urls()[tab] ?? `/${tab}`;\n }\n\n /**\n * Switch to `tab`, landing back on whatever page you last had open there.\n *\n * Tapping the tab you're already on takes you to its root, which is what every native tab bar\n * does — it's the standard way back out of a deep drill-down.\n */\n select(tab: string): Promise<boolean> {\n if (tab === this._active()) {\n return this.router.navigateByUrl(`/${tab}`);\n }\n return this.router.navigateByUrl(this.urlOf(tab));\n }\n}\n","import type { StackTransition, TransitionSpec } from './transition';\n\n/**\n * Pages swap instantly.\n *\n * Give it to a platform you'd rather not animate — `transitions: { web: noneTransition }` is a\n * common choice, since a page slide on a desktop monitor mostly just moves a lot of pixels.\n *\n * Note this also disarms the swipe on that platform in practice: there are no keyframes for a finger\n * to scrub, so a drag has nothing to follow.\n */\nexport const noneTransition: StackTransition = (): TransitionSpec => ({\n duration: 0,\n easing: 'linear',\n animations: [],\n});\n","/*\n * ngx-stack — native-feeling page stacks for Angular.\n */\n\n// Setup\nexport {\n provideNgxStack,\n provideCapacitorBack,\n provideCordovaBack,\n type CapacitorAppLike,\n} from './lib/provide';\nexport {\n type GuardPolicy,\n type NgxStackConfig,\n type StackTransitionMap,\n type SystemGesturePolicy,\n} from './lib/config';\n\n// The two ways to hold a stack\nexport { NgxStackOutlet } from './lib/router/stack-outlet';\nexport { NgxStack } from './lib/nav/ngx-stack';\n\n// Navigation\nexport { NgxStackNav } from './lib/router/stack-nav';\nexport { NgxStackTabs } from './lib/router/stack-tabs';\nexport { NgxStackSwipe } from './lib/gesture/swipe-service';\n\n// Required by provideNgxStack, and exported so an app composing its own strategy can defer to it.\nexport { NgxStackRouteReuseStrategy } from './lib/router/route-reuse-strategy';\n\n// Pages\nexport type { NgxStackPage, StackEntry } from './lib/core/stack-entry';\nexport type { StackTransitionEvent } from './lib/core/stack-controller';\n\n// Transitions\nexport { iosTransition } from './lib/animation/ios-transition';\nexport { androidTransition } from './lib/animation/android-transition';\nexport { webTransition } from './lib/animation/web-transition';\nexport { noneTransition } from './lib/animation/none-transition';\n// The two shapes the built-ins are made of. Build your own by re-tuning either.\nexport { slideTransition, type SlideOptions } from './lib/animation/slide';\nexport { riseTransition, type RiseOptions } from './lib/animation/rise';\nexport { scrimOf } from './lib/animation/transition';\nexport type {\n ElementAnimation,\n StackDirection,\n StackTransition,\n TransitionContext,\n TransitionSpec,\n} from './lib/animation/transition';\n\n// Deep links — for composing with a custom `deepLinks` function.\nexport { deriveParentUrl } from './lib/router/parent-url';\n\n// Platform\nexport { NGX_STACK_PLATFORM } from './lib/platform/platform';\nexport type { StackPlatform, StackPlatformKind } from './lib/platform/platform';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ngx-stack",
|
|
3
|
-
"version": "22.0.
|
|
3
|
+
"version": "22.0.1",
|
|
4
4
|
"description": "Native-feeling page stacks for Angular: push/pop transitions and an interactive iOS swipe-to-go-back. Built for Capacitor and Cordova, works on the web.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
package/types/ngx-stack.d.ts
CHANGED
|
@@ -92,21 +92,23 @@ interface StackTransitionMap {
|
|
|
92
92
|
/**
|
|
93
93
|
* What to do about the browser's *own* edge-swipe back gesture.
|
|
94
94
|
*
|
|
95
|
-
* Only relevant on iOS Safari and iOS standalone PWAs — WebKit
|
|
96
|
-
*
|
|
97
|
-
*
|
|
95
|
+
* Only relevant on iOS Safari and iOS standalone PWAs — WebKit runs its own interactive back
|
|
96
|
+
* navigation at the screen edge, and on a Router-based stack (real history entries) it will win over
|
|
97
|
+
* ours. Nothing web-side reliably disables it, so these options only *reduce the overlap*; the clean
|
|
98
|
+
* answer is a native shell (Capacitor/Cordova), whose WKWebView has the gesture off. See the "iOS
|
|
99
|
+
* Safari caveat" in the README.
|
|
98
100
|
*/
|
|
99
101
|
type SystemGesturePolicy =
|
|
100
102
|
/**
|
|
101
|
-
* Start our gesture zone a few px inland so the two don't fight over the same pixels. The
|
|
102
|
-
*
|
|
103
|
-
* our own animation rather than drawing a second one on top of WebKit's.
|
|
103
|
+
* Start our gesture zone a few px inland so the two don't fight over the same pixels. The system
|
|
104
|
+
* still owns the outermost `systemEdgeInset` px; when it fires we notice via `hasUAVisualTransition`
|
|
105
|
+
* and skip our own animation rather than drawing a second one on top of WebKit's.
|
|
104
106
|
*/
|
|
105
107
|
'inset'
|
|
106
108
|
/**
|
|
107
|
-
* `preventDefault()` the touchstart inside the edge zone
|
|
108
|
-
*
|
|
109
|
-
*
|
|
109
|
+
* `preventDefault()` the touchstart inside the edge zone. Helps in some embedded WebViews, but does
|
|
110
|
+
* **not** stop mobile Safari's system navigation — `preventDefault` doesn't reach it. It also
|
|
111
|
+
* suppresses the synthetic `click` for touches beginning there, so rarely worth it.
|
|
110
112
|
*/
|
|
111
113
|
| 'suppress'
|
|
112
114
|
/** Do nothing, and let both gestures coexist. */
|