@momo-kits/foundation 0.75.1-beta.3 → 0.75.1-beta.7

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.
package/Button/index.tsx CHANGED
@@ -13,6 +13,9 @@ import styles from './styles';
13
13
  import {Icon} from '../Icon';
14
14
 
15
15
  export interface ButtonProps extends TouchableOpacityProps {
16
+ /**
17
+ * Defines the visual style of the button.
18
+ */
16
19
  type?:
17
20
  | 'primary'
18
21
  | 'secondary'
@@ -21,12 +24,40 @@ export interface ButtonProps extends TouchableOpacityProps {
21
24
  | 'danger'
22
25
  | 'text'
23
26
  | 'disabled';
27
+
28
+ /**
29
+ * Defines the size of the button.
30
+ */
24
31
  size?: 'large' | 'medium' | 'small';
32
+
33
+ /**
34
+ * If true, the button will take the full width of its container.
35
+ */
25
36
  full?: boolean;
37
+
38
+ /**
39
+ * Specifies the name of the icon that should be placed on the right side of the button.
40
+ */
26
41
  iconRight?: string;
42
+
43
+ /**
44
+ * Specifies the name of the icon that should be placed on the left side of the button.
45
+ */
27
46
  iconLeft?: string;
47
+
48
+ /**
49
+ * Represents the text that will be displayed on the button.
50
+ */
28
51
  title: string;
52
+
53
+ /**
54
+ * If true, the icon of button will use the tint color provided by its container.
55
+ */
29
56
  useTintColor?: boolean;
57
+
58
+ /**
59
+ * A callback function that is called when the button is pressed.
60
+ */
30
61
  onPress: () => void;
31
62
  }
32
63
 
package/CheckBox/types.ts CHANGED
@@ -1,10 +1,38 @@
1
1
  import {ViewStyle} from 'react-native';
2
2
 
3
3
  export type CheckBoxProps = {
4
+ /**
5
+ * Represents whether the CheckBox is currently checked (`true`) or unchecked (`false`).
6
+ */
4
7
  value: boolean;
8
+
9
+ /**
10
+ * Optional. If `true`, the user won't be able to interact with the CheckBox.
11
+ * Defaults to `false` if not provided.
12
+ */
5
13
  disabled?: boolean;
14
+
15
+ /**
16
+ * Optional. Represents the text label displayed next to the CheckBox.
17
+ */
6
18
  label?: string;
19
+
20
+ /**
21
+ * A callback function that is called when the value of the CheckBox changes.
22
+ * Receives the new value of the CheckBox as a parameter.
23
+ */
7
24
  onChange: (value: boolean) => void;
25
+
26
+ /**
27
+ * Optional. If `true`, the CheckBox will be in an indeterminate state,
28
+ * which is typically used to represent a "mixed" or "partial" selection state.
29
+ * Defaults to `false` if not provided.
30
+ */
8
31
  indeterminated?: boolean;
32
+
33
+ /**
34
+ * Optional. Used to apply custom styling to the CheckBox component.
35
+ * Accepts an object of style properties.
36
+ */
9
37
  style?: ViewStyle;
10
38
  };
package/Consts/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './colors+spacing+radius';
2
2
  export * from './theme';
3
3
  export * from './styles';
4
+ export const GRIDVIEW = false;
package/Icon/types.ts CHANGED
@@ -1,8 +1,27 @@
1
1
  import {ViewStyle} from 'react-native';
2
2
 
3
3
  export type IconProps = {
4
+ /**
5
+ * Represents the identifier or the path for the icon image source.
6
+ * It is a required property.
7
+ */
4
8
  source: string;
9
+
10
+ /**
11
+ * Optional. Represents the size of the icon.
12
+ * It can be used to set the width and height of the icon.
13
+ */
5
14
  size?: number;
15
+
16
+ /**
17
+ * Optional. Represents the color of the icon.
18
+ * It can be any valid color in @momo-kits/foundation.
19
+ */
6
20
  color?: string;
21
+
22
+ /**
23
+ * Optional. Used to apply custom styling to the Icon component.
24
+ * Accepts an object of style properties.
25
+ */
7
26
  style?: ViewStyle;
8
27
  };
@@ -11,8 +11,20 @@ import {Icon} from '../Icon';
11
11
  import styles from './styles';
12
12
 
13
13
  export interface IconButtonProps extends TouchableOpacityProps {
14
+ /**
15
+ * Represents the name or key of the icon to be displayed on the IconButton.
16
+ * It is a required property.
17
+ */
14
18
  icon: string;
19
+
20
+ /**
21
+ * Optional. Defines the visual style of the IconButton.
22
+ */
15
23
  type?: 'primary' | 'tonal' | 'secondary' | 'danger' | 'outline' | 'disabled';
24
+
25
+ /**
26
+ * Optional. Defines the size of the IconButton.
27
+ */
16
28
  size?: 'large' | 'small';
17
29
  }
18
30
 
package/Input/Input.tsx CHANGED
@@ -8,15 +8,10 @@ import {
8
8
  } from 'react-native';
9
9
  import {ApplicationContext} from '../Navigation';
10
10
  import styles from './styles';
11
- import {
12
- checkTyping,
13
- ErrorView,
14
- FloatingView,
15
- getBorderColor,
16
- getSizeStyle,
17
- } from './common';
11
+ import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
18
12
  import {InputProps} from './index';
19
13
  import {Icon} from '../Icon';
14
+ import {checkTyping} from './utils';
20
15
 
21
16
  const Input: FC<InputProps> = ({
22
17
  value,
@@ -33,12 +28,11 @@ const Input: FC<InputProps> = ({
33
28
  floatingIconColor,
34
29
  iconColor,
35
30
  required,
36
- defaultValue,
37
31
  ...props
38
32
  }) => {
39
33
  const {theme} = useContext(ApplicationContext);
40
34
  const [focused, setFocused] = useState(false);
41
- const [haveValue, setHaveValue] = useState(!!value || !!defaultValue);
35
+ const [haveValue, setHaveValue] = useState(!!value || !!props.defaultValue);
42
36
 
43
37
  const inputRef = useRef<any>(null);
44
38
 
@@ -11,7 +11,7 @@ import {ApplicationContext} from '../Navigation';
11
11
  import styles from './styles';
12
12
  import {Icon} from '../Icon';
13
13
  import {Text} from '../Text';
14
- import {checkTyping} from './common';
14
+ import {checkTyping} from './utils';
15
15
 
16
16
  const InputSearch: FC<InputSearchProps> = ({
17
17
  placeholder,
package/Input/common.tsx CHANGED
@@ -116,10 +116,3 @@ export const FloatingView: FC<FloatingViewProps> = ({
116
116
  }
117
117
  return null;
118
118
  };
119
-
120
- export const checkTyping = (text: string, value: boolean, setValue: any) => {
121
- let typing = text?.length > 0;
122
- if (typing != value) {
123
- setValue(typing);
124
- }
125
- };
package/Input/index.tsx CHANGED
@@ -5,14 +5,52 @@ import InputMoney from './InputMoney';
5
5
  import {TextInputProps} from 'react-native';
6
6
 
7
7
  export interface InputProps extends TextInputProps {
8
+ /**
9
+ * Optional. Defines the size of the Input component.
10
+ */
8
11
  size?: 'small' | 'large';
12
+
13
+ /**
14
+ * Optional. Represents the value for the floating title in the Input component.
15
+ */
9
16
  floatingValue?: string;
17
+
18
+ /**
19
+ * Optional. Represents the name or key of the floating icon to be displayed in the Input component.
20
+ */
10
21
  floatingIcon?: string;
22
+
23
+ /**
24
+ * Optional. Represents the error message to be displayed below the Input component when there is an error.
25
+ */
11
26
  errorMessage?: string;
27
+
28
+ /**
29
+ * Optional. Represents the name or key of the icon to be displayed in the Input component.
30
+ */
12
31
  icon?: string;
32
+
33
+ /**
34
+ * Optional. If `true`, the user won't be able to interact with the Input component.
35
+ * Defaults to `false` if not provided.
36
+ */
13
37
  disabled?: boolean;
38
+
39
+ /**
40
+ * Optional. Represents the color of the floating icon in the Input component.
41
+ */
14
42
  floatingIconColor?: string;
43
+
44
+ /**
45
+ * Optional. Represents the color of the icon in the Input component.
46
+ */
15
47
  iconColor?: string;
48
+
49
+ /**
50
+ * Optional. If `true`, the Input component is marked as required,
51
+ * indicating that the user must provide a value before submitting a form.
52
+ * Defaults to `false` if not provided.
53
+ */
16
54
  required?: boolean;
17
55
  }
18
56
 
@@ -27,12 +65,29 @@ type InputPropsOmitForSearch = Omit<
27
65
  type InputPropsWithoutPlaceholder = Omit<InputProps, 'placeholder'>;
28
66
 
29
67
  export interface InputTextAreaProps extends InputPropsWithoutSizeAndIcon {
68
+ /**
69
+ * Optional. Defines the height of the InputTextArea component.
70
+ * It can be used to set a specific height for the text area.
71
+ */
30
72
  height?: number;
31
73
  }
32
74
 
33
75
  export interface InputSearchProps extends InputPropsOmitForSearch {
76
+ /**
77
+ * Optional. Represents the text to be displayed on the search button within the InputSearch component.
78
+ */
34
79
  buttonText?: string;
80
+
81
+ /**
82
+ * Optional. If `true`, the text on the search button will be displayed.
83
+ * Defaults to `false` if not provided.
84
+ */
35
85
  showButtonText?: boolean;
86
+
87
+ /**
88
+ * Optional. If `true`, a border will be displayed around the InputSearch component.
89
+ * Defaults to `true` if not provided.
90
+ */
36
91
  showBorder?: boolean;
37
92
  }
38
93
 
package/Input/utils.ts CHANGED
@@ -59,5 +59,11 @@ const formatMoneyToNumber = (money: string, currencyUnit: string) => {
59
59
 
60
60
  return Number(money);
61
61
  };
62
+ const checkTyping = (text: string, value: boolean, setValue: any) => {
63
+ let typing = text?.length > 0;
64
+ if (typing != value) {
65
+ setValue(typing);
66
+ }
67
+ };
62
68
 
63
- export {formatMoneyToNumber, formatNumberToMoney};
69
+ export {formatMoneyToNumber, formatNumberToMoney, checkTyping};
package/Layout/Card.tsx CHANGED
@@ -3,6 +3,7 @@ import {View} from 'react-native';
3
3
 
4
4
  import {CardProps, GridContextProps} from './types';
5
5
  import {GridContext} from './index';
6
+ import {GRIDVIEW} from '../Consts';
6
7
 
7
8
  const Card: React.FC<CardProps> = ({
8
9
  widthSpan = 12,
@@ -72,7 +73,7 @@ const Card: React.FC<CardProps> = ({
72
73
  <GridContext.Provider value={gridContext}>
73
74
  {children}
74
75
  </GridContext.Provider>
75
- {__DEV__ && renderOverlay()}
76
+ {GRIDVIEW && renderOverlay()}
76
77
  </View>
77
78
  );
78
79
  };
@@ -4,6 +4,7 @@ import {validateChildren} from './utils';
4
4
  import Card from './Card';
5
5
  import {GridContextProps, SectionProps} from './types';
6
6
  import {GridContext} from './index';
7
+ import {GRIDVIEW} from '../Consts';
7
8
 
8
9
  const Section: React.FC<SectionProps> = ({children, useMargin = true}) => {
9
10
  const numberOfColumns = 12;
@@ -129,7 +130,7 @@ const Section: React.FC<SectionProps> = ({children, useMargin = true}) => {
129
130
  flexWrap: 'wrap',
130
131
  }}>
131
132
  {renderView(validateChildren(children, Card))}
132
- {__DEV__ && renderOverlay()}
133
+ {GRIDVIEW && renderOverlay()}
133
134
  </View>
134
135
  </GridContext.Provider>
135
136
  );
package/Layout/types.ts CHANGED
@@ -3,19 +3,59 @@ import {ViewProps} from 'react-native';
3
3
  type SpanNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
4
4
 
5
5
  export type GridContextProps = {
6
+ /**
7
+ * Represents the number of columns in the grid.
8
+ */
6
9
  numberOfColumns: number;
10
+
11
+ /**
12
+ * Represents the size of the gutter between grid items.
13
+ */
7
14
  gutterSize: number;
15
+
16
+ /**
17
+ * Optional. Represents the margin around the grid.
18
+ */
8
19
  margin?: number;
20
+
21
+ /**
22
+ * Represents the size (width or height) per span number.
23
+ */
9
24
  sizePerSpan: number;
25
+
26
+ /**
27
+ * A function that receives a span number and returns the calculated size for that span.
28
+ */
10
29
  getSizeSpan: (span: number) => number;
11
30
  };
12
31
  export interface SectionProps extends ViewProps {
32
+ /**
33
+ * Optional. If `true`, the Section component will be displayed in an expanded state.
34
+ * Defaults to `false` if not provided.
35
+ */
13
36
  expanded?: boolean;
37
+
38
+ /**
39
+ * Optional. If `true`, margin will be applied to the Section component.
40
+ * Defaults to `false` if not provided.
41
+ */
14
42
  useMargin?: boolean;
15
43
  }
16
44
 
17
45
  export interface CardProps extends ViewProps {
46
+ /**
47
+ * Represents the width of the Card component in terms of span numbers (1-12).
48
+ */
18
49
  widthSpan: SpanNumber;
50
+
51
+ /**
52
+ * Optional. Represents the height of the Card component in terms of span numbers (1-12).
53
+ */
19
54
  heightSpan?: SpanNumber;
55
+
56
+ /**
57
+ * Optional. If `true`, padding will be applied to the Card component.
58
+ * Defaults to `false` if not provided.
59
+ */
20
60
  usePadding?: boolean;
21
61
  }
@@ -13,11 +13,11 @@ import {Image} from '../Image';
13
13
  import {
14
14
  HeaderBackgroundProps,
15
15
  HeaderBackProps,
16
+ HeaderToolkitProps,
16
17
  TitleCustomProps,
17
18
  } from './types';
18
19
  import {Text} from '../Text';
19
20
  import {Icon} from '../Icon';
20
- import {requestApi} from './utils';
21
21
  import Observer from './Observer';
22
22
  import {PopupNotify} from '../Popup';
23
23
 
@@ -74,6 +74,7 @@ const styles = StyleSheet.create({
74
74
  });
75
75
 
76
76
  const HeaderTitle: React.FC<any> = props => {
77
+ const {theme} = useContext(ApplicationContext);
77
78
  const opacity = props.animatedValue?.interpolate({
78
79
  inputRange: [0, 200],
79
80
  outputRange: [0, 1],
@@ -83,12 +84,20 @@ const HeaderTitle: React.FC<any> = props => {
83
84
  <Animated.Text
84
85
  {...props}
85
86
  accessibilityLabel={`HeaderTitle/${props.children}`}
86
- style={[styles.title, {opacity, color: props.tintColor}]}
87
+ style={[
88
+ styles.title,
89
+ {fontFamily: `${theme.font}-Bold`, opacity, color: props.tintColor},
90
+ ]}
87
91
  />
88
92
  );
89
93
  };
90
94
 
91
- const HeaderLeft: React.FC<HeaderBackProps> = ({tintColor, preventBack}) => {
95
+ const HeaderLeft: React.FC<HeaderBackProps> = ({
96
+ tintColor,
97
+ preventBack,
98
+ useBorder,
99
+ backgroundColor,
100
+ }) => {
92
101
  const {navigator} = useContext(ApplicationContext);
93
102
  const goBack = () => {
94
103
  const canGoBack = navigator?.ref.current?.canGoBack();
@@ -125,6 +134,8 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({tintColor, preventBack}) => {
125
134
  tintColor={tintColor}
126
135
  onPress={goBack}
127
136
  accessibilityLabel={'Back'}
137
+ useBorder={useBorder}
138
+ backgroundColor={backgroundColor}
128
139
  />
129
140
  </View>
130
141
  );
@@ -137,9 +148,7 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
137
148
  }) => {
138
149
  const {theme} = useContext(ApplicationContext);
139
150
  let headerImage = theme.assets?.headerBackground;
140
- let borderBottomWidth = 0;
141
151
  if (image === null) {
142
- borderBottomWidth = 1;
143
152
  headerImage = undefined;
144
153
  }
145
154
  const opacity = animatedValue?.interpolate({
@@ -155,7 +164,7 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
155
164
  {
156
165
  backgroundColor: backgroundColor ?? theme.colors.background.default,
157
166
  overflow: 'hidden',
158
- borderBottomWidth: borderBottomWidth,
167
+ borderBottomWidth: headerImage ? 0 : 1,
159
168
  borderColor: theme.colors.border.default,
160
169
  opacity,
161
170
  },
@@ -207,12 +216,15 @@ const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
207
216
  console.warn(
208
217
  'element type of NavigationButton, Please migrate to use NavigationButton of kits.',
209
218
  );
219
+ return <View />;
210
220
  }
211
221
  };
212
222
  const renderAction = () => {
213
223
  if (Array.isArray(children)) {
214
224
  return children.map((child, index) => {
215
- validType(child);
225
+ if (__DEV__) {
226
+ validType(child);
227
+ }
216
228
  return (
217
229
  <React.Fragment key={index}>
218
230
  {React.cloneElement(child, {...restProps})}
@@ -227,62 +239,80 @@ const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
227
239
  return <View style={styles.headerRightButton}>{renderAction()}</View>;
228
240
  };
229
241
 
230
- const HeaderToolkitAction: React.FC<any> = ({tintColor, utilityToolConfig}) => {
231
- const {appCode, hidden, type, onAction} = utilityToolConfig ?? {};
232
- const {theme} = useContext(ApplicationContext);
233
- const [showUtility, setShowUtility] = useState(hidden === false);
242
+ const HeaderToolkitAction: React.FC<any> = ({tintColor}) => {
243
+ const {theme, navigator} = useContext(ApplicationContext);
244
+ const [toolConfig, setToolConfig] = useState<HeaderToolkitProps>();
245
+ const {appCode, hidden, type, onAction} = toolConfig ?? {};
234
246
 
235
247
  let backgroundColor;
236
248
  if (tintColor != Colors.black_01) {
237
249
  backgroundColor = theme.colors.background.surface;
238
250
  }
239
251
 
252
+ useEffect(() => {
253
+ navigator?.getToolkit().then(toolConfig => {
254
+ setToolConfig(toolConfig);
255
+ });
256
+ }, []);
257
+
240
258
  useEffect(() => {
241
259
  let addFavorite: any;
242
260
  let removeFavorite: any;
243
- if (appCode && type === 'addFavorite') {
261
+ if (appCode) {
244
262
  const addSchema = `observerToolkit_addFavorite_${appCode}`;
245
263
  const removeSchema = `observerToolkit_removeFavorite_${appCode}`;
246
- addFavorite = Observer?.getInstance(addSchema);
247
- removeFavorite = Observer?.getInstance(removeSchema);
248
-
249
- addFavorite?.attach((data: any) => {
250
- if (data?.status) {
251
- setShowUtility(false);
252
- }
253
- });
254
- removeFavorite?.attach((data: any) => {
255
- if (data?.status) {
256
- setShowUtility(true);
257
- }
258
- });
264
+ addFavorite = navigator?.requestApi(
265
+ 'observer',
266
+ [addSchema],
267
+ (data: any) => {
268
+ if (data?.status) {
269
+ setToolConfig({
270
+ ...(toolConfig as HeaderToolkitProps),
271
+ hidden: true,
272
+ });
273
+ }
274
+ },
275
+ );
276
+ addFavorite = navigator?.requestApi(
277
+ 'observer',
278
+ [removeSchema],
279
+ (data: any) => {
280
+ if (data?.status) {
281
+ setToolConfig({
282
+ ...(toolConfig as HeaderToolkitProps),
283
+ hidden: false,
284
+ });
285
+ }
286
+ },
287
+ );
259
288
  }
289
+
260
290
  return () => {
261
291
  addFavorite?.();
262
292
  removeFavorite?.();
263
293
  };
264
- }, []);
294
+ }, [appCode]);
265
295
 
266
296
  const onUtilityTool = () => {
267
297
  onAction?.('onUtilityTool');
268
- requestApi(type, [undefined], undefined);
298
+ navigator?.requestApi(type, undefined, undefined);
269
299
  };
270
300
 
271
301
  const onMore = () => {
272
302
  onAction?.('onMore');
273
- requestApi('showToolkit', [utilityToolConfig], undefined);
303
+ navigator?.requestApi('showToolkit', [toolConfig], undefined);
274
304
  };
275
305
 
276
306
  const onClose = () => {
277
307
  onAction?.('onClose');
278
- requestApi('dismiss', [], undefined);
308
+ navigator?.requestApi('dismiss', undefined, undefined);
279
309
  };
280
310
 
281
311
  const renderUtilityTool = () => {
282
- if (showUtility) {
312
+ if (toolConfig?.hidden === false) {
283
313
  return (
284
314
  <NavigationButton
285
- icon={type}
315
+ icon={type as string}
286
316
  tintColor={tintColor}
287
317
  onPress={onUtilityTool}
288
318
  />
@@ -290,33 +320,39 @@ const HeaderToolkitAction: React.FC<any> = ({tintColor, utilityToolConfig}) => {
290
320
  }
291
321
  };
292
322
 
293
- return (
294
- <View style={styles.headerRightButton}>
295
- {renderUtilityTool()}
296
- <View
297
- style={[
298
- styles.toolkitContainer,
299
- {
300
- backgroundColor: backgroundColor ?? '#00000066',
301
- borderWidth: backgroundColor ? 0.5 : 0,
302
- },
303
- ]}>
304
- <TouchableOpacity accessibilityLabel={'Toolkit/More'} onPress={onMore}>
305
- <Icon color={tintColor} source="navigation_more_horiz" size={20} />
306
- </TouchableOpacity>
307
- <View style={[styles.divider, {backgroundColor: tintColor}]} />
308
- <TouchableOpacity
309
- accessibilityLabel={'Toolkit/Close'}
310
- onPress={onClose}>
311
- <Icon
312
- color={tintColor}
313
- source="16_navigation_close_circle"
314
- size={20}
315
- />
316
- </TouchableOpacity>
323
+ if (toolConfig) {
324
+ return (
325
+ <View style={styles.headerRightButton}>
326
+ {renderUtilityTool()}
327
+ <View
328
+ style={[
329
+ styles.toolkitContainer,
330
+ {
331
+ backgroundColor: backgroundColor ?? '#00000066',
332
+ borderWidth: backgroundColor ? 0.5 : 0,
333
+ },
334
+ ]}>
335
+ <TouchableOpacity
336
+ accessibilityLabel={'Toolkit/More'}
337
+ onPress={onMore}>
338
+ <Icon color={tintColor} source="navigation_more_horiz" size={20} />
339
+ </TouchableOpacity>
340
+ <View style={[styles.divider, {backgroundColor: tintColor}]} />
341
+ <TouchableOpacity
342
+ accessibilityLabel={'Toolkit/Close'}
343
+ onPress={onClose}>
344
+ <Icon
345
+ color={tintColor}
346
+ source="16_navigation_close_circle"
347
+ size={20}
348
+ />
349
+ </TouchableOpacity>
350
+ </View>
317
351
  </View>
318
- </View>
319
- );
352
+ );
353
+ }
354
+
355
+ return <View />;
320
356
  };
321
357
 
322
358
  export {
@@ -18,6 +18,7 @@ import {
18
18
  NavigationButton,
19
19
  NavigationContainer,
20
20
  } from './index';
21
+ import {HeaderBackground, HeaderLeft} from './Components';
21
22
 
22
23
  const ModalScreen: React.FC<any> = props => {
23
24
  useEffect(() => {
@@ -114,7 +115,6 @@ const BottomSheet: React.FC<BottomSheetParams> = ({navigation, route}) => {
114
115
  if (options?.surface) {
115
116
  backgroundColor = theme.colors.background.surface;
116
117
  }
117
- const sheetTheme = {...theme, assets: undefined};
118
118
 
119
119
  return (
120
120
  <SafeAreaView style={Styles.flex}>
@@ -141,11 +141,30 @@ const BottomSheet: React.FC<BottomSheetParams> = ({navigation, route}) => {
141
141
  />
142
142
  </View>
143
143
  <NavigationContainer
144
- theme={sheetTheme}
144
+ theme={{
145
+ ...theme,
146
+ assets: {...theme.assets, headerBackground: undefined},
147
+ }}
145
148
  screen={props => <Component {...props} {...params} />}
146
149
  options={{
147
150
  ...options,
148
- ...{headerLeft: null, headerTransparent: false},
151
+ ...{
152
+ headerLeft: (props: any) => {
153
+ if (props.canGoBack) {
154
+ return (
155
+ <HeaderLeft
156
+ {...props}
157
+ useBorder={false}
158
+ backgroundColor="transparent"
159
+ />
160
+ );
161
+ }
162
+ },
163
+ headerBackground: () => (
164
+ <HeaderBackground backgroundColor={backgroundColor} />
165
+ ),
166
+ headerTransparent: false,
167
+ },
149
168
  headerTitleAlign: 'center',
150
169
  headerRight: props => (
151
170
  <HeaderRightAction>
@@ -2,6 +2,7 @@ import {NavigationProp} from '@react-navigation/native';
2
2
  import {NavigationOptions, Theme} from './types';
3
3
  import {HeaderRightAction} from './index';
4
4
  import {getOptions} from './utils';
5
+ import {HeaderToolkitAction} from './Components';
5
6
 
6
7
  class Navigation {
7
8
  instance: NavigationProp<any>;
@@ -15,9 +16,12 @@ class Navigation {
15
16
  verifyParams = (params: NavigationOptions) => {
16
17
  if (params.headerRight) {
17
18
  const headerRight = params.headerRight?.();
18
- if (headerRight.type !== HeaderRightAction) {
19
+ if (
20
+ headerRight?.type !== HeaderRightAction &&
21
+ headerRight?.type !== HeaderToolkitAction
22
+ ) {
19
23
  console.warn(
20
- 'headerRight not return element type of HeaderRightAction, Please migrate to use HeaderRightAction of kits.',
24
+ 'headerRight not return element type of HeaderRightAction | HeaderToolkitAction, Please migrate to use of kits.',
21
25
  );
22
26
  }
23
27
  }
@@ -29,7 +33,9 @@ class Navigation {
29
33
  };
30
34
 
31
35
  setOptions = (params: NavigationOptions) => {
32
- params = this.verifyParams(params);
36
+ if (__DEV__) {
37
+ params = this.verifyParams(params);
38
+ }
33
39
  params = getOptions(params, this.theme);
34
40
  this.instance.setOptions(params);
35
41
  };
@@ -11,7 +11,7 @@ import ModalScreen from './ModalScreen';
11
11
  import Navigator from './Navigator';
12
12
  import {getDialogOptions, getModalOptions, getStackOptions} from './utils';
13
13
  import {GridSystem} from '../Layout';
14
- import {defaultContext} from '../Consts';
14
+ import {defaultContext, GRIDVIEW} from '../Consts';
15
15
  import {NavigationContainerProps} from './types';
16
16
 
17
17
  const Stack = createStackNavigator();
@@ -21,15 +21,11 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
21
21
  screen,
22
22
  theme,
23
23
  options,
24
+ maxApi,
24
25
  }) => {
25
26
  const navigationRef = React.useRef<NavigationContainerRef>(null);
26
27
  const navigator = useRef(new Navigator(navigationRef));
27
-
28
- useEffect(() => {
29
- if (options) {
30
- navigationRef.current?.setParams({options: options});
31
- }
32
- }, []);
28
+ navigator.current.maxApi = maxApi;
33
29
 
34
30
  return (
35
31
  <SafeAreaProvider>
@@ -39,7 +35,6 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
39
35
  <ReactNavigationContainer
40
36
  theme={{
41
37
  ...theme,
42
- dark: false,
43
38
  colors: {
44
39
  ...theme.colors,
45
40
  background: theme.colors.background.default,
@@ -56,7 +51,7 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
56
51
  name="Stack"
57
52
  component={StackScreen}
58
53
  initialParams={{screen}}
59
- options={getStackOptions(theme)}
54
+ options={{...getStackOptions(theme), ...options}}
60
55
  />
61
56
  <Stack.Screen
62
57
  name="Dialog"
@@ -74,7 +69,7 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
74
69
  </ReactNavigationContainer>
75
70
  </ApplicationContext.Provider>
76
71
  </BottomSheetModalProvider>
77
- {__DEV__ && <GridSystem />}
72
+ {GRIDVIEW && <GridSystem />}
78
73
  </SafeAreaProvider>
79
74
  );
80
75
  };
@@ -1,10 +1,15 @@
1
1
  import {StackActions} from '@react-navigation/native';
2
- import {BottomSheetParams, ModalParams, ScreenParams} from './types';
3
- import {requestApi} from './utils';
2
+ import {
3
+ BottomSheetParams,
4
+ HeaderToolkitProps,
5
+ ModalParams,
6
+ ScreenParams,
7
+ } from './types';
4
8
 
5
9
  class Navigator {
6
10
  ref?: any;
7
- utilityToolConfig: any;
11
+ toolkitConfig?: HeaderToolkitProps;
12
+ maxApi?: any;
8
13
 
9
14
  constructor(navigation: any) {
10
15
  this.ref = navigation;
@@ -43,17 +48,28 @@ class Navigator {
43
48
  this.ref.current.dispatch(StackActions.popToTop());
44
49
  };
45
50
 
46
- getToolkit = async () => {
47
- if (this.utilityToolConfig) return this.utilityToolConfig;
51
+ requestApi = (func: any, args: any = [], callback: any) => {
52
+ if (this.maxApi) {
53
+ this.maxApi[func]?.(...args, callback);
54
+ } else {
55
+ const instance: any = global;
56
+ instance?.miniAppApi?.dispatch?.(func, ...args, callback);
57
+ }
58
+ };
59
+ getToolkit = async (): Promise<HeaderToolkitProps | undefined> => {
48
60
  return new Promise(resolve => {
49
- requestApi('getToolkit', [null], (result: any) => {
50
- if (result === true) {
51
- requestApi('getToolkitConfig', [null], (config: any) => {
52
- this.utilityToolConfig = {
61
+ if (this.toolkitConfig) {
62
+ resolve(this.toolkitConfig);
63
+ return;
64
+ }
65
+ this.requestApi('getToolkit', [undefined], (result: boolean) => {
66
+ if (result) {
67
+ this.requestApi('getToolkitConfig', [undefined], (config: any) => {
68
+ this.toolkitConfig = {
53
69
  ...config?.utilityToolConfig,
54
70
  appCode: config?.appCode,
55
71
  };
56
- resolve(this.utilityToolConfig);
72
+ resolve(this.toolkitConfig);
57
73
  });
58
74
  } else {
59
75
  resolve(undefined);
@@ -2,7 +2,6 @@ import React, {useContext, useEffect} from 'react';
2
2
  import {ScreenParams} from './types';
3
3
  import Navigation from './Navigation';
4
4
  import {ApplicationContext} from './NavigationContainer';
5
- import {HeaderToolkitAction} from './Components';
6
5
 
7
6
  const StackScreen: React.FC<any> = props => {
8
7
  const {route, navigation} = props;
@@ -17,18 +16,6 @@ const StackScreen: React.FC<any> = props => {
17
16
  delete params.screen;
18
17
 
19
18
  useEffect(() => {
20
- navigator?.getToolkit().then(utilityToolConfig => {
21
- if (utilityToolConfig) {
22
- params.navigation.setOptions({
23
- headerRight: (props: any) => (
24
- <HeaderToolkitAction
25
- {...props}
26
- utilityToolConfig={utilityToolConfig}
27
- />
28
- ),
29
- });
30
- }
31
- });
32
19
  if (options) {
33
20
  params.navigation.setOptions(options);
34
21
  }
@@ -67,6 +67,7 @@ export type NavigationContainerProps = {
67
67
  screen: React.ElementType;
68
68
  options?: NavigationOptions;
69
69
  theme: Theme;
70
+ maxApi?: any;
70
71
  };
71
72
 
72
73
  export interface ScreenContainerProps extends ViewProps {
@@ -115,10 +116,9 @@ export type NavigationOptions = {
115
116
  animatedValue?: Animated.Value;
116
117
  };
117
118
 
118
- export type HeaderBackProps = {
119
- tintColor?: string;
119
+ export interface HeaderBackProps extends NavigationButtonProps {
120
120
  preventBack?: PopupNotifyProps;
121
- };
121
+ }
122
122
 
123
123
  export type HeaderBackgroundProps = {
124
124
  image?: string | null;
@@ -136,6 +136,14 @@ export type TitleCustomProps = {
136
136
  content?: React.ReactNode;
137
137
  };
138
138
 
139
+ export type HeaderToolkitProps = {
140
+ [key: string]: any;
141
+ appCode: string;
142
+ hidden: boolean;
143
+ type: string;
144
+ onAction?: (action: string) => void;
145
+ };
146
+
139
147
  export type BottomTabItemProps = {
140
148
  label: string;
141
149
  icon: string;
@@ -3,41 +3,16 @@ import {
3
3
  StackNavigationOptions,
4
4
  TransitionPresets,
5
5
  } from '@react-navigation/stack';
6
- import {DeviceEventEmitter} from 'react-native';
7
6
  import {
8
7
  HeaderBackground,
9
8
  HeaderCustom,
10
9
  HeaderLeft,
11
10
  HeaderTitle,
11
+ HeaderToolkitAction,
12
12
  } from './Components';
13
13
  import {NavigationOptions, Theme} from './types';
14
14
  import {Colors} from '../Consts';
15
15
 
16
- const requestApi = (func: any, args: any = [], callback: any) => {
17
- const instance: any = global;
18
- if (instance?.miniAppApi?.dispatch) {
19
- instance?.miniAppApi?.dispatch?.(func, ...args, callback);
20
- } else {
21
- let listener: any;
22
- const responseId = new Date().getTime();
23
- const responseListener = `KIT_RESPONSE_MESSAGE_${responseId}`;
24
- const TIME_OUT = 5000;
25
- const timeout = setTimeout(() => {
26
- listener?.remove?.();
27
- }, TIME_OUT);
28
- listener = DeviceEventEmitter.addListener(responseListener, result => {
29
- listener?.remove?.();
30
- clearTimeout(timeout);
31
- callback?.(result);
32
- });
33
- DeviceEventEmitter.emit('KITS_REQUEST_MESSAGE', {
34
- func,
35
- args,
36
- responseListener,
37
- });
38
- }
39
- };
40
-
41
16
  const getTintColor = (theme: Theme): any => {
42
17
  if (theme.assets?.headerBackground) {
43
18
  return {
@@ -55,6 +30,7 @@ const getStackOptions = (theme: Theme): StackNavigationOptions => {
55
30
  headerTitle: HeaderTitle,
56
31
  headerBackground: HeaderBackground,
57
32
  headerLeft: (props: any) => <HeaderLeft {...props} />,
33
+ headerRight: (props: any) => <HeaderToolkitAction {...props} />,
58
34
  ...getTintColor(theme),
59
35
  };
60
36
  };
@@ -158,10 +134,4 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
158
134
  };
159
135
  };
160
136
 
161
- export {
162
- requestApi,
163
- getStackOptions,
164
- getDialogOptions,
165
- getModalOptions,
166
- getOptions,
167
- };
137
+ export {getStackOptions, getDialogOptions, getModalOptions, getOptions};
@@ -2,8 +2,23 @@ import {ScrollView, ScrollViewProps, ViewStyle} from 'react-native';
2
2
  import {Ref} from 'react';
3
3
 
4
4
  export type PaginationProps = {
5
+ /**
6
+ * Optional. Defines the visual style of the Pagination component.
7
+ * - 'default': Represents the default style.
8
+ * - 'black_white': Represents a pagination that have black background.
9
+ * - 'number': Represents a style where pages are represented by numbers.
10
+ * - 'scroll': Represents a scrollable style.
11
+ */
5
12
  type?: 'default' | 'black_white' | 'number' | 'scroll';
13
+
14
+ /**
15
+ * Represents the currently active (selected) index in the Pagination component.
16
+ */
6
17
  activeIndex: number;
18
+
19
+ /**
20
+ * Represents the total number of items (pages) in the Pagination component.
21
+ */
7
22
  dataLength: number;
8
23
  };
9
24
 
@@ -13,6 +28,10 @@ export type DotProps = {
13
28
  };
14
29
 
15
30
  export interface ScrollIndicatorProps extends ScrollViewProps {
31
+ /**
32
+ * Optional. Represents a reference to the ScrollView component.
33
+ * It can be used to access the instance methods of the ScrollView.
34
+ */
16
35
  scrollViewRef?: Ref<ScrollView>;
17
36
  }
18
37
 
@@ -183,7 +183,7 @@ const styles = StyleSheet.create({
183
183
  },
184
184
  contentAction: {
185
185
  paddingHorizontal: Spacing.XL,
186
- paddingBottom: Spacing.L,
186
+ paddingBottom: Spacing.XL,
187
187
  },
188
188
  buttonSpace: {
189
189
  width: Spacing.S,
package/Popup/types.ts CHANGED
@@ -1,21 +1,69 @@
1
1
  export type PopupNotifyProps = {
2
+ /**
3
+ * `image`: Optional. Represents the URL or path of the image to be displayed in the PopupNotify component.
4
+ */
2
5
  image?: string;
6
+
7
+ /**
8
+ * `title`: Represents the title text to be displayed in the PopupNotify component.
9
+ */
3
10
  title: string;
11
+
12
+ /**
13
+ * `description`: Represents the description text to be displayed in the PopupNotify component.
14
+ */
4
15
  description: string;
16
+
17
+ /**
18
+ * `information`: Optional. Represents additional information text to be displayed in the PopupNotify component.
19
+ */
5
20
  information?: string;
21
+
22
+ /**
23
+ * `secondary`: Optional. Represents the secondary action that can be performed from the PopupNotify component.
24
+ */
6
25
  secondary?: PopupAction;
26
+
27
+ /**
28
+ * `primary`: Represents the primary action that can be performed from the PopupNotify component.
29
+ */
7
30
  primary: PopupAction;
31
+
32
+ /**
33
+ * `buttonDirection`: Optional. Represents the direction in which the action buttons are laid out.
34
+ * - 'row': Buttons are laid out horizontally.
35
+ * - 'column': Buttons are laid out vertically.
36
+ * - 'auto': The layout is automatically determined by title length.
37
+ */
8
38
  buttonDirection?: PopupActionDirection;
39
+
40
+ /**
41
+ * `onIconClose`: Optional. A callback function that is called when the close icon in the PopupNotify component is pressed.
42
+ */
9
43
  onIconClose?: () => void;
10
44
  };
11
45
 
12
46
  export type PopupPromotionProps = {
47
+ /**
48
+ * `image`: Represents the URL or path of the image to be displayed in the PopupPromotion component.
49
+ */
13
50
  image: string;
51
+
52
+ /**
53
+ * `onClose`: Optional. A callback function that is called when the PopupPromotion component is closed.
54
+ */
14
55
  onClose?: () => void;
15
56
  };
16
57
 
17
58
  type PopupAction = {
59
+ /**
60
+ * `title`: Represents the title text of the action button.
61
+ */
18
62
  title: string;
63
+
64
+ /**
65
+ * `onPress`: A callback function that is called when the action button is pressed.
66
+ */
19
67
  onPress: () => void;
20
68
  };
21
69
 
package/Radio/types.ts CHANGED
@@ -1,10 +1,38 @@
1
1
  import {ViewStyle} from 'react-native';
2
2
 
3
3
  export type RadioProps = {
4
+ /**
5
+ * `value`: Represents the value associated with the Radio component.
6
+ * It is used to determine whether the Radio component is selected or not in comparison with the `groupValue`.
7
+ */
4
8
  value: string;
9
+
10
+ /**
11
+ * `disabled`: Optional. If `true`, the user won't be able to interact with the Radio component.
12
+ * Defaults to `false` if not provided.
13
+ */
5
14
  disabled?: boolean;
15
+
16
+ /**
17
+ * `label`: Optional. Represents the text label displayed next to the Radio component.
18
+ */
6
19
  label?: string;
20
+
21
+ /**
22
+ * `onChange`: A callback function that is called when the value of the Radio component changes.
23
+ * It is triggered when the user interacts with the Radio component.
24
+ */
7
25
  onChange: () => void;
26
+
27
+ /**
28
+ * `groupValue`: Represents the value of the selected Radio component within a group of Radio components.
29
+ * The Radio component for which `value` equals `groupValue` will be selected.
30
+ */
8
31
  groupValue: string;
32
+
33
+ /**
34
+ * `style`: Optional. Used to apply custom styling to the Radio component.
35
+ * Accepts an object of style properties.
36
+ */
9
37
  style?: ViewStyle;
10
38
  };
package/Switch/types.ts CHANGED
@@ -1,8 +1,26 @@
1
1
  import {ViewStyle} from 'react-native';
2
2
 
3
3
  export type SwitchProps = {
4
+ /**
5
+ * `value`: Represents whether the Switch component is currently in the 'on' (`true`) or 'off' (`false`) state.
6
+ */
4
7
  value: boolean;
8
+
9
+ /**
10
+ * `onChange`: A callback function that is called when the value of the Switch component changes.
11
+ * It receives the new value of the Switch as a parameter.
12
+ */
5
13
  onChange: (value: boolean) => void;
14
+
15
+ /**
16
+ * `disabled`: Optional. If `true`, the user won't be able to interact with the Switch component.
17
+ * Defaults to `false` if not provided.
18
+ */
6
19
  disabled?: boolean;
20
+
21
+ /**
22
+ * `style`: Optional. Used to apply custom styling to the Switch component.
23
+ * Accepts an object of style properties.
24
+ */
7
25
  style?: ViewStyle;
8
26
  };
package/Tag/types.ts CHANGED
@@ -1,10 +1,36 @@
1
1
  import {ViewStyle} from 'react-native';
2
2
 
3
3
  export type TagProps = {
4
+ /**
5
+ * `label`: Represents the text label displayed on the Tag component.
6
+ */
4
7
  label: string;
8
+
9
+ /**
10
+ * `size`: Optional. Defines the size of the Tag component.
11
+ * Defaults to 'medium' if not provided.
12
+ */
5
13
  size?: 'medium' | 'large';
14
+
15
+ /**
16
+ * `icon`: Optional. Represents the name or key of the icon to be displayed in the Tag component.
17
+ */
6
18
  icon?: string;
19
+
20
+ /**
21
+ * `color`: Optional. Defines the color style of the Tag component.
22
+ */
7
23
  color?: 'default' | 'orange' | 'green' | 'red' | 'blue' | 'grey';
24
+
25
+ /**
26
+ * `style`: Optional. Used to apply custom styling to the Tag component.
27
+ * Accepts an object of style properties.
28
+ */
8
29
  style?: ViewStyle;
30
+
31
+ /**
32
+ * `customColor`: Optional. Represents a custom color string (e.g., hex, rgb, rgba, etc.)
33
+ * that can be applied to the Tag component.
34
+ */
9
35
  customColor?: string;
10
36
  };
package/Text/index.tsx CHANGED
@@ -39,11 +39,24 @@ const FontStyle: {[key: string]: string} = {
39
39
  };
40
40
 
41
41
  export interface TextProps extends RNTextProps {
42
+ /**
43
+ * Represents the typography style applied to the Text component.
44
+ * It defines the appearance of the text in terms of font size, weight, line height etc.
45
+ */
42
46
  typography: Typography;
47
+
48
+ /**
49
+ * Optional. Represents the color of the text in the Text component.
50
+ * It can be any valid color string (e.g., hex, rgb, rgba, etc.).
51
+ */
43
52
  color?: string;
53
+
54
+ /**
55
+ * Optional. Represents the width of the Text component in terms of span numbers.
56
+ * It can be used to set a specific width for the text based on a predefined grid system.
57
+ */
44
58
  widthSpan?: number;
45
59
  }
46
-
47
60
  const Text: React.FC<TextProps> = ({
48
61
  typography,
49
62
  color,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.75.1-beta.3",
3
+ "version": "0.75.1-beta.7",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {