@momo-kits/foundation 0.92.26-beta.2 → 0.92.26-beta.21
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/Application/BottomSheet.tsx +24 -26
- package/Application/BottomTab/index.tsx +1 -2
- package/Application/Components.tsx +235 -39
- package/Application/ModalScreen.tsx +2 -2
- package/Application/Navigation.ts +4 -18
- package/Application/StackScreen.tsx +12 -3
- package/Application/index.ts +0 -2
- package/Application/types.ts +17 -6
- package/Application/utils.tsx +60 -18
- package/Button/index.tsx +0 -1
- package/Input/InputMoney.tsx +3 -3
- package/Input/InputOTP.tsx +4 -4
- package/Input/InputSearch.tsx +249 -144
- package/Input/TextTyping.tsx +113 -0
- package/Input/index.tsx +19 -1
- package/Input/styles.ts +10 -3
- package/Layout/Screen.tsx +171 -92
- package/Layout/styles.ts +0 -6
- package/Layout/types.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,113 @@
|
|
|
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
|
+
});
|
package/Input/index.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {TextInputProps, ViewStyle} from 'react-native';
|
|
1
|
+
import {GestureResponderEvent, TextInputProps, ViewStyle} from 'react-native';
|
|
2
2
|
import Input from './Input';
|
|
3
3
|
import InputDropDown from './InputDropDown';
|
|
4
4
|
import InputMoney from './InputMoney';
|
|
@@ -143,6 +143,17 @@ export interface InputSearchProps extends TextInputProps {
|
|
|
143
143
|
* Optional. Represents the style of the InputSearch component.
|
|
144
144
|
*/
|
|
145
145
|
params?: any;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Optional. Represents the data for typing animation.
|
|
149
|
+
*/
|
|
150
|
+
typingData?: string[];
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Optional. Represents the callback function to be called when the search button is pressed.
|
|
154
|
+
* @param e
|
|
155
|
+
*/
|
|
156
|
+
onPress?: (e: GestureResponderEvent) => void;
|
|
146
157
|
}
|
|
147
158
|
|
|
148
159
|
export interface InputMoneyProps extends Omit<InputProps, 'placeholder'> {}
|
|
@@ -282,4 +293,11 @@ export interface InputDropDownProps extends InputProps {
|
|
|
282
293
|
style?: ViewStyle | ViewStyle[];
|
|
283
294
|
}
|
|
284
295
|
|
|
296
|
+
export type InputRef = {
|
|
297
|
+
clear: () => void;
|
|
298
|
+
focus: () => void | undefined;
|
|
299
|
+
blur: () => void | undefined;
|
|
300
|
+
setText: (text: string) => void;
|
|
301
|
+
};
|
|
302
|
+
|
|
285
303
|
export {Input, InputDropDown, InputMoney, InputOTP, InputSearch, InputTextArea};
|
package/Input/styles.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {StyleSheet} from 'react-native';
|
|
2
|
-
import {Radius, Spacing} from '../Consts';
|
|
1
|
+
import {Platform, StyleSheet} from 'react-native';
|
|
2
|
+
import {Colors, Radius, Spacing} from '../Consts';
|
|
3
3
|
import {scaleSize} from '../Text';
|
|
4
4
|
|
|
5
5
|
export default StyleSheet.create({
|
|
@@ -133,7 +133,14 @@ export default StyleSheet.create({
|
|
|
133
133
|
paddingVertical: Spacing.S,
|
|
134
134
|
fontWeight: 'bold',
|
|
135
135
|
},
|
|
136
|
-
|
|
136
|
+
inputStyle: {
|
|
137
|
+
color: Colors.black_12,
|
|
138
|
+
fontSize: scaleSize(12),
|
|
139
|
+
height: Platform.select({
|
|
140
|
+
android: 60,
|
|
141
|
+
ios: 36,
|
|
142
|
+
}),
|
|
143
|
+
},
|
|
137
144
|
//OTP
|
|
138
145
|
otpWrapper: {
|
|
139
146
|
width: '100%',
|
package/Layout/Screen.tsx
CHANGED
|
@@ -27,10 +27,11 @@ 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';
|
|
31
30
|
import {Card, Section, validateChildren} from './index';
|
|
32
31
|
import styles from './styles';
|
|
33
32
|
import {HeaderType} from './types';
|
|
33
|
+
import {InputSearchProps} from '../Input';
|
|
34
|
+
import {HeaderExtendHeader} from '../Application/Components';
|
|
34
35
|
|
|
35
36
|
export interface ScreenProps extends ViewProps {
|
|
36
37
|
/**
|
|
@@ -101,6 +102,11 @@ export interface ScreenProps extends ViewProps {
|
|
|
101
102
|
* Optional. If `true`, the screen content is using grid layout by span.
|
|
102
103
|
*/
|
|
103
104
|
useGridLayout?: boolean;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Optional. specs for input search.
|
|
108
|
+
*/
|
|
109
|
+
inputSearchProps?: InputSearchProps;
|
|
104
110
|
}
|
|
105
111
|
|
|
106
112
|
const Screen = forwardRef(
|
|
@@ -120,32 +126,132 @@ const Screen = forwardRef(
|
|
|
120
126
|
floatingButtonProps,
|
|
121
127
|
useGridLayout = true,
|
|
122
128
|
keyboardVerticalOffset,
|
|
129
|
+
inputSearchProps,
|
|
123
130
|
}: ScreenProps,
|
|
124
|
-
ref
|
|
131
|
+
ref
|
|
125
132
|
) => {
|
|
126
|
-
const animatedValue = useRef<Animated.Value>(new Animated.Value(0));
|
|
127
133
|
const {theme} = useContext(ApplicationContext);
|
|
128
134
|
const insets = useSafeAreaInsets();
|
|
129
135
|
const heightHeader = useHeaderHeight();
|
|
136
|
+
const animatedValue = useRef<Animated.Value>(new Animated.Value(0));
|
|
137
|
+
const scrollViewRef = useRef<any>(ref);
|
|
130
138
|
const currentTint = useRef(Colors.black_01);
|
|
131
|
-
const isTab = navigation?.instance?.getState?.()?.type
|
|
139
|
+
const isTab = navigation?.instance?.getState?.()?.type === 'tab';
|
|
132
140
|
|
|
133
|
-
let styleAnimatedHeader: NavigationOptions;
|
|
134
141
|
let handleScroll;
|
|
135
|
-
let headerBackground: string | undefined = undefined;
|
|
136
142
|
let Component: any = View;
|
|
137
143
|
let keyboardOffset = heightHeader - 20;
|
|
138
|
-
if (headerType
|
|
144
|
+
if (headerType === 'extended' || animatedHeader) {
|
|
139
145
|
keyboardOffset = -20;
|
|
140
146
|
}
|
|
141
147
|
|
|
142
|
-
if (headerType == 'extended') {
|
|
143
|
-
headerBackground = theme.assets?.headerBackground;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
148
|
useEffect(() => {
|
|
149
|
+
let options: NavigationOptions;
|
|
150
|
+
/**
|
|
151
|
+
* handle for basic header type
|
|
152
|
+
*/
|
|
153
|
+
switch (headerType) {
|
|
154
|
+
case 'none':
|
|
155
|
+
options = {
|
|
156
|
+
headerTransparent: true,
|
|
157
|
+
headerBackground: () => null,
|
|
158
|
+
headerShown: false,
|
|
159
|
+
};
|
|
160
|
+
break;
|
|
161
|
+
|
|
162
|
+
case 'surface':
|
|
163
|
+
options = {
|
|
164
|
+
headerTransparent: false,
|
|
165
|
+
headerShown: true,
|
|
166
|
+
headerTintColor: theme.colors.text.default,
|
|
167
|
+
headerBackground: (props: any) => (
|
|
168
|
+
<HeaderBackground {...props} image={null} useSurface={true} />
|
|
169
|
+
),
|
|
170
|
+
headerTitle: (props: any) => <HeaderTitle {...props} />,
|
|
171
|
+
};
|
|
172
|
+
if (inputSearchProps) {
|
|
173
|
+
options = {
|
|
174
|
+
headerShown: true,
|
|
175
|
+
headerTransparent: true,
|
|
176
|
+
headerTintColor: theme.colors.text.default,
|
|
177
|
+
headerBackground: () => null,
|
|
178
|
+
headerTitle: (props: any) => (
|
|
179
|
+
<HeaderTitle
|
|
180
|
+
{...props}
|
|
181
|
+
interpolate={{
|
|
182
|
+
inputRange: [0, 50],
|
|
183
|
+
outputRange: [1, 0],
|
|
184
|
+
extrapolate: 'clamp',
|
|
185
|
+
}}
|
|
186
|
+
animatedValue={animatedValue.current}
|
|
187
|
+
/>
|
|
188
|
+
),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
break;
|
|
192
|
+
|
|
193
|
+
case 'extended':
|
|
194
|
+
options = {
|
|
195
|
+
headerShown: true,
|
|
196
|
+
headerTransparent: true,
|
|
197
|
+
headerTintColor: Colors.black_01,
|
|
198
|
+
headerBackground: () => null,
|
|
199
|
+
headerTitle: (props: any) => <HeaderTitle {...props} />,
|
|
200
|
+
};
|
|
201
|
+
if (inputSearchProps) {
|
|
202
|
+
options = {
|
|
203
|
+
headerShown: true,
|
|
204
|
+
headerTransparent: true,
|
|
205
|
+
headerTintColor: Colors.black_01,
|
|
206
|
+
headerBackground: () => null,
|
|
207
|
+
headerTitle: (props: any) => (
|
|
208
|
+
<HeaderTitle
|
|
209
|
+
{...props}
|
|
210
|
+
interpolate={{
|
|
211
|
+
inputRange: [0, 50],
|
|
212
|
+
outputRange: [1, 0],
|
|
213
|
+
extrapolate: 'clamp',
|
|
214
|
+
}}
|
|
215
|
+
animatedValue={animatedValue.current}
|
|
216
|
+
/>
|
|
217
|
+
),
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
break;
|
|
221
|
+
|
|
222
|
+
default:
|
|
223
|
+
options = {
|
|
224
|
+
headerTransparent: false,
|
|
225
|
+
headerShown: true,
|
|
226
|
+
headerTintColor: Colors.black_01,
|
|
227
|
+
headerBackground: (props: any) => <HeaderBackground {...props} />,
|
|
228
|
+
};
|
|
229
|
+
if (inputSearchProps) {
|
|
230
|
+
options = {
|
|
231
|
+
headerShown: true,
|
|
232
|
+
headerTransparent: true,
|
|
233
|
+
headerTintColor: Colors.black_01,
|
|
234
|
+
headerBackground: () => null,
|
|
235
|
+
headerTitle: (props: any) => (
|
|
236
|
+
<HeaderTitle
|
|
237
|
+
{...props}
|
|
238
|
+
interpolate={{
|
|
239
|
+
inputRange: [0, 50],
|
|
240
|
+
outputRange: [1, 0],
|
|
241
|
+
extrapolate: 'clamp',
|
|
242
|
+
}}
|
|
243
|
+
animatedValue={animatedValue.current}
|
|
244
|
+
/>
|
|
245
|
+
),
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* override options for animated header
|
|
252
|
+
*/
|
|
147
253
|
if (animatedHeader) {
|
|
148
|
-
|
|
254
|
+
options = {
|
|
149
255
|
headerTransparent: true,
|
|
150
256
|
headerBackground: (props: any) => (
|
|
151
257
|
<HeaderBackground
|
|
@@ -157,9 +263,9 @@ const Screen = forwardRef(
|
|
|
157
263
|
<HeaderTitle {...props} animatedValue={animatedValue.current} />
|
|
158
264
|
),
|
|
159
265
|
};
|
|
160
|
-
if (animatedHeader.type
|
|
161
|
-
|
|
162
|
-
...
|
|
266
|
+
if (animatedHeader.type === 'surface') {
|
|
267
|
+
options = {
|
|
268
|
+
...options,
|
|
163
269
|
headerBackground: (props: any) => (
|
|
164
270
|
<HeaderBackground
|
|
165
271
|
{...props}
|
|
@@ -171,8 +277,8 @@ const Screen = forwardRef(
|
|
|
171
277
|
};
|
|
172
278
|
}
|
|
173
279
|
if (animatedHeader.headerTitle) {
|
|
174
|
-
|
|
175
|
-
...
|
|
280
|
+
options = {
|
|
281
|
+
...options,
|
|
176
282
|
headerTitle: (props: any) =>
|
|
177
283
|
animatedHeader.headerTitle?.({
|
|
178
284
|
...props,
|
|
@@ -180,55 +286,10 @@ const Screen = forwardRef(
|
|
|
180
286
|
}),
|
|
181
287
|
};
|
|
182
288
|
}
|
|
183
|
-
navigation?.setOptions(styleAnimatedHeader);
|
|
184
289
|
}
|
|
185
|
-
}, [animatedHeader]);
|
|
186
|
-
|
|
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
290
|
|
|
199
|
-
|
|
200
|
-
|
|
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]);
|
|
291
|
+
navigation?.setOptions(options);
|
|
292
|
+
}, [headerType, animatedHeader]);
|
|
232
293
|
|
|
233
294
|
/**
|
|
234
295
|
* animated when use scroll && animated value
|
|
@@ -236,7 +297,7 @@ const Screen = forwardRef(
|
|
|
236
297
|
if (scrollable) {
|
|
237
298
|
Component = Animated.ScrollView;
|
|
238
299
|
handleScroll = scrollViewProps?.onScroll;
|
|
239
|
-
if (animatedHeader || floatingButtonProps?.icon) {
|
|
300
|
+
if (animatedHeader || floatingButtonProps?.icon || inputSearchProps) {
|
|
240
301
|
handleScroll = Animated.event(
|
|
241
302
|
[
|
|
242
303
|
{
|
|
@@ -249,13 +310,13 @@ const Screen = forwardRef(
|
|
|
249
310
|
useNativeDriver: true,
|
|
250
311
|
listener: (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
251
312
|
scrollViewProps?.onScroll?.(e);
|
|
252
|
-
if (animatedHeader?.type
|
|
313
|
+
if (animatedHeader?.type === 'surface') {
|
|
253
314
|
const offsetY = e.nativeEvent.contentOffset.y;
|
|
254
315
|
let color = Colors.black_01;
|
|
255
316
|
if (offsetY > 50) {
|
|
256
317
|
color = theme.colors.text.default;
|
|
257
318
|
}
|
|
258
|
-
if (color
|
|
319
|
+
if (color !== currentTint.current) {
|
|
259
320
|
currentTint.current = color;
|
|
260
321
|
navigation?.setOptions({
|
|
261
322
|
headerTintColor: color,
|
|
@@ -263,31 +324,52 @@ const Screen = forwardRef(
|
|
|
263
324
|
}
|
|
264
325
|
}
|
|
265
326
|
},
|
|
266
|
-
}
|
|
327
|
+
}
|
|
267
328
|
);
|
|
268
329
|
}
|
|
269
330
|
}
|
|
270
331
|
|
|
332
|
+
/**
|
|
333
|
+
* handle scroll end
|
|
334
|
+
* @param e
|
|
335
|
+
*/
|
|
336
|
+
const handleScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
337
|
+
const offsetY = e.nativeEvent.contentOffset.y;
|
|
338
|
+
if (inputSearchProps && offsetY < 100 && offsetY > 0) {
|
|
339
|
+
Animated.timing(animatedValue.current, {
|
|
340
|
+
toValue: 0,
|
|
341
|
+
useNativeDriver: true,
|
|
342
|
+
duration: 300,
|
|
343
|
+
}).start();
|
|
344
|
+
scrollViewRef.current?.scrollTo({y: 0, animated: true});
|
|
345
|
+
}
|
|
346
|
+
scrollViewProps?.onScrollEndDrag?.(e);
|
|
347
|
+
};
|
|
348
|
+
|
|
271
349
|
/**
|
|
272
350
|
* render top navigation banner
|
|
273
351
|
*/
|
|
274
|
-
const
|
|
352
|
+
const renderAnimatedHeader = () => {
|
|
275
353
|
if (typeof animatedHeader?.component === 'function') {
|
|
276
|
-
return
|
|
277
|
-
|
|
278
|
-
|
|
354
|
+
return (
|
|
355
|
+
<View style={[styles.screenBanner, {maxHeight: 210 + layoutOffset}]}>
|
|
356
|
+
{animatedHeader?.component({
|
|
357
|
+
animatedValue: animatedValue.current,
|
|
358
|
+
})}
|
|
359
|
+
</View>
|
|
360
|
+
);
|
|
279
361
|
}
|
|
280
362
|
};
|
|
281
363
|
|
|
282
364
|
/**
|
|
283
|
-
* build content for screen
|
|
365
|
+
* build content for screen for grid rule
|
|
284
366
|
*/
|
|
285
367
|
const renderContent = (children: any): any => {
|
|
286
368
|
const results = validateChildren(children, [Section, Card, undefined]);
|
|
287
369
|
if (Array.isArray(results)) {
|
|
288
370
|
return results.map((item, index) => {
|
|
289
371
|
const space = item?.props?.useMargin === false ? 0 : Spacing.M;
|
|
290
|
-
if (item?.type
|
|
372
|
+
if (item?.type === Fragment) {
|
|
291
373
|
return renderContent(item?.props?.children);
|
|
292
374
|
}
|
|
293
375
|
if (item) {
|
|
@@ -307,7 +389,7 @@ const Screen = forwardRef(
|
|
|
307
389
|
} else {
|
|
308
390
|
const item: any = children;
|
|
309
391
|
const space = item?.props?.useMargin === false ? 0 : Spacing.M;
|
|
310
|
-
if (item?.type
|
|
392
|
+
if (item?.type === Fragment) {
|
|
311
393
|
return renderContent(item?.props?.children);
|
|
312
394
|
}
|
|
313
395
|
return (
|
|
@@ -326,17 +408,14 @@ const Screen = forwardRef(
|
|
|
326
408
|
|
|
327
409
|
return (
|
|
328
410
|
<View style={[Styles.flex, {backgroundColor}]}>
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
<View style={{height: heightHeader}} />
|
|
338
|
-
</>
|
|
339
|
-
)}
|
|
411
|
+
<HeaderExtendHeader
|
|
412
|
+
headerType={headerType}
|
|
413
|
+
heightHeader={heightHeader}
|
|
414
|
+
animatedValue={animatedValue.current}
|
|
415
|
+
inputSearchProps={inputSearchProps}
|
|
416
|
+
navigation={navigation}
|
|
417
|
+
/>
|
|
418
|
+
|
|
340
419
|
<KeyboardAvoidingView
|
|
341
420
|
style={Styles.flex}
|
|
342
421
|
enabled={enableKeyboardAvoidingView}
|
|
@@ -349,14 +428,14 @@ const Screen = forwardRef(
|
|
|
349
428
|
|
|
350
429
|
<Component
|
|
351
430
|
{...scrollViewProps}
|
|
352
|
-
ref={
|
|
431
|
+
ref={scrollViewRef}
|
|
353
432
|
showsVerticalScrollIndicator={false}
|
|
354
433
|
onScroll={handleScroll}
|
|
434
|
+
onScrollEndDrag={handleScrollEnd}
|
|
435
|
+
scrollEventThrottle={16}
|
|
355
436
|
style={Styles.flex}>
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
{renderHeader()}
|
|
359
|
-
</View>
|
|
437
|
+
{renderAnimatedHeader()}
|
|
438
|
+
|
|
360
439
|
{useGridLayout ? renderContent(children) : children}
|
|
361
440
|
</Component>
|
|
362
441
|
|
|
@@ -387,7 +466,7 @@ const Screen = forwardRef(
|
|
|
387
466
|
</KeyboardAvoidingView>
|
|
388
467
|
</View>
|
|
389
468
|
);
|
|
390
|
-
}
|
|
469
|
+
}
|
|
391
470
|
);
|
|
392
471
|
|
|
393
472
|
export default Screen;
|
package/Layout/styles.ts
CHANGED
|
@@ -2,12 +2,6 @@ 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
|
-
},
|
|
11
5
|
screenBanner: {
|
|
12
6
|
width: '100%',
|
|
13
7
|
},
|
package/Layout/types.ts
CHANGED