@momo-kits/foundation 0.161.2-beta.1 → 0.161.2-beta.10
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 +5 -4
- package/Application/BottomTab/BottomTabBar.tsx +15 -15
- package/Application/BottomTab/index.tsx +56 -32
- package/Application/Components/BackgroundImageView.tsx +6 -22
- package/Application/Components/HeaderAnimated.tsx +29 -32
- package/Application/Components/HeaderBackground.tsx +26 -20
- package/Application/Components/HeaderExtendHeader.tsx +94 -114
- package/Application/Components/HeaderTitle.tsx +10 -39
- package/Application/Components/SearchHeader.tsx +21 -16
- package/Application/types.ts +4 -4
- package/Application/utils.tsx +3 -4
- package/Badge/BadgeDotAnimation.tsx +71 -53
- package/Button/index.tsx +4 -1
- package/Input/InputOTP.tsx +23 -38
- package/Layout/FloatingButton.tsx +59 -59
- package/Layout/Screen.tsx +62 -65
- package/Loader/ProgressBar.tsx +18 -20
- package/Pagination/Dot.tsx +2 -2
- package/Pagination/PaginationScroll.tsx +27 -31
- package/Skeleton/index.tsx +24 -32
- package/package.json +1 -1
package/Input/InputOTP.tsx
CHANGED
|
@@ -8,22 +8,13 @@ import React, {
|
|
|
8
8
|
useState,
|
|
9
9
|
} from 'react';
|
|
10
10
|
import {
|
|
11
|
+
Animated,
|
|
11
12
|
PixelRatio,
|
|
12
13
|
TextInput,
|
|
13
14
|
TextInputFocusEvent,
|
|
14
15
|
TouchableOpacity,
|
|
15
16
|
View,
|
|
16
17
|
} from 'react-native';
|
|
17
|
-
import Animated, {
|
|
18
|
-
cancelAnimation,
|
|
19
|
-
Easing,
|
|
20
|
-
useAnimatedStyle,
|
|
21
|
-
useSharedValue,
|
|
22
|
-
withDelay,
|
|
23
|
-
withRepeat,
|
|
24
|
-
withSequence,
|
|
25
|
-
withTiming,
|
|
26
|
-
} from 'react-native-reanimated';
|
|
27
18
|
import { useComponentId } from '../Application';
|
|
28
19
|
import { Spacing, Styles } from '../Consts';
|
|
29
20
|
import { useScaleSize, Text } from '../Text';
|
|
@@ -41,43 +32,37 @@ import {
|
|
|
41
32
|
const OTPCaret: FC<CaretProps> = ({ index, length }) => {
|
|
42
33
|
const DURATION = 300;
|
|
43
34
|
const { theme } = useContext(ApplicationContext);
|
|
44
|
-
const opacity =
|
|
35
|
+
const opacity = useRef(new Animated.Value(0)).current;
|
|
45
36
|
|
|
46
37
|
useEffect(() => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
DURATION
|
|
52
|
-
|
|
53
|
-
),
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
38
|
+
Animated.loop(
|
|
39
|
+
Animated.sequence([
|
|
40
|
+
Animated.timing(opacity, {
|
|
41
|
+
toValue: 1,
|
|
42
|
+
duration: DURATION,
|
|
43
|
+
useNativeDriver: true,
|
|
44
|
+
}),
|
|
45
|
+
Animated.delay(DURATION * 2),
|
|
46
|
+
Animated.timing(opacity, {
|
|
47
|
+
toValue: 0,
|
|
48
|
+
duration: DURATION,
|
|
49
|
+
useNativeDriver: true,
|
|
50
|
+
}),
|
|
51
|
+
]),
|
|
52
|
+
).start();
|
|
61
53
|
}, [opacity]);
|
|
62
|
-
|
|
63
|
-
const animatedStyle = useAnimatedStyle(() => ({
|
|
64
|
-
opacity: opacity.value,
|
|
65
|
-
}));
|
|
66
|
-
|
|
67
54
|
const spacingStyle = !isNaN(Number(length)) &&
|
|
68
55
|
index !== Number(length) - 1 && { marginRight: Spacing.L };
|
|
69
56
|
|
|
70
57
|
return (
|
|
71
58
|
<View style={[Styles.rowCenter, spacingStyle]}>
|
|
72
59
|
<Animated.View
|
|
73
|
-
style={
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
animatedStyle,
|
|
80
|
-
]}
|
|
60
|
+
style={{
|
|
61
|
+
height: useScaleSize(12),
|
|
62
|
+
width: 1,
|
|
63
|
+
backgroundColor: theme.colors.primary,
|
|
64
|
+
opacity,
|
|
65
|
+
}}
|
|
81
66
|
/>
|
|
82
67
|
<Text color={theme.colors.text.hint} typography={'body_default_regular'}>
|
|
83
68
|
-
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import React, { useContext, useEffect, useState } from 'react';
|
|
2
1
|
import {
|
|
2
|
+
default as React,
|
|
3
|
+
useContext,
|
|
4
|
+
useEffect,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react';
|
|
8
|
+
import {
|
|
9
|
+
Animated,
|
|
3
10
|
LayoutChangeEvent,
|
|
4
11
|
StyleSheet,
|
|
5
12
|
TouchableOpacity,
|
|
6
13
|
View,
|
|
7
14
|
} from 'react-native';
|
|
8
|
-
import Animated, {
|
|
9
|
-
useAnimatedReaction,
|
|
10
|
-
useAnimatedStyle,
|
|
11
|
-
useSharedValue,
|
|
12
|
-
withTiming,
|
|
13
|
-
runOnJS,
|
|
14
|
-
type SharedValue,
|
|
15
|
-
} from 'react-native-reanimated';
|
|
16
15
|
import { ApplicationContext } from '../Context';
|
|
17
16
|
import { Icon } from '../Icon';
|
|
18
17
|
import { useScaleSize } from '../Text';
|
|
@@ -24,7 +23,7 @@ export interface FloatingButtonProps {
|
|
|
24
23
|
icon?: string;
|
|
25
24
|
iconColor?: string;
|
|
26
25
|
size?: 'small' | 'large';
|
|
27
|
-
animatedValue?:
|
|
26
|
+
animatedValue?: Animated.Value;
|
|
28
27
|
bottom?: number;
|
|
29
28
|
renderComponent?: () => React.ReactNode;
|
|
30
29
|
}
|
|
@@ -43,67 +42,68 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
|
43
42
|
const { theme } = useContext(ApplicationContext);
|
|
44
43
|
const scaledFontSize = useScaleSize(16);
|
|
45
44
|
const scaledLineHeight = useScaleSize(22);
|
|
46
|
-
const maxWidth =
|
|
45
|
+
const maxWidth = useRef(0);
|
|
47
46
|
const minWidth = size === 'small' ? 36 : 48;
|
|
48
|
-
const opacityAnimated =
|
|
49
|
-
const widthAnimated =
|
|
50
|
-
const lastOffset =
|
|
51
|
-
const lastDirection =
|
|
52
|
-
const [showText, setShowText] = useState(true);
|
|
47
|
+
const [opacityAnimated] = useState(new Animated.Value(0)); // Initial opacity set to 0
|
|
48
|
+
const [widthAnimated, setWidthAnimated] = useState<Animated.Value>();
|
|
49
|
+
const lastOffset = useRef(0);
|
|
50
|
+
const lastDirection = useRef<string>(null);
|
|
51
|
+
const [showText, setShowText] = React.useState(true);
|
|
53
52
|
|
|
54
53
|
useEffect(() => {
|
|
55
54
|
if (!label) return;
|
|
56
|
-
opacityAnimated.value = withTiming(1, { duration: 100 });
|
|
57
|
-
}, [label, opacityAnimated]);
|
|
58
55
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
56
|
+
Animated.timing(opacityAnimated, {
|
|
57
|
+
toValue: 1,
|
|
58
|
+
duration: 100,
|
|
59
|
+
useNativeDriver: true,
|
|
60
|
+
}).start();
|
|
61
|
+
|
|
62
|
+
const listener = animatedValue?.addListener(({ value }) => {
|
|
63
|
+
if (value !== lastOffset.current && value > 0) {
|
|
64
|
+
const direction = value > lastOffset.current ? 'down' : 'up';
|
|
65
|
+
lastOffset.current = value;
|
|
66
|
+
if (lastDirection.current !== direction) {
|
|
67
|
+
lastDirection.current = direction;
|
|
69
68
|
if (direction === 'down') {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
Animated.timing(opacityAnimated, {
|
|
70
|
+
toValue: 0,
|
|
71
|
+
duration: 100,
|
|
72
|
+
useNativeDriver: true,
|
|
73
|
+
}).start();
|
|
74
|
+
Animated.timing(widthAnimated!, {
|
|
75
|
+
toValue: minWidth,
|
|
76
|
+
duration: 100,
|
|
77
|
+
useNativeDriver: false,
|
|
78
|
+
}).start(() => setShowText(false));
|
|
78
79
|
} else {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
Animated.timing(opacityAnimated, {
|
|
81
|
+
toValue: 1,
|
|
82
|
+
duration: 100,
|
|
83
|
+
useNativeDriver: true,
|
|
84
|
+
}).start();
|
|
85
|
+
Animated.timing(widthAnimated!, {
|
|
86
|
+
toValue: maxWidth.current,
|
|
87
|
+
duration: 100,
|
|
88
|
+
useNativeDriver: false,
|
|
89
|
+
}).start(() => setShowText(true));
|
|
87
90
|
}
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
|
-
}
|
|
91
|
-
[label, animatedValue, minWidth],
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
const containerStyle = useAnimatedStyle(() => ({
|
|
95
|
-
width: widthAnimated.value ?? undefined,
|
|
96
|
-
}));
|
|
93
|
+
});
|
|
97
94
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
return () => {
|
|
96
|
+
if (listener) {
|
|
97
|
+
animatedValue?.removeListener(listener);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}, [animatedValue, label, minWidth, opacityAnimated, widthAnimated]);
|
|
101
101
|
|
|
102
102
|
const handleLayout = (event: LayoutChangeEvent) => {
|
|
103
103
|
const layout = event.nativeEvent.layout;
|
|
104
|
-
if (widthAnimated
|
|
105
|
-
maxWidth.
|
|
106
|
-
|
|
104
|
+
if (widthAnimated) return;
|
|
105
|
+
maxWidth.current = layout.width;
|
|
106
|
+
setWidthAnimated(new Animated.Value(layout.width));
|
|
107
107
|
};
|
|
108
108
|
|
|
109
109
|
if (renderComponent) {
|
|
@@ -132,11 +132,11 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
|
132
132
|
{
|
|
133
133
|
right: position === 'right' ? 12 : undefined,
|
|
134
134
|
alignSelf: position === 'center' ? 'center' : 'flex-end',
|
|
135
|
+
width: widthAnimated,
|
|
135
136
|
height: size === 'small' ? 36 : 48,
|
|
136
137
|
backgroundColor: theme.colors.primary,
|
|
137
138
|
bottom,
|
|
138
139
|
},
|
|
139
|
-
containerStyle,
|
|
140
140
|
]}
|
|
141
141
|
>
|
|
142
142
|
<TouchableOpacity
|
|
@@ -156,9 +156,9 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
|
156
156
|
{
|
|
157
157
|
fontSize: scaledFontSize,
|
|
158
158
|
lineHeight: scaledLineHeight,
|
|
159
|
+
opacity: opacityAnimated,
|
|
159
160
|
color: 'white',
|
|
160
161
|
},
|
|
161
|
-
labelStyle,
|
|
162
162
|
]}
|
|
163
163
|
numberOfLines={1}
|
|
164
164
|
>
|
package/Layout/Screen.tsx
CHANGED
|
@@ -12,6 +12,7 @@ import React, {
|
|
|
12
12
|
useRef,
|
|
13
13
|
} from 'react';
|
|
14
14
|
import {
|
|
15
|
+
Animated,
|
|
15
16
|
KeyboardAvoidingView,
|
|
16
17
|
NativeScrollEvent,
|
|
17
18
|
NativeSyntheticEvent,
|
|
@@ -24,13 +25,6 @@ import {
|
|
|
24
25
|
View,
|
|
25
26
|
ViewProps,
|
|
26
27
|
} from 'react-native';
|
|
27
|
-
import Animated, {
|
|
28
|
-
runOnJS,
|
|
29
|
-
useAnimatedScrollHandler,
|
|
30
|
-
useSharedValue,
|
|
31
|
-
withTiming,
|
|
32
|
-
type SharedValue,
|
|
33
|
-
} from 'react-native-reanimated';
|
|
34
28
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
35
29
|
import { ApplicationContext, ScreenContext } from '../Context';
|
|
36
30
|
import Navigation from '../Application/Navigation';
|
|
@@ -144,7 +138,7 @@ export interface ScreenProps extends ViewProps {
|
|
|
144
138
|
/**
|
|
145
139
|
* Optional. Animated value for header.
|
|
146
140
|
*/
|
|
147
|
-
animatedValue?:
|
|
141
|
+
animatedValue?: Animated.Value;
|
|
148
142
|
|
|
149
143
|
/**
|
|
150
144
|
* Optional. If `true`, use shadow header.
|
|
@@ -201,17 +195,19 @@ const Screen = forwardRef(
|
|
|
201
195
|
const screen: any = useContext(ScreenContext);
|
|
202
196
|
const insets = useSafeAreaInsets();
|
|
203
197
|
const heightHeader = useHeaderHeight();
|
|
204
|
-
const
|
|
205
|
-
|
|
198
|
+
const animatedValue = useRef<Animated.Value>(
|
|
199
|
+
customAnimatedValue || new Animated.Value(0),
|
|
200
|
+
);
|
|
206
201
|
const currentTint = useRef<string | undefined>(undefined);
|
|
207
202
|
const isTab = navigation?.instance?.getState?.()?.type === 'tab';
|
|
208
203
|
|
|
209
|
-
let handleScroll
|
|
204
|
+
let handleScroll;
|
|
210
205
|
let Component: any = View;
|
|
211
206
|
|
|
212
|
-
|
|
207
|
+
const bottomInset = Platform.OS === 'ios' ? Math.min(insets.bottom, 21) : insets.bottom;
|
|
208
|
+
let keyboardOffset = heightHeader - bottomInset;
|
|
213
209
|
if (headerType === 'extended' || animatedHeader || inputSearchProps) {
|
|
214
|
-
keyboardOffset = -
|
|
210
|
+
keyboardOffset = -bottomInset;
|
|
215
211
|
}
|
|
216
212
|
|
|
217
213
|
/**
|
|
@@ -253,8 +249,9 @@ const Screen = forwardRef(
|
|
|
253
249
|
interpolate={{
|
|
254
250
|
inputRange: [0, 50],
|
|
255
251
|
outputRange: [1, 0],
|
|
252
|
+
extrapolate: 'clamp',
|
|
256
253
|
}}
|
|
257
|
-
animatedValue={animatedValue}
|
|
254
|
+
animatedValue={animatedValue.current}
|
|
258
255
|
/>
|
|
259
256
|
),
|
|
260
257
|
};
|
|
@@ -269,7 +266,7 @@ const Screen = forwardRef(
|
|
|
269
266
|
headerBackground: (props: any) => (
|
|
270
267
|
<HeaderBackground
|
|
271
268
|
{...props}
|
|
272
|
-
animatedValue={animatedValue}
|
|
269
|
+
animatedValue={animatedValue.current}
|
|
273
270
|
useShadowHeader={useShadowHeader}
|
|
274
271
|
headerBackground={headerBackground}
|
|
275
272
|
gradientColor={gradientColor}
|
|
@@ -288,8 +285,9 @@ const Screen = forwardRef(
|
|
|
288
285
|
interpolate={{
|
|
289
286
|
inputRange: [0, 50],
|
|
290
287
|
outputRange: [1, 0],
|
|
288
|
+
extrapolate: 'clamp',
|
|
291
289
|
}}
|
|
292
|
-
animatedValue={animatedValue}
|
|
290
|
+
animatedValue={animatedValue.current}
|
|
293
291
|
/>
|
|
294
292
|
),
|
|
295
293
|
};
|
|
@@ -324,7 +322,7 @@ const Screen = forwardRef(
|
|
|
324
322
|
headerBackground: (props: any) => (
|
|
325
323
|
<HeaderBackground
|
|
326
324
|
{...props}
|
|
327
|
-
animatedValue={animatedValue}
|
|
325
|
+
animatedValue={animatedValue.current}
|
|
328
326
|
useGradient={false}
|
|
329
327
|
useShadowHeader={useShadowHeader}
|
|
330
328
|
headerBackground={headerBackground}
|
|
@@ -362,8 +360,9 @@ const Screen = forwardRef(
|
|
|
362
360
|
interpolate={{
|
|
363
361
|
inputRange: [0, 50],
|
|
364
362
|
outputRange: [1, 0],
|
|
363
|
+
extrapolate: 'clamp',
|
|
365
364
|
}}
|
|
366
|
-
animatedValue={animatedValue}
|
|
365
|
+
animatedValue={animatedValue.current}
|
|
367
366
|
/>
|
|
368
367
|
),
|
|
369
368
|
};
|
|
@@ -392,7 +391,7 @@ const Screen = forwardRef(
|
|
|
392
391
|
headerLeft: (props: any) =>
|
|
393
392
|
params?.hiddenBack ? null : <HeaderLeft {...props} />,
|
|
394
393
|
headerTitle: () => (
|
|
395
|
-
<SearchHeader {...params} animatedValue={animatedValue} />
|
|
394
|
+
<SearchHeader {...params} animatedValue={animatedValue.current} />
|
|
396
395
|
),
|
|
397
396
|
};
|
|
398
397
|
|
|
@@ -443,51 +442,45 @@ const Screen = forwardRef(
|
|
|
443
442
|
});
|
|
444
443
|
});
|
|
445
444
|
|
|
446
|
-
const onTintColorChange = useCallback(
|
|
447
|
-
(offsetY: number) => {
|
|
448
|
-
if (!animatedHeader) return;
|
|
449
|
-
let color = animatedHeader?.headerTintColor ?? Colors.black_17;
|
|
450
|
-
if (offsetY > 50) {
|
|
451
|
-
color = Colors.black_17;
|
|
452
|
-
}
|
|
453
|
-
if (color !== currentTint.current) {
|
|
454
|
-
currentTint.current = color;
|
|
455
|
-
navigation?.setOptions({
|
|
456
|
-
headerTintColor: color,
|
|
457
|
-
});
|
|
458
|
-
let barStyle: StatusBarStyle = 'dark-content';
|
|
459
|
-
if (currentTint.current === Colors.black_01) {
|
|
460
|
-
barStyle = 'light-content';
|
|
461
|
-
}
|
|
462
|
-
StatusBar.setBarStyle(barStyle, true);
|
|
463
|
-
}
|
|
464
|
-
},
|
|
465
|
-
[animatedHeader, navigation],
|
|
466
|
-
);
|
|
467
|
-
|
|
468
|
-
const emitOnScroll = useCallback(
|
|
469
|
-
(offsetY: number) => {
|
|
470
|
-
scrollViewProps?.onScroll?.({
|
|
471
|
-
nativeEvent: { contentOffset: { x: 0, y: offsetY } },
|
|
472
|
-
} as NativeSyntheticEvent<NativeScrollEvent>);
|
|
473
|
-
},
|
|
474
|
-
[scrollViewProps],
|
|
475
|
-
);
|
|
476
|
-
|
|
477
|
-
const scrollHandler = useAnimatedScrollHandler({
|
|
478
|
-
onScroll: (event) => {
|
|
479
|
-
animatedValue.value = event.contentOffset.y;
|
|
480
|
-
runOnJS(emitOnScroll)(event.contentOffset.y);
|
|
481
|
-
runOnJS(onTintColorChange)(event.contentOffset.y);
|
|
482
|
-
},
|
|
483
|
-
});
|
|
484
|
-
|
|
485
445
|
/**
|
|
486
446
|
* animated when use scroll && animated value
|
|
487
447
|
*/
|
|
488
448
|
if (scrollable) {
|
|
489
449
|
Component = Animated.ScrollView;
|
|
490
|
-
handleScroll =
|
|
450
|
+
handleScroll = Animated.event(
|
|
451
|
+
[
|
|
452
|
+
{
|
|
453
|
+
nativeEvent: {
|
|
454
|
+
contentOffset: { y: animatedValue.current as Animated.Value },
|
|
455
|
+
},
|
|
456
|
+
},
|
|
457
|
+
],
|
|
458
|
+
{
|
|
459
|
+
useNativeDriver: true,
|
|
460
|
+
listener: (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
461
|
+
scrollViewProps?.onScroll?.(e);
|
|
462
|
+
if (animatedHeader) {
|
|
463
|
+
const offsetY = e.nativeEvent.contentOffset.y;
|
|
464
|
+
let color = animatedHeader?.headerTintColor ?? Colors.black_17;
|
|
465
|
+
if (offsetY > 50) {
|
|
466
|
+
color = Colors.black_17;
|
|
467
|
+
}
|
|
468
|
+
if (color !== currentTint.current) {
|
|
469
|
+
currentTint.current = color;
|
|
470
|
+
navigation?.setOptions({
|
|
471
|
+
headerTintColor: color,
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
let barStyle: StatusBarStyle = 'dark-content';
|
|
475
|
+
if (currentTint.current === Colors.black_01) {
|
|
476
|
+
barStyle = 'light-content';
|
|
477
|
+
}
|
|
478
|
+
StatusBar.setBarStyle(barStyle, true);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
},
|
|
483
|
+
);
|
|
491
484
|
}
|
|
492
485
|
|
|
493
486
|
/**
|
|
@@ -497,7 +490,11 @@ const Screen = forwardRef(
|
|
|
497
490
|
const handleScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
498
491
|
const offsetY = e.nativeEvent.contentOffset.y;
|
|
499
492
|
if (inputSearchProps && offsetY < 100 && offsetY > 0) {
|
|
500
|
-
animatedValue.
|
|
493
|
+
Animated.timing(animatedValue.current, {
|
|
494
|
+
toValue: 0,
|
|
495
|
+
useNativeDriver: true,
|
|
496
|
+
duration: 300,
|
|
497
|
+
}).start();
|
|
501
498
|
ref?.scrollTo?.({ y: 0, animated: true });
|
|
502
499
|
}
|
|
503
500
|
scrollViewProps?.onScrollEndDrag?.(e);
|
|
@@ -513,7 +510,7 @@ const Screen = forwardRef(
|
|
|
513
510
|
style={[styles.screenBanner, { maxHeight: 210 + layoutOffset }]}
|
|
514
511
|
>
|
|
515
512
|
{animatedHeader?.component({
|
|
516
|
-
animatedValue: animatedValue,
|
|
513
|
+
animatedValue: animatedValue.current,
|
|
517
514
|
})}
|
|
518
515
|
</View>
|
|
519
516
|
);
|
|
@@ -580,7 +577,7 @@ const Screen = forwardRef(
|
|
|
580
577
|
headerType={headerType}
|
|
581
578
|
heightHeader={heightHeader}
|
|
582
579
|
headerRightWidth={headerRightWidth}
|
|
583
|
-
animatedValue={animatedValue}
|
|
580
|
+
animatedValue={animatedValue.current}
|
|
584
581
|
inputSearchProps={inputSearchProps}
|
|
585
582
|
navigation={navigation}
|
|
586
583
|
inputSearchRef={inputSearchRef}
|
|
@@ -618,9 +615,9 @@ const Screen = forwardRef(
|
|
|
618
615
|
<View>
|
|
619
616
|
<FloatingButton
|
|
620
617
|
{...floatingButtonProps}
|
|
621
|
-
animatedValue={animatedValue}
|
|
618
|
+
animatedValue={animatedValue.current}
|
|
622
619
|
bottom={
|
|
623
|
-
Footer || isTab ? 12 :
|
|
620
|
+
Footer || isTab ? 12 : bottomInset + Spacing.S
|
|
624
621
|
}
|
|
625
622
|
/>
|
|
626
623
|
</View>
|
|
@@ -631,7 +628,7 @@ const Screen = forwardRef(
|
|
|
631
628
|
style={[
|
|
632
629
|
styles.shadow,
|
|
633
630
|
{
|
|
634
|
-
paddingBottom:
|
|
631
|
+
paddingBottom: bottomInset + Spacing.S,
|
|
635
632
|
backgroundColor: theme.colors.background.surface,
|
|
636
633
|
},
|
|
637
634
|
]}
|
package/Loader/ProgressBar.tsx
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import React, { FC, useContext, useEffect } from 'react';
|
|
2
|
-
import { View } from 'react-native';
|
|
3
|
-
import Animated, {
|
|
4
|
-
useAnimatedStyle,
|
|
5
|
-
useSharedValue,
|
|
6
|
-
withTiming,
|
|
7
|
-
} from 'react-native-reanimated';
|
|
1
|
+
import React, { FC, useContext, useEffect, useRef } from 'react';
|
|
2
|
+
import { Animated, View } from 'react-native';
|
|
8
3
|
import styles from './styles';
|
|
9
4
|
import { ProgressBarProps } from './types';
|
|
10
5
|
import { ApplicationContext } from '../Context';
|
|
@@ -12,15 +7,20 @@ import { Radius } from '../Consts';
|
|
|
12
7
|
|
|
13
8
|
const ProgressBar: FC<ProgressBarProps> = ({ percent = 0, style }) => {
|
|
14
9
|
const { theme } = useContext(ApplicationContext);
|
|
15
|
-
const animation =
|
|
10
|
+
const animation = useRef(new Animated.Value(0)).current;
|
|
16
11
|
|
|
17
12
|
useEffect(() => {
|
|
18
|
-
|
|
13
|
+
Animated.timing(animation, {
|
|
14
|
+
toValue: percent,
|
|
15
|
+
duration: 200,
|
|
16
|
+
useNativeDriver: false,
|
|
17
|
+
}).start();
|
|
19
18
|
}, [percent, animation]);
|
|
20
19
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
const width = animation.interpolate({
|
|
21
|
+
inputRange: [0, 100],
|
|
22
|
+
outputRange: ['0%', '100%'],
|
|
23
|
+
});
|
|
24
24
|
|
|
25
25
|
return (
|
|
26
26
|
<View
|
|
@@ -31,14 +31,12 @@ const ProgressBar: FC<ProgressBarProps> = ({ percent = 0, style }) => {
|
|
|
31
31
|
]}
|
|
32
32
|
>
|
|
33
33
|
<Animated.View
|
|
34
|
-
style={
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
animatedStyle,
|
|
41
|
-
]}
|
|
34
|
+
style={{
|
|
35
|
+
height: 4,
|
|
36
|
+
borderRadius: Radius.XXS,
|
|
37
|
+
width,
|
|
38
|
+
backgroundColor: theme.colors.primary,
|
|
39
|
+
}}
|
|
42
40
|
/>
|
|
43
41
|
</View>
|
|
44
42
|
);
|
package/Pagination/Dot.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { FC, useContext } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { Animated } from 'react-native';
|
|
3
3
|
import styles from './styles';
|
|
4
4
|
import { DotProps } from './types';
|
|
5
5
|
import { ApplicationContext } from '../Context';
|
|
@@ -13,7 +13,7 @@ const Dot: FC<DotProps> = ({ active, style }) => {
|
|
|
13
13
|
{ backgroundColor: theme.colors.background.pressed },
|
|
14
14
|
];
|
|
15
15
|
|
|
16
|
-
return <View style={[style, dotStyle]} />;
|
|
16
|
+
return <Animated.View style={[style, dotStyle]} />;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
export default Dot;
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
import React, { FC, useContext, useState } from 'react';
|
|
2
|
-
import { View } from 'react-native';
|
|
3
|
-
import Animated, {
|
|
4
|
-
Extrapolation,
|
|
5
|
-
interpolate,
|
|
6
|
-
useAnimatedScrollHandler,
|
|
7
|
-
useAnimatedStyle,
|
|
8
|
-
useSharedValue,
|
|
9
|
-
} from 'react-native-reanimated';
|
|
1
|
+
import React, { FC, useContext, useRef, useState } from 'react';
|
|
2
|
+
import { Animated, View } from 'react-native';
|
|
10
3
|
import { ScrollIndicatorProps } from './types';
|
|
11
4
|
import styles from './styles';
|
|
12
5
|
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
@@ -20,37 +13,40 @@ const PaginationScroll: FC<ScrollIndicatorProps> = ({
|
|
|
20
13
|
}) => {
|
|
21
14
|
const { theme } = useContext(ApplicationContext);
|
|
22
15
|
const context = useContext<any>(MiniAppContext);
|
|
23
|
-
const left =
|
|
16
|
+
const left = useRef(new Animated.Value(0)).current;
|
|
24
17
|
const [scrollViewWidth, setScrollViewWidth] = useState(0);
|
|
25
18
|
const [scrollContentWidth, setScrollContentWidth] = useState(0);
|
|
26
19
|
|
|
27
20
|
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
28
21
|
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return {};
|
|
22
|
+
const translateX = () => {
|
|
23
|
+
if (scrollViewWidth && scrollContentWidth) {
|
|
24
|
+
const value = left.interpolate({
|
|
25
|
+
inputRange: [0, scrollContentWidth - scrollViewWidth],
|
|
26
|
+
outputRange: [0, INDICATOR_CONTAINER_WIDTH - INDICATOR_WIDTH],
|
|
27
|
+
extrapolate: 'clamp',
|
|
28
|
+
});
|
|
29
|
+
return { transform: [{ translateX: value }] };
|
|
38
30
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
[0, scrollContentWidth - scrollViewWidth],
|
|
42
|
-
[0, INDICATOR_CONTAINER_WIDTH - INDICATOR_WIDTH],
|
|
43
|
-
Extrapolation.CLAMP,
|
|
44
|
-
);
|
|
45
|
-
return { transform: [{ translateX: value }] };
|
|
46
|
-
});
|
|
31
|
+
return {};
|
|
32
|
+
};
|
|
47
33
|
|
|
48
34
|
const renderScrollView = () => {
|
|
49
35
|
return (
|
|
50
36
|
<Animated.ScrollView
|
|
51
|
-
ref={scrollViewRef
|
|
52
|
-
onScroll={
|
|
53
|
-
|
|
37
|
+
ref={scrollViewRef}
|
|
38
|
+
onScroll={Animated.event(
|
|
39
|
+
[
|
|
40
|
+
{
|
|
41
|
+
nativeEvent: {
|
|
42
|
+
contentOffset: {
|
|
43
|
+
x: left,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
{ useNativeDriver: true },
|
|
49
|
+
)}
|
|
54
50
|
alwaysBounceHorizontal={false}
|
|
55
51
|
showsHorizontalScrollIndicator={false}
|
|
56
52
|
horizontal
|
|
@@ -80,7 +76,7 @@ const PaginationScroll: FC<ScrollIndicatorProps> = ({
|
|
|
80
76
|
{
|
|
81
77
|
backgroundColor: theme.colors.primary,
|
|
82
78
|
},
|
|
83
|
-
|
|
79
|
+
translateX(),
|
|
84
80
|
]}
|
|
85
81
|
/>
|
|
86
82
|
</View>
|