@momo-kits/foundation 0.80.8 → 0.80.9

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,4 +1,4 @@
1
- import React, {useContext, useEffect, useState} from 'react';
1
+ import React, {Fragment, useContext, useEffect, useState} from 'react';
2
2
  import {
3
3
  Alert,
4
4
  Animated,
@@ -6,8 +6,8 @@ import {
6
6
  Platform,
7
7
  StatusBar,
8
8
  StyleSheet,
9
- View,
10
9
  TouchableOpacity as TouchableRN,
10
+ View,
11
11
  } from 'react-native';
12
12
  import {TouchableOpacity as TouchableGesture} from 'react-native-gesture-handler';
13
13
  import {ApplicationContext} from './index';
@@ -271,22 +271,23 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
271
271
  };
272
272
 
273
273
  const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
274
- const validType = (item: any) => {
275
- if (__DEV__ && item.type !== NavigationButton) {
274
+ const validateType = (child: React.ReactElement) => {
275
+ const valid = child?.type === NavigationButton || child?.type == Fragment;
276
+ if (__DEV__ && !valid) {
276
277
  Alert.alert(
277
278
  'Rule',
278
279
  'HeaderRightAction contains element type of NavigationButton, Please check again.',
279
280
  );
280
- return <View />;
281
281
  }
282
- return item;
282
+ return child;
283
283
  };
284
+
284
285
  const renderAction = () => {
285
286
  if (Array.isArray(children)) {
286
287
  return children.map((child, index) => {
287
288
  return (
288
- <View key={index} style={styles.headerButton}>
289
- {React.cloneElement(validType(child), {...restProps})}
289
+ <View key={`HeaderRightAction ${index}`} style={styles.headerButton}>
290
+ {React.cloneElement(validateType(child), {...restProps})}
290
291
  </View>
291
292
  );
292
293
  });
@@ -294,7 +295,7 @@ const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
294
295
 
295
296
  return (
296
297
  <View style={styles.headerButton}>
297
- {React.cloneElement(validType(children), {...restProps})}
298
+ {React.cloneElement(validateType(children), {...restProps})}
298
299
  </View>
299
300
  );
300
301
  };
@@ -72,54 +72,61 @@ const getModalOptions = (): StackNavigationOptions => {
72
72
  };
73
73
 
74
74
  const getOptions = (params: NavigationOptions, theme: Theme) => {
75
- let backgroundProps = {};
76
- let titleProps = {};
75
+ let backgroundProps: any;
76
+ let titleProps: any;
77
77
  let options = {};
78
78
 
79
- if (typeof params.onPressLeftHeader === 'function') {
79
+ if (
80
+ typeof params.onPressLeftHeader === 'function' ||
81
+ params.preventBack !== undefined ||
82
+ typeof params.hiddenBack === 'boolean'
83
+ ) {
80
84
  options = {
81
85
  ...options,
82
- headerLeft: (props: any) => (
83
- <HeaderLeft
84
- {...props}
85
- preventBack={params.preventBack}
86
- onPressLeftHeader={params.onPressLeftHeader}
87
- />
88
- ),
86
+ headerLeft: params.hiddenBack
87
+ ? null
88
+ : (props: any) => (
89
+ <HeaderLeft
90
+ {...props}
91
+ preventBack={params.preventBack}
92
+ onPressLeftHeader={params.onPressLeftHeader}
93
+ />
94
+ ),
89
95
  };
90
96
  }
91
97
 
92
- if (params.preventBack) {
93
- options = {
94
- ...options,
95
- headerLeft: (props: any) => (
96
- <HeaderLeft {...props} preventBack={params.preventBack} />
97
- ),
98
- };
98
+ if (typeof params.surface == 'boolean') {
99
+ if (params.surface) {
100
+ options = {
101
+ ...options,
102
+ ...getTintColor({
103
+ ...theme,
104
+ assets: {...theme.assets, headerBackground: undefined},
105
+ }),
106
+ };
107
+ backgroundProps = {
108
+ image: null,
109
+ backgroundColor: theme.colors.background.surface,
110
+ useBorder: true,
111
+ };
112
+ } else {
113
+ options = {
114
+ ...options,
115
+ ...getTintColor(theme),
116
+ headerBackground: HeaderBackground,
117
+ };
118
+ }
99
119
  }
100
120
 
101
- if (params.surface == true) {
121
+ if (params.animatedValue) {
122
+ backgroundProps = {...backgroundProps, animatedValue: params.animatedValue};
123
+ titleProps = {animatedValue: params.animatedValue};
102
124
  options = {
103
125
  ...options,
104
- ...getTintColor({
105
- ...theme,
106
- assets: {...theme.assets, headerBackground: undefined},
107
- }),
108
- };
109
- backgroundProps = {
110
- ...backgroundProps,
111
- image: null,
112
- backgroundColor: theme.colors.background.surface,
113
- useBorder: true,
126
+ headerTitle: (props: any) => {
127
+ return <HeaderTitle {...titleProps} {...props} />;
128
+ },
114
129
  };
115
- } else {
116
- backgroundProps = {};
117
- options = {...options, ...getTintColor(theme)};
118
- }
119
-
120
- if (params.animatedValue) {
121
- backgroundProps = {...backgroundProps, animatedValue: params.animatedValue};
122
- titleProps = {...titleProps, animatedValue: params.animatedValue};
123
130
  }
124
131
 
125
132
  if (params.customTitle) {
@@ -130,26 +137,18 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
130
137
  return <HeaderCustom {...params.customTitle} {...props} />;
131
138
  },
132
139
  };
133
- } else if (!params.headerTitle) {
134
- options = {
135
- ...options,
136
- headerTitle: (props: any) => {
137
- return <HeaderTitle {...titleProps} {...props} />;
138
- },
139
- };
140
140
  }
141
141
 
142
- if (params.hiddenBack) {
142
+ if (backgroundProps) {
143
143
  options = {
144
144
  ...options,
145
- headerLeft: null,
145
+ headerBackground: () => <HeaderBackground {...backgroundProps} />,
146
146
  };
147
147
  }
148
148
 
149
149
  return {
150
150
  ...params,
151
151
  ...options,
152
- headerBackground: () => <HeaderBackground {...backgroundProps} />,
153
152
  };
154
153
  };
155
154
 
@@ -1,4 +1,4 @@
1
- import React, {forwardRef, useContext, useRef} from 'react';
1
+ import React, {useContext} from 'react';
2
2
  import {TextInput, TouchableOpacity, View} from 'react-native';
3
3
  import {ApplicationContext} from '../Application';
4
4
  import styles from './styles';
@@ -8,117 +8,110 @@ import {Icon} from '../Icon';
8
8
  import {Loader} from '../Loader';
9
9
  import {Styles} from '../Consts';
10
10
 
11
- const InputDropDown = forwardRef(
12
- (
13
- {
14
- value,
15
- floatingValue,
16
- floatingIcon,
17
- size,
18
- onPress,
19
- placeholder,
20
- errorMessage,
21
- icon = 'arrow_chevron_down_small',
22
- disabled,
23
- floatingIconColor,
24
- iconColor,
25
- required,
26
- errorSpacing,
27
- loading,
28
- leadingIcon,
29
- leadingIconColor,
30
- ...props
31
- }: InputDropDownProps,
32
- ref,
33
- ) => {
34
- const {theme} = useContext(ApplicationContext);
35
- const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
36
- const full = !!value || !!placeholder;
37
- const renderIcon = (color: string | undefined) => {
38
- if (loading) {
39
- return <Loader type={'spinner'} color={color} />;
40
- }
41
- if (icon) {
42
- return <Icon color={color} source={icon} size={24} />;
43
- }
44
- };
11
+ const InputDropDown = ({
12
+ value,
13
+ floatingValue,
14
+ floatingIcon,
15
+ size,
16
+ onPress,
17
+ placeholder,
18
+ errorMessage,
19
+ icon = 'arrow_chevron_down_small',
20
+ disabled,
21
+ floatingIconColor,
22
+ iconColor,
23
+ required,
24
+ errorSpacing,
25
+ loading,
26
+ leadingIcon,
27
+ leadingIconColor,
28
+ ...props
29
+ }: InputDropDownProps) => {
30
+ const {theme} = useContext(ApplicationContext);
31
+ const full = !!value || !!placeholder;
32
+ const renderIcon = (color: string | undefined) => {
33
+ if (loading) {
34
+ return <Loader type={'spinner'} color={color} />;
35
+ }
36
+ if (icon) {
37
+ return <Icon color={color} source={icon} size={24} />;
38
+ }
39
+ };
45
40
 
46
- const renderInputView = () => {
47
- const disabledColor = theme.colors.text.disable;
48
- let textColor = theme.colors.text.default;
49
- let placeholderColor = theme.colors.text.hint;
50
- let iconTintColor = iconColor;
41
+ const renderInputView = () => {
42
+ const disabledColor = theme.colors.text.disable;
43
+ let textColor = theme.colors.text.default;
44
+ let placeholderColor = theme.colors.text.hint;
45
+ let iconTintColor = iconColor;
51
46
 
52
- if (disabled) {
53
- textColor = disabledColor;
54
- placeholderColor = disabledColor;
55
- iconTintColor = disabledColor;
56
- }
47
+ if (disabled) {
48
+ textColor = disabledColor;
49
+ placeholderColor = disabledColor;
50
+ iconTintColor = disabledColor;
51
+ }
57
52
 
58
- return (
59
- <View
60
- style={[
61
- styles.inputWrapper,
62
- {backgroundColor: theme.colors.background.surface},
63
- getSizeStyle(size),
64
- getBorderColor(theme, false, errorMessage, disabled),
65
- ]}>
66
- <FloatingView
67
- floatingValue={floatingValue}
68
- floatingIconColor={floatingIconColor}
69
- disabled={disabled}
70
- required={required}
71
- floatingIcon={floatingIcon}
72
- />
73
- <View style={full ? styles.inputView : Styles.row}>
74
- {!!leadingIcon && (
75
- <View style={styles.leadingIconContainer}>
76
- <Icon
77
- color={leadingIconColor}
78
- source={leadingIcon}
79
- size={size === 'small' ? 24 : 32}
80
- />
81
- </View>
82
- )}
83
- {full && (
84
- <TextInput
85
- {...props}
86
- onPressIn={onPress}
87
- accessibilityLabel={`TextInput`}
88
- editable={false}
89
- textAlignVertical="top"
90
- ref={inputRef}
91
- style={[
92
- styles.input,
93
- {
94
- color: textColor,
95
- fontFamily: `${theme.font}-Regular`,
96
- },
97
- ]}
98
- textBreakStrategy="highQuality"
99
- value={value}
100
- placeholder={placeholder}
101
- selectionColor={theme.colors.primary}
102
- placeholderTextColor={placeholderColor}
53
+ return (
54
+ <View
55
+ style={[
56
+ styles.inputWrapper,
57
+ {backgroundColor: theme.colors.background.surface},
58
+ getSizeStyle(size),
59
+ getBorderColor(theme, false, errorMessage, disabled),
60
+ ]}>
61
+ <FloatingView
62
+ floatingValue={floatingValue}
63
+ floatingIconColor={floatingIconColor}
64
+ disabled={disabled}
65
+ required={required}
66
+ floatingIcon={floatingIcon}
67
+ />
68
+ <View style={full ? styles.inputView : Styles.row}>
69
+ {!!leadingIcon && (
70
+ <View style={styles.leadingIconContainer}>
71
+ <Icon
72
+ color={leadingIconColor}
73
+ source={leadingIcon}
74
+ size={size === 'small' ? 24 : 32}
103
75
  />
104
- )}
105
- </View>
106
- <View style={styles.iconView}>{renderIcon(iconTintColor)}</View>
76
+ </View>
77
+ )}
78
+ {full && (
79
+ <TextInput
80
+ {...props}
81
+ onPressIn={onPress}
82
+ accessibilityLabel={`TextInput`}
83
+ editable={false}
84
+ textAlignVertical="top"
85
+ style={[
86
+ styles.input,
87
+ {
88
+ color: textColor,
89
+ fontFamily: `${theme.font}-Regular`,
90
+ },
91
+ ]}
92
+ textBreakStrategy="highQuality"
93
+ value={value}
94
+ placeholder={placeholder}
95
+ selectionColor={theme.colors.primary}
96
+ placeholderTextColor={placeholderColor}
97
+ />
98
+ )}
107
99
  </View>
108
- );
109
- };
110
-
111
- return (
112
- <TouchableOpacity
113
- onPress={onPress}
114
- style={full && styles.wrapper}
115
- accessibilityLabel={`InputDropDown/${floatingValue}`}>
116
- {renderInputView()}
117
- <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
118
- </TouchableOpacity>
100
+ <View style={styles.iconView}>{renderIcon(iconTintColor)}</View>
101
+ </View>
119
102
  );
120
- },
121
- );
103
+ };
104
+
105
+ return (
106
+ <TouchableOpacity
107
+ onPress={onPress}
108
+ style={full && styles.wrapper}
109
+ accessibilityLabel={`InputDropDown/${floatingValue}`}>
110
+ {renderInputView()}
111
+ <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
112
+ </TouchableOpacity>
113
+ );
114
+ };
122
115
 
123
116
  InputDropDown.defaultProps = {
124
117
  size: 'small',
package/Input/index.tsx CHANGED
@@ -123,73 +123,95 @@ export interface InputMoneyProps extends InputPropsWithoutPlaceholder {}
123
123
  export type OTPInputLength = 2 | 4 | 6 | 8 | 10;
124
124
 
125
125
  export interface InputOTPProps extends InputPropsWithoutSizeAndIcon {
126
+ /**
127
+ * Optional. Defines the length of the OTP (One Time Password) input.
128
+ * Can be 2, 4, 6, 8, or 10.
129
+ */
126
130
  length?: OTPInputLength;
131
+
132
+ /**
133
+ * Optional. Defines the data type of the OTP input.
134
+ * 'string' - The OTP input will be treated as a string.
135
+ * 'number' - The OTP input will be treated as a number.
136
+ */
127
137
  dataType?: 'string' | 'number';
128
138
  }
129
139
 
130
140
  export type CaretProps = {
141
+ /**
142
+ * Optional. The index of the caret in the input field.
143
+ * Represents the position where the caret is located.
144
+ */
131
145
  index?: number;
146
+
147
+ /**
148
+ * Optional. The total length of the input field in which the caret is present.
149
+ * This dictates the maximum value of the 'index' property.
150
+ */
132
151
  length?: number;
133
152
  };
134
153
 
135
- export type InputDropDownProps = {
154
+ export interface InputDropDownProps {
136
155
  /**
137
- * Optional. Defines the size of the Input component.
156
+ * Optional. Defines the size of the InputDropDown component.
157
+ * 'small' - A smaller, less prominent input.
158
+ * 'large' - A larger, more prominent input.
138
159
  */
139
160
  size?: 'small' | 'large';
140
161
 
141
162
  /**
142
- * Optional. Defines the value of InputDropDown.
163
+ * Optional. The current value of the InputDropDown.
143
164
  */
144
165
  value?: string;
145
166
 
146
167
  /**
147
- * Optional. Defines the placeholder of InputDropDown.
168
+ * Optional. Text that is displayed when there is no value set in the InputDropDown.
148
169
  */
149
170
  placeholder?: string;
150
171
 
151
172
  /**
152
- * Optional. Defines the onPress of InputDropDown.
173
+ * Optional. Function to be called when the InputDropDown is pressed.
153
174
  */
154
175
  onPress?: () => void;
176
+
155
177
  /**
156
- * Optional. Represents the value for the floating title in the Input component.
178
+ * Optional. Represents the value for the floating title in the InputDropDown component.
157
179
  */
158
180
  floatingValue?: string;
159
181
 
160
182
  /**
161
- * Optional. Represents the name or key of the floating icon to be displayed in the Input component.
183
+ * Optional. Represents the name or key of the floating icon to be displayed in the InputDropDown component.
162
184
  */
163
185
  floatingIcon?: string;
164
186
 
165
187
  /**
166
- * Optional. Represents the error message to be displayed below the Input component when there is an error.
188
+ * Optional. Represents the error message to be displayed below the InputDropDown component when there is an error.
167
189
  */
168
190
  errorMessage?: string;
169
191
 
170
192
  /**
171
- * Optional. Represents the name or key of the icon to be displayed in the Input component.
193
+ * Optional. Represents the name or key of the icon to be displayed in the InputDropDown component.
172
194
  */
173
195
  icon?: string;
174
196
 
175
197
  /**
176
- * Optional. Represents the color of the icon in the Input component.
198
+ * Optional. Represents the color of the icon in the InputDropDown component.
177
199
  */
178
200
  iconColor?: string;
179
201
 
180
202
  /**
181
- * Optional. If `true`, the user won't be able to interact with the Input component.
203
+ * Optional. If `true`, the user won't be able to interact with the InputDropDown component.
182
204
  * Defaults to `false` if not provided.
183
205
  */
184
206
  disabled?: boolean;
185
207
 
186
208
  /**
187
- * Optional. Represents the color of the floating icon in the Input component.
209
+ * Optional. Represents the color of the floating icon in the InputDropDown component.
188
210
  */
189
211
  floatingIconColor?: string;
190
212
 
191
213
  /**
192
- * Optional. If `true`, the Input component is marked as required,
214
+ * Optional. If `true`, the InputDropDown component is marked as required,
193
215
  * indicating that the user must provide a value before submitting a form.
194
216
  * Defaults to `false` if not provided.
195
217
  */
@@ -197,25 +219,25 @@ export type InputDropDownProps = {
197
219
 
198
220
  /**
199
221
  * Optional. If `true`,
200
- * include spacing when Input not have error message.
222
+ * includes spacing when InputDropDown does not have an error message.
201
223
  * Defaults to `false` if not provided.
202
224
  */
203
225
  errorSpacing?: boolean;
204
226
 
205
227
  /**
206
- * If true, the icon of input will use be show indicator loading.
228
+ * If `true`, the icon of the input will show an indicator for loading.
207
229
  */
208
230
  loading?: boolean;
209
231
 
210
232
  /**
211
- * Optional. Represents the leading icon in the Input component.
233
+ * Optional. Represents the leading icon in the InputDropDown component.
212
234
  */
213
235
  leadingIcon?: string;
214
236
 
215
237
  /**
216
- * Optional. Represents the color of the leading icon in the Input component.
238
+ * Optional. Represents the color of the leading icon in the InputDropDown component.
217
239
  */
218
240
  leadingIconColor?: string;
219
- };
241
+ }
220
242
 
221
243
  export {Input, InputTextArea, InputSearch, InputMoney, InputOTP, InputDropDown};
package/Title/index.tsx CHANGED
@@ -5,7 +5,6 @@ import {Icon} from '../Icon';
5
5
  import styles from './styles';
6
6
  import {ApplicationContext} from '../Application';
7
7
  import {Colors, Spacing} from '../Consts';
8
- import {Button} from '../Button';
9
8
  import {scaleSize, Text} from '../Text';
10
9
 
11
10
  const Title: FC<TitleProps> = ({
package/Title/types.ts CHANGED
@@ -1,11 +1,51 @@
1
1
  export type TitleProps = {
2
+ /**
3
+ * Optional. Defines the type of Title component.
4
+ * 'screen' - Used for screen titles.
5
+ * 'section' - Used for section titles within a screen.
6
+ * 'card' - Used for titles within a card component.
7
+ */
2
8
  type?: 'screen' | 'section' | 'card';
9
+
10
+ /**
11
+ * Required. The text of the title.
12
+ */
3
13
  title: string;
14
+
15
+ /**
16
+ * Optional. A description or subtitle that appears below the title.
17
+ */
4
18
  description?: string;
19
+
20
+ /**
21
+ * Optional. Defines the size of the Title component.
22
+ * 'large' - A larger, more prominent title.
23
+ * 'small' - A smaller, less prominent title.
24
+ */
5
25
  size?: 'large' | 'small';
26
+
27
+ /**
28
+ * Optional. Represents the name or key of the icon to be displayed alongside the title.
29
+ */
6
30
  icon?: string;
31
+
32
+ /**
33
+ * Optional. If `true`, the title will be flexible in its container, adjusting its width dynamically.
34
+ */
7
35
  titleFlex?: boolean;
36
+
37
+ /**
38
+ * Optional. Text for an action button associated with the title.
39
+ */
8
40
  actionTitle?: string;
41
+
42
+ /**
43
+ * Optional. Function to be called when the action associated with the title is pressed.
44
+ */
9
45
  onPressAction?: () => void;
46
+
47
+ /**
48
+ * Optional. If `true`, an action button or icon is displayed alongside the title.
49
+ */
10
50
  showAction?: boolean;
11
51
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.80.8",
3
+ "version": "0.80.9",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {
@@ -42,4 +42,4 @@
42
42
  },
43
43
  "author": "@momo-kits/foundation",
44
44
  "license": "ISC"
45
- }
45
+ }