@momo-kits/foundation 0.92.21-beta.2 → 0.92.21-beta.4

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.
@@ -125,7 +125,7 @@ export default function BottomTabBar({
125
125
  );
126
126
  });
127
127
  },
128
- [JSON.stringify(routes), state, descriptors, focusedTab],
128
+ [JSON.stringify(routes), state, descriptors, focusedTab]
129
129
  );
130
130
 
131
131
  /**
@@ -153,7 +153,7 @@ export default function BottomTabBar({
153
153
  </View>
154
154
  <View
155
155
  style={{
156
- top: -6,
156
+ top: -4,
157
157
  backgroundColor: activeTintColor ?? theme.colors.primary,
158
158
  borderRadius: Radius.XL,
159
159
  paddingHorizontal: 6,
@@ -101,7 +101,7 @@ const BottomTab: React.FC<BottomTabProps> = ({
101
101
  name={item.name}
102
102
  component={TabScreen}
103
103
  initialParams={{...item, nested}}
104
- listeners={listeners}
104
+ listeners={item.listeners ?? listeners}
105
105
  options={{
106
106
  tabBarLabel: ({color, focused}) => {
107
107
  return (
@@ -1,9 +1,8 @@
1
1
  import React, {
2
- FC,
2
+ Fragment,
3
3
  useCallback,
4
4
  useContext,
5
5
  useEffect,
6
- useRef,
7
6
  useState,
8
7
  } from 'react';
9
8
  import {
@@ -84,6 +83,11 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
84
83
 
85
84
  const HeaderTitle: React.FC<any> = props => {
86
85
  const {theme} = useContext(ApplicationContext);
86
+ const opacity = props.animatedValue?.interpolate({
87
+ inputRange: [0, 200],
88
+ outputRange: [0, 1],
89
+ extrapolate: 'clamp',
90
+ });
87
91
 
88
92
  return (
89
93
  <Animated.Text
@@ -91,11 +95,7 @@ const HeaderTitle: React.FC<any> = props => {
91
95
  accessibilityLabel={'title_navigation_header'}
92
96
  style={[
93
97
  styles.title,
94
- {
95
- fontFamily: `${theme.font}-Bold`,
96
- color: props.tintColor,
97
- opacity: props.titleOpacity,
98
- },
98
+ {fontFamily: `${theme.font}-Bold`, opacity, color: props.tintColor},
99
99
  ]}
100
100
  />
101
101
  );
@@ -113,7 +113,7 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
113
113
  useEffect(() => {
114
114
  const backHandler = BackHandler.addEventListener(
115
115
  'hardwareBackPress',
116
- goBackSafe
116
+ goBackSafe,
117
117
  );
118
118
 
119
119
  return () => backHandler.remove();
@@ -263,40 +263,35 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
263
263
  return <View style={styles.headerTitleContainer}>{content ?? header}</View>;
264
264
  };
265
265
 
266
- const HeaderRight: FC<any> = ({type, ...props}) => {
267
- let buttons = props?.buttons || [];
268
- if (!type) {
269
- return <View />;
270
- }
266
+ const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
267
+ const validateType = (child: React.ReactElement) => {
268
+ const valid = child?.type === NavigationButton || child?.type === Fragment;
269
+ if (__DEV__ && !valid) {
270
+ console.warn(
271
+ 'HeaderRightAction contains element type of NavigationButton, Please check again.',
272
+ );
273
+ }
274
+ return child;
275
+ };
271
276
 
272
- if (type === 'iconButton') {
273
- if (buttons?.length > 3) {
274
- buttons = buttons.slice(0, 3);
277
+ const renderAction = () => {
278
+ if (Array.isArray(children)) {
279
+ return children.map((child, index) => {
280
+ return (
281
+ <View key={`HeaderRightAction ${index}`} style={styles.headerButton}>
282
+ {React.cloneElement(validateType(child), {...restProps})}
283
+ </View>
284
+ );
285
+ });
275
286
  }
287
+
276
288
  return (
277
- <View style={styles.headerRightButton}>
278
- {buttons?.map?.(
279
- ({icon, onPress}: NavigationButtonProps, index: number) => {
280
- return (
281
- <View
282
- key={`HeaderRightAction ${index}`}
283
- style={{
284
- marginLeft: index !== 0 ? Spacing.S : 0,
285
- }}>
286
- <NavigationButton
287
- icon={icon}
288
- onPress={onPress}
289
- tintColor={props?.tintColor}
290
- />
291
- </View>
292
- );
293
- }
294
- )}
289
+ <View style={styles.headerButton}>
290
+ {React.cloneElement(validateType(children), {...restProps})}
295
291
  </View>
296
292
  );
297
- }
298
-
299
- return <HeaderToolkitAction {...props} />;
293
+ };
294
+ return <View style={styles.headerRightButton}>{renderAction()}</View>;
300
295
  };
301
296
 
302
297
  const HeaderToolkitAction: React.FC<any> = ({
@@ -332,7 +327,7 @@ const HeaderToolkitAction: React.FC<any> = ({
332
327
  (config: any) => {
333
328
  navigator.toolkitConfig = config;
334
329
  setToolConfig(navigator?.toolkitConfig);
335
- }
330
+ },
336
331
  );
337
332
  };
338
333
 
@@ -345,7 +340,7 @@ const HeaderToolkitAction: React.FC<any> = ({
345
340
  const {item} = res;
346
341
  navigator?.toolkitCallback?.(item);
347
342
  getToolkitConfig();
348
- }
343
+ },
349
344
  );
350
345
  };
351
346
 
@@ -362,7 +357,7 @@ const HeaderToolkitAction: React.FC<any> = ({
362
357
  navigator?.maxApi?.dispatchFunction?.(
363
358
  'dismiss',
364
359
  undefined,
365
- undefined
360
+ undefined,
366
361
  );
367
362
  },
368
363
  }}
@@ -393,7 +388,7 @@ const HeaderToolkitAction: React.FC<any> = ({
393
388
  [pinTool?.key],
394
389
  () => {
395
390
  getToolkitConfig();
396
- }
391
+ },
397
392
  );
398
393
  navigator?.toolkitCallback?.(pinTool.key);
399
394
  }}
@@ -410,7 +405,6 @@ const HeaderToolkitAction: React.FC<any> = ({
410
405
  {
411
406
  backgroundColor: backgroundColor ?? '#00000066',
412
407
  borderWidth: backgroundColor ? 0.5 : 0,
413
- marginLeft: renderPinnedTool() ? Spacing.S : 0,
414
408
  },
415
409
  ]}>
416
410
  <TouchableOpacity
@@ -476,42 +470,6 @@ const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
476
470
  );
477
471
  };
478
472
 
479
- const ExtendBackground: FC<{
480
- headerBackground: string;
481
- animatedValue: Animated.Value;
482
- heightHeader: number;
483
- }> = ({headerBackground, animatedValue, heightHeader}) => {
484
- const heightAnimated = useRef(new Animated.Value(0));
485
- useEffect(() => {
486
- const listener = animatedValue.addListener(({value}) => {
487
- heightAnimated.current.setValue(value);
488
- });
489
- return () => {
490
- animatedValue?.removeListener(listener);
491
- };
492
- }, []);
493
-
494
- return (
495
- <>
496
- <Image
497
- source={{
498
- uri: headerBackground,
499
- }}
500
- style={styles.extendedHeader}
501
- />
502
- <Animated.View
503
- style={{
504
- height: heightAnimated.current.interpolate({
505
- inputRange: [0, 100],
506
- outputRange: [heightHeader, heightHeader - 52],
507
- extrapolate: 'clamp',
508
- }),
509
- }}
510
- />
511
- </>
512
- );
513
- };
514
-
515
473
  const styles = StyleSheet.create({
516
474
  navigationButton: {
517
475
  height: 28,
@@ -551,6 +509,7 @@ const styles = StyleSheet.create({
551
509
  paddingRight: Spacing.M,
552
510
  },
553
511
  toolkitContainer: {
512
+ marginLeft: Spacing.S,
554
513
  padding: Spacing.XS,
555
514
  height: 28,
556
515
  borderRadius: 14,
@@ -582,12 +541,6 @@ const styles = StyleSheet.create({
582
541
  top: -Spacing.XS,
583
542
  right: -Spacing.XS,
584
543
  },
585
- extendedHeader: {
586
- aspectRatio: 1.75,
587
- position: 'absolute',
588
- width: '100%',
589
- height: 210,
590
- },
591
544
  });
592
545
 
593
546
  export {
@@ -595,9 +548,8 @@ export {
595
548
  HeaderTitle,
596
549
  HeaderLeft,
597
550
  HeaderBackground,
551
+ HeaderRightAction,
598
552
  HeaderToolkitAction,
599
553
  HeaderCustom,
600
554
  HeaderAnimated,
601
- HeaderRight,
602
- ExtendBackground,
603
555
  };
@@ -1,6 +1,9 @@
1
+ import React from 'react';
1
2
  import {NavigationProp} from '@react-navigation/native';
2
3
  import {NavigationOptions, Theme} from './types';
4
+ import {HeaderRightAction} from './index';
3
5
  import {getOptions} from './utils';
6
+ import {HeaderToolkitAction} from './Components';
4
7
 
5
8
  class Navigation {
6
9
  instance: NavigationProp<any>;
@@ -16,6 +19,16 @@ class Navigation {
16
19
  * @param params
17
20
  */
18
21
  private filterParams = (params: NavigationOptions) => {
22
+ if (params.headerRight) {
23
+ const headerRight = params.headerRight?.({}) as React.ReactElement;
24
+ const type = headerRight?.type;
25
+ if (type !== HeaderRightAction && type !== HeaderToolkitAction) {
26
+ console.warn(
27
+ 'headerRight contains element type of HeaderRightAction | HeaderToolkitAction, Please check again.',
28
+ );
29
+ }
30
+ }
31
+
19
32
  if (params.headerLeft) {
20
33
  console.warn('headerLeft not allow override render by design system!');
21
34
  delete params.headerLeft;
@@ -1,4 +1,5 @@
1
1
  import {StackNavigationOptions} from '@react-navigation/stack';
2
+ import {EventArg} from '@react-navigation/core';
2
3
  import React from 'react';
3
4
  import {Animated, ViewProps} from 'react-native';
4
5
  import {PopupNotifyProps} from '../Popup/types';
@@ -144,29 +145,19 @@ export type RuntimeToolType = {
144
145
  key: string;
145
146
  };
146
147
 
147
- export interface NavigationOptions
148
- extends Omit<StackNavigationOptions, 'headerRight'> {
148
+ export interface NavigationOptions extends StackNavigationOptions {
149
149
  preventBack?: PopupNotifyProps;
150
150
  onPressLeftHeader?: () => void;
151
151
  surface?: boolean;
152
152
  hiddenBack?: boolean;
153
153
  customTitle?: TitleCustomProps;
154
- headerRight?: HeaderRightToolkit | HeaderRightActions | Element;
154
+ toolkitParams?: {
155
+ pinnedTool?: PinnedToolType;
156
+ runtimeTools?: RuntimeToolType[];
157
+ preventClose?: PopupNotifyProps;
158
+ };
155
159
  }
156
160
 
157
- export type HeaderRightToolkit = {
158
- type?: 'toolkit';
159
- pinnedTool?: PinnedToolType;
160
- runtimeTools?: RuntimeToolType[];
161
- preventClose?: PopupNotifyProps;
162
- useMore?: boolean;
163
- };
164
-
165
- export type HeaderRightActions = {
166
- type?: 'iconButton';
167
- buttons: NavigationButtonProps[];
168
- };
169
-
170
161
  export interface HeaderBackProps extends NavigationButtonProps {
171
162
  preventBack?: PopupNotifyProps;
172
163
  onPressLeftHeader?: () => void;
@@ -208,6 +199,11 @@ export type BottomTabItemProps = {
208
199
  screen: Screen;
209
200
  options: NavigationOptions;
210
201
  initialParams?: any;
202
+ listeners?: {
203
+ tabPress?: (e: EventArg<'tabPress', true, undefined>) => void;
204
+ focus?: (e: EventArg<'focus', false, unknown>) => void;
205
+ blur?: (e: EventArg<'blur', false, unknown>) => void;
206
+ };
211
207
  };
212
208
 
213
209
  export type BottomTabProps = {
@@ -216,8 +212,9 @@ export type BottomTabProps = {
216
212
  initialRouteName?: string;
217
213
  navigation: Navigation;
218
214
  listeners?: {
219
- tabPress?: any;
220
- focus?: any;
215
+ tabPress?: (e: EventArg<'tabPress', true, undefined>) => void;
216
+ focus?: (e: EventArg<'focus', false, unknown>) => void;
217
+ blur?: (e: EventArg<'blur', false, unknown>) => void;
221
218
  };
222
219
  floatingButton?: FloatingButtonProps;
223
220
  };
@@ -122,6 +122,15 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
122
122
  };
123
123
  }
124
124
 
125
+ if (params.toolkitParams) {
126
+ options = {
127
+ ...options,
128
+ headerRight: (props: any) => {
129
+ return <HeaderToolkitAction {...params.toolkitParams} {...props} />;
130
+ },
131
+ };
132
+ }
133
+
125
134
  return {
126
135
  ...params,
127
136
  ...options,
package/Button/index.tsx CHANGED
@@ -297,6 +297,7 @@ const Button: FC<ButtonProps> = ({
297
297
  };
298
298
 
299
299
  const activeOpacity = type === 'disabled' ? 0.75 : 0.5;
300
+
300
301
  return (
301
302
  <ComponentContext.Provider
302
303
  value={{
package/Icon/types.ts CHANGED
@@ -16,7 +16,6 @@ export type IconProps = {
16
16
 
17
17
  /**
18
18
  * Optional. Represents the color of the icon.
19
- * It can be any valid color in @momo-kits/foundation.
20
19
  */
21
20
  color?: string | null;
22
21
 
@@ -4,7 +4,7 @@ import {ApplicationContext, ComponentContext} from '../Application';
4
4
  import {Styles} from '../Consts';
5
5
  import {Icon} from '../Icon';
6
6
  import {Loader} from '../Loader';
7
- import {ErrorView, FloatingView, getSizeStyle} from './common';
7
+ import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
8
8
  import {InputDropDownProps} from './index';
9
9
  import styles from './styles';
10
10
 
@@ -61,7 +61,7 @@ const InputDropDown = ({
61
61
  styles.inputWrapper,
62
62
  {backgroundColor: theme.colors.background.surface},
63
63
  getSizeStyle(size),
64
- // getBorderColor(theme, false, errorMessage, disabled),
64
+ getBorderColor(theme, false, errorMessage, disabled),
65
65
  ]}>
66
66
  <FloatingView
67
67
  floatingValue={floatingValue}
@@ -44,7 +44,7 @@ const InputMoney = forwardRef(
44
44
  value: _value,
45
45
  ...props
46
46
  }: InputMoneyProps,
47
- ref
47
+ ref,
48
48
  ) => {
49
49
  const {theme} = useContext(ApplicationContext);
50
50
  const [focused, setFocused] = useState(false);
@@ -63,7 +63,7 @@ const InputMoney = forwardRef(
63
63
  };
64
64
 
65
65
  const [value, setValue] = useState(
66
- defaultValue ? validateText(defaultValue) : ''
66
+ defaultValue ? validateText(defaultValue) : '',
67
67
  );
68
68
 
69
69
  const onClearText = () => {
@@ -198,7 +198,7 @@ const InputMoney = forwardRef(
198
198
  </View>
199
199
  </ComponentContext.Provider>
200
200
  );
201
- }
201
+ },
202
202
  );
203
203
 
204
204
  export default InputMoney;
@@ -41,7 +41,7 @@ const OTPCaret: FC<CaretProps> = ({index, length}) => {
41
41
  duration: DURATION,
42
42
  useNativeDriver: true,
43
43
  }),
44
- ])
44
+ ]),
45
45
  ).start();
46
46
  }, []);
47
47
  const spacingStyle = !isNaN(Number(length)) &&
@@ -81,7 +81,7 @@ const InputOTP = forwardRef(
81
81
  hintText,
82
82
  ...props
83
83
  }: InputOTPProps,
84
- ref
84
+ ref,
85
85
  ) => {
86
86
  const MAX_LENGTH = 10;
87
87
  const [value, setValue] = useState('');
@@ -143,7 +143,7 @@ const InputOTP = forwardRef(
143
143
  {value[i] || '-'}
144
144
  </Text>
145
145
  )}
146
- </View>
146
+ </View>,
147
147
  );
148
148
  }
149
149
  return TextInputs;
@@ -248,7 +248,7 @@ const InputOTP = forwardRef(
248
248
  </TouchableOpacity>
249
249
  </ComponentContext.Provider>
250
250
  );
251
- }
251
+ },
252
252
  );
253
253
 
254
254
  export default InputOTP;