@momo-kits/foundation 0.89.5 → 0.92.1-rc.1

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 (41) hide show
  1. package/Application/BottomTab/BottomTabBar.tsx +507 -0
  2. package/Application/BottomTab/CurvedView.tsx +27 -0
  3. package/Application/{BottomTab.tsx → BottomTab/index.tsx} +17 -9
  4. package/Application/BottomTab/path.ts +202 -0
  5. package/Application/Components.tsx +48 -26
  6. package/Application/ModalScreen.tsx +107 -131
  7. package/Application/NavigationContainer.tsx +64 -51
  8. package/Application/Navigator.ts +51 -31
  9. package/Application/StackScreen.tsx +83 -12
  10. package/Application/index.ts +0 -4
  11. package/Application/types.ts +16 -7
  12. package/Application/utils.tsx +65 -10
  13. package/Badge/Badge.tsx +1 -1
  14. package/Button/index.tsx +48 -14
  15. package/CheckBox/index.tsx +47 -20
  16. package/CheckBox/types.ts +4 -0
  17. package/Consts/colors+spacing+radius.ts +13 -0
  18. package/IconButton/index.tsx +30 -7
  19. package/Image/index.tsx +3 -1
  20. package/Input/Input.tsx +60 -5
  21. package/Input/InputDropDown.tsx +38 -4
  22. package/Input/InputMoney.tsx +45 -4
  23. package/Input/InputOTP.tsx +33 -7
  24. package/Input/InputSearch.tsx +61 -25
  25. package/Input/InputTextArea.tsx +21 -0
  26. package/Input/index.tsx +29 -2
  27. package/Input/styles.ts +3 -3
  28. package/Popup/PopupNotify.tsx +13 -2
  29. package/Popup/PopupPromotion.tsx +11 -4
  30. package/Radio/index.tsx +46 -19
  31. package/Radio/types.ts +5 -0
  32. package/Switch/index.tsx +39 -14
  33. package/Switch/types.ts +4 -0
  34. package/Text/index.tsx +3 -5
  35. package/Text/styles.ts +7 -7
  36. package/Title/index.tsx +119 -102
  37. package/Title/styles.ts +26 -6
  38. package/Title/types.ts +11 -48
  39. package/index.ts +2 -1
  40. package/package.json +4 -1
  41. package/verify.js +9 -6
@@ -1,10 +1,10 @@
1
1
  import React, {useContext, useEffect, useRef, useState} from 'react';
2
- import {BottomSheetModalProvider} from '@gorhom/bottom-sheet';
3
2
  import {SafeAreaProvider} from 'react-native-safe-area-context';
4
3
  import {
5
4
  NavigationContainer as ReactNavigationContainer,
6
5
  NavigationContainerRef,
7
6
  } from '@react-navigation/native';
7
+ import {BottomSheetModalProvider} from '@gorhom/bottom-sheet';
8
8
  import {createStackNavigator} from '@react-navigation/stack';
9
9
  import {DeviceEventEmitter} from 'react-native';
10
10
  import StackScreen from './StackScreen';
@@ -12,9 +12,19 @@ import ModalScreen from './ModalScreen';
12
12
  import Navigator from './Navigator';
13
13
  import {getDialogOptions, getModalOptions, getStackOptions} from './utils';
14
14
  import {LocalizationObject, NavigationContainerProps} from './types';
15
- import {ApplicationContext, MiniAppContext} from './index';
15
+ import {ApplicationContext} from './index';
16
16
  import kitLocalization from '../Assets/language.json';
17
17
 
18
+ const {
19
+ MiniAppContext,
20
+ } = require('react-native/Libraries/Components/ScreenContext');
21
+
22
+ /**
23
+ * link for deprecated
24
+ */
25
+
26
+ console.log(typeof BottomSheetModalProvider);
27
+
18
28
  const Stack = createStackNavigator();
19
29
 
20
30
  const NavigationContainer: React.FC<NavigationContainerProps> = ({
@@ -23,10 +33,12 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
23
33
  options,
24
34
  maxApi,
25
35
  localization,
36
+ initialParams,
26
37
  }) => {
27
- const context = useContext(MiniAppContext);
28
- const navigationRef = React.useRef<NavigationContainerRef>(null);
29
- const navigator = useRef(new Navigator(navigationRef));
38
+ const context = useContext<any>(MiniAppContext);
39
+ const navigationRef = useRef<NavigationContainerRef>(null);
40
+ const isReady = useRef(false);
41
+ const navigator = useRef(new Navigator(navigationRef, isReady));
30
42
  const [showGrid, setShowGrid] = useState(false);
31
43
  const config = useRef<any>();
32
44
 
@@ -67,52 +79,53 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
67
79
 
68
80
  return (
69
81
  <SafeAreaProvider>
70
- <BottomSheetModalProvider>
71
- <ApplicationContext.Provider
72
- value={{
73
- navigator: navigator.current,
74
- config: config.current,
75
- theme,
76
- showGrid,
77
- translate,
78
- }}>
79
- <ReactNavigationContainer
80
- theme={{
81
- ...theme,
82
- colors: {
83
- ...theme.colors,
84
- background: theme.colors.background.default,
85
- card: theme.colors.background.surface,
86
- text: theme.colors.text.default,
87
- border: theme.colors.border.default,
88
- notification: theme.colors.error.primary,
89
- },
90
- }}
91
- ref={navigator.current?.ref}
92
- independent={true}>
93
- <Stack.Navigator initialRouteName="Stack" headerMode="screen">
94
- <Stack.Screen
95
- name="Stack"
96
- component={StackScreen}
97
- initialParams={{screen}}
98
- options={{...getStackOptions(), ...options}}
99
- />
100
- <Stack.Screen
101
- name="Dialog"
102
- component={StackScreen}
103
- options={getDialogOptions()}
104
- initialParams={{screen}}
105
- />
106
- <Stack.Screen
107
- name="Modal"
108
- component={ModalScreen}
109
- options={getModalOptions()}
110
- initialParams={{screen}}
111
- />
112
- </Stack.Navigator>
113
- </ReactNavigationContainer>
114
- </ApplicationContext.Provider>
115
- </BottomSheetModalProvider>
82
+ <ApplicationContext.Provider
83
+ value={{
84
+ navigator: navigator.current,
85
+ config: config.current,
86
+ theme,
87
+ showGrid,
88
+ translate,
89
+ }}>
90
+ <ReactNavigationContainer
91
+ theme={{
92
+ ...theme,
93
+ colors: {
94
+ ...theme.colors,
95
+ background: theme.colors.background.default,
96
+ card: theme.colors.background.surface,
97
+ text: theme.colors.text.default,
98
+ border: theme.colors.border.default,
99
+ notification: theme.colors.error.primary,
100
+ },
101
+ }}
102
+ ref={navigator.current?.ref}
103
+ onReady={() => {
104
+ isReady.current = true;
105
+ }}
106
+ independent={true}>
107
+ <Stack.Navigator initialRouteName="Stack" headerMode="screen">
108
+ <Stack.Screen
109
+ name="Stack"
110
+ component={StackScreen}
111
+ initialParams={{screen, initialParams}}
112
+ options={{...getStackOptions(), ...options}}
113
+ />
114
+ <Stack.Screen
115
+ name="Dialog"
116
+ component={StackScreen}
117
+ options={getDialogOptions()}
118
+ initialParams={{screen}}
119
+ />
120
+ <Stack.Screen
121
+ name="Modal"
122
+ component={ModalScreen}
123
+ options={getModalOptions()}
124
+ initialParams={{screen}}
125
+ />
126
+ </Stack.Navigator>
127
+ </ReactNavigationContainer>
128
+ </ApplicationContext.Provider>
116
129
  </SafeAreaProvider>
117
130
  );
118
131
  };
@@ -8,13 +8,15 @@ import {
8
8
 
9
9
  class Navigator {
10
10
  ref?: any;
11
+ isReady?: any;
11
12
  toolkitConfig?: HeaderToolkitProps;
12
13
  maxApi?: any;
13
14
  dismissData?: any;
14
15
  toolkitCallback?: (item: any) => void;
15
16
 
16
- constructor(navigation: any) {
17
+ constructor(navigation: any, isReady: any) {
17
18
  this.ref = navigation;
19
+ this.isReady = isReady;
18
20
  }
19
21
 
20
22
  /**
@@ -22,7 +24,9 @@ class Navigator {
22
24
  * @param params
23
25
  */
24
26
  push = (params: ScreenParams) => {
25
- this.ref.current.dispatch(StackActions.push('Stack', params));
27
+ if (this.isReady.current) {
28
+ this.ref.current.dispatch(StackActions.push('Stack', params));
29
+ }
26
30
  };
27
31
 
28
32
  /**
@@ -30,14 +34,18 @@ class Navigator {
30
34
  * @param params
31
35
  */
32
36
  replace = (params: ScreenParams) => {
33
- this.ref.current.dispatch(StackActions.replace('Stack', params));
37
+ if (this.isReady.current) {
38
+ this.ref.current.dispatch(StackActions.replace('Stack', params));
39
+ }
34
40
  };
35
41
  /**
36
42
  * pop to dismiss a screen
37
43
  * @param count
38
44
  */
39
45
  pop = (count?: number) => {
40
- this.ref.current.dispatch(StackActions.pop(count ?? 1));
46
+ if (this.isReady.current) {
47
+ this.ref.current.dispatch(StackActions.pop(count ?? 1));
48
+ }
41
49
  };
42
50
 
43
51
  /**
@@ -45,7 +53,9 @@ class Navigator {
45
53
  * @param params
46
54
  */
47
55
  present = (params: ScreenParams) => {
48
- this.ref.current.dispatch(StackActions.push('Dialog', params));
56
+ if (this.isReady.current) {
57
+ this.ref.current.dispatch(StackActions.push('Dialog', params));
58
+ }
49
59
  };
50
60
 
51
61
  /**
@@ -53,7 +63,9 @@ class Navigator {
53
63
  * @param params
54
64
  */
55
65
  showModal = (params: ModalParams) => {
56
- this.ref.current.dispatch(StackActions.push('Modal', params));
66
+ if (this.isReady.current) {
67
+ this.ref.current.dispatch(StackActions.push('Modal', params));
68
+ }
57
69
  };
58
70
 
59
71
  /**
@@ -61,19 +73,23 @@ class Navigator {
61
73
  * @param params
62
74
  */
63
75
  showBottomSheet = (params: BottomSheetParams) => {
64
- this.ref.current.dispatch(
65
- StackActions.push('Modal', {
66
- ...params,
67
- isBottomSheet: true,
68
- }),
69
- );
76
+ if (this.isReady.current) {
77
+ this.ref.current.dispatch(
78
+ StackActions.push('Modal', {
79
+ ...params,
80
+ isBottomSheet: true,
81
+ }),
82
+ );
83
+ }
70
84
  };
71
85
 
72
86
  /**
73
87
  * pop all screen route
74
88
  */
75
89
  popToTop = () => {
76
- this.ref.current.dispatch(StackActions.popToTop());
90
+ if (this.isReady.current) {
91
+ this.ref.current.dispatch(StackActions.popToTop());
92
+ }
77
93
  };
78
94
 
79
95
  /**
@@ -82,12 +98,14 @@ class Navigator {
82
98
  * @param params
83
99
  */
84
100
  navigate = (name: string, params: any) => {
85
- this.ref.current.dispatch(
86
- CommonActions.navigate({
87
- name,
88
- params,
89
- }),
90
- );
101
+ if (this.isReady.current) {
102
+ this.ref.current.dispatch(
103
+ CommonActions.navigate({
104
+ name,
105
+ params,
106
+ }),
107
+ );
108
+ }
91
109
  };
92
110
 
93
111
  /**
@@ -95,18 +113,20 @@ class Navigator {
95
113
  * @param params
96
114
  */
97
115
  reset = (params: ScreenParams) => {
98
- this.ref.current.dispatch(
99
- CommonActions.reset({
100
- index: 0,
101
- routes: [
102
- {
103
- name: 'Stack',
104
- key: `Stack_${new Date().getTime()}`,
105
- params,
106
- },
107
- ],
108
- }),
109
- );
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
+ );
129
+ }
110
130
  };
111
131
 
112
132
  /**
@@ -1,29 +1,54 @@
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, MiniAppContext} from './index';
4
+ import {ApplicationContext} from './index';
5
5
  import {GridSystem} from '../Layout';
6
6
  import {useHeaderHeight} from '@react-navigation/stack';
7
+ import {Alert, InteractionManager} from 'react-native';
8
+
9
+ const {
10
+ ScreenContext,
11
+ MiniAppContext,
12
+ } = require('react-native/Libraries/Components/ScreenContext');
7
13
 
8
14
  const StackScreen: React.FC<ScreenParams> = props => {
9
15
  const {theme, showGrid, navigator} = useContext(ApplicationContext);
10
- const context = useContext(MiniAppContext);
16
+ const startTime = useRef(Date.now());
17
+ const endTime = useRef(Date.now());
18
+ const timeLoad = useRef(0);
19
+ const timeout = useRef<any>();
20
+
21
+ const context = useContext<any>(MiniAppContext);
11
22
 
12
- const {screen: Component, options}: ScreenParams = props.route.params;
23
+ const {screen: Component, options, initialParams} = props.route.params;
13
24
  const navigation = new Navigation(props.navigation, theme);
14
25
  const heightHeader = useHeaderHeight();
15
26
 
16
- const params = {
27
+ const data = {
17
28
  ...props.route.params,
29
+ ...initialParams,
18
30
  navigation,
19
31
  };
20
32
 
21
- delete params.screen;
33
+ delete data.screen;
34
+ delete data.initialParams;
35
+
36
+ const screenName = Component?.name || Component?.type?.name || '';
22
37
 
23
38
  /**
24
39
  * set options for screen
25
40
  */
26
41
  useLayoutEffect(() => {
42
+ const host = (global as any).miniAppApi?.currentHost || {};
43
+ host.screenName = screenName;
44
+ InteractionManager.runAfterInteractions(() => {
45
+ navigator?.maxApi?.showToastDebug?.({
46
+ appId: `auto - ${context.appId}`,
47
+ message: `${screenName} screen_interaction_time ${
48
+ Date.now() - startTime.current
49
+ }`,
50
+ });
51
+ });
27
52
  if (options) {
28
53
  navigation.setOptions(options);
29
54
  }
@@ -33,9 +58,18 @@ const StackScreen: React.FC<ScreenParams> = props => {
33
58
  * tracking for screen
34
59
  */
35
60
  useEffect(() => {
61
+ if (__DEV__) {
62
+ if (!screenName || screenName === 'screen') {
63
+ Alert.alert(
64
+ 'Design system',
65
+ `Unvalidated screen name "${screenName}" !`,
66
+ );
67
+ }
68
+ }
69
+
36
70
  const tracking = {
37
71
  ...context,
38
- screen_name: Component.name,
72
+ screen_name: screenName,
39
73
  };
40
74
 
41
75
  const routes = props.navigation.getState()?.routes || [];
@@ -45,26 +79,63 @@ const StackScreen: React.FC<ScreenParams> = props => {
45
79
  pre_screen_name = routes[routesLength - 2]?.params?.screen?.name;
46
80
  }
47
81
 
48
- navigator?.maxApi?.trackEvent?.('service_frame_displayed', {
82
+ const params = {
49
83
  ...tracking,
50
84
  pre_screen_name,
51
85
  trigger_id: '111378000000000000',
86
+ };
87
+ navigator?.maxApi?.trackEvent?.('service_frame_displayed', params);
88
+ navigator?.maxApi?.showToastDebug?.({
89
+ appId: `auto - ${context.appId}`,
90
+ message: `${screenName} service_frame_displayed`,
91
+ params,
52
92
  });
53
93
 
54
94
  return props.navigation.addListener('beforeRemove', () => {
55
- navigator?.maxApi?.trackEvent?.('service_icon_clicked', {
95
+ const params = {
56
96
  ...tracking,
57
97
  trigger_id: '111154000000000000',
58
98
  icon_name: 'back',
99
+ };
100
+ navigator?.maxApi?.trackEvent?.('service_icon_clicked', params);
101
+ navigator?.maxApi?.showToastDebug?.({
102
+ appId: `auto - ${context.appId}`,
103
+ message: `${screenName} service_icon_clicked`,
104
+ params,
59
105
  });
60
106
  });
61
107
  }, []);
62
108
 
63
109
  return (
64
- <>
65
- <Component heightHeader={heightHeader} {...params} />
110
+ <ScreenContext.Provider
111
+ value={{
112
+ appId: context.appId,
113
+ code: context.code,
114
+ screenName,
115
+ autoTracking: (data: any) => {
116
+ navigator?.maxApi?.dispatchFunction?.('autoTracking', data);
117
+ },
118
+ onElementLoad: () => {
119
+ endTime.current = Date.now();
120
+ clearTimeout(timeout.current);
121
+ timeout.current = setTimeout(() => {
122
+ if (timeLoad.current === 0) {
123
+ timeLoad.current = endTime.current - startTime.current;
124
+ navigator?.maxApi?.showToastDebug?.({
125
+ appId: `auto - ${context.appId}`,
126
+ message: `${screenName} screen_load_time ${timeLoad.current}`,
127
+ });
128
+ }
129
+ }, 2000);
130
+ },
131
+ }}>
132
+ <Component
133
+ heightHeader={heightHeader}
134
+ {...data}
135
+ onScreenLoad={() => {}}
136
+ />
66
137
  {showGrid && <GridSystem />}
67
- </>
138
+ </ScreenContext.Provider>
68
139
  );
69
140
  };
70
141
 
@@ -4,10 +4,8 @@ import {
4
4
  HeaderAnimated,
5
5
  HeaderBackground,
6
6
  HeaderCustom,
7
- HeaderLeft,
8
7
  HeaderRightAction,
9
8
  HeaderTitle,
10
- HeaderToolkitAction,
11
9
  NavigationButton,
12
10
  } from './Components';
13
11
  import BottomTab from './BottomTab';
@@ -32,10 +30,8 @@ export {
32
30
  BottomTab,
33
31
  NavigationButton,
34
32
  HeaderTitle,
35
- HeaderLeft,
36
33
  HeaderBackground,
37
34
  HeaderRightAction,
38
- HeaderToolkitAction,
39
35
  HeaderCustom,
40
36
  HeaderAnimated,
41
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, FlatListProps, 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
 
@@ -95,6 +95,7 @@ export type NavigationContainerProps = {
95
95
  theme: Theme;
96
96
  maxApi: any;
97
97
  localization?: LocalizationObject;
98
+ initialParams?: any;
98
99
  };
99
100
 
100
101
  export type NavigationScreenProps = {
@@ -118,8 +119,8 @@ export interface ModalParams extends ScreenParams {
118
119
  export interface BottomSheetParams extends ScreenParams {
119
120
  [key: string]: any;
120
121
  onDismiss?: () => void;
121
- snapPoint?: '30%' | '50%' | '70%' | '90%' | 'content';
122
- indicatorColor?: string;
122
+ footerComponent?: React.ReactNode;
123
+ flatListProps: FlatListProps<any>;
123
124
  }
124
125
 
125
126
  export type NavigationButtonProps = {
@@ -129,6 +130,7 @@ export type NavigationButtonProps = {
129
130
  onPress: () => void;
130
131
  badgeType?: 'dot' | 'number';
131
132
  badgeValue?: number;
133
+ accessibilityID?: string;
132
134
  };
133
135
 
134
136
  export type PinnedToolType = {
@@ -152,6 +154,7 @@ export interface NavigationOptions extends StackNavigationOptions {
152
154
  toolkitParams?: {
153
155
  pinnedTool?: PinnedToolType;
154
156
  runtimeTools?: RuntimeToolType[];
157
+ preventClose?: PopupNotifyProps;
155
158
  };
156
159
  }
157
160
 
@@ -183,11 +186,10 @@ export type HeaderToolkitProps = {
183
186
  configs: any[];
184
187
  };
185
188
 
186
- export type HeaderAnimatedProps = {
189
+ export interface HeaderAnimatedProps extends ViewProps {
187
190
  animatedValue: Animated.Value;
188
191
  image: string;
189
- onPress?: () => void;
190
- };
192
+ }
191
193
 
192
194
  export type BottomTabItemProps = {
193
195
  name: string;
@@ -208,6 +210,13 @@ export type BottomTabProps = {
208
210
  tabPress?: any;
209
211
  focus?: any;
210
212
  };
213
+ floatingButton?: FloatingButtonProps;
214
+ };
215
+
216
+ export type FloatingButtonProps = {
217
+ icon: string | React.ReactNode;
218
+ label: string;
219
+ onPress: () => void;
211
220
  };
212
221
 
213
222
  export type AnimatedHeader = {
@@ -12,7 +12,8 @@ import {
12
12
  } from './Components';
13
13
  import {NavigationOptions, Theme} from './types';
14
14
  import {Colors} from '../Consts';
15
-
15
+ import {Platform} from 'react-native';
16
+ const isIOS = Platform.OS === 'ios';
16
17
  /**
17
18
  * default options for stack screen
18
19
  */
@@ -126,19 +127,14 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
126
127
  };
127
128
  }
128
129
 
130
+ if (params.toolkitParams) {
129
131
  options = {
130
132
  ...options,
131
133
  headerRight: (props: any) => {
132
- return (
133
- <HeaderToolkitAction
134
- preventBack={params.preventBack}
135
- pinnedTool={params.toolkitParams?.pinnedTool}
136
- runtimeTools={params.toolkitParams?.runtimeTools}
137
- {...props}
138
- />
139
- );
134
+ return <HeaderToolkitAction {...params.toolkitParams} {...props} />;
140
135
  },
141
136
  };
137
+ }
142
138
 
143
139
  return {
144
140
  ...params,
@@ -146,4 +142,63 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
146
142
  };
147
143
  };
148
144
 
149
- export {getStackOptions, getDialogOptions, getModalOptions, getOptions};
145
+ const getAccessibilityID = (
146
+ key = '',
147
+ override: string | undefined = undefined,
148
+ ) => {
149
+ if (isIOS) {
150
+ return {
151
+ accessible: true,
152
+ testID: override || key,
153
+ };
154
+ } else {
155
+ return {
156
+ accessibilityLabel: override || key,
157
+ };
158
+ }
159
+ };
160
+
161
+ const formatComponentName = (word = '') => {
162
+ const accentsMap = {
163
+ a: 'á|à|ả|ã|ạ|â|ấ|ầ|ẩ|ẫ|ậ|ă|ắ|ằ|ẳ|ẵ|ặ',
164
+ A: 'Á|À|Ả|Ã|Ạ|Â|Ấ|Ầ|Ẩ|Ẫ|Ậ|Ă|Ắ|Ằ|Ẳ|Ẵ|Ặ',
165
+ e: 'é|è|ẻ|ẽ|ẹ|ê|ế|ề|ể|ễ|ệ',
166
+ E: 'É|È|Ẻ|Ẽ|Ẹ|Ê|Ế|Ề|Ể|Ễ|Ệ',
167
+ i: 'í|ì|ỉ|ĩ|ị',
168
+ I: 'Í|Ì|Ỉ|Ĩ|Ị',
169
+ o: 'ó|ò|ỏ|õ|ọ|ô|ố|ồ|ổ|ỗ|ộ|ơ|ớ|ờ|ở|ỡ|ợ',
170
+ O: 'Ó|Ò|Ỏ|Õ|Ọ|Ô|Ố|Ồ|Ổ|Ỗ|Ộ|Ơ|Ớ|Ờ|Ở|Ỡ|Ợ',
171
+ u: 'ú|ù|ủ|ũ|ụ|ư|ứ|ừ|ử|ữ|ự',
172
+ U: 'Ú|Ù|Ủ|Ũ|Ụ|Ư|Ứ|Ừ|Ử|Ữ|Ự',
173
+ y: 'ý|ỳ|ỷ|ỹ|ỵ',
174
+ Y: 'Ý|Ỳ|Ỷ|Ỹ|Ỵ',
175
+ d: 'đ',
176
+ D: 'Đ',
177
+ };
178
+
179
+ for (const [nonAccent, accentGroup] of Object.entries(accentsMap)) {
180
+ const accents = new RegExp(accentGroup, 'g');
181
+ word = word.replace(accents, nonAccent);
182
+ }
183
+
184
+ word = word.replace(/\s+/g, '_').toLowerCase();
185
+
186
+ return word;
187
+ };
188
+
189
+ const formatNameLength = (name = '') => {
190
+ let formattedName = name;
191
+ if (formattedName.length > 100) {
192
+ formattedName = formattedName.substring(0, 100);
193
+ }
194
+ return formattedName;
195
+ };
196
+ export {
197
+ getStackOptions,
198
+ getDialogOptions,
199
+ getModalOptions,
200
+ getOptions,
201
+ formatComponentName,
202
+ formatNameLength,
203
+ getAccessibilityID,
204
+ };
package/Badge/Badge.tsx CHANGED
@@ -46,7 +46,7 @@ const Badge: FC<BadgeProps> = ({label = 'Label', style, backgroundColor}) => {
46
46
 
47
47
  return (
48
48
  <View style={[style, styles.badge, {backgroundColor: badgeColor}]}>
49
- <Text color={Colors.black_01} typography={'action_xs_bold'}>
49
+ <Text color={Colors.black_01} typography={'action_xxs_bold'}>
50
50
  {formatTitle()}
51
51
  </Text>
52
52
  </View>