@momo-kits/foundation 0.162.2-test.8 → 0.162.3-fontscale.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 +5 -4
- package/Application/BottomTab/BottomTabBar.tsx +15 -15
- package/Application/BottomTab/index.tsx +32 -56
- package/Application/Components/BackgroundImageView.tsx +22 -6
- package/Application/Components/HeaderAnimated.tsx +29 -29
- package/Application/Components/HeaderBackground.tsx +20 -26
- package/Application/Components/HeaderExtendHeader.tsx +115 -94
- package/Application/Components/HeaderLeft.tsx +1 -1
- package/Application/Components/HeaderTitle.tsx +43 -10
- package/Application/Components/SearchHeader.tsx +13 -21
- package/Application/NavigationContainer.tsx +8 -27
- package/Application/ScaleSizeProvider.tsx +3 -5
- package/Application/WidgetContainer.tsx +1 -1
- package/Application/types.ts +5 -5
- package/Application/utils.tsx +42 -2
- package/Badge/BadgeDotAnimation.tsx +53 -71
- package/Button/index.tsx +1 -4
- package/Context/index.ts +3 -6
- package/Input/Input.tsx +12 -1
- package/Input/InputOTP.tsx +38 -23
- package/Input/InputPhoneNumber.tsx +12 -1
- package/Layout/FloatingButton.tsx +64 -59
- package/Layout/Screen.tsx +75 -21
- package/Loader/ProgressBar.tsx +20 -18
- package/Pagination/Dot.tsx +2 -2
- package/Pagination/PaginationScroll.tsx +31 -27
- package/Skeleton/index.tsx +32 -24
- package/Text/utils.ts +6 -11
- package/package.json +1 -1
package/Layout/Screen.tsx
CHANGED
|
@@ -25,6 +25,10 @@ import {
|
|
|
25
25
|
View,
|
|
26
26
|
ViewProps,
|
|
27
27
|
} from 'react-native';
|
|
28
|
+
import {
|
|
29
|
+
useSharedValue,
|
|
30
|
+
withTiming,
|
|
31
|
+
} from 'react-native-reanimated';
|
|
28
32
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
29
33
|
import { ApplicationContext, ScreenContext } from '../Context';
|
|
30
34
|
import Navigation from '../Application/Navigation';
|
|
@@ -136,7 +140,8 @@ export interface ScreenProps extends ViewProps {
|
|
|
136
140
|
inputSearchRef?: Ref<InputRef>;
|
|
137
141
|
|
|
138
142
|
/**
|
|
139
|
-
* Optional.
|
|
143
|
+
* Optional. React Native animated value for header.
|
|
144
|
+
* Internally, Screen mirrors it into a reanimated shared value.
|
|
140
145
|
*/
|
|
141
146
|
animatedValue?: Animated.Value;
|
|
142
147
|
|
|
@@ -195,18 +200,50 @@ const Screen = forwardRef(
|
|
|
195
200
|
const screen: any = useContext(ScreenContext);
|
|
196
201
|
const insets = useSafeAreaInsets();
|
|
197
202
|
const heightHeader = useHeaderHeight();
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Dual animation source:
|
|
206
|
+
* - `animatedValue` is a react-native `Animated.Value` driven natively by the
|
|
207
|
+
* scroll event. It is what legacy consumers receive (`animatedValue`).
|
|
208
|
+
* - `sharedValue` is a reanimated `SharedValue` consumed by every internal
|
|
209
|
+
* foundation component (and offered to modern consumers). It is kept in
|
|
210
|
+
* sync from the scroll `listener` (see below), which fires on the JS
|
|
211
|
+
* thread even when the scroll uses the native driver.
|
|
212
|
+
* If a legacy value is driven outside of Screen, its listener also
|
|
213
|
+
* mirrors JS-driven updates into the shared value.
|
|
214
|
+
* Consumers pass only `Animated.Value`; the reanimated shared value stays
|
|
215
|
+
* an internal implementation detail.
|
|
216
|
+
*/
|
|
198
217
|
const animatedValue = useRef<Animated.Value>(
|
|
199
|
-
customAnimatedValue
|
|
218
|
+
customAnimatedValue ?? new Animated.Value(0),
|
|
200
219
|
);
|
|
220
|
+
const internalShared = useSharedValue(0);
|
|
221
|
+
const sharedValue = internalShared;
|
|
222
|
+
|
|
223
|
+
useEffect(() => {
|
|
224
|
+
if (!customAnimatedValue) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const listenerId = customAnimatedValue.addListener(({ value }) => {
|
|
229
|
+
internalShared.value = value;
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
return () => {
|
|
233
|
+
customAnimatedValue.removeListener(listenerId);
|
|
234
|
+
};
|
|
235
|
+
}, [customAnimatedValue, internalShared]);
|
|
236
|
+
|
|
201
237
|
const currentTint = useRef<string | undefined>(undefined);
|
|
202
238
|
const isTab = navigation?.instance?.getState?.()?.type === 'tab';
|
|
203
239
|
|
|
204
240
|
let handleScroll;
|
|
205
241
|
let Component: any = View;
|
|
206
242
|
|
|
207
|
-
|
|
243
|
+
const bottomInset = Platform.OS === 'ios' ? Math.min(insets.bottom, 21) : insets.bottom;
|
|
244
|
+
let keyboardOffset = heightHeader - bottomInset;
|
|
208
245
|
if (headerType === 'extended' || animatedHeader || inputSearchProps) {
|
|
209
|
-
keyboardOffset = -
|
|
246
|
+
keyboardOffset = -bottomInset;
|
|
210
247
|
}
|
|
211
248
|
|
|
212
249
|
/**
|
|
@@ -248,9 +285,8 @@ const Screen = forwardRef(
|
|
|
248
285
|
interpolate={{
|
|
249
286
|
inputRange: [0, 50],
|
|
250
287
|
outputRange: [1, 0],
|
|
251
|
-
extrapolate: 'clamp',
|
|
252
288
|
}}
|
|
253
|
-
animatedValue={
|
|
289
|
+
animatedValue={sharedValue}
|
|
254
290
|
/>
|
|
255
291
|
),
|
|
256
292
|
};
|
|
@@ -265,7 +301,7 @@ const Screen = forwardRef(
|
|
|
265
301
|
headerBackground: (props: any) => (
|
|
266
302
|
<HeaderBackground
|
|
267
303
|
{...props}
|
|
268
|
-
animatedValue={
|
|
304
|
+
animatedValue={sharedValue}
|
|
269
305
|
useShadowHeader={useShadowHeader}
|
|
270
306
|
headerBackground={headerBackground}
|
|
271
307
|
gradientColor={gradientColor}
|
|
@@ -284,9 +320,8 @@ const Screen = forwardRef(
|
|
|
284
320
|
interpolate={{
|
|
285
321
|
inputRange: [0, 50],
|
|
286
322
|
outputRange: [1, 0],
|
|
287
|
-
extrapolate: 'clamp',
|
|
288
323
|
}}
|
|
289
|
-
animatedValue={
|
|
324
|
+
animatedValue={sharedValue}
|
|
290
325
|
/>
|
|
291
326
|
),
|
|
292
327
|
};
|
|
@@ -300,6 +335,7 @@ const Screen = forwardRef(
|
|
|
300
335
|
headerBackground,
|
|
301
336
|
inputSearchProps,
|
|
302
337
|
navigation?.instance,
|
|
338
|
+
sharedValue,
|
|
303
339
|
useShadowHeader,
|
|
304
340
|
],
|
|
305
341
|
);
|
|
@@ -321,7 +357,7 @@ const Screen = forwardRef(
|
|
|
321
357
|
headerBackground: (props: any) => (
|
|
322
358
|
<HeaderBackground
|
|
323
359
|
{...props}
|
|
324
|
-
animatedValue={
|
|
360
|
+
animatedValue={sharedValue}
|
|
325
361
|
useGradient={false}
|
|
326
362
|
useShadowHeader={useShadowHeader}
|
|
327
363
|
headerBackground={headerBackground}
|
|
@@ -342,7 +378,13 @@ const Screen = forwardRef(
|
|
|
342
378
|
|
|
343
379
|
navigation?.instance?.setOptions(options);
|
|
344
380
|
},
|
|
345
|
-
[
|
|
381
|
+
[
|
|
382
|
+
gradientColor,
|
|
383
|
+
headerBackground,
|
|
384
|
+
navigation?.instance,
|
|
385
|
+
sharedValue,
|
|
386
|
+
useShadowHeader,
|
|
387
|
+
],
|
|
346
388
|
);
|
|
347
389
|
|
|
348
390
|
/**
|
|
@@ -359,15 +401,14 @@ const Screen = forwardRef(
|
|
|
359
401
|
interpolate={{
|
|
360
402
|
inputRange: [0, 50],
|
|
361
403
|
outputRange: [1, 0],
|
|
362
|
-
extrapolate: 'clamp',
|
|
363
404
|
}}
|
|
364
|
-
animatedValue={
|
|
405
|
+
animatedValue={sharedValue}
|
|
365
406
|
/>
|
|
366
407
|
),
|
|
367
408
|
};
|
|
368
409
|
|
|
369
410
|
navigation?.instance?.setOptions(options);
|
|
370
|
-
}, [navigation?.instance]);
|
|
411
|
+
}, [navigation?.instance, sharedValue]);
|
|
371
412
|
|
|
372
413
|
/**
|
|
373
414
|
* export search header
|
|
@@ -390,7 +431,7 @@ const Screen = forwardRef(
|
|
|
390
431
|
headerLeft: (props: any) =>
|
|
391
432
|
params?.hiddenBack ? null : <HeaderLeft {...props} />,
|
|
392
433
|
headerTitle: () => (
|
|
393
|
-
<SearchHeader {...params} animatedValue={
|
|
434
|
+
<SearchHeader {...params} animatedValue={sharedValue} />
|
|
394
435
|
),
|
|
395
436
|
};
|
|
396
437
|
|
|
@@ -457,9 +498,11 @@ const Screen = forwardRef(
|
|
|
457
498
|
{
|
|
458
499
|
useNativeDriver: true,
|
|
459
500
|
listener: (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
501
|
+
const offsetY = e.nativeEvent.contentOffset.y;
|
|
502
|
+
// keep the reanimated source in sync for the internal components.
|
|
503
|
+
sharedValue.value = offsetY;
|
|
460
504
|
scrollViewProps?.onScroll?.(e);
|
|
461
505
|
if (animatedHeader) {
|
|
462
|
-
const offsetY = e.nativeEvent.contentOffset.y;
|
|
463
506
|
let color = animatedHeader?.headerTintColor ?? Colors.black_17;
|
|
464
507
|
if (offsetY > 50) {
|
|
465
508
|
color = Colors.black_17;
|
|
@@ -494,6 +537,7 @@ const Screen = forwardRef(
|
|
|
494
537
|
useNativeDriver: true,
|
|
495
538
|
duration: 300,
|
|
496
539
|
}).start();
|
|
540
|
+
sharedValue.value = withTiming(0, { duration: 300 });
|
|
497
541
|
ref?.scrollTo?.({ y: 0, animated: true });
|
|
498
542
|
}
|
|
499
543
|
scrollViewProps?.onScrollEndDrag?.(e);
|
|
@@ -509,7 +553,10 @@ const Screen = forwardRef(
|
|
|
509
553
|
style={[styles.screenBanner, { maxHeight: 210 + layoutOffset }]}
|
|
510
554
|
>
|
|
511
555
|
{animatedHeader?.component({
|
|
556
|
+
// legacy consumers read `animatedValue` (Animated.Value),
|
|
557
|
+
// modern consumers read `sharedValue` (SharedValue).
|
|
512
558
|
animatedValue: animatedValue.current,
|
|
559
|
+
sharedValue: sharedValue,
|
|
513
560
|
})}
|
|
514
561
|
</View>
|
|
515
562
|
);
|
|
@@ -576,7 +623,7 @@ const Screen = forwardRef(
|
|
|
576
623
|
headerType={headerType}
|
|
577
624
|
heightHeader={heightHeader}
|
|
578
625
|
headerRightWidth={headerRightWidth}
|
|
579
|
-
animatedValue={
|
|
626
|
+
animatedValue={sharedValue}
|
|
580
627
|
inputSearchProps={inputSearchProps}
|
|
581
628
|
navigation={navigation}
|
|
582
629
|
inputSearchRef={inputSearchRef}
|
|
@@ -603,7 +650,14 @@ const Screen = forwardRef(
|
|
|
603
650
|
onScroll={handleScroll}
|
|
604
651
|
onScrollEndDrag={handleScrollEnd}
|
|
605
652
|
scrollEventThrottle={16}
|
|
606
|
-
style={
|
|
653
|
+
style={[
|
|
654
|
+
Styles.flex,
|
|
655
|
+
!scrollable && !Footer && !isTab && { paddingBottom: bottomInset },
|
|
656
|
+
]}
|
|
657
|
+
contentContainerStyle={[
|
|
658
|
+
scrollable && !Footer && !isTab && { paddingBottom: bottomInset },
|
|
659
|
+
scrollViewProps?.contentContainerStyle,
|
|
660
|
+
]}
|
|
607
661
|
>
|
|
608
662
|
{renderAnimatedHeader()}
|
|
609
663
|
|
|
@@ -614,9 +668,9 @@ const Screen = forwardRef(
|
|
|
614
668
|
<View>
|
|
615
669
|
<FloatingButton
|
|
616
670
|
{...floatingButtonProps}
|
|
617
|
-
animatedValue={
|
|
671
|
+
animatedValue={sharedValue}
|
|
618
672
|
bottom={
|
|
619
|
-
Footer || isTab ? 12 :
|
|
673
|
+
Footer || isTab ? 12 : bottomInset + Spacing.S
|
|
620
674
|
}
|
|
621
675
|
/>
|
|
622
676
|
</View>
|
|
@@ -627,7 +681,7 @@ const Screen = forwardRef(
|
|
|
627
681
|
style={[
|
|
628
682
|
styles.shadow,
|
|
629
683
|
{
|
|
630
|
-
paddingBottom:
|
|
684
|
+
paddingBottom: bottomInset + Spacing.S,
|
|
631
685
|
backgroundColor: theme.colors.background.surface,
|
|
632
686
|
},
|
|
633
687
|
]}
|
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;
|
|
@@ -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
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>
|
package/Skeleton/index.tsx
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
import React, { useContext, useEffect,
|
|
1
|
+
import React, { useContext, useEffect, useState } from 'react';
|
|
2
2
|
import {
|
|
3
|
-
Animated,
|
|
4
|
-
Easing,
|
|
5
3
|
LayoutAnimation,
|
|
6
4
|
Platform,
|
|
7
5
|
StyleSheet,
|
|
8
6
|
UIManager,
|
|
9
7
|
View,
|
|
10
8
|
} from 'react-native';
|
|
9
|
+
import Animated, {
|
|
10
|
+
cancelAnimation,
|
|
11
|
+
Easing,
|
|
12
|
+
interpolate,
|
|
13
|
+
useAnimatedStyle,
|
|
14
|
+
useSharedValue,
|
|
15
|
+
withRepeat,
|
|
16
|
+
withTiming,
|
|
17
|
+
} from 'react-native-reanimated';
|
|
11
18
|
import LinearGradient from 'react-native-linear-gradient';
|
|
12
19
|
import { SkeletonTypes } from './types';
|
|
13
20
|
import { Colors, Styles } from '../Consts';
|
|
@@ -20,32 +27,31 @@ const Skeleton: React.FC<SkeletonTypes> = ({ style }) => {
|
|
|
20
27
|
const PRIMARY_COLOR = Colors.black_05;
|
|
21
28
|
const HIGHLIGHT_COLOR1 = Colors.black_05;
|
|
22
29
|
const HIGHLIGHT_COLOR2 = Colors.black_03;
|
|
23
|
-
const
|
|
30
|
+
const progress = useSharedValue(0);
|
|
24
31
|
|
|
25
32
|
const shimmerColors = [HIGHLIGHT_COLOR1, HIGHLIGHT_COLOR2, HIGHLIGHT_COLOR1];
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return Animated.loop(
|
|
32
|
-
Animated.timing(beginShimmerPosition, {
|
|
33
|
-
toValue: 1,
|
|
33
|
+
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
progress.value = 0;
|
|
36
|
+
progress.value = withRepeat(
|
|
37
|
+
withTiming(1, {
|
|
34
38
|
duration: 1000,
|
|
35
39
|
easing: Easing.linear,
|
|
36
|
-
useNativeDriver: Platform.OS !== 'web',
|
|
37
40
|
}),
|
|
41
|
+
-1,
|
|
42
|
+
false,
|
|
38
43
|
);
|
|
39
|
-
}, [beginShimmerPosition]);
|
|
40
|
-
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
animatedValue.start();
|
|
43
44
|
screen?.onLoading?.(true);
|
|
44
45
|
return () => {
|
|
45
|
-
|
|
46
|
+
cancelAnimation(progress);
|
|
46
47
|
screen?.onLoading?.(false);
|
|
47
48
|
};
|
|
48
|
-
}, [
|
|
49
|
+
}, [progress, screen]);
|
|
50
|
+
|
|
51
|
+
const shimmerStyle = useAnimatedStyle(() => {
|
|
52
|
+
const translateX = interpolate(progress.value, [0, 1], [-width, width]);
|
|
53
|
+
return { transform: [{ translateX }] };
|
|
54
|
+
});
|
|
49
55
|
|
|
50
56
|
const onLayout = (newWidth: number) => {
|
|
51
57
|
if (newWidth !== width) {
|
|
@@ -60,11 +66,13 @@ const Skeleton: React.FC<SkeletonTypes> = ({ style }) => {
|
|
|
60
66
|
style={[Styles.flex, { backgroundColor: PRIMARY_COLOR }]}
|
|
61
67
|
>
|
|
62
68
|
<Animated.View
|
|
63
|
-
style={
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
style={[
|
|
70
|
+
{
|
|
71
|
+
width: '60%',
|
|
72
|
+
height: '100%',
|
|
73
|
+
},
|
|
74
|
+
shimmerStyle,
|
|
75
|
+
]}
|
|
68
76
|
>
|
|
69
77
|
<LinearGradient
|
|
70
78
|
style={[StyleSheet.absoluteFill]}
|
package/Text/utils.ts
CHANGED
|
@@ -7,18 +7,13 @@ const DEFAULT_SCREEN_SIZE = 375;
|
|
|
7
7
|
const MAX_FONT_SCALE = 1.5;
|
|
8
8
|
const MAX_DEVICE_SCALE = 5;
|
|
9
9
|
|
|
10
|
-
const useScaleSize = (size: number,
|
|
11
|
-
const {
|
|
12
|
-
useContext(ScaleSizeContext);
|
|
10
|
+
const useScaleSize = (size: number, scaleRate?: number) => {
|
|
11
|
+
const { scaleSizeMaxRate = MAX_FONT_SCALE } = useContext(ScaleSizeContext);
|
|
13
12
|
const fontScale = PixelRatio.getFontScale();
|
|
14
13
|
const { width } = useWindowDimensions();
|
|
15
14
|
const deviceScale = width / DEFAULT_SCREEN_SIZE;
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
const customRate = userScaleRate ?? ctxRate ?? 1;
|
|
19
|
-
// useOSFontScale on -> apply the OS scale, ignore the custom rate;
|
|
20
|
-
// off -> use the custom rate. Both hard-capped at MAX_FONT_SCALE (150%).
|
|
21
|
-
const appliedRate = useOSFontScale ? fontScale : customRate;
|
|
16
|
+
const maxScaleRate = scaleRate ?? scaleSizeMaxRate;
|
|
22
17
|
|
|
23
18
|
let fontSizeDeviceScale = size;
|
|
24
19
|
let fontSizeOSScale = size;
|
|
@@ -30,10 +25,10 @@ const useScaleSize = (size: number, userScaleRate?: number) => {
|
|
|
30
25
|
);
|
|
31
26
|
}
|
|
32
27
|
|
|
33
|
-
if (
|
|
28
|
+
if (fontScale > 1) {
|
|
34
29
|
fontSizeOSScale = Math.min(
|
|
35
|
-
|
|
36
|
-
fontSizeOSScale *
|
|
30
|
+
fontSizeOSScale * fontScale,
|
|
31
|
+
fontSizeOSScale * maxScaleRate,
|
|
37
32
|
);
|
|
38
33
|
}
|
|
39
34
|
|