@momo-kits/foundation 0.92.23 → 0.92.25

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/Layout/Screen.tsx CHANGED
@@ -27,12 +27,10 @@ import Navigation from '../Application/Navigation';
27
27
  import {AnimatedHeader, NavigationOptions} from '../Application/types';
28
28
  import {Colors, Spacing, Styles} from '../Consts';
29
29
  import {FloatingButton, FloatingButtonProps} from './FloatingButton';
30
+ import {Image} from '../Image';
30
31
  import {Card, Section, validateChildren} from './index';
31
32
  import styles from './styles';
32
33
  import {HeaderType} from './types';
33
- import AnimatedInputSearch from './AnimatedInputSearch';
34
- import {InputSearchProps} from '../Input';
35
- import {HeaderExtendBackground} from '../Application/Components';
36
34
 
37
35
  export interface ScreenProps extends ViewProps {
38
36
  /**
@@ -103,11 +101,6 @@ export interface ScreenProps extends ViewProps {
103
101
  * Optional. If `true`, the screen content is using grid layout by span.
104
102
  */
105
103
  useGridLayout?: boolean;
106
-
107
- /**
108
- * Optional. specs for input search.
109
- */
110
- inputSearchProps?: InputSearchProps;
111
104
  }
112
105
 
113
106
  const Screen = forwardRef(
@@ -127,79 +120,32 @@ const Screen = forwardRef(
127
120
  floatingButtonProps,
128
121
  useGridLayout = true,
129
122
  keyboardVerticalOffset,
130
- inputSearchProps,
131
123
  }: ScreenProps,
132
- ref
124
+ ref,
133
125
  ) => {
126
+ const animatedValue = useRef<Animated.Value>(new Animated.Value(0));
134
127
  const {theme} = useContext(ApplicationContext);
135
128
  const insets = useSafeAreaInsets();
136
129
  const heightHeader = useHeaderHeight();
137
- const animatedValue = useRef<Animated.Value>(new Animated.Value(0));
138
- const scrollViewRef = useRef<any>(ref);
139
130
  const currentTint = useRef(Colors.black_01);
140
- const isTab = navigation?.instance?.getState?.()?.type === 'tab';
131
+ const isTab = navigation?.instance?.getState?.()?.type == 'tab';
141
132
 
133
+ let styleAnimatedHeader: NavigationOptions;
142
134
  let handleScroll;
143
135
  let headerBackground: string | undefined = undefined;
144
136
  let Component: any = View;
145
137
  let keyboardOffset = heightHeader - 20;
146
- if (headerType === 'extended' || animatedHeader) {
138
+ if (headerType == 'extended' || animatedHeader) {
147
139
  keyboardOffset = -20;
148
140
  }
149
- if (headerType === 'extended') {
141
+
142
+ if (headerType == 'extended') {
150
143
  headerBackground = theme.assets?.headerBackground;
151
144
  }
152
145
 
153
146
  useEffect(() => {
154
- let options: NavigationOptions;
155
- /**
156
- * handle for basic header type
157
- */
158
- switch (headerType) {
159
- case 'none':
160
- options = {
161
- headerTransparent: true,
162
- headerBackground: () => null,
163
- headerShown: false,
164
- };
165
- break;
166
-
167
- case 'surface':
168
- options = {
169
- headerTransparent: false,
170
- headerShown: true,
171
- headerTintColor: theme.colors.text.default,
172
- headerBackground: (props: any) => (
173
- <HeaderBackground {...props} image={null} useSurface={true} />
174
- ),
175
- headerTitle: (props: any) => <HeaderTitle {...props} />,
176
- };
177
- break;
178
-
179
- case 'extended':
180
- options = {
181
- headerShown: true,
182
- headerTransparent: true,
183
- headerTintColor: Colors.black_01,
184
- headerBackground: () => null,
185
- headerTitle: (props: any) => <HeaderTitle {...props} />,
186
- };
187
- break;
188
-
189
- default:
190
- options = {
191
- headerTransparent: false,
192
- headerShown: true,
193
- headerTintColor: Colors.black_01,
194
- headerBackground: (props: any) => <HeaderBackground {...props} />,
195
- };
196
- }
197
-
198
- /**
199
- * override options for animated header
200
- */
201
147
  if (animatedHeader) {
202
- options = {
148
+ styleAnimatedHeader = {
203
149
  headerTransparent: true,
204
150
  headerBackground: (props: any) => (
205
151
  <HeaderBackground
@@ -211,9 +157,9 @@ const Screen = forwardRef(
211
157
  <HeaderTitle {...props} animatedValue={animatedValue.current} />
212
158
  ),
213
159
  };
214
- if (animatedHeader.type === 'surface') {
215
- options = {
216
- ...options,
160
+ if (animatedHeader.type == 'surface') {
161
+ styleAnimatedHeader = {
162
+ ...styleAnimatedHeader,
217
163
  headerBackground: (props: any) => (
218
164
  <HeaderBackground
219
165
  {...props}
@@ -225,8 +171,8 @@ const Screen = forwardRef(
225
171
  };
226
172
  }
227
173
  if (animatedHeader.headerTitle) {
228
- options = {
229
- ...options,
174
+ styleAnimatedHeader = {
175
+ ...styleAnimatedHeader,
230
176
  headerTitle: (props: any) =>
231
177
  animatedHeader.headerTitle?.({
232
178
  ...props,
@@ -234,10 +180,55 @@ const Screen = forwardRef(
234
180
  }),
235
181
  };
236
182
  }
183
+ navigation?.setOptions(styleAnimatedHeader);
237
184
  }
185
+ }, [animatedHeader]);
238
186
 
239
- navigation?.setOptions(options);
240
- }, [headerType, animatedHeader]);
187
+ useEffect(() => {
188
+ if (!animatedHeader) {
189
+ let headerOptions: NavigationOptions;
190
+ switch (headerType) {
191
+ case 'none':
192
+ headerOptions = {
193
+ headerTransparent: true,
194
+ headerBackground: () => null,
195
+ headerShown: false,
196
+ };
197
+ break;
198
+
199
+ case 'surface':
200
+ headerOptions = {
201
+ headerTransparent: false,
202
+ headerShown: true,
203
+ headerTintColor: theme.colors.text.default,
204
+ headerBackground: (props: any) => (
205
+ <HeaderBackground {...props} image={null} useSurface={true} />
206
+ ),
207
+ headerTitle: (props: any) => <HeaderTitle {...props} />,
208
+ };
209
+ break;
210
+
211
+ case 'extended':
212
+ headerOptions = {
213
+ headerShown: true,
214
+ headerTransparent: true,
215
+ headerTintColor: Colors.black_01,
216
+ headerBackground: () => null,
217
+ headerTitle: (props: any) => <HeaderTitle {...props} />,
218
+ };
219
+ break;
220
+
221
+ default:
222
+ headerOptions = {
223
+ headerTransparent: false,
224
+ headerShown: true,
225
+ headerTintColor: Colors.black_01,
226
+ headerBackground: (props: any) => <HeaderBackground {...props} />,
227
+ };
228
+ }
229
+ navigation?.setOptions(headerOptions);
230
+ }
231
+ }, [headerType]);
241
232
 
242
233
  /**
243
234
  * animated when use scroll && animated value
@@ -245,7 +236,7 @@ const Screen = forwardRef(
245
236
  if (scrollable) {
246
237
  Component = Animated.ScrollView;
247
238
  handleScroll = scrollViewProps?.onScroll;
248
- if (animatedHeader || floatingButtonProps?.icon || inputSearchProps) {
239
+ if (animatedHeader || floatingButtonProps?.icon) {
249
240
  handleScroll = Animated.event(
250
241
  [
251
242
  {
@@ -258,13 +249,13 @@ const Screen = forwardRef(
258
249
  useNativeDriver: true,
259
250
  listener: (e: NativeSyntheticEvent<NativeScrollEvent>) => {
260
251
  scrollViewProps?.onScroll?.(e);
261
- if (animatedHeader?.type === 'surface') {
252
+ if (animatedHeader?.type == 'surface') {
262
253
  const offsetY = e.nativeEvent.contentOffset.y;
263
254
  let color = Colors.black_01;
264
255
  if (offsetY > 50) {
265
256
  color = theme.colors.text.default;
266
257
  }
267
- if (color !== currentTint.current) {
258
+ if (color != currentTint.current) {
268
259
  currentTint.current = color;
269
260
  navigation?.setOptions({
270
261
  headerTintColor: color,
@@ -272,52 +263,31 @@ const Screen = forwardRef(
272
263
  }
273
264
  }
274
265
  },
275
- }
266
+ },
276
267
  );
277
268
  }
278
269
  }
279
270
 
280
- /**
281
- * handle scroll end
282
- * @param e
283
- */
284
- const handleScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
285
- const offsetY = e.nativeEvent.contentOffset.y;
286
- if (inputSearchProps && offsetY < 100 && offsetY > 0) {
287
- Animated.timing(animatedValue.current, {
288
- toValue: 0,
289
- useNativeDriver: true,
290
- duration: 300,
291
- }).start();
292
- scrollViewRef.current?.scrollTo({y: 0, animated: true});
293
- }
294
- scrollViewProps?.onScrollEndDrag?.(e);
295
- };
296
-
297
271
  /**
298
272
  * render top navigation banner
299
273
  */
300
- const renderAnimatedHeader = () => {
274
+ const renderHeader = () => {
301
275
  if (typeof animatedHeader?.component === 'function') {
302
- return (
303
- <View style={[styles.screenBanner, {maxHeight: 210 + layoutOffset}]}>
304
- {animatedHeader?.component({
305
- animatedValue: animatedValue.current,
306
- })}
307
- </View>
308
- );
276
+ return animatedHeader?.component({
277
+ animatedValue: animatedValue.current,
278
+ });
309
279
  }
310
280
  };
311
281
 
312
282
  /**
313
- * build content for screen for grid rule
283
+ * build content for screen
314
284
  */
315
285
  const renderContent = (children: any): any => {
316
286
  const results = validateChildren(children, [Section, Card, undefined]);
317
287
  if (Array.isArray(results)) {
318
288
  return results.map((item, index) => {
319
289
  const space = item?.props?.useMargin === false ? 0 : Spacing.M;
320
- if (item?.type === Fragment) {
290
+ if (item?.type == Fragment) {
321
291
  return renderContent(item?.props?.children);
322
292
  }
323
293
  if (item) {
@@ -337,7 +307,7 @@ const Screen = forwardRef(
337
307
  } else {
338
308
  const item: any = children;
339
309
  const space = item?.props?.useMargin === false ? 0 : Spacing.M;
340
- if (item?.type === Fragment) {
310
+ if (item?.type == Fragment) {
341
311
  return renderContent(item?.props?.children);
342
312
  }
343
313
  return (
@@ -357,21 +327,16 @@ const Screen = forwardRef(
357
327
  return (
358
328
  <View style={[Styles.flex, {backgroundColor}]}>
359
329
  {!!headerBackground && (
360
- <HeaderExtendBackground
361
- headerBackground={headerBackground}
362
- heightHeader={heightHeader}
363
- animatedValue={animatedValue.current}
364
- />
365
- )}
366
-
367
- {inputSearchProps && (
368
- <AnimatedInputSearch
369
- animatedValue={animatedValue.current}
370
- navigation={navigation}
371
- {...inputSearchProps}
372
- />
330
+ <>
331
+ <Image
332
+ source={{
333
+ uri: headerBackground,
334
+ }}
335
+ style={styles.extendedHeader}
336
+ />
337
+ <View style={{height: heightHeader}} />
338
+ </>
373
339
  )}
374
-
375
340
  <KeyboardAvoidingView
376
341
  style={Styles.flex}
377
342
  enabled={enableKeyboardAvoidingView}
@@ -384,14 +349,14 @@ const Screen = forwardRef(
384
349
 
385
350
  <Component
386
351
  {...scrollViewProps}
387
- ref={scrollViewRef}
352
+ ref={ref}
388
353
  showsVerticalScrollIndicator={false}
389
354
  onScroll={handleScroll}
390
- onScrollEndDrag={handleScrollEnd}
391
- scrollEventThrottle={16}
392
355
  style={Styles.flex}>
393
- {renderAnimatedHeader()}
394
-
356
+ <View
357
+ style={[styles.screenBanner, {maxHeight: 210 + layoutOffset}]}>
358
+ {renderHeader()}
359
+ </View>
395
360
  {useGridLayout ? renderContent(children) : children}
396
361
  </Component>
397
362
 
@@ -422,7 +387,7 @@ const Screen = forwardRef(
422
387
  </KeyboardAvoidingView>
423
388
  </View>
424
389
  );
425
- }
390
+ },
426
391
  );
427
392
 
428
393
  export default Screen;
package/Layout/styles.ts CHANGED
@@ -2,6 +2,12 @@ import {Platform, StyleSheet} from 'react-native';
2
2
  import {Colors, Radius, Spacing} from '../Consts';
3
3
 
4
4
  export default StyleSheet.create({
5
+ extendedHeader: {
6
+ aspectRatio: 1.75,
7
+ position: 'absolute',
8
+ width: '100%',
9
+ height: 210,
10
+ },
5
11
  screenBanner: {
6
12
  width: '100%',
7
13
  },
package/Layout/types.ts CHANGED
@@ -1,8 +1,4 @@
1
- import {Animated} from 'react-native';
2
- import {InputSearchProps, InputSearchRef} from '../Input';
3
- import {LegacyRef} from 'react';
4
-
5
- export type HeaderType = 'default' | 'surface' | 'extended' | 'search' | 'none';
1
+ export type HeaderType = 'default' | 'surface' | 'extended' | 'none';
6
2
 
7
3
  export type GridContextProps = {
8
4
  /**
@@ -25,18 +21,3 @@ export type GridContextProps = {
25
21
  */
26
22
  getSizeSpan: (span: number) => number;
27
23
  };
28
-
29
- export type AnimatedInputSearchProps = {
30
- animatedValue: Animated.Value;
31
- headerRightWidth: number;
32
- heightHeader: number;
33
- headerType: HeaderType;
34
- inputSearchProps?: InputSearchProps;
35
- inputRef?: LegacyRef<InputSearchRef>;
36
- };
37
-
38
- export type ExtendHeaderProps = {
39
- headerBackground: string;
40
- animatedValue: Animated.Value;
41
- heightHeader: number;
42
- };
package/Title/index.tsx CHANGED
@@ -1,16 +1,13 @@
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
+ import {Icon} from '../Icon';
4
+ import {scaleSize, Text} from '../Text';
5
+ import {ApplicationContext} from '../Application';
6
+ import {Badge} from '../Badge';
7
+ import {Colors} from '../Consts';
12
8
  import styles from './styles';
13
9
  import {TitleProps} from './types';
10
+ import {Typography} from '../Text/types';
14
11
 
15
12
  const Title: FC<TitleProps> = ({
16
13
  title = 'Title',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.92.23",
3
+ "version": "0.92.25",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {},
@@ -1,113 +0,0 @@
1
- import React, {FC, memo, useEffect, useRef} from 'react';
2
- import {Platform, StyleSheet, TextInput, TextStyle} from 'react-native';
3
- import {Colors} from '../Consts';
4
- import {scaleSize} from '../Text';
5
-
6
- export interface TextTypingProps {
7
- data: string[];
8
- timeDelayEnd?: number;
9
- timeDelayNextChar?: number;
10
- inputStyle?: TextStyle;
11
- }
12
-
13
- const TextTyping: FC<TextTypingProps> = ({
14
- data = [],
15
- timeDelayEnd = 2000,
16
- timeDelayNextChar = 20,
17
- inputStyle = {},
18
- }) => {
19
- const textRef = useRef<TextInput>(null);
20
-
21
- const currentIndex = useRef<number>(0);
22
- const currentCharIndex = useRef<number>(0);
23
- const currentText = useRef('');
24
-
25
- useEffect(() => {
26
- setTimeout(() => {
27
- playAnimation();
28
- }, 1000);
29
- }, []);
30
-
31
- const playAnimation = () => {
32
- const handleResetList = () => {
33
- currentIndex.current = 0;
34
- handleAnimation();
35
- };
36
-
37
- const handleAnimation = () => {
38
- const listChar = data?.[currentIndex.current]?.split('') || [];
39
- listChar.length !== 0 && showChar(listChar?.[currentCharIndex.current]);
40
- };
41
-
42
- currentIndex.current >= data?.length
43
- ? handleResetList()
44
- : handleAnimation();
45
- };
46
-
47
- const showChar = (char?: string) => {
48
- const handleResetString = () => {
49
- setTimeout(() => {
50
- reset();
51
- }, timeDelayEnd);
52
- };
53
-
54
- const handleShowChar = () => {
55
- setTimeout(() => {
56
- textRef.current?.setNativeProps?.({
57
- text: currentText.current + char,
58
- });
59
- currentText.current += char;
60
- currentCharIndex.current++;
61
- playAnimation();
62
- }, timeDelayNextChar);
63
- };
64
-
65
- currentCharIndex.current >= (data?.[currentIndex.current]?.length || 0)
66
- ? handleResetString()
67
- : handleShowChar();
68
- };
69
-
70
- const reset = () => {
71
- const handleNextString = () => {
72
- currentIndex.current++;
73
- playAnimation();
74
- };
75
-
76
- const handleReset = () => {
77
- setTimeout(() => {
78
- textRef.current?.setNativeProps?.({
79
- text: currentText.current.slice(0, -1),
80
- });
81
- currentText.current = currentText.current.slice(0, -1);
82
- currentCharIndex.current--;
83
- reset();
84
- }, timeDelayNextChar);
85
- };
86
-
87
- currentCharIndex.current <= 0 ? handleNextString() : handleReset();
88
- };
89
-
90
- return (
91
- <TextInput
92
- style={[styles.inputStyle, inputStyle]}
93
- ref={textRef}
94
- editable={false}
95
- autoCorrect={false}
96
- pointerEvents={'none'}
97
- numberOfLines={1}
98
- />
99
- );
100
- };
101
-
102
- export default memo(TextTyping);
103
-
104
- const styles = StyleSheet.create({
105
- inputStyle: {
106
- color: Colors.black_12,
107
- fontSize: scaleSize(12),
108
- height: Platform.select({
109
- android: 60,
110
- ios: 36,
111
- }),
112
- },
113
- });
@@ -1,66 +0,0 @@
1
- import React, {FC, useEffect, useRef, useState} from 'react';
2
- import {InputSearch, InputSearchProps} from '../Input';
3
- import {Animated, Dimensions} from 'react-native';
4
- import {Spacing} from '../Consts';
5
- import {scaleSize} from '../Text';
6
- import Navigation from '../Application/Navigation';
7
-
8
- export interface AnimatedInputSearchProps extends InputSearchProps {
9
- animatedValue: Animated.Value;
10
- navigation?: Navigation;
11
- }
12
-
13
- const SCREEN_PADDING = 12;
14
- const BACK_WIDTH = scaleSize(28);
15
-
16
- const AnimatedInputSearch: FC<AnimatedInputSearchProps> = ({
17
- animatedValue,
18
- navigation,
19
- ...props
20
- }) => {
21
- const {width: screenWidth} = Dimensions.get('window');
22
- const widthAnimated = useRef(new Animated.Value(0));
23
- const [rightSpace, setRightSpace] = useState(
24
- navigation?.rightHeaderWidth ?? 0
25
- );
26
-
27
- useEffect(() => {
28
- setTimeout(() => {
29
- if (rightSpace != navigation?.rightHeaderWidth) {
30
- setRightSpace(navigation?.rightHeaderWidth ?? 0);
31
- }
32
- }, 500);
33
- const listener = animatedValue.addListener(({value}) => {
34
- widthAnimated.current.setValue(value);
35
- });
36
- return () => {
37
- animatedValue?.removeListener(listener);
38
- };
39
- }, []);
40
-
41
- const translateX = widthAnimated.current.interpolate({
42
- inputRange: [0, 100],
43
- outputRange: [SCREEN_PADDING, BACK_WIDTH + SCREEN_PADDING * 2],
44
- extrapolate: 'clamp',
45
- });
46
-
47
- return (
48
- <Animated.View
49
- style={{
50
- transform: [{translateX}],
51
- marginVertical: Spacing.S,
52
- width: widthAnimated.current.interpolate({
53
- inputRange: [0, 100],
54
- outputRange: [
55
- screenWidth - SCREEN_PADDING * 2,
56
- screenWidth - SCREEN_PADDING * 3 - BACK_WIDTH - rightSpace,
57
- ],
58
- extrapolate: 'clamp',
59
- }),
60
- }}>
61
- <InputSearch {...props} showButtonText={false} />
62
- </Animated.View>
63
- );
64
- };
65
-
66
- export default AnimatedInputSearch;