@momo-kits/foundation 0.161.1-beta.2 → 0.161.2-beta.1
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 +3 -3
- package/Application/BottomTab/BottomTabBar.tsx +17 -17
- package/Application/BottomTab/CustomBottomTabItem.tsx +1 -1
- package/Application/BottomTab/index.tsx +31 -55
- package/Application/Components/BackgroundImageView.tsx +22 -6
- package/Application/Components/HeaderAnimated.tsx +32 -29
- package/Application/Components/HeaderBackground.tsx +21 -27
- package/Application/Components/HeaderExtendHeader.tsx +114 -94
- package/Application/Components/HeaderTitle.tsx +40 -11
- package/Application/Components/SearchHeader.tsx +17 -22
- package/Application/NavigationContainer.tsx +21 -25
- package/Application/ScaleSizeProvider.tsx +16 -0
- package/Application/WidgetContainer.tsx +7 -18
- package/Application/index.ts +2 -0
- package/Application/types.ts +10 -4
- package/Application/utils.tsx +4 -3
- package/Badge/Badge.tsx +3 -9
- package/Badge/BadgeDot.tsx +1 -1
- package/Badge/BadgeDotAnimation.tsx +53 -71
- package/Badge/BadgeRibbon.tsx +1 -1
- package/Button/index.tsx +3 -6
- package/CheckBox/index.tsx +1 -1
- package/Context/index.ts +4 -0
- package/Icon/index.tsx +1 -1
- package/IconButton/index.tsx +1 -1
- package/Image/index.tsx +13 -3
- package/Input/Input.tsx +1 -1
- package/Input/InputDropDown.tsx +1 -1
- package/Input/InputMoney.tsx +1 -1
- package/Input/InputOTP.tsx +39 -24
- package/Input/InputPhoneNumber.tsx +1 -1
- package/Input/InputSearch.tsx +1 -1
- package/Input/InputTextArea.tsx +10 -4
- package/Layout/FloatingButton.tsx +59 -59
- package/Layout/Item.tsx +1 -1
- package/Layout/Screen.tsx +61 -57
- package/Loader/ProgressBar.tsx +20 -18
- package/Pagination/Dot.tsx +2 -2
- package/Pagination/PaginationDot.tsx +1 -1
- package/Pagination/PaginationNumber.tsx +1 -1
- package/Pagination/PaginationScroll.tsx +32 -28
- package/Pagination/PaginationWhiteDot.tsx +1 -1
- package/Popup/PopupNotify.tsx +1 -1
- package/Popup/PopupPromotion.tsx +1 -1
- package/Radio/index.tsx +1 -1
- package/Skeleton/index.tsx +32 -24
- package/Switch/index.tsx +1 -1
- package/Tag/index.tsx +1 -1
- package/Text/index.tsx +1 -1
- package/Text/utils.ts +41 -18
- package/Title/index.tsx +1 -1
- package/package.json +34 -34
|
@@ -1,17 +1,18 @@
|
|
|
1
|
+
import React, { useContext, useEffect, useState } from 'react';
|
|
1
2
|
import {
|
|
2
|
-
default as React,
|
|
3
|
-
useContext,
|
|
4
|
-
useEffect,
|
|
5
|
-
useRef,
|
|
6
|
-
useState,
|
|
7
|
-
} from 'react';
|
|
8
|
-
import {
|
|
9
|
-
Animated,
|
|
10
3
|
LayoutChangeEvent,
|
|
11
4
|
StyleSheet,
|
|
12
5
|
TouchableOpacity,
|
|
13
6
|
View,
|
|
14
7
|
} from 'react-native';
|
|
8
|
+
import Animated, {
|
|
9
|
+
useAnimatedReaction,
|
|
10
|
+
useAnimatedStyle,
|
|
11
|
+
useSharedValue,
|
|
12
|
+
withTiming,
|
|
13
|
+
runOnJS,
|
|
14
|
+
type SharedValue,
|
|
15
|
+
} from 'react-native-reanimated';
|
|
15
16
|
import { ApplicationContext } from '../Context';
|
|
16
17
|
import { Icon } from '../Icon';
|
|
17
18
|
import { useScaleSize } from '../Text';
|
|
@@ -23,7 +24,7 @@ export interface FloatingButtonProps {
|
|
|
23
24
|
icon?: string;
|
|
24
25
|
iconColor?: string;
|
|
25
26
|
size?: 'small' | 'large';
|
|
26
|
-
animatedValue?:
|
|
27
|
+
animatedValue?: SharedValue<number>;
|
|
27
28
|
bottom?: number;
|
|
28
29
|
renderComponent?: () => React.ReactNode;
|
|
29
30
|
}
|
|
@@ -42,68 +43,67 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
|
42
43
|
const { theme } = useContext(ApplicationContext);
|
|
43
44
|
const scaledFontSize = useScaleSize(16);
|
|
44
45
|
const scaledLineHeight = useScaleSize(22);
|
|
45
|
-
const maxWidth =
|
|
46
|
+
const maxWidth = useSharedValue(0);
|
|
46
47
|
const minWidth = size === 'small' ? 36 : 48;
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
const lastOffset =
|
|
50
|
-
const lastDirection =
|
|
51
|
-
const [showText, setShowText] =
|
|
48
|
+
const opacityAnimated = useSharedValue(0);
|
|
49
|
+
const widthAnimated = useSharedValue<number | null>(null);
|
|
50
|
+
const lastOffset = useSharedValue(0);
|
|
51
|
+
const lastDirection = useSharedValue<string | null>(null);
|
|
52
|
+
const [showText, setShowText] = useState(true);
|
|
52
53
|
|
|
53
54
|
useEffect(() => {
|
|
54
55
|
if (!label) return;
|
|
56
|
+
opacityAnimated.value = withTiming(1, { duration: 100 });
|
|
57
|
+
}, [label, opacityAnimated]);
|
|
55
58
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (lastDirection.current !== direction) {
|
|
67
|
-
lastDirection.current = direction;
|
|
59
|
+
useAnimatedReaction(
|
|
60
|
+
() => animatedValue?.value ?? 0,
|
|
61
|
+
(value) => {
|
|
62
|
+
'worklet';
|
|
63
|
+
if (!label || !animatedValue) return;
|
|
64
|
+
if (value !== lastOffset.value && value > 0) {
|
|
65
|
+
const direction = value > lastOffset.value ? 'down' : 'up';
|
|
66
|
+
lastOffset.value = value;
|
|
67
|
+
if (lastDirection.value !== direction) {
|
|
68
|
+
lastDirection.value = direction;
|
|
68
69
|
if (direction === 'down') {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
useNativeDriver: false,
|
|
78
|
-
}).start(() => setShowText(false));
|
|
70
|
+
opacityAnimated.value = withTiming(0, { duration: 100 });
|
|
71
|
+
widthAnimated.value = withTiming(
|
|
72
|
+
minWidth,
|
|
73
|
+
{ duration: 100 },
|
|
74
|
+
(finished) => {
|
|
75
|
+
if (finished) runOnJS(setShowText)(false);
|
|
76
|
+
},
|
|
77
|
+
);
|
|
79
78
|
} else {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
useNativeDriver: false,
|
|
89
|
-
}).start(() => setShowText(true));
|
|
79
|
+
opacityAnimated.value = withTiming(1, { duration: 100 });
|
|
80
|
+
widthAnimated.value = withTiming(
|
|
81
|
+
maxWidth.value,
|
|
82
|
+
{ duration: 100 },
|
|
83
|
+
(finished) => {
|
|
84
|
+
if (finished) runOnJS(setShowText)(true);
|
|
85
|
+
},
|
|
86
|
+
);
|
|
90
87
|
}
|
|
91
88
|
}
|
|
92
89
|
}
|
|
93
|
-
}
|
|
90
|
+
},
|
|
91
|
+
[label, animatedValue, minWidth],
|
|
92
|
+
);
|
|
94
93
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
94
|
+
const containerStyle = useAnimatedStyle(() => ({
|
|
95
|
+
width: widthAnimated.value ?? undefined,
|
|
96
|
+
}));
|
|
97
|
+
|
|
98
|
+
const labelStyle = useAnimatedStyle(() => ({
|
|
99
|
+
opacity: opacityAnimated.value,
|
|
100
|
+
}));
|
|
101
101
|
|
|
102
102
|
const handleLayout = (event: LayoutChangeEvent) => {
|
|
103
103
|
const layout = event.nativeEvent.layout;
|
|
104
|
-
if (widthAnimated) return;
|
|
105
|
-
maxWidth.
|
|
106
|
-
|
|
104
|
+
if (widthAnimated.value != null) return;
|
|
105
|
+
maxWidth.value = layout.width;
|
|
106
|
+
widthAnimated.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,
|
|
136
135
|
height: size === 'small' ? 36 : 48,
|
|
137
136
|
backgroundColor: theme.colors.primary,
|
|
138
137
|
bottom,
|
|
139
138
|
},
|
|
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,
|
|
160
159
|
color: 'white',
|
|
161
160
|
},
|
|
161
|
+
labelStyle,
|
|
162
162
|
]}
|
|
163
163
|
numberOfLines={1}
|
|
164
164
|
>
|
package/Layout/Item.tsx
CHANGED
|
@@ -27,7 +27,7 @@ const Item: React.FC<ItemProps> = ({
|
|
|
27
27
|
const context = useContext<any>(MiniAppContext);
|
|
28
28
|
const grid = useContext(GridContext);
|
|
29
29
|
|
|
30
|
-
const showBaseLineDebug = context?.
|
|
30
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* render overlay view only dev mode
|
package/Layout/Screen.tsx
CHANGED
|
@@ -12,7 +12,6 @@ import React, {
|
|
|
12
12
|
useRef,
|
|
13
13
|
} from 'react';
|
|
14
14
|
import {
|
|
15
|
-
Animated,
|
|
16
15
|
KeyboardAvoidingView,
|
|
17
16
|
NativeScrollEvent,
|
|
18
17
|
NativeSyntheticEvent,
|
|
@@ -25,6 +24,13 @@ import {
|
|
|
25
24
|
View,
|
|
26
25
|
ViewProps,
|
|
27
26
|
} from 'react-native';
|
|
27
|
+
import Animated, {
|
|
28
|
+
runOnJS,
|
|
29
|
+
useAnimatedScrollHandler,
|
|
30
|
+
useSharedValue,
|
|
31
|
+
withTiming,
|
|
32
|
+
type SharedValue,
|
|
33
|
+
} from 'react-native-reanimated';
|
|
28
34
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
29
35
|
import { ApplicationContext, ScreenContext } from '../Context';
|
|
30
36
|
import Navigation from '../Application/Navigation';
|
|
@@ -138,7 +144,7 @@ export interface ScreenProps extends ViewProps {
|
|
|
138
144
|
/**
|
|
139
145
|
* Optional. Animated value for header.
|
|
140
146
|
*/
|
|
141
|
-
animatedValue?:
|
|
147
|
+
animatedValue?: SharedValue<number>;
|
|
142
148
|
|
|
143
149
|
/**
|
|
144
150
|
* Optional. If `true`, use shadow header.
|
|
@@ -195,13 +201,12 @@ const Screen = forwardRef(
|
|
|
195
201
|
const screen: any = useContext(ScreenContext);
|
|
196
202
|
const insets = useSafeAreaInsets();
|
|
197
203
|
const heightHeader = useHeaderHeight();
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
);
|
|
204
|
+
const internalAnimatedValue = useSharedValue(0);
|
|
205
|
+
const animatedValue = customAnimatedValue ?? internalAnimatedValue;
|
|
201
206
|
const currentTint = useRef<string | undefined>(undefined);
|
|
202
207
|
const isTab = navigation?.instance?.getState?.()?.type === 'tab';
|
|
203
208
|
|
|
204
|
-
let handleScroll;
|
|
209
|
+
let handleScroll: any;
|
|
205
210
|
let Component: any = View;
|
|
206
211
|
|
|
207
212
|
let keyboardOffset = heightHeader - Math.min(insets.bottom, 21);
|
|
@@ -248,9 +253,8 @@ const Screen = forwardRef(
|
|
|
248
253
|
interpolate={{
|
|
249
254
|
inputRange: [0, 50],
|
|
250
255
|
outputRange: [1, 0],
|
|
251
|
-
extrapolate: 'clamp',
|
|
252
256
|
}}
|
|
253
|
-
animatedValue={animatedValue
|
|
257
|
+
animatedValue={animatedValue}
|
|
254
258
|
/>
|
|
255
259
|
),
|
|
256
260
|
};
|
|
@@ -265,7 +269,7 @@ const Screen = forwardRef(
|
|
|
265
269
|
headerBackground: (props: any) => (
|
|
266
270
|
<HeaderBackground
|
|
267
271
|
{...props}
|
|
268
|
-
animatedValue={animatedValue
|
|
272
|
+
animatedValue={animatedValue}
|
|
269
273
|
useShadowHeader={useShadowHeader}
|
|
270
274
|
headerBackground={headerBackground}
|
|
271
275
|
gradientColor={gradientColor}
|
|
@@ -284,9 +288,8 @@ const Screen = forwardRef(
|
|
|
284
288
|
interpolate={{
|
|
285
289
|
inputRange: [0, 50],
|
|
286
290
|
outputRange: [1, 0],
|
|
287
|
-
extrapolate: 'clamp',
|
|
288
291
|
}}
|
|
289
|
-
animatedValue={animatedValue
|
|
292
|
+
animatedValue={animatedValue}
|
|
290
293
|
/>
|
|
291
294
|
),
|
|
292
295
|
};
|
|
@@ -321,7 +324,7 @@ const Screen = forwardRef(
|
|
|
321
324
|
headerBackground: (props: any) => (
|
|
322
325
|
<HeaderBackground
|
|
323
326
|
{...props}
|
|
324
|
-
animatedValue={animatedValue
|
|
327
|
+
animatedValue={animatedValue}
|
|
325
328
|
useGradient={false}
|
|
326
329
|
useShadowHeader={useShadowHeader}
|
|
327
330
|
headerBackground={headerBackground}
|
|
@@ -359,9 +362,8 @@ const Screen = forwardRef(
|
|
|
359
362
|
interpolate={{
|
|
360
363
|
inputRange: [0, 50],
|
|
361
364
|
outputRange: [1, 0],
|
|
362
|
-
extrapolate: 'clamp',
|
|
363
365
|
}}
|
|
364
|
-
animatedValue={animatedValue
|
|
366
|
+
animatedValue={animatedValue}
|
|
365
367
|
/>
|
|
366
368
|
),
|
|
367
369
|
};
|
|
@@ -390,7 +392,7 @@ const Screen = forwardRef(
|
|
|
390
392
|
headerLeft: (props: any) =>
|
|
391
393
|
params?.hiddenBack ? null : <HeaderLeft {...props} />,
|
|
392
394
|
headerTitle: () => (
|
|
393
|
-
<SearchHeader {...params} animatedValue={animatedValue
|
|
395
|
+
<SearchHeader {...params} animatedValue={animatedValue} />
|
|
394
396
|
),
|
|
395
397
|
};
|
|
396
398
|
|
|
@@ -441,45 +443,51 @@ const Screen = forwardRef(
|
|
|
441
443
|
});
|
|
442
444
|
});
|
|
443
445
|
|
|
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
|
+
|
|
444
485
|
/**
|
|
445
486
|
* animated when use scroll && animated value
|
|
446
487
|
*/
|
|
447
488
|
if (scrollable) {
|
|
448
489
|
Component = Animated.ScrollView;
|
|
449
|
-
handleScroll =
|
|
450
|
-
[
|
|
451
|
-
{
|
|
452
|
-
nativeEvent: {
|
|
453
|
-
contentOffset: { y: animatedValue.current as Animated.Value },
|
|
454
|
-
},
|
|
455
|
-
},
|
|
456
|
-
],
|
|
457
|
-
{
|
|
458
|
-
useNativeDriver: true,
|
|
459
|
-
listener: (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
460
|
-
scrollViewProps?.onScroll?.(e);
|
|
461
|
-
if (animatedHeader) {
|
|
462
|
-
const offsetY = e.nativeEvent.contentOffset.y;
|
|
463
|
-
let color = animatedHeader?.headerTintColor ?? Colors.black_17;
|
|
464
|
-
if (offsetY > 50) {
|
|
465
|
-
color = Colors.black_17;
|
|
466
|
-
}
|
|
467
|
-
if (color !== currentTint.current) {
|
|
468
|
-
currentTint.current = color;
|
|
469
|
-
navigation?.setOptions({
|
|
470
|
-
headerTintColor: color,
|
|
471
|
-
});
|
|
472
|
-
|
|
473
|
-
let barStyle: StatusBarStyle = 'dark-content';
|
|
474
|
-
if (currentTint.current === Colors.black_01) {
|
|
475
|
-
barStyle = 'light-content';
|
|
476
|
-
}
|
|
477
|
-
StatusBar.setBarStyle(barStyle, true);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
},
|
|
481
|
-
},
|
|
482
|
-
);
|
|
490
|
+
handleScroll = scrollHandler;
|
|
483
491
|
}
|
|
484
492
|
|
|
485
493
|
/**
|
|
@@ -489,11 +497,7 @@ const Screen = forwardRef(
|
|
|
489
497
|
const handleScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
490
498
|
const offsetY = e.nativeEvent.contentOffset.y;
|
|
491
499
|
if (inputSearchProps && offsetY < 100 && offsetY > 0) {
|
|
492
|
-
|
|
493
|
-
toValue: 0,
|
|
494
|
-
useNativeDriver: true,
|
|
495
|
-
duration: 300,
|
|
496
|
-
}).start();
|
|
500
|
+
animatedValue.value = withTiming(0, { duration: 300 });
|
|
497
501
|
ref?.scrollTo?.({ y: 0, animated: true });
|
|
498
502
|
}
|
|
499
503
|
scrollViewProps?.onScrollEndDrag?.(e);
|
|
@@ -509,7 +513,7 @@ const Screen = forwardRef(
|
|
|
509
513
|
style={[styles.screenBanner, { maxHeight: 210 + layoutOffset }]}
|
|
510
514
|
>
|
|
511
515
|
{animatedHeader?.component({
|
|
512
|
-
animatedValue: animatedValue
|
|
516
|
+
animatedValue: animatedValue,
|
|
513
517
|
})}
|
|
514
518
|
</View>
|
|
515
519
|
);
|
|
@@ -576,7 +580,7 @@ const Screen = forwardRef(
|
|
|
576
580
|
headerType={headerType}
|
|
577
581
|
heightHeader={heightHeader}
|
|
578
582
|
headerRightWidth={headerRightWidth}
|
|
579
|
-
animatedValue={animatedValue
|
|
583
|
+
animatedValue={animatedValue}
|
|
580
584
|
inputSearchProps={inputSearchProps}
|
|
581
585
|
navigation={navigation}
|
|
582
586
|
inputSearchRef={inputSearchRef}
|
|
@@ -614,7 +618,7 @@ const Screen = forwardRef(
|
|
|
614
618
|
<View>
|
|
615
619
|
<FloatingButton
|
|
616
620
|
{...floatingButtonProps}
|
|
617
|
-
animatedValue={animatedValue
|
|
621
|
+
animatedValue={animatedValue}
|
|
618
622
|
bottom={
|
|
619
623
|
Footer || isTab ? 12 : Math.min(insets.bottom, 21) + Spacing.S
|
|
620
624
|
}
|
package/Loader/ProgressBar.tsx
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import React, { FC, useContext, useEffect
|
|
2
|
-
import {
|
|
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';
|
|
3
8
|
import styles from './styles';
|
|
4
9
|
import { ProgressBarProps } from './types';
|
|
5
10
|
import { ApplicationContext } from '../Context';
|
|
@@ -7,20 +12,15 @@ import { Radius } from '../Consts';
|
|
|
7
12
|
|
|
8
13
|
const ProgressBar: FC<ProgressBarProps> = ({ percent = 0, style }) => {
|
|
9
14
|
const { theme } = useContext(ApplicationContext);
|
|
10
|
-
const animation =
|
|
15
|
+
const animation = useSharedValue(0);
|
|
11
16
|
|
|
12
17
|
useEffect(() => {
|
|
13
|
-
|
|
14
|
-
toValue: percent,
|
|
15
|
-
duration: 200,
|
|
16
|
-
useNativeDriver: false,
|
|
17
|
-
}).start();
|
|
18
|
+
animation.value = withTiming(percent, { duration: 200 });
|
|
18
19
|
}, [percent, animation]);
|
|
19
20
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
});
|
|
21
|
+
const animatedStyle = useAnimatedStyle(() => ({
|
|
22
|
+
width: `${Math.min(Math.max(animation.value, 0), 100)}%`,
|
|
23
|
+
}));
|
|
24
24
|
|
|
25
25
|
return (
|
|
26
26
|
<View
|
|
@@ -31,12 +31,14 @@ const ProgressBar: FC<ProgressBarProps> = ({ percent = 0, style }) => {
|
|
|
31
31
|
]}
|
|
32
32
|
>
|
|
33
33
|
<Animated.View
|
|
34
|
-
style={
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
style={[
|
|
35
|
+
{
|
|
36
|
+
height: 4,
|
|
37
|
+
borderRadius: Radius.XXS,
|
|
38
|
+
backgroundColor: theme.colors.primary,
|
|
39
|
+
},
|
|
40
|
+
animatedStyle,
|
|
41
|
+
]}
|
|
40
42
|
/>
|
|
41
43
|
</View>
|
|
42
44
|
);
|
package/Pagination/Dot.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { FC, useContext } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { View } 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 <
|
|
16
|
+
return <View style={[style, dotStyle]} />;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
export default Dot;
|
|
@@ -14,7 +14,7 @@ const PaginationDot: FC<ChildPaginationProps> = ({
|
|
|
14
14
|
const { theme } = useContext(ApplicationContext);
|
|
15
15
|
const context = useContext<any>(MiniAppContext);
|
|
16
16
|
|
|
17
|
-
const showBaseLineDebug = context?.
|
|
17
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
18
18
|
|
|
19
19
|
const renderDots = () => {
|
|
20
20
|
const dots: React.ReactElement[] = [];
|
|
@@ -13,7 +13,7 @@ const PaginationNumber: FC<ChildPaginationProps> = ({
|
|
|
13
13
|
}) => {
|
|
14
14
|
const context = useContext<any>(MiniAppContext);
|
|
15
15
|
|
|
16
|
-
const showBaseLineDebug = context?.
|
|
16
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
17
17
|
|
|
18
18
|
return (
|
|
19
19
|
<View
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import React, { FC, useContext,
|
|
2
|
-
import {
|
|
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';
|
|
3
10
|
import { ScrollIndicatorProps } from './types';
|
|
4
11
|
import styles from './styles';
|
|
5
12
|
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
@@ -13,40 +20,37 @@ const PaginationScroll: FC<ScrollIndicatorProps> = ({
|
|
|
13
20
|
}) => {
|
|
14
21
|
const { theme } = useContext(ApplicationContext);
|
|
15
22
|
const context = useContext<any>(MiniAppContext);
|
|
16
|
-
const left =
|
|
23
|
+
const left = useSharedValue(0);
|
|
17
24
|
const [scrollViewWidth, setScrollViewWidth] = useState(0);
|
|
18
25
|
const [scrollContentWidth, setScrollContentWidth] = useState(0);
|
|
19
26
|
|
|
20
|
-
const showBaseLineDebug = context?.
|
|
27
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
21
28
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
const onScroll = useAnimatedScrollHandler({
|
|
30
|
+
onScroll: (event) => {
|
|
31
|
+
left.value = event.contentOffset.x;
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const indicatorStyle = useAnimatedStyle(() => {
|
|
36
|
+
if (!scrollViewWidth || !scrollContentWidth) {
|
|
37
|
+
return {};
|
|
30
38
|
}
|
|
31
|
-
|
|
32
|
-
|
|
39
|
+
const value = interpolate(
|
|
40
|
+
left.value,
|
|
41
|
+
[0, scrollContentWidth - scrollViewWidth],
|
|
42
|
+
[0, INDICATOR_CONTAINER_WIDTH - INDICATOR_WIDTH],
|
|
43
|
+
Extrapolation.CLAMP,
|
|
44
|
+
);
|
|
45
|
+
return { transform: [{ translateX: value }] };
|
|
46
|
+
});
|
|
33
47
|
|
|
34
48
|
const renderScrollView = () => {
|
|
35
49
|
return (
|
|
36
50
|
<Animated.ScrollView
|
|
37
|
-
ref={scrollViewRef}
|
|
38
|
-
onScroll={
|
|
39
|
-
|
|
40
|
-
{
|
|
41
|
-
nativeEvent: {
|
|
42
|
-
contentOffset: {
|
|
43
|
-
x: left,
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
{ useNativeDriver: true },
|
|
49
|
-
)}
|
|
51
|
+
ref={scrollViewRef as any}
|
|
52
|
+
onScroll={onScroll}
|
|
53
|
+
scrollEventThrottle={16}
|
|
50
54
|
alwaysBounceHorizontal={false}
|
|
51
55
|
showsHorizontalScrollIndicator={false}
|
|
52
56
|
horizontal
|
|
@@ -76,7 +80,7 @@ const PaginationScroll: FC<ScrollIndicatorProps> = ({
|
|
|
76
80
|
{
|
|
77
81
|
backgroundColor: theme.colors.primary,
|
|
78
82
|
},
|
|
79
|
-
|
|
83
|
+
indicatorStyle,
|
|
80
84
|
]}
|
|
81
85
|
/>
|
|
82
86
|
</View>
|
|
@@ -13,7 +13,7 @@ const PaginationWhiteDot: FC<ChildPaginationProps> = ({
|
|
|
13
13
|
}) => {
|
|
14
14
|
const context = useContext<any>(MiniAppContext);
|
|
15
15
|
|
|
16
|
-
const showBaseLineDebug = context?.
|
|
16
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
17
17
|
|
|
18
18
|
const renderDots = () => {
|
|
19
19
|
const dots: React.ReactElement[] = [];
|
package/Popup/PopupNotify.tsx
CHANGED
|
@@ -32,7 +32,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
32
32
|
const { width: widthDevice } = Dimensions.get('window');
|
|
33
33
|
const scaledMaxHeight = useScaleSize(172);
|
|
34
34
|
|
|
35
|
-
const showBaseLineDebug = context?.
|
|
35
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
36
36
|
const closeAction = useRef('touch_outside');
|
|
37
37
|
let descriptionStyle = {};
|
|
38
38
|
let Description: any = View;
|
package/Popup/PopupPromotion.tsx
CHANGED
|
@@ -17,7 +17,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
|
17
17
|
const { width: widthDevice } = Dimensions.get('window');
|
|
18
18
|
const closeAction = useRef('touch_outside');
|
|
19
19
|
|
|
20
|
-
const showBaseLineDebug = context?.
|
|
20
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* on action popup
|
package/Radio/index.tsx
CHANGED
|
@@ -33,7 +33,7 @@ const Radio: FC<RadioProps> = ({
|
|
|
33
33
|
accessibilityLabel,
|
|
34
34
|
);
|
|
35
35
|
|
|
36
|
-
const showBaseLineDebug = context?.
|
|
36
|
+
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
37
37
|
let disabledStyle = {};
|
|
38
38
|
let checkBoxStyle = {
|
|
39
39
|
borderWidth: 2,
|