@granite-js/react-native 0.1.23-next.0 → 0.1.23-next.10

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.
Files changed (32) hide show
  1. package/CHANGELOG.md +120 -0
  2. package/dist/async-bridges.d.mts +1 -1
  3. package/dist/async-bridges.js +5 -8
  4. package/dist/async-bridges.mjs +1 -1
  5. package/dist/chunk-A3JGM5OI.mjs +7 -0
  6. package/dist/chunk-OWDLSIVX.mjs +7 -0
  7. package/dist/constant-bridges.js +4 -7
  8. package/dist/constant-bridges.mjs +2 -2
  9. package/dist/native-modules/index.d.ts +0 -1
  10. package/dist/native-modules/natives/GraniteModule.brick.d.ts +11 -0
  11. package/dist/native-modules/natives/closeView.d.ts +1 -1
  12. package/dist/react/index.d.ts +1 -0
  13. package/dist/react/useWaitForReturnNavigator.d.ts +39 -0
  14. package/dist/router/Router.d.ts +2 -3
  15. package/dist/router/components/CanGoBackGuard.d.ts +2 -1
  16. package/dist/router/components/useRouterBackHandler.d.ts +1 -1
  17. package/package.json +13 -11
  18. package/src/native-modules/index.ts +0 -1
  19. package/src/native-modules/natives/GraniteModule.brick.ts +12 -0
  20. package/src/native-modules/natives/closeView.ts +1 -1
  21. package/src/native-modules/natives/getSchemeUri.ts +2 -2
  22. package/src/router/Router.tsx +31 -8
  23. package/src/router/components/CanGoBackGuard.tsx +2 -3
  24. package/src/router/components/useRouterBackHandler.tsx +1 -1
  25. package/src/visibility/useVisibilityChanged.tsx +2 -6
  26. package/src/native-event-emitter/eventEmitters/index.ts +0 -3
  27. package/src/native-event-emitter/eventEmitters/types.ts +0 -4
  28. package/src/native-event-emitter/eventEmitters/visibilityChanged.ts +0 -11
  29. package/src/native-event-emitter/index.ts +0 -1
  30. package/src/native-event-emitter/nativeEventEmitter.ts +0 -29
  31. package/src/native-modules/core/GraniteCoreModule.ts +0 -9
  32. package/src/native-modules/natives/GraniteModule.ts +0 -11
package/CHANGELOG.md CHANGED
@@ -1,5 +1,125 @@
1
1
  # @granite-js/react-native
2
2
 
3
+ ## 0.1.23-next.10
4
+
5
+ ### Patch Changes
6
+
7
+ - fix
8
+ - Updated dependencies
9
+ - @granite-js/plugin-core@0.1.23-next.10
10
+ - @granite-js/style-utils@0.1.23-next.10
11
+ - @granite-js/lottie@0.1.23-next.10
12
+ - @granite-js/native@0.1.23-next.10
13
+ - @granite-js/image@0.1.23-next.10
14
+ - @granite-js/mpack@0.1.23-next.10
15
+ - @granite-js/jest@0.1.23-next.10
16
+ - @granite-js/cli@0.1.23-next.10
17
+
18
+ ## 0.1.23-next.9
19
+
20
+ ### Patch Changes
21
+
22
+ - tollback
23
+ - Updated dependencies
24
+ - @granite-js/plugin-core@0.1.23-next.9
25
+ - @granite-js/style-utils@0.1.23-next.9
26
+ - @granite-js/lottie@0.1.23-next.9
27
+ - @granite-js/native@0.1.23-next.9
28
+ - @granite-js/image@0.1.23-next.9
29
+ - @granite-js/mpack@0.1.23-next.9
30
+ - @granite-js/jest@0.1.23-next.9
31
+ - @granite-js/cli@0.1.23-next.9
32
+
33
+ ## 0.1.23-next.8
34
+
35
+ ### Patch Changes
36
+
37
+ - router
38
+ - Updated dependencies
39
+ - @granite-js/plugin-core@0.1.23-next.8
40
+ - @granite-js/style-utils@0.1.23-next.8
41
+ - @granite-js/lottie@0.1.23-next.8
42
+ - @granite-js/native@0.1.23-next.8
43
+ - @granite-js/image@0.1.23-next.8
44
+ - @granite-js/mpack@0.1.23-next.8
45
+ - @granite-js/jest@0.1.23-next.8
46
+ - @granite-js/cli@0.1.23-next.8
47
+
48
+ ## 0.1.23-next.7
49
+
50
+ ### Patch Changes
51
+
52
+ - fix
53
+ - Updated dependencies
54
+ - @granite-js/plugin-core@0.1.23-next.7
55
+ - @granite-js/style-utils@0.1.23-next.7
56
+ - @granite-js/lottie@0.1.23-next.7
57
+ - @granite-js/native@0.1.23-next.7
58
+ - @granite-js/image@0.1.23-next.7
59
+ - @granite-js/mpack@0.1.23-next.7
60
+ - @granite-js/jest@0.1.23-next.7
61
+ - @granite-js/cli@0.1.23-next.7
62
+
63
+ ## 0.1.23-next.6
64
+
65
+ ### Patch Changes
66
+
67
+ - test
68
+ - Updated dependencies
69
+ - @granite-js/plugin-core@0.1.23-next.6
70
+ - @granite-js/style-utils@0.1.23-next.6
71
+ - @granite-js/lottie@0.1.23-next.6
72
+ - @granite-js/native@0.1.23-next.6
73
+ - @granite-js/image@0.1.23-next.6
74
+ - @granite-js/mpack@0.1.23-next.6
75
+ - @granite-js/jest@0.1.23-next.6
76
+ - @granite-js/cli@0.1.23-next.6
77
+
78
+ ## 0.1.23-next.5
79
+
80
+ ### Patch Changes
81
+
82
+ - temp
83
+ - Updated dependencies
84
+ - @granite-js/plugin-core@0.1.23-next.5
85
+ - @granite-js/style-utils@0.1.23-next.5
86
+ - @granite-js/lottie@0.1.23-next.5
87
+ - @granite-js/native@0.1.23-next.5
88
+ - @granite-js/image@0.1.23-next.5
89
+ - @granite-js/mpack@0.1.23-next.5
90
+ - @granite-js/jest@0.1.23-next.5
91
+ - @granite-js/cli@0.1.23-next.5
92
+
93
+ ## 0.1.23-next.4
94
+
95
+ ### Patch Changes
96
+
97
+ - test
98
+ - Updated dependencies
99
+ - @granite-js/plugin-core@0.1.23-next.4
100
+ - @granite-js/style-utils@0.1.23-next.4
101
+ - @granite-js/lottie@0.1.23-next.4
102
+ - @granite-js/native@0.1.23-next.4
103
+ - @granite-js/image@0.1.23-next.4
104
+ - @granite-js/mpack@0.1.23-next.4
105
+ - @granite-js/jest@0.1.23-next.4
106
+ - @granite-js/cli@0.1.23-next.4
107
+
108
+ ## 0.1.23-next.3
109
+
110
+ ### Patch Changes
111
+
112
+ - test
113
+ - Updated dependencies
114
+ - @granite-js/plugin-core@0.1.23-next.3
115
+ - @granite-js/style-utils@0.1.23-next.3
116
+ - @granite-js/lottie@0.1.23-next.3
117
+ - @granite-js/native@0.1.23-next.3
118
+ - @granite-js/image@0.1.23-next.3
119
+ - @granite-js/mpack@0.1.23-next.3
120
+ - @granite-js/jest@0.1.23-next.3
121
+ - @granite-js/cli@0.1.23-next.3
122
+
3
123
  ## 0.1.23-next.0
4
124
 
5
125
  ### Patch Changes
@@ -18,7 +18,7 @@
18
18
  * }
19
19
  * ```
20
20
  */
21
- declare function closeView(): Promise<void | undefined>;
21
+ declare function closeView(): Promise<void>;
22
22
 
23
23
  /**
24
24
  * @public
@@ -25,12 +25,9 @@ __export(async_bridges_exports, {
25
25
  });
26
26
  module.exports = __toCommonJS(async_bridges_exports);
27
27
 
28
- // src/native-modules/natives/GraniteModule.ts
29
- var import_react_native = require("react-native");
30
- var GraniteModule = import_react_native.TurboModuleRegistry.get("GraniteModule");
31
- if (!GraniteModule) {
32
- console.warn("[GraniteModule] is not registered");
33
- }
28
+ // src/native-modules/natives/GraniteModule.brick.ts
29
+ var import_brick_module = require("brick-module");
30
+ var GraniteModule = import_brick_module.BrickModule.get("GraniteModule");
34
31
 
35
32
  // src/native-modules/natives/closeView.ts
36
33
  async function closeView() {
@@ -38,9 +35,9 @@ async function closeView() {
38
35
  }
39
36
 
40
37
  // src/native-modules/natives/openURL.ts
41
- var import_react_native2 = require("react-native");
38
+ var import_react_native = require("react-native");
42
39
  function openURL(url) {
43
- return import_react_native2.Linking.openURL(url);
40
+ return import_react_native.Linking.openURL(url);
44
41
  }
45
42
  // Annotate the CommonJS export names for ESM import in node:
46
43
  0 && (module.exports = {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  GraniteModule
3
- } from "./chunk-2PYPIQMA.mjs";
3
+ } from "./chunk-OWDLSIVX.mjs";
4
4
 
5
5
  // src/native-modules/natives/closeView.ts
6
6
  async function closeView() {
@@ -0,0 +1,7 @@
1
+ // src/native-modules/natives/GraniteModule.ts
2
+ import { TurboModuleRegistry } from "react-native";
3
+ var GraniteModule = TurboModuleRegistry.getEnforcing("GraniteModule");
4
+
5
+ export {
6
+ GraniteModule
7
+ };
@@ -0,0 +1,7 @@
1
+ // src/native-modules/natives/GraniteModule.brick.ts
2
+ import { BrickModule } from "brick-module";
3
+ var GraniteModule = BrickModule.get("GraniteModule");
4
+
5
+ export {
6
+ GraniteModule
7
+ };
@@ -24,16 +24,13 @@ __export(constant_bridges_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(constant_bridges_exports);
26
26
 
27
- // src/native-modules/natives/GraniteModule.ts
28
- var import_react_native = require("react-native");
29
- var GraniteModule = import_react_native.TurboModuleRegistry.get("GraniteModule");
30
- if (!GraniteModule) {
31
- console.warn("[GraniteModule] is not registered");
32
- }
27
+ // src/native-modules/natives/GraniteModule.brick.ts
28
+ var import_brick_module = require("brick-module");
29
+ var GraniteModule = import_brick_module.BrickModule.get("GraniteModule");
33
30
 
34
31
  // src/native-modules/natives/getSchemeUri.ts
35
32
  function getSchemeUri() {
36
- return GraniteModule?.schemeUri ?? "unknown";
33
+ return GraniteModule.schemeUri;
37
34
  }
38
35
  // Annotate the CommonJS export names for ESM import in node:
39
36
  0 && (module.exports = {
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  GraniteModule
3
- } from "./chunk-2PYPIQMA.mjs";
3
+ } from "./chunk-OWDLSIVX.mjs";
4
4
 
5
5
  // src/native-modules/natives/getSchemeUri.ts
6
6
  function getSchemeUri() {
7
- return GraniteModule?.schemeUri ?? "unknown";
7
+ return GraniteModule.schemeUri;
8
8
  }
9
9
  export {
10
10
  getSchemeUri
@@ -1,3 +1,2 @@
1
1
  /** Bridges API */
2
2
  export * from './natives';
3
- export { GraniteCoreModule } from './core/GraniteCoreModule';
@@ -0,0 +1,11 @@
1
+ import { BrickModuleSpec } from 'brick-module';
2
+ interface GraniteModuleSpec extends BrickModuleSpec {
3
+ readonly moduleName: 'GraniteModule';
4
+ readonly supportedEvents: ['visibilityChanged'];
5
+ closeView(): Promise<void>;
6
+ schemeUri: string;
7
+ }
8
+ export declare const GraniteModule: GraniteModuleSpec & {
9
+ addEventListener<TEvent = unknown>(eventName: "visibilityChanged", listener: (event: TEvent) => void): () => void;
10
+ };
11
+ export {};
@@ -18,4 +18,4 @@
18
18
  * }
19
19
  * ```
20
20
  */
21
- export declare function closeView(): Promise<void | undefined>;
21
+ export declare function closeView(): Promise<void>;
@@ -0,0 +1 @@
1
+ export { useWaitForReturnNavigator } from './useWaitForReturnNavigator';
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @public
3
+ * @category Screen Control
4
+ * @name useWaitForReturnNavigator
5
+ * @description
6
+ * A Hook that helps execute the next code synchronously when returning from a screen transition.
7
+ * Screen navigation uses [@react-navigation/native `useNavigation`'s `navigate`](https://reactnavigation.org/docs/6.x/navigation-prop#navigate).
8
+ *
9
+ * For example, it can be used when you want to log that a user has navigated to another screen and returned.
10
+ *
11
+ * @example
12
+ * ### Example of code execution when returning from screen navigation
13
+ *
14
+ * When the **"Navigate"** button is pressed, it navigates to another screen, and logs are created when returning.
15
+ *
16
+ * ```tsx
17
+ * import { Button } from 'react-native';
18
+ * import { useWaitForReturnNavigator } from '@granite-js/react-native';
19
+ *
20
+ * export function UseWaitForReturnNavigator() {
21
+ * const navigate = useWaitForReturnNavigator();
22
+ *
23
+ * return (
24
+ * <>
25
+ * <Button
26
+ * title="Navigate"
27
+ * onPress={async () => {
28
+ * console.log(1);
29
+ * await navigate('/examples/use-visibility');
30
+ * // This code executes when returning to the screen
31
+ * console.log(2);
32
+ * }}
33
+ * />
34
+ * </>
35
+ * );
36
+ * }
37
+ * ```
38
+ */
39
+ export declare function useWaitForReturnNavigator<T extends Record<string, object | undefined>>(): <RouteName extends keyof T>(route: RouteName, params?: T[RouteName]) => Promise<void>;
@@ -8,7 +8,7 @@ interface StackNavigatorProps {
8
8
  * @description
9
9
  * You can create and pass a NavigationContainerRef from @react-navigation/native externally. This allows external control of the router.
10
10
  */
11
- navigationContainerRef?: NavigationContainerRefWithCurrent<any>;
11
+ navigationContainerRef?: NavigationContainerRefWithCurrent<never>;
12
12
  /**
13
13
  * @name defaultScreenOption
14
14
  * @description
@@ -26,7 +26,6 @@ interface StackNavigatorProps {
26
26
  screenContainer?: ComponentType<PropsWithChildren<any>>;
27
27
  }
28
28
  type NavigationContainerProps = Pick<ComponentProps<typeof NavigationContainer>, 'ref' | 'documentTitle' | 'fallback' | 'onReady' | 'onUnhandledAction' | 'onStateChange'>;
29
- export declare const navigationRef: NavigationContainerRefWithCurrent<never>;
30
29
  /**
31
30
  * @category Components
32
31
  * @kind function
@@ -38,7 +37,7 @@ export declare const navigationRef: NavigationContainerRefWithCurrent<never>;
38
37
  *
39
38
  * @param {string} prefix Prefix to use when the scheme is executed. For example, to enter 'scheme://my-service/intro', you need to set 'scheme://my-service' as the prefix.
40
39
  * @param {RequireContext} context Object containing information about screens for file-based routing.
41
- * @param {NavigationContainerRefWithCurrent<any>} [navigationContainerRef] You can create and pass a NavigationContainerRef from @react-navigation/native externally. This allows external control of the router.
40
+ * @param {NavigationContainerRefWithCurrent<never>} [navigationContainerRef] You can create and pass a NavigationContainerRef from @react-navigation/native externally. This allows external control of the router.
42
41
  * @param {NativeStackNavigationOptions | ((props: { route: RouteProp<ParamListBase>; navigation: any }) => NativeStackNavigationOptions)} [defaultScreenOption] Default options for screens. You can set options to be applied commonly to screens, such as title or headerStyle.
43
42
  * @param {boolean} [canGoBack=true] Whether navigation back is possible. Default is true, and when set to true, you can use the back gesture or back button from @react-navigation/native.
44
43
  * @param {() => void} [onBack] Callback function called when the user presses the back button or uses the back gesture. For example, you can set it to log when the user presses the back button.
@@ -1,6 +1,7 @@
1
1
  import { ReactNode } from 'react';
2
- export declare function CanGoBackGuard({ children, canGoBack, onBack, setIosSwipeGestureEnabled, }: {
2
+ export declare function CanGoBackGuard({ children, canGoBack, onBack, isInitialScreen, setIosSwipeGestureEnabled, }: {
3
3
  canGoBack: boolean;
4
+ isInitialScreen: boolean;
4
5
  children: ReactNode;
5
6
  onBack?: () => void;
6
7
  setIosSwipeGestureEnabled?: ({ isEnabled }: {
@@ -6,7 +6,7 @@ import { NavigationContainerRefWithCurrent } from '@granite-js/native/@react-nav
6
6
  * @description
7
7
  * A hook that provides a handler for handling back navigation actions. This can be used when you need to close a view directly when the back button is pressed in modals or independent screens where there's no navigation stack. This hook uses `NavigationContainerRef` from `@react-navigation/native` to navigate to the previous screen if there's a remaining navigation stack, or executes the user-defined `onClose` function if the stack is empty.
8
8
  *
9
- * @param {NavigationContainerRefWithCurrent<any>} navigationContainerRef - A `NavigationContainerRef` that can reference the current navigation state. Used when executing back navigation actions.
9
+ * @param {NavigationContainerRefWithCurrent<never>} navigationContainerRef - A `NavigationContainerRef` that can reference the current navigation state. Used when executing back navigation actions.
10
10
  * @param {() => void} [onClose] - A function to execute when the navigation stack is empty. For example, you can pass a function that closes a React Native View.
11
11
  *
12
12
  * @returns {{ handler: () => void }} A handler function that can be used in back buttons or similar components.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@granite-js/react-native",
3
- "version": "0.1.23-next.0",
3
+ "version": "0.1.23-next.10",
4
4
  "description": "The Granite Framework",
5
5
  "bin": {
6
6
  "granite": "./bin/cli.js"
@@ -86,7 +86,7 @@
86
86
  "@babel/core": "^7.24.9",
87
87
  "@babel/preset-env": "^7.24.8",
88
88
  "@babel/preset-typescript": "^7.24.7",
89
- "@granite-js/native": "0.1.23-next.0",
89
+ "@granite-js/native": "0.1.23-next.10",
90
90
  "@testing-library/dom": "^10.4.0",
91
91
  "@testing-library/react": "^16.1.0",
92
92
  "@types/babel__core": "^7",
@@ -94,29 +94,31 @@
94
94
  "@types/node": "^22.10.2",
95
95
  "@types/react": "npm:19.1.0",
96
96
  "@vitest/coverage-v8": "^2.1.8",
97
+ "brick-module": "^0.1.19",
97
98
  "esbuild": "0.25.9",
98
99
  "eslint": "^9.7.0",
99
100
  "jsdom": "^25.0.1",
100
101
  "react": "npm:19.1.0",
101
- "react-native": "npm:0.81.0",
102
+ "react-native": "npm:0.81.3",
102
103
  "tsup": "^8.5.0",
103
104
  "typescript": "5.8.3",
104
105
  "vitest": "^2.1.8"
105
106
  },
106
107
  "peerDependencies": {
107
- "@granite-js/native": "0.1.23-next.0",
108
+ "@granite-js/native": "0.1.23-next.10",
108
109
  "@types/react": "*",
110
+ "brick-module": "*",
109
111
  "react": "*",
110
112
  "react-native": "*"
111
113
  },
112
114
  "dependencies": {
113
- "@granite-js/cli": "0.1.23-next.0",
114
- "@granite-js/image": "0.1.23-next.0",
115
- "@granite-js/jest": "0.1.23-next.0",
116
- "@granite-js/lottie": "0.1.23-next.0",
117
- "@granite-js/mpack": "0.1.23-next.0",
118
- "@granite-js/plugin-core": "0.1.23-next.0",
119
- "@granite-js/style-utils": "0.1.23-next.0",
115
+ "@granite-js/cli": "0.1.23-next.10",
116
+ "@granite-js/image": "0.1.23-next.10",
117
+ "@granite-js/jest": "0.1.23-next.10",
118
+ "@granite-js/lottie": "0.1.23-next.10",
119
+ "@granite-js/mpack": "0.1.23-next.10",
120
+ "@granite-js/plugin-core": "0.1.23-next.10",
121
+ "@granite-js/style-utils": "0.1.23-next.10",
120
122
  "es-toolkit": "^1.39.8",
121
123
  "react-native-url-polyfill": "1.3.0"
122
124
  }
@@ -1,3 +1,2 @@
1
1
  /** Bridges API */
2
2
  export * from './natives';
3
- export { GraniteCoreModule } from './core/GraniteCoreModule';
@@ -0,0 +1,12 @@
1
+ import { BrickModule, BrickModuleSpec } from 'brick-module';
2
+
3
+ interface GraniteModuleSpec extends BrickModuleSpec {
4
+ readonly moduleName: 'GraniteModule';
5
+
6
+ readonly supportedEvents: ['visibilityChanged'];
7
+
8
+ closeView(): Promise<void>;
9
+ schemeUri: string;
10
+ }
11
+
12
+ export const GraniteModule = BrickModule.get<GraniteModuleSpec>('GraniteModule');
@@ -1,4 +1,4 @@
1
- import { GraniteModule } from './GraniteModule';
1
+ import { GraniteModule } from './GraniteModule.brick';
2
2
 
3
3
  /**
4
4
  * @public
@@ -1,4 +1,4 @@
1
- import { GraniteModule } from './GraniteModule';
1
+ import { GraniteModule } from './GraniteModule.brick';
2
2
 
3
3
  /**
4
4
  * @public
@@ -23,5 +23,5 @@ import { GraniteModule } from './GraniteModule';
23
23
  * ```
24
24
  */
25
25
  export function getSchemeUri() {
26
- return GraniteModule?.schemeUri ?? 'unknown';
26
+ return GraniteModule.schemeUri;
27
27
  }
@@ -7,7 +7,16 @@ import {
7
7
  RouteProp,
8
8
  } from '@granite-js/native/@react-navigation/native';
9
9
  import { NativeStackNavigationOptions } from '@granite-js/native/@react-navigation/native-stack';
10
- import { ComponentProps, ComponentType, Fragment, PropsWithChildren, ReactElement, useCallback } from 'react';
10
+ import {
11
+ ComponentProps,
12
+ ComponentType,
13
+ Fragment,
14
+ PropsWithChildren,
15
+ ReactElement,
16
+ useCallback,
17
+ useMemo,
18
+ useState,
19
+ } from 'react';
11
20
  import { InitialProps } from '..';
12
21
  import { closeView } from '../native-modules';
13
22
  import { BackButton } from './components/BackButton';
@@ -67,7 +76,7 @@ interface StackNavigatorProps {
67
76
  * @description
68
77
  * You can create and pass a NavigationContainerRef from @react-navigation/native externally. This allows external control of the router.
69
78
  */
70
- navigationContainerRef?: NavigationContainerRefWithCurrent<any>;
79
+ navigationContainerRef?: NavigationContainerRefWithCurrent<never>;
71
80
  /**
72
81
  * @name defaultScreenOption
73
82
  * @description
@@ -89,8 +98,6 @@ type NavigationContainerProps = Pick<
89
98
  'ref' | 'documentTitle' | 'fallback' | 'onReady' | 'onUnhandledAction' | 'onStateChange'
90
99
  >;
91
100
 
92
- export const navigationRef = createNavigationContainerRef<never>();
93
-
94
101
  /**
95
102
  * @category Components
96
103
  * @kind function
@@ -102,7 +109,7 @@ export const navigationRef = createNavigationContainerRef<never>();
102
109
  *
103
110
  * @param {string} prefix Prefix to use when the scheme is executed. For example, to enter 'scheme://my-service/intro', you need to set 'scheme://my-service' as the prefix.
104
111
  * @param {RequireContext} context Object containing information about screens for file-based routing.
105
- * @param {NavigationContainerRefWithCurrent<any>} [navigationContainerRef] You can create and pass a NavigationContainerRef from @react-navigation/native externally. This allows external control of the router.
112
+ * @param {NavigationContainerRefWithCurrent<never>} [navigationContainerRef] You can create and pass a NavigationContainerRef from @react-navigation/native externally. This allows external control of the router.
106
113
  * @param {NativeStackNavigationOptions | ((props: { route: RouteProp<ParamListBase>; navigation: any }) => NativeStackNavigationOptions)} [defaultScreenOption] Default options for screens. You can set options to be applied commonly to screens, such as title or headerStyle.
107
114
  * @param {boolean} [canGoBack=true] Whether navigation back is possible. Default is true, and when set to true, you can use the back gesture or back button from @react-navigation/native.
108
115
  * @param {() => void} [onBack] Callback function called when the user presses the back button or uses the back gesture. For example, you can set it to log when the user presses the back button.
@@ -143,8 +150,10 @@ export function Router({
143
150
  initialScheme,
144
151
  });
145
152
 
153
+ const ref = useMemo(() => navigationContainerRef ?? createNavigationContainerRef<never>(), [navigationContainerRef]);
154
+
146
155
  const { handler, canGoBack, onBack } = useInternalRouterBackHandler({
147
- navigationContainerRef: navigationRef,
156
+ navigationContainerRef: ref,
148
157
  onClose: closeView,
149
158
  });
150
159
 
@@ -163,9 +172,23 @@ export function Router({
163
172
  [canGoBack, defaultScreenOption, headerLeft]
164
173
  );
165
174
 
175
+ const [isInitialScreen, setIsInitialScreen] = useState(true);
176
+
166
177
  return (
167
- <NavigationContainer ref={navigationRef} {...navigationContainerProps} linking={linkingOptions}>
168
- <CanGoBackGuard canGoBack={canGoBack} onBack={onBack} setIosSwipeGestureEnabled={setIosSwipeGestureEnabled}>
178
+ <NavigationContainer
179
+ onStateChange={(state) => {
180
+ setIsInitialScreen(state ? state?.index === 0 : true);
181
+ }}
182
+ ref={ref}
183
+ {...navigationContainerProps}
184
+ linking={linkingOptions}
185
+ >
186
+ <CanGoBackGuard
187
+ canGoBack={canGoBack}
188
+ isInitialScreen={isInitialScreen}
189
+ onBack={onBack}
190
+ setIosSwipeGestureEnabled={setIosSwipeGestureEnabled}
191
+ >
169
192
  <Container {...initialProps}>
170
193
  <StackNavigator.Navigator initialRouteName={initialRouteName} screenOptions={screenOptions}>
171
194
  {Screens}
@@ -1,20 +1,19 @@
1
1
  import { ReactNode, useEffect } from 'react';
2
2
  import { BackHandler } from 'react-native';
3
- import { useIsInitialScreen } from '../hooks/useIsInitialScreen';
4
3
 
5
4
  export function CanGoBackGuard({
6
5
  children,
7
6
  canGoBack,
8
7
  onBack,
8
+ isInitialScreen,
9
9
  setIosSwipeGestureEnabled,
10
10
  }: {
11
11
  canGoBack: boolean;
12
+ isInitialScreen: boolean;
12
13
  children: ReactNode;
13
14
  onBack?: () => void;
14
15
  setIosSwipeGestureEnabled?: ({ isEnabled }: { isEnabled: boolean }) => void;
15
16
  }) {
16
- const isInitialScreen = useIsInitialScreen();
17
-
18
17
  const shouldBlockGoingBack = !canGoBack;
19
18
 
20
19
  useEffect(() => {
@@ -9,7 +9,7 @@ import { useBackEventContext } from '../../use-back-event';
9
9
  * @description
10
10
  * A hook that provides a handler for handling back navigation actions. This can be used when you need to close a view directly when the back button is pressed in modals or independent screens where there's no navigation stack. This hook uses `NavigationContainerRef` from `@react-navigation/native` to navigate to the previous screen if there's a remaining navigation stack, or executes the user-defined `onClose` function if the stack is empty.
11
11
  *
12
- * @param {NavigationContainerRefWithCurrent<any>} navigationContainerRef - A `NavigationContainerRef` that can reference the current navigation state. Used when executing back navigation actions.
12
+ * @param {NavigationContainerRefWithCurrent<never>} navigationContainerRef - A `NavigationContainerRef` that can reference the current navigation state. Used when executing back navigation actions.
13
13
  * @param {() => void} [onClose] - A function to execute when the navigation stack is empty. For example, you can pass a function that closes a React Native View.
14
14
  *
15
15
  * @returns {{ handler: () => void }} A handler function that can be used in back buttons or similar components.
@@ -1,5 +1,5 @@
1
1
  import { createContext, PropsWithChildren, ReactElement, useContext, useEffect, useState } from 'react';
2
- import { nativeEventEmitter } from '../native-event-emitter';
2
+ import { GraniteModule } from '../native-modules/natives/GraniteModule.brick';
3
3
 
4
4
  const VisibilityChangedContext = createContext<boolean | undefined>(undefined);
5
5
 
@@ -31,13 +31,9 @@ export function VisibilityChangedProvider({
31
31
  const [visible, setVisible] = useState(isVisible);
32
32
 
33
33
  useEffect(() => {
34
- const subscription = nativeEventEmitter.addListener('visibilityChanged', (nextVisible) => {
34
+ return GraniteModule.addEventListener('visibilityChanged', (nextVisible: boolean) => {
35
35
  setVisible(nextVisible);
36
36
  });
37
-
38
- return () => {
39
- subscription.remove();
40
- };
41
37
  }, []);
42
38
 
43
39
  return <VisibilityChangedContext.Provider value={visible}>{children}</VisibilityChangedContext.Provider>;
@@ -1,3 +0,0 @@
1
- import { VisibilityChangedEventEmitter } from './visibilityChanged';
2
-
3
- export type EventEmitters = VisibilityChangedEventEmitter;
@@ -1,4 +0,0 @@
1
- export interface EventEmitterSchema<K extends string, P extends unknown[]> {
2
- name: K;
3
- params: P;
4
- }
@@ -1,11 +0,0 @@
1
- import { EventEmitterSchema } from './types';
2
-
3
- /**
4
- * @name VisibilityChangedEventEmitter
5
- * @kind typedef
6
- * @platform iOS
7
- * @description
8
- * Emits an event when the visibility state of the app changes.
9
- * Only available on iOS.
10
- */
11
- export type VisibilityChangedEventEmitter = EventEmitterSchema<'visibilityChanged', [boolean]>;
@@ -1 +0,0 @@
1
- export * from './nativeEventEmitter';
@@ -1,29 +0,0 @@
1
- import { EmitterSubscription, NativeEventEmitter } from 'react-native';
2
- import { EventEmitters } from './eventEmitters';
3
- import { GraniteCoreModule } from '../native-modules';
4
- import { EventEmitterSchema } from './eventEmitters/types';
5
-
6
- type MapOf<T> = T extends EventEmitterSchema<infer K, any> ? { [key in K]: T } : never;
7
- type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
8
- type EventEmittersMap = UnionToIntersection<MapOf<EventEmitters>>;
9
- type EventKeys = keyof EventEmittersMap;
10
- type ParamOf<K extends EventKeys> = EventEmittersMap[K]['params'];
11
- interface EventEmitter {
12
- addListener<Event extends EventKeys>(
13
- event: Event,
14
- callback: (...params: ParamOf<Event>) => void
15
- ): EmitterSubscription;
16
- }
17
-
18
- export const nativeEventEmitter = GraniteCoreModule
19
- ? (new NativeEventEmitter(GraniteCoreModule) as unknown as EventEmitter)
20
- : {
21
- addListener: () => {
22
- console.warn('[GraniteCoreModule] is not registered');
23
- return {
24
- remove: () => {
25
- console.warn('[GraniteCoreModule] is not registered');
26
- },
27
- };
28
- },
29
- };
@@ -1,9 +0,0 @@
1
- import { TurboModule, TurboModuleRegistry } from 'react-native';
2
-
3
- interface GraniteCoreModule extends TurboModule {
4
- addListener: (eventType: string) => void;
5
- removeListeners: (count: number) => void;
6
- importLazy: () => Promise<void>;
7
- }
8
-
9
- export const GraniteCoreModule = TurboModuleRegistry.get<GraniteCoreModule>('GraniteCoreModule');
@@ -1,11 +0,0 @@
1
- import { TurboModule, TurboModuleRegistry } from 'react-native';
2
-
3
- interface GraniteModuleSpec extends TurboModule {
4
- closeView: () => void;
5
- schemeUri: string;
6
- }
7
-
8
- export const GraniteModule = TurboModuleRegistry.get<GraniteModuleSpec>('GraniteModule');
9
- if (!GraniteModule) {
10
- console.warn('[GraniteModule] is not registered');
11
- }