@momo-kits/foundation 0.81.1-beta.6 → 0.81.1-optimize.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 (77) hide show
  1. package/Application/BottomSheet.tsx +225 -0
  2. package/Application/BottomTab/BottomTabBar.tsx +291 -0
  3. package/Application/BottomTab/index.tsx +138 -0
  4. package/Application/Components.tsx +274 -211
  5. package/Application/ModalScreen.tsx +10 -226
  6. package/Application/Navigation.ts +17 -6
  7. package/Application/NavigationContainer.tsx +66 -65
  8. package/Application/Navigator.ts +106 -53
  9. package/Application/StackScreen.tsx +123 -28
  10. package/Application/index.ts +15 -9
  11. package/Application/types.ts +55 -31
  12. package/Application/utils.tsx +36 -6
  13. package/Assets/icon.json +83 -5
  14. package/Assets/icon_bank.json +506 -0
  15. package/Assets/language.json +3 -1
  16. package/Badge/Badge.tsx +56 -0
  17. package/Badge/BadgeDot.tsx +11 -0
  18. package/Badge/BadgeRibbon.tsx +125 -0
  19. package/Badge/Shape.tsx +29 -0
  20. package/Badge/index.tsx +7 -0
  21. package/Badge/styles.ts +58 -0
  22. package/Badge/types.ts +63 -0
  23. package/Button/index.tsx +60 -24
  24. package/Button/styles.ts +19 -0
  25. package/CheckBox/index.tsx +37 -27
  26. package/CheckBox/types.ts +5 -3
  27. package/Consts/colors+spacing+radius.ts +17 -3
  28. package/Icon/index.tsx +14 -9
  29. package/Icon/types.ts +4 -3
  30. package/IconButton/index.tsx +24 -15
  31. package/Image/index.tsx +61 -55
  32. package/Image/styles.ts +1 -9
  33. package/Image/types.ts +5 -1
  34. package/Input/Input.tsx +102 -25
  35. package/Input/InputDropDown.tsx +32 -23
  36. package/Input/InputMoney.tsx +67 -18
  37. package/Input/InputOTP.tsx +194 -148
  38. package/Input/InputSearch.tsx +72 -36
  39. package/Input/InputTextArea.tsx +33 -18
  40. package/Input/common.tsx +25 -16
  41. package/Input/index.tsx +62 -16
  42. package/Input/styles.ts +5 -8
  43. package/Layout/Card.tsx +20 -11
  44. package/Layout/FloatingButton.tsx +168 -0
  45. package/Layout/GridSystem.tsx +1 -2
  46. package/Layout/Item.tsx +0 -1
  47. package/Layout/ItemList.tsx +39 -40
  48. package/Layout/ItemSectionList.tsx +39 -0
  49. package/Layout/Screen.tsx +151 -65
  50. package/Layout/Section.tsx +17 -19
  51. package/Layout/index.ts +2 -1
  52. package/Layout/styles.ts +20 -15
  53. package/Layout/types.ts +2 -5
  54. package/Layout/utils.ts +2 -2
  55. package/Pagination/PaginationNumber.tsx +1 -1
  56. package/Pagination/PaginationScroll.tsx +0 -1
  57. package/Popup/PopupNotify.tsx +105 -37
  58. package/Popup/PopupPromotion.tsx +44 -9
  59. package/Popup/types.ts +12 -9
  60. package/Radio/index.tsx +35 -21
  61. package/Radio/types.ts +5 -3
  62. package/Skeleton/index.tsx +1 -1
  63. package/Switch/index.tsx +32 -19
  64. package/Switch/types.ts +5 -3
  65. package/Tag/index.tsx +2 -4
  66. package/Text/index.tsx +26 -6
  67. package/Text/styles.ts +38 -0
  68. package/Text/types.ts +25 -13
  69. package/Title/index.tsx +172 -63
  70. package/Title/styles.ts +48 -15
  71. package/Title/types.ts +16 -47
  72. package/code-scanner.js +131 -39
  73. package/index.ts +9 -0
  74. package/migrate_typo.js +56 -0
  75. package/package.json +8 -8
  76. package/verify.js +24 -6
  77. package/Application/BottomTab.tsx +0 -65
@@ -8,90 +8,143 @@ import {
8
8
 
9
9
  class Navigator {
10
10
  ref?: any;
11
+ isReady?: any;
11
12
  toolkitConfig?: HeaderToolkitProps;
12
13
  maxApi?: any;
14
+ dismissData?: any;
15
+ toolkitCallback?: (item: any) => void;
13
16
 
14
- constructor(navigation: any) {
17
+ constructor(navigation: any, isReady: any) {
15
18
  this.ref = navigation;
19
+ this.isReady = isReady;
16
20
  }
17
21
 
22
+ /**
23
+ * push new stack screen
24
+ * @param params
25
+ */
18
26
  push = (params: ScreenParams) => {
19
- this.ref.current.dispatch(StackActions.push('Stack', params));
27
+ if (this.isReady.current) {
28
+ this.ref.current.dispatch(StackActions.push('Stack', params));
29
+ }
20
30
  };
21
31
 
32
+ /**
33
+ * replace current screen with new screen
34
+ * @param params
35
+ */
22
36
  replace = (params: ScreenParams) => {
23
- this.ref.current.dispatch(StackActions.replace('Stack', params));
37
+ if (this.isReady.current) {
38
+ this.ref.current.dispatch(StackActions.replace('Stack', params));
39
+ }
24
40
  };
25
-
41
+ /**
42
+ * pop to dismiss a screen
43
+ * @param count
44
+ */
26
45
  pop = (count?: number) => {
27
- this.ref.current.dispatch(StackActions.pop(count ?? 1));
46
+ if (this.isReady.current) {
47
+ this.ref.current.dispatch(StackActions.pop(count ?? 1));
48
+ }
28
49
  };
29
50
 
51
+ /**
52
+ * present a new screen, show from bottom iOS
53
+ * @param params
54
+ */
30
55
  present = (params: ScreenParams) => {
31
- this.ref.current.dispatch(StackActions.push('Dialog', params));
56
+ if (this.isReady.current) {
57
+ this.ref.current.dispatch(StackActions.push('Dialog', params));
58
+ }
32
59
  };
33
60
 
61
+ /**
62
+ * show a modal popup
63
+ * @param params
64
+ */
34
65
  showModal = (params: ModalParams) => {
35
- this.ref.current.dispatch(StackActions.push('Modal', params));
66
+ if (this.isReady.current) {
67
+ this.ref.current.dispatch(StackActions.push('Modal', params));
68
+ }
36
69
  };
37
70
 
71
+ /**
72
+ * show a bottom sheet
73
+ * @param params
74
+ */
38
75
  showBottomSheet = (params: BottomSheetParams) => {
39
- this.ref.current.dispatch(
40
- StackActions.push('Modal', {
41
- ...params,
42
- isBottomSheet: true,
43
- }),
44
- );
76
+ if (this.isReady.current) {
77
+ this.ref.current.dispatch(
78
+ StackActions.push('Modal', {
79
+ ...params,
80
+ isBottomSheet: true,
81
+ }),
82
+ );
83
+ }
45
84
  };
46
85
 
86
+ /**
87
+ * pop all screen route
88
+ */
47
89
  popToTop = () => {
48
- this.ref.current.dispatch(StackActions.popToTop());
90
+ if (this.isReady.current) {
91
+ this.ref.current.dispatch(StackActions.popToTop());
92
+ }
49
93
  };
50
94
 
51
- reset = (params: ScreenParams) => {
52
- this.ref.current.dispatch(
53
- CommonActions.reset({
54
- index: 0,
55
- routes: [
56
- {
57
- name: 'Stack',
58
- key: `Stack_${new Date().getTime()}`,
59
- params,
60
- },
61
- ],
62
- }),
63
- );
95
+ /**
96
+ * navigate
97
+ * @param name
98
+ * @param params
99
+ */
100
+ navigate = (name: string, params: any) => {
101
+ if (this.isReady.current) {
102
+ this.ref.current.dispatch(
103
+ CommonActions.navigate({
104
+ name,
105
+ params,
106
+ }),
107
+ );
108
+ }
64
109
  };
65
110
 
66
- requestApi = (func: any, args: any = [], callback: any) => {
67
- if (this.maxApi) {
68
- this.maxApi[func]?.(...args, callback);
69
- } else {
70
- const instance: any = global;
71
- instance?.miniAppApi?.dispatch?.(func, ...args, callback);
111
+ /**
112
+ * reset a navigation flow with new screen
113
+ * @param params
114
+ */
115
+ reset = (params: ScreenParams) => {
116
+ if (this.isReady.current) {
117
+ this.ref.current.dispatch(
118
+ CommonActions.reset({
119
+ index: 0,
120
+ routes: [
121
+ {
122
+ name: 'Stack',
123
+ key: `Stack_${new Date().getTime()}`,
124
+ params,
125
+ },
126
+ ],
127
+ }),
128
+ );
72
129
  }
73
130
  };
74
131
 
75
- getToolkit = async (): Promise<HeaderToolkitProps | undefined> => {
76
- return new Promise(resolve => {
77
- if (this.toolkitConfig) {
78
- resolve(this.toolkitConfig);
79
- return;
80
- }
81
- this.requestApi('getToolkit', [undefined], (result: boolean) => {
82
- if (result) {
83
- this.requestApi('getToolkitConfig', [undefined], (config: any) => {
84
- this.toolkitConfig = {
85
- ...config?.utilityToolConfig,
86
- appCode: config?.appCode,
87
- };
88
- resolve(this.toolkitConfig);
89
- });
90
- } else {
91
- resolve(undefined);
92
- }
93
- });
94
- });
132
+ /**
133
+ * dismiss a feature data
134
+ * @param data
135
+ */
136
+ setDismissData = (data: any) => {
137
+ this.dismissData = data;
138
+ };
139
+
140
+ /**
141
+ * set callback function for toolkit
142
+ * @param callback
143
+ */
144
+ setToolkitCallback = (
145
+ callback: (item: {key: string; action: string}) => void,
146
+ ) => {
147
+ this.toolkitCallback = callback;
95
148
  };
96
149
  }
97
150
 
@@ -1,52 +1,147 @@
1
- import React, {useContext, useEffect, useLayoutEffect} from 'react';
1
+ import React, {useContext, useEffect, useLayoutEffect, useRef} from 'react';
2
2
  import {ScreenParams} from './types';
3
3
  import Navigation from './Navigation';
4
- import {ApplicationContext} from './index';
4
+ import {ApplicationContext, MiniAppContext, ScreenContext} from './index';
5
5
  import {GridSystem} from '../Layout';
6
-
7
- const TRIGGER_ID = '111378000000000000';
6
+ import {useHeaderHeight} from '@react-navigation/stack';
7
+ import {Alert, InteractionManager} from 'react-native';
8
8
 
9
9
  const StackScreen: React.FC<ScreenParams> = props => {
10
- const {screen: Component, options}: ScreenParams = props.route.params;
11
- const {theme, showGrid, navigator, appInfo} = useContext(ApplicationContext);
10
+ const {theme, showGrid, navigator} = useContext(ApplicationContext);
11
+ const startTime = useRef(Date.now());
12
+ const endTime = useRef(Date.now());
13
+ const timeLoad = useRef(0);
14
+ const timeInteraction = useRef(0);
15
+ const timeoutLoad = useRef<any>();
16
+ const tracked = useRef<any>({
17
+ releaseLoad: undefined,
18
+ releaseInteraction: undefined,
19
+ timeoutLoad: undefined,
20
+ timeoutInteraction: undefined,
21
+ });
22
+ const interaction = useRef<any>();
23
+ const context = useContext<any>(MiniAppContext);
24
+
25
+ const {screen: Component, options, initialParams} = props.route.params;
12
26
  const navigation = new Navigation(props.navigation, theme);
27
+ const heightHeader = useHeaderHeight();
13
28
 
14
- const params = {
29
+ const data = {
30
+ ...initialParams,
15
31
  ...props.route.params,
16
32
  navigation,
17
33
  };
18
34
 
19
- delete params.screen;
35
+ delete data.screen;
36
+ delete data.initialParams;
20
37
 
21
- const navigationRoutes = props.navigation.getState()?.routes || [];
22
- const routesLength = navigationRoutes.length;
23
- let pre_screen_name = navigationRoutes?.[0]?.params?.screen?.name;
24
- if (routesLength > 1) {
25
- pre_screen_name = navigationRoutes[routesLength - 2]?.params?.screen?.name;
26
- }
27
-
28
- useEffect(() => {
29
- if (appInfo) {
30
- navigator?.maxApi?.trackEvent('service_frame_displayed', {
31
- ...appInfo,
32
- screen_name: Component.name,
33
- pre_screen_name,
34
- trigger_id: TRIGGER_ID,
35
- });
36
- }
37
- }, []);
38
+ const screenName = Component?.name || Component?.type?.name || 'Invalid';
38
39
 
40
+ /**
41
+ * set options for screen
42
+ */
39
43
  useLayoutEffect(() => {
40
44
  if (options) {
41
45
  navigation.setOptions(options);
42
46
  }
43
47
  }, [options]);
44
48
 
49
+ /**
50
+ * tracking for screen
51
+ */
52
+ useEffect(() => {
53
+ if (__DEV__ && (!screenName || screenName == 'Invalid')) {
54
+ Alert.alert('Design system', `Unvalidated screen name "${screenName}" !`);
55
+ }
56
+
57
+ navigator?.maxApi?.of?.({screenName});
58
+
59
+ tracked.current.timeoutLoad = setTimeout(() => {
60
+ onScreenLoad();
61
+ }, 5000);
62
+ tracked.current.timeoutInteraction = setTimeout(() => {
63
+ onScreenInteraction();
64
+ }, 5000);
65
+
66
+ return () => {
67
+ onScreenLoad();
68
+ onScreenInteraction();
69
+ };
70
+ }, []);
71
+
72
+ /**
73
+ * tracking for screen load
74
+ */
75
+ const onScreenLoad = () => {
76
+ clearTimeout(tracked.current.timeoutLoad);
77
+ if (!tracked.current?.releaseLoad) {
78
+ context.autoTracking?.({
79
+ appId: context.appId,
80
+ code: context.code,
81
+ buildNumber: context.buildNumber,
82
+ screenName,
83
+ componentName: 'Screen',
84
+ state: 'load',
85
+ duration: timeLoad.current,
86
+ });
87
+ navigator?.maxApi?.showToastDebug?.({
88
+ appId: `auto - ${context.appId}`,
89
+ message: `${screenName} screen_load_time ${timeLoad.current}`,
90
+ });
91
+ tracked.current.releaseLoad = true;
92
+ }
93
+ };
94
+
95
+ /**
96
+ * tracking for screen load
97
+ */
98
+ const onScreenInteraction = () => {
99
+ clearTimeout(tracked.current.timeoutInteraction);
100
+ if (!tracked.current?.releaseInteraction) {
101
+ context.autoTracking?.({
102
+ appId: context.appId,
103
+ code: context.code,
104
+ buildNumber: context.buildNumber,
105
+ screenName,
106
+ componentName: 'Screen',
107
+ state: 'interaction',
108
+ duration: timeInteraction.current - timeLoad.current,
109
+ });
110
+
111
+ navigator?.maxApi?.showToastDebug?.({
112
+ appId: `auto - ${context.appId}`,
113
+ message: `${screenName} screen_interaction_time ${timeInteraction.current}`,
114
+ });
115
+ tracked.current.releaseInteraction = true;
116
+ }
117
+ };
118
+
45
119
  return (
46
- <>
47
- <Component {...params} />
120
+ <ScreenContext.Provider
121
+ value={{
122
+ screenName,
123
+ onElementLoad: () => {
124
+ endTime.current = Date.now();
125
+ interaction.current?.cancel?.();
126
+ interaction.current = InteractionManager.runAfterInteractions(() => {
127
+ timeInteraction.current = Date.now() - startTime.current;
128
+ });
129
+ clearTimeout(timeoutLoad.current);
130
+ timeoutLoad.current = setTimeout(() => {
131
+ if (timeLoad.current === 0) {
132
+ timeLoad.current = endTime.current - startTime.current;
133
+ }
134
+ }, 2000);
135
+ },
136
+ }}>
137
+ <Component
138
+ heightHeader={heightHeader}
139
+ {...data}
140
+ onScreenLoad={onScreenLoad}
141
+ onScreenInteraction={onScreenInteraction}
142
+ />
48
143
  {showGrid && <GridSystem />}
49
- </>
144
+ </ScreenContext.Provider>
50
145
  );
51
146
  };
52
147
 
@@ -1,31 +1,37 @@
1
+ import {Platform} from 'react-native';
1
2
  import {NavigationContainer} from './NavigationContainer';
2
3
  import Screen from '../Layout/Screen';
3
4
  import {
4
- NavigationButton,
5
- HeaderTitle,
6
- HeaderLeft,
5
+ HeaderAnimated,
7
6
  HeaderBackground,
8
- HeaderRightAction,
9
- HeaderToolkitAction,
10
7
  HeaderCustom,
11
- HeaderAnimated,
8
+ HeaderRightAction,
9
+ HeaderTitle,
10
+ NavigationButton,
12
11
  } from './Components';
13
12
  import BottomTab from './BottomTab';
14
13
  import {createContext} from 'react';
15
14
  import {defaultContext} from '../Consts';
16
15
 
16
+ const Context = createContext({});
17
17
  const ApplicationContext = createContext(defaultContext);
18
+
19
+ const MiniAppContext = (Platform as any).MiniAppContext ?? createContext({});
20
+ const ScreenContext = (Platform as any).ScreenContext ?? createContext({});
21
+ const ComponentContext = (Platform as any).ComponentContext ?? Context;
22
+
18
23
  export {
19
- NavigationContainer,
20
24
  ApplicationContext,
25
+ MiniAppContext,
26
+ ScreenContext,
27
+ ComponentContext,
28
+ NavigationContainer,
21
29
  Screen,
22
30
  BottomTab,
23
31
  NavigationButton,
24
32
  HeaderTitle,
25
- HeaderLeft,
26
33
  HeaderBackground,
27
34
  HeaderRightAction,
28
- HeaderToolkitAction,
29
35
  HeaderCustom,
30
36
  HeaderAnimated,
31
37
  };
@@ -1,9 +1,9 @@
1
- import {Animated} from 'react-native';
2
1
  import {StackNavigationOptions} from '@react-navigation/stack';
3
2
  import React from 'react';
4
- import Navigator from './Navigator';
3
+ import {Animated, ViewProps} from 'react-native';
5
4
  import {PopupNotifyProps} from '../Popup/types';
6
5
  import Navigation from './Navigation';
6
+ import Navigator from './Navigator';
7
7
 
8
8
  type Screen = React.ComponentType<NavigationScreenProps>;
9
9
 
@@ -63,12 +63,11 @@ export type Theme = {
63
63
  };
64
64
 
65
65
  export type Context = {
66
+ [key: string]: any;
66
67
  theme: Theme;
67
68
  navigator?: Navigator;
68
69
  showGrid?: boolean;
69
- language?: 'vi' | 'en';
70
70
  translate?: (key: string) => string;
71
- appInfo: MiniAppInfo;
72
71
  };
73
72
 
74
73
  export type LocalizationObject = {
@@ -80,20 +79,13 @@ export type LocalizationObject = {
80
79
  };
81
80
  };
82
81
 
83
- export type MiniAppInfo = {
84
- feature_code: string;
85
- app_id: string;
86
- build_number: number;
87
- flow_partner_id?: string;
88
- };
89
-
90
82
  export type NavigationContainerProps = {
91
83
  screen: Screen;
92
84
  options?: NavigationOptions;
93
85
  theme: Theme;
94
86
  maxApi: any;
95
87
  localization?: LocalizationObject;
96
- appInfo: MiniAppInfo;
88
+ initialParams?: any;
97
89
  };
98
90
 
99
91
  export type NavigationScreenProps = {
@@ -106,50 +98,74 @@ export type ScreenParams = {
106
98
  [key: string]: any;
107
99
  screen: Screen;
108
100
  options?: NavigationOptions;
109
- tracking?: any;
110
101
  };
111
102
 
112
- export interface ModalParams extends ScreenParams {
103
+ export type ModalParams = {
113
104
  [key: string]: any;
114
- modalName?: string;
105
+ screen: Screen;
115
106
  onDismiss?: () => void;
116
107
  barrierDismissible?: boolean;
117
- }
108
+ };
118
109
 
119
- export interface BottomSheetParams extends ScreenParams {
110
+ export type BottomSheetParams = {
120
111
  [key: string]: any;
121
- onDismiss?: () => void;
122
- snapPoint?: '30%' | '50%' | '70%' | '90%';
123
- }
112
+ screen: Screen;
113
+ options: {
114
+ title: string;
115
+ surface?: boolean;
116
+ };
117
+ snapPoint?: '30%' | '50%' | '70%' | '90%' | 'content';
118
+ surface?: boolean;
119
+ onDismiss?: (type?: string) => void;
120
+ barrierDismissible?: boolean;
121
+ draggable?: boolean;
122
+ dragOnContent?: boolean;
123
+ };
124
124
 
125
125
  export type NavigationButtonProps = {
126
126
  icon: string;
127
127
  tintColor?: string;
128
- backgroundColor?: string;
129
128
  useBorder?: boolean;
130
129
  onPress: () => void;
130
+ badgeType?: 'dot' | 'number';
131
+ badgeValue?: number;
131
132
  accessibilityLabel?: string;
132
133
  };
133
134
 
135
+ export type PinnedToolType = {
136
+ key: string;
137
+ badgeValue?: number;
138
+ badgeType?: 'number' | 'dot';
139
+ };
140
+
141
+ export type RuntimeToolType = {
142
+ title: {vi: string; en: string};
143
+ icon: string;
144
+ key: string;
145
+ };
146
+
134
147
  export interface NavigationOptions extends StackNavigationOptions {
135
148
  preventBack?: PopupNotifyProps;
136
149
  onPressLeftHeader?: () => void;
137
150
  surface?: boolean;
138
151
  hiddenBack?: boolean;
139
152
  customTitle?: TitleCustomProps;
153
+ toolkitParams?: {
154
+ pinnedTool?: PinnedToolType;
155
+ runtimeTools?: RuntimeToolType[];
156
+ preventClose?: PopupNotifyProps;
157
+ };
140
158
  }
141
159
 
142
160
  export interface HeaderBackProps extends NavigationButtonProps {
143
161
  preventBack?: PopupNotifyProps;
144
162
  onPressLeftHeader?: () => void;
145
- accessibilityLabel?: string;
146
163
  }
147
164
 
148
165
  export type HeaderBackgroundProps = {
149
166
  image?: string | null;
150
- backgroundColor?: string | null;
151
167
  animatedValue?: Animated.Value;
152
- useBorder?: boolean;
168
+ useSurface?: boolean;
153
169
  };
154
170
 
155
171
  export type TitleCustomProps = {
@@ -165,37 +181,45 @@ export type TitleCustomProps = {
165
181
  export type HeaderToolkitProps = {
166
182
  [key: string]: any;
167
183
  appCode: string;
168
- hidden: boolean;
169
- type: string;
170
- onAction?: (action: string) => void;
184
+ configs: any[];
171
185
  };
172
186
 
173
- export type HeaderAnimatedProps = {
187
+ export interface HeaderAnimatedProps extends ViewProps {
174
188
  animatedValue: Animated.Value;
175
189
  image: string;
176
- onPress?: () => void;
177
- };
190
+ }
178
191
 
179
192
  export type BottomTabItemProps = {
180
193
  name: string;
181
194
  label: string;
182
195
  icon: string;
183
196
  showDot?: boolean;
184
- badgeLabel?: string;
197
+ badgeLabel?: string | number;
185
198
  screen: Screen;
186
199
  options: NavigationOptions;
187
200
  };
188
201
 
189
202
  export type BottomTabProps = {
203
+ nested?: boolean;
190
204
  tabs: BottomTabItemProps[];
205
+ initialRouteName?: string;
191
206
  navigation: Navigation;
192
207
  listeners?: {
193
208
  tabPress?: any;
194
209
  focus?: any;
195
210
  };
211
+ floatingButton?: FloatingButtonProps;
212
+ };
213
+
214
+ export type FloatingButtonProps = {
215
+ container?: React.ReactNode;
216
+ icon: string | React.ReactNode;
217
+ label: string;
218
+ onPress: () => void;
196
219
  };
197
220
 
198
221
  export type AnimatedHeader = {
199
222
  type: 'default' | 'surface';
200
223
  component?: (props?: any) => React.ReactElement;
224
+ headerTitle?: (props?: any) => React.ReactElement;
201
225
  };
@@ -13,6 +13,9 @@ import {
13
13
  import {NavigationOptions, Theme} from './types';
14
14
  import {Colors} from '../Consts';
15
15
 
16
+ /**
17
+ * default options for stack screen
18
+ */
16
19
  const getStackOptions = (): StackNavigationOptions => {
17
20
  return {
18
21
  headerTitleAlign: 'left',
@@ -24,6 +27,9 @@ const getStackOptions = (): StackNavigationOptions => {
24
27
  };
25
28
  };
26
29
 
30
+ /**
31
+ * default options for dialog screen
32
+ */
27
33
  const getDialogOptions = (): StackNavigationOptions => {
28
34
  return {
29
35
  headerTitleAlign: 'left',
@@ -35,6 +41,9 @@ const getDialogOptions = (): StackNavigationOptions => {
35
41
  };
36
42
  };
37
43
 
44
+ /**
45
+ * default options for modal screen
46
+ */
38
47
  const getModalOptions = (): StackNavigationOptions => {
39
48
  return {
40
49
  headerShown: false,
@@ -60,6 +69,9 @@ const getModalOptions = (): StackNavigationOptions => {
60
69
  };
61
70
  };
62
71
 
72
+ /**
73
+ * build react-navigation options
74
+ */
63
75
  const getOptions = (params: NavigationOptions, theme: Theme) => {
64
76
  let options = {};
65
77
 
@@ -88,11 +100,7 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
88
100
  ...options,
89
101
  headerTintColor: theme.colors.text.default,
90
102
  headerBackground: () => (
91
- <HeaderBackground
92
- image={null}
93
- backgroundColor={theme.colors.background.surface}
94
- useBorder={true}
95
- />
103
+ <HeaderBackground image={null} useSurface={true} />
96
104
  ),
97
105
  };
98
106
  } else {
@@ -114,10 +122,32 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
114
122
  };
115
123
  }
116
124
 
125
+ if (params.toolkitParams) {
126
+ options = {
127
+ ...options,
128
+ headerRight: (props: any) => {
129
+ return <HeaderToolkitAction {...params.toolkitParams} {...props} />;
130
+ },
131
+ };
132
+ }
133
+
117
134
  return {
118
135
  ...params,
119
136
  ...options,
120
137
  };
121
138
  };
122
139
 
123
- export {getStackOptions, getDialogOptions, getModalOptions, getOptions};
140
+ const formatNameLength = (name = '') => {
141
+ let formattedName = name;
142
+ if (formattedName.length > 100) {
143
+ formattedName = formattedName.substring(0, 100);
144
+ }
145
+ return formattedName;
146
+ };
147
+ export {
148
+ getStackOptions,
149
+ getDialogOptions,
150
+ getModalOptions,
151
+ getOptions,
152
+ formatNameLength,
153
+ };