@ng-native/router 0.18.2 → 0.19.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"native-navigation.js","sourceRoot":"","sources":["../src/native-navigation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The typed facade over `Router` for the intents a URL cannot express (ADR 0003).\n *\n * Angular's `Router` stays the single source of truth: each of these is a line over\n * `router.navigate`, setting `replaceUrl` and a presentation on `NavigationExtras.state`. Deep\n * links, guards and resolvers keep working because it is still the Router, and because state\n * rides in history a back restores the presentation the screen was opened with.\n *\n * A navigation service that owns the stack was rejected: it either re-implements guards,\n * resolvers and deep linking, or it drifts from the URL, and once the stack is not derived from\n * router state the two can disagree.\n *\n * No decorators, so tests can import it at runtime and so it can be provided with `useClass`,\n * exactly as `NativePlatformLocation` and `NativeStackReuseStrategy` are.\n */\nimport { DestroyRef, inject } from '@angular/core';\nimport {\n NavigationCancel,\n NavigationCancellationCode,\n NavigationEnd,\n NavigationError,\n NavigationSkipped,\n NavigationSkippedCode,\n PRIMARY_OUTLET,\n Router,\n type Navigation,\n type NavigationExtras,\n} from '@angular/router';\nimport { NativeBack } from './native-back.ts';\nimport type { ScreenPresentation, StackPresentation } from './screen-presentation.ts';\nimport { PRESENTED, leavingPresented, presentedCommands } from './presented-route.ts';\nimport { hasCommandKeyParameters, urlCommands, withWrittenParameters } from './url-commands.ts';\n\n/** What `Router` takes: a url string, or the array form with segments and params. */\nexport type NavigationCommands = string | readonly unknown[];\n\n/**\n * Where the intent rides. `NavigationExtras.state` is the app's own object, so ours sits under\n * one reserved key rather than spread through it.\n */\nexport const NATIVE_INTENT = 'ɵnativeStack';\n\n/** What a navigation asks the outlet to do with the stack, over and above rendering the route. */\nexport interface NativeIntent {\n /** `replace` drops the screen it supersedes; `reset` empties the stack first. */\n readonly stack?: 'push' | 'replace' | 'reset';\n readonly presentation?: ScreenPresentation;\n}\n\nexport interface NativeNavigationOptions extends NavigationExtras {\n /** How the screen arrives: presentation, animation, gesture and sheet props. */\n presentation?: ScreenPresentation;\n}\n\nexport interface PresentOptions extends NativeNavigationOptions {\n /** Shorthand for `presentation.stackPresentation`. Defaults to `modal`. */\n as?: StackPresentation;\n}\n\n/** Whether commands ask for a query or a fragment, written into a url string or as extras. */\nconst asksMore = (commands: NavigationCommands, extras: NavigationExtras): boolean =>\n (typeof commands === 'string' && /[?#]/.test(commands)) ||\n extras.queryParams != null ||\n extras.fragment != null;\n\n/** A url string's path, and the outlet whose segments it writes. */\ninterface WrittenPath {\n readonly path: string;\n readonly outlet: string;\n}\n\n/** A url string up to its query or fragment. */\nconst pathOf = (url: string): string => url.split(/[?#]/, 1)[0]!;\n\n/**\n * A replace's or a reset's presentation, made to push its screen in with the `stackAnimation` it\n * names unless it names a `replaceAnimation` too. `RNSScreenStack` otherwise runs it as a pop of\n * the screen leaving, which animates as that screen says and never reads the one arriving.\n * `default` names no animation of its own, so it is left a pop, as no `stackAnimation` is.\n */\nfunction arrivingAs(intent: NativeIntent, presentation: ScreenPresentation): ScreenPresentation {\n const replacing = intent.stack === 'replace' || intent.stack === 'reset';\n const named =\n presentation.stackAnimation !== undefined && presentation.stackAnimation !== 'default';\n if (!replacing || !named || presentation.replaceAnimation) return presentation;\n return { ...presentation, replaceAnimation: 'push' };\n}\n\n/** Read the intent off a navigation's state, if it carries one. */\nexport function intentOf(state: unknown): NativeIntent | null {\n if (!state || typeof state !== 'object') return null;\n const intent = (state as Record<string, unknown>)[NATIVE_INTENT];\n return intent && typeof intent === 'object' ? (intent as NativeIntent) : null;\n}\n\n/**\n * The intent of a navigation a guard redirected, for the navigation the redirect starts.\n *\n * The router starts a new navigation for a guard's `UrlTree`, keeping `replaceUrl` but not\n * `state`, so a reset to a page that sends a signed-out user to sign in would push the sign-in\n * page over the stack it was meant to clear. Held for that one navigation by its id, which no\n * later navigation shares.\n */\nconst redirected = new WeakMap<object, { readonly id: number; readonly intent: NativeIntent }>();\n\n/** What a navigation asks of the stack: its own intent, or the one it was redirected from. */\nexport function navigationIntent(\n router: object,\n navigation: Pick<Navigation, 'id' | 'extras'> | null | undefined,\n): NativeIntent | null {\n if (!navigation) return null;\n const own = intentOf(navigation.extras.state);\n if (own) return own;\n const carried = redirected.get(router);\n return carried?.id === navigation.id ? carried.intent : null;\n}\n\n/**\n * Hand a navigation's intent on to the one its guard redirects it to. The router schedules that\n * navigation as soon as it has reported the cancel, so it takes the next id.\n *\n * A reset that lands on the screen already on top, its own url or the one a redirect sends it to,\n * is one no outlet activates anything for: the router skips the url already showing, and reuses\n * the screen for another url of it. So the stack is reset here, to the screen on top.\n */\nexport function carryIntentAcrossRedirects(): void {\n const router = inject(Router);\n const outlets = inject(NativeBack);\n const events = router.events.subscribe((event) => {\n if (event instanceof NavigationCancel && event.code === NavigationCancellationCode.Redirect) {\n carryPast(router, event.id);\n return;\n }\n if (keptTop(event, outlets) && intentAt(router, event.id)?.stack === 'reset') {\n outlets.resetToTop();\n }\n if (ended(event) && redirected.get(router)?.id === event.id) redirected.delete(router);\n });\n inject(DestroyRef).onDestroy(() => events.unsubscribe());\n}\n\n/**\n * Whether the navigation `event` ends left the screen on top where it was: one the router skipped\n * for the url already showing, or one no stack put a screen on top for, such as a url with another\n * query, or one a redirect sends to the page on top.\n */\nfunction keptTop(event: unknown, outlets: NativeBack): event is { readonly id: number } {\n if (event instanceof NavigationSkipped) {\n return event.code === NavigationSkippedCode.IgnoredSameUrlNavigation;\n }\n return event instanceof NavigationEnd && !outlets.stackedIn(event.id);\n}\n\n/** The intent of the navigation in progress, when it is the one with `id`. */\nfunction intentAt(router: Router, id: number): NativeIntent | null {\n const navigation = router.currentNavigation();\n return navigation?.id === id ? navigationIntent(router, navigation) : null;\n}\n\n/** Hold the intent of the navigation a guard redirected for the one the redirect starts. */\nfunction carryPast(router: Router, id: number): void {\n const intent = intentAt(router, id);\n if (intent) redirected.set(router, { id: id + 1, intent });\n else redirected.delete(router);\n}\n\n/** Whether the event is the last a navigation reports. */\nfunction ended(event: unknown): event is { readonly id: number } {\n return (\n event instanceof NavigationEnd ||\n event instanceof NavigationCancel ||\n event instanceof NavigationError ||\n event instanceof NavigationSkipped\n );\n}\n\nexport class NativeNavigation {\n private readonly router = inject(Router);\n private readonly outlets = inject(NativeBack);\n\n /**\n * Push a new screen onto the stack. The plain case, and what `nativeRouterLink` does.\n *\n * From a presented screen the new one is presented the same way, over it, since a pushed\n * screen would slide in under it; `presentation` says otherwise, `stackAnimation` and all.\n */\n push(commands: NavigationCommands, options: NativeNavigationOptions = {}): Promise<boolean> {\n return this.go(commands, options, { stack: 'push' });\n }\n\n /**\n * Swap the current screen for another. The history entry is replaced too, so a back from the\n * new screen goes where a back from the old one would have.\n *\n * A `stackAnimation` in `presentation` is the one the new screen arrives with. Without one, with\n * `default`, or with a `replaceAnimation`, the swap animates as the screen leaving was opened.\n */\n replace(commands: NavigationCommands, options: NativeNavigationOptions = {}): Promise<boolean> {\n return this.go(commands, { ...options, replaceUrl: true }, { stack: 'replace' });\n }\n\n /**\n * Present a screen over the stack rather than pushing into it: a modal, or a sheet.\n *\n * `present('/filters', { as: 'formSheet', presentation: { sheetAllowedDetents: [0.5, 1] } })`.\n *\n * A presented screen is put on screen outside the stack's navigation controller, so it has no\n * native header and no automatic safe-area insets: it needs its own way out, and its own\n * `safe-area-view`. A sheet can also be dragged away, but `fullScreenModal` cannot, and with\n * `gestureEnabled: false` neither can.\n */\n present(commands: NavigationCommands, options: PresentOptions = {}): Promise<boolean> {\n if (this.firstNavigationRunning()) {\n return this.firstNavigation().then(() => this.present(commands, options));\n }\n const { as = 'modal', presentation, ...extras } = options;\n const intent: NativeIntent = {\n stack: 'push',\n presentation: { stackPresentation: as, ...presentation },\n };\n // Asked at once, and only waited for when the page is another tab's: finding its route may\n // load a lazy one.\n const over = this.overTheTabInFront(commands, extras);\n if (!over) return this.go(commands, extras, intent);\n return over.then((found) =>\n found\n ? this.go(found.commands, found.extras, intent, found.written)\n : this.go(commands, extras, intent),\n );\n }\n\n /**\n * Replace the whole stack with one screen, the way signing out or finishing onboarding does.\n * Every screen below is destroyed, so there is nothing to go back to.\n *\n * A `stackAnimation` in `presentation` is the one a new screen arrives with:\n * `reset('/sign-in', { presentation: { stackAnimation: 'none' } })` lands with no animation.\n * Without one, with `default`, or with a `replaceAnimation`, the reset animates as the screen\n * leaving was opened, and so does a reset to a screen still on the stack, which is kept.\n */\n reset(commands: NavigationCommands, options: NativeNavigationOptions = {}): Promise<boolean> {\n return this.go(commands, { ...options, replaceUrl: true }, { stack: 'reset' });\n }\n\n /**\n * Go back exactly as the Android back button does: pop the stack in front, or at the root of a\n * tab's stack, go to the first tab. Not one entry back through history, which after a trip to\n * another tab is that tab. At the root of the app there is nowhere to go, and this does nothing.\n */\n back(): void {\n // Optional call: a test that stands a plain object in for the router has no such signal.\n if (!this.router.currentNavigation?.()) {\n this.outlets.back();\n return;\n }\n // Asked while a navigation is still putting its screen up: a page that leaves as it appears,\n // from an effect in its constructor. No stack has that screen to pop yet, so the back waits\n // for the navigation, and goes nowhere if the navigation does not arrive.\n if (this.backWaiting) return;\n this.backWaiting = this.router.events.subscribe((event) => {\n const ended = event instanceof NavigationEnd;\n if (!ended && !(event instanceof NavigationCancel) && !(event instanceof NavigationError)) {\n return;\n }\n this.backWaiting?.unsubscribe();\n this.backWaiting = null;\n if (ended) this.outlets.back();\n });\n }\n\n /** The wait of a back asked for mid-navigation, so two asked for in one are one. */\n private backWaiting: { unsubscribe(): void } | null = null;\n\n /**\n * Pop straight back to the screen at `commands`, taking every screen above it off the stack at\n * once - `popToViewController`. The screen is the one already there, with its state, not a new\n * one; where that url is also the one showing, the screen on top is the one kept. Resolves\n * false, doing nothing, when no screen below the top of a stack in front is showing that url; a\n * push is the way to a screen that is not there.\n */\n popTo(commands: NavigationCommands): Promise<boolean> {\n const tree =\n typeof commands === 'string'\n ? this.router.parseUrl(commands)\n : this.router.createUrlTree([...commands]);\n return this.outlets.popTo(this.router.serializeUrl(tree));\n }\n\n /**\n * Pop the stack in front to its first screen - `popToRootViewController`. Inside a tab, that is\n * the tab's first screen; the screens below keep their state. Resolves false at the root already.\n */\n popToRoot(): Promise<boolean> {\n return this.outlets.popToRoot();\n }\n\n private go(\n commands: NavigationCommands,\n options: NativeNavigationOptions,\n intent: NativeIntent,\n written: WrittenPath | null = typeof commands === 'string'\n ? { path: pathOf(commands), outlet: PRIMARY_OUTLET }\n : null,\n ): Promise<boolean> {\n const { presentation, state, ...extras } = options;\n const full: NativeIntent = presentation\n ? { ...intent, presentation: arrivingAs(intent, { ...intent.presentation, ...presentation }) }\n : intent;\n\n const navigate = () => {\n const list =\n typeof commands === 'string' ? urlCommands(this.router, pathOf(commands)) : [...commands];\n const all = {\n ...extras,\n ...(typeof commands === 'string' ? this.queryOf(commands, extras) : {}),\n state: { ...(state as object), [NATIVE_INTENT]: full },\n };\n const leaving = leavingPresented(this.router, list, all);\n // A parameter the commands could not carry goes back on the tree they make, which is what\n // `navigate` would go to; `navigateByUrl` then takes it as it is.\n if (written && hasCommandKeyParameters(this.router, written.path)) {\n const tree = leaving ?? this.router.createUrlTree(list, all);\n return this.router.navigateByUrl(\n withWrittenParameters(this.router, tree, written.path, written.outlet),\n all,\n );\n }\n return leaving ? this.router.navigateByUrl(leaving, all) : this.router.navigate(list, all);\n };\n // A screen stacked on the first one waits for it. Navigating while the router's first\n // navigation is still running - a lazily loaded root waiting on its import - cancels that\n // navigation, and the app opens on this screen with nothing beneath it. A reset replaces the\n // stack anyway, so it goes at once.\n const start = () => this.underTabRoot(commands, extras, full, navigate);\n return intent.stack !== 'reset' && this.firstNavigationRunning()\n ? this.firstNavigation().then(start)\n : start();\n }\n\n /**\n * A push to a page of a tab bar that a screen over it covers, pushed on the app's own stack or\n * presented, goes back to the bar first: to its tab, where that was left, and then pushes the\n * page there unless the tab is already showing it. One tab bar, as a native app has. Pushed as\n * it was asked, the page would build a second bar over the screen.\n *\n * A push into a tab nobody has opened goes to the tab first, so its stack has the tab's own\n * first screen under the page, and a back from the page lands there: what a tab bar with a\n * navigation controller per tab does. Without it the page is the stack's only screen, and the\n * same push leaves a different stack behind depending on whether the tab was ever tapped. A\n * presented screen goes where it is asked, and a replace or a reset has nothing to keep.\n */\n private underTabRoot(\n commands: NavigationCommands,\n extras: NavigationExtras,\n intent: NativeIntent,\n navigate: () => Promise<boolean>,\n ): Promise<boolean> {\n if (intent.stack !== 'push' || intent.presentation) return navigate();\n const path = this.pathFor(commands, extras);\n const left = this.outlets.coveredTabAt(path);\n if (left) {\n // The tab is open once the bar is back, so the page goes straight onto it, unless it is the\n // page the tab was left on and nothing more, a query or a fragment, is asked of it.\n const asked = pathOf(left) !== path || asksMore(commands, extras);\n // A guard that redirects elsewhere still resolves true, so the tab must be in front now.\n return this.router.navigateByUrl(left).then((arrived) => {\n const there =\n arrived && !this.outlets.coveredTabAt(path) && !this.outlets.inTabBehind(path);\n return there && asked ? navigate() : there;\n });\n }\n const tab = this.outlets.unopenedTabOf(path);\n if (!tab) return navigate();\n return this.router\n .navigateByUrl(tab)\n .then((arrived) => (arrived && !this.outlets.unopenedTabOf(path) ? navigate() : false));\n }\n\n /** The path the commands lead to, without its query and fragment. */\n private pathFor(commands: NavigationCommands, extras: NavigationExtras): string {\n if (typeof commands === 'string' && commands.startsWith('/')) return pathOf(commands);\n // Resolved as `go` navigates them: a relative string against `relativeTo`.\n const list =\n typeof commands === 'string' ? urlCommands(this.router, pathOf(commands)) : [...commands];\n return pathOf(this.router.serializeUrl(this.router.createUrlTree(list, extras)));\n }\n\n /**\n * A page of a tab that is not in front, presented over the one that is, or over a screen that\n * covers the bar: its url would select\n * its own tab and show it there, so it goes to the root's presented outlet instead, where the\n * app's own stack shows it over everything. See `presented-route.ts`. Null for a page of the\n * tab in front, or of no tab, which is presented where its url puts it.\n */\n private overTheTabInFront(\n commands: NavigationCommands,\n extras: NavigationExtras,\n ): Promise<{\n commands: unknown[];\n extras: NavigationExtras;\n written: WrittenPath;\n } | null> | null {\n if (!this.outlets.presents) return null;\n const path = this.pathFor(commands, extras);\n // A tab in front of a bar a screen covers is behind that screen just the same.\n if (!this.outlets.inTabBehind(path) && !this.outlets.coveredTabAt(path)) return null;\n const query = typeof commands === 'string' ? this.queryOf(commands, extras) : {};\n return presentedCommands(this.router, path).then(\n (presented) =>\n presented && {\n commands: presented,\n extras: { ...extras, ...query, relativeTo: null },\n written: { path, outlet: PRESENTED },\n },\n );\n }\n\n /**\n * The query and fragment written into a url string, as the extras `navigate` takes them: it\n * reads a string command as one path segment, and would encode a `?` into it. Extras given\n * alongside win over the ones in the string.\n */\n private queryOf(url: string, extras: NavigationExtras): NavigationExtras {\n const cut = url.search(/[?#]/);\n if (cut < 0) return {};\n const { queryParams, fragment } = this.router.parseUrl(url.slice(cut));\n return {\n queryParams: { ...queryParams, ...extras.queryParams },\n fragment: extras.fragment ?? fragment ?? undefined,\n };\n }\n\n private firstNavigationRunning(): boolean {\n const router = this.router as Partial<Router>;\n return router.navigated === false && !!router.currentNavigation?.();\n }\n\n private firstNavigation(): Promise<void> {\n return new Promise((resolve) => {\n const events = this.router.events.subscribe((event) => {\n if (ended(event) && !carriesOn(event)) {\n events.unsubscribe();\n resolve();\n }\n });\n });\n }\n}\n\n/**\n * Whether a navigation ended only for another to take its place: a guard's redirect does, and so\n * does a newer navigation. Waiting for a navigation to end goes on past one of these, or what\n * starts next supersedes the redirect and opens with nothing beneath it, past the guard.\n */\nexport function carriesOn(event: unknown): boolean {\n return (\n event instanceof NavigationCancel &&\n (event.code === NavigationCancellationCode.Redirect ||\n event.code === NavigationCancellationCode.SupersededByNewNavigation)\n );\n}\n"]}
1
+ {"version":3,"file":"native-navigation.js","sourceRoot":"","sources":["../src/native-navigation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The typed facade over `Router` for the intents a URL cannot express (ADR 0003).\n *\n * Angular's `Router` stays the single source of truth: each of these is a line over\n * `router.navigate`, setting `replaceUrl` and a presentation on `NavigationExtras.state`. Deep\n * links, guards and resolvers keep working because it is still the Router, and because state\n * rides in history a back restores the presentation the screen was opened with.\n *\n * A navigation service that owns the stack was rejected: it either re-implements guards,\n * resolvers and deep linking, or it drifts from the URL, and once the stack is not derived from\n * router state the two can disagree.\n *\n * No decorators, so tests can import it at runtime and so it can be provided with `useClass`,\n * exactly as `NativePlatformLocation` and `NativeStackReuseStrategy` are.\n */\nimport { DestroyRef, EnvironmentInjector, inject } from '@angular/core';\nimport {\n NavigationCancel,\n NavigationCancellationCode,\n NavigationEnd,\n NavigationError,\n NavigationSkipped,\n NavigationSkippedCode,\n PRIMARY_OUTLET,\n Router,\n type Navigation,\n type NavigationExtras,\n} from '@angular/router';\nimport { NativeBack } from './native-back.ts';\nimport type { ScreenPresentation, StackPresentation } from './screen-presentation.ts';\nimport { PRESENTED, leavingPresented, presentedCommands } from './presented-route.ts';\nimport { hasCommandKeyParameters, urlCommands, withWrittenParameters } from './url-commands.ts';\n\n/** What `Router` takes: a url string, or the array form with segments and params. */\nexport type NavigationCommands = string | readonly unknown[];\n\n/**\n * Where the intent rides. `NavigationExtras.state` is the app's own object, so ours sits under\n * one reserved key rather than spread through it.\n */\nexport const NATIVE_INTENT = 'ɵnativeStack';\n\n/** What a navigation asks the outlet to do with the stack, over and above rendering the route. */\nexport interface NativeIntent {\n /** `replace` drops the screen it supersedes; `reset` empties the stack first. */\n readonly stack?: 'push' | 'replace' | 'reset';\n readonly presentation?: ScreenPresentation;\n}\n\nexport interface NativeNavigationOptions extends NavigationExtras {\n /** How the screen arrives: presentation, animation, gesture and sheet props. */\n presentation?: ScreenPresentation;\n}\n\nexport interface PresentOptions extends NativeNavigationOptions {\n /** Shorthand for `presentation.stackPresentation`. Defaults to `modal`. */\n as?: StackPresentation;\n}\n\n/** Whether commands ask for a query or a fragment, written into a url string or as extras. */\nconst asksMore = (commands: NavigationCommands, extras: NavigationExtras): boolean =>\n (typeof commands === 'string' && /[?#]/.test(commands)) ||\n extras.queryParams != null ||\n extras.fragment != null;\n\n/** A url string's path, and the outlet whose segments it writes. */\ninterface WrittenPath {\n readonly path: string;\n readonly outlet: string;\n}\n\n/** A url string up to its query or fragment. */\nconst pathOf = (url: string): string => url.split(/[?#]/, 1)[0]!;\n\n/**\n * A replace's or a reset's presentation, made to push its screen in with the `stackAnimation` it\n * names unless it names a `replaceAnimation` too. `RNSScreenStack` otherwise runs it as a pop of\n * the screen leaving, which animates as that screen says and never reads the one arriving.\n * `default` names no animation of its own, so it is left a pop, as no `stackAnimation` is.\n */\nfunction arrivingAs(intent: NativeIntent, presentation: ScreenPresentation): ScreenPresentation {\n const replacing = intent.stack === 'replace' || intent.stack === 'reset';\n const named =\n presentation.stackAnimation !== undefined && presentation.stackAnimation !== 'default';\n if (!replacing || !named || presentation.replaceAnimation) return presentation;\n return { ...presentation, replaceAnimation: 'push' };\n}\n\n/** Read the intent off a navigation's state, if it carries one. */\nexport function intentOf(state: unknown): NativeIntent | null {\n if (!state || typeof state !== 'object') return null;\n const intent = (state as Record<string, unknown>)[NATIVE_INTENT];\n return intent && typeof intent === 'object' ? (intent as NativeIntent) : null;\n}\n\n/**\n * The intent of a navigation a guard redirected, for the navigation the redirect starts.\n *\n * The router starts a new navigation for a guard's `UrlTree`, keeping `replaceUrl` but not\n * `state`, so a reset to a page that sends a signed-out user to sign in would push the sign-in\n * page over the stack it was meant to clear. Held for that one navigation by its id, which no\n * later navigation shares.\n */\nconst redirected = new WeakMap<object, { readonly id: number; readonly intent: NativeIntent }>();\n\n/** What a navigation asks of the stack: its own intent, or the one it was redirected from. */\nexport function navigationIntent(\n router: object,\n navigation: Pick<Navigation, 'id' | 'extras'> | null | undefined,\n): NativeIntent | null {\n if (!navigation) return null;\n const own = intentOf(navigation.extras.state);\n if (own) return own;\n const carried = redirected.get(router);\n return carried?.id === navigation.id ? carried.intent : null;\n}\n\n/**\n * Hand a navigation's intent on to the one its guard redirects it to. The router schedules that\n * navigation as soon as it has reported the cancel, so it takes the next id.\n *\n * A reset that lands on the screen already on top, its own url or the one a redirect sends it to,\n * is one no outlet activates anything for: the router skips the url already showing, and reuses\n * the screen for another url of it. So the stack is reset here, to the screen on top.\n */\nexport function carryIntentAcrossRedirects(): void {\n const router = inject(Router);\n const outlets = inject(NativeBack);\n const events = router.events.subscribe((event) => {\n if (event instanceof NavigationCancel && event.code === NavigationCancellationCode.Redirect) {\n carryPast(router, event.id);\n return;\n }\n if (keptTop(event, outlets) && intentAt(router, event.id)?.stack === 'reset') {\n outlets.resetToTop();\n }\n if (ended(event) && redirected.get(router)?.id === event.id) redirected.delete(router);\n });\n inject(DestroyRef).onDestroy(() => events.unsubscribe());\n}\n\n/**\n * Whether the navigation `event` ends left the screen on top where it was: one the router skipped\n * for the url already showing, or one no stack put a screen on top for, such as a url with another\n * query, or one a redirect sends to the page on top.\n */\nfunction keptTop(event: unknown, outlets: NativeBack): event is { readonly id: number } {\n if (event instanceof NavigationSkipped) {\n return event.code === NavigationSkippedCode.IgnoredSameUrlNavigation;\n }\n return event instanceof NavigationEnd && !outlets.stackedIn(event.id);\n}\n\n/** The intent of the navigation in progress, when it is the one with `id`. */\nfunction intentAt(router: Router, id: number): NativeIntent | null {\n const navigation = router.currentNavigation();\n return navigation?.id === id ? navigationIntent(router, navigation) : null;\n}\n\n/** Hold the intent of the navigation a guard redirected for the one the redirect starts. */\nfunction carryPast(router: Router, id: number): void {\n const intent = intentAt(router, id);\n if (intent) redirected.set(router, { id: id + 1, intent });\n else redirected.delete(router);\n}\n\n/** Whether the event is the last a navigation reports. */\nfunction ended(event: unknown): event is { readonly id: number } {\n return (\n event instanceof NavigationEnd ||\n event instanceof NavigationCancel ||\n event instanceof NavigationError ||\n event instanceof NavigationSkipped\n );\n}\n\nexport class NativeNavigation {\n private readonly router = inject(Router);\n // Absent only where the service is made outside an app, as a unit test makes it.\n private readonly injector = inject(EnvironmentInjector, { optional: true }) ?? undefined;\n private readonly outlets = inject(NativeBack);\n\n /**\n * Push a new screen onto the stack. The plain case, and what `nativeRouterLink` does.\n *\n * From a presented screen the new one is presented the same way, over it, since a pushed\n * screen would slide in under it; `presentation` says otherwise, `stackAnimation` and all.\n */\n push(commands: NavigationCommands, options: NativeNavigationOptions = {}): Promise<boolean> {\n return this.go(commands, options, { stack: 'push' });\n }\n\n /**\n * Swap the current screen for another. The history entry is replaced too, so a back from the\n * new screen goes where a back from the old one would have.\n *\n * A `stackAnimation` in `presentation` is the one the new screen arrives with. Without one, with\n * `default`, or with a `replaceAnimation`, the swap animates as the screen leaving was opened.\n */\n replace(commands: NavigationCommands, options: NativeNavigationOptions = {}): Promise<boolean> {\n return this.go(commands, { ...options, replaceUrl: true }, { stack: 'replace' });\n }\n\n /**\n * Present a screen over the stack rather than pushing into it: a modal, or a sheet.\n *\n * `present('/filters', { as: 'formSheet', presentation: { sheetAllowedDetents: [0.5, 1] } })`.\n *\n * A presented screen is put on screen outside the stack's navigation controller, so it has no\n * native header and no automatic safe-area insets: it needs its own way out, and its own\n * `safe-area-view`. A sheet can also be dragged away, but `fullScreenModal` cannot, and with\n * `gestureEnabled: false` neither can.\n *\n * On iOS, from a screen a tab's stack presents `fullScreenModal`, a screen for the app's own\n * stack cannot show, and this resolves false: see `refuse-screens-under-full-screen.ts`.\n */\n present(commands: NavigationCommands, options: PresentOptions = {}): Promise<boolean> {\n if (this.firstNavigationRunning()) {\n return this.firstNavigation().then(() => this.present(commands, options));\n }\n const { as = 'modal', presentation, ...extras } = options;\n const intent: NativeIntent = {\n stack: 'push',\n presentation: { stackPresentation: as, ...presentation },\n };\n // Asked at once, and only waited for when the page is another tab's: finding its route may\n // load a lazy one.\n const over = this.overTheTabInFront(commands, extras);\n if (!over) return this.go(commands, extras, intent);\n return over.then((found) =>\n found\n ? this.go(found.commands, found.extras, intent, found.written)\n : this.go(commands, extras, intent),\n );\n }\n\n /**\n * Replace the whole stack with one screen, the way signing out or finishing onboarding does.\n * Every screen below is destroyed, so there is nothing to go back to.\n *\n * A `stackAnimation` in `presentation` is the one a new screen arrives with:\n * `reset('/sign-in', { presentation: { stackAnimation: 'none' } })` lands with no animation.\n * Without one, with `default`, or with a `replaceAnimation`, the reset animates as the screen\n * leaving was opened, and so does a reset to a screen still on the stack, which is kept.\n */\n reset(commands: NavigationCommands, options: NativeNavigationOptions = {}): Promise<boolean> {\n return this.go(commands, { ...options, replaceUrl: true }, { stack: 'reset' });\n }\n\n /**\n * Go back exactly as the Android back button does: pop the stack in front, or at the root of a\n * tab's stack, go to the first tab. Not one entry back through history, which after a trip to\n * another tab is that tab. At the root of the app there is nowhere to go, and this does nothing.\n */\n back(): void {\n // Optional call: a test that stands a plain object in for the router has no such signal.\n if (!this.router.currentNavigation?.()) {\n this.outlets.back();\n return;\n }\n // Asked while a navigation is still putting its screen up: a page that leaves as it appears,\n // from an effect in its constructor. No stack has that screen to pop yet, so the back waits\n // for the navigation, and goes nowhere if the navigation does not arrive.\n if (this.backWaiting) return;\n this.backWaiting = this.router.events.subscribe((event) => {\n const ended = event instanceof NavigationEnd;\n if (!ended && !(event instanceof NavigationCancel) && !(event instanceof NavigationError)) {\n return;\n }\n this.backWaiting?.unsubscribe();\n this.backWaiting = null;\n if (ended) this.outlets.back();\n });\n }\n\n /** The wait of a back asked for mid-navigation, so two asked for in one are one. */\n private backWaiting: { unsubscribe(): void } | null = null;\n\n /**\n * Pop straight back to the screen at `commands`, taking every screen above it off the stack at\n * once - `popToViewController`. The screen is the one already there, with its state, not a new\n * one; where that url is also the one showing, the screen on top is the one kept. Resolves\n * false, doing nothing, when no screen below the top of a stack in front is showing that url; a\n * push is the way to a screen that is not there.\n */\n popTo(commands: NavigationCommands): Promise<boolean> {\n const tree =\n typeof commands === 'string'\n ? this.router.parseUrl(commands)\n : this.router.createUrlTree([...commands]);\n return this.outlets.popTo(this.router.serializeUrl(tree));\n }\n\n /**\n * Pop the stack in front to its first screen - `popToRootViewController`. Inside a tab, that is\n * the tab's first screen; the screens below keep their state. Resolves false at the root already.\n */\n popToRoot(): Promise<boolean> {\n return this.outlets.popToRoot();\n }\n\n private go(\n commands: NavigationCommands,\n options: NativeNavigationOptions,\n intent: NativeIntent,\n written: WrittenPath | null = typeof commands === 'string'\n ? { path: pathOf(commands), outlet: PRIMARY_OUTLET }\n : null,\n ): Promise<boolean> {\n const { presentation, state, ...extras } = options;\n const full: NativeIntent = presentation\n ? { ...intent, presentation: arrivingAs(intent, { ...intent.presentation, ...presentation }) }\n : intent;\n\n const navigate = () => {\n const list =\n typeof commands === 'string' ? urlCommands(this.router, pathOf(commands)) : [...commands];\n const all = {\n ...extras,\n ...(typeof commands === 'string' ? this.queryOf(commands, extras) : {}),\n state: { ...(state as object), [NATIVE_INTENT]: full },\n };\n const leaving = leavingPresented(this.router, list, all);\n // A parameter the commands could not carry goes back on the tree they make, which is what\n // `navigate` would go to; `navigateByUrl` then takes it as it is.\n if (written && hasCommandKeyParameters(this.router, written.path)) {\n const tree = leaving ?? this.router.createUrlTree(list, all);\n return this.router.navigateByUrl(\n withWrittenParameters(this.router, tree, written.path, written.outlet),\n all,\n );\n }\n return leaving ? this.router.navigateByUrl(leaving, all) : this.router.navigate(list, all);\n };\n // A screen stacked on the first one waits for it. Navigating while the router's first\n // navigation is still running - a lazily loaded root waiting on its import - cancels that\n // navigation, and the app opens on this screen with nothing beneath it. A reset replaces the\n // stack anyway, so it goes at once.\n const start = () => this.underTabRoot(commands, extras, full, navigate);\n return intent.stack !== 'reset' && this.firstNavigationRunning()\n ? this.firstNavigation().then(start)\n : start();\n }\n\n /**\n * A push to a page of a tab bar that a screen over it covers, pushed on the app's own stack or\n * presented, goes back to the bar first: to its tab, where that was left, and then pushes the\n * page there unless the tab is already showing it. One tab bar, as a native app has. Pushed as\n * it was asked, the page would build a second bar over the screen.\n *\n * A push into a tab nobody has opened goes to the tab first, so its stack has the tab's own\n * first screen under the page, and a back from the page lands there: what a tab bar with a\n * navigation controller per tab does. Without it the page is the stack's only screen, and the\n * same push leaves a different stack behind depending on whether the tab was ever tapped. A\n * presented screen goes where it is asked, and a replace or a reset has nothing to keep.\n */\n private underTabRoot(\n commands: NavigationCommands,\n extras: NavigationExtras,\n intent: NativeIntent,\n navigate: () => Promise<boolean>,\n ): Promise<boolean> {\n if (intent.stack !== 'push' || intent.presentation) return navigate();\n const path = this.pathFor(commands, extras);\n const left = this.outlets.coveredTabAt(path);\n if (left) {\n // The tab is open once the bar is back, so the page goes straight onto it, unless it is the\n // page the tab was left on and nothing more, a query or a fragment, is asked of it.\n const asked = pathOf(left) !== path || asksMore(commands, extras);\n // A guard that redirects elsewhere still resolves true, so the tab must be in front now.\n return this.router.navigateByUrl(left).then((arrived) => {\n const there =\n arrived && !this.outlets.coveredTabAt(path) && !this.outlets.inTabBehind(path);\n return there && asked ? navigate() : there;\n });\n }\n const tab = this.outlets.unopenedTabOf(path);\n if (!tab) return navigate();\n return this.router\n .navigateByUrl(tab)\n .then((arrived) => (arrived && !this.outlets.unopenedTabOf(path) ? navigate() : false));\n }\n\n /** The path the commands lead to, without its query and fragment. */\n private pathFor(commands: NavigationCommands, extras: NavigationExtras): string {\n if (typeof commands === 'string' && commands.startsWith('/')) return pathOf(commands);\n // Resolved as `go` navigates them: a relative string against `relativeTo`.\n const list =\n typeof commands === 'string' ? urlCommands(this.router, pathOf(commands)) : [...commands];\n return pathOf(this.router.serializeUrl(this.router.createUrlTree(list, extras)));\n }\n\n /**\n * A page of a tab that is not in front, presented over the one that is, or over a screen that\n * covers the bar: its url would select\n * its own tab and show it there, so it goes to the root's presented outlet instead, where the\n * app's own stack shows it over everything. See `presented-route.ts`. Null for a page of the\n * tab in front, or of no tab, which is presented where its url puts it.\n */\n private overTheTabInFront(\n commands: NavigationCommands,\n extras: NavigationExtras,\n ): Promise<{\n commands: unknown[];\n extras: NavigationExtras;\n written: WrittenPath;\n } | null> | null {\n if (!this.outlets.presents) return null;\n const path = this.pathFor(commands, extras);\n // A tab in front of a bar a screen covers is behind that screen just the same.\n if (!this.outlets.inTabBehind(path) && !this.outlets.coveredTabAt(path)) return null;\n const query = typeof commands === 'string' ? this.queryOf(commands, extras) : {};\n return presentedCommands(this.router, path, this.injector).then(\n (presented) =>\n presented && {\n commands: presented,\n extras: { ...extras, ...query, relativeTo: null },\n written: { path, outlet: PRESENTED },\n },\n );\n }\n\n /**\n * The query and fragment written into a url string, as the extras `navigate` takes them: it\n * reads a string command as one path segment, and would encode a `?` into it. Extras given\n * alongside win over the ones in the string.\n */\n private queryOf(url: string, extras: NavigationExtras): NavigationExtras {\n const cut = url.search(/[?#]/);\n if (cut < 0) return {};\n const { queryParams, fragment } = this.router.parseUrl(url.slice(cut));\n return {\n queryParams: { ...queryParams, ...extras.queryParams },\n fragment: extras.fragment ?? fragment ?? undefined,\n };\n }\n\n private firstNavigationRunning(): boolean {\n const router = this.router as Partial<Router>;\n return router.navigated === false && !!router.currentNavigation?.();\n }\n\n private firstNavigation(): Promise<void> {\n return new Promise((resolve) => {\n const events = this.router.events.subscribe((event) => {\n if (ended(event) && !carriesOn(event)) {\n events.unsubscribe();\n resolve();\n }\n });\n });\n }\n}\n\n/**\n * Whether a navigation ended only for another to take its place: a guard's redirect does, and so\n * does a newer navigation. Waiting for a navigation to end goes on past one of these, or what\n * starts next supersedes the redirect and opens with nothing beneath it, past the guard.\n */\nexport function carriesOn(event: unknown): boolean {\n return (\n event instanceof NavigationCancel &&\n (event.code === NavigationCancellationCode.Redirect ||\n event.code === NavigationCancellationCode.SupersededByNewNavigation)\n );\n}\n"]}
@@ -20,7 +20,9 @@
20
20
  * ponytail: react-native-screens has no scope bar and no search tokens; a scope is a segmented
21
21
  * control under the header, and a token is text. Nor has its search bar a font prop on iOS or
22
22
  * Android, so the field and placeholder stay in the system font; `<search-field>` from
23
- * `@ng-native/expo/search-field` takes the font its CSS resolves to.
23
+ * `@ng-native/expo/search-field` takes the font its CSS resolves to. On iOS 27 the field is white
24
+ * glass where SwiftUI's `.searchable` draws flat grey, and neither UIKit nor react-native-screens
25
+ * has a public switch for that material.
24
26
  */
25
27
  import { Component, DestroyRef, ElementRef, afterRenderEffect, inject, input, model, output, untracked, } from '@angular/core';
26
28
  import { HostEngine } from '@ng-native/fabric';
@@ -1 +1 @@
1
- {"version":3,"file":"native-search-bar.js","sourceRoot":"","sources":["../src/native-search-bar.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The navigation bar's search field: react-native-screens' `RNSSearchBar`, the UISearchController\n * iOS puts under a large title. Place it in the header's search slot:\n *\n * ```html\n * <native-header title=\"Properties\" [largeTitle]=\"true\">\n * <native-header-item type=\"searchBar\">\n * <native-search-bar placeholder=\"Search\" [(query)]=\"query\" />\n * </native-header-item>\n * </native-header>\n * ```\n *\n * The text is a two-way `query`: what a list filter wants. Typing updates it, and a query set from\n * code - a recent search tapped, a suggestion taken - is put in the field, as a controlled text\n * input's value is. `(search)` is the keyboard's search key, with the text; `(cancel)` the Cancel\n * button; `(searchFocus)` and `(searchBlur)` the field taking and leaving the keyboard, which is when\n * a suggestions list comes and goes. `focus()`, `blur()`, `clear()` and `cancelSearch()` do those\n * from code.\n *\n * ponytail: react-native-screens has no scope bar and no search tokens; a scope is a segmented\n * control under the header, and a token is text. Nor has its search bar a font prop on iOS or\n * Android, so the field and placeholder stay in the system font; `<search-field>` from\n * `@ng-native/expo/search-field` takes the font its CSS resolves to.\n */\nimport {\n Component,\n DestroyRef,\n ElementRef,\n afterRenderEffect,\n inject,\n input,\n model,\n output,\n untracked,\n} from '@angular/core';\nimport { type EngineNode, HostEngine, type NativeSyntheticEvent } from '@ng-native/fabric';\nimport { ownHost } from './own-host.ts';\nimport { optionalBoolean } from './transforms.ts';\n\n/** react-native-screens' placements for the navigation bar's search field. */\nexport type SearchBarPlacement =\n 'automatic' | 'inline' | 'stacked' | 'integrated' | 'integratedButton' | 'integratedCentered';\n\n@Component({\n selector: 'native-search-bar',\n template: '',\n host: {\n '[placeholder]': 'placeholder()',\n '[hideWhenScrolling]': 'hideWhenScrolling()',\n '[cancelButtonText]': 'cancelButtonText()',\n '[placement]': 'placement()',\n '[allowToolbarIntegration]': 'allowToolbarIntegration()',\n '[autoCapitalize]': 'autoCapitalize()',\n '[obscureBackground]':\n 'obscureBackground() === undefined ? undefined : String(obscureBackground())',\n '[hideNavigationBar]':\n 'hideNavigationBar() === undefined ? undefined : String(hideNavigationBar())',\n '[tintColor]': 'tintColor()',\n '[textColor]': 'textColor()',\n '(changeText)': 'onNativeText($event?.nativeEvent?.text ?? \"\")',\n },\n})\nexport class NativeSearchBar {\n readonly query = model('');\n readonly placeholder = input<string>();\n /** Scroll the field away with the content, as iOS lists do by default. */\n readonly hideWhenScrolling = input(undefined, { transform: optionalBoolean });\n readonly cancelButtonText = input<string>();\n /**\n * Where iOS puts the field. `automatic` lets iOS 26 fold it into a toolbar, which a presented\n * sheet does not have, so there it shows nowhere; `stacked` keeps it under the title.\n */\n readonly placement = input<SearchBarPlacement>();\n /** iOS 26: whether `automatic` may move the field into the toolbar. */\n readonly allowToolbarIntegration = input(undefined, { transform: optionalBoolean });\n readonly autoCapitalize = input<\n 'systemDefault' | 'none' | 'words' | 'sentences' | 'characters'\n >();\n /** Dim the content behind the field while it is being typed in. */\n readonly obscureBackground = input(undefined, { transform: optionalBoolean });\n /** Hide the navigation bar while the field is being typed in. */\n readonly hideNavigationBar = input(undefined, { transform: optionalBoolean });\n /** iOS: the cursor and the Cancel button. Android: the field's background. */\n readonly tintColor = input<string>();\n /** The typed text. */\n readonly textColor = input<string>();\n\n /** The keyboard's search key was pressed, with the text in the field. */\n readonly search = output<string>();\n /** The Cancel button was pressed. */\n readonly cancel = output<void>();\n readonly searchFocus = output<void>();\n readonly searchBlur = output<void>();\n\n private readonly node = inject(ElementRef).nativeElement as EngineNode;\n private readonly engine = this.node.engine ?? inject(HostEngine);\n /** What the field last said it holds, to tell a query set from code from the field's echo. */\n private fieldText = '';\n\n constructor() {\n ownHost(this.node, NativeSearchBar);\n const listen = (event: string, handle: (payload: Record<string, unknown>) => void) =>\n this.engine.setEventListener(this.node, event, (raw) =>\n handle((raw as NativeSyntheticEvent<Record<string, unknown>>)?.nativeEvent ?? {}),\n );\n const stops = [\n listen('topSearchButtonPress', ({ text }) => this.search.emit(String(text ?? this.query()))),\n listen('topCancelButtonPress', () => this.cancel.emit()),\n listen('topSearchFocus', () => this.searchFocus.emit()),\n listen('topSearchBlur', () => this.searchBlur.emit()),\n ];\n inject(DestroyRef).onDestroy(() => stops.forEach((stop) => stop()));\n // A query that is not what the field holds was set from code: put it in the field. After the\n // render, so a query the page starts with reaches a field that has been committed.\n afterRenderEffect({\n write: () => {\n const query = this.query();\n untracked(() => {\n if (query === this.fieldText) return;\n this.fieldText = query;\n this.engine.dispatchCommand(this.node, 'setText', [query]);\n });\n },\n });\n }\n\n focus(): void {\n this.engine.dispatchCommand(this.node, 'focus');\n }\n\n blur(): void {\n this.engine.dispatchCommand(this.node, 'blur');\n }\n\n /** Empty the field, and the query with it. */\n clear(): void {\n this.fieldText = '';\n this.query.set('');\n this.engine.dispatchCommand(this.node, 'clearText');\n }\n\n /** Close the search, as the Cancel button does. */\n cancelSearch(): void {\n this.engine.dispatchCommand(this.node, 'cancelSearch');\n }\n\n protected onNativeText(text: string): void {\n this.fieldText = text;\n this.query.set(text);\n }\n}\n"]}
1
+ {"version":3,"file":"native-search-bar.js","sourceRoot":"","sources":["../src/native-search-bar.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The navigation bar's search field: react-native-screens' `RNSSearchBar`, the UISearchController\n * iOS puts under a large title. Place it in the header's search slot:\n *\n * ```html\n * <native-header title=\"Properties\" [largeTitle]=\"true\">\n * <native-header-item type=\"searchBar\">\n * <native-search-bar placeholder=\"Search\" [(query)]=\"query\" />\n * </native-header-item>\n * </native-header>\n * ```\n *\n * The text is a two-way `query`: what a list filter wants. Typing updates it, and a query set from\n * code - a recent search tapped, a suggestion taken - is put in the field, as a controlled text\n * input's value is. `(search)` is the keyboard's search key, with the text; `(cancel)` the Cancel\n * button; `(searchFocus)` and `(searchBlur)` the field taking and leaving the keyboard, which is when\n * a suggestions list comes and goes. `focus()`, `blur()`, `clear()` and `cancelSearch()` do those\n * from code.\n *\n * ponytail: react-native-screens has no scope bar and no search tokens; a scope is a segmented\n * control under the header, and a token is text. Nor has its search bar a font prop on iOS or\n * Android, so the field and placeholder stay in the system font; `<search-field>` from\n * `@ng-native/expo/search-field` takes the font its CSS resolves to. On iOS 27 the field is white\n * glass where SwiftUI's `.searchable` draws flat grey, and neither UIKit nor react-native-screens\n * has a public switch for that material.\n */\nimport {\n Component,\n DestroyRef,\n ElementRef,\n afterRenderEffect,\n inject,\n input,\n model,\n output,\n untracked,\n} from '@angular/core';\nimport { type EngineNode, HostEngine, type NativeSyntheticEvent } from '@ng-native/fabric';\nimport { ownHost } from './own-host.ts';\nimport { optionalBoolean } from './transforms.ts';\n\n/** react-native-screens' placements for the navigation bar's search field. */\nexport type SearchBarPlacement =\n 'automatic' | 'inline' | 'stacked' | 'integrated' | 'integratedButton' | 'integratedCentered';\n\n@Component({\n selector: 'native-search-bar',\n template: '',\n host: {\n '[placeholder]': 'placeholder()',\n '[hideWhenScrolling]': 'hideWhenScrolling()',\n '[cancelButtonText]': 'cancelButtonText()',\n '[placement]': 'placement()',\n '[allowToolbarIntegration]': 'allowToolbarIntegration()',\n '[autoCapitalize]': 'autoCapitalize()',\n '[obscureBackground]':\n 'obscureBackground() === undefined ? undefined : String(obscureBackground())',\n '[hideNavigationBar]':\n 'hideNavigationBar() === undefined ? undefined : String(hideNavigationBar())',\n '[tintColor]': 'tintColor()',\n '[textColor]': 'textColor()',\n '(changeText)': 'onNativeText($event?.nativeEvent?.text ?? \"\")',\n },\n})\nexport class NativeSearchBar {\n readonly query = model('');\n readonly placeholder = input<string>();\n /** Scroll the field away with the content, as iOS lists do by default. */\n readonly hideWhenScrolling = input(undefined, { transform: optionalBoolean });\n readonly cancelButtonText = input<string>();\n /**\n * Where iOS puts the field. `automatic` lets iOS 26 fold it into a toolbar, which a presented\n * sheet does not have, so there it shows nowhere; `stacked` keeps it under the title.\n */\n readonly placement = input<SearchBarPlacement>();\n /** iOS 26: whether `automatic` may move the field into the toolbar. */\n readonly allowToolbarIntegration = input(undefined, { transform: optionalBoolean });\n readonly autoCapitalize = input<\n 'systemDefault' | 'none' | 'words' | 'sentences' | 'characters'\n >();\n /** Dim the content behind the field while it is being typed in. */\n readonly obscureBackground = input(undefined, { transform: optionalBoolean });\n /** Hide the navigation bar while the field is being typed in. */\n readonly hideNavigationBar = input(undefined, { transform: optionalBoolean });\n /** iOS: the cursor and the Cancel button. Android: the field's background. */\n readonly tintColor = input<string>();\n /** The typed text. */\n readonly textColor = input<string>();\n\n /** The keyboard's search key was pressed, with the text in the field. */\n readonly search = output<string>();\n /** The Cancel button was pressed. */\n readonly cancel = output<void>();\n readonly searchFocus = output<void>();\n readonly searchBlur = output<void>();\n\n private readonly node = inject(ElementRef).nativeElement as EngineNode;\n private readonly engine = this.node.engine ?? inject(HostEngine);\n /** What the field last said it holds, to tell a query set from code from the field's echo. */\n private fieldText = '';\n\n constructor() {\n ownHost(this.node, NativeSearchBar);\n const listen = (event: string, handle: (payload: Record<string, unknown>) => void) =>\n this.engine.setEventListener(this.node, event, (raw) =>\n handle((raw as NativeSyntheticEvent<Record<string, unknown>>)?.nativeEvent ?? {}),\n );\n const stops = [\n listen('topSearchButtonPress', ({ text }) => this.search.emit(String(text ?? this.query()))),\n listen('topCancelButtonPress', () => this.cancel.emit()),\n listen('topSearchFocus', () => this.searchFocus.emit()),\n listen('topSearchBlur', () => this.searchBlur.emit()),\n ];\n inject(DestroyRef).onDestroy(() => stops.forEach((stop) => stop()));\n // A query that is not what the field holds was set from code: put it in the field. After the\n // render, so a query the page starts with reaches a field that has been committed.\n afterRenderEffect({\n write: () => {\n const query = this.query();\n untracked(() => {\n if (query === this.fieldText) return;\n this.fieldText = query;\n this.engine.dispatchCommand(this.node, 'setText', [query]);\n });\n },\n });\n }\n\n focus(): void {\n this.engine.dispatchCommand(this.node, 'focus');\n }\n\n blur(): void {\n this.engine.dispatchCommand(this.node, 'blur');\n }\n\n /** Empty the field, and the query with it. */\n clear(): void {\n this.fieldText = '';\n this.query.set('');\n this.engine.dispatchCommand(this.node, 'clearText');\n }\n\n /** Close the search, as the Cancel button does. */\n cancelSearch(): void {\n this.engine.dispatchCommand(this.node, 'cancelSearch');\n }\n\n protected onNativeText(text: string): void {\n this.fieldText = text;\n this.query.set(text);\n }\n}\n"]}
@@ -243,21 +243,21 @@ export declare class NativeStackOutlet implements RouterOutletContract, OnInit {
243
243
  */
244
244
  private fillScreen;
245
245
  /**
246
- * On iOS 26 and later, the view a page's content commits in, as react-native-screens'
247
- * `ScreenStackItem` wraps it in its `SafeAreaView` there. From 4.30 the screen runs under the
248
- * navigation bar whether the bar is opaque or not
246
+ * On iOS 26 and later, have the screen commit a page's content in a `SafeAreaView`
247
+ * (`RNSSafeAreaView`), as react-native-screens' `ScreenStackItem` wraps it there. From 4.30 the
248
+ * screen runs under the navigation bar whether the bar is opaque or not
249
249
  * (`+[RNSScreenStackHeaderConfig screensExtendUnderOpaqueNavigationBar]`), and this view insets
250
250
  * the content below an opaque one. Before 4.30 the screen starts below such a bar, its safe area
251
- * is zero at the top, and the view insets by nothing. Null elsewhere: the content commits
252
- * straight into the screen.
251
+ * is zero at the top, and the view insets by nothing. The engine makes the view
252
+ * (`wrapChildren`), so the page's template stays in its host, the screen, for its `:host`
253
+ * style and selectors, and the header stays a child of the screen.
254
+ *
255
+ * It insets the top edge while the page's header is shown and not translucent, which a large
256
+ * title on iOS is, and no edge otherwise, as `getSafeAreaEdges` in `ScreenStackItem` chooses.
257
+ * The view stays when the header changes, so the content is not made again. The effect runs in
258
+ * the page's first change detection, before anything of it is committed.
253
259
  */
254
260
  private insetContent;
255
- /**
256
- * The top edge while the page's header is shown and not translucent, which a large title on iOS
257
- * is, and no edge otherwise, as `getSafeAreaEdges` in `ScreenStackItem` chooses. The view stays
258
- * when the header changes, so the content is not made again. Native takes all four edges.
259
- */
260
- private followHeader;
261
261
  private createScreen;
262
262
  /**
263
263
  * Puts the app's status bar and navigation bar claims on a screen that has no value of its own
@@ -147,6 +147,9 @@ export class NativeStackOutlet {
147
147
  this.remove(entry);
148
148
  return true;
149
149
  },
150
+ top: () => this.activatedRoute,
151
+ fullScreen: () => this.entries.find((entry) => entry.presentation?.stackPresentation === 'fullScreenModal')
152
+ ?.route ?? null,
150
153
  });
151
154
  // Optional for the same reason as the router: the outlet's own tests stand one in without it.
152
155
  const navigations = this.router?.events?.subscribe((event) => {
@@ -398,7 +401,6 @@ export class NativeStackOutlet {
398
401
  let unbind;
399
402
  const header = signal(false, /* @ts-ignore */
400
403
  ...(ngDevMode ? [{ debugName: "header" }] : /* istanbul ignore next */ []));
401
- const content = this.insetContent(screen);
402
404
  try {
403
405
  ref = createComponent(component, {
404
406
  environmentInjector,
@@ -406,8 +408,8 @@ export class NativeStackOutlet {
406
408
  hostElement: screen,
407
409
  });
408
410
  this.applicationRef.attachView(ref.hostView);
409
- if (content)
410
- this.followHeader(content, header, ref.injector);
411
+ if (this.underBar)
412
+ this.insetContent(screen, header, ref.injector);
411
413
  // Route params onto inputs before the first change detection, not after: a required input
412
414
  // read in the template throws NG0950 if it is still unset when the page first renders.
413
415
  unbind = this.bindInputs(ref, route);
@@ -781,33 +783,27 @@ export class NativeStackOutlet {
781
783
  }
782
784
  }
783
785
  /**
784
- * On iOS 26 and later, the view a page's content commits in, as react-native-screens'
785
- * `ScreenStackItem` wraps it in its `SafeAreaView` there. From 4.30 the screen runs under the
786
- * navigation bar whether the bar is opaque or not
786
+ * On iOS 26 and later, have the screen commit a page's content in a `SafeAreaView`
787
+ * (`RNSSafeAreaView`), as react-native-screens' `ScreenStackItem` wraps it there. From 4.30 the
788
+ * screen runs under the navigation bar whether the bar is opaque or not
787
789
  * (`+[RNSScreenStackHeaderConfig screensExtendUnderOpaqueNavigationBar]`), and this view insets
788
790
  * the content below an opaque one. Before 4.30 the screen starts below such a bar, its safe area
789
- * is zero at the top, and the view insets by nothing. Null elsewhere: the content commits
790
- * straight into the screen.
791
- */
792
- insetContent(screen) {
793
- if (!this.underBar)
794
- return null;
795
- const content = ownHost(this.renderer.createElement('screen-content'));
796
- this.renderer.appendChild(screen, content);
797
- screen.contentView = content;
798
- return content;
799
- }
800
- /**
801
- * The top edge while the page's header is shown and not translucent, which a large title on iOS
802
- * is, and no edge otherwise, as `getSafeAreaEdges` in `ScreenStackItem` chooses. The view stays
803
- * when the header changes, so the content is not made again. Native takes all four edges.
791
+ * is zero at the top, and the view insets by nothing. The engine makes the view
792
+ * (`wrapChildren`), so the page's template stays in its host, the screen, for its `:host`
793
+ * style and selectors, and the header stays a child of the screen.
794
+ *
795
+ * It insets the top edge while the page's header is shown and not translucent, which a large
796
+ * title on iOS is, and no edge otherwise, as `getSafeAreaEdges` in `ScreenStackItem` chooses.
797
+ * The view stays when the header changes, so the content is not made again. The effect runs in
798
+ * the page's first change detection, before anything of it is committed.
804
799
  */
805
- followHeader(content, header, injector) {
806
- effect(() => this.renderer.setProperty(content, 'edges', {
807
- top: header(),
808
- right: false,
809
- bottom: false,
810
- left: false,
800
+ insetContent(screen, header, injector) {
801
+ const node = screen;
802
+ const engine = node.engine;
803
+ effect(() => engine.wrapChildren(node, {
804
+ viewName: 'RNSSafeAreaView',
805
+ // The fill is `SafeAreaView.tsx`'s. Native takes all four edges.
806
+ props: { flex: 1, edges: { top: header(), right: false, bottom: false, left: false } },
811
807
  }), { injector });
812
808
  }
813
809
  createScreen(presentation, dismissed = (count) => this.onNativeDismiss(count)) {