@momo-kits/foundation 0.81.5 → 0.81.7-beta.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.
@@ -1,14 +1,13 @@
1
1
  import React, {Fragment, useContext, useEffect, useState} from 'react';
2
2
  import {
3
3
  Animated,
4
+ BackHandler,
4
5
  DeviceEventEmitter,
5
- Platform,
6
6
  StatusBar,
7
7
  StyleSheet,
8
8
  TouchableOpacity,
9
9
  View,
10
10
  } from 'react-native';
11
- import {TouchableOpacity as TouchableGesture} from 'react-native-gesture-handler';
12
11
  import {ApplicationContext} from './index';
13
12
  import {Colors, Radius, Spacing, Styles} from '../Consts';
14
13
  import {Image} from '../Image';
@@ -24,9 +23,6 @@ import {scaleSize, Text} from '../Text';
24
23
  import {Icon} from '../Icon';
25
24
  import {PopupNotify} from '../Popup';
26
25
 
27
- const Touchable =
28
- Platform.OS === 'android' ? TouchableGesture : TouchableOpacity;
29
-
30
26
  const styles = StyleSheet.create({
31
27
  navigationButton: {
32
28
  height: 28,
@@ -106,7 +102,7 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
106
102
  }
107
103
 
108
104
  return (
109
- <Touchable
105
+ <TouchableOpacity
110
106
  accessibilityLabel={`NavigationButton/${accessibilityLabel}`}
111
107
  style={[
112
108
  styles.navigationButton,
@@ -121,7 +117,7 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
121
117
  color={tintColor ?? theme.colors.text.default}
122
118
  size={20}
123
119
  />
124
- </Touchable>
120
+ </TouchableOpacity>
125
121
  );
126
122
  };
127
123
 
@@ -154,8 +150,29 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
154
150
  accessibilityLabel = '',
155
151
  }) => {
156
152
  const {navigator} = useContext(ApplicationContext);
153
+
154
+ useEffect(() => {
155
+ const backHandler = BackHandler.addEventListener(
156
+ 'hardwareBackPress',
157
+ goBack,
158
+ );
159
+
160
+ return () => backHandler.remove();
161
+ }, []);
162
+
157
163
  const goBack = () => {
158
164
  const canGoBack = navigator?.ref.current?.canGoBack();
165
+ const currentRoute = navigator?.ref?.current.getCurrentRoute();
166
+
167
+ if (navigator?.trackingInfo) {
168
+ navigator?.maxApi?.trackEvent('service_icon_clicked', {
169
+ ...navigator?.trackingInfo,
170
+ screen_name: currentRoute?.params?.screen?.name ?? currentRoute?.name,
171
+ trigger_id: '111154000000000000',
172
+ icon_name: 'back',
173
+ });
174
+ }
175
+
159
176
  if (canGoBack) {
160
177
  if (preventBack) {
161
178
  navigator?.showModal({
@@ -181,6 +198,7 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
181
198
  DeviceEventEmitter.emit('dismiss', {requestId});
182
199
  }
183
200
  onPressLeftHeader?.();
201
+ return true;
184
202
  };
185
203
 
186
204
  return (
@@ -313,9 +331,25 @@ const HeaderToolkitAction: React.FC<any> = ({tintColor}) => {
313
331
  }
314
332
 
315
333
  useEffect(() => {
316
- navigator?.getToolkit().then((toolConfig: any) => {
317
- setToolConfig(toolConfig);
318
- });
334
+ if (navigator?.toolkitConfig) {
335
+ setToolConfig(navigator?.toolkitConfig);
336
+ } else {
337
+ navigator?.requestApi('getToolkit', [undefined], (result: boolean) => {
338
+ if (result) {
339
+ navigator?.requestApi(
340
+ 'getToolkitConfig',
341
+ [undefined],
342
+ (config: any) => {
343
+ navigator.toolkitConfig = {
344
+ ...config?.utilityToolConfig,
345
+ appCode: config?.appCode,
346
+ };
347
+ setToolConfig(navigator?.toolkitConfig);
348
+ },
349
+ );
350
+ }
351
+ });
352
+ }
319
353
  }, []);
320
354
 
321
355
  useEffect(() => {
@@ -397,17 +431,21 @@ const HeaderToolkitAction: React.FC<any> = ({tintColor}) => {
397
431
  borderWidth: backgroundColor ? 0.5 : 0,
398
432
  },
399
433
  ]}>
400
- <Touchable accessibilityLabel={'Toolkit/More'} onPress={onMore}>
434
+ <TouchableOpacity
435
+ accessibilityLabel={'Toolkit/More'}
436
+ onPress={onMore}>
401
437
  <Icon color={tintColor} source="navigation_more_horiz" size={20} />
402
- </Touchable>
438
+ </TouchableOpacity>
403
439
  <View style={[styles.divider, {backgroundColor: tintColor}]} />
404
- <Touchable accessibilityLabel={`Toolkit/Close`} onPress={onClose}>
440
+ <TouchableOpacity
441
+ accessibilityLabel={`Toolkit/Close`}
442
+ onPress={onClose}>
405
443
  <Icon
406
444
  color={tintColor}
407
445
  source="16_navigation_close_circle"
408
446
  size={20}
409
447
  />
410
- </Touchable>
448
+ </TouchableOpacity>
411
449
  </View>
412
450
  </View>
413
451
  );
@@ -26,6 +26,9 @@ import {
26
26
  import {HeaderBackground, HeaderLeft, HeaderTitle} from './Components';
27
27
 
28
28
  const ModalScreen: React.FC<any> = props => {
29
+ /**
30
+ * dismiss callback when modal | bottom sheet dismissed
31
+ */
29
32
  useEffect(() => {
30
33
  return () => {
31
34
  props.route.params?.onDismiss?.();
@@ -40,7 +43,7 @@ const ModalScreen: React.FC<any> = props => {
40
43
 
41
44
  const Modal: React.FC<ModalParams> = props => {
42
45
  const {theme, navigator} = useContext(ApplicationContext);
43
- const {screen, barrierDismissible}: ModalParams = props.route.params;
46
+ const {screen, barrierDismissible, modalName} = props.route.params;
44
47
  const Component = useRef(screen).current;
45
48
  const navigation = new Navigation(props.navigation, theme);
46
49
  const params = {
@@ -50,6 +53,42 @@ const Modal: React.FC<ModalParams> = props => {
50
53
 
51
54
  delete params.screen;
52
55
 
56
+ /**
57
+ * tracking
58
+ */
59
+ useEffect(() => {
60
+ if (navigator?.trackingInfo) {
61
+ const TRIGGER_ID = '111012100000000000';
62
+ const navigationRoutes = props.navigation.getState()?.routes || [];
63
+ const routesLength = navigationRoutes.length;
64
+ let screen_name = navigationRoutes?.[0]?.params?.screen?.name;
65
+ if (routesLength > 1) {
66
+ screen_name = navigationRoutes[routesLength - 2]?.params?.screen?.name;
67
+ }
68
+ const error_code = (screen as Function)?.()?.props?.information;
69
+ navigator?.maxApi?.trackEvent('service_component_displayed', {
70
+ ...navigator?.trackingInfo,
71
+ screen_name,
72
+ trigger_id: '111012100000000000',
73
+ component_type: 'popup',
74
+ component_name: modalName,
75
+ error_code,
76
+ });
77
+
78
+ return () => {
79
+ navigator?.maxApi?.trackEvent('service_icon_clicked', {
80
+ ...navigator?.trackingInfo,
81
+ screen_name,
82
+ trigger_id: '111154100000000001',
83
+ component_type: 'popup',
84
+ component_name: modalName,
85
+ error_code,
86
+ icon_name: 'close',
87
+ });
88
+ };
89
+ }
90
+ }, []);
91
+
53
92
  const onDismiss = () => {
54
93
  if (barrierDismissible) {
55
94
  return;
@@ -160,7 +199,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
160
199
  navigator?.pop();
161
200
  }
162
201
  }}
163
- bottomInset={bottomInset}
202
+ bottomInset={Platform.OS === 'ios' ? bottomInset : 0}
164
203
  handleComponent={null}
165
204
  backdropComponent={backdropComponent}>
166
205
  <BottomSheetView accessibilityLabel={'BottomSheet'}>
@@ -181,6 +220,8 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
181
220
  />
182
221
  </View>
183
222
  <NavigationContainer
223
+ trackingInfo={navigator?.trackingInfo}
224
+ maxApi={navigator?.maxApi}
184
225
  theme={{
185
226
  ...theme,
186
227
  assets: {...theme.assets, headerBackground: undefined},
@@ -223,7 +264,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
223
264
  icon="24_navigation_close"
224
265
  backgroundColor="transparent"
225
266
  useBorder={false}
226
- onPress={bottomSheetRef.current?.dismiss}
267
+ onPress={() => bottomSheetRef.current?.dismiss()}
227
268
  accessibilityLabel={'BottomSheet/Close'}
228
269
  />
229
270
  </HeaderRightAction>
@@ -14,6 +14,10 @@ class Navigation {
14
14
  this.theme = theme;
15
15
  }
16
16
 
17
+ /**
18
+ * navigation options will be remove if used
19
+ * @param params
20
+ */
17
21
  private filterParams = (params: NavigationOptions) => {
18
22
  if (params.headerRight) {
19
23
  const headerRight = params.headerRight?.({}) as React.ReactElement;
@@ -27,6 +31,10 @@ class Navigation {
27
31
  return params;
28
32
  };
29
33
 
34
+ /**
35
+ * navigation setOptions support props NavigationOptions base on react-navigation options
36
+ * @param params
37
+ */
30
38
  setOptions = (params: NavigationOptions) => {
31
39
  if (__DEV__) {
32
40
  params = this.filterParams(params);
@@ -23,12 +23,16 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
23
23
  options,
24
24
  maxApi,
25
25
  localization,
26
+ trackingInfo,
26
27
  }) => {
27
28
  const navigationRef = React.useRef<NavigationContainerRef>(null);
28
29
  const navigator = useRef(new Navigator(navigationRef));
29
30
  const [showGrid, setShowGrid] = useState(false);
30
31
  const [language, setLanguage] = useState<'vi' | 'en'>('vi');
31
32
 
33
+ /**
34
+ * engine only shake to enable grid view
35
+ */
32
36
  useEffect(() => {
33
37
  const subscription = DeviceEventEmitter.addListener(
34
38
  'onChangeGrid',
@@ -37,10 +41,13 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
37
41
  },
38
42
  );
39
43
  return () => {
40
- subscription.remove();
44
+ subscription?.remove?.();
41
45
  };
42
46
  }, []);
43
47
 
48
+ /**
49
+ * handle mini language & listen change
50
+ */
44
51
  useEffect(() => {
45
52
  maxApi?.getLanguage?.((lang: 'vi' | 'en') => {
46
53
  setLanguage(lang);
@@ -53,8 +60,16 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
53
60
  };
54
61
  }, []);
55
62
 
63
+ /**
64
+ * inject data for navigator
65
+ */
56
66
  navigator.current.maxApi = maxApi;
67
+ navigator.current.trackingInfo = trackingInfo;
57
68
 
69
+ /**
70
+ * translate
71
+ * @param key
72
+ */
58
73
  const translate = (key: string) => {
59
74
  const mergedLocalization: LocalizationObject = {
60
75
  vi: {...localization?.vi, ...kitLocalization.vi},
@@ -4,37 +4,62 @@ import {
4
4
  HeaderToolkitProps,
5
5
  ModalParams,
6
6
  ScreenParams,
7
+ TrackingInfo,
7
8
  } from './types';
8
9
 
9
10
  class Navigator {
10
11
  ref?: any;
11
12
  toolkitConfig?: HeaderToolkitProps;
12
13
  maxApi?: any;
14
+ trackingInfo?: TrackingInfo;
13
15
 
14
16
  constructor(navigation: any) {
15
17
  this.ref = navigation;
16
18
  }
17
19
 
20
+ /**
21
+ * push new stack screen
22
+ * @param params
23
+ */
18
24
  push = (params: ScreenParams) => {
19
25
  this.ref.current.dispatch(StackActions.push('Stack', params));
20
26
  };
21
27
 
28
+ /**
29
+ * replace current screen with new screen
30
+ * @param params
31
+ */
22
32
  replace = (params: ScreenParams) => {
23
33
  this.ref.current.dispatch(StackActions.replace('Stack', params));
24
34
  };
25
-
35
+ /**
36
+ * pop to dismiss a screen
37
+ * @param count
38
+ */
26
39
  pop = (count?: number) => {
27
40
  this.ref.current.dispatch(StackActions.pop(count ?? 1));
28
41
  };
29
42
 
43
+ /**
44
+ * present a new screen, show from bottom iOS
45
+ * @param params
46
+ */
30
47
  present = (params: ScreenParams) => {
31
48
  this.ref.current.dispatch(StackActions.push('Dialog', params));
32
49
  };
33
50
 
51
+ /**
52
+ * show a modal popup
53
+ * @param params
54
+ */
34
55
  showModal = (params: ModalParams) => {
35
56
  this.ref.current.dispatch(StackActions.push('Modal', params));
36
57
  };
37
58
 
59
+ /**
60
+ * show a bottom sheet
61
+ * @param params
62
+ */
38
63
  showBottomSheet = (params: BottomSheetParams) => {
39
64
  this.ref.current.dispatch(
40
65
  StackActions.push('Modal', {
@@ -44,10 +69,17 @@ class Navigator {
44
69
  );
45
70
  };
46
71
 
72
+ /**
73
+ * pop all screen route
74
+ */
47
75
  popToTop = () => {
48
76
  this.ref.current.dispatch(StackActions.popToTop());
49
77
  };
50
78
 
79
+ /**
80
+ * reset a navigation flow with new screen
81
+ * @param params
82
+ */
51
83
  reset = (params: ScreenParams) => {
52
84
  this.ref.current.dispatch(
53
85
  CommonActions.reset({
@@ -63,36 +95,17 @@ class Navigator {
63
95
  );
64
96
  };
65
97
 
98
+ /**
99
+ * request max api for mini app
100
+ * @param func
101
+ * @param args
102
+ * @param callback
103
+ */
66
104
  requestApi = (func: any, args: any = [], callback: any) => {
67
105
  if (this.maxApi) {
68
106
  this.maxApi[func]?.(...args, callback);
69
- } else {
70
- const instance: any = global;
71
- instance?.miniAppApi?.dispatch?.(func, ...args, callback);
72
107
  }
73
108
  };
74
-
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
- });
95
- };
96
109
  }
97
110
 
98
111
  export default Navigator;
@@ -1,4 +1,4 @@
1
- import React, {useContext, useLayoutEffect} from 'react';
1
+ import React, {useContext, useEffect, useLayoutEffect} from 'react';
2
2
  import {ScreenParams} from './types';
3
3
  import Navigation from './Navigation';
4
4
  import {ApplicationContext} from './index';
@@ -6,7 +6,7 @@ import {GridSystem} from '../Layout';
6
6
 
7
7
  const StackScreen: React.FC<ScreenParams> = props => {
8
8
  const {screen: Component, options}: ScreenParams = props.route.params;
9
- const {theme, showGrid} = useContext(ApplicationContext);
9
+ const {theme, showGrid, navigator} = useContext(ApplicationContext);
10
10
  const navigation = new Navigation(props.navigation, theme);
11
11
 
12
12
  const params = {
@@ -16,12 +16,36 @@ const StackScreen: React.FC<ScreenParams> = props => {
16
16
 
17
17
  delete params.screen;
18
18
 
19
+ /**
20
+ * set options for screen
21
+ */
19
22
  useLayoutEffect(() => {
20
23
  if (options) {
21
24
  navigation.setOptions(options);
22
25
  }
23
26
  }, [options]);
24
27
 
28
+ /**
29
+ * tracking for screen
30
+ */
31
+ useEffect(() => {
32
+ if (navigator?.trackingInfo) {
33
+ const navigationRoutes = props.navigation.getState()?.routes || [];
34
+ const routesLength = navigationRoutes.length;
35
+ let pre_screen_name = navigationRoutes?.[0]?.params?.screen?.name;
36
+ if (routesLength > 1) {
37
+ pre_screen_name =
38
+ navigationRoutes[routesLength - 2]?.params?.screen?.name;
39
+ }
40
+ navigator?.maxApi?.trackEvent('service_frame_displayed', {
41
+ ...navigator?.trackingInfo,
42
+ screen_name: Component.name,
43
+ pre_screen_name,
44
+ trigger_id: '111378000000000000',
45
+ });
46
+ }
47
+ }, []);
48
+
25
49
  return (
26
50
  <>
27
51
  <Component {...params} />
@@ -79,12 +79,20 @@ export type LocalizationObject = {
79
79
  };
80
80
  };
81
81
 
82
+ export type TrackingInfo = {
83
+ [key: string]: any;
84
+ feature_code: string;
85
+ app_id: string;
86
+ miniapp_version: number;
87
+ };
88
+
82
89
  export type NavigationContainerProps = {
83
90
  screen: Screen;
84
91
  options?: NavigationOptions;
85
92
  theme: Theme;
86
- maxApi?: any;
93
+ maxApi: any;
87
94
  localization?: LocalizationObject;
95
+ trackingInfo?: TrackingInfo;
88
96
  };
89
97
 
90
98
  export type NavigationScreenProps = {
@@ -97,10 +105,12 @@ export type ScreenParams = {
97
105
  [key: string]: any;
98
106
  screen: Screen;
99
107
  options?: NavigationOptions;
108
+ tracking?: any;
100
109
  };
101
110
 
102
111
  export interface ModalParams extends ScreenParams {
103
112
  [key: string]: any;
113
+ modalName?: string;
104
114
  onDismiss?: () => void;
105
115
  barrierDismissible?: boolean;
106
116
  }
@@ -125,9 +135,7 @@ export interface NavigationOptions extends StackNavigationOptions {
125
135
  onPressLeftHeader?: () => void;
126
136
  surface?: boolean;
127
137
  hiddenBack?: boolean;
128
- headerTitleAlign?: 'left' | 'center';
129
138
  customTitle?: TitleCustomProps;
130
- animatedValue?: Animated.Value;
131
139
  }
132
140
 
133
141
  export interface HeaderBackProps extends NavigationButtonProps {
@@ -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
 
@@ -103,7 +103,7 @@ const InputOTP: FC<InputOTPProps> = ({
103
103
  };
104
104
 
105
105
  const renderInputs = (length: number) => {
106
- const TextInputs = [];
106
+ const TextInputs: React.ReactNode[] = [];
107
107
  for (let i = 0; i < length; i++) {
108
108
  TextInputs.push(
109
109
  <View>
package/Layout/Card.tsx CHANGED
@@ -145,6 +145,7 @@ const Card: React.FC<CardProps> = ({
145
145
  accessibilityLabel={`Card`}
146
146
  style={[
147
147
  style,
148
+ styles.protectedStyle,
148
149
  styles.card,
149
150
  {
150
151
  width: widthSection,
package/Layout/Item.tsx CHANGED
@@ -5,7 +5,7 @@ import {GridContext} from './index';
5
5
  import {ApplicationContext} from '../Application';
6
6
  import styles from './styles';
7
7
 
8
- type SpanNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
8
+ export type SpanNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
9
9
 
10
10
  export interface ItemProps extends ViewProps {
11
11
  /**
@@ -1,39 +1,40 @@
1
- import React, {FC, ReactElement, useContext} from 'react';
1
+ import React, {FC, useContext} from 'react';
2
2
  import {FlatList, FlatListProps, View} from 'react-native';
3
- import Item from './Item';
3
+ import Item, {SpanNumber} from './Item';
4
4
  import {GridContext} from './index';
5
5
  import styles from './styles';
6
6
 
7
- const ItemList: FC<FlatListProps<any>> = ({
7
+ export interface ItemListProps extends FlatListProps<any> {
8
+ /**
9
+ * Require key support number columns change grid system
10
+ */
11
+
12
+ key: string;
13
+ /**
14
+ * Represents the width of the Card component in terms of span numbers (1-12).
15
+ */
16
+ widthSpan?: SpanNumber;
17
+ }
18
+
19
+ const ItemList: FC<ItemListProps> = ({
20
+ key,
8
21
  renderItem,
9
- numColumns = 1,
22
+ widthSpan,
10
23
  style,
11
24
  contentContainerStyle,
12
25
  ...props
13
26
  }) => {
14
- const {gutterSize} = useContext(GridContext);
15
-
16
- const _renderItem = (info: any) => {
17
- const {item, index, separators} = info;
18
-
19
- const children = renderItem?.({
20
- item,
21
- index,
22
- separators,
23
- }) as ReactElement;
24
-
25
- if (children?.type !== Item) {
26
- console.warn('Wrong children type for this component, expected are Item');
27
+ const {gutterSize, numberOfColumns} = useContext(GridContext);
28
+ const widthItem = (widthSpan ?? numberOfColumns) as SpanNumber;
29
+ const numColumns = Math.floor(numberOfColumns / widthItem);
30
+ const indexBegin = props?.data?.map((_i, index) => index * numColumns);
31
+ const _renderItem = (item: any) => {
32
+ if (indexBegin?.includes(item?.index)) {
33
+ return <Item widthSpan={widthItem}>{renderItem?.(item)}</Item>;
27
34
  }
28
-
29
35
  return (
30
- <View
31
- style={
32
- numColumns > 1 && {
33
- marginRight: gutterSize,
34
- }
35
- }>
36
- {children}
36
+ <View style={{paddingLeft: gutterSize}}>
37
+ <Item widthSpan={widthItem}>{renderItem?.(item)}</Item>
37
38
  </View>
38
39
  );
39
40
  };
@@ -41,6 +42,7 @@ const ItemList: FC<FlatListProps<any>> = ({
41
42
  return (
42
43
  <FlatList
43
44
  {...props}
45
+ key={`${key ?? 'ItemList'}${numColumns}}`}
44
46
  numColumns={numColumns}
45
47
  renderItem={_renderItem}
46
48
  horizontal={false}
@@ -0,0 +1,45 @@
1
+ import React, {FC, useContext} from 'react';
2
+ import {SectionList, SectionListProps, View} from 'react-native';
3
+ import Item, {SpanNumber} from './Item';
4
+ import {GridContext} from './index';
5
+ import styles from './styles';
6
+
7
+ export interface ItemSectionListProps extends SectionListProps<any> {
8
+ /**
9
+ * Require key support number columns change grid system
10
+ */
11
+
12
+ key: string;
13
+ /**
14
+ * Represents the width of the Card component in terms of span numbers (1-12).
15
+ */
16
+ widthSpan?: SpanNumber;
17
+ }
18
+
19
+ const ItemSectionList: FC<ItemSectionListProps> = ({
20
+ key,
21
+ renderItem,
22
+ widthSpan,
23
+ style,
24
+ contentContainerStyle,
25
+ ...props
26
+ }) => {
27
+ const {gutterSize, numberOfColumns} = useContext(GridContext);
28
+ const widthItem = (widthSpan ?? numberOfColumns) as SpanNumber;
29
+ const _renderItem = (item: any) => {
30
+ return <Item widthSpan={widthItem}>{renderItem?.(item)}</Item>;
31
+ };
32
+
33
+ return (
34
+ <SectionList
35
+ {...props}
36
+ renderItem={_renderItem}
37
+ horizontal={false}
38
+ ItemSeparatorComponent={() => <View style={{height: gutterSize}} />}
39
+ style={[style, styles.protectedStyle]}
40
+ contentContainerStyle={[contentContainerStyle, styles.protectedStyle]}
41
+ />
42
+ );
43
+ };
44
+
45
+ export default ItemSectionList;
@@ -22,11 +22,6 @@ export interface SectionProps extends ViewProps {
22
22
  */
23
23
  useMargin?: boolean;
24
24
 
25
- /**
26
- * Optional. Background color for the Section component.
27
- */
28
- backgroundColor?: string;
29
-
30
25
  /**
31
26
  * Optional. Background image for the Section component.
32
27
  */
@@ -36,8 +31,8 @@ export interface SectionProps extends ViewProps {
36
31
  const Section: React.FC<SectionProps> = ({
37
32
  children,
38
33
  useMargin = true,
39
- backgroundColor,
40
34
  backgroundImage,
35
+ style,
41
36
  }) => {
42
37
  const {showGrid} = useContext(ApplicationContext);
43
38
  const {numberOfColumns} = useGridSystem();
@@ -156,13 +151,16 @@ const Section: React.FC<SectionProps> = ({
156
151
  }}>
157
152
  <View
158
153
  accessibilityLabel={`Section`}
159
- style={{
160
- width: widthSection,
161
- marginHorizontal: gridContext.margin,
162
- flexDirection: 'row',
163
- flexWrap: 'wrap',
164
- backgroundColor: backgroundColor,
165
- }}>
154
+ style={[
155
+ style,
156
+ styles.protectedStyle,
157
+ {
158
+ width: widthSection,
159
+ marginHorizontal: gridContext.margin,
160
+ flexDirection: 'row',
161
+ flexWrap: 'wrap',
162
+ },
163
+ ]}>
166
164
  {!!backgroundImage && (
167
165
  <Image
168
166
  source={{uri: backgroundImage}}
package/Layout/styles.ts CHANGED
@@ -45,19 +45,7 @@ export default StyleSheet.create({
45
45
  flexDirection: 'row',
46
46
  flexWrap: 'wrap',
47
47
  borderRadius: Radius.M,
48
- paddingTop: undefined,
49
- paddingBottom: undefined,
50
- paddingLeft: undefined,
51
- paddingRight: undefined,
52
- paddingVertical: undefined,
53
- paddingHorizontal: undefined,
54
48
  padding: 12,
55
- margin: undefined,
56
- marginTop: undefined,
57
- marginBottom: undefined,
58
- marginLeft: undefined,
59
- marginRight: undefined,
60
- marginVertical: undefined,
61
49
  },
62
50
  item: {
63
51
  overflow: 'hidden',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.81.5",
3
+ "version": "0.81.7-beta.1",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {
@@ -10,7 +10,7 @@
10
10
  "@momo-kits/foundation"
11
11
  ],
12
12
  "dependencies": {
13
- "@gorhom/bottom-sheet": "2.4.1",
13
+ "@gorhom/bottom-sheet": "git+https://gitlab.com/dung.huynh1/bottom-sheet.git#main",
14
14
  "react-native-safe-area-context": "3.1.4",
15
15
  "react-native-linear-gradient": "2.5.6",
16
16
  "react-native-gesture-handler": "1.10.3",
@@ -38,6 +38,7 @@
38
38
  "metro-react-native-babel-preset": "^0.64.0",
39
39
  "react-test-renderer": "17.0.1",
40
40
  "typescript": "^4.0.3",
41
+ "@momo-platform/versions": "4.1.11",
41
42
  "react-scanner": "^1.1.0"
42
43
  },
43
44
  "author": "@momo-kits/foundation",
package/tsconfig.json CHANGED
@@ -20,6 +20,5 @@
20
20
  "skipLibCheck": true,
21
21
  "strict": true,
22
22
  "target": "esnext",
23
- "verbatimModuleSyntax": false
24
23
  }
25
24
  }