@ng-native/router 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"screens.js","sourceRoot":"","sources":["../src/screens.ts"],"names":[],"mappings":"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","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 * The Fabric name of one of `ExpoRouterToolbarModule`'s views, as `requireNativeView` in\n * `expo-modules-core` computes it. Expo Go runs many projects in one binary and names every view\n * after the one it is running; a build of the app's own has no such suffix.\n *\n * `@ng-native/expo` derives the same name for its own views. The Angular-facing packages do not\n * import each other, and this is three lines.\n */\nfunction expoRouterToolbarView(view: string): string {\n const identifier = (globalThis as { expo?: { __expo_app_identifier__?: string } }).expo\n ?.__expo_app_identifier__;\n return `ViewManagerAdapter_ExpoRouterToolbarModule_${view}${identifier ? `_${identifier}` : ''}`;\n}\n\n/**\n * Ask React Native for react-native-screens' native module, which is what makes it.\n *\n * `ScreensModule` on Android installs, as it is made, the listener that starts a removed screen's\n * transition before its views are unmounted: without it a sheet is emptied and then slides away,\n * and a popped screen leaves as a blank one. React Native makes a module when JavaScript first\n * asks, and react-native-screens asks as its own JavaScript is imported (`fabric/\n * NativeScreensModule`), none of which is imported here. Through the two globals React Native's\n * own `TurboModuleRegistry` reads, in its order, so nothing of React Native is imported either:\n * the second is the only one there is without the bridge.\n */\nfunction loadScreensModule(): void {\n const host = globalThis as {\n __turboModuleProxy?: (name: string) => unknown;\n nativeModuleProxy?: Record<string, unknown>;\n };\n void (host.__turboModuleProxy?.('RNSModule') ?? host.nativeModuleProxy?.['RNSModule']);\n}\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 loadScreensModule();\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 // A screen's bottom toolbar is Expo Router's, which react-native-screens has none of: see\n // `native-toolbar.ts`. Android has no such bar, so the elements are plain views there.\n registerViewName('native-toolbar', {\n ios: expoRouterToolbarView('RouterToolbarHostView'),\n android: 'RCTView',\n });\n registerViewName('native-toolbar-item', {\n ios: expoRouterToolbarView('RouterToolbarItemView'),\n android: 'RCTView',\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":"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","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 * The Fabric name of one of `ExpoRouterToolbarModule`'s views, as `requireNativeView` in\n * `expo-modules-core` computes it. Expo Go runs many projects in one binary and names every view\n * after the one it is running; a build of the app's own has no such suffix.\n *\n * `@ng-native/expo` derives the same name for its own views. The Angular-facing packages do not\n * import each other, and this is three lines.\n */\nfunction expoRouterToolbarView(view: string): string {\n const identifier = (globalThis as { expo?: { __expo_app_identifier__?: string } }).expo\n ?.__expo_app_identifier__;\n return `ViewManagerAdapter_ExpoRouterToolbarModule_${view}${identifier ? `_${identifier}` : ''}`;\n}\n\n/**\n * Ask React Native for react-native-screens' native module, which is what makes it.\n *\n * `ScreensModule` on Android installs, as it is made, the listener that starts a removed screen's\n * transition before its views are unmounted: without it a sheet is emptied and then slides away,\n * and a popped screen leaves as a blank one. React Native makes a module when JavaScript first\n * asks, and react-native-screens asks as its own JavaScript is imported (`fabric/\n * NativeScreensModule`), none of which is imported here. Through the two globals React Native's\n * own `TurboModuleRegistry` reads, in its order, so nothing of React Native is imported either:\n * the second is the only one there is without the bridge.\n */\nfunction loadScreensModule(): void {\n const host = globalThis as {\n __turboModuleProxy?: (name: string) => unknown;\n nativeModuleProxy?: Record<string, unknown>;\n };\n void (host.__turboModuleProxy?.('RNSModule') ?? host.nativeModuleProxy?.['RNSModule']);\n}\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 loadScreensModule();\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 // A screen's bottom toolbar is Expo Router's, which react-native-screens has none of: see\n // `native-toolbar.ts`. Android has no such bar, so the elements are plain views there.\n registerViewName('native-toolbar', {\n ios: expoRouterToolbarView('RouterToolbarHostView'),\n android: 'RCTView',\n });\n registerViewName('native-toolbar-item', {\n ios: expoRouterToolbarView('RouterToolbarItemView'),\n android: 'RCTView',\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 // A tab's page with no stack has no screen of its own: past its tab is the screen holding the\n // whole tab bar, so its header stops at the tab.\n registerHoist('native-header', 'screen', { standIn: { hidden: true }, stopAt: ['native-tab'] });\n // The toolbar host is a view of its own, absolute and out of the layout, that finds its screen\n // through its superviews. Written ahead of a page's scroll view it would be the screen's first\n // subview, where UIKit looks for the scroll view a large title collapses against.\n registerHoist('native-toolbar', 'screen');\n // The header config takes header items and nothing else, so one written inside a component of\n // the header commits as the config's child, not inside the component's view.\n registerHoist('native-header-item', 'native-header', { only: true });\n}\n"]}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * How a `<native-tab>` icon written as SVG markup is drawn. Neither platform's tab bar draws SVG,
3
+ * so the markup is drawn once by a renderer the app provides, `withSvgIcons(SvgImages)` with
4
+ * `SvgImages` from `@ng-native/icons`, and the image it gives back is what native shows. The
5
+ * router imports no renderer: drawing SVG is the icons package's, and it imports no router.
6
+ */
7
+ import { InjectionToken, type ViewContainerRef } from '@angular/core';
8
+ /** Draws SVG markup as an image. `SvgImages` from `@ng-native/icons` is one. */
9
+ export interface SvgIconRenderer {
10
+ /**
11
+ * The markup drawn `size` points square, as an image source native can show, such as a
12
+ * `{ uri, scale }`. It may draw the markup into a view it creates in `at`, which is on screen.
13
+ * Null when it could not be drawn.
14
+ */
15
+ render(svg: string, size: number, at: ViewContainerRef): Promise<unknown>;
16
+ }
17
+ /** The app's renderer, or null when it provides none. */
18
+ export declare const SVG_ICON_RENDERER: InjectionToken<SvgIconRenderer | null>;
19
+ /**
20
+ * Where a tab's SVG icon is drawn: beside the tabs outlet, which is on screen. A tab that is not
21
+ * selected is not, and Android draws nothing that is off screen.
22
+ */
23
+ export declare const SVG_ICON_HOST: InjectionToken<ViewContainerRef>;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * How a `<native-tab>` icon written as SVG markup is drawn. Neither platform's tab bar draws SVG,
3
+ * so the markup is drawn once by a renderer the app provides, `withSvgIcons(SvgImages)` with
4
+ * `SvgImages` from `@ng-native/icons`, and the image it gives back is what native shows. The
5
+ * router imports no renderer: drawing SVG is the icons package's, and it imports no router.
6
+ */
7
+ import { InjectionToken } from '@angular/core';
8
+ /** The app's renderer, or null when it provides none. */
9
+ export const SVG_ICON_RENDERER = new InjectionToken('angular-native.svgIconRenderer', { factory: () => null });
10
+ /**
11
+ * Where a tab's SVG icon is drawn: beside the tabs outlet, which is on screen. A tab that is not
12
+ * selected is not, and Android draws nothing that is off screen.
13
+ */
14
+ export const SVG_ICON_HOST = new InjectionToken('angular-native.svgIconHost');
15
+ //# sourceMappingURL=svg-icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svg-icons.js","sourceRoot":"","sources":["../src/svg-icons.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,cAAc,EAAyB,MAAM,eAAe,CAAC;AAYtE,yDAAyD;AACzD,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,cAAc,CACjD,gCAAgC,EAChC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,CACxB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,cAAc,CAAmB,4BAA4B,CAAC,CAAC","sourcesContent":["/**\n * How a `<native-tab>` icon written as SVG markup is drawn. Neither platform's tab bar draws SVG,\n * so the markup is drawn once by a renderer the app provides, `withSvgIcons(SvgImages)` with\n * `SvgImages` from `@ng-native/icons`, and the image it gives back is what native shows. The\n * router imports no renderer: drawing SVG is the icons package's, and it imports no router.\n */\nimport { InjectionToken, type ViewContainerRef } from '@angular/core';\n\n/** Draws SVG markup as an image. `SvgImages` from `@ng-native/icons` is one. */\nexport interface SvgIconRenderer {\n /**\n * The markup drawn `size` points square, as an image source native can show, such as a\n * `{ uri, scale }`. It may draw the markup into a view it creates in `at`, which is on screen.\n * Null when it could not be drawn.\n */\n render(svg: string, size: number, at: ViewContainerRef): Promise<unknown>;\n}\n\n/** The app's renderer, or null when it provides none. */\nexport const SVG_ICON_RENDERER = new InjectionToken<SvgIconRenderer | null>(\n 'angular-native.svgIconRenderer',\n { factory: () => null },\n);\n\n/**\n * Where a tab's SVG icon is drawn: beside the tabs outlet, which is on screen. A tab that is not\n * selected is not, and Android draws nothing that is off screen.\n */\nexport const SVG_ICON_HOST = new InjectionToken<ViewContainerRef>('angular-native.svgIconHost');\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ng-native/router",
3
- "version": "0.13.0",
3
+ "version": "0.14.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.13.0",
21
- "@ng-native/fabric": "0.13.0"
20
+ "@ng-native/device": "0.14.0",
21
+ "@ng-native/fabric": "0.14.0"
22
22
  },
23
23
  "peerDependencies": {
24
24
  "@angular/common": "^22.0.0",