@momo-kits/foundation 0.75.2-beta.0 → 0.75.4-beta.0

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.
@@ -4,10 +4,10 @@ import {
4
4
  LayoutChangeEvent,
5
5
  StyleSheet,
6
6
  TouchableOpacity,
7
+ View,
7
8
  } from 'react-native';
8
9
  import {ApplicationContext} from '../Application';
9
10
  import {Icon} from '../Icon';
10
- import {Text} from '../Text';
11
11
 
12
12
  export interface FloatingButtonProps {
13
13
  label?: string;
@@ -18,9 +18,11 @@ export interface FloatingButtonProps {
18
18
  size?: 'small' | 'large';
19
19
  animatedValue?: Animated.Value;
20
20
  bottom?: number;
21
+ renderComponent?: () => React.ReactNode;
21
22
  }
22
23
 
23
24
  export const FloatingButton: React.FC<FloatingButtonProps> = ({
25
+ renderComponent,
24
26
  label = '',
25
27
  onPress = () => {},
26
28
  position = 'right',
@@ -33,33 +35,52 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
33
35
  const {theme} = useContext(ApplicationContext);
34
36
  const maxWidth = useRef(0);
35
37
  const minWidth = size == 'small' ? 36 : 48;
38
+ const [opacityAnimated] = useState(new Animated.Value(0)); // Initial opacity set to 0
36
39
  const [widthAnimated, setWidthAnimated] = useState<Animated.Value>();
37
40
  const lastOffset = useRef(0);
38
- const debounce = useRef<any>();
41
+ const lastDirection = useRef<string>();
39
42
  const [showText, setShowText] = React.useState(true);
40
43
 
41
44
  useEffect(() => {
42
45
  if (!label) return;
43
46
 
47
+ Animated.timing(opacityAnimated, {
48
+ toValue: 1,
49
+ duration: 100,
50
+ useNativeDriver: true,
51
+ }).start();
52
+
44
53
  const listener = animatedValue?.addListener(({value}) => {
45
- clearTimeout(debounce.current);
46
- debounce.current = setTimeout(() => {
47
- const down = value > lastOffset.current;
54
+ if (value !== lastOffset.current && value > 0) {
55
+ const direction = value > lastOffset.current ? 'down' : 'up';
48
56
  lastOffset.current = value;
49
- if (down) {
50
- Animated.timing(widthAnimated!, {
51
- toValue: minWidth,
52
- duration: 300,
53
- useNativeDriver: false,
54
- }).start(() => setShowText(false));
55
- } else {
56
- Animated.timing(widthAnimated!, {
57
- toValue: maxWidth.current,
58
- duration: 300,
59
- useNativeDriver: false,
60
- }).start(() => setShowText(true));
57
+ if (lastDirection.current !== direction) {
58
+ lastDirection.current = direction;
59
+ if (direction === 'down') {
60
+ Animated.timing(opacityAnimated, {
61
+ toValue: 0,
62
+ duration: 100,
63
+ useNativeDriver: true,
64
+ }).start();
65
+ Animated.timing(widthAnimated!, {
66
+ toValue: minWidth,
67
+ duration: 100,
68
+ useNativeDriver: false,
69
+ }).start(() => setShowText(false));
70
+ } else {
71
+ Animated.timing(opacityAnimated, {
72
+ toValue: 1,
73
+ duration: 100,
74
+ useNativeDriver: true,
75
+ }).start();
76
+ Animated.timing(widthAnimated!, {
77
+ toValue: maxWidth.current,
78
+ duration: 100,
79
+ useNativeDriver: false,
80
+ }).start(() => setShowText(true));
81
+ }
61
82
  }
62
- }, 500);
83
+ }
63
84
  });
64
85
 
65
86
  return () => {
@@ -76,6 +97,23 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
76
97
  setWidthAnimated(new Animated.Value(layout.width));
77
98
  };
78
99
 
100
+ if (renderComponent) {
101
+ return (
102
+ <View
103
+ onLayout={handleLayout}
104
+ style={[
105
+ styles.container,
106
+ {
107
+ right: position === 'right' ? 12 : undefined,
108
+ alignSelf: position === 'center' ? 'center' : 'flex-end',
109
+ bottom,
110
+ },
111
+ ]}>
112
+ {renderComponent()}
113
+ </View>
114
+ );
115
+ }
116
+
79
117
  return (
80
118
  <Animated.View
81
119
  onLayout={handleLayout}
@@ -99,12 +137,11 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
99
137
  color={iconColor}
100
138
  />
101
139
  {showText && !!label && (
102
- <Text
103
- style={styles.label}
104
- color="white"
105
- typography="action_default_bold">
140
+ <Animated.Text
141
+ style={[styles.label, {opacity: opacityAnimated, color: 'white'}]}
142
+ numberOfLines={1}>
106
143
  {label}
107
- </Text>
144
+ </Animated.Text>
108
145
  )}
109
146
  </TouchableOpacity>
110
147
  </Animated.View>
@@ -124,5 +161,8 @@ const styles = StyleSheet.create({
124
161
  },
125
162
  label: {
126
163
  marginLeft: 8,
164
+ fontSize: 16,
165
+ lineHeight: 22,
166
+ fontWeight: '700',
127
167
  },
128
168
  });
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
  };
@@ -234,8 +245,9 @@ const Screen = forwardRef(
234
245
  },
235
246
  ],
236
247
  {
237
- useNativeDriver: false,
248
+ useNativeDriver: true,
238
249
  listener: (e: NativeSyntheticEvent<NativeScrollEvent>) => {
250
+ scrollViewProps?.onScroll?.(e);
239
251
  if (animatedHeader?.type == 'surface') {
240
252
  const offsetY = e.nativeEvent.contentOffset.y;
241
253
  let color = Colors.black_01;
@@ -199,16 +199,20 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
199
199
  {title}
200
200
  </Text>
201
201
  <Description style={[styles.description, descriptionStyle]}>
202
- <Text
203
- typography={'body_default_regular'}
204
- onTextLayout={({nativeEvent: {lines}}) => {
205
- const enableScroll = lines.length > 3;
206
- if (enableScroll != scrollContent) {
207
- setScrollContent(enableScroll);
208
- }
209
- }}>
210
- {description}
211
- </Text>
202
+ {typeof description === 'string' ? (
203
+ <Text
204
+ typography={'body_default_regular'}
205
+ onTextLayout={({nativeEvent: {lines}}) => {
206
+ const enableScroll = lines.length > 3;
207
+ if (enableScroll != scrollContent) {
208
+ setScrollContent(enableScroll);
209
+ }
210
+ }}>
211
+ {description}
212
+ </Text>
213
+ ) : (
214
+ description
215
+ )}
212
216
  </Description>
213
217
  {!!error && (
214
218
  <View style={styles.information}>
package/Title/index.tsx CHANGED
@@ -1,13 +1,16 @@
1
1
  import React, {FC, useContext, useState} from 'react';
2
2
  import {Text as RNText, TouchableOpacity, View, ViewStyle} from 'react-native';
3
+ import {
4
+ Typography,
5
+ Colors,
6
+ Icon,
7
+ Badge,
8
+ ApplicationContext,
9
+ scaleSize,
10
+ Text,
11
+ } from '@momo-kits/foundation';
3
12
  import styles from './styles';
4
- import {Icon} from '../Icon';
5
- import {scaleSize, Text} from '../Text';
6
- import {ApplicationContext} from '../Application';
7
- import {Badge} from '../Badge';
8
- import {Typography} from '../Text/types';
9
13
  import {TitleProps} from './types';
10
- import {Colors} from '../Consts';
11
14
 
12
15
  const Title: FC<TitleProps> = ({
13
16
  title = 'Title',
@@ -67,7 +70,9 @@ const Title: FC<TitleProps> = ({
67
70
  <View style={styles.contentView}>
68
71
  <View
69
72
  onLayout={e => {
70
- setContentWidth(e.nativeEvent.layout.width);
73
+ if (e.nativeEvent.layout.width !== contentWidth) {
74
+ setContentWidth(e.nativeEvent.layout.width);
75
+ }
71
76
  }}
72
77
  style={[styles.iconLeftView, flexStyle]}>
73
78
  <RNText
@@ -75,14 +80,19 @@ const Title: FC<TitleProps> = ({
75
80
  style={[
76
81
  styleSheet[typography],
77
82
  styles.title,
78
- {maxWidth: contentWidth - badgeWidth},
83
+ {
84
+ maxWidth:
85
+ contentWidth > 0 ? contentWidth - badgeWidth : undefined,
86
+ },
79
87
  ]}>
80
88
  {title}
81
89
  </RNText>
82
90
  {badgeLabel && (
83
91
  <View
84
92
  onLayout={e => {
85
- setBadgeWidth(e.nativeEvent.layout.width);
93
+ if (e.nativeEvent.layout.width !== badgeWidth) {
94
+ setBadgeWidth(e.nativeEvent.layout.width);
95
+ }
86
96
  }}
87
97
  style={{
88
98
  alignItems: 'center',
@@ -164,6 +174,7 @@ const Title: FC<TitleProps> = ({
164
174
  if (textOnly) {
165
175
  return (
166
176
  <View style={isSection && styles.margin}>
177
+ zZ
167
178
  <RNText
168
179
  numberOfLines={numberOfLines}
169
180
  style={[styleSheet[typography], styles.title]}>
package/index.ts CHANGED
@@ -4,12 +4,11 @@ import {
4
4
  useSafeAreaInsets,
5
5
  } from 'react-native-safe-area-context';
6
6
  import LinearGradient from 'react-native-linear-gradient';
7
- import {getAccessibilityID} from "./Application/utils";
8
7
 
9
8
  /**
10
9
  * native export
11
10
  */
12
- export {SafeAreaView, useSafeAreaInsets, SafeAreaProvider, LinearGradient, getAccessibilityID};
11
+ export {SafeAreaView, useSafeAreaInsets, SafeAreaProvider, LinearGradient};
13
12
 
14
13
  /**
15
14
  * foundation component
@@ -50,3 +49,10 @@ export * from './Title';
50
49
  export * from './Title/types';
51
50
  export * from './Badge';
52
51
  export * from './Badge/types';
52
+
53
+ /**
54
+ * export trick for keep old mini app working
55
+ * @deprecated
56
+ */
57
+ export * from 'react-native-modalize';
58
+ export * from '@gorhom/bottom-sheet';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.75.2-beta.0",
3
+ "version": "0.75.4-beta.0",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {},
@@ -9,17 +9,17 @@
9
9
  ],
10
10
  "dependencies": {
11
11
  "@gorhom/bottom-sheet": "2.4.1",
12
+ "react-native-safe-area-context": "3.1.4",
13
+ "react-native-linear-gradient": "2.8.3",
14
+ "react-native-gesture-handler": "1.10.3",
15
+ "react-native-modalize": "2.1.1",
16
+ "react-native-fast-image": "8.1.5",
12
17
  "@react-navigation/bottom-tabs": "https://oauth2:5WXQLHPMxxCyvGt_Py4D@gitlab.mservice.com.vn/momo-platform/react-native-bottom-tabs.git",
13
18
  "@react-navigation/core": "5.16.1",
14
19
  "@react-navigation/native": "5.9.8",
15
20
  "@react-navigation/routers": "5.7.4",
16
- "@react-navigation/stack": "https://oauth2:eX-jVhzQdLc343AjD3Sc@gitlab.mservice.com.vn/momo-platform/react-navigation-stack.git",
17
21
  "lottie-react-native": "3.3.2",
18
- "react-native-fast-image": "8.1.5",
19
- "react-native-gesture-handler": "1.10.3",
20
- "react-native-linear-gradient": "2.8.3",
21
- "react-native-modalize": "2.1.1",
22
- "react-native-safe-area-context": "3.1.4"
22
+ "@react-navigation/stack": "https://oauth2:eX-jVhzQdLc343AjD3Sc@gitlab.mservice.com.vn/momo-platform/react-navigation-stack.git"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "react-native": "*"
@@ -27,19 +27,19 @@
27
27
  "devDependencies": {
28
28
  "@babel/core": "^7.12.9",
29
29
  "@babel/runtime": "^7.12.5",
30
- "@momo-platform/versions": "4.1.11",
31
30
  "@react-native-community/eslint-config": "^2.0.0",
32
- "@types/d3-shape": "1.3.7",
33
31
  "@types/jest": "26.0.23",
34
32
  "@types/react-native": "0.64.4",
35
33
  "@types/react-test-renderer": "16.9.2",
34
+ "@types/d3-shape": "1.3.7",
36
35
  "babel-jest": "^26.6.3",
37
36
  "eslint": "^7.14.0",
38
37
  "jest": "^26.6.3",
39
38
  "metro-react-native-babel-preset": "^0.64.0",
40
- "react-scanner": "^1.1.0",
41
39
  "react-test-renderer": "17.0.1",
42
- "typescript": "^4.0.3"
40
+ "typescript": "^4.0.3",
41
+ "@momo-platform/versions": "4.1.11",
42
+ "react-scanner": "^1.1.0"
43
43
  },
44
44
  "author": "@momo-kits/foundation",
45
45
  "license": "ISC"