@ng-native/router 0.4.0 → 0.5.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.
package/dist/index.d.ts CHANGED
@@ -18,6 +18,7 @@ export { NativeSearchBar, type SearchBarPlacement } from './native-search-bar.ts
18
18
  export { NativeStackOutlet } from './native-stack-outlet.ts';
19
19
  export { NativeTab, type TabAppearance, type TabBarBlurEffect, type TabIcon, type TabIconProps, type TabItemAppearance, type TabStateAppearance, type TabSystemItem, } from './native-tab.ts';
20
20
  export { NativeTabsOutlet } from './native-tabs-outlet.ts';
21
+ export { ScreenSafeAreaView, type ScreenSafeAreaEdge } from './screen-safe-area-view.ts';
21
22
  export { TabSafeAreaView, type TabSafeAreaEdge } from './tab-safe-area-view.ts';
22
23
  export { NativeStackReuseStrategy, reuseScreen } from './native-stack-reuse-strategy.ts';
23
24
  export { provideNativeRouter, withHeaderDefaults, withLinkParent, withTabDefaults, type NativeRouterFeature, } from './provide-native-router.ts';
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ export { NativeSearchBar } from "./native-search-bar.js";
18
18
  export { NativeStackOutlet } from "./native-stack-outlet.js";
19
19
  export { NativeTab, } from "./native-tab.js";
20
20
  export { NativeTabsOutlet } from "./native-tabs-outlet.js";
21
+ export { ScreenSafeAreaView } from "./screen-safe-area-view.js";
21
22
  export { TabSafeAreaView } from "./tab-safe-area-view.js";
22
23
  export { NativeStackReuseStrategy, reuseScreen } from "./native-stack-reuse-strategy.js";
23
24
  export { provideNativeRouter, withHeaderDefaults, withLinkParent, withTabDefaults, } from "./provide-native-router.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAmB,MAAM,mBAAmB,CAAC;AAChE,OAAO,EACL,gBAAgB,GAIjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,sBAAsB,EAAmB,MAAM,+BAA+B,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EACL,sBAAsB,EACtB,mBAAmB,GAIpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,YAAY,GAKb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GAEtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAuB,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,eAAe,EAA2B,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EACL,SAAS,GAQV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAwB,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACzF,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,eAAe,GAEhB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAON,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAA2B,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC","sourcesContent":["/**\n * `@angular/router` on a native stack: the outlet that maps activated routes onto `RNSScreen`,\n * the `PlatformLocation` that stands in for the browser's history, and the reuse strategy that\n * keeps a popped screen's component alive while it animates out.\n *\n * Two of these are decorated, so the same caveat as the components barrel applies: a Node test\n * reaches the source file, not this.\n */\nexport { followLink, type LinkParent } from './native-links.ts';\nexport {\n NativeNavigation,\n type NativeNavigationOptions,\n type NavigationCommands,\n type PresentOptions,\n} from './native-navigation.ts';\nexport { NativePlatformLocation, type LinkSource } from './native-platform-location.ts';\nexport { NativeRouterLink } from './native-router-link.ts';\nexport {\n NATIVE_HEADER_DEFAULTS,\n NATIVE_TAB_DEFAULTS,\n type HeaderDefaults,\n type SchemeDefaults,\n type TabDefaults,\n} from './native-bar-defaults.ts';\nexport {\n NativeHeader,\n type BackButtonDisplayMode,\n type BlurEffect,\n type HeaderDirection,\n type HeaderInterfaceStyle,\n} from './native-header.ts';\nexport {\n DEFAULT_HEADER_PALETTE,\n NATIVE_HEADER_PALETTE,\n type HeaderColors,\n} from './native-header-palette.ts';\nexport { NativeHeaderItem, type HeaderItemType } from './native-header-item.ts';\nexport { NativeSearchBar, type SearchBarPlacement } from './native-search-bar.ts';\nexport { NativeStackOutlet } from './native-stack-outlet.ts';\nexport {\n NativeTab,\n type TabAppearance,\n type TabBarBlurEffect,\n type TabIcon,\n type TabIconProps,\n type TabItemAppearance,\n type TabStateAppearance,\n type TabSystemItem,\n} from './native-tab.ts';\nexport { NativeTabsOutlet } from './native-tabs-outlet.ts';\nexport { TabSafeAreaView, type TabSafeAreaEdge } from './tab-safe-area-view.ts';\nexport { NativeStackReuseStrategy, reuseScreen } from './native-stack-reuse-strategy.ts';\nexport {\n provideNativeRouter,\n withHeaderDefaults,\n withLinkParent,\n withTabDefaults,\n type NativeRouterFeature,\n} from './provide-native-router.ts';\nexport {\n type GestureResponseDistance,\n type ReplaceAnimation,\n type ScreenPresentation,\n type StackAnimation,\n type StackPresentation,\n type SwipeDirection,\n} from './screen-presentation.ts';\nexport { ActivityState, type ActivityStateValue } from './screens.ts';\nexport { FullWindowOverlay } from './full-window-overlay.ts';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAmB,MAAM,mBAAmB,CAAC;AAChE,OAAO,EACL,gBAAgB,GAIjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,sBAAsB,EAAmB,MAAM,+BAA+B,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EACL,sBAAsB,EACtB,mBAAmB,GAIpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,YAAY,GAKb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GAEtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAuB,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,eAAe,EAA2B,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EACL,SAAS,GAQV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAA2B,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,eAAe,EAAwB,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACzF,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,eAAe,GAEhB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAON,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAA2B,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC","sourcesContent":["/**\n * `@angular/router` on a native stack: the outlet that maps activated routes onto `RNSScreen`,\n * the `PlatformLocation` that stands in for the browser's history, and the reuse strategy that\n * keeps a popped screen's component alive while it animates out.\n *\n * Two of these are decorated, so the same caveat as the components barrel applies: a Node test\n * reaches the source file, not this.\n */\nexport { followLink, type LinkParent } from './native-links.ts';\nexport {\n NativeNavigation,\n type NativeNavigationOptions,\n type NavigationCommands,\n type PresentOptions,\n} from './native-navigation.ts';\nexport { NativePlatformLocation, type LinkSource } from './native-platform-location.ts';\nexport { NativeRouterLink } from './native-router-link.ts';\nexport {\n NATIVE_HEADER_DEFAULTS,\n NATIVE_TAB_DEFAULTS,\n type HeaderDefaults,\n type SchemeDefaults,\n type TabDefaults,\n} from './native-bar-defaults.ts';\nexport {\n NativeHeader,\n type BackButtonDisplayMode,\n type BlurEffect,\n type HeaderDirection,\n type HeaderInterfaceStyle,\n} from './native-header.ts';\nexport {\n DEFAULT_HEADER_PALETTE,\n NATIVE_HEADER_PALETTE,\n type HeaderColors,\n} from './native-header-palette.ts';\nexport { NativeHeaderItem, type HeaderItemType } from './native-header-item.ts';\nexport { NativeSearchBar, type SearchBarPlacement } from './native-search-bar.ts';\nexport { NativeStackOutlet } from './native-stack-outlet.ts';\nexport {\n NativeTab,\n type TabAppearance,\n type TabBarBlurEffect,\n type TabIcon,\n type TabIconProps,\n type TabItemAppearance,\n type TabStateAppearance,\n type TabSystemItem,\n} from './native-tab.ts';\nexport { NativeTabsOutlet } from './native-tabs-outlet.ts';\nexport { ScreenSafeAreaView, type ScreenSafeAreaEdge } from './screen-safe-area-view.ts';\nexport { TabSafeAreaView, type TabSafeAreaEdge } from './tab-safe-area-view.ts';\nexport { NativeStackReuseStrategy, reuseScreen } from './native-stack-reuse-strategy.ts';\nexport {\n provideNativeRouter,\n withHeaderDefaults,\n withLinkParent,\n withTabDefaults,\n type NativeRouterFeature,\n} from './provide-native-router.ts';\nexport {\n type GestureResponseDistance,\n type ReplaceAnimation,\n type ScreenPresentation,\n type StackAnimation,\n type StackPresentation,\n type SwipeDirection,\n} from './screen-presentation.ts';\nexport { ActivityState, type ActivityStateValue } from './screens.ts';\nexport { FullWindowOverlay } from './full-window-overlay.ts';\n"]}
@@ -12,6 +12,8 @@ export declare class NativeHeader {
12
12
  private readonly palette;
13
13
  /** The app's `withHeaderDefaults`, for whatever this header does not bind itself. */
14
14
  protected readonly defaults: import("@angular/core").Signal<import("./native-bar-defaults.ts").HeaderDefaults>;
15
+ /** Told whether this is a bar the page starts below. See `screen-header.ts`. */
16
+ private readonly above;
15
17
  constructor();
16
18
  /**
17
19
  * The palette for the scheme the app is wearing, for whichever colours were not bound.
@@ -41,6 +43,8 @@ export declare class NativeHeader {
41
43
  * iOS 26 the large title sits in the scroll view, above its content, where a bar with a
42
44
  * background paints over it; and over an opaque bar the inline title never fades in.
43
45
  */
46
+ /** Whether the page runs under the bar rather than starting below it. */
47
+ protected readonly isTranslucent: import("@angular/core").Signal<boolean | undefined>;
44
48
  protected readonly iosLargeTitle: import("@angular/core").Signal<true | undefined>;
45
49
  protected readonly resolvedLargeTitleBackgroundColor: import("@angular/core").Signal<string | number | undefined>;
46
50
  /** The bar's title. Absent leaves whatever the platform would show, which is nothing. */
@@ -25,12 +25,12 @@
25
25
  * `headerRightBarButtonItems` are deliberately absent: native bar button items are data rather
26
26
  * than views, and they are a later opt-in rather than the primary API.
27
27
  */
28
- import { Component, computed, input } from '@angular/core';
29
- import { ElementRef, inject } from '@angular/core';
28
+ import { Component, DestroyRef, ElementRef, computed, effect, inject, input } from '@angular/core';
30
29
  import { ColorScheme, OS_VERSION } from '@ng-native/device';
31
30
  import { NATIVE_HEADER_DEFAULTS } from "./native-bar-defaults.js";
32
31
  import { NATIVE_HEADER_PALETTE } from "./native-header-palette.js";
33
32
  import { ownHost } from "./own-host.js";
33
+ import { SCREEN_HEADER } from "./screen-header.js";
34
34
  import { nativePlatform } from '@ng-native/fabric';
35
35
  import { optionalBoolean, optionalNumber } from "./transforms.js";
36
36
  import * as i0 from "@angular/core";
@@ -39,8 +39,15 @@ export class NativeHeader {
39
39
  palette = inject(NATIVE_HEADER_PALETTE);
40
40
  /** The app's `withHeaderDefaults`, for whatever this header does not bind itself. */
41
41
  defaults = inject(NATIVE_HEADER_DEFAULTS);
42
+ /** Told whether this is a bar the page starts below. See `screen-header.ts`. */
43
+ above = inject(SCREEN_HEADER, { optional: true });
42
44
  constructor() {
43
45
  ownHost(inject(ElementRef).nativeElement, this.constructor);
46
+ const above = this.above;
47
+ if (!above)
48
+ return;
49
+ effect(() => above.set(!this.hidden() && !this.isTranslucent()));
50
+ inject(DestroyRef).onDestroy(() => above.set(false));
44
51
  }
45
52
  /**
46
53
  * The palette for the scheme the app is wearing, for whichever colours were not bound.
@@ -82,6 +89,12 @@ export class NativeHeader {
82
89
  * iOS 26 the large title sits in the scroll view, above its content, where a bar with a
83
90
  * background paints over it; and over an opaque bar the inline title never fades in.
84
91
  */
92
+ /** Whether the page runs under the bar rather than starting below it. */
93
+ isTranslucent = computed(() => this.translucent() ??
94
+ this.defaults().translucent ??
95
+ this.iosLargeTitle() ??
96
+ this.isLiquidGlass(), /* @ts-ignore */
97
+ ...(ngDevMode ? [{ debugName: "isTranslucent" }] : /* istanbul ignore next */ []));
85
98
  iosLargeTitle = computed(() => this.largeTitle() && nativePlatform() === 'ios' ? true : undefined, /* @ts-ignore */
86
99
  ...(ngDevMode ? [{ debugName: "iosLargeTitle" }] : /* istanbul ignore next */ []));
87
100
  resolvedLargeTitleBackgroundColor = computed(() => this.largeTitleBackgroundColor() ??
@@ -181,7 +194,7 @@ export class NativeHeader {
181
194
  consumeRightInset = input(undefined, { ...(ngDevMode ? { debugName: "consumeRightInset" } : /* istanbul ignore next */ {}), transform: optionalBoolean });
182
195
  consumeBottomInset = input(undefined, { ...(ngDevMode ? { debugName: "consumeBottomInset" } : /* istanbul ignore next */ {}), transform: optionalBoolean });
183
196
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: NativeHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
184
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.2.0", type: NativeHeader, isStandalone: true, selector: "native-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, titleColor: { classPropertyName: "titleColor", publicName: "titleColor", isSignal: true, isRequired: false, transformFunction: null }, titleFontFamily: { classPropertyName: "titleFontFamily", publicName: "titleFontFamily", isSignal: true, isRequired: false, transformFunction: null }, titleFontSize: { classPropertyName: "titleFontSize", publicName: "titleFontSize", isSignal: true, isRequired: false, transformFunction: null }, titleFontWeight: { classPropertyName: "titleFontWeight", publicName: "titleFontWeight", isSignal: true, isRequired: false, transformFunction: null }, liquidGlass: { classPropertyName: "liquidGlass", publicName: "liquidGlass", isSignal: true, isRequired: false, transformFunction: null }, backgroundColor: { classPropertyName: "backgroundColor", publicName: "backgroundColor", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, blurEffect: { classPropertyName: "blurEffect", publicName: "blurEffect", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null }, hideShadow: { classPropertyName: "hideShadow", publicName: "hideShadow", isSignal: true, isRequired: false, transformFunction: null }, translucent: { classPropertyName: "translucent", publicName: "translucent", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, topInsetEnabled: { classPropertyName: "topInsetEnabled", publicName: "topInsetEnabled", isSignal: true, isRequired: false, transformFunction: null }, userInterfaceStyle: { classPropertyName: "userInterfaceStyle", publicName: "userInterfaceStyle", isSignal: true, isRequired: false, transformFunction: null }, largeTitle: { classPropertyName: "largeTitle", publicName: "largeTitle", isSignal: true, isRequired: false, transformFunction: null }, largeTitleColor: { classPropertyName: "largeTitleColor", publicName: "largeTitleColor", isSignal: true, isRequired: false, transformFunction: null }, largeTitleBackgroundColor: { classPropertyName: "largeTitleBackgroundColor", publicName: "largeTitleBackgroundColor", isSignal: true, isRequired: false, transformFunction: null }, largeTitleFontFamily: { classPropertyName: "largeTitleFontFamily", publicName: "largeTitleFontFamily", isSignal: true, isRequired: false, transformFunction: null }, largeTitleFontSize: { classPropertyName: "largeTitleFontSize", publicName: "largeTitleFontSize", isSignal: true, isRequired: false, transformFunction: null }, largeTitleFontWeight: { classPropertyName: "largeTitleFontWeight", publicName: "largeTitleFontWeight", isSignal: true, isRequired: false, transformFunction: null }, largeTitleHideShadow: { classPropertyName: "largeTitleHideShadow", publicName: "largeTitleHideShadow", isSignal: true, isRequired: false, transformFunction: null }, backTitle: { classPropertyName: "backTitle", publicName: "backTitle", isSignal: true, isRequired: false, transformFunction: null }, backTitleFontFamily: { classPropertyName: "backTitleFontFamily", publicName: "backTitleFontFamily", isSignal: true, isRequired: false, transformFunction: null }, backTitleFontSize: { classPropertyName: "backTitleFontSize", publicName: "backTitleFontSize", isSignal: true, isRequired: false, transformFunction: null }, backTitleVisible: { classPropertyName: "backTitleVisible", publicName: "backTitleVisible", isSignal: true, isRequired: false, transformFunction: null }, backButtonDisplayMode: { classPropertyName: "backButtonDisplayMode", publicName: "backButtonDisplayMode", isSignal: true, isRequired: false, transformFunction: null }, backButtonInCustomView: { classPropertyName: "backButtonInCustomView", publicName: "backButtonInCustomView", isSignal: true, isRequired: false, transformFunction: null }, disableBackButtonMenu: { classPropertyName: "disableBackButtonMenu", publicName: "disableBackButtonMenu", isSignal: true, isRequired: false, transformFunction: null }, hideBackButton: { classPropertyName: "hideBackButton", publicName: "hideBackButton", isSignal: true, isRequired: false, transformFunction: null }, consumeTopInset: { classPropertyName: "consumeTopInset", publicName: "consumeTopInset", isSignal: true, isRequired: false, transformFunction: null }, consumeLeftInset: { classPropertyName: "consumeLeftInset", publicName: "consumeLeftInset", isSignal: true, isRequired: false, transformFunction: null }, consumeRightInset: { classPropertyName: "consumeRightInset", publicName: "consumeRightInset", isSignal: true, isRequired: false, transformFunction: null }, consumeBottomInset: { classPropertyName: "consumeBottomInset", publicName: "consumeBottomInset", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "title": "title()", "titleColor": "resolvedTitleColor()", "titleFontFamily": "titleFontFamily() ?? defaults().titleFontFamily", "titleFontSize": "titleFontSize() ?? defaults().titleFontSize", "titleFontWeight": "titleFontWeight() ?? defaults().titleFontWeight", "backgroundColor": "resolvedBackgroundColor()", "color": "resolvedColor()", "blurEffect": "blurEffect() ?? defaults().blurEffect", "hidden": "hidden()", "hideShadow": "hideShadow() ?? defaults().hideShadow ?? isLiquidGlass()", "translucent": "translucent() ?? defaults().translucent ?? iosLargeTitle() ?? isLiquidGlass()", "direction": "direction()", "topInsetEnabled": "topInsetEnabled()", "userInterfaceStyle": "userInterfaceStyle() ?? defaults().userInterfaceStyle", "largeTitle": "largeTitle()", "largeTitleColor": "largeTitleColor() ?? defaults().largeTitleColor", "largeTitleBackgroundColor": "resolvedLargeTitleBackgroundColor()", "largeTitleFontFamily": "largeTitleFontFamily() ?? defaults().largeTitleFontFamily", "largeTitleFontSize": "largeTitleFontSize() ?? defaults().largeTitleFontSize", "largeTitleFontWeight": "largeTitleFontWeight() ?? defaults().largeTitleFontWeight", "largeTitleHideShadow": "largeTitleHideShadow() ?? defaults().largeTitleHideShadow ?? iosLargeTitle()", "backTitle": "backTitle()", "backTitleFontFamily": "backTitleFontFamily() ?? defaults().backTitleFontFamily", "backTitleFontSize": "backTitleFontSize() ?? defaults().backTitleFontSize", "backTitleVisible": "backTitleVisible()", "backButtonDisplayMode": "backButtonDisplayMode() ?? defaults().backButtonDisplayMode", "backButtonInCustomView": "backButtonInCustomView()", "disableBackButtonMenu": "disableBackButtonMenu()", "hideBackButton": "hideBackButton()", "consumeTopInset": "consumeTopInset()", "consumeLeftInset": "consumeLeftInset()", "consumeRightInset": "consumeRightInset()", "consumeBottomInset": "consumeBottomInset()" } }, ngImport: i0, template: '<ng-content />', isInline: true });
197
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.2.0", type: NativeHeader, isStandalone: true, selector: "native-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, titleColor: { classPropertyName: "titleColor", publicName: "titleColor", isSignal: true, isRequired: false, transformFunction: null }, titleFontFamily: { classPropertyName: "titleFontFamily", publicName: "titleFontFamily", isSignal: true, isRequired: false, transformFunction: null }, titleFontSize: { classPropertyName: "titleFontSize", publicName: "titleFontSize", isSignal: true, isRequired: false, transformFunction: null }, titleFontWeight: { classPropertyName: "titleFontWeight", publicName: "titleFontWeight", isSignal: true, isRequired: false, transformFunction: null }, liquidGlass: { classPropertyName: "liquidGlass", publicName: "liquidGlass", isSignal: true, isRequired: false, transformFunction: null }, backgroundColor: { classPropertyName: "backgroundColor", publicName: "backgroundColor", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, blurEffect: { classPropertyName: "blurEffect", publicName: "blurEffect", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null }, hideShadow: { classPropertyName: "hideShadow", publicName: "hideShadow", isSignal: true, isRequired: false, transformFunction: null }, translucent: { classPropertyName: "translucent", publicName: "translucent", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, topInsetEnabled: { classPropertyName: "topInsetEnabled", publicName: "topInsetEnabled", isSignal: true, isRequired: false, transformFunction: null }, userInterfaceStyle: { classPropertyName: "userInterfaceStyle", publicName: "userInterfaceStyle", isSignal: true, isRequired: false, transformFunction: null }, largeTitle: { classPropertyName: "largeTitle", publicName: "largeTitle", isSignal: true, isRequired: false, transformFunction: null }, largeTitleColor: { classPropertyName: "largeTitleColor", publicName: "largeTitleColor", isSignal: true, isRequired: false, transformFunction: null }, largeTitleBackgroundColor: { classPropertyName: "largeTitleBackgroundColor", publicName: "largeTitleBackgroundColor", isSignal: true, isRequired: false, transformFunction: null }, largeTitleFontFamily: { classPropertyName: "largeTitleFontFamily", publicName: "largeTitleFontFamily", isSignal: true, isRequired: false, transformFunction: null }, largeTitleFontSize: { classPropertyName: "largeTitleFontSize", publicName: "largeTitleFontSize", isSignal: true, isRequired: false, transformFunction: null }, largeTitleFontWeight: { classPropertyName: "largeTitleFontWeight", publicName: "largeTitleFontWeight", isSignal: true, isRequired: false, transformFunction: null }, largeTitleHideShadow: { classPropertyName: "largeTitleHideShadow", publicName: "largeTitleHideShadow", isSignal: true, isRequired: false, transformFunction: null }, backTitle: { classPropertyName: "backTitle", publicName: "backTitle", isSignal: true, isRequired: false, transformFunction: null }, backTitleFontFamily: { classPropertyName: "backTitleFontFamily", publicName: "backTitleFontFamily", isSignal: true, isRequired: false, transformFunction: null }, backTitleFontSize: { classPropertyName: "backTitleFontSize", publicName: "backTitleFontSize", isSignal: true, isRequired: false, transformFunction: null }, backTitleVisible: { classPropertyName: "backTitleVisible", publicName: "backTitleVisible", isSignal: true, isRequired: false, transformFunction: null }, backButtonDisplayMode: { classPropertyName: "backButtonDisplayMode", publicName: "backButtonDisplayMode", isSignal: true, isRequired: false, transformFunction: null }, backButtonInCustomView: { classPropertyName: "backButtonInCustomView", publicName: "backButtonInCustomView", isSignal: true, isRequired: false, transformFunction: null }, disableBackButtonMenu: { classPropertyName: "disableBackButtonMenu", publicName: "disableBackButtonMenu", isSignal: true, isRequired: false, transformFunction: null }, hideBackButton: { classPropertyName: "hideBackButton", publicName: "hideBackButton", isSignal: true, isRequired: false, transformFunction: null }, consumeTopInset: { classPropertyName: "consumeTopInset", publicName: "consumeTopInset", isSignal: true, isRequired: false, transformFunction: null }, consumeLeftInset: { classPropertyName: "consumeLeftInset", publicName: "consumeLeftInset", isSignal: true, isRequired: false, transformFunction: null }, consumeRightInset: { classPropertyName: "consumeRightInset", publicName: "consumeRightInset", isSignal: true, isRequired: false, transformFunction: null }, consumeBottomInset: { classPropertyName: "consumeBottomInset", publicName: "consumeBottomInset", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "title": "title()", "titleColor": "resolvedTitleColor()", "titleFontFamily": "titleFontFamily() ?? defaults().titleFontFamily", "titleFontSize": "titleFontSize() ?? defaults().titleFontSize", "titleFontWeight": "titleFontWeight() ?? defaults().titleFontWeight", "backgroundColor": "resolvedBackgroundColor()", "color": "resolvedColor()", "blurEffect": "blurEffect() ?? defaults().blurEffect", "hidden": "hidden()", "hideShadow": "hideShadow() ?? defaults().hideShadow ?? isLiquidGlass()", "translucent": "isTranslucent()", "direction": "direction()", "topInsetEnabled": "topInsetEnabled()", "userInterfaceStyle": "userInterfaceStyle() ?? defaults().userInterfaceStyle", "largeTitle": "largeTitle()", "largeTitleColor": "largeTitleColor() ?? defaults().largeTitleColor", "largeTitleBackgroundColor": "resolvedLargeTitleBackgroundColor()", "largeTitleFontFamily": "largeTitleFontFamily() ?? defaults().largeTitleFontFamily", "largeTitleFontSize": "largeTitleFontSize() ?? defaults().largeTitleFontSize", "largeTitleFontWeight": "largeTitleFontWeight() ?? defaults().largeTitleFontWeight", "largeTitleHideShadow": "largeTitleHideShadow() ?? defaults().largeTitleHideShadow ?? iosLargeTitle()", "backTitle": "backTitle()", "backTitleFontFamily": "backTitleFontFamily() ?? defaults().backTitleFontFamily", "backTitleFontSize": "backTitleFontSize() ?? defaults().backTitleFontSize", "backTitleVisible": "backTitleVisible()", "backButtonDisplayMode": "backButtonDisplayMode() ?? defaults().backButtonDisplayMode", "backButtonInCustomView": "backButtonInCustomView()", "disableBackButtonMenu": "disableBackButtonMenu()", "hideBackButton": "hideBackButton()", "consumeTopInset": "consumeTopInset()", "consumeLeftInset": "consumeLeftInset()", "consumeRightInset": "consumeRightInset()", "consumeBottomInset": "consumeBottomInset()" } }, ngImport: i0, template: '<ng-content />', isInline: true });
185
198
  }
186
199
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: NativeHeader, decorators: [{
187
200
  type: Component,
@@ -199,7 +212,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImpor
199
212
  '[blurEffect]': 'blurEffect() ?? defaults().blurEffect',
200
213
  '[hidden]': 'hidden()',
201
214
  '[hideShadow]': 'hideShadow() ?? defaults().hideShadow ?? isLiquidGlass()',
202
- '[translucent]': 'translucent() ?? defaults().translucent ?? iosLargeTitle() ?? isLiquidGlass()',
215
+ '[translucent]': 'isTranslucent()',
203
216
  '[direction]': 'direction()',
204
217
  '[topInsetEnabled]': 'topInsetEnabled()',
205
218
  '[userInterfaceStyle]': 'userInterfaceStyle() ?? defaults().userInterfaceStyle',
@@ -1 +1 @@
1
- {"version":3,"file":"native-header.js","sourceRoot":"","sources":["../src/native-header.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The screen's navigation bar, as a component you write inside a page's template.\n *\n * Commits as `RNSScreenStackHeaderConfig`. It is a configuration node rather than a view: the\n * native side reads its props and builds a `UINavigationItem` from them, and the only children\n * that mean anything are `native-header-item`s. `findHeaderConfig` in `RNSScreen.mm` scans the\n * screen's direct `reactSubviews` without recursing, which is why a page's host element is the\n * screen itself (ADR 0004). It can still be written anywhere in the page, inside a `safe-area-view`\n * or a layout component: `registerScreenComponents` has the engine commit it as a direct child of\n * the screen, just after the part of the page it was written in (`registerHoist`). Keep the page's\n * scroll view ahead of it. UIKit then finds that scroll view and collapses a large title into the\n * inline title as the content scrolls.\n *\n * A header owns the top inset. A page that has one should not also wrap itself in a\n * `safe-area-view`, or the content clears the notch twice.\n *\n * **A presented screen has no header.** `RNSScreenStack.mm` presents a modal or a sheet with\n * `presentViewController:`, outside the stack's `UINavigationController`, so there is no\n * navigation bar for this to configure and nothing adjusting the screen's insets either. A page\n * opened with `present()` owns its own chrome: its title, its way out, and its `safe-area-view`.\n * react-navigation has the same shape, which is why a modal there needs a stack nested inside it\n * before it has a header.\n *\n * Props are the `RNSScreenStackHeaderConfig` codegen spec. `headerLeftBarButtonItems` and\n * `headerRightBarButtonItems` are deliberately absent: native bar button items are data rather\n * than views, and they are a later opt-in rather than the primary API.\n */\nimport { Component, computed, input } from '@angular/core';\nimport { ElementRef, inject } from '@angular/core';\nimport { ColorScheme, OS_VERSION } from '@ng-native/device';\nimport { NATIVE_HEADER_DEFAULTS } from './native-bar-defaults.ts';\nimport { NATIVE_HEADER_PALETTE } from './native-header-palette.ts';\nimport type { EngineNode } from '@ng-native/fabric';\nimport { ownHost } from './own-host.ts';\nimport { nativePlatform } from '@ng-native/fabric';\nimport { optionalBoolean, optionalNumber } from './transforms.ts';\n\n/** Where the back button's title comes from, on iOS 14+. */\nexport type BackButtonDisplayMode = 'minimal' | 'default' | 'generic';\n\n/** Direction the bar lays out in, for right-to-left languages. */\nexport type HeaderDirection = 'ltr' | 'rtl';\n\n/** How the bar blurs what scrolls under it. `none` paints `backgroundColor` instead. */\nexport type BlurEffect =\n | 'none'\n | 'extraLight'\n | 'light'\n | 'dark'\n | 'regular'\n | 'prominent'\n | 'systemUltraThinMaterial'\n | 'systemThinMaterial'\n | 'systemMaterial'\n | 'systemThickMaterial'\n | 'systemChromeMaterial'\n | 'systemUltraThinMaterialLight'\n | 'systemThinMaterialLight'\n | 'systemMaterialLight'\n | 'systemThickMaterialLight'\n | 'systemChromeMaterialLight'\n | 'systemUltraThinMaterialDark'\n | 'systemThinMaterialDark'\n | 'systemMaterialDark'\n | 'systemThickMaterialDark'\n | 'systemChromeMaterialDark';\n\n/** Overrides the bar's light/dark appearance independently of the app's. */\nexport type HeaderInterfaceStyle = 'unspecified' | 'light' | 'dark';\n\n@Component({\n selector: 'native-header',\n template: '<ng-content />',\n host: {\n '[title]': 'title()',\n '[titleColor]': 'resolvedTitleColor()',\n '[titleFontFamily]': 'titleFontFamily() ?? defaults().titleFontFamily',\n '[titleFontSize]': 'titleFontSize() ?? defaults().titleFontSize',\n '[titleFontWeight]': 'titleFontWeight() ?? defaults().titleFontWeight',\n '[backgroundColor]': 'resolvedBackgroundColor()',\n '[color]': 'resolvedColor()',\n '[blurEffect]': 'blurEffect() ?? defaults().blurEffect',\n '[hidden]': 'hidden()',\n '[hideShadow]': 'hideShadow() ?? defaults().hideShadow ?? isLiquidGlass()',\n '[translucent]':\n 'translucent() ?? defaults().translucent ?? iosLargeTitle() ?? isLiquidGlass()',\n '[direction]': 'direction()',\n '[topInsetEnabled]': 'topInsetEnabled()',\n '[userInterfaceStyle]': 'userInterfaceStyle() ?? defaults().userInterfaceStyle',\n '[largeTitle]': 'largeTitle()',\n '[largeTitleColor]': 'largeTitleColor() ?? defaults().largeTitleColor',\n '[largeTitleBackgroundColor]': 'resolvedLargeTitleBackgroundColor()',\n '[largeTitleFontFamily]': 'largeTitleFontFamily() ?? defaults().largeTitleFontFamily',\n '[largeTitleFontSize]': 'largeTitleFontSize() ?? defaults().largeTitleFontSize',\n '[largeTitleFontWeight]': 'largeTitleFontWeight() ?? defaults().largeTitleFontWeight',\n '[largeTitleHideShadow]':\n 'largeTitleHideShadow() ?? defaults().largeTitleHideShadow ?? iosLargeTitle()',\n '[backTitle]': 'backTitle()',\n '[backTitleFontFamily]': 'backTitleFontFamily() ?? defaults().backTitleFontFamily',\n '[backTitleFontSize]': 'backTitleFontSize() ?? defaults().backTitleFontSize',\n '[backTitleVisible]': 'backTitleVisible()',\n '[backButtonDisplayMode]': 'backButtonDisplayMode() ?? defaults().backButtonDisplayMode',\n '[backButtonInCustomView]': 'backButtonInCustomView()',\n '[disableBackButtonMenu]': 'disableBackButtonMenu()',\n '[hideBackButton]': 'hideBackButton()',\n '[consumeTopInset]': 'consumeTopInset()',\n '[consumeLeftInset]': 'consumeLeftInset()',\n '[consumeRightInset]': 'consumeRightInset()',\n '[consumeBottomInset]': 'consumeBottomInset()',\n },\n})\nexport class NativeHeader {\n private readonly scheme = inject(ColorScheme);\n private readonly palette = inject(NATIVE_HEADER_PALETTE);\n /** The app's `withHeaderDefaults`, for whatever this header does not bind itself. */\n protected readonly defaults = inject(NATIVE_HEADER_DEFAULTS);\n\n constructor() {\n ownHost(inject(ElementRef).nativeElement as EngineNode, this.constructor);\n }\n\n /**\n * The palette for the scheme the app is wearing, for whichever colours were not bound.\n *\n * A header prop cannot read the cascade, so left alone each platform chooses: iOS follows the\n * system appearance and looks about right, Android takes the app theme's `colorPrimary` and is\n * the framework blue on every screen. These fill the gap without overriding anything a call site\n * or `withHeaderDefaults` did say. See `native-header-palette.ts` for retuning them.\n */\n private readonly colours = computed(() => this.palette[this.scheme.current()]);\n\n /** iOS 26 and later, where the system's own bar is clear and floats over the content. */\n private readonly glass = nativePlatform() === 'ios' && (inject(OS_VERSION) ?? 0) >= 26;\n\n /**\n * Whether the bar is iOS 26's Liquid Glass one, which `liquidGlass` asks for here or through\n * `withHeaderDefaults`: clear, over the content, with no line under it, where the system blurs\n * what scrolls beneath and floats the buttons. Only on iOS 26 and later, and only while nothing\n * gave the bar a background of its own.\n */\n protected readonly isLiquidGlass = computed(() =>\n this.glass &&\n (this.liquidGlass() ?? this.defaults().liquidGlass) &&\n this.backgroundColor() === undefined &&\n this.defaults().backgroundColor === undefined\n ? true\n : undefined,\n );\n\n protected readonly resolvedBackgroundColor = computed(\n () =>\n this.backgroundColor() ??\n this.defaults().backgroundColor ??\n (this.isLiquidGlass() ? 'transparent' : this.colours().background),\n );\n protected readonly resolvedColor = computed(\n () => this.color() ?? this.defaults().color ?? this.colours().foreground,\n );\n protected readonly resolvedTitleColor = computed(\n () => this.titleColor() ?? this.defaults().titleColor ?? this.colours().foreground,\n );\n\n /**\n * A large title on iOS, drawn as UIKit draws one unless the call site says otherwise: over the\n * content with the bar clear and unlined at the top, so the page's scroll view (with\n * `contentInsetAdjustmentBehavior=\"automatic\"`) collapses it into the bar as it scrolls. Since\n * iOS 26 the large title sits in the scroll view, above its content, where a bar with a\n * background paints over it; and over an opaque bar the inline title never fades in.\n */\n protected readonly iosLargeTitle = computed(() =>\n this.largeTitle() && nativePlatform() === 'ios' ? true : undefined,\n );\n protected readonly resolvedLargeTitleBackgroundColor = computed(\n () =>\n this.largeTitleBackgroundColor() ??\n this.defaults().largeTitleBackgroundColor ??\n (this.iosLargeTitle() ? 'transparent' : undefined),\n );\n\n // --- title ---------------------------------------------------------------------------\n\n /** The bar's title. Absent leaves whatever the platform would show, which is nothing. */\n readonly title = input<string>();\n /** Title colour. */\n readonly titleColor = input<string | number>();\n readonly titleFontFamily = input<string>();\n readonly titleFontSize = input(undefined, { transform: optionalNumber });\n /** A CSS font weight, `'600'` or `'bold'`. */\n readonly titleFontWeight = input<string>();\n\n // --- the bar itself ------------------------------------------------------------------\n\n /**\n * On iOS 26 and later, the Liquid Glass navigation bar for this header, where it has no\n * background of its own: clear and unlined, with the content scrolling under it. `false` keeps\n * the neutral bar on a page of an app whose `withHeaderDefaults` asks for the glass one. The\n * bar is over the page, so its scroll view takes `contentInsetAdjustmentBehavior=\"automatic\"`.\n */\n readonly liquidGlass = input(undefined, { transform: optionalBoolean });\n /** The bar's background. Ignored unless `blurEffect` is `none`. */\n readonly backgroundColor = input<string | number>();\n /** Tint colour: the back chevron, and any header item that does not set its own. */\n readonly color = input<string | number>();\n /** iOS blur material behind the bar. */\n readonly blurEffect = input<BlurEffect>();\n /** Hide the bar entirely, keeping the screen's gestures and safe areas. */\n readonly hidden = input(undefined, { transform: optionalBoolean });\n /** Drop the hairline under the bar. */\n readonly hideShadow = input(undefined, { transform: optionalBoolean });\n /** Let content scroll under the bar rather than starting below it. */\n readonly translucent = input(undefined, { transform: optionalBoolean });\n /** Lay the bar out right to left. */\n readonly direction = input<HeaderDirection>();\n /** Android: add the status bar inset to the bar's height. */\n readonly topInsetEnabled = input(undefined, { transform: optionalBoolean });\n /** Force the bar light or dark regardless of the app's appearance. */\n readonly userInterfaceStyle = input<HeaderInterfaceStyle>();\n\n // --- large title (iOS) ---------------------------------------------------------------\n\n /** iOS large title, which collapses into the bar as content scrolls. */\n readonly largeTitle = input(undefined, { transform: optionalBoolean });\n readonly largeTitleColor = input<string | number>();\n readonly largeTitleBackgroundColor = input<string | number>();\n readonly largeTitleFontFamily = input<string>();\n readonly largeTitleFontSize = input(undefined, { transform: optionalNumber });\n readonly largeTitleFontWeight = input<string>();\n readonly largeTitleHideShadow = input(undefined, { transform: optionalBoolean });\n\n // --- the back button -----------------------------------------------------------------\n\n /**\n * What *this* screen's back button says. `RNSScreenStackHeaderConfig.mm` writes it onto the\n * previous screen's navigation item, falling back to that screen's title, which is why an\n * unset back title reads as the title of the screen you came from.\n */\n readonly backTitle = input<string>();\n readonly backTitleFontFamily = input<string>();\n readonly backTitleFontSize = input(undefined, { transform: optionalNumber });\n /** Show the back button's title at all. Native defaults this to true. */\n readonly backTitleVisible = input(undefined, { transform: optionalBoolean });\n /** iOS 14+: how aggressively the back title is shortened when space is tight. */\n readonly backButtonDisplayMode = input<BackButtonDisplayMode>();\n /** Put the back button in the custom view slot, so a `back` header item can replace it. */\n readonly backButtonInCustomView = input(undefined, { transform: optionalBoolean });\n /** Drop the long-press menu of the screens below. */\n readonly disableBackButtonMenu = input(undefined, { transform: optionalBoolean });\n /** Hide the back button without disabling the swipe-back gesture. */\n readonly hideBackButton = input(undefined, { transform: optionalBoolean });\n\n // --- insets (experimental in react-native-screens) -------------------------------------\n\n /**\n * Android: whether the bar takes the status bar's height as padding, so its title sits below\n * it rather than under it.\n *\n * Defaulted per platform because getting it wrong is invisible in a screenshot until you look\n * for it: react-native-screens leaves it false, Android 15 draws every app edge to edge, and\n * the result is a title behind the clock. iOS has a navigation controller doing this itself.\n */\n readonly consumeTopInset = input(nativePlatform() === 'android', {\n transform: optionalBoolean,\n });\n readonly consumeLeftInset = input(undefined, { transform: optionalBoolean });\n readonly consumeRightInset = input(undefined, { transform: optionalBoolean });\n readonly consumeBottomInset = input(undefined, { transform: optionalBoolean });\n}\n"]}
1
+ {"version":3,"file":"native-header.js","sourceRoot":"","sources":["../src/native-header.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The screen's navigation bar, as a component you write inside a page's template.\n *\n * Commits as `RNSScreenStackHeaderConfig`. It is a configuration node rather than a view: the\n * native side reads its props and builds a `UINavigationItem` from them, and the only children\n * that mean anything are `native-header-item`s. `findHeaderConfig` in `RNSScreen.mm` scans the\n * screen's direct `reactSubviews` without recursing, which is why a page's host element is the\n * screen itself (ADR 0004). It can still be written anywhere in the page, inside a `safe-area-view`\n * or a layout component: `registerScreenComponents` has the engine commit it as a direct child of\n * the screen, just after the part of the page it was written in (`registerHoist`). Keep the page's\n * scroll view ahead of it. UIKit then finds that scroll view and collapses a large title into the\n * inline title as the content scrolls.\n *\n * A header owns the top inset. A page that has one should not also wrap itself in a\n * `safe-area-view`, or the content clears the notch twice.\n *\n * **A presented screen has no header.** `RNSScreenStack.mm` presents a modal or a sheet with\n * `presentViewController:`, outside the stack's `UINavigationController`, so there is no\n * navigation bar for this to configure and nothing adjusting the screen's insets either. A page\n * opened with `present()` owns its own chrome: its title, its way out, and its `safe-area-view`.\n * react-navigation has the same shape, which is why a modal there needs a stack nested inside it\n * before it has a header.\n *\n * Props are the `RNSScreenStackHeaderConfig` codegen spec. `headerLeftBarButtonItems` and\n * `headerRightBarButtonItems` are deliberately absent: native bar button items are data rather\n * than views, and they are a later opt-in rather than the primary API.\n */\nimport { Component, DestroyRef, ElementRef, computed, effect, inject, input } from '@angular/core';\nimport { ColorScheme, OS_VERSION } from '@ng-native/device';\nimport { NATIVE_HEADER_DEFAULTS } from './native-bar-defaults.ts';\nimport { NATIVE_HEADER_PALETTE } from './native-header-palette.ts';\nimport type { EngineNode } from '@ng-native/fabric';\nimport { ownHost } from './own-host.ts';\nimport { SCREEN_HEADER } from './screen-header.ts';\nimport { nativePlatform } from '@ng-native/fabric';\nimport { optionalBoolean, optionalNumber } from './transforms.ts';\n\n/** Where the back button's title comes from, on iOS 14+. */\nexport type BackButtonDisplayMode = 'minimal' | 'default' | 'generic';\n\n/** Direction the bar lays out in, for right-to-left languages. */\nexport type HeaderDirection = 'ltr' | 'rtl';\n\n/** How the bar blurs what scrolls under it. `none` paints `backgroundColor` instead. */\nexport type BlurEffect =\n | 'none'\n | 'extraLight'\n | 'light'\n | 'dark'\n | 'regular'\n | 'prominent'\n | 'systemUltraThinMaterial'\n | 'systemThinMaterial'\n | 'systemMaterial'\n | 'systemThickMaterial'\n | 'systemChromeMaterial'\n | 'systemUltraThinMaterialLight'\n | 'systemThinMaterialLight'\n | 'systemMaterialLight'\n | 'systemThickMaterialLight'\n | 'systemChromeMaterialLight'\n | 'systemUltraThinMaterialDark'\n | 'systemThinMaterialDark'\n | 'systemMaterialDark'\n | 'systemThickMaterialDark'\n | 'systemChromeMaterialDark';\n\n/** Overrides the bar's light/dark appearance independently of the app's. */\nexport type HeaderInterfaceStyle = 'unspecified' | 'light' | 'dark';\n\n@Component({\n selector: 'native-header',\n template: '<ng-content />',\n host: {\n '[title]': 'title()',\n '[titleColor]': 'resolvedTitleColor()',\n '[titleFontFamily]': 'titleFontFamily() ?? defaults().titleFontFamily',\n '[titleFontSize]': 'titleFontSize() ?? defaults().titleFontSize',\n '[titleFontWeight]': 'titleFontWeight() ?? defaults().titleFontWeight',\n '[backgroundColor]': 'resolvedBackgroundColor()',\n '[color]': 'resolvedColor()',\n '[blurEffect]': 'blurEffect() ?? defaults().blurEffect',\n '[hidden]': 'hidden()',\n '[hideShadow]': 'hideShadow() ?? defaults().hideShadow ?? isLiquidGlass()',\n '[translucent]': 'isTranslucent()',\n '[direction]': 'direction()',\n '[topInsetEnabled]': 'topInsetEnabled()',\n '[userInterfaceStyle]': 'userInterfaceStyle() ?? defaults().userInterfaceStyle',\n '[largeTitle]': 'largeTitle()',\n '[largeTitleColor]': 'largeTitleColor() ?? defaults().largeTitleColor',\n '[largeTitleBackgroundColor]': 'resolvedLargeTitleBackgroundColor()',\n '[largeTitleFontFamily]': 'largeTitleFontFamily() ?? defaults().largeTitleFontFamily',\n '[largeTitleFontSize]': 'largeTitleFontSize() ?? defaults().largeTitleFontSize',\n '[largeTitleFontWeight]': 'largeTitleFontWeight() ?? defaults().largeTitleFontWeight',\n '[largeTitleHideShadow]':\n 'largeTitleHideShadow() ?? defaults().largeTitleHideShadow ?? iosLargeTitle()',\n '[backTitle]': 'backTitle()',\n '[backTitleFontFamily]': 'backTitleFontFamily() ?? defaults().backTitleFontFamily',\n '[backTitleFontSize]': 'backTitleFontSize() ?? defaults().backTitleFontSize',\n '[backTitleVisible]': 'backTitleVisible()',\n '[backButtonDisplayMode]': 'backButtonDisplayMode() ?? defaults().backButtonDisplayMode',\n '[backButtonInCustomView]': 'backButtonInCustomView()',\n '[disableBackButtonMenu]': 'disableBackButtonMenu()',\n '[hideBackButton]': 'hideBackButton()',\n '[consumeTopInset]': 'consumeTopInset()',\n '[consumeLeftInset]': 'consumeLeftInset()',\n '[consumeRightInset]': 'consumeRightInset()',\n '[consumeBottomInset]': 'consumeBottomInset()',\n },\n})\nexport class NativeHeader {\n private readonly scheme = inject(ColorScheme);\n private readonly palette = inject(NATIVE_HEADER_PALETTE);\n /** The app's `withHeaderDefaults`, for whatever this header does not bind itself. */\n protected readonly defaults = inject(NATIVE_HEADER_DEFAULTS);\n\n /** Told whether this is a bar the page starts below. See `screen-header.ts`. */\n private readonly above = inject(SCREEN_HEADER, { optional: true });\n\n constructor() {\n ownHost(inject(ElementRef).nativeElement as EngineNode, this.constructor);\n const above = this.above;\n if (!above) return;\n effect(() => above.set(!this.hidden() && !this.isTranslucent()));\n inject(DestroyRef).onDestroy(() => above.set(false));\n }\n\n /**\n * The palette for the scheme the app is wearing, for whichever colours were not bound.\n *\n * A header prop cannot read the cascade, so left alone each platform chooses: iOS follows the\n * system appearance and looks about right, Android takes the app theme's `colorPrimary` and is\n * the framework blue on every screen. These fill the gap without overriding anything a call site\n * or `withHeaderDefaults` did say. See `native-header-palette.ts` for retuning them.\n */\n private readonly colours = computed(() => this.palette[this.scheme.current()]);\n\n /** iOS 26 and later, where the system's own bar is clear and floats over the content. */\n private readonly glass = nativePlatform() === 'ios' && (inject(OS_VERSION) ?? 0) >= 26;\n\n /**\n * Whether the bar is iOS 26's Liquid Glass one, which `liquidGlass` asks for here or through\n * `withHeaderDefaults`: clear, over the content, with no line under it, where the system blurs\n * what scrolls beneath and floats the buttons. Only on iOS 26 and later, and only while nothing\n * gave the bar a background of its own.\n */\n protected readonly isLiquidGlass = computed(() =>\n this.glass &&\n (this.liquidGlass() ?? this.defaults().liquidGlass) &&\n this.backgroundColor() === undefined &&\n this.defaults().backgroundColor === undefined\n ? true\n : undefined,\n );\n\n protected readonly resolvedBackgroundColor = computed(\n () =>\n this.backgroundColor() ??\n this.defaults().backgroundColor ??\n (this.isLiquidGlass() ? 'transparent' : this.colours().background),\n );\n protected readonly resolvedColor = computed(\n () => this.color() ?? this.defaults().color ?? this.colours().foreground,\n );\n protected readonly resolvedTitleColor = computed(\n () => this.titleColor() ?? this.defaults().titleColor ?? this.colours().foreground,\n );\n\n /**\n * A large title on iOS, drawn as UIKit draws one unless the call site says otherwise: over the\n * content with the bar clear and unlined at the top, so the page's scroll view (with\n * `contentInsetAdjustmentBehavior=\"automatic\"`) collapses it into the bar as it scrolls. Since\n * iOS 26 the large title sits in the scroll view, above its content, where a bar with a\n * background paints over it; and over an opaque bar the inline title never fades in.\n */\n /** Whether the page runs under the bar rather than starting below it. */\n protected readonly isTranslucent = computed(\n () =>\n this.translucent() ??\n this.defaults().translucent ??\n this.iosLargeTitle() ??\n this.isLiquidGlass(),\n );\n\n protected readonly iosLargeTitle = computed(() =>\n this.largeTitle() && nativePlatform() === 'ios' ? true : undefined,\n );\n protected readonly resolvedLargeTitleBackgroundColor = computed(\n () =>\n this.largeTitleBackgroundColor() ??\n this.defaults().largeTitleBackgroundColor ??\n (this.iosLargeTitle() ? 'transparent' : undefined),\n );\n\n // --- title ---------------------------------------------------------------------------\n\n /** The bar's title. Absent leaves whatever the platform would show, which is nothing. */\n readonly title = input<string>();\n /** Title colour. */\n readonly titleColor = input<string | number>();\n readonly titleFontFamily = input<string>();\n readonly titleFontSize = input(undefined, { transform: optionalNumber });\n /** A CSS font weight, `'600'` or `'bold'`. */\n readonly titleFontWeight = input<string>();\n\n // --- the bar itself ------------------------------------------------------------------\n\n /**\n * On iOS 26 and later, the Liquid Glass navigation bar for this header, where it has no\n * background of its own: clear and unlined, with the content scrolling under it. `false` keeps\n * the neutral bar on a page of an app whose `withHeaderDefaults` asks for the glass one. The\n * bar is over the page, so its scroll view takes `contentInsetAdjustmentBehavior=\"automatic\"`.\n */\n readonly liquidGlass = input(undefined, { transform: optionalBoolean });\n /** The bar's background. Ignored unless `blurEffect` is `none`. */\n readonly backgroundColor = input<string | number>();\n /** Tint colour: the back chevron, and any header item that does not set its own. */\n readonly color = input<string | number>();\n /** iOS blur material behind the bar. */\n readonly blurEffect = input<BlurEffect>();\n /** Hide the bar entirely, keeping the screen's gestures and safe areas. */\n readonly hidden = input(undefined, { transform: optionalBoolean });\n /** Drop the hairline under the bar. */\n readonly hideShadow = input(undefined, { transform: optionalBoolean });\n /** Let content scroll under the bar rather than starting below it. */\n readonly translucent = input(undefined, { transform: optionalBoolean });\n /** Lay the bar out right to left. */\n readonly direction = input<HeaderDirection>();\n /** Android: add the status bar inset to the bar's height. */\n readonly topInsetEnabled = input(undefined, { transform: optionalBoolean });\n /** Force the bar light or dark regardless of the app's appearance. */\n readonly userInterfaceStyle = input<HeaderInterfaceStyle>();\n\n // --- large title (iOS) ---------------------------------------------------------------\n\n /** iOS large title, which collapses into the bar as content scrolls. */\n readonly largeTitle = input(undefined, { transform: optionalBoolean });\n readonly largeTitleColor = input<string | number>();\n readonly largeTitleBackgroundColor = input<string | number>();\n readonly largeTitleFontFamily = input<string>();\n readonly largeTitleFontSize = input(undefined, { transform: optionalNumber });\n readonly largeTitleFontWeight = input<string>();\n readonly largeTitleHideShadow = input(undefined, { transform: optionalBoolean });\n\n // --- the back button -----------------------------------------------------------------\n\n /**\n * What *this* screen's back button says. `RNSScreenStackHeaderConfig.mm` writes it onto the\n * previous screen's navigation item, falling back to that screen's title, which is why an\n * unset back title reads as the title of the screen you came from.\n */\n readonly backTitle = input<string>();\n readonly backTitleFontFamily = input<string>();\n readonly backTitleFontSize = input(undefined, { transform: optionalNumber });\n /** Show the back button's title at all. Native defaults this to true. */\n readonly backTitleVisible = input(undefined, { transform: optionalBoolean });\n /** iOS 14+: how aggressively the back title is shortened when space is tight. */\n readonly backButtonDisplayMode = input<BackButtonDisplayMode>();\n /** Put the back button in the custom view slot, so a `back` header item can replace it. */\n readonly backButtonInCustomView = input(undefined, { transform: optionalBoolean });\n /** Drop the long-press menu of the screens below. */\n readonly disableBackButtonMenu = input(undefined, { transform: optionalBoolean });\n /** Hide the back button without disabling the swipe-back gesture. */\n readonly hideBackButton = input(undefined, { transform: optionalBoolean });\n\n // --- insets (experimental in react-native-screens) -------------------------------------\n\n /**\n * Android: whether the bar takes the status bar's height as padding, so its title sits below\n * it rather than under it.\n *\n * Defaulted per platform because getting it wrong is invisible in a screenshot until you look\n * for it: react-native-screens leaves it false, Android 15 draws every app edge to edge, and\n * the result is a title behind the clock. iOS has a navigation controller doing this itself.\n */\n readonly consumeTopInset = input(nativePlatform() === 'android', {\n transform: optionalBoolean,\n });\n readonly consumeLeftInset = input(undefined, { transform: optionalBoolean });\n readonly consumeRightInset = input(undefined, { transform: optionalBoolean });\n readonly consumeBottomInset = input(undefined, { transform: optionalBoolean });\n}\n"]}
@@ -27,6 +27,7 @@ import { NativePlatformLocation } from "./native-platform-location.js";
27
27
  import { PRESENTED, withoutPresented } from "./presented-route.js";
28
28
  import { markScreenRoute } from "./tab-routes.js";
29
29
  import { ownHost } from "./own-host.js";
30
+ import { SCREEN_HEADER } from "./screen-header.js";
30
31
  import { HostEngine } from '@ng-native/fabric';
31
32
  import { ActivityState } from "./screens.js";
32
33
  import * as i0 from "@angular/core";
@@ -760,6 +761,7 @@ export class NativeStackOutlet {
760
761
  },
761
762
  },
762
763
  { provide: ActivatedRoute, useValue: route },
764
+ { provide: SCREEN_HEADER, useValue: signal(false) },
763
765
  {
764
766
  provide: ChildrenOutletContexts,
765
767
  useValue: this.parentContexts.getOrCreateContext(outlet).children,
@@ -1 +1 @@
1
- {"version":3,"file":"native-stack-outlet.js","sourceRoot":"","sources":["../src/native-stack-outlet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EACL,cAAc,EACd,SAAS,EACT,UAAU,EACV,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,QAAQ,EACR,SAAS,EACT,gBAAgB,EAChB,QAAQ,EACR,eAAe,EACf,MAAM,EACN,MAAM,GAMP,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,cAAc,EACd,MAAM,EACN,yBAAyB,GAG1B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAqB,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,UAAU,EAAmB,MAAM,mBAAmB,CAAC;AAEhE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;;AAqB7C;;;;;;;GAOG;AACH,MAAM,SAAS,GAAG,IAAI,OAAO,EAAkB,CAAC;AAEhD,8FAA8F;AAC9F,MAAM,IAAI,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAW,CAAC;AAErF,mDAAmD;AACnD,MAAM,eAAe,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAW,CAAC;AAE7E;;;;GAIG;AACH,MAAM,cAAc,GAAG,IAAI,cAAc,CAAgB,iCAAiC,CAAC,CAAC;AAW5F,yEAAyE;AACzE,MAAM,OAAO,GAAG,CAAC,MAAe,EAAW,EAAE,CAC1C,MAA0C,EAAE,KAAK,EAAE,CAAC,sBAAsB,CAAC,KAAK,IAAI,CAAC;AAUxF,MAAM,OAAO,iBAAiB;IAC5B;;;;OAIG;IACM,IAAI,GAAG,MAAM,CAAC,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,cAAc,CAAC;IAEpF,gCAAgC,GAAG,IAAI,CAAC;IAEhC,cAAc,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAChD,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7B,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;IACxC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5B,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC1B,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5B,OAAO,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACpD;;;OAGG;IACc,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,2EAA2E;IAC1D,MAAM,GAAG,MAAM,CAAC,UAAU,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhD,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IAC/C,kFAAkF;IACjE,MAAM,GAAG,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACrE,+FAA+F;IACvF,IAAI,GAA4B,IAAI,CAAC;IAE5B,OAAO,GAAiB,EAAE,CAAC;IAC5C;;;OAGG;IACK,UAAU,GAAyD,IAAI,CAAC;IAE7D,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAEtC;QACE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACjC,wCAAwC;QACxC,OAAQ,IAAI,CAAC,IAAI,CAAC,aAAoD,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrF,IAAI,CAAC,cAAc,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAE1D,6FAA6F;QAC7F,uFAAuF;QACvF,6FAA6F;QAC7F,iCAAiC;QACjC,EAAE;QACF,wFAAwF;QACxF,4FAA4F;QAC5F,0EAA0E;QAC1E,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;QAChC,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAC3C,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CACjE,CAAC;QACF,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC;YACrC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE;YAC/B,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACtE,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;gBACb,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;gBAC3E,OAAO,KAAK,KAAK,CAAC,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACzF,CAAC;SACF,CAAC,CAAC;QACH,8FAA8F;QAC9F,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;YAC3D,IAAI,KAAK,YAAY,aAAa;gBAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;iBACrD,IAAI,KAAK,YAAY,eAAe;gBAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACxE,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAEhD,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,EAAE,CAAC;YACX,SAAS,EAAE,EAAE,CAAC;YACd,eAAe,EAAE,CAAC;YAClB,gBAAgB,EAAE,CAAC;YACnB,WAAW,EAAE,WAAW,EAAE,CAAC;YAC3B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACf,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACtB,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACxB,IAAI,CAAC,cAAc,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,wFAAwF;IAChF,aAAa,GAA+C,IAAI,CAAC;IAEzE;;;;OAIG;IACK,kBAAkB,CAAC,IAAgB;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,EAAE,WAAW,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,IAAI,IAAI,KAAK,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YAC7F,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC;QACtC,MAAM,MAAM,GAAyB;YACnC,gCAAgC,EAAE,IAAI;YACtC,IAAI,WAAW;gBACb,OAAO,IAAI,EAAE,KAAK,IAAI,CAAC;YACzB,CAAC;YACD,IAAI,SAAS;gBACX,OAAQ,IAAI,EAAE,EAAE,GAAG,CAAC,QAA+B,IAAI,IAAI,CAAC;YAC9D,CAAC;YACD,IAAI,cAAc;gBAChB,OAAO,IAAI,EAAE,EAAE,KAAK,IAAI,IAAI,CAAC;YAC/B,CAAC;YACD,IAAI,kBAAkB;gBACpB,OAAO,IAAI,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;YAC3C,CAAC;YACD,YAAY,EAAE,CAAC,KAAK,EAAE,mBAAmB,EAAE,EAAE,CAC3C,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,CAAC;YACpD,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE;YAC1C,MAAM,EAAE,GAAG,EAAE;gBACX,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;YAClF,CAAC;YACD,MAAM,EAAE,GAAG,EAAE;gBACX,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;YACnF,CAAC;SACF,CAAC;QACF,IAAI,CAAC,cAAc,CAAC,oBAAoB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,IAAI,CAAC,cAAc,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC;QACxD,CAAC,CAAC;IACJ,CAAC;IAEO,WAAW,CACjB,KAAqB,EACrB,mBAAwC,EACxC,IAAgB;QAEhB,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAyB,CAAC;QACxF,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACtF,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,IAAI;YACnE,iBAAiB,EAAE,OAAO;SAC3B,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC;QAClF,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI;oFAAC,CAAC;QAC7B,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CACrC,SAAS,EACT,KAAK,EACL,mBAAmB,EACnB,MAAM,EACN,OAAO,EACP,SAAS,CACV,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACxB,4FAA4F;QAC5F,+CAA+C;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC;QAChE,IAAI,CAAC,aAAa,GAAG;YACnB,KAAK;YACL,GAAG;YACH,MAAM;YACN,QAAQ,EAAE,KAAK;YACf,MAAM;YACN,YAAY;YACZ,OAAO;YACP,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,iEAAiE;IACzD,iBAAiB;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC;QAChC,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IAED;;;;OAIG;IACK,oBAAoB;QAC1B,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QACtD,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/D,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO;YAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;;YAC5D,KAAK,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QACnE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2EAA2E;IAC3E,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAED;;;;;OAKG;IACK,oBAAoB;QAC1B,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,IAAI,CAAC,OAAO,EAAE,KAAK;YAAE,OAAO;QAC5B,IAAI,OAAO,CAAC,SAAS;YAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;;YAChE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,CAAC;IAED,0EAA0E;IAE1E,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;IACtD,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAmB,CAAC,CAAC,CAAC,IAAI,CAAC;IACnF,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAChE,CAAC;IAED,IAAI,kBAAkB;QACpB,OAAO,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;IAClD,CAAC;IAED,4EAA4E;IAC5E,IAAI,qBAAqB;QACvB,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC;IAC/B,CAAC;IAED,YAAY,CAAC,KAAqB,EAAE,mBAAwC;QAC1E,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAyB,CAAC;QACxF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QACD,uFAAuF;QACvF,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW;YAAE,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAE5E,qFAAqF;QACrF,yFAAyF;QACzF,6FAA6F;QAC7F,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACpC,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAClD,EAAE;QACF,0FAA0F;QAC1F,yFAAyF;QACzF,6FAA6F;QAC7F,4FAA4F;QAC5F,4FAA4F;QAC5F,kFAAkF;QAClF,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI;oFAAC,CAAC;QAC7B,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAChG,2FAA2F;QAC3F,6FAA6F;QAC7F,iFAAiF;QACjF,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAExB,IAAI,MAAM,EAAE,KAAK,KAAK,OAAO;YAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,UAAU,CAAC,CAAC;aAC3E,IAAI,MAAM,EAAE,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG;YAAE,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;QACzF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAChB,KAAK;YACL,GAAG;YACH,MAAM;YACN,QAAQ,EAAE,KAAK;YACf,MAAM;YACN,YAAY;YACZ,WAAW,EAAE,UAAU;YACvB,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACK,UAAU,CAChB,SAAwB,EACxB,KAAqB,EACrB,mBAAwC,EACxC,MAAe,EACf,OAAgC,EAChC,MAAM,GAAG,IAAI,CAAC,IAAI;QAElB,IAAI,GAAsC,CAAC;QAC3C,IAAI,MAAgC,CAAC;QACrC,IAAI,CAAC;YACH,GAAG,GAAG,eAAe,CAAC,SAAS,EAAE;gBAC/B,mBAAmB;gBACnB,eAAe,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC;gBACpE,WAAW,EAAE,MAAiB;aAC/B,CAAC,CAAC;YACH,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC7C,0FAA0F;YAC1F,uFAAuF;YACvF,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACrC,4FAA4F;YAC5F,2FAA2F;YAC3F,4FAA4F;YAC5F,yFAAyF;YACzF,0FAA0F;YAC1F,yEAAyE;YACzE,GAAG,CAAC,iBAAiB,CAAC,aAAa,EAAE,CAAC;YACtC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,EAAE,EAAE,CAAC;YACX,GAAG,EAAE,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAC1B,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAC/B,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,UAAU;QACR,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO;QAC9B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAG,CAAC,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,MAAM;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;QAC3F,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACzB,gFAAgF;QAChF,0FAA0F;QAC1F,4FAA4F;QAC5F,iFAAiF;QACjF,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC,GAAG,CAAC;IACnB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,GAA0B,EAAE,KAAqB;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;QAEnE,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACjB,uFAAuF;YACvF,uFAAuF;YACvF,wDAAwD;YACxD,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;YAC3D,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;gBAChB,KAAK;gBACL,GAAG;gBACH,MAAM;gBACN,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC;gBACnC,mFAAmF;gBACnF,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC;aACtB,CAAC,CAAC;YACH,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrE,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAE,CAAC;YACnC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC;YACvB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACxB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;YACpB,sFAAsF;YACtF,KAAK,CAAC,MAAM,EAAE,CAAC;YACf,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC7C,CAAC;QAED,qEAAqE;QACrE,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;IAED,2EAA2E;IAE3E;;;;OAIG;IACK,UAAU,CAAC,GAA0B,EAAE,KAAqB;QAClE,OAAO,IAAI,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;IAC5F,CAAC;IAED,IAAY,GAAG;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED;;;OAGG;IACK,aAAa;QACnB,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,oBAAoB,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACrE,CAAC;IAED;;;;;;;;;OASG;IACK,eAAe,CAAC,MAA2B;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,EAAE,iBAAiB,CAAC;QAC3D,IAAI,MAAM,EAAE,KAAK,KAAK,OAAO,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,MAAM,IAAI,GAAG,EAAE,iBAAiB,EAAE,CAAC;YAC5F,OAAO,GAAG,CAAC;QACb,CAAC;QACD,OAAO,EAAE,GAAG,GAAG,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC;IACjD,CAAC;IAED,4FAA4F;IACpF,iBAAiB,CAAC,MAA2B;QACnD,IAAI,CAAC,MAAM,EAAE,YAAY;YAAE,OAAO,SAAS,CAAC;QAC5C,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,oBAAoB,EAAE,EAAE,EAAE,CAAC;QACnD,IAAI,EAAE,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC,YAAY,CAAC;QACjD,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAO,CAAC,KAAK,EAAE;YAAE,OAAO,SAAS,CAAC;QACzD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAO,EAAE,EAAE,CAAC,CAAC;QAChC,OAAO,MAAM,CAAC,YAAY,CAAC;IAC7B,CAAC;IAED,oFAAoF;IAC5E,IAAI,CAAC,KAAiB;QAC5B,KAAK,CAAC,MAAM,EAAE,CAAC;QACf,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,oEAAoE;IAC5D,MAAM,CAAC,KAAiB;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,OAAO;QACzB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;IAED,4EAA4E;IAE5E,2EAA2E;IACnE,YAAY;QAClB,OAAO,IAAI,CAAC,MAAM,EAAE,oBAAoB,EAAE,EAAE,EAAE,CAAC;IACjD,CAAC;IAED;;;;;OAKG;IACK,SAAS,CAAC,OAAqB,EAAE,UAA8B;QACrE,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,KAAK,MAAM,KAAK,IAAI,OAAO;gBAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IAC5C,CAAC;IAED,8FAA8F;IACtF,MAAM,CAAC,UAAkB;QAC/B,IAAI,IAAI,CAAC,UAAU,EAAE,UAAU,KAAK,UAAU,EAAE,CAAC;YAC/C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO;gBAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAChE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,WAAW,KAAK,UAAU;gBAAE,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC;YACpE,IAAI,KAAK,CAAC,UAAU,KAAK,UAAU;gBAAE,KAAK,CAAC,UAAU,GAAG,SAAS,CAAC;QACpE,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACK,QAAQ,CAAC,UAAkB;QACjC,IAAI,IAAI,CAAC,UAAU,EAAE,UAAU,KAAK,UAAU;YAAE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvE,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,WAAW,KAAK,UAAU,CAAC,EAAE,CAAC;YAC7F,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACrB,IAAI,CAAC,GAAG,EAAE,QAAQ,IAAI,GAAG,CAAC,UAAU,KAAK,UAAU;YAAE,OAAO;QAC5D,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAC;QACrB,GAAG,CAAC,UAAU,GAAG,SAAS,CAAC;QAC3B,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACK,UAAU,CAAC,MAAe;QAChC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAiB,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAEO,YAAY,CAClB,YAAiC,EACjC,YAAY,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;QAE1D,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACxB,oEAAoE;QACpE,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,EAAE,eAAe,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QACzE,0FAA0F;QAC1F,2FAA2F;QAC3F,2FAA2F;QAC3F,IAAI,CAAC,QAAQ,CAAC,MAAM,CAClB,MAAM,EACN,WAAW,EACX,CAAC,KAAkD,EAAE,EAAE,CACrD,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,IAAI,CAAC,CAAC,CACnD,CAAC;QACF,4FAA4F;QAC5F,0FAA0F;QAC1F,mDAAmD;QACnD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,CAAC;YAC/D,IAAI,KAAK,KAAK,SAAS;gBAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC1E,CAAC;QACD,0FAA0F;QAC1F,8FAA8F;QAC9F,oDAAoD;QACpD,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,EAAE,yBAAyB,EAAE;YAC3D,GAAG,eAAe;YAClB,GAAG,YAAY,EAAE,uBAAuB;SACzC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAC3D,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;;OAUG;IACK,eAAe,CAAC,KAAa;QACnC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACH;;;;;OAKG;IACK,aAAa;QACnB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAAE,OAAO,KAAK,CAAC;QAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAI,CAAC,MAAoB,CAAC;QAC9C,IAAI,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAChE,iFAAiF;QACjF,wEAAwE;QACxE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAmD,CAAC;QACxE,MAAM,EAAE,aAAa,EAAE,CAAC,MAAM,EAAE,2BAA2B,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACK,YAAY,CAAC,MAAqB;QACxC,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;QAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CACnC,MAAM,CAAC,MAAM,EACb,wBAAwB,EACxB,CAAC,KAAgC,EAAE,EAAE;YACnC,6EAA6E;YAC7E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG;gBAAE,OAAO;YAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAmD,CAAC;YACxE,MAAM,MAAM,GAAG,KAAK,EAAE,WAAW,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;YACzD,MAAM,EAAE,aAAa,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,2BAA2B,EAAE,MAAM,CAAC,CAAC;QAC3E,CAAC,CACF,CAAC;QACF,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,QAAQ,EAAE,CAAC;YACX,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC,CAAC;IACJ,CAAC;IAEO,WAAW,CAAC,MAAqB;QACvC,2EAA2E;QAC3E,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACjF,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;YAAE,OAAO;QACnC,2FAA2F;QAC3F,2FAA2F;QAC3F,IAAI,CAAC,IAAI,GAAG,EAAE,GAAG,EAAG,MAAM,CAAC,MAAqB,CAAC,KAAK,EAAE,CAAC,sBAAsB,CAAC,EAAE,CAAC;QACnF,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAsB,EAAE,IAAI,CAAC,CAAC;QACvE,MAAM,CAAC,cAAc,EAAE,CAAC;IAC1B,CAAC;IAED,4EAA4E;IACpE,OAAO,CAAC,MAAqB;QACnC,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO;QACvB,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAsB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC;QACzF,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,MAAM,CAAC,cAAc,EAAE,CAAC;IAC1B,CAAC;IAEO,MAAM;QACZ,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAAE,OAAO,KAAK,CAAC;QAC/D,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6FAA6F;IACrF,SAAS;QACf,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAC9B,OAAO,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,GAAI,CAAC,KAAK,CAAC,CAAC;IACrE,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,KAAa;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAG,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5D,yFAAyF;QACzF,8FAA8F;QAC9F,yFAAyF;QACzF,uFAAuF;QACvF,+DAA+D;QAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,GAAG,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC;YAChC,OAAO;QACT,CAAC;QACD,KAAK,IAAI,CAAC,MAAO,CAAC,aAAa,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED;;;;;OAKG;IACK,UAAU,CAAC,KAAa;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAE,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC;QAC9C,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;YACpC,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACtC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC;YAChC,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,IAAI,CAAC,MAAO,CAAC,aAAa,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,yDAAyD;IACjD,cAAc;QACpB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;gBACrD,IAAI,KAAK,YAAY,aAAa;oBAAE,OAAO,CAAC,IAAI,CAAC,CAAC;qBAC7C,IAAI,KAAK,YAAY,eAAe,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;oBAC/E,OAAO,CAAC,KAAK,CAAC,CAAC;gBACjB,CAAC;;oBAAM,OAAO;gBACd,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,6FAA6F;IACrF,KAAK,CAAC,KAAiB;QAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC;QACtC,MAAM,IAAI,GAAG,yBAAyB,CAAC,QAAQ,EAAE,EAAE,EAAE,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC9F,OAAO,IAAI,CAAC,MAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAED;;;;OAIG;IACK,UAAU,CAAC,MAAc;QAC/B,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,YAAY,sBAAsB,CAAC;YAAE,OAAO,SAAS,CAAC;QACxE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACxC,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACrF,CAAC;IAEO,YAAY,CAAC,MAAe;QAClC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;IAED;;;;OAIG;IACK,cAAc,CACpB,KAAqB,EACrB,OAAgC,EAChC,MAAe,EACf,MAAM,GAAG,IAAI,CAAC,IAAI;QAElB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QACjD,OAAO,QAAQ,CAAC,MAAM,CAAC;YACrB,MAAM,EAAE,IAAI,CAAC,QAAQ;YACrB,SAAS,EAAE;gBACT,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,IAAI,OAAO,EAAE,CAAC,EAAE;gBAC5E;oBACE,OAAO,EAAE,cAAc;oBACvB,QAAQ,EAAE;wBACR,MAAM;wBACN,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC;qBAC3C;iBAC1B;gBACD,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAC5C;oBACE,OAAO,EAAE,sBAAsB;oBAC/B,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,QAAQ;iBAClE;aACF;SACF,CAAC,CAAC;IACL,CAAC;uGApwBU,iBAAiB;2FAAjB,iBAAiB,0HAHlB,EAAE;;2FAGD,iBAAiB;kBAL7B,SAAS;mBAAC;oBACT,QAAQ,EAAE,qBAAqB;oBAC/B,QAAQ,EAAE,EAAE;oBACZ,IAAI,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE;iBAC5B","sourcesContent":["/**\n * A `RouterOutlet` that renders a native stack instead of swapping one view for another.\n *\n * The outlet's host element *is* the `RNSScreenStack`, and each activated route's component is\n * created directly on its own `screen` child rather than on a wrapper view inside it (ADR 0004).\n * The screens below the top stay mounted, which is what keeps a pushed-away screen's native\n * state alive: its scroll offset, its text cursor, its keyboard focus.\n *\n * Push and pop are inferred from the calls the router already makes. With a reuse strategy that\n * detaches, navigating forward is `detach()` then `activateWith()`, and navigating back is\n * `detach()` then `attach(ref)` with a ref we handed out earlier. Finding that ref in our own\n * stack is what identifies a pop, so nothing here needs to consult the URL.\n *\n * Note `activityState` is set once, to active, and never lowered. `Screen.tsx` throws on any\n * decrease while `isNativeStack`, because a native stack decides what is visible from the order\n * of its children rather than from a per-screen flag. Toggling that flag is for `ScreenContainer`\n * (tabs), where every screen is mounted at once.\n */\nimport {\n ApplicationRef,\n Component,\n DestroyRef,\n ElementRef,\n ErrorHandler,\n HostAttributeToken,\n InjectionToken,\n Injector,\n Renderer2,\n afterEveryRender,\n computed,\n createComponent,\n inject,\n signal,\n type ComponentRef,\n type EnvironmentInjector,\n type OnInit,\n type Type,\n type WritableSignal,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n ChildrenOutletContexts,\n NavigationCancel,\n NavigationEnd,\n NavigationError,\n PRIMARY_OUTLET,\n Router,\n createUrlTreeFromSnapshot,\n type Data,\n type RouterOutletContract,\n} from '@angular/router';\nimport { Location, PlatformLocation } from '@angular/common';\nimport { SCREEN_IN_FRONT } from '@ng-native/device';\nimport { bindRouteInputs } from './bind-route-inputs.ts';\nimport { NativeBack, isShowing } from './native-back.ts';\nimport { intentOf, type NativeIntent } from './native-navigation.ts';\nimport { NativePlatformLocation } from './native-platform-location.ts';\nimport { PRESENTED, withoutPresented } from './presented-route.ts';\nimport { markScreenRoute } from './tab-routes.ts';\nimport { ownHost } from './own-host.ts';\nimport { HostEngine, type EngineNode } from '@ng-native/fabric';\nimport type { ScreenPresentation } from './screen-presentation.ts';\nimport { ActivityState } from './screens.ts';\n\ninterface StackEntry {\n route: ActivatedRoute;\n ref: ComponentRef<unknown>;\n /** The `screen` element this entry's component lives inside. */\n screen: unknown;\n /** True while the router is holding this ref for a later `attach`. */\n detached: boolean;\n /** Stops feeding route params into the component's inputs. */\n unbind: () => void;\n /** How the screen was put on screen, for a push from it to follow. */\n presentation?: ScreenPresentation;\n /** The navigation that put this screen on the stack, until that navigation ends. */\n activatedIn?: number;\n /** The navigation that covered this screen, until that navigation ends. */\n detachedIn?: number;\n /** Whether this screen is the one in front, for what it holds: see `SCREEN_IN_FRONT`. */\n inFront: WritableSignal<boolean>;\n}\n\n/**\n * The last navigation, per router, whose presentation an outlet has already given a screen.\n *\n * Presenting a route that is a stack of its own activates two outlets in one navigation: the one\n * the route is presented in, and the one inside it that shows the route's first child. Only the\n * first is presented; the second is the first screen of a stack inside a presented screen, and a\n * push inside that stack must see it as a pushed screen, not one to present over.\n */\nconst presented = new WeakMap<object, number>();\n\n/** What every screen needs to fill the stack, the same five keys RNSScreen itself expects. */\nconst FILL = { position: 'absolute', left: 0, right: 0, top: 0, bottom: 0 } as const;\n\n/** A swipe-back area with no limit on any edge. */\nconst UNLIMITED_SWIPE = { start: -1, end: -1, top: -1, bottom: -1 } as const;\n\n/**\n * The screen a page lives in, for a stack inside that page. A presented screen with a header is\n * such a stack, and the page that knows whether to refuse a dismissal is a screen inside it, where\n * the screen a swipe down dismisses is this one.\n */\nconst HOLDING_SCREEN = new InjectionToken<HoldingScreen>('ng-native.router.holding-screen');\n\ninterface HoldingScreen {\n readonly screen: unknown;\n /**\n * Told when a stack inside the screen changes what the screen refuses, so the stack the screen\n * is in can pass that on in turn, in the same render: its own look came before this one.\n */\n refusalChanged(): void;\n}\n\n/** Whether a screen refuses a native dismissal, as its page bound it. */\nconst refuses = (screen: unknown): boolean =>\n (screen as Partial<EngineNode> | undefined)?.props?.['preventNativeDismiss'] === true;\n\n/** The native engine's `dispatchEvent`, as Fabric calls it. */\ntype NativeDispatch = (node: unknown, topLevelType: string, nativeEvent: unknown) => void;\n\n@Component({\n selector: 'native-stack-outlet',\n template: '',\n host: { '[style]': 'fill' },\n})\nexport class NativeStackOutlet implements RouterOutletContract, OnInit {\n /**\n * Named outlets work exactly as on the web: `<native-stack-outlet name=\"list\" />` is filled by\n * routes with `outlet: 'list'`. The default is the primary one. Read once, as the router's own\n * outlet reads it, since an outlet cannot change which contexts it is registered under.\n */\n readonly name = inject(new HostAttributeToken('name'), { optional: true }) ?? PRIMARY_OUTLET;\n\n readonly supportsBindingToComponentInputs = true;\n\n private readonly parentContexts = inject(ChildrenOutletContexts);\n private readonly renderer = inject(Renderer2);\n private readonly applicationRef = inject(ApplicationRef);\n private readonly injector = inject(Injector);\n private readonly host = inject(ElementRef);\n private readonly location = inject(Location);\n private readonly history = inject(PlatformLocation);\n /**\n * Only for the intent a navigation carries. Optional so the outlet can be exercised through\n * `RouterOutletContract` directly, which is how its own tests drive it.\n */\n private readonly router = inject(Router, { optional: true });\n /** For a refused back to reach the screen as native's own report would. */\n private readonly engine = inject(HostEngine, { optional: true });\n\n private readonly errors = inject(ErrorHandler);\n /** The screen this stack sits in, when it is a stack inside a page of another. */\n private readonly holder = inject(HOLDING_SCREEN, { optional: true });\n /** What the holder's own `preventNativeDismiss` was, while this stack's top screen refuses. */\n private held: { own: unknown } | null = null;\n\n private readonly entries: StackEntry[] = [];\n /**\n * The screens a replace or a reset supersedes, kept until the navigation that supersedes them\n * succeeds: one that fails leaves the stack as it was.\n */\n private superseded: { entries: StackEntry[]; navigation: number } | null = null;\n\n protected readonly fill = { flex: 1 };\n\n constructor() {\n ownHost(this.host.nativeElement);\n // Ours, not a prop of the native stack.\n delete (this.host.nativeElement as { props: Record<string, unknown> }).props['name'];\n this.parentContexts.onChildOutletCreated(this.name, this);\n\n // Android's back button, and `NativeNavigation.back()`. Declining at the bottom of the stack\n // is deliberate: the outlet this one sits in gets its turn, and when none takes it the\n // platform backgrounds the app, which is what a user expects, rather than the app swallowing\n // the press and appearing stuck.\n //\n // Not yet verified on a device: whether react-native-screens' own Android back handling\n // (`nativeBackButtonDismissalEnabled`) also pops the screen, which would make one press pop\n // twice. If a back press ever skips a screen on Android, look here first.\n const back = inject(NativeBack);\n const unsubscribeBack = back.handle((from) =>\n from === 'button' && this.refusesButton() ? true : this.goBack(),\n );\n const unsubscribeStack = back.addStack({\n showing: () => this.isShowing(),\n popToRoot: () => (this.entries.length > 1 ? this.popToEntry(0) : null),\n popTo: (url) => {\n const index = this.entries.findIndex((entry) => this.urlOf(entry) === url);\n return index !== -1 && index < this.entries.length - 1 ? this.popToEntry(index) : null;\n },\n });\n // Optional for the same reason as the router: the outlet's own tests stand one in without it.\n const navigations = this.router?.events?.subscribe((event) => {\n if (event instanceof NavigationEnd) this.settle(event.id);\n else if (event instanceof NavigationError) this.rollBack(event.id);\n });\n\n const unhold = this.holder ? this.holdRefusals(this.holder) : undefined;\n const unpresent = this.takePresentedPages(back);\n\n inject(DestroyRef).onDestroy(() => {\n unhold?.();\n unpresent?.();\n unsubscribeBack();\n unsubscribeStack();\n navigations?.unsubscribe();\n for (const entry of this.entries) {\n entry.unbind();\n entry.ref.destroy();\n }\n this.entries.length = 0;\n this.parentContexts.onChildOutletDestroyed(this.name);\n });\n }\n\n /** The page presented over everything, while there is one. See `presented-route.ts`. */\n private presentedPage: (StackEntry & { stopBack(): void }) | null = null;\n\n /**\n * The app's own stack, the one in the root component, is also the root's presented outlet: a\n * page of a tab that is not in front is shown here, as a screen over the bar and everything in\n * it. One page at a time, which the router sees to, and never kept: it is dismissed.\n */\n private takePresentedPages(back: NativeBack): (() => void) | undefined {\n const router = this.router;\n const root = inject(ActivatedRoute, { optional: true });\n if (!router?.routerState || this.name !== PRIMARY_OUTLET || root !== router.routerState.root) {\n return undefined;\n }\n const page = () => this.presentedPage;\n const outlet: RouterOutletContract = {\n supportsBindingToComponentInputs: true,\n get isActivated() {\n return page() !== null;\n },\n get component() {\n return (page()?.ref.instance as Object | undefined) ?? null;\n },\n get activatedRoute() {\n return page()?.route ?? null;\n },\n get activatedRouteData() {\n return page()?.route.snapshot.data ?? {};\n },\n activateWith: (route, environmentInjector) =>\n this.presentPage(route, environmentInjector, back),\n deactivate: () => this.dropPresentedPage(),\n detach: () => {\n throw new Error('[angular-native] a presented page is dismissed, not detached');\n },\n attach: () => {\n throw new Error('[angular-native] a presented page is not kept to attach again');\n },\n };\n this.parentContexts.onChildOutletCreated(PRESENTED, outlet);\n back.presents = true;\n return () => {\n back.presents = false;\n this.dropPresentedPage();\n this.parentContexts.onChildOutletDestroyed(PRESENTED);\n };\n }\n\n private presentPage(\n route: ActivatedRoute,\n environmentInjector: EnvironmentInjector,\n back: NativeBack,\n ): void {\n const component = (route.component ?? route.snapshot.component) as Type<unknown> | null;\n if (!component) throw new Error('[angular-native] route has no component to present');\n const presentation = this.claimPresentation(this.currentIntent()) ?? {\n stackPresentation: 'modal',\n };\n const screen = this.createScreen(presentation, () => this.dismissPresentedPage());\n const inFront = signal(true);\n const { ref, unbind } = this.createPage(\n component,\n route,\n environmentInjector,\n screen,\n inFront,\n PRESENTED,\n );\n this.fillScreen(screen);\n // Subscribed now, so it is the newest answer and the first asked: a back dismisses the page\n // before it pops anything in the tab under it.\n const stopBack = back.handle(() => this.dismissPresentedPage());\n this.presentedPage = {\n route,\n ref,\n screen,\n detached: false,\n unbind,\n presentation,\n inFront,\n stopBack,\n };\n }\n\n /** The router left the presented page: take it off the stack. */\n private dropPresentedPage(): void {\n const page = this.presentedPage;\n if (!page) return;\n this.presentedPage = null;\n page.stopBack();\n this.drop(page);\n }\n\n /**\n * Take the router off the presented page, for a back or for a sheet the user swiped away: one\n * entry back where that is the url without the page, and otherwise a navigation to that url in\n * place of this entry, since something under the page was navigated while it was up.\n */\n private dismissPresentedPage(): boolean {\n if (!this.presentedPage || !this.router) return false;\n const without = withoutPresented(this.router, this.router.url);\n if (this.historyUrl(-1) === without) this.location.historyGo(-1);\n else void this.router.navigateByUrl(without, { replaceUrl: true });\n return true;\n }\n\n /** The screens currently in the stack, oldest first. Exposed for tests. */\n get depth(): number {\n return this.entries.length;\n }\n\n ngOnInit(): void {\n this.activateCurrentRoute();\n }\n\n /**\n * The route the router is already on, for an outlet created after the navigation that reached\n * it: one held behind a condition until a session or a database is ready. The router activates\n * an outlet as a navigation ends, and that one ended with no outlet to activate, so the outlet\n * takes the route from its context as it arrives, as Angular's own `RouterOutlet` does.\n */\n private activateCurrentRoute(): void {\n if (this.isActivated) return;\n const context = this.parentContexts.getContext(this.name);\n if (!context?.route) return;\n if (context.attachRef) this.attach(context.attachRef, context.route);\n else this.activateWith(context.route, context.injector);\n }\n\n // --- RouterOutletContract ----------------------------------------------\n\n get isActivated(): boolean {\n return this.top !== undefined && !this.top.detached;\n }\n\n get component(): Object | null {\n return this.top && !this.top.detached ? (this.top.ref.instance as Object) : null;\n }\n\n get activatedRoute(): ActivatedRoute | null {\n return this.top && !this.top.detached ? this.top.route : null;\n }\n\n get activatedRouteData(): Data {\n return this.activatedRoute?.snapshot.data ?? {};\n }\n\n /** The input binder reads this to bind route params to component inputs. */\n get activatedComponentRef(): ComponentRef<unknown> | null {\n return this.top?.ref ?? null;\n }\n\n activateWith(route: ActivatedRoute, environmentInjector: EnvironmentInjector): void {\n const component = (route.component ?? route.snapshot.component) as Type<unknown> | null;\n if (!component) {\n throw new Error('[angular-native] route has no component to activate');\n }\n // Whatever a stack shows is a screen, children or not, and must survive being covered.\n if (route.snapshot.routeConfig) markScreenRoute(route.snapshot.routeConfig);\n\n // What kind of navigation this is, over and above which route it lands on: a replace\n // supersedes the screen below rather than stacking on it, and a reset empties the stack.\n // Everything else leaves the screens below mounted, so their native state survives the trip.\n const intent = this.currentIntent();\n const navigation = this.navigationId();\n const presentation = this.presentationFor(intent);\n //\n // The screen is the page's host element, so its props are set before the component exists\n // and the component's own host bindings land on top of them. Style bindings merge key by\n // key, so a page styling itself keeps the absolute fill the stack lays out with - except for\n // `position` and the four insets, which a page naming them writes over outright rather than\n // merging into. Those five are re-asserted below, after the page's own change detection has\n // run, so the outlet's positioning always wins whatever a page's host style says.\n const screen = this.createScreen(presentation);\n const inFront = signal(true);\n const { ref, unbind } = this.createPage(component, route, environmentInjector, screen, inFront);\n // The page's own host style, including any `position` or inset it declared, has now landed\n // on the screen: put the stack's fill back over it. Per-key, through `setStyle`, so whatever\n // else the page's style set - a background colour, say - still merges and stays.\n this.fillScreen(screen);\n\n if (intent?.stack === 'reset') this.supersede(this.entries.slice(), navigation);\n else if (intent?.stack === 'replace' && this.top) this.supersede([this.top], navigation);\n this.entries.push({\n route,\n ref,\n screen,\n detached: false,\n unbind,\n presentation,\n activatedIn: navigation,\n inFront,\n });\n }\n\n /**\n * The page's component, created on its screen and rendered once.\n *\n * A page that throws on that first render fails the navigation, and nothing of it may stay: a\n * half-made screen left on the stack is one the router does not know about, with a component\n * still running on it. So its component is destroyed, its screen taken off the stack, the\n * screen it was pushed from given back its change detection, and the error handed to the\n * app's `ErrorHandler` before the router fails the navigation with it.\n */\n private createPage(\n component: Type<unknown>,\n route: ActivatedRoute,\n environmentInjector: EnvironmentInjector,\n screen: unknown,\n inFront: WritableSignal<boolean>,\n outlet = this.name,\n ): { ref: ComponentRef<unknown>; unbind: () => void } {\n let ref: ComponentRef<unknown> | undefined;\n let unbind: (() => void) | undefined;\n try {\n ref = createComponent(component, {\n environmentInjector,\n elementInjector: this.outletInjector(route, inFront, screen, outlet),\n hostElement: screen as Element,\n });\n this.applicationRef.attachView(ref.hostView);\n // Route params onto inputs before the first change detection, not after: a required input\n // read in the template throws NG0950 if it is still unset when the page first renders.\n unbind = this.bindInputs(ref, route);\n // Before anything can commit. Creating the page's nodes dirties the tree, which schedules a\n // commit of its own - and that commit would capture the page with its elements created and\n // its bindings not yet applied. On iOS the props catch up a frame later and nobody sees it;\n // on Android the flattening decision is made from the props a view is created with, so a\n // content wrapper that arrives without its `collapsable: false` is flattened for good and\n // its children end up parented to a scroll view that allows exactly one.\n ref.changeDetectorRef.detectChanges();\n return { ref, unbind };\n } catch (error) {\n unbind?.();\n ref?.destroy();\n this.removeScreen(screen);\n this.uncover();\n this.errors.handleError(error);\n throw error;\n }\n }\n\n /**\n * Take the screen in front off the stack, when there is one: nothing once the router has\n * detached it, as Angular's own outlet does nothing then. A route with no component of its own,\n * a `loadChildren` wrapper or a group, has the router detach the page under it and then\n * deactivate this same outlet, and that page is a screen pushed from, still to come back to.\n */\n deactivate(): void {\n if (!this.isActivated) return;\n this.drop(this.entries.pop()!);\n }\n\n /**\n * Hand the live `ComponentRef` back to the router without destroying it. The screen stays\n * mounted, so the component keeps running and its native views keep their state.\n */\n detach(): ComponentRef<unknown> {\n const entry = this.top;\n if (!entry) throw new Error('[angular-native] outlet is not activated, nothing to detach');\n entry.detached = true;\n entry.detachedIn = this.navigationId();\n entry.inFront.set(false);\n // `ChangeDetectorRef.detach`, not `ApplicationRef.detachView`. The latter calls\n // `renderDetachView` and pulls the view's nodes out of the tree, which is exactly what we\n // are trying to avoid: the screen would vanish from the stack the moment we pushed past it.\n // This stops change detection for an off-screen screen while leaving it mounted.\n entry.ref.hostView.detach();\n return entry.ref;\n }\n\n /**\n * Re-attach a previously detached ref. If we still hold it, everything stacked above it is a\n * screen the user has navigated back past, so those are destroyed: that is the pop.\n */\n attach(ref: ComponentRef<unknown>, route: ActivatedRoute): void {\n const index = this.entries.findIndex((entry) => entry.ref === ref);\n\n if (index === -1) {\n // Not ours: the router is restoring a ref detached by a different outlet instance. Its\n // host element is already a screen, complete with the `dismissed` listener that outlet\n // registered, so it is re-parented rather than rebuilt.\n const screen = ref.location.nativeElement;\n this.renderer.appendChild(this.host.nativeElement, screen);\n this.entries.push({\n route,\n ref,\n screen,\n detached: false,\n unbind: this.bindInputs(ref, route),\n // What it was given is its first outlet's; this one has no say over that screen's.\n inFront: signal(true),\n });\n this.applicationRef.attachView(ref.hostView);\n } else {\n for (const above of this.entries.splice(index + 1)) this.drop(above);\n const entry = this.entries[index]!;\n entry.detached = false;\n entry.inFront.set(true);\n entry.route = route;\n // The route object is new even when the url is not, so the inputs follow the new one.\n entry.unbind();\n entry.unbind = this.bindInputs(ref, route);\n }\n\n // Resume change detection for the screen the user is coming back to.\n ref.hostView.reattach();\n }\n\n // --- native stack -------------------------------------------------------\n\n /**\n * Route params onto the page's inputs, but only in an app that asked for it with\n * `withComponentInputBinding()`, which is the only time Angular's own outlet binds them. Read\n * per screen rather than once, for a test that stands the router in.\n */\n private bindInputs(ref: ComponentRef<unknown>, route: ActivatedRoute): () => void {\n return this.router?.componentInputBindingEnabled ? bindRouteInputs(ref, route) : () => {};\n }\n\n private get top(): StackEntry | undefined {\n return this.entries[this.entries.length - 1];\n }\n\n /**\n * What the navigation asked for, if it asked for anything. Read here rather than remembered,\n * because the router is mid-navigation for exactly as long as an activation takes.\n */\n private currentIntent(): NativeIntent | null {\n return intentOf(this.router?.getCurrentNavigation()?.extras.state);\n }\n\n /**\n * How the screen a navigation activates is put on screen.\n *\n * A push on top of a presented screen is presented the same way. `RNSScreenStack` pushes a push\n * screen that follows a modal onto the navigation controller under the modal, so the router\n * would be on the new route while the modal stayed in front, and the modal's own way out would\n * first pop a screen nobody could see. A presentation the navigation names itself wins, and a\n * reset starts a stack with nothing to follow. A presented screen that is a stack of its own is\n * where a push to one of its children goes instead, inside it.\n */\n private presentationFor(intent: NativeIntent | null): ScreenPresentation | undefined {\n const own = this.claimPresentation(intent);\n const covering = this.top?.presentation?.stackPresentation;\n if (intent?.stack === 'reset' || !covering || covering === 'push' || own?.stackPresentation) {\n return own;\n }\n return { ...own, stackPresentation: covering };\n }\n\n /** The navigation's own presentation, unless an outlet further out already presented it. */\n private claimPresentation(intent: NativeIntent | null): ScreenPresentation | undefined {\n if (!intent?.presentation) return undefined;\n const id = this.router?.getCurrentNavigation()?.id;\n if (id === undefined) return intent.presentation;\n if (presented.get(this.router!) === id) return undefined;\n presented.set(this.router!, id);\n return intent.presentation;\n }\n\n /** Take a screen out for good: its bindings, its component, and its native view. */\n private drop(entry: StackEntry): void {\n entry.unbind();\n entry.ref.destroy();\n this.removeScreen(entry.screen);\n }\n\n /** Take one entry out of the stack, wherever it is, and drop it. */\n private remove(entry: StackEntry): void {\n const index = this.entries.indexOf(entry);\n if (index === -1) return;\n this.entries.splice(index, 1);\n this.drop(entry);\n }\n\n // --- a navigation's outcome ----------------------------------------------\n\n /** The id of the navigation in progress, when there is a router to say. */\n private navigationId(): number | undefined {\n return this.router?.getCurrentNavigation()?.id;\n }\n\n /**\n * Take out the screens a replace or a reset supersedes once its navigation has succeeded, or\n * at once when there is no navigation to wait for. A replaced screen has already been detached\n * by the router, and with `replaceUrl` its history entry is gone too, so nothing will attach it\n * again; the reuse strategy notices the ref is destroyed and drops its handle.\n */\n private supersede(entries: StackEntry[], navigation: number | undefined): void {\n if (navigation === undefined) {\n for (const entry of entries) this.remove(entry);\n return;\n }\n this.superseded = { entries, navigation };\n }\n\n /** A navigation succeeded: what it superseded goes, and what it did is no longer undoable. */\n private settle(navigation: number): void {\n if (this.superseded?.navigation === navigation) {\n for (const entry of this.superseded.entries) this.remove(entry);\n this.superseded = null;\n }\n for (const entry of this.entries) {\n if (entry.activatedIn === navigation) entry.activatedIn = undefined;\n if (entry.detachedIn === navigation) entry.detachedIn = undefined;\n }\n }\n\n /**\n * A navigation failed, so the router is back where it started: undo what it did here too.\n *\n * The screen that threw has already gone (`createPage`), but a screen this outlet activated for\n * the same navigation has not when the one that threw is further in, the first screen of a\n * stack inside it. That one goes, with everything in it, and the screen it covered carries on.\n */\n private rollBack(navigation: number): void {\n if (this.superseded?.navigation === navigation) this.superseded = null;\n for (const entry of this.entries.filter((candidate) => candidate.activatedIn === navigation)) {\n this.remove(entry);\n }\n this.uncover(navigation);\n }\n\n /**\n * Give the top screen back its change detection when the router covered it for a navigation\n * that is not going to happen: the one given, or the one in progress.\n */\n private uncover(navigation = this.navigationId()): void {\n const top = this.top;\n if (!top?.detached || top.detachedIn !== navigation) return;\n top.detached = false;\n top.detachedIn = undefined;\n top.inFront.set(true);\n top.ref.hostView.reattach();\n }\n\n /**\n * `position: absolute` and the four insets, through `setStyle` rather than one `setProperty`\n * so each key merges into whatever style is already on the screen instead of replacing it -\n * the same merge a page's own host style gets, just asserted last so the stack's layout wins.\n */\n private fillScreen(screen: unknown): void {\n for (const [key, value] of Object.entries(FILL)) {\n this.renderer.setStyle(screen as Element, key, value);\n }\n }\n\n private createScreen(\n presentation?: ScreenPresentation,\n dismissed = (count: number) => this.onNativeDismiss(count),\n ): unknown {\n const screen = ownHost(this.renderer.createElement('screen'));\n this.fillScreen(screen);\n // Set once and never lowered: see the note at the top of this file.\n this.renderer.setProperty(screen, 'activityState', ActivityState.Active);\n // A swipe-back or an Android back button pops the screen natively and only then tells JS.\n // Without this the native stack and the router disagree from that moment on: the screen is\n // gone but the URL still points at it, so the next navigation starts from the wrong place.\n this.renderer.listen(\n screen,\n 'dismissed',\n (event: { nativeEvent?: { dismissCount?: number } }) =>\n dismissed(event?.nativeEvent?.dismissCount ?? 1),\n );\n // Every key is a prop `RNSScreen` already declares, spelled the way the codegen spec spells\n // it, so this forwards rather than translates. Set before the screen joins the stack: the\n // native side reads the presentation as it mounts.\n for (const [prop, value] of Object.entries(presentation ?? {})) {\n if (value !== undefined) this.renderer.setProperty(screen, prop, value);\n }\n // Except this one, which is a struct with no default: an edge left out is 0 natively, and\n // `RNSScreenStack` refuses a swipe-back that starts beyond 0 points. -1 is no limit, which is\n // what `Screen.tsx` sends for every edge not given.\n this.renderer.setProperty(screen, 'gestureResponseDistance', {\n ...UNLIMITED_SWIPE,\n ...presentation?.gestureResponseDistance,\n });\n\n this.renderer.appendChild(this.host.nativeElement, screen);\n return screen;\n }\n\n /**\n * Follow a pop the user already made. `historyGo`, not `back()`, because iOS coalesces a long\n * swipe into a single event with a count.\n *\n * Only ever fires for a native dismissal: verified on device that a pop this outlet drives\n * itself emits `willAppear`/`appear` for the screen below but no `dismissed`, so there is no\n * double-pop to guard against.\n *\n * The gesture itself is unverified by tooling: idb cannot synthesise a `UIScreenEdgePan` that\n * UIKit accepts, so this path was reasoned from the events rather than driven end to end.\n */\n private onNativeDismiss(count: number): void {\n this.popBy(Math.max(1, count));\n }\n\n /**\n * A back, from the button or `NativeNavigation`: pop the top screen, as long as there is one\n * below it and this stack is the one the user is looking at. A stack in a tab behind, or under\n * a screen pushed over the tab bar, is still subscribed, and the newest one would otherwise\n * answer for the stack in front.\n */\n /**\n * Android's Back button is the platform's own dismissal there, and react-native-screens leaves\n * it to JS: its Android screen ignores `preventNativeDismiss`. So a top screen that sets it\n * refuses the press here, as iOS refuses a swipe, and hears `nativeDismissCancelled` the same\n * way, through the engine, as if native had sent it.\n */\n private refusesButton(): boolean {\n if (this.entries.length < 2 || !this.isShowing()) return false;\n const screen = this.top!.screen as EngineNode;\n if (screen.props['preventNativeDismiss'] !== true) return false;\n // The native engine's own entry point for an event, the one Fabric calls. Not on\n // `HostEngine`, because only a native host has a screen to refuse with.\n const native = this.engine as { dispatchEvent?: NativeDispatch } | null;\n native?.dispatchEvent?.(screen, 'topNativeDismissCancelled', { dismissCount: 1 });\n return true;\n }\n\n /**\n * Passes the top screen's refusal to the screen this stack sits in, and that screen's report of\n * an attempt back to the top screen: the swipe that dismisses a presented stack is on the\n * screen holding it, which the page inside cannot bind.\n *\n * Read after every render, since the refusal is a host binding of whatever page is on top.\n */\n private holdRefusals(holder: HoldingScreen): () => void {\n const render = afterEveryRender(() => this.holdRefusal(holder));\n const unlisten = this.renderer.listen(\n holder.screen,\n 'nativeDismissCancelled',\n (event: { nativeEvent?: unknown }) => {\n // The stack can have lost its last screen with the refusal not yet released.\n const top = this.top;\n if (!this.held || !top) return;\n const native = this.engine as { dispatchEvent?: NativeDispatch } | null;\n const report = event?.nativeEvent ?? { dismissCount: 1 };\n native?.dispatchEvent?.(top.screen, 'topNativeDismissCancelled', report);\n },\n );\n return () => {\n render.destroy();\n unlisten();\n this.release(holder);\n };\n }\n\n private holdRefusal(holder: HoldingScreen): void {\n // A stack in a tab behind is inside the same screen, and has no say in it.\n if (!refuses(this.top?.screen) || !this.isShowing()) return this.release(holder);\n if (refuses(holder.screen)) return;\n // ponytail: the holder's own binding is read when the top screen starts refusing. One that\n // turns true while it does is put back as it was then; bind the refusal in one of the two.\n this.held = { own: (holder.screen as EngineNode).props?.['preventNativeDismiss'] };\n this.renderer.setProperty(holder.screen, 'preventNativeDismiss', true);\n holder.refusalChanged();\n }\n\n /** The holder's own answer again, once the top screen no longer refuses. */\n private release(holder: HoldingScreen): void {\n if (!this.held) return;\n this.renderer.setProperty(holder.screen, 'preventNativeDismiss', this.held.own ?? false);\n this.held = null;\n holder.refusalChanged();\n }\n\n private goBack(): boolean {\n if (this.entries.length < 2 || !this.isShowing()) return false;\n this.popBy(1);\n return true;\n }\n\n /** Whether the top screen is part of what the router shows now. Assumed without a router. */\n private isShowing(): boolean {\n if (!this.router) return true;\n return this.isActivated && isShowing(this.router, this.top!.route);\n }\n\n /**\n * Take the router to the screen `steps` below the top, whether native already popped it or it\n * is about to be popped because the router arrives there.\n */\n private popBy(steps: number): void {\n const below = this.entries[this.entries.length - 1 - steps];\n const url = below && this.router ? this.urlOf(below) : null;\n // Usually the entry that far back is the screen the pop revealed, and going back through\n // history keeps it tidy. Not always: a stack inside a tab shares history with the other tabs,\n // so after a trip to one and back the entry behind the top screen is that other tab, and\n // going back would switch tab rather than pop. Then the router is sent to the revealed\n // screen instead, replacing the entry of the one that is gone.\n const behind = this.historyUrl(-steps);\n if (!url || behind === undefined || behind === url) {\n this.location.historyGo(-steps);\n return;\n }\n void this.router!.navigateByUrl(url, { replaceUrl: true });\n }\n\n /**\n * Take the router down to the screen at `index`, popping every screen above it together.\n * Through history when the entries behind are these screens, so going back from there keeps\n * working one screen at a time; otherwise by a navigation to it that replaces the entry, as\n * `popBy` does when a tab's history interleaves.\n */\n private popToEntry(index: number): Promise<boolean> {\n const url = this.urlOf(this.entries[index]!);\n const steps = this.entries.length - 1 - index;\n if (this.historyUrl(-steps) === url) {\n const arrived = this.nextNavigation();\n this.location.historyGo(-steps);\n return arrived;\n }\n return this.router!.navigateByUrl(url, { replaceUrl: true });\n }\n\n /** Whether the navigation that happens next succeeds. */\n private nextNavigation(): Promise<boolean> {\n return new Promise((resolve) => {\n const events = this.router!.events.subscribe((event) => {\n if (event instanceof NavigationEnd) resolve(true);\n else if (event instanceof NavigationError || event instanceof NavigationCancel) {\n resolve(false);\n } else return;\n events.unsubscribe();\n });\n });\n }\n\n /** The url a screen was showing when it was covered, rebuilt from its own route snapshot. */\n private urlOf(entry: StackEntry): string {\n const snapshot = entry.route.snapshot;\n const tree = createUrlTreeFromSnapshot(snapshot, [], snapshot.queryParams, snapshot.fragment);\n return this.router!.serializeUrl(tree);\n }\n\n /**\n * The url of the history entry `offset` away, normalised the way the router writes it: null past\n * the start of history, and undefined when the history is not ours to read, so the pop has to go\n * through it blind.\n */\n private historyUrl(offset: number): string | null | undefined {\n if (!(this.history instanceof NativePlatformLocation)) return undefined;\n const url = this.history.ɵurlAt(offset);\n return url === null ? null : this.router!.serializeUrl(this.router!.parseUrl(url));\n }\n\n private removeScreen(screen: unknown): void {\n this.renderer.removeChild(this.host.nativeElement, screen);\n }\n\n /**\n * What a page is created with: its route, its screen, the outlet contexts its own outlets\n * register in, and whether its screen is in front - which is this screen's own say and, for a stack inside a\n * screen of another, that screen's too.\n */\n private outletInjector(\n route: ActivatedRoute,\n inFront: WritableSignal<boolean>,\n screen: unknown,\n outlet = this.name,\n ): Injector {\n const outer = this.injector.get(SCREEN_IN_FRONT);\n return Injector.create({\n parent: this.injector,\n providers: [\n { provide: SCREEN_IN_FRONT, useValue: computed(() => outer() && inFront()) },\n {\n provide: HOLDING_SCREEN,\n useValue: {\n screen,\n refusalChanged: () => this.holder && this.holdRefusal(this.holder),\n } satisfies HoldingScreen,\n },\n { provide: ActivatedRoute, useValue: route },\n {\n provide: ChildrenOutletContexts,\n useValue: this.parentContexts.getOrCreateContext(outlet).children,\n },\n ],\n });\n }\n}\n"]}
1
+ {"version":3,"file":"native-stack-outlet.js","sourceRoot":"","sources":["../src/native-stack-outlet.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A `RouterOutlet` that renders a native stack instead of swapping one view for another.\n *\n * The outlet's host element *is* the `RNSScreenStack`, and each activated route's component is\n * created directly on its own `screen` child rather than on a wrapper view inside it (ADR 0004).\n * The screens below the top stay mounted, which is what keeps a pushed-away screen's native\n * state alive: its scroll offset, its text cursor, its keyboard focus.\n *\n * Push and pop are inferred from the calls the router already makes. With a reuse strategy that\n * detaches, navigating forward is `detach()` then `activateWith()`, and navigating back is\n * `detach()` then `attach(ref)` with a ref we handed out earlier. Finding that ref in our own\n * stack is what identifies a pop, so nothing here needs to consult the URL.\n *\n * Note `activityState` is set once, to active, and never lowered. `Screen.tsx` throws on any\n * decrease while `isNativeStack`, because a native stack decides what is visible from the order\n * of its children rather than from a per-screen flag. Toggling that flag is for `ScreenContainer`\n * (tabs), where every screen is mounted at once.\n */\nimport {\n ApplicationRef,\n Component,\n DestroyRef,\n ElementRef,\n ErrorHandler,\n HostAttributeToken,\n InjectionToken,\n Injector,\n Renderer2,\n afterEveryRender,\n computed,\n createComponent,\n inject,\n signal,\n type ComponentRef,\n type EnvironmentInjector,\n type OnInit,\n type Type,\n type WritableSignal,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n ChildrenOutletContexts,\n NavigationCancel,\n NavigationEnd,\n NavigationError,\n PRIMARY_OUTLET,\n Router,\n createUrlTreeFromSnapshot,\n type Data,\n type RouterOutletContract,\n} from '@angular/router';\nimport { Location, PlatformLocation } from '@angular/common';\nimport { SCREEN_IN_FRONT } from '@ng-native/device';\nimport { bindRouteInputs } from './bind-route-inputs.ts';\nimport { NativeBack, isShowing } from './native-back.ts';\nimport { intentOf, type NativeIntent } from './native-navigation.ts';\nimport { NativePlatformLocation } from './native-platform-location.ts';\nimport { PRESENTED, withoutPresented } from './presented-route.ts';\nimport { markScreenRoute } from './tab-routes.ts';\nimport { ownHost } from './own-host.ts';\nimport { SCREEN_HEADER } from './screen-header.ts';\nimport { HostEngine, type EngineNode } from '@ng-native/fabric';\nimport type { ScreenPresentation } from './screen-presentation.ts';\nimport { ActivityState } from './screens.ts';\n\ninterface StackEntry {\n route: ActivatedRoute;\n ref: ComponentRef<unknown>;\n /** The `screen` element this entry's component lives inside. */\n screen: unknown;\n /** True while the router is holding this ref for a later `attach`. */\n detached: boolean;\n /** Stops feeding route params into the component's inputs. */\n unbind: () => void;\n /** How the screen was put on screen, for a push from it to follow. */\n presentation?: ScreenPresentation;\n /** The navigation that put this screen on the stack, until that navigation ends. */\n activatedIn?: number;\n /** The navigation that covered this screen, until that navigation ends. */\n detachedIn?: number;\n /** Whether this screen is the one in front, for what it holds: see `SCREEN_IN_FRONT`. */\n inFront: WritableSignal<boolean>;\n}\n\n/**\n * The last navigation, per router, whose presentation an outlet has already given a screen.\n *\n * Presenting a route that is a stack of its own activates two outlets in one navigation: the one\n * the route is presented in, and the one inside it that shows the route's first child. Only the\n * first is presented; the second is the first screen of a stack inside a presented screen, and a\n * push inside that stack must see it as a pushed screen, not one to present over.\n */\nconst presented = new WeakMap<object, number>();\n\n/** What every screen needs to fill the stack, the same five keys RNSScreen itself expects. */\nconst FILL = { position: 'absolute', left: 0, right: 0, top: 0, bottom: 0 } as const;\n\n/** A swipe-back area with no limit on any edge. */\nconst UNLIMITED_SWIPE = { start: -1, end: -1, top: -1, bottom: -1 } as const;\n\n/**\n * The screen a page lives in, for a stack inside that page. A presented screen with a header is\n * such a stack, and the page that knows whether to refuse a dismissal is a screen inside it, where\n * the screen a swipe down dismisses is this one.\n */\nconst HOLDING_SCREEN = new InjectionToken<HoldingScreen>('ng-native.router.holding-screen');\n\ninterface HoldingScreen {\n readonly screen: unknown;\n /**\n * Told when a stack inside the screen changes what the screen refuses, so the stack the screen\n * is in can pass that on in turn, in the same render: its own look came before this one.\n */\n refusalChanged(): void;\n}\n\n/** Whether a screen refuses a native dismissal, as its page bound it. */\nconst refuses = (screen: unknown): boolean =>\n (screen as Partial<EngineNode> | undefined)?.props?.['preventNativeDismiss'] === true;\n\n/** The native engine's `dispatchEvent`, as Fabric calls it. */\ntype NativeDispatch = (node: unknown, topLevelType: string, nativeEvent: unknown) => void;\n\n@Component({\n selector: 'native-stack-outlet',\n template: '',\n host: { '[style]': 'fill' },\n})\nexport class NativeStackOutlet implements RouterOutletContract, OnInit {\n /**\n * Named outlets work exactly as on the web: `<native-stack-outlet name=\"list\" />` is filled by\n * routes with `outlet: 'list'`. The default is the primary one. Read once, as the router's own\n * outlet reads it, since an outlet cannot change which contexts it is registered under.\n */\n readonly name = inject(new HostAttributeToken('name'), { optional: true }) ?? PRIMARY_OUTLET;\n\n readonly supportsBindingToComponentInputs = true;\n\n private readonly parentContexts = inject(ChildrenOutletContexts);\n private readonly renderer = inject(Renderer2);\n private readonly applicationRef = inject(ApplicationRef);\n private readonly injector = inject(Injector);\n private readonly host = inject(ElementRef);\n private readonly location = inject(Location);\n private readonly history = inject(PlatformLocation);\n /**\n * Only for the intent a navigation carries. Optional so the outlet can be exercised through\n * `RouterOutletContract` directly, which is how its own tests drive it.\n */\n private readonly router = inject(Router, { optional: true });\n /** For a refused back to reach the screen as native's own report would. */\n private readonly engine = inject(HostEngine, { optional: true });\n\n private readonly errors = inject(ErrorHandler);\n /** The screen this stack sits in, when it is a stack inside a page of another. */\n private readonly holder = inject(HOLDING_SCREEN, { optional: true });\n /** What the holder's own `preventNativeDismiss` was, while this stack's top screen refuses. */\n private held: { own: unknown } | null = null;\n\n private readonly entries: StackEntry[] = [];\n /**\n * The screens a replace or a reset supersedes, kept until the navigation that supersedes them\n * succeeds: one that fails leaves the stack as it was.\n */\n private superseded: { entries: StackEntry[]; navigation: number } | null = null;\n\n protected readonly fill = { flex: 1 };\n\n constructor() {\n ownHost(this.host.nativeElement);\n // Ours, not a prop of the native stack.\n delete (this.host.nativeElement as { props: Record<string, unknown> }).props['name'];\n this.parentContexts.onChildOutletCreated(this.name, this);\n\n // Android's back button, and `NativeNavigation.back()`. Declining at the bottom of the stack\n // is deliberate: the outlet this one sits in gets its turn, and when none takes it the\n // platform backgrounds the app, which is what a user expects, rather than the app swallowing\n // the press and appearing stuck.\n //\n // Not yet verified on a device: whether react-native-screens' own Android back handling\n // (`nativeBackButtonDismissalEnabled`) also pops the screen, which would make one press pop\n // twice. If a back press ever skips a screen on Android, look here first.\n const back = inject(NativeBack);\n const unsubscribeBack = back.handle((from) =>\n from === 'button' && this.refusesButton() ? true : this.goBack(),\n );\n const unsubscribeStack = back.addStack({\n showing: () => this.isShowing(),\n popToRoot: () => (this.entries.length > 1 ? this.popToEntry(0) : null),\n popTo: (url) => {\n const index = this.entries.findIndex((entry) => this.urlOf(entry) === url);\n return index !== -1 && index < this.entries.length - 1 ? this.popToEntry(index) : null;\n },\n });\n // Optional for the same reason as the router: the outlet's own tests stand one in without it.\n const navigations = this.router?.events?.subscribe((event) => {\n if (event instanceof NavigationEnd) this.settle(event.id);\n else if (event instanceof NavigationError) this.rollBack(event.id);\n });\n\n const unhold = this.holder ? this.holdRefusals(this.holder) : undefined;\n const unpresent = this.takePresentedPages(back);\n\n inject(DestroyRef).onDestroy(() => {\n unhold?.();\n unpresent?.();\n unsubscribeBack();\n unsubscribeStack();\n navigations?.unsubscribe();\n for (const entry of this.entries) {\n entry.unbind();\n entry.ref.destroy();\n }\n this.entries.length = 0;\n this.parentContexts.onChildOutletDestroyed(this.name);\n });\n }\n\n /** The page presented over everything, while there is one. See `presented-route.ts`. */\n private presentedPage: (StackEntry & { stopBack(): void }) | null = null;\n\n /**\n * The app's own stack, the one in the root component, is also the root's presented outlet: a\n * page of a tab that is not in front is shown here, as a screen over the bar and everything in\n * it. One page at a time, which the router sees to, and never kept: it is dismissed.\n */\n private takePresentedPages(back: NativeBack): (() => void) | undefined {\n const router = this.router;\n const root = inject(ActivatedRoute, { optional: true });\n if (!router?.routerState || this.name !== PRIMARY_OUTLET || root !== router.routerState.root) {\n return undefined;\n }\n const page = () => this.presentedPage;\n const outlet: RouterOutletContract = {\n supportsBindingToComponentInputs: true,\n get isActivated() {\n return page() !== null;\n },\n get component() {\n return (page()?.ref.instance as Object | undefined) ?? null;\n },\n get activatedRoute() {\n return page()?.route ?? null;\n },\n get activatedRouteData() {\n return page()?.route.snapshot.data ?? {};\n },\n activateWith: (route, environmentInjector) =>\n this.presentPage(route, environmentInjector, back),\n deactivate: () => this.dropPresentedPage(),\n detach: () => {\n throw new Error('[angular-native] a presented page is dismissed, not detached');\n },\n attach: () => {\n throw new Error('[angular-native] a presented page is not kept to attach again');\n },\n };\n this.parentContexts.onChildOutletCreated(PRESENTED, outlet);\n back.presents = true;\n return () => {\n back.presents = false;\n this.dropPresentedPage();\n this.parentContexts.onChildOutletDestroyed(PRESENTED);\n };\n }\n\n private presentPage(\n route: ActivatedRoute,\n environmentInjector: EnvironmentInjector,\n back: NativeBack,\n ): void {\n const component = (route.component ?? route.snapshot.component) as Type<unknown> | null;\n if (!component) throw new Error('[angular-native] route has no component to present');\n const presentation = this.claimPresentation(this.currentIntent()) ?? {\n stackPresentation: 'modal',\n };\n const screen = this.createScreen(presentation, () => this.dismissPresentedPage());\n const inFront = signal(true);\n const { ref, unbind } = this.createPage(\n component,\n route,\n environmentInjector,\n screen,\n inFront,\n PRESENTED,\n );\n this.fillScreen(screen);\n // Subscribed now, so it is the newest answer and the first asked: a back dismisses the page\n // before it pops anything in the tab under it.\n const stopBack = back.handle(() => this.dismissPresentedPage());\n this.presentedPage = {\n route,\n ref,\n screen,\n detached: false,\n unbind,\n presentation,\n inFront,\n stopBack,\n };\n }\n\n /** The router left the presented page: take it off the stack. */\n private dropPresentedPage(): void {\n const page = this.presentedPage;\n if (!page) return;\n this.presentedPage = null;\n page.stopBack();\n this.drop(page);\n }\n\n /**\n * Take the router off the presented page, for a back or for a sheet the user swiped away: one\n * entry back where that is the url without the page, and otherwise a navigation to that url in\n * place of this entry, since something under the page was navigated while it was up.\n */\n private dismissPresentedPage(): boolean {\n if (!this.presentedPage || !this.router) return false;\n const without = withoutPresented(this.router, this.router.url);\n if (this.historyUrl(-1) === without) this.location.historyGo(-1);\n else void this.router.navigateByUrl(without, { replaceUrl: true });\n return true;\n }\n\n /** The screens currently in the stack, oldest first. Exposed for tests. */\n get depth(): number {\n return this.entries.length;\n }\n\n ngOnInit(): void {\n this.activateCurrentRoute();\n }\n\n /**\n * The route the router is already on, for an outlet created after the navigation that reached\n * it: one held behind a condition until a session or a database is ready. The router activates\n * an outlet as a navigation ends, and that one ended with no outlet to activate, so the outlet\n * takes the route from its context as it arrives, as Angular's own `RouterOutlet` does.\n */\n private activateCurrentRoute(): void {\n if (this.isActivated) return;\n const context = this.parentContexts.getContext(this.name);\n if (!context?.route) return;\n if (context.attachRef) this.attach(context.attachRef, context.route);\n else this.activateWith(context.route, context.injector);\n }\n\n // --- RouterOutletContract ----------------------------------------------\n\n get isActivated(): boolean {\n return this.top !== undefined && !this.top.detached;\n }\n\n get component(): Object | null {\n return this.top && !this.top.detached ? (this.top.ref.instance as Object) : null;\n }\n\n get activatedRoute(): ActivatedRoute | null {\n return this.top && !this.top.detached ? this.top.route : null;\n }\n\n get activatedRouteData(): Data {\n return this.activatedRoute?.snapshot.data ?? {};\n }\n\n /** The input binder reads this to bind route params to component inputs. */\n get activatedComponentRef(): ComponentRef<unknown> | null {\n return this.top?.ref ?? null;\n }\n\n activateWith(route: ActivatedRoute, environmentInjector: EnvironmentInjector): void {\n const component = (route.component ?? route.snapshot.component) as Type<unknown> | null;\n if (!component) {\n throw new Error('[angular-native] route has no component to activate');\n }\n // Whatever a stack shows is a screen, children or not, and must survive being covered.\n if (route.snapshot.routeConfig) markScreenRoute(route.snapshot.routeConfig);\n\n // What kind of navigation this is, over and above which route it lands on: a replace\n // supersedes the screen below rather than stacking on it, and a reset empties the stack.\n // Everything else leaves the screens below mounted, so their native state survives the trip.\n const intent = this.currentIntent();\n const navigation = this.navigationId();\n const presentation = this.presentationFor(intent);\n //\n // The screen is the page's host element, so its props are set before the component exists\n // and the component's own host bindings land on top of them. Style bindings merge key by\n // key, so a page styling itself keeps the absolute fill the stack lays out with - except for\n // `position` and the four insets, which a page naming them writes over outright rather than\n // merging into. Those five are re-asserted below, after the page's own change detection has\n // run, so the outlet's positioning always wins whatever a page's host style says.\n const screen = this.createScreen(presentation);\n const inFront = signal(true);\n const { ref, unbind } = this.createPage(component, route, environmentInjector, screen, inFront);\n // The page's own host style, including any `position` or inset it declared, has now landed\n // on the screen: put the stack's fill back over it. Per-key, through `setStyle`, so whatever\n // else the page's style set - a background colour, say - still merges and stays.\n this.fillScreen(screen);\n\n if (intent?.stack === 'reset') this.supersede(this.entries.slice(), navigation);\n else if (intent?.stack === 'replace' && this.top) this.supersede([this.top], navigation);\n this.entries.push({\n route,\n ref,\n screen,\n detached: false,\n unbind,\n presentation,\n activatedIn: navigation,\n inFront,\n });\n }\n\n /**\n * The page's component, created on its screen and rendered once.\n *\n * A page that throws on that first render fails the navigation, and nothing of it may stay: a\n * half-made screen left on the stack is one the router does not know about, with a component\n * still running on it. So its component is destroyed, its screen taken off the stack, the\n * screen it was pushed from given back its change detection, and the error handed to the\n * app's `ErrorHandler` before the router fails the navigation with it.\n */\n private createPage(\n component: Type<unknown>,\n route: ActivatedRoute,\n environmentInjector: EnvironmentInjector,\n screen: unknown,\n inFront: WritableSignal<boolean>,\n outlet = this.name,\n ): { ref: ComponentRef<unknown>; unbind: () => void } {\n let ref: ComponentRef<unknown> | undefined;\n let unbind: (() => void) | undefined;\n try {\n ref = createComponent(component, {\n environmentInjector,\n elementInjector: this.outletInjector(route, inFront, screen, outlet),\n hostElement: screen as Element,\n });\n this.applicationRef.attachView(ref.hostView);\n // Route params onto inputs before the first change detection, not after: a required input\n // read in the template throws NG0950 if it is still unset when the page first renders.\n unbind = this.bindInputs(ref, route);\n // Before anything can commit. Creating the page's nodes dirties the tree, which schedules a\n // commit of its own - and that commit would capture the page with its elements created and\n // its bindings not yet applied. On iOS the props catch up a frame later and nobody sees it;\n // on Android the flattening decision is made from the props a view is created with, so a\n // content wrapper that arrives without its `collapsable: false` is flattened for good and\n // its children end up parented to a scroll view that allows exactly one.\n ref.changeDetectorRef.detectChanges();\n return { ref, unbind };\n } catch (error) {\n unbind?.();\n ref?.destroy();\n this.removeScreen(screen);\n this.uncover();\n this.errors.handleError(error);\n throw error;\n }\n }\n\n /**\n * Take the screen in front off the stack, when there is one: nothing once the router has\n * detached it, as Angular's own outlet does nothing then. A route with no component of its own,\n * a `loadChildren` wrapper or a group, has the router detach the page under it and then\n * deactivate this same outlet, and that page is a screen pushed from, still to come back to.\n */\n deactivate(): void {\n if (!this.isActivated) return;\n this.drop(this.entries.pop()!);\n }\n\n /**\n * Hand the live `ComponentRef` back to the router without destroying it. The screen stays\n * mounted, so the component keeps running and its native views keep their state.\n */\n detach(): ComponentRef<unknown> {\n const entry = this.top;\n if (!entry) throw new Error('[angular-native] outlet is not activated, nothing to detach');\n entry.detached = true;\n entry.detachedIn = this.navigationId();\n entry.inFront.set(false);\n // `ChangeDetectorRef.detach`, not `ApplicationRef.detachView`. The latter calls\n // `renderDetachView` and pulls the view's nodes out of the tree, which is exactly what we\n // are trying to avoid: the screen would vanish from the stack the moment we pushed past it.\n // This stops change detection for an off-screen screen while leaving it mounted.\n entry.ref.hostView.detach();\n return entry.ref;\n }\n\n /**\n * Re-attach a previously detached ref. If we still hold it, everything stacked above it is a\n * screen the user has navigated back past, so those are destroyed: that is the pop.\n */\n attach(ref: ComponentRef<unknown>, route: ActivatedRoute): void {\n const index = this.entries.findIndex((entry) => entry.ref === ref);\n\n if (index === -1) {\n // Not ours: the router is restoring a ref detached by a different outlet instance. Its\n // host element is already a screen, complete with the `dismissed` listener that outlet\n // registered, so it is re-parented rather than rebuilt.\n const screen = ref.location.nativeElement;\n this.renderer.appendChild(this.host.nativeElement, screen);\n this.entries.push({\n route,\n ref,\n screen,\n detached: false,\n unbind: this.bindInputs(ref, route),\n // What it was given is its first outlet's; this one has no say over that screen's.\n inFront: signal(true),\n });\n this.applicationRef.attachView(ref.hostView);\n } else {\n for (const above of this.entries.splice(index + 1)) this.drop(above);\n const entry = this.entries[index]!;\n entry.detached = false;\n entry.inFront.set(true);\n entry.route = route;\n // The route object is new even when the url is not, so the inputs follow the new one.\n entry.unbind();\n entry.unbind = this.bindInputs(ref, route);\n }\n\n // Resume change detection for the screen the user is coming back to.\n ref.hostView.reattach();\n }\n\n // --- native stack -------------------------------------------------------\n\n /**\n * Route params onto the page's inputs, but only in an app that asked for it with\n * `withComponentInputBinding()`, which is the only time Angular's own outlet binds them. Read\n * per screen rather than once, for a test that stands the router in.\n */\n private bindInputs(ref: ComponentRef<unknown>, route: ActivatedRoute): () => void {\n return this.router?.componentInputBindingEnabled ? bindRouteInputs(ref, route) : () => {};\n }\n\n private get top(): StackEntry | undefined {\n return this.entries[this.entries.length - 1];\n }\n\n /**\n * What the navigation asked for, if it asked for anything. Read here rather than remembered,\n * because the router is mid-navigation for exactly as long as an activation takes.\n */\n private currentIntent(): NativeIntent | null {\n return intentOf(this.router?.getCurrentNavigation()?.extras.state);\n }\n\n /**\n * How the screen a navigation activates is put on screen.\n *\n * A push on top of a presented screen is presented the same way. `RNSScreenStack` pushes a push\n * screen that follows a modal onto the navigation controller under the modal, so the router\n * would be on the new route while the modal stayed in front, and the modal's own way out would\n * first pop a screen nobody could see. A presentation the navigation names itself wins, and a\n * reset starts a stack with nothing to follow. A presented screen that is a stack of its own is\n * where a push to one of its children goes instead, inside it.\n */\n private presentationFor(intent: NativeIntent | null): ScreenPresentation | undefined {\n const own = this.claimPresentation(intent);\n const covering = this.top?.presentation?.stackPresentation;\n if (intent?.stack === 'reset' || !covering || covering === 'push' || own?.stackPresentation) {\n return own;\n }\n return { ...own, stackPresentation: covering };\n }\n\n /** The navigation's own presentation, unless an outlet further out already presented it. */\n private claimPresentation(intent: NativeIntent | null): ScreenPresentation | undefined {\n if (!intent?.presentation) return undefined;\n const id = this.router?.getCurrentNavigation()?.id;\n if (id === undefined) return intent.presentation;\n if (presented.get(this.router!) === id) return undefined;\n presented.set(this.router!, id);\n return intent.presentation;\n }\n\n /** Take a screen out for good: its bindings, its component, and its native view. */\n private drop(entry: StackEntry): void {\n entry.unbind();\n entry.ref.destroy();\n this.removeScreen(entry.screen);\n }\n\n /** Take one entry out of the stack, wherever it is, and drop it. */\n private remove(entry: StackEntry): void {\n const index = this.entries.indexOf(entry);\n if (index === -1) return;\n this.entries.splice(index, 1);\n this.drop(entry);\n }\n\n // --- a navigation's outcome ----------------------------------------------\n\n /** The id of the navigation in progress, when there is a router to say. */\n private navigationId(): number | undefined {\n return this.router?.getCurrentNavigation()?.id;\n }\n\n /**\n * Take out the screens a replace or a reset supersedes once its navigation has succeeded, or\n * at once when there is no navigation to wait for. A replaced screen has already been detached\n * by the router, and with `replaceUrl` its history entry is gone too, so nothing will attach it\n * again; the reuse strategy notices the ref is destroyed and drops its handle.\n */\n private supersede(entries: StackEntry[], navigation: number | undefined): void {\n if (navigation === undefined) {\n for (const entry of entries) this.remove(entry);\n return;\n }\n this.superseded = { entries, navigation };\n }\n\n /** A navigation succeeded: what it superseded goes, and what it did is no longer undoable. */\n private settle(navigation: number): void {\n if (this.superseded?.navigation === navigation) {\n for (const entry of this.superseded.entries) this.remove(entry);\n this.superseded = null;\n }\n for (const entry of this.entries) {\n if (entry.activatedIn === navigation) entry.activatedIn = undefined;\n if (entry.detachedIn === navigation) entry.detachedIn = undefined;\n }\n }\n\n /**\n * A navigation failed, so the router is back where it started: undo what it did here too.\n *\n * The screen that threw has already gone (`createPage`), but a screen this outlet activated for\n * the same navigation has not when the one that threw is further in, the first screen of a\n * stack inside it. That one goes, with everything in it, and the screen it covered carries on.\n */\n private rollBack(navigation: number): void {\n if (this.superseded?.navigation === navigation) this.superseded = null;\n for (const entry of this.entries.filter((candidate) => candidate.activatedIn === navigation)) {\n this.remove(entry);\n }\n this.uncover(navigation);\n }\n\n /**\n * Give the top screen back its change detection when the router covered it for a navigation\n * that is not going to happen: the one given, or the one in progress.\n */\n private uncover(navigation = this.navigationId()): void {\n const top = this.top;\n if (!top?.detached || top.detachedIn !== navigation) return;\n top.detached = false;\n top.detachedIn = undefined;\n top.inFront.set(true);\n top.ref.hostView.reattach();\n }\n\n /**\n * `position: absolute` and the four insets, through `setStyle` rather than one `setProperty`\n * so each key merges into whatever style is already on the screen instead of replacing it -\n * the same merge a page's own host style gets, just asserted last so the stack's layout wins.\n */\n private fillScreen(screen: unknown): void {\n for (const [key, value] of Object.entries(FILL)) {\n this.renderer.setStyle(screen as Element, key, value);\n }\n }\n\n private createScreen(\n presentation?: ScreenPresentation,\n dismissed = (count: number) => this.onNativeDismiss(count),\n ): unknown {\n const screen = ownHost(this.renderer.createElement('screen'));\n this.fillScreen(screen);\n // Set once and never lowered: see the note at the top of this file.\n this.renderer.setProperty(screen, 'activityState', ActivityState.Active);\n // A swipe-back or an Android back button pops the screen natively and only then tells JS.\n // Without this the native stack and the router disagree from that moment on: the screen is\n // gone but the URL still points at it, so the next navigation starts from the wrong place.\n this.renderer.listen(\n screen,\n 'dismissed',\n (event: { nativeEvent?: { dismissCount?: number } }) =>\n dismissed(event?.nativeEvent?.dismissCount ?? 1),\n );\n // Every key is a prop `RNSScreen` already declares, spelled the way the codegen spec spells\n // it, so this forwards rather than translates. Set before the screen joins the stack: the\n // native side reads the presentation as it mounts.\n for (const [prop, value] of Object.entries(presentation ?? {})) {\n if (value !== undefined) this.renderer.setProperty(screen, prop, value);\n }\n // Except this one, which is a struct with no default: an edge left out is 0 natively, and\n // `RNSScreenStack` refuses a swipe-back that starts beyond 0 points. -1 is no limit, which is\n // what `Screen.tsx` sends for every edge not given.\n this.renderer.setProperty(screen, 'gestureResponseDistance', {\n ...UNLIMITED_SWIPE,\n ...presentation?.gestureResponseDistance,\n });\n\n this.renderer.appendChild(this.host.nativeElement, screen);\n return screen;\n }\n\n /**\n * Follow a pop the user already made. `historyGo`, not `back()`, because iOS coalesces a long\n * swipe into a single event with a count.\n *\n * Only ever fires for a native dismissal: verified on device that a pop this outlet drives\n * itself emits `willAppear`/`appear` for the screen below but no `dismissed`, so there is no\n * double-pop to guard against.\n *\n * The gesture itself is unverified by tooling: idb cannot synthesise a `UIScreenEdgePan` that\n * UIKit accepts, so this path was reasoned from the events rather than driven end to end.\n */\n private onNativeDismiss(count: number): void {\n this.popBy(Math.max(1, count));\n }\n\n /**\n * A back, from the button or `NativeNavigation`: pop the top screen, as long as there is one\n * below it and this stack is the one the user is looking at. A stack in a tab behind, or under\n * a screen pushed over the tab bar, is still subscribed, and the newest one would otherwise\n * answer for the stack in front.\n */\n /**\n * Android's Back button is the platform's own dismissal there, and react-native-screens leaves\n * it to JS: its Android screen ignores `preventNativeDismiss`. So a top screen that sets it\n * refuses the press here, as iOS refuses a swipe, and hears `nativeDismissCancelled` the same\n * way, through the engine, as if native had sent it.\n */\n private refusesButton(): boolean {\n if (this.entries.length < 2 || !this.isShowing()) return false;\n const screen = this.top!.screen as EngineNode;\n if (screen.props['preventNativeDismiss'] !== true) return false;\n // The native engine's own entry point for an event, the one Fabric calls. Not on\n // `HostEngine`, because only a native host has a screen to refuse with.\n const native = this.engine as { dispatchEvent?: NativeDispatch } | null;\n native?.dispatchEvent?.(screen, 'topNativeDismissCancelled', { dismissCount: 1 });\n return true;\n }\n\n /**\n * Passes the top screen's refusal to the screen this stack sits in, and that screen's report of\n * an attempt back to the top screen: the swipe that dismisses a presented stack is on the\n * screen holding it, which the page inside cannot bind.\n *\n * Read after every render, since the refusal is a host binding of whatever page is on top.\n */\n private holdRefusals(holder: HoldingScreen): () => void {\n const render = afterEveryRender(() => this.holdRefusal(holder));\n const unlisten = this.renderer.listen(\n holder.screen,\n 'nativeDismissCancelled',\n (event: { nativeEvent?: unknown }) => {\n // The stack can have lost its last screen with the refusal not yet released.\n const top = this.top;\n if (!this.held || !top) return;\n const native = this.engine as { dispatchEvent?: NativeDispatch } | null;\n const report = event?.nativeEvent ?? { dismissCount: 1 };\n native?.dispatchEvent?.(top.screen, 'topNativeDismissCancelled', report);\n },\n );\n return () => {\n render.destroy();\n unlisten();\n this.release(holder);\n };\n }\n\n private holdRefusal(holder: HoldingScreen): void {\n // A stack in a tab behind is inside the same screen, and has no say in it.\n if (!refuses(this.top?.screen) || !this.isShowing()) return this.release(holder);\n if (refuses(holder.screen)) return;\n // ponytail: the holder's own binding is read when the top screen starts refusing. One that\n // turns true while it does is put back as it was then; bind the refusal in one of the two.\n this.held = { own: (holder.screen as EngineNode).props?.['preventNativeDismiss'] };\n this.renderer.setProperty(holder.screen, 'preventNativeDismiss', true);\n holder.refusalChanged();\n }\n\n /** The holder's own answer again, once the top screen no longer refuses. */\n private release(holder: HoldingScreen): void {\n if (!this.held) return;\n this.renderer.setProperty(holder.screen, 'preventNativeDismiss', this.held.own ?? false);\n this.held = null;\n holder.refusalChanged();\n }\n\n private goBack(): boolean {\n if (this.entries.length < 2 || !this.isShowing()) return false;\n this.popBy(1);\n return true;\n }\n\n /** Whether the top screen is part of what the router shows now. Assumed without a router. */\n private isShowing(): boolean {\n if (!this.router) return true;\n return this.isActivated && isShowing(this.router, this.top!.route);\n }\n\n /**\n * Take the router to the screen `steps` below the top, whether native already popped it or it\n * is about to be popped because the router arrives there.\n */\n private popBy(steps: number): void {\n const below = this.entries[this.entries.length - 1 - steps];\n const url = below && this.router ? this.urlOf(below) : null;\n // Usually the entry that far back is the screen the pop revealed, and going back through\n // history keeps it tidy. Not always: a stack inside a tab shares history with the other tabs,\n // so after a trip to one and back the entry behind the top screen is that other tab, and\n // going back would switch tab rather than pop. Then the router is sent to the revealed\n // screen instead, replacing the entry of the one that is gone.\n const behind = this.historyUrl(-steps);\n if (!url || behind === undefined || behind === url) {\n this.location.historyGo(-steps);\n return;\n }\n void this.router!.navigateByUrl(url, { replaceUrl: true });\n }\n\n /**\n * Take the router down to the screen at `index`, popping every screen above it together.\n * Through history when the entries behind are these screens, so going back from there keeps\n * working one screen at a time; otherwise by a navigation to it that replaces the entry, as\n * `popBy` does when a tab's history interleaves.\n */\n private popToEntry(index: number): Promise<boolean> {\n const url = this.urlOf(this.entries[index]!);\n const steps = this.entries.length - 1 - index;\n if (this.historyUrl(-steps) === url) {\n const arrived = this.nextNavigation();\n this.location.historyGo(-steps);\n return arrived;\n }\n return this.router!.navigateByUrl(url, { replaceUrl: true });\n }\n\n /** Whether the navigation that happens next succeeds. */\n private nextNavigation(): Promise<boolean> {\n return new Promise((resolve) => {\n const events = this.router!.events.subscribe((event) => {\n if (event instanceof NavigationEnd) resolve(true);\n else if (event instanceof NavigationError || event instanceof NavigationCancel) {\n resolve(false);\n } else return;\n events.unsubscribe();\n });\n });\n }\n\n /** The url a screen was showing when it was covered, rebuilt from its own route snapshot. */\n private urlOf(entry: StackEntry): string {\n const snapshot = entry.route.snapshot;\n const tree = createUrlTreeFromSnapshot(snapshot, [], snapshot.queryParams, snapshot.fragment);\n return this.router!.serializeUrl(tree);\n }\n\n /**\n * The url of the history entry `offset` away, normalised the way the router writes it: null past\n * the start of history, and undefined when the history is not ours to read, so the pop has to go\n * through it blind.\n */\n private historyUrl(offset: number): string | null | undefined {\n if (!(this.history instanceof NativePlatformLocation)) return undefined;\n const url = this.history.ɵurlAt(offset);\n return url === null ? null : this.router!.serializeUrl(this.router!.parseUrl(url));\n }\n\n private removeScreen(screen: unknown): void {\n this.renderer.removeChild(this.host.nativeElement, screen);\n }\n\n /**\n * What a page is created with: its route, its screen, the outlet contexts its own outlets\n * register in, and whether its screen is in front - which is this screen's own say and, for a stack inside a\n * screen of another, that screen's too.\n */\n private outletInjector(\n route: ActivatedRoute,\n inFront: WritableSignal<boolean>,\n screen: unknown,\n outlet = this.name,\n ): Injector {\n const outer = this.injector.get(SCREEN_IN_FRONT);\n return Injector.create({\n parent: this.injector,\n providers: [\n { provide: SCREEN_IN_FRONT, useValue: computed(() => outer() && inFront()) },\n {\n provide: HOLDING_SCREEN,\n useValue: {\n screen,\n refusalChanged: () => this.holder && this.holdRefusal(this.holder),\n } satisfies HoldingScreen,\n },\n { provide: ActivatedRoute, useValue: route },\n { provide: SCREEN_HEADER, useValue: signal(false) },\n {\n provide: ChildrenOutletContexts,\n useValue: this.parentContexts.getOrCreateContext(outlet).children,\n },\n ],\n });\n }\n}\n"]}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Whether the screen a page is on has a bar above its content: a header that is shown and is not
3
+ * translucent, which the page starts below.
4
+ *
5
+ * The header says so and `<screen-safe-area-view>` reads it. On iOS the screen's own safe area
6
+ * already knows, and is zero at the top under such a bar. Android's has no such thing: its view
7
+ * insets by the status bar whatever is above it, which under the bar is a gap of that height.
8
+ */
9
+ import { InjectionToken, type WritableSignal } from '@angular/core';
10
+ export declare const SCREEN_HEADER: InjectionToken<WritableSignal<boolean>>;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Whether the screen a page is on has a bar above its content: a header that is shown and is not
3
+ * translucent, which the page starts below.
4
+ *
5
+ * The header says so and `<screen-safe-area-view>` reads it. On iOS the screen's own safe area
6
+ * already knows, and is zero at the top under such a bar. Android's has no such thing: its view
7
+ * insets by the status bar whatever is above it, which under the bar is a gap of that height.
8
+ */
9
+ import { InjectionToken } from '@angular/core';
10
+ export const SCREEN_HEADER = new InjectionToken('ng-native.router.screen-header');
11
+ //# sourceMappingURL=screen-header.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen-header.js","sourceRoot":"","sources":["../src/screen-header.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,cAAc,EAAuB,MAAM,eAAe,CAAC;AAEpE,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,cAAc,CAC7C,gCAAgC,CACjC,CAAC","sourcesContent":["/**\n * Whether the screen a page is on has a bar above its content: a header that is shown and is not\n * translucent, which the page starts below.\n *\n * The header says so and `<screen-safe-area-view>` reads it. On iOS the screen's own safe area\n * already knows, and is zero at the top under such a bar. Android's has no such thing: its view\n * insets by the status bar whatever is above it, which under the bar is a gap of that height.\n */\nimport { InjectionToken, type WritableSignal } from '@angular/core';\n\nexport const SCREEN_HEADER = new InjectionToken<WritableSignal<boolean>>(\n 'ng-native.router.screen-header',\n);\n"]}
@@ -0,0 +1,18 @@
1
+ import * as i0 from "@angular/core";
2
+ /** The edges of the screen. */
3
+ export type ScreenSafeAreaEdge = 'top' | 'right' | 'bottom' | 'left';
4
+ export declare class ScreenSafeAreaView {
5
+ constructor();
6
+ /** Whether the screen has a bar the page starts below. See `screen-header.ts`. */
7
+ private readonly header;
8
+ private readonly android;
9
+ /** Which edges to inset. Absent insets all four. */
10
+ readonly edges: import("@angular/core").InputSignal<readonly ScreenSafeAreaEdge[] | undefined>;
11
+ /**
12
+ * Native takes all four edges every time, as booleans; a partial record leaves the missing
13
+ * ones at whatever they were.
14
+ */
15
+ protected readonly resolvedEdges: import("@angular/core").Signal<Record<ScreenSafeAreaEdge, boolean>>;
16
+ static ɵfac: i0.ɵɵFactoryDeclaration<ScreenSafeAreaView, never>;
17
+ static ɵcmp: i0.ɵɵComponentDeclaration<ScreenSafeAreaView, "screen-safe-area-view", never, { "edges": { "alias": "edges"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
18
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * A view that keeps its content clear of whatever covers the screen it is in: a translucent
3
+ * navigation bar and the search bar under it, the tab bar, the home indicator and the system bars.
4
+ *
5
+ * ```html
6
+ * <native-header title="Planner" />
7
+ * <screen-safe-area-view [edges]="['top']" style="flex: 1">
8
+ * <view class="controls">…</view>
9
+ * <scroll-view>…</scroll-view>
10
+ * </screen-safe-area-view>
11
+ * ```
12
+ *
13
+ * `<safe-area-view>` cannot do this. Its insets come from the nearest `<safe-area-provider>`,
14
+ * which sits at the root of the app, above every bar, and so measures only the window's own
15
+ * unsafe areas: a page under a Liquid Glass header starts behind the bar, and anything pinned to
16
+ * the bottom of a tab ends up under the tab bar.
17
+ *
18
+ * This is react-native-screens' own `RNSSafeAreaView`, which asks the screen it is in instead.
19
+ * On iOS that is the screen's `safeAreaInsets`, which UIKit extends by a translucent navigation
20
+ * bar and by the tab bar, floating or not, on top of the status bar and the home indicator. On
21
+ * Android it is the larger of the bottom navigation bar's height and the system bars. Both follow
22
+ * the bars as they change, rotate, or are hidden.
23
+ *
24
+ * Android's bar is above the page rather than over it, and its view insets the top by the status
25
+ * bar all the same. So under a header that is shown and not translucent the top edge is left
26
+ * alone there, and the page starts under the bar as it does on iOS.
27
+ *
28
+ * **The insets are applied as margin, not padding.** Whatever is beneath the inset shows through
29
+ * it, so a panel whose background has to reach the edge of the screen puts that background on a
30
+ * parent and this inside it: the parent grows by the margin and paints behind the bar, and the
31
+ * content ends where the bar begins.
32
+ *
33
+ * It has to be inside a screen: a page of a stack, or a tab. On iOS, with no screen above it, it
34
+ * insets by nothing.
35
+ */
36
+ import { Component, ElementRef, computed, inject, input } from '@angular/core';
37
+ import { nativePlatform } from '@ng-native/fabric';
38
+ import { ownHost } from "./own-host.js";
39
+ import { SCREEN_HEADER } from "./screen-header.js";
40
+ import * as i0 from "@angular/core";
41
+ const ALL = ['top', 'right', 'bottom', 'left'];
42
+ export class ScreenSafeAreaView {
43
+ constructor() {
44
+ ownHost(inject(ElementRef).nativeElement, this.constructor);
45
+ }
46
+ /** Whether the screen has a bar the page starts below. See `screen-header.ts`. */
47
+ header = inject(SCREEN_HEADER, { optional: true });
48
+ android = nativePlatform() === 'android';
49
+ /** Which edges to inset. Absent insets all four. */
50
+ edges = input(/* @ts-ignore */
51
+ ...(ngDevMode ? [undefined, { debugName: "edges" }] : /* istanbul ignore next */ []));
52
+ /**
53
+ * Native takes all four edges every time, as booleans; a partial record leaves the missing
54
+ * ones at whatever they were.
55
+ */
56
+ resolvedEdges = computed(() => {
57
+ const edges = this.edges() ?? ALL;
58
+ // Android insets the top by the status bar whatever is above the page, and a bar is.
59
+ const covered = this.android && this.header?.() ? 'top' : null;
60
+ return Object.fromEntries(ALL.map((edge) => [edge, edge !== covered && edges.includes(edge)]));
61
+ }, /* @ts-ignore */
62
+ ...(ngDevMode ? [{ debugName: "resolvedEdges" }] : /* istanbul ignore next */ []));
63
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: ScreenSafeAreaView, deps: [], target: i0.ɵɵFactoryTarget.Component });
64
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.2.0", type: ScreenSafeAreaView, isStandalone: true, selector: "screen-safe-area-view", inputs: { edges: { classPropertyName: "edges", publicName: "edges", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "edges": "resolvedEdges()" } }, ngImport: i0, template: '<ng-content />', isInline: true });
65
+ }
66
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: ScreenSafeAreaView, decorators: [{
67
+ type: Component,
68
+ args: [{
69
+ selector: 'screen-safe-area-view',
70
+ template: '<ng-content />',
71
+ host: { '[edges]': 'resolvedEdges()' },
72
+ }]
73
+ }], ctorParameters: () => [], propDecorators: { edges: [{ type: i0.Input, args: [{ isSignal: true, alias: "edges", required: false }] }] } });
74
+ //# sourceMappingURL=screen-safe-area-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen-safe-area-view.js","sourceRoot":"","sources":["../src/screen-safe-area-view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAmB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;;AAKnD,MAAM,GAAG,GAAkC,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAO9E,MAAM,OAAO,kBAAkB;IAC7B;QACE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,aAA2B,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAC5E,CAAC;IAED,kFAAkF;IACjE,MAAM,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,OAAO,GAAG,cAAc,EAAE,KAAK,SAAS,CAAC;IAE1D,oDAAoD;IAC3C,KAAK,GAAG,KAAK;yFAAiC,CAAC;IAExD;;;OAGG;IACgB,aAAa,GAAG,QAAQ,CAAC,GAAG,EAAE;QAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC;QAClC,qFAAqF;QACrF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/D,OAAO,MAAM,CAAC,WAAW,CACvB,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAC7B,CAAC;IAC3C,CAAC;sFAAC,CAAC;uGAvBQ,kBAAkB;2FAAlB,kBAAkB,2QAHnB,gBAAgB;;2FAGf,kBAAkB;kBAL9B,SAAS;mBAAC;oBACT,QAAQ,EAAE,uBAAuB;oBACjC,QAAQ,EAAE,gBAAgB;oBAC1B,IAAI,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE;iBACvC","sourcesContent":["/**\n * A view that keeps its content clear of whatever covers the screen it is in: a translucent\n * navigation bar and the search bar under it, the tab bar, the home indicator and the system bars.\n *\n * ```html\n * <native-header title=\"Planner\" />\n * <screen-safe-area-view [edges]=\"['top']\" style=\"flex: 1\">\n * <view class=\"controls\">…</view>\n * <scroll-view>…</scroll-view>\n * </screen-safe-area-view>\n * ```\n *\n * `<safe-area-view>` cannot do this. Its insets come from the nearest `<safe-area-provider>`,\n * which sits at the root of the app, above every bar, and so measures only the window's own\n * unsafe areas: a page under a Liquid Glass header starts behind the bar, and anything pinned to\n * the bottom of a tab ends up under the tab bar.\n *\n * This is react-native-screens' own `RNSSafeAreaView`, which asks the screen it is in instead.\n * On iOS that is the screen's `safeAreaInsets`, which UIKit extends by a translucent navigation\n * bar and by the tab bar, floating or not, on top of the status bar and the home indicator. On\n * Android it is the larger of the bottom navigation bar's height and the system bars. Both follow\n * the bars as they change, rotate, or are hidden.\n *\n * Android's bar is above the page rather than over it, and its view insets the top by the status\n * bar all the same. So under a header that is shown and not translucent the top edge is left\n * alone there, and the page starts under the bar as it does on iOS.\n *\n * **The insets are applied as margin, not padding.** Whatever is beneath the inset shows through\n * it, so a panel whose background has to reach the edge of the screen puts that background on a\n * parent and this inside it: the parent grows by the margin and paints behind the bar, and the\n * content ends where the bar begins.\n *\n * It has to be inside a screen: a page of a stack, or a tab. On iOS, with no screen above it, it\n * insets by nothing.\n */\nimport { Component, ElementRef, computed, inject, input } from '@angular/core';\nimport { nativePlatform, type EngineNode } from '@ng-native/fabric';\nimport { ownHost } from './own-host.ts';\nimport { SCREEN_HEADER } from './screen-header.ts';\n\n/** The edges of the screen. */\nexport type ScreenSafeAreaEdge = 'top' | 'right' | 'bottom' | 'left';\n\nconst ALL: readonly ScreenSafeAreaEdge[] = ['top', 'right', 'bottom', 'left'];\n\n@Component({\n selector: 'screen-safe-area-view',\n template: '<ng-content />',\n host: { '[edges]': 'resolvedEdges()' },\n})\nexport class ScreenSafeAreaView {\n constructor() {\n ownHost(inject(ElementRef).nativeElement as EngineNode, this.constructor);\n }\n\n /** Whether the screen has a bar the page starts below. See `screen-header.ts`. */\n private readonly header = inject(SCREEN_HEADER, { optional: true });\n private readonly android = nativePlatform() === 'android';\n\n /** Which edges to inset. Absent insets all four. */\n readonly edges = input<readonly ScreenSafeAreaEdge[]>();\n\n /**\n * Native takes all four edges every time, as booleans; a partial record leaves the missing\n * ones at whatever they were.\n */\n protected readonly resolvedEdges = computed(() => {\n const edges = this.edges() ?? ALL;\n // Android insets the top by the status bar whatever is above the page, and a bar is.\n const covered = this.android && this.header?.() ? 'top' : null;\n return Object.fromEntries(\n ALL.map((edge) => [edge, edge !== covered && edges.includes(edge)]),\n ) as Record<ScreenSafeAreaEdge, boolean>;\n });\n}\n"]}
package/dist/screens.js CHANGED
@@ -40,8 +40,9 @@ export const SCREEN_VIEW_NAMES = {
40
40
  'RNSScreenStackHeaderSubview',
41
41
  { flexDirection: 'row', alignItems: 'center', justifyContent: 'center' },
42
42
  ],
43
- // Insets by what the screen it is in says is covered, the tab bar included. See
44
- // `tab-safe-area-view.ts`. The same name on both platforms.
43
+ // Insets by what the screen it is in says is covered: a translucent navigation bar, and the tab
44
+ // bar. See `screen-safe-area-view.ts`. The same name on both platforms.
45
+ 'screen-safe-area-view': ['RNSSafeAreaView'],
45
46
  'tab-safe-area-view': ['RNSSafeAreaView'],
46
47
  };
47
48
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"screens.js","sourceRoot":"","sources":["../src/screens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEpE;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA0D;IACtF,qDAAqD;IACrD,qBAAqB,EAAE,CAAC,gBAAgB,CAAC;IACzC,oFAAoF;IACpF,MAAM,EAAE,CAAC,WAAW,CAAC;IACrB,eAAe,EAAE;QACf,4BAA4B;QAC5B;YACE,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,MAAM;YACb,aAAa,EAAE,KAAK;YACpB,cAAc,EAAE,eAAe;YAC/B,UAAU,EAAE,QAAQ;SACrB;KACF;IACD,+FAA+F;IAC/F,mBAAmB,EAAE,CAAC,cAAc,CAAC;IACrC,oBAAoB,EAAE;QACpB,6BAA6B;QAC7B,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE;KACzE;IACD,gFAAgF;IAChF,4DAA4D;IAC5D,oBAAoB,EAAE,CAAC,iBAAiB,CAAC;CAC1C,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,cAAc,GAAsE;IACxF,oBAAoB,EAAE;QACpB,gBAAgB;QAChB,oBAAoB;QACpB,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;KAC3C;IACD,YAAY,EAAE;QACZ,kBAAkB;QAClB,sBAAsB;QACtB,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;KACjE;CACF,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,gDAAgD;IAChD,QAAQ,EAAE,CAAC;IACX,oDAAoD;IACpD,aAAa,EAAE,CAAC;IAChB,iCAAiC;IACjC,MAAM,EAAE,CAAC;CACD,CAAC;AAIX;;;;;;;;GAQG;AACH,MAAM,UAAU,wBAAwB;IACtC,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAChF,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,QAA+C,CAAC,CAAC;IACvF,CAAC;IACD,6FAA6F;IAC7F,kDAAkD;IAClD,yFAAyF;IACzF,gBAAgB,CAAC,qBAAqB,EAAE,EAAE,GAAG,EAAE,sBAAsB,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7F,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QACjF,gBAAgB,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,QAAmC,CAAC,CAAC;IACnF,CAAC;IACD,+FAA+F;IAC/F,+FAA+F;IAC/F,+FAA+F;IAC/F,2FAA2F;IAC3F,aAAa,CAAC,eAAe,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAC1E,CAAC","sourcesContent":["/**\n * react-native-screens, driven directly.\n *\n * The native half of navigation already exists as codegen'd Fabric components. We register their\n * names and drive them with `createNode`; their React components are unreachable (hooks) and\n * `react-navigation` is not a dependency.\n *\n * No decorators here on purpose: tests import these at runtime, and Node's type stripping\n * refuses decorators.\n */\nimport { registerHoist, registerViewName } from '@ng-native/fabric';\n\n/**\n * Element name -> codegen'd Fabric component name, and the base style that component's React\n * wrapper would have applied in JS. Element names are lowercase, because the compiler silently\n * empties a template containing a capitalized one.\n *\n * The header's styles are `ScreenStackHeaderConfig.tsx`'s own, and the absolute positioning is\n * load-bearing: without it the config view takes part in the screen's flex layout and every page\n * renders a header's height too far down. `alignItems` is iOS-only there; it is harmless on\n * Android, where the native side lays the bar out itself.\n */\nexport const SCREEN_VIEW_NAMES: Record<string, [viewName: string, defaults?: object]> = {\n // NativeStackOutlet's own host element is the stack.\n 'native-stack-outlet': ['RNSScreenStack'],\n // Created by the outlet, one per activated route; nobody writes this in a template.\n screen: ['RNSScreen'],\n 'native-header': [\n 'RNSScreenStackHeaderConfig',\n {\n position: 'absolute',\n width: '100%',\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n },\n ],\n // Placed in a `<native-header-item type=\"searchBar\">`, as react-native-screens places its own.\n 'native-search-bar': ['RNSSearchBar'],\n 'native-header-item': [\n 'RNSScreenStackHeaderSubview',\n { flexDirection: 'row', alignItems: 'center', justifyContent: 'center' },\n ],\n // Insets by what the screen it is in says is covered, the tab bar included. See\n // `tab-safe-area-view.ts`. The same name on both platforms.\n 'tab-safe-area-view': ['RNSSafeAreaView'],\n};\n\n/**\n * The tabs half, which react-native-screens names per platform rather than sharing one component:\n * `RNSTabsHostIOS` wraps a `UITabBarController`, `RNSTabsHostAndroid` a bottom navigation bar,\n * and their props differ enough that the codegen specs are separate files.\n *\n * The fills are `TabsHost.ios.tsx`'s and `TabsScreen.ios.tsx`'s own. A tab screen is positioned\n * absolutely because it is one of several occupying the same space, only one of which is visible.\n */\nconst TAB_VIEW_NAMES: Record<string, [ios: string, android: string, defaults?: object]> = {\n 'native-tabs-outlet': [\n 'RNSTabsHostIOS',\n 'RNSTabsHostAndroid',\n { flex: 1, width: '100%', height: '100%' },\n ],\n 'native-tab': [\n 'RNSTabsScreenIOS',\n 'RNSTabsScreenAndroid',\n { position: 'absolute', flex: 1, width: '100%', height: '100%' },\n ],\n};\n\n/**\n * How visible a screen is. The native stack keeps every screen mounted and reads this rather\n * than adding and removing views, which is what preserves a pushed-away screen's native state.\n *\n * `Screen.tsx` throws if this ever *decreases* while in a native stack, so a screen goes\n * 0 -> 2 on push and is removed outright on pop rather than walked back down.\n */\nexport const ActivityState = {\n /** Off screen, and a candidate for freezing. */\n Inactive: 0,\n /** Mid transition: on screen but not the target. */\n Transitioning: 1,\n /** The screen the user is on. */\n Active: 2,\n} as const;\n\nexport type ActivityStateValue = (typeof ActivityState)[keyof typeof ActivityState];\n\n/**\n * Call once at startup, before the first navigation.\n *\n * The app must also have `react-native-screens` installed so the native side registers these\n * components; this only teaches the engine the element-to-view-name mapping. A name the native\n * side does not know renders as `UnimplementedNativeView`, not an error. None of its JavaScript\n * is imported - Expo Go happens to bundle the native half, which is why the canary worked before\n * it declared the dependency at all, and why an app that forgets it fails only once it ships.\n */\nexport function registerScreenComponents(): void {\n for (const [element, [viewName, defaults]] of Object.entries(SCREEN_VIEW_NAMES)) {\n registerViewName(element, viewName, defaults as Record<string, unknown> | undefined);\n }\n // By platform, chosen when the view is looked up: this runs as the app's config is imported,\n // before its `main.ts` has reported the platform.\n // A window of its own on iOS; see `full-window-overlay.ts`. Its fill is the component's.\n registerViewName('full-window-overlay', { ios: 'RNSFullWindowOverlay', android: 'RCTView' });\n for (const [element, [ios, android, defaults]] of Object.entries(TAB_VIEW_NAMES)) {\n registerViewName(element, { ios, android }, defaults as Record<string, unknown>);\n }\n // `findHeaderConfig` in `RNSScreen.mm` looks at the screen's direct children and no deeper, so\n // a header a page wrote inside a `safe-area-view` or a component of its own commits beside it.\n // Nothing in `RNSScreen.mm` updates the bar when its config is unmounted, so a header an `@if`\n // takes away leaves a config behind that hides the bar, and one that comes back adopts it.\n registerHoist('native-header', 'screen', { standIn: { hidden: true } });\n}\n"]}
1
+ {"version":3,"file":"screens.js","sourceRoot":"","sources":["../src/screens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEpE;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA0D;IACtF,qDAAqD;IACrD,qBAAqB,EAAE,CAAC,gBAAgB,CAAC;IACzC,oFAAoF;IACpF,MAAM,EAAE,CAAC,WAAW,CAAC;IACrB,eAAe,EAAE;QACf,4BAA4B;QAC5B;YACE,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,MAAM;YACb,aAAa,EAAE,KAAK;YACpB,cAAc,EAAE,eAAe;YAC/B,UAAU,EAAE,QAAQ;SACrB;KACF;IACD,+FAA+F;IAC/F,mBAAmB,EAAE,CAAC,cAAc,CAAC;IACrC,oBAAoB,EAAE;QACpB,6BAA6B;QAC7B,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE;KACzE;IACD,gGAAgG;IAChG,wEAAwE;IACxE,uBAAuB,EAAE,CAAC,iBAAiB,CAAC;IAC5C,oBAAoB,EAAE,CAAC,iBAAiB,CAAC;CAC1C,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,cAAc,GAAsE;IACxF,oBAAoB,EAAE;QACpB,gBAAgB;QAChB,oBAAoB;QACpB,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;KAC3C;IACD,YAAY,EAAE;QACZ,kBAAkB;QAClB,sBAAsB;QACtB,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;KACjE;CACF,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,gDAAgD;IAChD,QAAQ,EAAE,CAAC;IACX,oDAAoD;IACpD,aAAa,EAAE,CAAC;IAChB,iCAAiC;IACjC,MAAM,EAAE,CAAC;CACD,CAAC;AAIX;;;;;;;;GAQG;AACH,MAAM,UAAU,wBAAwB;IACtC,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAChF,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,QAA+C,CAAC,CAAC;IACvF,CAAC;IACD,6FAA6F;IAC7F,kDAAkD;IAClD,yFAAyF;IACzF,gBAAgB,CAAC,qBAAqB,EAAE,EAAE,GAAG,EAAE,sBAAsB,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7F,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QACjF,gBAAgB,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,QAAmC,CAAC,CAAC;IACnF,CAAC;IACD,+FAA+F;IAC/F,+FAA+F;IAC/F,+FAA+F;IAC/F,2FAA2F;IAC3F,aAAa,CAAC,eAAe,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAC1E,CAAC","sourcesContent":["/**\n * react-native-screens, driven directly.\n *\n * The native half of navigation already exists as codegen'd Fabric components. We register their\n * names and drive them with `createNode`; their React components are unreachable (hooks) and\n * `react-navigation` is not a dependency.\n *\n * No decorators here on purpose: tests import these at runtime, and Node's type stripping\n * refuses decorators.\n */\nimport { registerHoist, registerViewName } from '@ng-native/fabric';\n\n/**\n * Element name -> codegen'd Fabric component name, and the base style that component's React\n * wrapper would have applied in JS. Element names are lowercase, because the compiler silently\n * empties a template containing a capitalized one.\n *\n * The header's styles are `ScreenStackHeaderConfig.tsx`'s own, and the absolute positioning is\n * load-bearing: without it the config view takes part in the screen's flex layout and every page\n * renders a header's height too far down. `alignItems` is iOS-only there; it is harmless on\n * Android, where the native side lays the bar out itself.\n */\nexport const SCREEN_VIEW_NAMES: Record<string, [viewName: string, defaults?: object]> = {\n // NativeStackOutlet's own host element is the stack.\n 'native-stack-outlet': ['RNSScreenStack'],\n // Created by the outlet, one per activated route; nobody writes this in a template.\n screen: ['RNSScreen'],\n 'native-header': [\n 'RNSScreenStackHeaderConfig',\n {\n position: 'absolute',\n width: '100%',\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n },\n ],\n // Placed in a `<native-header-item type=\"searchBar\">`, as react-native-screens places its own.\n 'native-search-bar': ['RNSSearchBar'],\n 'native-header-item': [\n 'RNSScreenStackHeaderSubview',\n { flexDirection: 'row', alignItems: 'center', justifyContent: 'center' },\n ],\n // Insets by what the screen it is in says is covered: a translucent navigation bar, and the tab\n // bar. See `screen-safe-area-view.ts`. The same name on both platforms.\n 'screen-safe-area-view': ['RNSSafeAreaView'],\n 'tab-safe-area-view': ['RNSSafeAreaView'],\n};\n\n/**\n * The tabs half, which react-native-screens names per platform rather than sharing one component:\n * `RNSTabsHostIOS` wraps a `UITabBarController`, `RNSTabsHostAndroid` a bottom navigation bar,\n * and their props differ enough that the codegen specs are separate files.\n *\n * The fills are `TabsHost.ios.tsx`'s and `TabsScreen.ios.tsx`'s own. A tab screen is positioned\n * absolutely because it is one of several occupying the same space, only one of which is visible.\n */\nconst TAB_VIEW_NAMES: Record<string, [ios: string, android: string, defaults?: object]> = {\n 'native-tabs-outlet': [\n 'RNSTabsHostIOS',\n 'RNSTabsHostAndroid',\n { flex: 1, width: '100%', height: '100%' },\n ],\n 'native-tab': [\n 'RNSTabsScreenIOS',\n 'RNSTabsScreenAndroid',\n { position: 'absolute', flex: 1, width: '100%', height: '100%' },\n ],\n};\n\n/**\n * How visible a screen is. The native stack keeps every screen mounted and reads this rather\n * than adding and removing views, which is what preserves a pushed-away screen's native state.\n *\n * `Screen.tsx` throws if this ever *decreases* while in a native stack, so a screen goes\n * 0 -> 2 on push and is removed outright on pop rather than walked back down.\n */\nexport const ActivityState = {\n /** Off screen, and a candidate for freezing. */\n Inactive: 0,\n /** Mid transition: on screen but not the target. */\n Transitioning: 1,\n /** The screen the user is on. */\n Active: 2,\n} as const;\n\nexport type ActivityStateValue = (typeof ActivityState)[keyof typeof ActivityState];\n\n/**\n * Call once at startup, before the first navigation.\n *\n * The app must also have `react-native-screens` installed so the native side registers these\n * components; this only teaches the engine the element-to-view-name mapping. A name the native\n * side does not know renders as `UnimplementedNativeView`, not an error. None of its JavaScript\n * is imported - Expo Go happens to bundle the native half, which is why the canary worked before\n * it declared the dependency at all, and why an app that forgets it fails only once it ships.\n */\nexport function registerScreenComponents(): void {\n for (const [element, [viewName, defaults]] of Object.entries(SCREEN_VIEW_NAMES)) {\n registerViewName(element, viewName, defaults as Record<string, unknown> | undefined);\n }\n // By platform, chosen when the view is looked up: this runs as the app's config is imported,\n // before its `main.ts` has reported the platform.\n // A window of its own on iOS; see `full-window-overlay.ts`. Its fill is the component's.\n registerViewName('full-window-overlay', { ios: 'RNSFullWindowOverlay', android: 'RCTView' });\n for (const [element, [ios, android, defaults]] of Object.entries(TAB_VIEW_NAMES)) {\n registerViewName(element, { ios, android }, defaults as Record<string, unknown>);\n }\n // `findHeaderConfig` in `RNSScreen.mm` looks at the screen's direct children and no deeper, so\n // a header a page wrote inside a `safe-area-view` or a component of its own commits beside it.\n // Nothing in `RNSScreen.mm` updates the bar when its config is unmounted, so a header an `@if`\n // takes away leaves a config behind that hides the bar, and one that comes back adopts it.\n registerHoist('native-header', 'screen', { standIn: { hidden: true } });\n}\n"]}
@@ -1,15 +1,8 @@
1
+ import { ScreenSafeAreaView, type ScreenSafeAreaEdge } from './screen-safe-area-view.ts';
1
2
  import * as i0 from "@angular/core";
2
3
  /** The edges of the screen. */
3
- export type TabSafeAreaEdge = 'top' | 'right' | 'bottom' | 'left';
4
- export declare class TabSafeAreaView {
5
- constructor();
6
- /** Which edges to inset: usually `['bottom']`. Absent insets all four. */
7
- readonly edges: import("@angular/core").InputSignal<readonly TabSafeAreaEdge[] | undefined>;
8
- /**
9
- * Native takes all four edges every time, as booleans; a partial record leaves the missing
10
- * ones at whatever they were.
11
- */
12
- protected readonly resolvedEdges: import("@angular/core").Signal<Record<TabSafeAreaEdge, boolean>>;
4
+ export type TabSafeAreaEdge = ScreenSafeAreaEdge;
5
+ export declare class TabSafeAreaView extends ScreenSafeAreaView {
13
6
  static ɵfac: i0.ɵɵFactoryDeclaration<TabSafeAreaView, never>;
14
- static ɵcmp: i0.ɵɵComponentDeclaration<TabSafeAreaView, "tab-safe-area-view", never, { "edges": { "alias": "edges"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
7
+ static ɵcmp: i0.ɵɵComponentDeclaration<TabSafeAreaView, "tab-safe-area-view", never, {}, {}, never, ["*"], true, never>;
15
8
  }
@@ -8,56 +8,21 @@
8
8
  * </view>
9
9
  * ```
10
10
  *
11
- * `<safe-area-view>` cannot do this. Its insets come from the nearest `<safe-area-provider>`,
12
- * which sits at the root of the app, above the tab bar, and so measures only the window's own
13
- * unsafe areas: inside a tab its bottom inset is the home indicator, and anything pinned to the
14
- * bottom of a tab ends up under the bar. On iOS 26 the bar floats over the screen's content, and
15
- * on Android the bottom navigation bar overlays it, so there is no layout that avoids it either.
16
- *
17
- * This is react-native-screens' own `RNSSafeAreaView`, which asks the screen it is in instead.
18
- * On iOS that is the tab screen's `safeAreaInsets`, which UIKit extends by the tab bar - floating
19
- * or not, and with the gap under a floating one - on top of the home indicator; a stack inside a
20
- * tab passes the same insets down to its pages. On Android it is the larger of the bottom
21
- * navigation bar's height and the system bars. Both follow the bar as it changes, rotates, or is
22
- * hidden.
23
- *
24
- * **The insets are applied as margin, not padding.** Whatever is beneath the inset shows through
25
- * it, so a panel whose background has to reach the bottom of the screen puts that background on
26
- * a parent and this inside it, as above: the parent grows by the margin and paints behind the
27
- * bar, and the content ends where the bar begins.
28
- *
29
- * It has to be inside a tab, or a page of a stack inside one. On iOS, with no screen above it, it
30
- * insets by nothing.
11
+ * It is `<screen-safe-area-view>` under the name it has inside a tab, where the screen it asks is
12
+ * the tab's and the bar it clears is the tab bar. See `screen-safe-area-view.ts`.
31
13
  */
32
- import { Component, ElementRef, computed, inject, input } from '@angular/core';
33
- import { ownHost } from "./own-host.js";
14
+ import { Component } from '@angular/core';
15
+ import { ScreenSafeAreaView } from "./screen-safe-area-view.js";
34
16
  import * as i0 from "@angular/core";
35
- const ALL = ['top', 'right', 'bottom', 'left'];
36
- export class TabSafeAreaView {
37
- constructor() {
38
- ownHost(inject(ElementRef).nativeElement, this.constructor);
39
- }
40
- /** Which edges to inset: usually `['bottom']`. Absent insets all four. */
41
- edges = input(/* @ts-ignore */
42
- ...(ngDevMode ? [undefined, { debugName: "edges" }] : /* istanbul ignore next */ []));
43
- /**
44
- * Native takes all four edges every time, as booleans; a partial record leaves the missing
45
- * ones at whatever they were.
46
- */
47
- resolvedEdges = computed(() => {
48
- const edges = this.edges() ?? ALL;
49
- return Object.fromEntries(ALL.map((edge) => [edge, edges.includes(edge)]));
50
- }, /* @ts-ignore */
51
- ...(ngDevMode ? [{ debugName: "resolvedEdges" }] : /* istanbul ignore next */ []));
52
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: TabSafeAreaView, deps: [], target: i0.ɵɵFactoryTarget.Component });
53
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.2.0", type: TabSafeAreaView, isStandalone: true, selector: "tab-safe-area-view", inputs: { edges: { classPropertyName: "edges", publicName: "edges", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "edges": "resolvedEdges()" } }, ngImport: i0, template: '<ng-content />', isInline: true });
17
+ export class TabSafeAreaView extends ScreenSafeAreaView {
18
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: TabSafeAreaView, deps: null, target: i0.ɵɵFactoryTarget.Component });
19
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.2.0", type: TabSafeAreaView, isStandalone: true, selector: "tab-safe-area-view", usesInheritance: true, ngImport: i0, template: '<ng-content />', isInline: true });
54
20
  }
55
21
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: TabSafeAreaView, decorators: [{
56
22
  type: Component,
57
23
  args: [{
58
24
  selector: 'tab-safe-area-view',
59
25
  template: '<ng-content />',
60
- host: { '[edges]': 'resolvedEdges()' },
61
26
  }]
62
- }], ctorParameters: () => [], propDecorators: { edges: [{ type: i0.Input, args: [{ isSignal: true, alias: "edges", required: false }] }] } });
27
+ }] });
63
28
  //# sourceMappingURL=tab-safe-area-view.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tab-safe-area-view.js","sourceRoot":"","sources":["../src/tab-safe-area-view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE/E,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;;AAKxC,MAAM,GAAG,GAA+B,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAO3E,MAAM,OAAO,eAAe;IAC1B;QACE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,aAA2B,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAC5E,CAAC;IAED,0EAA0E;IACjE,KAAK,GAAG,KAAK;yFAA8B,CAAC;IAErD;;;OAGG;IACgB,aAAa,GAAG,QAAQ,CAAC,GAAG,EAAE;QAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC;QAClC,OAAO,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAGxE,CAAC;IACJ,CAAC;sFAAC,CAAC;uGAlBQ,eAAe;2FAAf,eAAe,wQAHhB,gBAAgB;;2FAGf,eAAe;kBAL3B,SAAS;mBAAC;oBACT,QAAQ,EAAE,oBAAoB;oBAC9B,QAAQ,EAAE,gBAAgB;oBAC1B,IAAI,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE;iBACvC","sourcesContent":["/**\n * A view that keeps its content clear of the tab bar, as well as the home indicator and the\n * system bars.\n *\n * ```html\n * <view class=\"panel absolute bottom-0 left-0 right-0\">\n * <tab-safe-area-view [edges]=\"['bottom']\">…</tab-safe-area-view>\n * </view>\n * ```\n *\n * `<safe-area-view>` cannot do this. Its insets come from the nearest `<safe-area-provider>`,\n * which sits at the root of the app, above the tab bar, and so measures only the window's own\n * unsafe areas: inside a tab its bottom inset is the home indicator, and anything pinned to the\n * bottom of a tab ends up under the bar. On iOS 26 the bar floats over the screen's content, and\n * on Android the bottom navigation bar overlays it, so there is no layout that avoids it either.\n *\n * This is react-native-screens' own `RNSSafeAreaView`, which asks the screen it is in instead.\n * On iOS that is the tab screen's `safeAreaInsets`, which UIKit extends by the tab bar - floating\n * or not, and with the gap under a floating one - on top of the home indicator; a stack inside a\n * tab passes the same insets down to its pages. On Android it is the larger of the bottom\n * navigation bar's height and the system bars. Both follow the bar as it changes, rotates, or is\n * hidden.\n *\n * **The insets are applied as margin, not padding.** Whatever is beneath the inset shows through\n * it, so a panel whose background has to reach the bottom of the screen puts that background on\n * a parent and this inside it, as above: the parent grows by the margin and paints behind the\n * bar, and the content ends where the bar begins.\n *\n * It has to be inside a tab, or a page of a stack inside one. On iOS, with no screen above it, it\n * insets by nothing.\n */\nimport { Component, ElementRef, computed, inject, input } from '@angular/core';\nimport type { EngineNode } from '@ng-native/fabric';\nimport { ownHost } from './own-host.ts';\n\n/** The edges of the screen. */\nexport type TabSafeAreaEdge = 'top' | 'right' | 'bottom' | 'left';\n\nconst ALL: readonly TabSafeAreaEdge[] = ['top', 'right', 'bottom', 'left'];\n\n@Component({\n selector: 'tab-safe-area-view',\n template: '<ng-content />',\n host: { '[edges]': 'resolvedEdges()' },\n})\nexport class TabSafeAreaView {\n constructor() {\n ownHost(inject(ElementRef).nativeElement as EngineNode, this.constructor);\n }\n\n /** Which edges to inset: usually `['bottom']`. Absent insets all four. */\n readonly edges = input<readonly TabSafeAreaEdge[]>();\n\n /**\n * Native takes all four edges every time, as booleans; a partial record leaves the missing\n * ones at whatever they were.\n */\n protected readonly resolvedEdges = computed(() => {\n const edges = this.edges() ?? ALL;\n return Object.fromEntries(ALL.map((edge) => [edge, edges.includes(edge)])) as Record<\n TabSafeAreaEdge,\n boolean\n >;\n });\n}\n"]}
1
+ {"version":3,"file":"tab-safe-area-view.js","sourceRoot":"","sources":["../src/tab-safe-area-view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAA2B,MAAM,4BAA4B,CAAC;;AASzF,MAAM,OAAO,eAAgB,SAAQ,kBAAkB;uGAA1C,eAAe;2FAAf,eAAe,qGAFhB,gBAAgB;;2FAEf,eAAe;kBAJ3B,SAAS;mBAAC;oBACT,QAAQ,EAAE,oBAAoB;oBAC9B,QAAQ,EAAE,gBAAgB;iBAC3B","sourcesContent":["/**\n * A view that keeps its content clear of the tab bar, as well as the home indicator and the\n * system bars.\n *\n * ```html\n * <view class=\"panel absolute bottom-0 left-0 right-0\">\n * <tab-safe-area-view [edges]=\"['bottom']\">…</tab-safe-area-view>\n * </view>\n * ```\n *\n * It is `<screen-safe-area-view>` under the name it has inside a tab, where the screen it asks is\n * the tab's and the bar it clears is the tab bar. See `screen-safe-area-view.ts`.\n */\nimport { Component } from '@angular/core';\nimport { ScreenSafeAreaView, type ScreenSafeAreaEdge } from './screen-safe-area-view.ts';\n\n/** The edges of the screen. */\nexport type TabSafeAreaEdge = ScreenSafeAreaEdge;\n\n@Component({\n selector: 'tab-safe-area-view',\n template: '<ng-content />',\n})\nexport class TabSafeAreaView extends ScreenSafeAreaView {}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ng-native/router",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "@angular/router over native navigation for Angular Native: stack and tab outlets, native headers and links.",
5
5
  "keywords": [
6
6
  "angular",
@@ -17,8 +17,8 @@
17
17
  "type": "module",
18
18
  "main": "dist/index.js",
19
19
  "dependencies": {
20
- "@ng-native/device": "0.4.0",
21
- "@ng-native/fabric": "0.4.0"
20
+ "@ng-native/device": "0.5.0",
21
+ "@ng-native/fabric": "0.5.0"
22
22
  },
23
23
  "peerDependencies": {
24
24
  "@angular/common": "^22.0.0",