@momo-kits/foundation 0.163.1-beta.15 → 0.163.1-beta.17

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.
@@ -16,7 +16,7 @@ import { DeviceEventEmitter } from 'react-native';
16
16
  import StackScreen from './StackScreen';
17
17
  import ModalScreen from './ModalScreen';
18
18
  import Navigator from './Navigator';
19
- import { getModalOptions, getStackOptions } from './utils';
19
+ import { getModalOptions, getStackOptions, useNativeCanGoBack } from './utils';
20
20
  import { NavigationContainerProps } from './types';
21
21
  import { ApplicationContext, MiniAppContext } from '../Context';
22
22
  import Localize from './Localize';
@@ -93,6 +93,7 @@ const Navigation: React.FC<any> = ({
93
93
  const navigator = useRef(new Navigator(navigationRef, isReady));
94
94
  const [showGrid, setShowGrid] = useState(false);
95
95
  const insets = useSafeAreaInsets();
96
+ const syncCanGoBack = useNativeCanGoBack();
96
97
 
97
98
  let headerBackground = context?.designSystemConfig?.config?.headerBar;
98
99
  let headerGradient = theme.colors?.gradient;
@@ -192,7 +193,9 @@ const Navigation: React.FC<any> = ({
192
193
  ref={navigationRef}
193
194
  onReady={() => {
194
195
  isReady.current = true;
196
+ syncCanGoBack(navigationRef.current?.getRootState?.());
195
197
  }}
198
+ onStateChange={syncCanGoBack}
196
199
  >
197
200
  <Stack.Navigator
198
201
  initialRouteName="Stack"
@@ -1,11 +1,18 @@
1
- import React, { useContext, useEffect, useMemo, useRef } from 'react';
1
+ import React, {
2
+ useCallback,
3
+ useContext,
4
+ useEffect,
5
+ useMemo,
6
+ useRef,
7
+ } from 'react';
2
8
  import {
3
9
  StackNavigationOptions,
4
10
  TransitionPresets,
5
11
  } from '@react-navigation/stack';
12
+ import type { NavigationState, PartialState } from '@react-navigation/native';
6
13
  import type { HeaderTitleProps, NavigationOptions } from './types';
7
14
  import { Colors, Spacing } from '../Consts';
8
- import { Animated, AppState, Platform } from 'react-native';
15
+ import { Animated, AppState, NativeModules, Platform } from 'react-native';
9
16
  import type { SharedValue } from 'react-native-reanimated';
10
17
  import { useSharedValue } from 'react-native-reanimated';
11
18
  import {
@@ -38,9 +45,6 @@ const getStackOptions = (): StackNavigationOptions => {
38
45
  headerLeft: (props: any) => <HeaderLeft {...props} />,
39
46
  headerRight: (props: any) => <HeaderRight {...props} />,
40
47
  headerTintColor: Colors.black_17,
41
- /**
42
- * swipe back for iOS only, Android keeps the hardware back button
43
- */
44
48
  gestureEnabled: Platform.OS === 'ios',
45
49
  ...TransitionPresets.SlideFromRightIOS,
46
50
  };
@@ -57,9 +61,6 @@ const getModalOptions = (): StackNavigationOptions => {
57
61
  cardOverlayEnabled: true,
58
62
  animation: 'none',
59
63
  presentation: 'transparentModal',
60
- /**
61
- * modal & bottom sheet dismiss through their own overlay/pan gesture
62
- */
63
64
  gestureEnabled: false,
64
65
  };
65
66
  };
@@ -254,6 +255,55 @@ const useAppState = () => {
254
255
  };
255
256
  };
256
257
 
258
+ /**
259
+ * screens the focused navigation branch can still pop.
260
+ * only stack navigators count, switching bottom tab is not a back step
261
+ */
262
+ const getStackDepth = (
263
+ state?: NavigationState | PartialState<NavigationState>,
264
+ ): number => {
265
+ const routes = state?.routes;
266
+ if (!routes?.length) {
267
+ return 0;
268
+ }
269
+
270
+ const index = state?.index ?? routes.length - 1;
271
+ const depth = state?.type === 'stack' ? index : 0;
272
+
273
+ return depth + getStackDepth(routes[index]?.state);
274
+ };
275
+
276
+ /**
277
+ * report back ownership to the native container: `true` when the mini app sits
278
+ * on its root screen and native may dismiss the rootview, `false` while
279
+ * react-navigation still has screens (or a modal / bottom sheet) to pop.
280
+ */
281
+ const useNativeCanGoBack = () => {
282
+ const lastValue = useRef<boolean | undefined>(undefined);
283
+
284
+ return useCallback(
285
+ (state?: NavigationState | PartialState<NavigationState>) => {
286
+ const canDismiss = getStackDepth(state) === 0;
287
+ if (lastValue.current === canDismiss) {
288
+ return;
289
+ }
290
+
291
+ const setCanGoBack = NativeModules?.MiniAppModule?.setCanGoBack;
292
+ if (typeof setCanGoBack !== 'function') {
293
+ return;
294
+ }
295
+
296
+ lastValue.current = canDismiss;
297
+ try {
298
+ setCanGoBack(canDismiss);
299
+ } catch (error) {
300
+ console.warn('[NavigationContainer] setCanGoBack failed:', error);
301
+ }
302
+ },
303
+ [],
304
+ );
305
+ };
306
+
257
307
  /**
258
308
  * Union of the two animation runtimes an internal foundation component might
259
309
  * receive. Public Screen props still accept React Native Animated.Value only;
@@ -295,9 +345,11 @@ export {
295
345
  getStackOptions,
296
346
  getModalOptions,
297
347
  getOptions,
348
+ getStackDepth,
298
349
  exportHeaderTitle,
299
350
  setAutomationID,
300
351
  useComponentId,
301
352
  useAppState,
353
+ useNativeCanGoBack,
302
354
  useNormalizedSharedValue,
303
355
  };
package/package.json CHANGED
@@ -1,35 +1,35 @@
1
1
  {
2
- "name": "@momo-kits/foundation",
3
- "version": "0.163.1-beta.15",
4
- "description": "React Native Component Kits",
5
- "main": "index.ts",
6
- "scripts": {},
7
- "keywords": [
8
- "@momo-kits/foundation"
9
- ],
10
- "dependencies": {
11
- "react-native-fast-image": "git+https://oauth2:TGi6oBj-LdzsKpLXQSoH@gitlab.mservice.com.vn/momo-platform/public/react-native-fast-image.git#v8.11.0",
12
- "@react-navigation/bottom-tabs": "7.4.2",
13
- "@react-navigation/core": "7.12.1",
14
- "@react-navigation/elements": "2.5.2",
15
- "@react-navigation/native": "7.1.14",
16
- "@react-navigation/routers": "7.4.1",
17
- "@react-navigation/stack": "7.4.2",
18
- "react-native-gesture-handler": "2.27.1",
19
- "react-native-linear-gradient": "git+https://oauth2:TGi6oBj-LdzsKpLXQSoH@gitlab.mservice.com.vn/momo-platform/public/react-native-linear-gradient#v3.0.0",
20
- "react-native-reanimated": "4.2.2",
21
- "react-native-safe-area-context": "5.5.2",
22
- "@shopify/flash-list": "2.1.0",
23
- "lottie-react-native": "7.2.4"
24
- },
25
- "peerDependencies": {
26
- "react-native": "*"
27
- },
28
- "devDependencies": {
29
- "@types/color": "3.0.6"
30
- },
31
- "publishConfig": {
32
- "registry": "https://registry.npmjs.org/"
33
- },
34
- "license": "MoMo"
35
- }
2
+ "name": "@momo-kits/foundation",
3
+ "version": "0.163.1-beta.17",
4
+ "description": "React Native Component Kits",
5
+ "main": "index.ts",
6
+ "scripts": {},
7
+ "keywords": [
8
+ "@momo-kits/foundation"
9
+ ],
10
+ "dependencies": {
11
+ "react-native-fast-image": "git+https://oauth2:TGi6oBj-LdzsKpLXQSoH@gitlab.mservice.com.vn/momo-platform/public/react-native-fast-image.git#v8.11.0",
12
+ "@react-navigation/bottom-tabs": "7.4.2",
13
+ "@react-navigation/core": "7.12.1",
14
+ "@react-navigation/elements": "2.5.2",
15
+ "@react-navigation/native": "7.1.14",
16
+ "@react-navigation/routers": "7.4.1",
17
+ "@react-navigation/stack": "7.4.2",
18
+ "react-native-gesture-handler": "2.27.1",
19
+ "react-native-linear-gradient": "git+https://oauth2:TGi6oBj-LdzsKpLXQSoH@gitlab.mservice.com.vn/momo-platform/public/react-native-linear-gradient#v3.0.0",
20
+ "react-native-reanimated": "4.2.2",
21
+ "react-native-safe-area-context": "5.5.2",
22
+ "@shopify/flash-list": "2.1.0",
23
+ "lottie-react-native": "7.2.4"
24
+ },
25
+ "peerDependencies": {
26
+ "react-native": "*"
27
+ },
28
+ "devDependencies": {
29
+ "@types/color": "3.0.6"
30
+ },
31
+ "publishConfig": {
32
+ "registry": "https://registry.npmjs.org/"
33
+ },
34
+ "license": "MoMo"
35
+ }