@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.
Files changed (52) hide show
  1. package/Application/BottomSheet.tsx +3 -3
  2. package/Application/BottomTab/BottomTabBar.tsx +17 -17
  3. package/Application/BottomTab/CustomBottomTabItem.tsx +1 -1
  4. package/Application/BottomTab/index.tsx +31 -55
  5. package/Application/Components/BackgroundImageView.tsx +22 -6
  6. package/Application/Components/HeaderAnimated.tsx +32 -29
  7. package/Application/Components/HeaderBackground.tsx +21 -27
  8. package/Application/Components/HeaderExtendHeader.tsx +114 -94
  9. package/Application/Components/HeaderTitle.tsx +40 -11
  10. package/Application/Components/SearchHeader.tsx +17 -22
  11. package/Application/NavigationContainer.tsx +21 -25
  12. package/Application/ScaleSizeProvider.tsx +16 -0
  13. package/Application/WidgetContainer.tsx +7 -18
  14. package/Application/index.ts +2 -0
  15. package/Application/types.ts +10 -4
  16. package/Application/utils.tsx +4 -3
  17. package/Badge/Badge.tsx +3 -9
  18. package/Badge/BadgeDot.tsx +1 -1
  19. package/Badge/BadgeDotAnimation.tsx +53 -71
  20. package/Badge/BadgeRibbon.tsx +1 -1
  21. package/Button/index.tsx +3 -6
  22. package/CheckBox/index.tsx +1 -1
  23. package/Context/index.ts +4 -0
  24. package/Icon/index.tsx +1 -1
  25. package/IconButton/index.tsx +1 -1
  26. package/Image/index.tsx +13 -3
  27. package/Input/Input.tsx +1 -1
  28. package/Input/InputDropDown.tsx +1 -1
  29. package/Input/InputMoney.tsx +1 -1
  30. package/Input/InputOTP.tsx +39 -24
  31. package/Input/InputPhoneNumber.tsx +1 -1
  32. package/Input/InputSearch.tsx +1 -1
  33. package/Input/InputTextArea.tsx +10 -4
  34. package/Layout/FloatingButton.tsx +59 -59
  35. package/Layout/Item.tsx +1 -1
  36. package/Layout/Screen.tsx +61 -57
  37. package/Loader/ProgressBar.tsx +20 -18
  38. package/Pagination/Dot.tsx +2 -2
  39. package/Pagination/PaginationDot.tsx +1 -1
  40. package/Pagination/PaginationNumber.tsx +1 -1
  41. package/Pagination/PaginationScroll.tsx +32 -28
  42. package/Pagination/PaginationWhiteDot.tsx +1 -1
  43. package/Popup/PopupNotify.tsx +1 -1
  44. package/Popup/PopupPromotion.tsx +1 -1
  45. package/Radio/index.tsx +1 -1
  46. package/Skeleton/index.tsx +32 -24
  47. package/Switch/index.tsx +1 -1
  48. package/Tag/index.tsx +1 -1
  49. package/Text/index.tsx +1 -1
  50. package/Text/utils.ts +41 -18
  51. package/Title/index.tsx +1 -1
  52. 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?: Animated.Value;
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 = useRef(0);
46
+ const maxWidth = useSharedValue(0);
46
47
  const minWidth = size === 'small' ? 36 : 48;
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);
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
- 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;
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
- 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));
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
- 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));
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
- return () => {
96
- if (listener) {
97
- animatedValue?.removeListener(listener);
98
- }
99
- };
100
- }, [animatedValue, label, minWidth, opacityAnimated, widthAnimated]);
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.current = layout.width;
106
- setWidthAnimated(new Animated.Value(layout.width));
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?.designSystemConfig?.isBaselineEnabled;
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?: Animated.Value;
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 animatedValue = useRef<Animated.Value>(
199
- customAnimatedValue || new Animated.Value(0),
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.current}
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.current}
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.current}
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.current}
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.current}
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.current} />
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 = Animated.event(
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
- Animated.timing(animatedValue.current, {
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.current,
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.current}
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.current}
621
+ animatedValue={animatedValue}
618
622
  bottom={
619
623
  Footer || isTab ? 12 : Math.min(insets.bottom, 21) + Spacing.S
620
624
  }
@@ -1,5 +1,10 @@
1
- import React, { FC, useContext, useEffect, useRef } from 'react';
2
- import { Animated, View } from 'react-native';
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 = useRef(new Animated.Value(0)).current;
15
+ const animation = useSharedValue(0);
11
16
 
12
17
  useEffect(() => {
13
- Animated.timing(animation, {
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 width = animation.interpolate({
21
- inputRange: [0, 100],
22
- outputRange: ['0%', '100%'],
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
- height: 4,
36
- borderRadius: Radius.XXS,
37
- width,
38
- backgroundColor: theme.colors.primary,
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
  );
@@ -1,5 +1,5 @@
1
1
  import React, { FC, useContext } from 'react';
2
- import { Animated } from 'react-native';
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 <Animated.View style={[style, dotStyle]} />;
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?.designSystemConfig?.isBaselineEnabled;
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?.designSystemConfig?.isBaselineEnabled;
16
+ const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
17
17
 
18
18
  return (
19
19
  <View
@@ -1,5 +1,12 @@
1
- import React, { FC, useContext, useRef, useState } from 'react';
2
- import { Animated, View } from 'react-native';
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 = useRef(new Animated.Value(0)).current;
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?.designSystemConfig?.isBaselineEnabled;
27
+ const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
21
28
 
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 }] };
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
- return {};
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={Animated.event(
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
- translateX(),
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?.designSystemConfig?.isBaselineEnabled;
16
+ const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
17
17
 
18
18
  const renderDots = () => {
19
19
  const dots: React.ReactElement[] = [];
@@ -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?.designSystemConfig?.isBaselineEnabled;
35
+ const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
36
36
  const closeAction = useRef('touch_outside');
37
37
  let descriptionStyle = {};
38
38
  let Description: any = View;
@@ -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?.designSystemConfig?.isBaselineEnabled;
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?.designSystemConfig?.isBaselineEnabled;
36
+ const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
37
37
  let disabledStyle = {};
38
38
  let checkBoxStyle = {
39
39
  borderWidth: 2,