@momo-kits/foundation 0.77.1-optimzie.4 → 0.77.1-optimzie.6

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.
@@ -293,21 +293,19 @@ export default function BottomTabBar({
293
293
  );
294
294
 
295
295
  const renderCenterComponent = useCallback(() => {
296
- const renderFloatingButton = () => {
297
- if (typeof floatingButton?.icon == 'string') {
298
- return <Icon source={floatingButton?.icon} size={32} color={'white'} />;
299
- } else if (floatingButton?.icon) {
300
- return floatingButton?.icon;
301
- } else {
302
- return null;
303
- }
304
- };
305
296
  if (floatingButton?.icon && state.routes.length !== 4) {
306
297
  console.warn(
307
298
  "Can't render floating button with icon when routes length is not 4",
308
299
  );
309
300
  return null;
310
301
  }
302
+ const renderFloatingButton = () => {
303
+ if (typeof floatingButton?.icon == 'string') {
304
+ return <Icon source={floatingButton?.icon} size={32} color={'white'} />;
305
+ }
306
+ return floatingButton?.icon;
307
+ };
308
+
311
309
  return (
312
310
  <View style={{flex: 1}}>
313
311
  <TouchableOpacity
@@ -370,8 +368,6 @@ export default function BottomTabBar({
370
368
  }),
371
369
  },
372
370
  ],
373
- // Absolutely position the tab bar so that the content is below it
374
- // This is needed to avoid gap at bottom when the tab bar is hidden
375
371
  position: isTabBarHidden ? 'absolute' : (null as any),
376
372
  },
377
373
  {
@@ -430,8 +426,8 @@ const styles = StyleSheet.create({
430
426
  justifyContent: 'center',
431
427
  height: 48,
432
428
  width: 48,
433
- borderRadius: 100,
434
- top: -12,
429
+ borderRadius: 24,
430
+ top: -10,
435
431
  },
436
432
  indicator: {
437
433
  height: 2,
@@ -10,21 +10,26 @@ import {Text} from '../../Text';
10
10
  import {ApplicationContext} from '../index';
11
11
  import StackScreen from '../StackScreen';
12
12
  import {BottomTabProps, NavigationScreenProps} from '../types';
13
- import {getStackOptions} from '../utils';
13
+ import {getOptions, getStackOptions} from '../utils';
14
14
  import BottomTabBar from './BottomTabBar';
15
15
 
16
16
  const Tab = createBottomTabNavigator();
17
17
  const Stack = createStackNavigator();
18
18
 
19
19
  const TabScreen: React.FC<NavigationScreenProps> = ({route}) => {
20
+ const {theme} = useContext(ApplicationContext);
21
+ let options = {};
22
+ if (route.params?.options) {
23
+ options = getOptions(route.params?.options, theme);
24
+ }
20
25
  if (route.params?.nested) {
21
26
  return (
22
27
  <Stack.Navigator>
23
28
  <Stack.Screen
24
29
  name="Stack"
25
30
  component={StackScreen}
26
- initialParams={{screen: route.params?.screen}}
27
- options={{...getStackOptions(), ...route.params?.options}}
31
+ initialParams={{screen: route.params?.screen, options}}
32
+ options={{...getStackOptions()}}
28
33
  />
29
34
  </Stack.Navigator>
30
35
  );
@@ -35,7 +40,7 @@ const TabScreen: React.FC<NavigationScreenProps> = ({route}) => {
35
40
  <Stack.Screen
36
41
  name="Stack"
37
42
  component={StackScreen}
38
- initialParams={{screen: route.params?.screen}}
43
+ initialParams={{screen: route.params?.screen, options}}
39
44
  options={{...getStackOptions(), ...route.params?.options}}
40
45
  />
41
46
  </Stack.Navigator>
@@ -83,6 +88,8 @@ const BottomTab: React.FC<BottomTabProps> = ({
83
88
  },
84
89
  }}>
85
90
  {tabs.map(item => {
91
+ const isNum = !isNaN(parseInt(`${item?.badgeLabel}`));
92
+ const isDot = typeof item?.badgeLabel == 'string' && !item?.badgeLabel;
86
93
  return (
87
94
  <Tab.Screen
88
95
  key={item.name}
@@ -113,12 +120,9 @@ const BottomTab: React.FC<BottomTabProps> = ({
113
120
  fontWeight: 'bold',
114
121
  alignSelf: 'center',
115
122
  fontFamily: `${theme.font}-Bold`,
116
- left: item?.showDot ? 8 : 4,
117
- top: item?.showDot ? -2 : -6,
118
- backgroundColor:
119
- typeof item?.badgeLabel === 'string'
120
- ? Colors.orange_03
121
- : Colors.red_03,
123
+ left: isDot ? 8 : 4,
124
+ top: isDot ? -2 : -6,
125
+ backgroundColor: isNum ? Colors.orange_03 : Colors.red_03,
122
126
  },
123
127
  tabBarIcon: ({color}) => (
124
128
  <Icon source={item.icon} color={color} size={28} />
@@ -183,15 +183,18 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
183
183
 
184
184
  const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
185
185
  image,
186
- backgroundColor,
187
186
  animatedValue,
188
- useBorder = false,
187
+ useSurface = false,
189
188
  }) => {
190
189
  const {theme} = useContext(ApplicationContext);
191
190
  let headerImage = theme.assets?.headerBackground;
191
+ let backgroundColor;
192
192
  if (image === null) {
193
193
  headerImage = undefined;
194
194
  }
195
+ if (useSurface) {
196
+ backgroundColor = theme.colors.background.surface;
197
+ }
195
198
  const opacity = animatedValue?.interpolate({
196
199
  inputRange: [0, 114],
197
200
  outputRange: [0, 1],
@@ -203,9 +206,9 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
203
206
  style={[
204
207
  Styles.flex,
205
208
  {
206
- backgroundColor: backgroundColor ?? theme.colors.background.default,
209
+ backgroundColor,
207
210
  overflow: 'hidden',
208
- borderBottomWidth: useBorder ? 1 : 0,
211
+ borderBottomWidth: useSurface ? 1 : 0,
209
212
  borderColor: theme.colors.border.default,
210
213
  opacity,
211
214
  },
@@ -90,6 +90,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
90
90
  options,
91
91
  footerComponent,
92
92
  flatListProps,
93
+ backgroundColor,
93
94
  }: BottomSheetParams = props.route.params;
94
95
 
95
96
  const navigation = new Navigation(props.navigation, theme);
@@ -127,6 +128,9 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
127
128
  options?.title ?? options?.customTitle?.title ?? '',
128
129
  handleClose,
129
130
  )}
131
+ modalStyle={{
132
+ backgroundColor: backgroundColor ?? theme.colors.background.surface,
133
+ }}
130
134
  FooterComponent={footerDefault(footerComponent)}>
131
135
  <View style={styles.bottomSheetContainer}>
132
136
  <Screen {...props} {...params} />
@@ -141,7 +145,7 @@ const headerDefault = (title: string, onClose: () => void) => {
141
145
  <View style={styles.header}>
142
146
  <Text
143
147
  style={styles.textOption}
144
- numberOfLines={2}
148
+ numberOfLines={1}
145
149
  typography="header_default_bold">
146
150
  {title ?? ''}
147
151
  </Text>
@@ -154,16 +158,18 @@ const headerDefault = (title: string, onClose: () => void) => {
154
158
 
155
159
  const footerDefault = (footerComponent: React.ReactNode) => {
156
160
  const insets = useSafeAreaInsets();
157
- if (!footerComponent) return;
158
- return (
159
- <View
160
- style={{
161
- marginBottom: Math.min(insets.bottom, 21) + Spacing.S,
162
- paddingHorizontal: 12,
163
- }}>
164
- {footerComponent}
165
- </View>
166
- );
161
+ if (footerComponent) {
162
+ return (
163
+ <View
164
+ style={{
165
+ marginBottom: Math.min(insets.bottom, 21),
166
+ paddingHorizontal: Spacing.M,
167
+ paddingVertical: Spacing.S,
168
+ }}>
169
+ {footerComponent}
170
+ </View>
171
+ );
172
+ }
167
173
  };
168
174
 
169
175
  const styles = StyleSheet.create({
@@ -204,9 +210,6 @@ const styles = StyleSheet.create({
204
210
  },
205
211
  bottomSheetContainer: {
206
212
  width: '100%',
207
- backgroundColor: 'white',
208
- borderTopRightRadius: 16,
209
- borderTopLeftRadius: 16,
210
213
  },
211
214
  header: {
212
215
  height: 50,
@@ -219,15 +222,9 @@ const styles = StyleSheet.create({
219
222
  color: '#303233',
220
223
  textAlign: 'center',
221
224
  fontWeight: 'bold',
222
- paddingHorizontal: 60,
223
- },
224
- imageOption: {
225
- height: 1,
226
- backgroundColor: '#ebebeb',
227
- width: '100%',
228
- position: 'absolute',
229
- bottom: 1,
225
+ paddingHorizontal: Spacing.L,
230
226
  },
227
+
231
228
  buttonClose: {
232
229
  padding: 12,
233
230
  position: 'absolute',
@@ -119,6 +119,7 @@ export interface ModalParams extends ScreenParams {
119
119
  export interface BottomSheetParams extends ScreenParams {
120
120
  [key: string]: any;
121
121
  onDismiss?: () => void;
122
+ backgroundColor?: string;
122
123
  footerComponent?: React.ReactNode;
123
124
  flatListProps?: FlatListProps<any>;
124
125
  }
@@ -165,9 +166,8 @@ export interface HeaderBackProps extends NavigationButtonProps {
165
166
 
166
167
  export type HeaderBackgroundProps = {
167
168
  image?: string | null;
168
- backgroundColor?: string | null;
169
169
  animatedValue?: Animated.Value;
170
- useBorder?: boolean;
170
+ useSurface?: boolean;
171
171
  };
172
172
 
173
173
  export type TitleCustomProps = {
@@ -223,4 +223,5 @@ export type FloatingButtonProps = {
223
223
  export type AnimatedHeader = {
224
224
  type: 'default' | 'surface';
225
225
  component?: (props?: any) => React.ReactElement;
226
+ headerTitle?: (props?: any) => React.ReactElement;
226
227
  };
@@ -100,11 +100,7 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
100
100
  ...options,
101
101
  headerTintColor: theme.colors.text.default,
102
102
  headerBackground: () => (
103
- <HeaderBackground
104
- image={null}
105
- backgroundColor={theme.colors.background.surface}
106
- useBorder={true}
107
- />
103
+ <HeaderBackground image={null} useSurface={true} />
108
104
  ),
109
105
  };
110
106
  } else {
package/Button/index.tsx CHANGED
@@ -58,7 +58,7 @@ export interface ButtonProps extends TouchableOpacityProps {
58
58
  /**
59
59
  * If true, the icon of button will use the tint color provided by its container.
60
60
  */
61
- useTintColor?: boolean;
61
+ tintColor?: string;
62
62
 
63
63
  /**
64
64
  * If true, the icon of button will use be show indicator loading.
@@ -76,7 +76,7 @@ export interface ButtonProps extends TouchableOpacityProps {
76
76
  const Button: FC<ButtonProps> = ({
77
77
  type = 'primary',
78
78
  size = 'large',
79
- useTintColor = true,
79
+ tintColor = null,
80
80
  full = true,
81
81
  iconRight,
82
82
  iconLeft,
@@ -231,7 +231,7 @@ const Button: FC<ButtonProps> = ({
231
231
  const renderLeading = () => {
232
232
  const iconSize = getIconSize();
233
233
  const marginRight = getIconSpace();
234
- const color = useTintColor ? getTextColor() : undefined;
234
+ const color = tintColor ?? getTextColor();
235
235
 
236
236
  if (loading) {
237
237
  return (
@@ -245,7 +245,7 @@ const Button: FC<ButtonProps> = ({
245
245
  borderRadius: Spacing.M,
246
246
  },
247
247
  ]}>
248
- <Loader type="spinner" color={color} />
248
+ <Loader type="spinner" color={getTextColor()} />
249
249
  </View>
250
250
  );
251
251
  }
@@ -266,7 +266,7 @@ const Button: FC<ButtonProps> = ({
266
266
  * render trailing
267
267
  */
268
268
  const renderTrailing = () => {
269
- const color = useTintColor ? getTextColor() : undefined;
269
+ const color = tintColor ?? getTextColor();
270
270
  const marginLeft = getIconSpace();
271
271
 
272
272
  if (iconRight) {
@@ -76,7 +76,6 @@ const InputMoney = forwardRef(
76
76
  clear: onClearText,
77
77
  focus: () => inputRef.current?.focus(),
78
78
  blur: () => inputRef.current?.blur(),
79
- changeText: (text: string) => _onChangeText(text),
80
79
  setText: _onChangeText,
81
80
  };
82
81
  });
package/Input/common.tsx CHANGED
@@ -16,13 +16,6 @@ type FloatingViewProps = {
16
16
  style?: ViewStyle;
17
17
  };
18
18
 
19
- export interface InputRef {
20
- focus: () => void;
21
- blur: () => void;
22
- clear: () => void;
23
- setText: (text: string) => void;
24
- }
25
-
26
19
  export const DEFAULT_HEIGHT = scaleSize(104);
27
20
  export const MAX_LENGTH = 300;
28
21
 
package/Input/index.tsx CHANGED
@@ -6,6 +6,13 @@ import InputOTP from './InputOTP';
6
6
  import InputSearch from './InputSearch';
7
7
  import InputTextArea from './InputTextArea';
8
8
 
9
+ export interface InputRef {
10
+ focus: () => void;
11
+ blur: () => void;
12
+ clear: () => void;
13
+ setText: (text: string) => void;
14
+ }
15
+
9
16
  export interface InputProps extends TextInputProps {
10
17
  /**
11
18
  * Optional. Defines the size of the Input component.
@@ -45,7 +45,7 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
45
45
  if (!label) return;
46
46
 
47
47
  const listener = animatedValue?.addListener(({value}) => {
48
- if (value !== lastOffset.current) {
48
+ if (value !== lastOffset.current && value > 0) {
49
49
  const direction = value > lastOffset.current ? 'down' : 'up';
50
50
  lastOffset.current = value;
51
51
  if (lastDirection.current !== direction) {
package/Layout/Screen.tsx CHANGED
@@ -89,6 +89,10 @@ export interface ScreenProps extends ViewProps {
89
89
  */
90
90
  floatingButtonProps?: Omit<FloatingButtonProps, 'animatedValue' | 'bottom'>;
91
91
 
92
+ /**
93
+ * optional animated value
94
+ */
95
+ animatedValue?: Animated.Value;
92
96
  /**
93
97
  * Optional. If `true`, the screen content is using grid layout by span.
94
98
  */
@@ -111,10 +115,13 @@ const Screen = forwardRef(
111
115
  headerType = 'default',
112
116
  floatingButtonProps,
113
117
  useGridLayout = true,
118
+ animatedValue: animated,
114
119
  }: ScreenProps,
115
120
  ref,
116
121
  ) => {
117
- const animatedValue = useRef<Animated.Value>(new Animated.Value(0));
122
+ const animatedValue = useRef<Animated.Value>(
123
+ animated ?? new Animated.Value(0),
124
+ );
118
125
  const {theme} = useContext(ApplicationContext);
119
126
  const insets = useSafeAreaInsets();
120
127
  const heightHeader = useHeaderHeight();
@@ -151,18 +158,27 @@ const Screen = forwardRef(
151
158
  };
152
159
  if (animatedHeader.type == 'surface') {
153
160
  styleAnimatedHeader = {
154
- headerTransparent: true,
161
+ ...styleAnimatedHeader,
155
162
  headerBackground: (props: any) => (
156
163
  <HeaderBackground
157
164
  {...props}
158
165
  image={null}
159
- backgroundColor={theme.colors.background.surface}
160
- useBorder={true}
166
+ useSurface={true}
161
167
  animatedValue={animatedValue.current}
162
168
  />
163
169
  ),
164
170
  };
165
171
  }
172
+ if (animatedHeader.headerTitle) {
173
+ styleAnimatedHeader = {
174
+ ...styleAnimatedHeader,
175
+ headerTitle: (props: any) =>
176
+ animatedHeader.headerTitle?.({
177
+ ...props,
178
+ animatedValue: animatedValue.current,
179
+ }),
180
+ };
181
+ }
166
182
  navigation?.setOptions(styleAnimatedHeader);
167
183
  }
168
184
  }, [animatedHeader]);
@@ -185,12 +201,7 @@ const Screen = forwardRef(
185
201
  headerShown: true,
186
202
  headerTintColor: theme.colors.text.default,
187
203
  headerBackground: (props: any) => (
188
- <HeaderBackground
189
- {...props}
190
- image={null}
191
- backgroundColor={theme.colors.background.surface}
192
- useBorder={true}
193
- />
204
+ <HeaderBackground {...props} image={null} useSurface={true} />
194
205
  ),
195
206
  headerTitle: (props: any) => <HeaderTitle {...props} />,
196
207
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.77.1-optimzie.4",
3
+ "version": "0.77.1-optimzie.6",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {},