@momo-kits/foundation 0.150.2-phuc.13 → 0.150.2-scaleSize.35

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 (74) hide show
  1. package/Application/BottomSheet.tsx +39 -114
  2. package/Application/BottomTab/Badge.tsx +15 -2
  3. package/Application/BottomTab/BottomTabBar.tsx +1 -1
  4. package/Application/BottomTab/CustomBottomTabItem.tsx +5 -3
  5. package/Application/BottomTab/TabBarIcon.tsx +8 -6
  6. package/Application/BottomTab/index.tsx +82 -87
  7. package/Application/Components/BackgroundImageView.tsx +1 -1
  8. package/Application/Components/HeaderAnimated.tsx +12 -11
  9. package/Application/Components/HeaderBackground.tsx +1 -1
  10. package/Application/Components/HeaderExtendHeader.tsx +31 -26
  11. package/Application/Components/HeaderLeft.tsx +2 -2
  12. package/Application/Components/HeaderRight.tsx +24 -20
  13. package/Application/Components/HeaderTitle.tsx +19 -7
  14. package/Application/Components/NavigationButton.tsx +12 -11
  15. package/Application/Components/SearchHeader.tsx +20 -3
  16. package/Application/ModalScreen.tsx +14 -1
  17. package/Application/NavigationContainer.tsx +13 -7
  18. package/Application/StackScreen.tsx +100 -155
  19. package/Application/WidgetContainer.tsx +1 -1
  20. package/Application/index.ts +12 -31
  21. package/Application/types.ts +66 -18
  22. package/Application/utils.tsx +41 -17
  23. package/Assets/language.json +6 -2
  24. package/Assets/lottie_circle_loader.json +1 -0
  25. package/Badge/Badge.tsx +14 -11
  26. package/Badge/BadgeRibbon.tsx +1 -1
  27. package/Button/index.tsx +47 -32
  28. package/CheckBox/index.tsx +23 -19
  29. package/CheckBox/styles.ts +1 -0
  30. package/Context/index.ts +23 -0
  31. package/Divider/DashDivider.tsx +10 -9
  32. package/Divider/index.tsx +7 -7
  33. package/FoundationList/index.tsx +7 -4
  34. package/Icon/index.tsx +9 -9
  35. package/IconButton/index.tsx +12 -10
  36. package/Image/index.tsx +9 -2
  37. package/Input/Input.tsx +3 -5
  38. package/Input/InputDropDown.tsx +31 -23
  39. package/Input/InputMoney.tsx +3 -5
  40. package/Input/InputOTP.tsx +7 -7
  41. package/Input/InputPhoneNumber.tsx +271 -0
  42. package/Input/InputSearch.tsx +3 -5
  43. package/Input/InputTextArea.tsx +2 -1
  44. package/Input/TextTyping.tsx +8 -2
  45. package/Input/common.tsx +31 -24
  46. package/Input/index.tsx +21 -1
  47. package/Input/styles.ts +17 -12
  48. package/Input/utils.ts +42 -1
  49. package/Layout/Card.tsx +4 -3
  50. package/Layout/FloatingButton.tsx +1 -1
  51. package/Layout/GridSystem.tsx +15 -14
  52. package/Layout/Item.tsx +1 -1
  53. package/Layout/Screen.tsx +8 -5
  54. package/Layout/Section.tsx +1 -1
  55. package/Layout/TrackingScope.tsx +3 -3
  56. package/Loader/DotLoader.tsx +7 -7
  57. package/Loader/ProgressBar.tsx +10 -9
  58. package/Loader/Spinner.tsx +7 -7
  59. package/Pagination/Dot.tsx +10 -7
  60. package/Pagination/PaginationDot.tsx +8 -8
  61. package/Pagination/PaginationScroll.tsx +12 -10
  62. package/Popup/PopupNotify.tsx +2 -2
  63. package/Popup/PopupPromotion.tsx +1 -1
  64. package/Radio/index.tsx +18 -18
  65. package/Skeleton/index.tsx +1 -1
  66. package/Switch/index.tsx +17 -12
  67. package/Text/index.tsx +4 -4
  68. package/Text/styles.ts +37 -36
  69. package/Text/types.ts +1 -0
  70. package/Text/utils.ts +33 -4
  71. package/Title/index.tsx +48 -29
  72. package/index.ts +1 -0
  73. package/package.json +35 -34
  74. package/Application/Components/index.ts +0 -7
@@ -1,17 +1,12 @@
1
- import React, {
2
- useCallback,
3
- useContext,
4
- useEffect,
5
- useLayoutEffect,
6
- useRef,
7
- } from 'react';
1
+ import React, { useContext, useEffect, useLayoutEffect, useRef } from 'react';
8
2
  import { Alert, InteractionManager } from 'react-native';
9
3
  import { useHeaderHeight } from '@react-navigation/elements';
10
4
  import { ScreenTrackingParams } from './types';
11
5
  import Navigation from './Navigation';
12
- import { ApplicationContext, MiniAppContext, ScreenContext } from './index';
6
+ import { ApplicationContext, MiniAppContext, ScreenContext } from '../Context';
13
7
  import { GridSystem } from '../Layout';
14
8
  import { version } from '../package.json';
9
+ import { useAppState } from './utils';
15
10
 
16
11
  const runAfterInteractions = InteractionManager.runAfterInteractions;
17
12
 
@@ -54,6 +49,7 @@ const StackScreen: React.FC<any> = props => {
54
49
  } = props.route.params;
55
50
  const navigation = useRef(new Navigation(props.navigation, context)).current;
56
51
  const heightHeader = useHeaderHeight();
52
+ const { isBackgroundToForeground } = useAppState();
57
53
 
58
54
  const data = {
59
55
  ...initialParams,
@@ -75,11 +71,81 @@ const StackScreen: React.FC<any> = props => {
75
71
  }
76
72
  }, [navigation, options]);
77
73
 
78
- const onScreenNavigated = useCallback(
79
- (preScreenName: string, screenName: string) => {
80
- const data: any = {
81
- preScreenName,
82
- screenName,
74
+ /**
75
+ * tracking for screen
76
+ */
77
+ useEffect(() => {
78
+ let focusScreen: any;
79
+ let onFocusApp: any;
80
+ if (['Invalid', 'screen'].includes(screenName)) {
81
+ navigator?.maxApi?.showPopup?.('notice', {
82
+ title: 'Invalid screen name',
83
+ message:
84
+ 'Your screen has not been rendered because Platform has not detected the screen name. Please migrate to support this feature.',
85
+ });
86
+ }
87
+
88
+ if (!bottomTab) {
89
+ focusScreen = props.navigation.addListener('focus', () => {
90
+ navigator?.maxApi?.getDataObserver?.('current_screen', (item: any) => {
91
+ onScreenNavigated(item?.screenName, screenName);
92
+ navigator?.maxApi?.setObserver?.('current_screen', { screenName });
93
+ });
94
+ });
95
+ onFocusApp = navigator?.maxApi?.listen?.('onFocusApp', () => {
96
+ if (props.navigation.isFocused()) {
97
+ navigator?.maxApi?.getDataObserver?.(
98
+ 'current_screen',
99
+ (item: any) => {
100
+ onScreenNavigated(item?.screenName, screenName);
101
+ navigator?.maxApi?.setObserver?.('current_screen', {
102
+ screenName,
103
+ });
104
+ },
105
+ );
106
+ }
107
+ });
108
+ }
109
+
110
+ navigator?.maxApi?.startTraceScreenLoad?.(
111
+ screenName,
112
+ context,
113
+ (item: any) => {
114
+ tracking.current.traceIdLoad = item?.traceId;
115
+ },
116
+ );
117
+ navigator?.maxApi?.startTraceScreenInteraction?.(
118
+ screenName,
119
+ context,
120
+ (item: any) => {
121
+ tracking.current.traceIdInteraction = item?.traceId;
122
+ },
123
+ );
124
+
125
+ tracking.current.timeoutTracking = setTimeout(() => {
126
+ onScreenLoad();
127
+ onScreenInteraction();
128
+ }, 5000);
129
+
130
+ return () => {
131
+ onScreenLoad();
132
+ onScreenInteraction();
133
+ clearTimeout(tracking.current.timeoutLoad);
134
+ clearTimeout(tracking.current.timeoutInteraction);
135
+ clearTimeout(tracking.current.timeoutTracking);
136
+ // eslint-disable-next-line react-hooks/exhaustive-deps
137
+ clearTimeout(tracking.current.timeoutLoading);
138
+ focusScreen?.();
139
+ onFocusApp?.remove?.();
140
+ };
141
+ // eslint-disable-next-line react-hooks/exhaustive-deps
142
+ }, []);
143
+
144
+ const onScreenNavigated = (pre: string, current: string) => {
145
+ if (!isBackgroundToForeground) {
146
+ const item: any = {
147
+ preScreenName: pre,
148
+ screenName: current,
83
149
  componentName: 'Screen',
84
150
  state: 'navigated',
85
151
  action: tracking.current?.mounted ? 'back' : 'push',
@@ -87,7 +153,7 @@ const StackScreen: React.FC<any> = props => {
87
153
 
88
154
  context?.autoTracking?.({
89
155
  ...context,
90
- ...data,
156
+ ...item,
91
157
  });
92
158
 
93
159
  tracking.current.mounted = true;
@@ -100,14 +166,13 @@ const StackScreen: React.FC<any> = props => {
100
166
  message: `${screenName} screen_navigated`,
101
167
  type: 'ERROR',
102
168
  });
103
- },
104
- [context, navigator?.maxApi],
105
- );
169
+ }
170
+ };
106
171
 
107
172
  /**
108
173
  * tracking for screen load
109
174
  */
110
- const onScreenLoad = useCallback(() => {
175
+ const onScreenLoad = () => {
111
176
  if (!tracking.current?.releaseLoad) {
112
177
  let timeLoad = tracking.current.timeLoad;
113
178
  if (timeLoad === 0) {
@@ -150,12 +215,12 @@ const StackScreen: React.FC<any> = props => {
150
215
  );
151
216
  }
152
217
  }
153
- }, [context, navigator?.maxApi, screenName]);
218
+ };
154
219
 
155
220
  /**
156
221
  * tracking for screen load
157
222
  */
158
- const onScreenInteraction = useCallback(() => {
223
+ const onScreenInteraction = () => {
159
224
  if (!tracking.current?.releaseInteraction) {
160
225
  let timeLoad = tracking.current.timeLoad;
161
226
  if (timeLoad === 0) {
@@ -191,130 +256,7 @@ const StackScreen: React.FC<any> = props => {
191
256
  type: 'ERROR',
192
257
  });
193
258
  }
194
- }, [context, navigator?.maxApi, screenName]);
195
-
196
- /**
197
- * tracking for screen
198
- */
199
- useEffect(() => {
200
- let focusScreen: any;
201
- let onFocusApp: any;
202
- if (['Invalid', 'screen'].includes(screenName)) {
203
- navigator?.maxApi?.showPopup?.('notice', {
204
- title: 'Invalid screen name',
205
- message:
206
- 'Your screen has not been rendered because Platform has not detected the screen name. Please migrate to support this feature.',
207
- });
208
- }
209
-
210
- if (!bottomTab) {
211
- focusScreen = props.navigation.addListener('focus', () => {
212
- navigator?.maxApi?.getDataObserver?.('current_screen', (data: any) => {
213
- onScreenNavigated(data?.screenName, screenName);
214
- navigator?.maxApi?.setObserver?.('current_screen', { screenName });
215
- });
216
- });
217
- onFocusApp = navigator?.maxApi?.listen?.('onFocusApp', () => {
218
- if (props.navigation.isFocused()) {
219
- navigator?.maxApi?.getDataObserver?.(
220
- 'current_screen',
221
- (data: any) => {
222
- onScreenNavigated(data?.screenName, screenName);
223
- navigator?.maxApi?.setObserver?.('current_screen', {
224
- screenName,
225
- });
226
- },
227
- );
228
- }
229
- });
230
- }
231
-
232
- navigator?.maxApi?.startTraceScreenLoad?.(
233
- screenName,
234
- context,
235
- (data: any) => {
236
- tracking.current.traceIdLoad = data?.traceId;
237
- },
238
- );
239
- navigator?.maxApi?.startTraceScreenInteraction?.(
240
- screenName,
241
- context,
242
- (data: any) => {
243
- tracking.current.traceIdInteraction = data?.traceId;
244
- },
245
- );
246
-
247
- tracking.current.timeoutTracking = setTimeout(() => {
248
- onScreenLoad();
249
- onScreenInteraction();
250
- }, 5000);
251
-
252
- return () => {
253
- onScreenLoad();
254
- onScreenInteraction();
255
- clearTimeout(tracking.current.timeoutLoad);
256
- clearTimeout(tracking.current.timeoutInteraction);
257
- clearTimeout(tracking.current.timeoutTracking);
258
- // eslint-disable-next-line react-hooks/exhaustive-deps
259
- clearTimeout(tracking.current.timeoutLoading);
260
- focusScreen?.();
261
- onFocusApp?.remove?.();
262
- };
263
- }, [
264
- bottomTab,
265
- context,
266
- navigator?.maxApi,
267
- onScreenInteraction,
268
- onScreenLoad,
269
- onScreenNavigated,
270
- props.navigation,
271
- screenName,
272
- ]);
273
-
274
- /**
275
- * tracking for screen
276
- */
277
- useEffect(() => {
278
- if (['Invalid', 'screen'].includes(screenName)) {
279
- navigator?.maxApi?.showPopup?.('notice', {
280
- title: 'Invalid screen name',
281
- message:
282
- 'Your screen has not been rendered because Platform has not detected the screen name. Please migrate to support this feature.',
283
- });
284
- }
285
-
286
- navigator?.maxApi?.startTraceScreenLoad?.(
287
- screenName,
288
- context,
289
- (item: any) => {
290
- tracking.current.traceIdLoad = item?.traceId;
291
- },
292
- );
293
- navigator?.maxApi?.startTraceScreenInteraction?.(
294
- screenName,
295
- context,
296
- (item: any) => {
297
- tracking.current.traceIdInteraction = item?.traceId;
298
- },
299
- );
300
-
301
- tracking.current.timeoutTracking = setTimeout(() => {
302
- onScreenLoad();
303
- onScreenInteraction();
304
- }, 5000);
305
-
306
- return () => {
307
- onScreenLoad();
308
- onScreenInteraction();
309
- };
310
- }, [
311
- context,
312
- navigator?.maxApi,
313
- onScreenInteraction,
314
- onScreenLoad,
315
- props.navigation,
316
- screenName,
317
- ]);
259
+ };
318
260
 
319
261
  /**
320
262
  * tracking for first interaction by user
@@ -343,16 +285,19 @@ const StackScreen: React.FC<any> = props => {
343
285
  }
344
286
  };
345
287
 
288
+ /**
289
+ * tracking for loading screen
290
+ */
346
291
  const onScreenLoading = () => {
347
- if (!tracking.current?.releaseLoading) {
348
- const timeLoad =
349
- tracking.current.timeEndLoading - tracking.current.timeStartLoading;
292
+ const start = tracking.current.timeStartLoading;
293
+ const end = tracking.current.timeEndLoading;
294
+ if (!tracking.current?.releaseLoading && start && end && end > start) {
350
295
  context?.autoTracking?.({
351
296
  ...context,
352
297
  screenName,
353
298
  componentName: 'Screen',
354
299
  state: 'loading',
355
- duration: timeLoad,
300
+ duration: end - start,
356
301
  loadingType: 'skeleton',
357
302
  });
358
303
  tracking.current.releaseLoading = true;
@@ -369,7 +314,7 @@ const StackScreen: React.FC<any> = props => {
369
314
  */
370
315
  if (item?.componentName === 'Widget') {
371
316
  const index = widgets.current.findIndex(
372
- (e: any) => e.componentId === item.componentId,
317
+ (element: any) => element.componentId === item.componentId,
373
318
  );
374
319
  const time = Date.now() - tracking.current.startTime;
375
320
  if (index === -1) {
@@ -404,8 +349,8 @@ const StackScreen: React.FC<any> = props => {
404
349
  /**
405
350
  * support for debug last element
406
351
  */
407
- if (data?.componentName) {
408
- tracking.current.lastElement = data;
352
+ if (item?.componentName) {
353
+ tracking.current.lastElement = item;
409
354
  }
410
355
 
411
356
  /**
@@ -414,7 +359,7 @@ const StackScreen: React.FC<any> = props => {
414
359
  if (item?.interaction) {
415
360
  onScreenLoad();
416
361
  onScreenInteraction();
417
- onFirstInteraction(data?.action);
362
+ onFirstInteraction(item?.action);
418
363
  }
419
364
  /**
420
365
  * timeout for handle tracking screen
@@ -439,7 +384,6 @@ const StackScreen: React.FC<any> = props => {
439
384
  /**
440
385
  * tracking for loading screen
441
386
  */
442
- clearTimeout(tracking.current.timeoutLoading);
443
387
  if (!loading) {
444
388
  tracking.current.timeEndLoading = Date.now();
445
389
  }
@@ -447,12 +391,13 @@ const StackScreen: React.FC<any> = props => {
447
391
  /**
448
392
  * timeout for handle tracking screen
449
393
  */
394
+ clearTimeout(tracking.current.timeoutLoading);
450
395
  tracking.current.timeoutLoading = setTimeout(() => {
451
396
  onScreenLoading();
452
397
  }, 2000);
453
398
  },
454
- onSetParams: (data: ScreenTrackingParams) => {
455
- tracking.current.params = data;
399
+ onSetParams: (item: ScreenTrackingParams) => {
400
+ tracking.current.params = item;
456
401
  },
457
402
  }}
458
403
  >
@@ -2,7 +2,7 @@ import React, { useContext, useRef, useState } from 'react';
2
2
  import { SafeAreaProvider } from 'react-native-safe-area-context';
3
3
  import Navigator from './Navigator';
4
4
  import { WidgetContainerProps } from './types';
5
- import { ApplicationContext, MiniAppContext } from './index';
5
+ import { ApplicationContext, MiniAppContext } from '../Context';
6
6
  import Localize from './Localize';
7
7
  import { defaultTheme } from '../Consts';
8
8
  import {
@@ -1,48 +1,29 @@
1
- import { Platform } from 'react-native';
2
- import { createContext } from 'react';
3
1
  import { NavigationContainer } from './NavigationContainer';
4
2
  import { WidgetContainer } from './WidgetContainer';
5
3
  import Localize from './Localize';
6
4
  import BottomTab from './BottomTab';
7
- import { defaultContext } from '../Consts';
8
- import {
9
- HeaderAnimated,
10
- HeaderBackground,
11
- HeaderTitle,
12
- NavigationButton,
13
- } from './Components';
14
- import { setAutomationID, useComponentId, exportHeaderTitle } from './utils';
15
- import Navigation from './Navigation';
16
- import Navigator from './Navigator';
17
5
 
18
- const Context = createContext({});
19
- const ApplicationContext = createContext(defaultContext);
6
+ export * from './Components/BackgroundImageView';
7
+ export * from './Components/HeaderAnimated';
8
+ export * from './Components/HeaderBackground';
9
+ export * from './Components/HeaderExtendHeader';
10
+ export * from './Components/HeaderLeft';
11
+ export * from './Components/HeaderRight';
12
+ export * from './Components/HeaderTitle';
13
+ export * from './Components/NavigationButton';
14
+ export * from './Components/SearchHeader';
20
15
 
21
- const MiniAppContext = (Platform as any).MiniAppContext ?? Context;
22
- const ScreenContext = (Platform as any).ScreenContext ?? Context;
23
- const ComponentContext = (Platform as any).ComponentContext ?? Context;
24
- const SkeletonContext = createContext({ loading: false });
25
- const TrackingScopeContext = createContext<{ scopeName?: string }>({
26
- scopeName: undefined,
27
- });
16
+ import { exportHeaderTitle, setAutomationID, useComponentId } from './utils';
17
+ import Navigation from './Navigation';
18
+ import Navigator from './Navigator';
28
19
 
29
20
  export {
30
- ApplicationContext,
31
- MiniAppContext,
32
- ScreenContext,
33
- ComponentContext,
34
- SkeletonContext,
35
21
  NavigationContainer,
36
22
  WidgetContainer,
37
23
  Localize,
38
- HeaderTitle,
39
- HeaderBackground,
40
- NavigationButton,
41
24
  BottomTab,
42
- HeaderAnimated,
43
25
  setAutomationID,
44
26
  useComponentId,
45
- TrackingScopeContext,
46
27
  Navigation,
47
28
  Navigator,
48
29
  exportHeaderTitle,
@@ -1,17 +1,54 @@
1
- import {EventArg} from '@react-navigation/core';
2
- import {StackNavigationOptions} from '@react-navigation/stack';
3
- import React, {ReactNode} from 'react';
1
+ import { EventArg } from '@react-navigation/core';
2
+ import { StackNavigationOptions } from '@react-navigation/stack';
3
+ import React, { ReactNode } from 'react';
4
4
  import {
5
5
  Animated,
6
6
  TouchableOpacityProps,
7
7
  ViewProps,
8
8
  ViewStyle,
9
9
  } from 'react-native';
10
- import {PopupNotifyProps} from '../Popup/types';
11
- import Localize from './Localize';
12
- import Navigation from './Navigation';
13
- import Navigator from './Navigator';
14
- import {InputRef, InputSearchProps} from '../Input';
10
+ import { PopupNotifyProps } from '../Popup/types';
11
+ import { InputRef, InputSearchProps } from '../Input';
12
+
13
+ export type NavigationProps = {
14
+ context: any;
15
+ setOptions: (params: NavigationOptions) => void;
16
+ };
17
+
18
+ export type NavigatorProps = {
19
+ ref?: any;
20
+ isReady?: any;
21
+ isWidget?: any;
22
+ maxApi?: any;
23
+ dismissData?: any;
24
+ push: (params: ScreenParams) => void;
25
+ replace: (params: ScreenParams) => void;
26
+ pop: (count?: number) => void;
27
+ present: (params: ScreenParams) => void;
28
+ showModal: (params: ModalParams, onError?: (error: string) => void) => void;
29
+ showBottomSheet: (
30
+ params: BottomSheetParams,
31
+ onError?: (error: string) => void,
32
+ ) => void;
33
+ popToTop: () => void;
34
+ navigate: (name: string) => void;
35
+ reset: (params: ScreenParams) => void;
36
+ setDismissData: (data: any) => void;
37
+ setCurrentContext: (context: {
38
+ code?: string;
39
+ name?: { vi: string; en: string };
40
+ description?: { vi: string; en: string };
41
+ icon?: string;
42
+ }) => void;
43
+ };
44
+
45
+ export type LocalizeProps = {
46
+ getCurrentLanguage: 'en' | 'vi';
47
+ getAssets: LocalizationObject;
48
+ translate: (key: string) => string;
49
+ translateData: (data: { vi: string; en: string }) => string;
50
+ addTranslations: (translations: LocalizationObject) => void;
51
+ };
15
52
 
16
53
  export type Theme = {
17
54
  dark: boolean;
@@ -72,9 +109,9 @@ export type Theme = {
72
109
  export type Context = {
73
110
  [key: string]: any;
74
111
  theme: Theme;
75
- navigator?: Navigator;
112
+ navigator?: NavigatorProps;
76
113
  showGrid?: boolean;
77
- translate?: (data: string | {vi: string; en: string}) => string;
114
+ translate?: (data: string | { vi: string; en: string }) => string;
78
115
  };
79
116
 
80
117
  export type LocalizationObject = {
@@ -87,39 +124,47 @@ export type LocalizationObject = {
87
124
  };
88
125
 
89
126
  export type ToolGroup = {
90
- title: {vi: string; en: string};
127
+ title: { vi: string; en: string };
91
128
  items: Tool[];
92
129
  };
93
130
 
94
131
  export type Tool = {
95
132
  icon: string;
96
- name: {vi: string; en: string};
133
+ name: { vi: string; en: string };
97
134
  key: string;
98
135
  showBadge?: boolean;
99
136
  showRightIcon?: boolean;
100
137
  onPress: () => void;
101
138
  };
102
139
 
140
+ export type FeaturesFlag = {
141
+ enableForceFoundationList?: boolean;
142
+ enableBottomTabAnimation?: boolean;
143
+ enableHapticBottomTab?: boolean;
144
+ enableHapticDialog?: boolean;
145
+ };
146
+
103
147
  export type NavigationContainerProps = {
104
148
  screen: React.ComponentType<NavigationScreenProps>;
105
149
  options?: NavigationOptions;
106
150
  theme?: Theme;
107
151
  maxApi: any;
108
152
  initialParams?: any;
109
- localize: Localize;
153
+ localize: LocalizeProps;
154
+ features: FeaturesFlag;
110
155
  };
111
156
 
112
157
  export type WidgetContainerProps = {
113
158
  widget: React.ComponentType<any>;
114
159
  theme?: Theme;
115
160
  maxApi: any;
116
- localize: Localize;
161
+ localize: LocalizeProps;
117
162
  };
118
163
 
119
164
  export type NavigationScreenProps = {
120
165
  [key: string]: any;
121
166
  options?: NavigationOptions;
122
- navigation: Navigation;
167
+ navigation: NavigationProps;
123
168
  };
124
169
 
125
170
  export type ScreenParams = {
@@ -157,9 +202,12 @@ export type BottomSheetParams = {
157
202
  useBottomInset?: boolean;
158
203
  useKeyboardAvoidingView?: boolean;
159
204
  keyboardVerticalOffset?: number;
160
- useScrollOverflow?: boolean;
161
205
  useDivider?: boolean;
162
206
  footerComponent?: React.ReactNode;
207
+ leftOptions?: {
208
+ iconLeft?: string;
209
+ onPressIconLeft?: () => void;
210
+ };
163
211
  };
164
212
 
165
213
  export interface NavigationButtonProps extends TouchableOpacityProps {
@@ -263,14 +311,13 @@ export type BottomTabProps = {
263
311
  nested?: boolean;
264
312
  tabs: BottomTabItemProps[];
265
313
  initialRouteName?: string;
266
- navigation: Navigation;
314
+ navigation: NavigationProps;
267
315
  listeners?: {
268
316
  tabPress?: (e: EventArg<'tabPress', true, undefined>) => void;
269
317
  focus?: (e: EventArg<'focus', false, unknown>) => void;
270
318
  blur?: (e: EventArg<'blur', false, unknown>) => void;
271
319
  };
272
320
  floatingButton?: FloatingButtonProps;
273
- useAnimation?: boolean;
274
321
  };
275
322
 
276
323
  export type FloatingButtonProps = {
@@ -292,4 +339,5 @@ export interface SearchHeaderProps extends InputSearchProps {
292
339
  headerRightWidth?: 0 | 74 | 110 | number;
293
340
  leftPosition?: 12 | 48 | number;
294
341
  renderButtons?: () => ReactNode;
342
+ hiddenBack?: boolean;
295
343
  }
@@ -1,19 +1,20 @@
1
- import React, { useContext, useMemo } from 'react';
1
+ import React, { useContext, useEffect, useMemo, useRef } from 'react';
2
2
  import {
3
3
  StackNavigationOptions,
4
4
  TransitionPresets,
5
5
  } from '@react-navigation/stack';
6
- import {
7
- HeaderBackground,
8
- HeaderLeft,
9
- HeaderRight,
10
- HeaderTitle,
11
- TitleCustom,
12
- } from './Components';
13
- import { HeaderTitleProps, NavigationOptions } from './types';
6
+ import type { HeaderTitleProps, NavigationOptions } from './types';
14
7
  import { Colors, Spacing } from '../Consts';
15
- import { Animated, Platform } from 'react-native';
16
- import { MiniAppContext, ScreenContext, TrackingScopeContext } from './index';
8
+ import { Animated, AppState, Platform } from 'react-native';
9
+ import {
10
+ MiniAppContext,
11
+ ScreenContext,
12
+ TrackingScopeContext,
13
+ } from '../Context';
14
+ import { HeaderTitle, TitleCustom } from './Components/HeaderTitle';
15
+ import { HeaderBackground } from './Components/HeaderBackground';
16
+ import { HeaderLeft } from './Components/HeaderLeft';
17
+ import { HeaderRight } from './Components/HeaderRight';
17
18
 
18
19
  /**
19
20
  * default options for stack screen
@@ -197,12 +198,34 @@ const useComponentId = (componentName: string, accessibilityLabel?: string) => {
197
198
  return { componentId };
198
199
  };
199
200
 
200
- export const getImageName = (source: any): string => {
201
- const parts = source?.uri?.split?.('/');
202
- if (parts?.length > 0) {
203
- return parts?.[parts.length - 1];
204
- }
205
- return '';
201
+ const useAppState = () => {
202
+ const isBackgroundToForeground = useRef(false);
203
+ const appState = useRef(AppState.currentState);
204
+
205
+ useEffect(() => {
206
+ const subscription = AppState.addEventListener('change', nextAppState => {
207
+ isBackgroundToForeground.current = !!(
208
+ appState.current.match(/inactive|background/) &&
209
+ nextAppState === 'active'
210
+ );
211
+ appState.current = nextAppState;
212
+
213
+ if (isBackgroundToForeground.current) {
214
+ setTimeout(() => {
215
+ isBackgroundToForeground.current = false;
216
+ }, 100);
217
+ }
218
+ });
219
+
220
+ return () => {
221
+ subscription.remove();
222
+ };
223
+ }, []);
224
+
225
+ return {
226
+ isBackgroundToForeground: isBackgroundToForeground.current,
227
+ appState: appState.current,
228
+ };
206
229
  };
207
230
 
208
231
  export {
@@ -212,4 +235,5 @@ export {
212
235
  exportHeaderTitle,
213
236
  setAutomationID,
214
237
  useComponentId,
238
+ useAppState,
215
239
  };
@@ -98,7 +98,9 @@
98
98
  "tutorial": "Hướng dẫn sử dụng",
99
99
  "question": "Câu hỏi thường gặp",
100
100
  "support": "Trung tâm hỗ trợ",
101
- "skip": "Bỏ qua"
101
+ "skip": "Bỏ qua",
102
+ "enterPhoneNumber": "Vui lòng nhập số điện thoại",
103
+ "invalidPhoneNumber": "Số điện thoại không đúng"
102
104
  },
103
105
  "en": {
104
106
  "seeMore": "See more",
@@ -199,6 +201,8 @@
199
201
  "question": "FAQ",
200
202
  "support": "Support center",
201
203
  "errorCode": "Error code: ",
202
- "skip": "Skip"
204
+ "skip": "Skip",
205
+ "enterPhoneNumber": "Please enter your phone number",
206
+ "invalidPhoneNumber": "Invalid phone number"
203
207
  }
204
208
  }