@momo-kits/foundation 0.162.2-test.1 → 0.162.2-test.20
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 +2 -2
- package/Application/BottomTab/BottomTabBar.tsx +15 -15
- package/Application/BottomTab/index.tsx +31 -55
- 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/HeaderTitle.tsx +43 -10
- package/Application/Components/SearchHeader.tsx +13 -21
- package/Application/NavigationContainer.tsx +21 -2
- package/Application/ScaleSizeProvider.tsx +5 -3
- package/Application/WidgetContainer.tsx +1 -1
- package/Application/types.ts +6 -4
- package/Application/utils.tsx +42 -2
- package/Badge/BadgeDotAnimation.tsx +53 -71
- package/Button/index.tsx +1 -4
- package/Context/index.ts +6 -3
- package/Input/Input.tsx +5 -1
- package/Input/InputOTP.tsx +38 -23
- package/Input/InputPhoneNumber.tsx +5 -1
- package/Layout/FloatingButton.tsx +64 -59
- package/Layout/Screen.tsx +62 -16
- 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 +10 -5
- 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,9 +200,40 @@ 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
|
|
|
@@ -249,9 +285,8 @@ const Screen = forwardRef(
|
|
|
249
285
|
interpolate={{
|
|
250
286
|
inputRange: [0, 50],
|
|
251
287
|
outputRange: [1, 0],
|
|
252
|
-
extrapolate: 'clamp',
|
|
253
288
|
}}
|
|
254
|
-
animatedValue={
|
|
289
|
+
animatedValue={sharedValue}
|
|
255
290
|
/>
|
|
256
291
|
),
|
|
257
292
|
};
|
|
@@ -266,7 +301,7 @@ const Screen = forwardRef(
|
|
|
266
301
|
headerBackground: (props: any) => (
|
|
267
302
|
<HeaderBackground
|
|
268
303
|
{...props}
|
|
269
|
-
animatedValue={
|
|
304
|
+
animatedValue={sharedValue}
|
|
270
305
|
useShadowHeader={useShadowHeader}
|
|
271
306
|
headerBackground={headerBackground}
|
|
272
307
|
gradientColor={gradientColor}
|
|
@@ -285,9 +320,8 @@ const Screen = forwardRef(
|
|
|
285
320
|
interpolate={{
|
|
286
321
|
inputRange: [0, 50],
|
|
287
322
|
outputRange: [1, 0],
|
|
288
|
-
extrapolate: 'clamp',
|
|
289
323
|
}}
|
|
290
|
-
animatedValue={
|
|
324
|
+
animatedValue={sharedValue}
|
|
291
325
|
/>
|
|
292
326
|
),
|
|
293
327
|
};
|
|
@@ -301,6 +335,7 @@ const Screen = forwardRef(
|
|
|
301
335
|
headerBackground,
|
|
302
336
|
inputSearchProps,
|
|
303
337
|
navigation?.instance,
|
|
338
|
+
sharedValue,
|
|
304
339
|
useShadowHeader,
|
|
305
340
|
],
|
|
306
341
|
);
|
|
@@ -322,7 +357,7 @@ const Screen = forwardRef(
|
|
|
322
357
|
headerBackground: (props: any) => (
|
|
323
358
|
<HeaderBackground
|
|
324
359
|
{...props}
|
|
325
|
-
animatedValue={
|
|
360
|
+
animatedValue={sharedValue}
|
|
326
361
|
useGradient={false}
|
|
327
362
|
useShadowHeader={useShadowHeader}
|
|
328
363
|
headerBackground={headerBackground}
|
|
@@ -343,7 +378,13 @@ const Screen = forwardRef(
|
|
|
343
378
|
|
|
344
379
|
navigation?.instance?.setOptions(options);
|
|
345
380
|
},
|
|
346
|
-
[
|
|
381
|
+
[
|
|
382
|
+
gradientColor,
|
|
383
|
+
headerBackground,
|
|
384
|
+
navigation?.instance,
|
|
385
|
+
sharedValue,
|
|
386
|
+
useShadowHeader,
|
|
387
|
+
],
|
|
347
388
|
);
|
|
348
389
|
|
|
349
390
|
/**
|
|
@@ -360,15 +401,14 @@ const Screen = forwardRef(
|
|
|
360
401
|
interpolate={{
|
|
361
402
|
inputRange: [0, 50],
|
|
362
403
|
outputRange: [1, 0],
|
|
363
|
-
extrapolate: 'clamp',
|
|
364
404
|
}}
|
|
365
|
-
animatedValue={
|
|
405
|
+
animatedValue={sharedValue}
|
|
366
406
|
/>
|
|
367
407
|
),
|
|
368
408
|
};
|
|
369
409
|
|
|
370
410
|
navigation?.instance?.setOptions(options);
|
|
371
|
-
}, [navigation?.instance]);
|
|
411
|
+
}, [navigation?.instance, sharedValue]);
|
|
372
412
|
|
|
373
413
|
/**
|
|
374
414
|
* export search header
|
|
@@ -391,7 +431,7 @@ const Screen = forwardRef(
|
|
|
391
431
|
headerLeft: (props: any) =>
|
|
392
432
|
params?.hiddenBack ? null : <HeaderLeft {...props} />,
|
|
393
433
|
headerTitle: () => (
|
|
394
|
-
<SearchHeader {...params} animatedValue={
|
|
434
|
+
<SearchHeader {...params} animatedValue={sharedValue} />
|
|
395
435
|
),
|
|
396
436
|
};
|
|
397
437
|
|
|
@@ -458,9 +498,11 @@ const Screen = forwardRef(
|
|
|
458
498
|
{
|
|
459
499
|
useNativeDriver: true,
|
|
460
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;
|
|
461
504
|
scrollViewProps?.onScroll?.(e);
|
|
462
505
|
if (animatedHeader) {
|
|
463
|
-
const offsetY = e.nativeEvent.contentOffset.y;
|
|
464
506
|
let color = animatedHeader?.headerTintColor ?? Colors.black_17;
|
|
465
507
|
if (offsetY > 50) {
|
|
466
508
|
color = Colors.black_17;
|
|
@@ -495,6 +537,7 @@ const Screen = forwardRef(
|
|
|
495
537
|
useNativeDriver: true,
|
|
496
538
|
duration: 300,
|
|
497
539
|
}).start();
|
|
540
|
+
sharedValue.value = withTiming(0, { duration: 300 });
|
|
498
541
|
ref?.scrollTo?.({ y: 0, animated: true });
|
|
499
542
|
}
|
|
500
543
|
scrollViewProps?.onScrollEndDrag?.(e);
|
|
@@ -510,7 +553,10 @@ const Screen = forwardRef(
|
|
|
510
553
|
style={[styles.screenBanner, { maxHeight: 210 + layoutOffset }]}
|
|
511
554
|
>
|
|
512
555
|
{animatedHeader?.component({
|
|
556
|
+
// legacy consumers read `animatedValue` (Animated.Value),
|
|
557
|
+
// modern consumers read `sharedValue` (SharedValue).
|
|
513
558
|
animatedValue: animatedValue.current,
|
|
559
|
+
sharedValue: sharedValue,
|
|
514
560
|
})}
|
|
515
561
|
</View>
|
|
516
562
|
);
|
|
@@ -577,7 +623,7 @@ const Screen = forwardRef(
|
|
|
577
623
|
headerType={headerType}
|
|
578
624
|
heightHeader={heightHeader}
|
|
579
625
|
headerRightWidth={headerRightWidth}
|
|
580
|
-
animatedValue={
|
|
626
|
+
animatedValue={sharedValue}
|
|
581
627
|
inputSearchProps={inputSearchProps}
|
|
582
628
|
navigation={navigation}
|
|
583
629
|
inputSearchRef={inputSearchRef}
|
|
@@ -615,7 +661,7 @@ const Screen = forwardRef(
|
|
|
615
661
|
<View>
|
|
616
662
|
<FloatingButton
|
|
617
663
|
{...floatingButtonProps}
|
|
618
|
-
animatedValue={
|
|
664
|
+
animatedValue={sharedValue}
|
|
619
665
|
bottom={
|
|
620
666
|
Footer || isTab ? 12 : bottomInset + Spacing.S
|
|
621
667
|
}
|
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,13 +7,18 @@ 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 {
|
|
10
|
+
const useScaleSize = (size: number, userScaleRate?: number) => {
|
|
11
|
+
const { useOSFontScale = true, userScaleRate: ctxRate } =
|
|
12
|
+
useContext(ScaleSizeContext);
|
|
12
13
|
const fontScale = PixelRatio.getFontScale();
|
|
13
14
|
const { width } = useWindowDimensions();
|
|
14
15
|
const deviceScale = width / DEFAULT_SCREEN_SIZE;
|
|
15
16
|
|
|
16
|
-
const
|
|
17
|
+
const customRate = userScaleRate ?? ctxRate ?? 1;
|
|
18
|
+
|
|
19
|
+
if (!useOSFontScale) {
|
|
20
|
+
return customRate > 1 ? customRate * size : size;
|
|
21
|
+
}
|
|
17
22
|
|
|
18
23
|
let fontSizeDeviceScale = size;
|
|
19
24
|
let fontSizeOSScale = size;
|
|
@@ -27,8 +32,8 @@ const useScaleSize = (size: number, scaleRate?: number) => {
|
|
|
27
32
|
|
|
28
33
|
if (fontScale > 1) {
|
|
29
34
|
fontSizeOSScale = Math.min(
|
|
30
|
-
|
|
31
|
-
fontSizeOSScale *
|
|
35
|
+
fontScale * fontSizeOSScale,
|
|
36
|
+
fontSizeOSScale * MAX_FONT_SCALE,
|
|
32
37
|
);
|
|
33
38
|
}
|
|
34
39
|
|