@momo-kits/foundation 0.81.43 → 0.88.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.
@@ -3,29 +3,45 @@ import {Platform} from 'react-native';
3
3
  import {BottomTabProps, NavigationScreenProps} from './types';
4
4
  import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
5
5
  import {createStackNavigator} from '@react-navigation/stack';
6
+ import {useSafeAreaInsets} from 'react-native-safe-area-context';
7
+ import {NavigationContainer} from '@react-navigation/native';
6
8
  import {Icon} from '../Icon';
7
9
  import {Text} from '../Text';
8
10
  import {ApplicationContext} from './index';
9
11
  import {getStackOptions} from './utils';
10
12
  import StackScreen from './StackScreen';
11
- import {useSafeAreaInsets} from 'react-native-safe-area-context';
12
13
 
13
14
  const Tab = createBottomTabNavigator();
14
15
  const Stack = createStackNavigator();
15
16
 
16
17
  const TabScreen: React.FC<NavigationScreenProps> = ({route}) => {
18
+ if (route.params?.nested) {
19
+ return (
20
+ <Stack.Navigator>
21
+ <Stack.Screen
22
+ name="Stack"
23
+ component={StackScreen}
24
+ initialParams={{screen: route.params?.screen}}
25
+ options={{...getStackOptions(), ...route.params?.options}}
26
+ />
27
+ </Stack.Navigator>
28
+ );
29
+ }
17
30
  return (
18
- <Stack.Navigator>
19
- <Stack.Screen
20
- name="Stack"
21
- component={StackScreen}
22
- initialParams={{screen: route.params?.screen}}
23
- options={{...getStackOptions(), ...route.params?.options}}
24
- />
25
- </Stack.Navigator>
31
+ <NavigationContainer independent={true}>
32
+ <Stack.Navigator>
33
+ <Stack.Screen
34
+ name="Stack"
35
+ component={StackScreen}
36
+ initialParams={{screen: route.params?.screen}}
37
+ options={{...getStackOptions(), ...route.params?.options}}
38
+ />
39
+ </Stack.Navigator>
40
+ </NavigationContainer>
26
41
  );
27
42
  };
28
43
  const BottomTab: React.FC<BottomTabProps> = ({
44
+ nested,
29
45
  tabs,
30
46
  listeners,
31
47
  navigation,
@@ -61,14 +77,16 @@ const BottomTab: React.FC<BottomTabProps> = ({
61
77
  key={item.name}
62
78
  name={item.name}
63
79
  component={TabScreen}
64
- initialParams={item}
80
+ initialParams={{...item, nested}}
65
81
  listeners={listeners}
66
82
  options={{
67
83
  tabBarLabel: ({color, focused}) => {
68
84
  return (
69
85
  <Text
70
86
  numberOfLines={1}
71
- typography={focused ? 'label_xs' : 'description_xs'}
87
+ typography={
88
+ focused ? 'label_xs_medium' : 'description_xs_regular'
89
+ }
72
90
  color={color}>
73
91
  {item.label}
74
92
  </Text>
@@ -22,7 +22,6 @@ import {
22
22
  HeaderAnimatedProps,
23
23
  HeaderBackgroundProps,
24
24
  HeaderBackProps,
25
- HeaderToolkitProps,
26
25
  NavigationButtonProps,
27
26
  TitleCustomProps,
28
27
  } from './types';
@@ -31,74 +30,6 @@ import {Icon} from '../Icon';
31
30
  import {PopupNotify} from '../Popup';
32
31
  import {Badge, BadgeDot} from '../Badge';
33
32
 
34
- const styles = StyleSheet.create({
35
- navigationButton: {
36
- height: 28,
37
- width: 28,
38
- borderRadius: 14,
39
- justifyContent: 'center',
40
- alignItems: 'center',
41
- },
42
- headerBackground: {
43
- width: '100%',
44
- height: undefined,
45
- position: 'absolute',
46
- aspectRatio: 375 / 154,
47
- },
48
- headerTitleContainer: {
49
- alignItems: 'center',
50
- justifyContent: 'center',
51
- width: '100%',
52
- },
53
- circle: {width: 36, height: 36, borderRadius: 18},
54
- square: {width: 36, height: 36, borderRadius: Radius.XS},
55
- dotAvatar: {
56
- position: 'absolute',
57
- width: 12,
58
- height: 12,
59
- borderRadius: 6,
60
- bottom: 0,
61
- right: 0,
62
- borderWidth: 1,
63
- borderColor: Colors.black_01,
64
- },
65
- headerButton: {paddingHorizontal: 4},
66
- headerRightButton: {
67
- flexDirection: 'row',
68
- justifyContent: 'center',
69
- alignItems: 'center',
70
- paddingRight: Spacing.S,
71
- },
72
- toolkitContainer: {
73
- marginLeft: Spacing.S,
74
- padding: Spacing.XS,
75
- height: 28,
76
- borderRadius: 14,
77
- borderColor: '#00000066',
78
- justifyContent: 'center',
79
- alignItems: 'center',
80
- flexDirection: 'row',
81
- },
82
- divider: {
83
- width: 1,
84
- height: 12,
85
- marginHorizontal: 4,
86
- },
87
- headerLeft: {
88
- marginLeft: 12,
89
- },
90
- title: {
91
- fontSize: scaleSize(15),
92
- lineHeight: scaleSize(22),
93
- fontWeight: 'bold',
94
- },
95
- badge: {
96
- position: 'absolute',
97
- top: -8,
98
- right: -8,
99
- },
100
- });
101
-
102
33
  const NavigationButton: React.FC<NavigationButtonProps> = ({
103
34
  icon,
104
35
  tintColor,
@@ -118,26 +49,35 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
118
49
  };
119
50
  }
120
51
 
52
+ const isNumber = (label: any) => {
53
+ const numberRegex = /^\d+$/;
54
+ return numberRegex.test(String(label));
55
+ };
56
+
121
57
  const renderBadge = useCallback(() => {
122
- if (!badgeValue && !badgeType) return null;
123
58
  if (badgeType === 'dot') {
124
- return <BadgeDot size="small" style={styles.badge} />;
59
+ return <BadgeDot size="small" style={styles.badgeDot} />;
60
+ }
61
+
62
+ if (isNumber(badgeValue)) {
63
+ return <Badge label={badgeValue} style={styles.badge} />;
125
64
  }
126
- return <Badge label={badgeValue} style={styles.badge} />;
127
65
  }, [badgeType, badgeValue]);
128
66
 
129
67
  return (
130
- <TouchableOpacity
131
- accessibilityLabel={`NavigationButton/${accessibilityLabel}`}
132
- style={[styles.navigationButton, buttonStyle]}
133
- onPress={onPress}>
134
- <Icon
135
- source={icon}
136
- color={tintColor ?? theme.colors.text.default}
137
- size={20}
138
- />
68
+ <View style={{width: scaleSize(28)}}>
69
+ <TouchableOpacity
70
+ accessibilityLabel={`NavigationButton/${accessibilityLabel}`}
71
+ style={[styles.navigationButton, buttonStyle]}
72
+ onPress={onPress}>
73
+ <Icon
74
+ source={icon}
75
+ color={tintColor ?? theme.colors.text.default}
76
+ size={20}
77
+ />
78
+ </TouchableOpacity>
139
79
  {renderBadge()}
140
- </TouchableOpacity>
80
+ </View>
141
81
  );
142
82
  };
143
83
 
@@ -304,10 +244,10 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
304
244
  )}
305
245
  </View>
306
246
  <View style={[Styles.flex, {paddingHorizontal: 8}]}>
307
- <Text typography="title_xs" color={tintColor}>
247
+ <Text typography="header_default_bold" color={tintColor}>
308
248
  {title}
309
249
  </Text>
310
- <Text typography="description_s" color={tintColor}>
250
+ <Text typography="description_default_regular" color={tintColor}>
311
251
  {subTitle}
312
252
  </Text>
313
253
  </View>
@@ -347,10 +287,14 @@ const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
347
287
  return <View style={styles.headerRightButton}>{renderAction()}</View>;
348
288
  };
349
289
 
350
- const HeaderToolkitAction: React.FC<any> = ({tintColor}) => {
290
+ const HeaderToolkitAction: React.FC<any> = ({
291
+ tintColor,
292
+ pinnedTool,
293
+ preventBack,
294
+ }) => {
351
295
  const {theme, navigator} = useContext(ApplicationContext);
352
- const [toolConfig, setToolConfig] = useState<HeaderToolkitProps>();
353
- const {appCode, hidden, type, onAction} = toolConfig ?? {};
296
+ const [toolConfig, setToolConfig] = useState<any>();
297
+ const {onAction} = toolConfig ?? {};
354
298
 
355
299
  let backgroundColor;
356
300
  if (tintColor != Colors.black_01) {
@@ -361,95 +305,78 @@ const HeaderToolkitAction: React.FC<any> = ({tintColor}) => {
361
305
  if (navigator?.toolkitConfig) {
362
306
  setToolConfig(navigator?.toolkitConfig);
363
307
  } else {
364
- navigator?.requestApi('getToolkit', [undefined], (result: boolean) => {
365
- if (result) {
366
- navigator?.requestApi(
367
- 'getToolkitConfig',
368
- [undefined],
369
- (config: any) => {
370
- navigator.toolkitConfig = {
371
- ...config?.utilityToolConfig,
372
- appCode: config?.appCode,
373
- };
374
- setToolConfig(navigator?.toolkitConfig);
375
- },
376
- );
377
- }
378
- });
308
+ getToolkitConfig();
379
309
  }
380
310
  }, []);
381
311
 
382
- useEffect(() => {
383
- let addFavorite: any;
384
- let removeFavorite: any;
385
- if (appCode) {
386
- const addSchema = `observerToolkit_addFavorite_${appCode}`;
387
- const removeSchema = `observerToolkit_removeFavorite_${appCode}`;
388
- addFavorite = navigator?.requestApi(
389
- 'observer',
390
- [addSchema],
391
- (data: any) => {
392
- if (data?.status) {
393
- setToolConfig({
394
- ...(toolConfig as HeaderToolkitProps),
395
- hidden: true,
396
- });
397
- }
398
- },
399
- );
400
- addFavorite = navigator?.requestApi(
401
- 'observer',
402
- [removeSchema],
403
- (data: any) => {
404
- if (data?.status) {
405
- setToolConfig({
406
- ...(toolConfig as HeaderToolkitProps),
407
- hidden: false,
408
- });
409
- }
410
- },
411
- );
412
- }
413
-
414
- return () => {
415
- addFavorite?.();
416
- removeFavorite?.();
417
- };
418
- }, [appCode]);
419
-
420
- const onUtilityTool = () => {
421
- onAction?.('onUtilityTool');
422
- navigator?.requestApi(type, undefined, undefined);
312
+ const getToolkitConfig = () => {
313
+ navigator?.requestApi('getToolsConfig', [undefined], (config: any) => {
314
+ navigator.toolkitConfig = config;
315
+ setToolConfig(navigator?.toolkitConfig);
316
+ });
423
317
  };
424
318
 
425
319
  const onMore = () => {
426
320
  onAction?.('onMore');
427
- navigator?.requestApi('showToolkit', [toolConfig], undefined);
321
+ navigator?.requestApi(
322
+ 'showTools',
323
+ [undefined],
324
+ (res: {item: {action?: string; key: string}}) => {
325
+ const {item} = res;
326
+ navigator?.toolkitCallback?.(item);
327
+ getToolkitConfig();
328
+ },
329
+ );
428
330
  };
429
331
 
430
332
  const onClose = () => {
431
- onAction?.('onClose');
432
- navigator?.requestApi('dismiss', undefined, undefined);
333
+ if (preventBack) {
334
+ navigator?.showModal({
335
+ screen: () => (
336
+ <PopupNotify
337
+ {...preventBack}
338
+ primary={{
339
+ title: preventBack.primary.title,
340
+ onPress: () => {
341
+ preventBack?.primary.onPress();
342
+ navigator?.requestApi('dismiss', undefined, undefined);
343
+ },
344
+ }}
345
+ />
346
+ ),
347
+ });
348
+ } else {
349
+ navigator?.requestApi('dismiss', undefined, undefined);
350
+ }
433
351
  };
434
352
 
435
- const renderUtilityTool = () => {
436
- if (hidden === false) {
353
+ const renderPinnedTool = () => {
354
+ const pinKey = pinnedTool?.key || toolConfig?.pinnedTool?.key;
355
+ const pinTool = toolConfig?.tools?.find((i: any) => i.key === pinKey);
356
+ const {badgeValue, badgeType} = pinnedTool ?? {};
357
+
358
+ if (pinTool)
437
359
  return (
438
360
  <NavigationButton
439
361
  accessibilityLabel={'UtilityTool'}
440
- icon={type as string}
362
+ icon={pinTool.icon as string}
441
363
  tintColor={tintColor}
442
- onPress={onUtilityTool}
364
+ badgeValue={badgeValue}
365
+ badgeType={badgeType}
366
+ onPress={() => {
367
+ navigator?.requestApi('onToolAction', [pinTool?.key], () => {
368
+ getToolkitConfig();
369
+ });
370
+ navigator?.toolkitCallback?.(pinTool.key);
371
+ }}
443
372
  />
444
373
  );
445
- }
446
- return null;
447
374
  };
448
375
 
449
376
  if (toolConfig) {
450
377
  return (
451
378
  <View style={styles.headerRightButton}>
452
- {renderUtilityTool()}
379
+ {renderPinnedTool()}
453
380
  <View
454
381
  style={[
455
382
  styles.toolkitContainer,
@@ -521,6 +448,79 @@ const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
521
448
  );
522
449
  };
523
450
 
451
+ const styles = StyleSheet.create({
452
+ navigationButton: {
453
+ height: 28,
454
+ width: 28,
455
+ borderRadius: 14,
456
+ justifyContent: 'center',
457
+ alignItems: 'center',
458
+ },
459
+ headerBackground: {
460
+ width: '100%',
461
+ height: undefined,
462
+ position: 'absolute',
463
+ aspectRatio: 375 / 154,
464
+ },
465
+ headerTitleContainer: {
466
+ alignItems: 'center',
467
+ justifyContent: 'center',
468
+ width: '100%',
469
+ },
470
+ circle: {width: 36, height: 36, borderRadius: 18},
471
+ square: {width: 36, height: 36, borderRadius: Radius.XS},
472
+ dotAvatar: {
473
+ position: 'absolute',
474
+ width: 12,
475
+ height: 12,
476
+ borderRadius: 6,
477
+ bottom: 0,
478
+ right: 0,
479
+ borderWidth: 1,
480
+ borderColor: Colors.black_01,
481
+ },
482
+ headerButton: {paddingHorizontal: 4},
483
+ headerRightButton: {
484
+ flexDirection: 'row',
485
+ justifyContent: 'center',
486
+ alignItems: 'center',
487
+ paddingRight: Spacing.S,
488
+ },
489
+ toolkitContainer: {
490
+ marginLeft: Spacing.S,
491
+ padding: Spacing.XS,
492
+ height: 28,
493
+ borderRadius: 14,
494
+ borderColor: '#00000066',
495
+ justifyContent: 'center',
496
+ alignItems: 'center',
497
+ flexDirection: 'row',
498
+ },
499
+ divider: {
500
+ width: 1,
501
+ height: 12,
502
+ marginHorizontal: 4,
503
+ },
504
+ headerLeft: {
505
+ marginLeft: 12,
506
+ },
507
+ title: {
508
+ fontSize: scaleSize(15),
509
+ lineHeight: scaleSize(22),
510
+ fontWeight: 'bold',
511
+ },
512
+ badge: {
513
+ position: 'absolute',
514
+ top: -Spacing.S,
515
+ right: -6,
516
+ },
517
+ badgeDot: {
518
+ position: 'absolute',
519
+ top: -Spacing.XS,
520
+ right: -Spacing.XS,
521
+ },
522
+ });
523
+
524
524
  export {
525
525
  NavigationButton,
526
526
  HeaderTitle,
@@ -13,6 +13,7 @@ class Navigator {
13
13
  maxApi?: any;
14
14
  trackingInfo?: TrackingInfo;
15
15
  dismissData?: any;
16
+ toolkitCallback?: (item: any) => void;
16
17
 
17
18
  constructor(navigation: any) {
18
19
  this.ref = navigation;
@@ -121,6 +122,12 @@ class Navigator {
121
122
  this.maxApi[func]?.(...args, callback);
122
123
  }
123
124
  };
125
+
126
+ setToolkitCallback = (
127
+ callback: (item: {key: string; action: string}) => void,
128
+ ) => {
129
+ this.toolkitCallback = callback;
130
+ };
124
131
  }
125
132
 
126
133
  export default Navigator;
@@ -128,8 +128,14 @@ export type NavigationButtonProps = {
128
128
  useBorder?: boolean;
129
129
  onPress: () => void;
130
130
  accessibilityLabel?: string;
131
- badgeType?: 'dot' | 'number' | 'string';
132
- badgeValue?: number | string;
131
+ badgeType?: 'dot' | 'number';
132
+ badgeValue?: number;
133
+ };
134
+
135
+ export type PinnedToolType = {
136
+ key: string;
137
+ badgeValue?: number;
138
+ badgeType?: 'number' | 'dot';
133
139
  };
134
140
 
135
141
  export interface NavigationOptions extends StackNavigationOptions {
@@ -138,6 +144,7 @@ export interface NavigationOptions extends StackNavigationOptions {
138
144
  surface?: boolean;
139
145
  hiddenBack?: boolean;
140
146
  customTitle?: TitleCustomProps;
147
+ pinnedTool?: PinnedToolType;
141
148
  }
142
149
 
143
150
  export interface HeaderBackProps extends NavigationButtonProps {
@@ -166,9 +173,7 @@ export type TitleCustomProps = {
166
173
  export type HeaderToolkitProps = {
167
174
  [key: string]: any;
168
175
  appCode: string;
169
- hidden: boolean;
170
- type: string;
171
- onAction?: (action: string) => void;
176
+ configs: any[];
172
177
  };
173
178
 
174
179
  export type HeaderAnimatedProps = {
@@ -188,6 +193,7 @@ export type BottomTabItemProps = {
188
193
  };
189
194
 
190
195
  export type BottomTabProps = {
196
+ nested?: boolean;
191
197
  tabs: BottomTabItemProps[];
192
198
  initialRouteName?: string;
193
199
  navigation: Navigation;
@@ -126,6 +126,21 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
126
126
  };
127
127
  }
128
128
 
129
+ if (params.pinnedTool) {
130
+ options = {
131
+ ...options,
132
+ headerRight: (props: any) => {
133
+ return (
134
+ <HeaderToolkitAction
135
+ preventBack={params.preventBack}
136
+ pinnedTool={params.pinnedTool}
137
+ {...props}
138
+ />
139
+ );
140
+ },
141
+ };
142
+ }
143
+
129
144
  return {
130
145
  ...params,
131
146
  ...options,
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_xxs'}>
49
+ <Text color={Colors.black_01} typography={'action_xs_bold'}>
50
50
  {formatTitle()}
51
51
  </Text>
52
52
  </View>
@@ -54,7 +54,7 @@ const BadgeRibbon: FC<BadgeRibbonProps> = ({
54
54
  },
55
55
  ]}
56
56
  color={Colors.black_01}
57
- typography={'label_xs'}>
57
+ typography={'label_xs_medium'}>
58
58
  {label}
59
59
  </Text>
60
60
  </View>
@@ -87,7 +87,7 @@ const BadgeRibbon: FC<BadgeRibbonProps> = ({
87
87
  },
88
88
  ]}
89
89
  color={Colors.black_01}
90
- typography={'label_xs'}>
90
+ typography={'label_xs_medium'}>
91
91
  {label}
92
92
  </Text>
93
93
  </View>
package/Badge/styles.ts CHANGED
@@ -4,13 +4,16 @@ import {scaleSize} from '../Text';
4
4
 
5
5
  export default StyleSheet.create({
6
6
  badge: {
7
+ paddingHorizontal: Spacing.XS,
7
8
  borderRadius: Radius.M,
8
9
  justifyContent: 'center',
10
+ alignItems: 'center',
9
11
  height: scaleSize(16),
12
+ minWidth: scaleSize(16),
10
13
  flexDirection: 'row',
14
+ borderWidth: 1,
11
15
  borderColor: Colors.black_01,
12
- paddingHorizontal: Spacing.XS,
13
- alignItems: 'center',
16
+ alignSelf: 'baseline',
14
17
  },
15
18
  dot: {
16
19
  width: 16,
package/Button/index.tsx CHANGED
@@ -172,14 +172,14 @@ const Button: FC<ButtonProps> = ({
172
172
  const getTypography = (): Typography => {
173
173
  switch (size) {
174
174
  case 'large':
175
- return 'action_default';
175
+ return 'action_default_bold';
176
176
  case 'medium':
177
- return 'action_s';
177
+ return 'action_s_bold';
178
178
  case 'small':
179
- return 'action_xs';
179
+ return 'action_xs_bold';
180
180
 
181
181
  default:
182
- return 'action_default';
182
+ return 'action_default_bold';
183
183
  }
184
184
  };
185
185
 
@@ -54,7 +54,7 @@ const CheckBox: FC<CheckBoxProps> = ({
54
54
  />
55
55
  )}
56
56
  </View>
57
- {!!label && <Text typography={'description_default'}>{label}</Text>}
57
+ {!!label && <Text typography={'body_default_regular'}>{label}</Text>}
58
58
  </TouchableOpacity>
59
59
  );
60
60
  };
@@ -57,7 +57,7 @@ const OTPCaret: FC<CaretProps> = ({index, length}) => {
57
57
  opacity,
58
58
  }}
59
59
  />
60
- <Text color={theme.colors.text.hint} typography={'paragraph_default'}>
60
+ <Text color={theme.colors.text.hint} typography={'body_default_regular'}>
61
61
  -
62
62
  </Text>
63
63
  </View>
@@ -135,7 +135,9 @@ const InputOTP = forwardRef(
135
135
  ? theme.colors.text.default
136
136
  : theme.colors.text.hint
137
137
  }
138
- typography={!!value[i] ? 'title_s' : 'paragraph_default'}>
138
+ typography={
139
+ !!value[i] ? 'header_m_bold' : 'body_default_regular'
140
+ }>
139
141
  {value[i] || '-'}
140
142
  </Text>
141
143
  )}
@@ -150,7 +152,9 @@ const InputOTP = forwardRef(
150
152
 
151
153
  if (!focused && value.length === 0 && !!placeholder) {
152
154
  return (
153
- <Text color={theme.colors.text.hint} typography={'description_s'}>
155
+ <Text
156
+ color={theme.colors.text.hint}
157
+ typography={'description_default_regular'}>
154
158
  {placeholder}
155
159
  </Text>
156
160
  );
@@ -167,7 +171,7 @@ const InputOTP = forwardRef(
167
171
  marginRight: Spacing.L,
168
172
  }
169
173
  }
170
- typography={'title_s'}>
174
+ typography={'header_m_bold'}>
171
175
  {letter}
172
176
  </Text>
173
177
  );
@@ -191,7 +195,9 @@ const InputOTP = forwardRef(
191
195
  styles.otpFloatingView,
192
196
  {backgroundColor: theme.colors.background.surface},
193
197
  ]}>
194
- <Text typography={'description_s'}>{floatingValue}</Text>
198
+ <Text typography={'description_default_regular'}>
199
+ {floatingValue}
200
+ </Text>
195
201
  </View>
196
202
  )}
197
203
  <View style={styles.otpInputsView}>
@@ -142,7 +142,7 @@ const InputSearch = forwardRef(
142
142
  </View>
143
143
  {showButtonText && (
144
144
  <TouchableOpacity onPress={onPressButtonText}>
145
- <Text typography={'action_default'} style={styles.textButton}>
145
+ <Text typography={'action_default_bold'} style={styles.textButton}>
146
146
  {buttonText}
147
147
  </Text>
148
148
  </TouchableOpacity>
@@ -71,7 +71,9 @@ const InputTextArea = forwardRef(
71
71
  const renderCountingView = () => {
72
72
  return (
73
73
  <View style={styles.countingView}>
74
- <Text color={theme.colors.text.hint} typography={'description_xs'}>
74
+ <Text
75
+ color={theme.colors.text.hint}
76
+ typography={'description_xs_regular'}>
75
77
  {`${inputValue.length}/${maxLength}`}
76
78
  </Text>
77
79
  </View>
package/Input/common.tsx CHANGED
@@ -64,7 +64,7 @@ export const ErrorView: FC<{errorMessage?: string; errorSpacing?: boolean}> = ({
64
64
  style={Styles.flex}
65
65
  color={errorColor}
66
66
  numberOfLines={2}
67
- typography={'description_s'}>
67
+ typography={'description_default_regular'}>
68
68
  {errorMessage}
69
69
  </Text>
70
70
  </View>
@@ -104,10 +104,12 @@ export const FloatingView: FC<FloatingViewProps> = ({
104
104
  },
105
105
  style,
106
106
  ]}>
107
- <Text color={floatingTextColor} typography={'label_s'}>
107
+ <Text color={floatingTextColor} typography={'label_s_medium'}>
108
108
  {floatingValue}
109
109
  {required && (
110
- <Text typography={'label_s'} color={theme.colors.error.primary}>
110
+ <Text
111
+ typography={'label_s_medium'}
112
+ color={theme.colors.error.primary}>
111
113
  *
112
114
  </Text>
113
115
  )}
package/Layout/Card.tsx CHANGED
@@ -29,7 +29,7 @@ const Card: React.FC<CardProps> = ({
29
29
  useShadow = false,
30
30
  ...props
31
31
  }) => {
32
- const {showGrid} = useContext(ApplicationContext);
32
+ const {showGrid, theme} = useContext(ApplicationContext);
33
33
  const {numberOfColumns} = useGridSystem();
34
34
 
35
35
  const gutterSize = 8;
@@ -47,6 +47,7 @@ const Card: React.FC<CardProps> = ({
47
47
  return span * sizePerSpan + (span - 1) * gutterSize;
48
48
  },
49
49
  };
50
+
50
51
  /**
51
52
  * render overlay only dev mode
52
53
  */
@@ -107,8 +108,9 @@ const Card: React.FC<CardProps> = ({
107
108
  if (Array.isArray(children)) {
108
109
  let cursor = 0;
109
110
  let rows: any[] = [];
110
- for (let i = 0; i < children.length; ++i) {
111
- const item = children[i];
111
+ const arrayChild = children.filter(item => !!item);
112
+ for (let i = 0; i < arrayChild.length; ++i) {
113
+ const item = arrayChild[i];
112
114
  const totalSpan = rows
113
115
  .concat([item])
114
116
  .map(i => i.props?.widthSpan)
@@ -124,7 +126,7 @@ const Card: React.FC<CardProps> = ({
124
126
  rows = [item];
125
127
  }
126
128
 
127
- if (i == children.length - 1) {
129
+ if (i == arrayChild.length - 1) {
128
130
  cursor += 1;
129
131
  element.push(addRowView(rows, cursor, true));
130
132
  }
@@ -138,23 +140,21 @@ const Card: React.FC<CardProps> = ({
138
140
  return element;
139
141
  };
140
142
 
141
- const {theme} = useContext(ApplicationContext);
142
143
  return (
143
144
  <GridContext.Provider value={gridContext}>
144
145
  <View
145
146
  {...props}
146
147
  accessibilityLabel={`Card`}
147
148
  style={[
149
+ {backgroundColor: theme.colors.background.surface},
148
150
  style,
149
151
  styles.protectedStyle,
150
152
  styles.card,
151
153
  {
152
154
  width: widthSection,
153
155
  marginHorizontal: margin,
154
- backgroundColor: backgroundImage
155
- ? undefined
156
- : theme.colors.background.surface,
157
156
  },
157
+ !!backgroundImage && {backgroundColor: undefined},
158
158
  useShadow && Shadow.Light,
159
159
  ]}>
160
160
  {!!backgroundImage && (
@@ -1,4 +1,4 @@
1
- import React, {FC, useContext} from 'react';
1
+ import React, {forwardRef, useContext} from 'react';
2
2
  import {FlatList, FlatListProps, View} from 'react-native';
3
3
  import Item, {SpanNumber} from './Item';
4
4
  import {GridContext} from './index';
@@ -11,39 +11,45 @@ export interface ItemListProps extends FlatListProps<any> {
11
11
  widthSpan?: SpanNumber;
12
12
  }
13
13
 
14
- const ItemList: FC<ItemListProps> = ({
15
- renderItem,
16
- widthSpan,
17
- style,
18
- contentContainerStyle,
19
- ...props
20
- }) => {
21
- const {gutterSize, numberOfColumns} = useContext(GridContext);
22
- const widthItem = (widthSpan ?? numberOfColumns) as SpanNumber;
23
- const numColumns = Math.floor(numberOfColumns / widthItem);
24
- const indexBegin = props?.data?.map((_i, index) => index * numColumns);
25
- const _renderItem = (item: any) => {
26
- if (indexBegin?.includes(item?.index)) {
27
- return <Item widthSpan={widthItem}>{renderItem?.(item)}</Item>;
28
- }
14
+ const ItemList = forwardRef(
15
+ (
16
+ {
17
+ renderItem,
18
+ widthSpan,
19
+ style,
20
+ contentContainerStyle,
21
+ ...props
22
+ }: ItemListProps,
23
+ ref,
24
+ ) => {
25
+ const {gutterSize, numberOfColumns} = useContext(GridContext);
26
+ const widthItem = (widthSpan ?? numberOfColumns) as SpanNumber;
27
+ const numColumns = Math.floor(numberOfColumns / widthItem);
28
+ const indexBegin = props?.data?.map((_i, index) => index * numColumns);
29
+ const _renderItem = (item: any) => {
30
+ if (indexBegin?.includes(item?.index)) {
31
+ return <Item widthSpan={widthItem}>{renderItem?.(item)}</Item>;
32
+ }
33
+ return (
34
+ <View style={{paddingLeft: gutterSize}}>
35
+ <Item widthSpan={widthItem}>{renderItem?.(item)}</Item>
36
+ </View>
37
+ );
38
+ };
39
+
29
40
  return (
30
- <View style={{paddingLeft: gutterSize}}>
31
- <Item widthSpan={widthItem}>{renderItem?.(item)}</Item>
32
- </View>
41
+ <FlatList
42
+ ref={ref as React.RefObject<FlatList>}
43
+ {...props}
44
+ numColumns={numColumns}
45
+ renderItem={_renderItem}
46
+ horizontal={false}
47
+ ItemSeparatorComponent={() => <View style={{height: gutterSize}} />}
48
+ style={[style, styles.protectedStyle]}
49
+ contentContainerStyle={[contentContainerStyle, styles.protectedStyle]}
50
+ />
33
51
  );
34
- };
35
-
36
- return (
37
- <FlatList
38
- {...props}
39
- numColumns={numColumns}
40
- renderItem={_renderItem}
41
- horizontal={false}
42
- ItemSeparatorComponent={() => <View style={{height: gutterSize}} />}
43
- style={[style, styles.protectedStyle]}
44
- contentContainerStyle={[contentContainerStyle, styles.protectedStyle]}
45
- />
46
- );
47
- };
52
+ },
53
+ );
48
54
 
49
55
  export default ItemList;
@@ -107,8 +107,9 @@ const Section: React.FC<SectionProps> = ({
107
107
  if (Array.isArray(children)) {
108
108
  let cursor = 0;
109
109
  let rows: any[] = [];
110
- for (let i = 0; i < children.length; ++i) {
111
- const item = children[i];
110
+ const arrayChild = children.filter(item => !!item);
111
+ for (let i = 0; i < arrayChild.length; ++i) {
112
+ const item = arrayChild[i];
112
113
  const totalSpan = rows
113
114
  .concat([item])
114
115
  .map(i => i.props?.widthSpan)
@@ -124,7 +125,7 @@ const Section: React.FC<SectionProps> = ({
124
125
  rows = [item];
125
126
  }
126
127
 
127
- if (i == children.length - 1) {
128
+ if (i == arrayChild.length - 1) {
128
129
  cursor += 1;
129
130
  element.push(addRowView(rows, cursor, true));
130
131
  }
@@ -13,7 +13,7 @@ const PaginationNumber: FC<ChildPaginationProps> = ({
13
13
  return (
14
14
  <View style={[style, styles.row]}>
15
15
  <View style={styles.paginationNumberContainer}>
16
- <Text color={Colors.black_01} typography={'label_default'}>{`${
16
+ <Text color={Colors.black_01} typography={'label_default_medium'}>{`${
17
17
  activeIndex + 1
18
18
  }/${dataLength}`}</Text>
19
19
  </View>
@@ -192,12 +192,12 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
192
192
  ]}>
193
193
  {!!image && <Image source={{uri: image}} style={styles.image} />}
194
194
  <View style={styles.content}>
195
- <Text typography={'title_xs'} numberOfLines={1}>
195
+ <Text typography={'header_default_bold'} numberOfLines={1}>
196
196
  {title}
197
197
  </Text>
198
198
  <Description style={[styles.description, descriptionStyle]}>
199
199
  <Text
200
- typography={'paragraph_default'}
200
+ typography={'body_default_regular'}
201
201
  onTextLayout={({nativeEvent: {lines}}) => {
202
202
  const enableScroll = lines.length > 3;
203
203
  if (enableScroll != scrollContent) {
@@ -210,7 +210,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
210
210
  {!!error && (
211
211
  <View style={styles.information}>
212
212
  <Text
213
- typography={'description_xs'}
213
+ typography={'description_xs_regular'}
214
214
  color={theme.colors.text.hint}
215
215
  numberOfLines={1}>
216
216
  {translate?.('errorCode')}
package/Radio/index.tsx CHANGED
@@ -57,7 +57,7 @@ const Radio: FC<RadioProps> = ({
57
57
  {marginRight: label ? Spacing.XS : 0},
58
58
  ]}
59
59
  />
60
- {!!label && <Text typography={'description_default'}>{label}</Text>}
60
+ {!!label && <Text typography={'body_default_regular'}>{label}</Text>}
61
61
  </TouchableOpacity>
62
62
  );
63
63
  };
package/Tag/index.tsx CHANGED
@@ -71,7 +71,7 @@ const Tag: FC<TagProps> = ({
71
71
  color={labelColor}
72
72
  />
73
73
  )}
74
- <Text color={labelColor} typography={'label_s'}>
74
+ <Text color={labelColor} typography={'label_s_medium'}>
75
75
  {label}
76
76
  </Text>
77
77
  </View>
package/Text/index.tsx CHANGED
@@ -84,6 +84,7 @@ const Text: React.FC<TextProps> = ({
84
84
  }
85
85
 
86
86
  return {
87
+ ...typoStyle,
87
88
  fontFamily,
88
89
  fontSize: scaleSize(fontSize),
89
90
  lineHeight: scaleSize(lineHeight),
@@ -104,7 +105,7 @@ const Text: React.FC<TextProps> = ({
104
105
  };
105
106
 
106
107
  Text.defaultProps = {
107
- typography: 'paragraph_default',
108
+ typography: 'body_default_regular',
108
109
  };
109
110
 
110
111
  export {Text, scaleSize};
package/Text/styles.ts CHANGED
@@ -1,4 +1,42 @@
1
1
  export default {
2
+ headline_default_bold: {fontSize: 24, lineHeight: 32, fontWeight: '700'},
3
+ header_m_bold: {fontSize: 18, lineHeight: 28, fontWeight: '700'},
4
+ header_default_bold: {fontSize: 16, lineHeight: 22, fontWeight: '700'},
5
+ header_s_semibold: {fontSize: 14, lineHeight: 20, fontWeight: '600'},
6
+ header_xs_semibold: {fontSize: 12, lineHeight: 16, fontWeight: '600'},
7
+ body_default_regular: {fontSize: 14, lineHeight: 20, fontWeight: '400'},
8
+ body_regularstrikethrought: {
9
+ fontSize: 14,
10
+ lineHeight: 20,
11
+ fontWeight: '400',
12
+ textDecorationLine: 'line-through',
13
+ },
14
+ description_default_regular: {
15
+ fontSize: 12,
16
+ lineHeight: 16,
17
+ fontWeight: '400',
18
+ },
19
+ description_default_regularstrikethrought: {
20
+ fontSize: 12,
21
+ lineHeight: 16,
22
+ fontWeight: '400',
23
+ textDecorationLine: 'line-through',
24
+ },
25
+ description_xs_regular: {fontSize: 10, lineHeight: 14, fontWeight: '400'},
26
+ description_xs_regularstrikethrought: {
27
+ fontSize: 10,
28
+ lineHeight: 14,
29
+ fontWeight: '400',
30
+ textDecorationLine: 'line-through',
31
+ },
32
+ label_default_medium: {fontSize: 14, lineHeight: 20, fontWeight: '500'},
33
+ label_s_medium: {fontSize: 12, lineHeight: 16, fontWeight: '500'},
34
+ label_xs_medium: {fontSize: 10, lineHeight: 14, fontWeight: '500'},
35
+ action_default_bold: {fontSize: 16, lineHeight: 22, fontWeight: '700'},
36
+ action_s_bold: {fontSize: 14, lineHeight: 20, fontWeight: '700'},
37
+ action_xs_bold: {fontSize: 12, lineHeight: 16, fontWeight: '700'},
38
+ action_xxs_bold: {fontSize: 10, lineHeight: 14, fontWeight: '700'},
39
+ /**non-support**/
2
40
  headline_default: {
3
41
  fontSize: 28,
4
42
  lineHeight: 34,
package/Text/types.ts CHANGED
@@ -14,27 +14,21 @@ export type TypographyWeight = {
14
14
  };
15
15
 
16
16
  export type Typography =
17
- | 'headline_default'
18
- | 'headline_s'
19
- | 'headline_l'
20
- | 'headline_xl'
21
- | 'title_default'
22
- | 'title_xs'
23
- | 'title_s'
24
- | 'header_default'
25
- | 'header_xs'
26
- | 'header_s'
27
- | 'paragraph_default'
28
- | 'paragraph_bold'
29
- | 'paragraph_italic'
30
- | 'description_default'
31
- | 'description_xs'
32
- | 'description_s'
33
- | 'label_default'
34
- | 'label_xxs'
35
- | 'label_xs'
36
- | 'label_s'
37
- | 'action_default'
38
- | 'action_xxs'
39
- | 'action_xs'
40
- | 'action_s';
17
+ | 'headline_default_bold'
18
+ | 'header_m_bold'
19
+ | 'header_default_bold'
20
+ | 'header_s_semibold'
21
+ | 'header_xs_semibold'
22
+ | 'body_default_regular'
23
+ | 'body_regularstrikethrought'
24
+ | 'description_default_regular'
25
+ | 'description_default_regularstrikethrought'
26
+ | 'description_xs_regular'
27
+ | 'description_xs_regularstrikethrought'
28
+ | 'label_default_medium'
29
+ | 'label_s_medium'
30
+ | 'label_xs_medium'
31
+ | 'action_default_bold'
32
+ | 'action_s_bold'
33
+ | 'action_xs_bold'
34
+ | 'action_xxs_bold';
package/Title/index.tsx CHANGED
@@ -39,7 +39,7 @@ const Title: FC<TitleProps> = ({
39
39
  const renderAction = () => {
40
40
  return !!actionTitle && titleFlex ? (
41
41
  <TouchableOpacity onPress={onPressAction}>
42
- <Text typography={'action_s'} color={theme.colors.primary}>
42
+ <Text typography={'action_s_bold'} color={theme.colors.primary}>
43
43
  {actionTitle}
44
44
  </Text>
45
45
  </TouchableOpacity>
@@ -116,7 +116,7 @@ const Title: FC<TitleProps> = ({
116
116
  {!!description && type !== 'screen' && (
117
117
  <Text
118
118
  numberOfLines={1}
119
- typography={'description_s'}
119
+ typography={'description_default_regular'}
120
120
  color={theme.colors.text.secondary}>
121
121
  {description}
122
122
  </Text>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.81.43",
3
+ "version": "0.88.1",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {
package/verify.js CHANGED
@@ -27,8 +27,9 @@ try {
27
27
  }
28
28
 
29
29
  if (
30
- miniInfo?.name !== '@momo-platform/momo-core' &&
31
- miniInfo?.resolutions?.['@momo-platform/momo-core'] !== packageInfo?.version
30
+ miniInfo?.dependencies?.['@momo-platform/momo-core'] &&
31
+ miniInfo?.dependencies?.['@momo-platform/momo-core'] !==
32
+ packageInfo?.version
32
33
  ) {
33
34
  console.error(
34
35
  `Package ${packageInfo.name} version: ${packageInfo.version} require install resolutions @momo-platform/momo-core ${packageInfo.version}`,