@hoddy-ui/core 1.1.3 → 2.0.0

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.
@@ -1,5 +1,12 @@
1
- import { useEffect, useRef } from "react";
2
- import { Animated, Easing, Platform } from "react-native";
1
+ import { useEffect } from "react";
2
+ import { Platform } from "react-native";
3
+ import {
4
+ Easing,
5
+ useAnimatedStyle,
6
+ useSharedValue,
7
+ withDelay,
8
+ withTiming,
9
+ } from "react-native-reanimated";
3
10
  import useAppState from "./useAppState";
4
11
 
5
12
  interface UseGrowAnimationProps {
@@ -12,43 +19,48 @@ interface UseGrowAnimationProps {
12
19
  export const useGrowAnimation = ({
13
20
  duration = 500,
14
21
  delay = 0,
15
- closeAfter = 2000,
22
+ closeAfter = null,
16
23
  initialScale = 0,
17
24
  }: UseGrowAnimationProps = {}) => {
18
- const scale = useRef(new Animated.Value(initialScale)).current;
25
+ const scale = useSharedValue(initialScale);
19
26
  const { isActive } = useAppState();
20
27
 
28
+ const animatedStyle = useAnimatedStyle(() => {
29
+ return {
30
+ transform: [{ scale: scale.value }],
31
+ };
32
+ });
33
+
21
34
  useEffect(() => {
22
35
  if (!isActive && Platform.OS === "ios") {
23
- scale.stopAnimation();
36
+ scale.value = initialScale;
37
+ return;
24
38
  }
25
- }, [isActive]);
26
39
 
27
- useEffect(() => {
28
40
  // Start grow-in animation with easing
29
- Animated.timing(scale, {
30
- toValue: 1,
31
- duration,
41
+ scale.value = withDelay(
32
42
  delay,
33
- easing: Easing.out(Easing.ease),
34
- useNativeDriver: true,
35
- }).start(() => {
36
- if (closeAfter) {
37
- setTimeout(() => {
38
- Animated.timing(scale, {
39
- toValue: initialScale,
40
- duration,
41
- easing: Easing.out(Easing.ease),
42
- useNativeDriver: true,
43
- }).start();
44
- }, closeAfter);
45
- }
46
- });
47
-
48
- return () => scale.stopAnimation();
49
- }, [scale, duration, delay, closeAfter, initialScale]);
43
+ withTiming(
44
+ 1,
45
+ {
46
+ duration,
47
+ easing: Easing.out(Easing.ease),
48
+ },
49
+ () => {
50
+ if (closeAfter) {
51
+ setTimeout(() => {
52
+ scale.value = withTiming(initialScale, {
53
+ duration,
54
+ easing: Easing.out(Easing.ease),
55
+ });
56
+ }, closeAfter);
57
+ }
58
+ }
59
+ )
60
+ );
61
+ }, [scale, duration, delay, closeAfter, initialScale, isActive]);
50
62
 
51
63
  return {
52
- animatedStyle: { transform: [{ scale }] },
64
+ animatedStyle,
53
65
  };
54
66
  };
@@ -1,5 +1,13 @@
1
- import { useEffect, useRef } from "react";
2
- import { Animated, Easing, Platform } from "react-native";
1
+ import { useEffect } from "react";
2
+ import { Platform } from "react-native";
3
+ import {
4
+ Easing,
5
+ interpolate,
6
+ useAnimatedStyle,
7
+ useSharedValue,
8
+ withDelay,
9
+ withTiming,
10
+ } from "react-native-reanimated";
3
11
  import useAppState from "./useAppState";
4
12
 
5
13
  interface UseRollAnimationProps {
@@ -13,74 +21,82 @@ interface UseRollAnimationProps {
13
21
  export const useRollAnimation = ({
14
22
  duration = 500,
15
23
  delay = 0,
16
- closeAfter = 2000,
24
+ closeAfter = null,
17
25
  initialTranslateY = 100,
18
26
  initialRotate = "0deg",
19
27
  }: UseRollAnimationProps = {}) => {
20
- const translateY = useRef(new Animated.Value(initialTranslateY)).current;
21
- const rotate = useRef(new Animated.Value(0.5)).current;
28
+ const translateY = useSharedValue(initialTranslateY);
29
+ const rotate = useSharedValue(0);
22
30
  const { isActive } = useAppState();
23
31
 
32
+ const animatedStyle = useAnimatedStyle(() => {
33
+ // Interpolate rotation from 0-1 to initial rotation to 360deg
34
+ const rotateInterpolated = interpolate(
35
+ rotate.value,
36
+ [0, 1],
37
+ [parseFloat(initialRotate.replace("deg", "")), 360]
38
+ );
39
+
40
+ return {
41
+ transform: [
42
+ { translateY: translateY.value },
43
+ { rotate: `${rotateInterpolated}deg` },
44
+ ],
45
+ };
46
+ });
47
+
24
48
  useEffect(() => {
25
49
  if (!isActive && Platform.OS === "ios") {
26
- rotate.stopAnimation();
27
- translateY.stopAnimation();
50
+ translateY.value = initialTranslateY;
51
+ rotate.value = 0;
52
+ return;
28
53
  }
29
- }, [isActive]);
30
54
 
31
- useEffect(() => {
32
- // Start roll-in animation with easing
33
- Animated.parallel([
34
- Animated.timing(translateY, {
35
- toValue: 0.5,
55
+ // Start roll-in animation with easing (parallel animations)
56
+ translateY.value = withDelay(
57
+ delay,
58
+ withTiming(0, {
36
59
  duration,
37
- delay,
38
60
  easing: Easing.out(Easing.ease),
39
- useNativeDriver: true,
40
- }),
41
- Animated.timing(rotate, {
42
- toValue: 1,
43
- duration,
44
- delay,
45
- easing: Easing.out(Easing.ease),
46
- useNativeDriver: true,
47
- }),
48
- ]).start(() => {
49
- if (closeAfter) {
50
- setTimeout(() => {
51
- Animated.parallel([
52
- Animated.timing(translateY, {
53
- toValue: initialTranslateY,
54
- duration,
55
- easing: Easing.out(Easing.ease),
56
- useNativeDriver: true,
57
- }),
58
- Animated.timing(rotate, {
59
- toValue: 0,
60
- duration,
61
- easing: Easing.out(Easing.ease),
62
- useNativeDriver: true,
63
- }),
64
- ]).start();
65
- }, closeAfter);
66
- }
67
- });
61
+ })
62
+ );
68
63
 
69
- return () => {
70
- translateY.stopAnimation();
71
- rotate.stopAnimation();
72
- };
73
- }, [translateY, rotate, duration, delay, closeAfter, initialTranslateY]);
74
-
75
- // Interpolate the rotation value to degrees
76
- const rotateInterpolation = rotate.interpolate({
77
- inputRange: [0, 1],
78
- outputRange: [initialRotate, "360deg"],
79
- });
64
+ rotate.value = withDelay(
65
+ delay,
66
+ withTiming(
67
+ 1,
68
+ {
69
+ duration,
70
+ easing: Easing.out(Easing.ease),
71
+ },
72
+ () => {
73
+ if (closeAfter) {
74
+ setTimeout(() => {
75
+ translateY.value = withTiming(initialTranslateY, {
76
+ duration,
77
+ easing: Easing.out(Easing.ease),
78
+ });
79
+ rotate.value = withTiming(0, {
80
+ duration,
81
+ easing: Easing.out(Easing.ease),
82
+ });
83
+ }, closeAfter);
84
+ }
85
+ }
86
+ )
87
+ );
88
+ }, [
89
+ translateY,
90
+ rotate,
91
+ duration,
92
+ delay,
93
+ closeAfter,
94
+ initialTranslateY,
95
+ initialRotate,
96
+ isActive,
97
+ ]);
80
98
 
81
99
  return {
82
- animatedStyle: {
83
- transform: [{ translateY }, { rotate: rotateInterpolation }],
84
- },
100
+ animatedStyle,
85
101
  };
86
102
  };
@@ -1,5 +1,12 @@
1
- import { useEffect, useRef } from "react";
2
- import { Animated, Dimensions, Easing, Platform } from "react-native";
1
+ import { useEffect } from "react";
2
+ import { Dimensions, Platform } from "react-native";
3
+ import {
4
+ Easing,
5
+ useAnimatedStyle,
6
+ useSharedValue,
7
+ withDelay,
8
+ withTiming,
9
+ } from "react-native-reanimated";
3
10
  import useAppState from "./useAppState";
4
11
 
5
12
  const { width, height } = Dimensions.get("window");
@@ -34,55 +41,60 @@ export const useSlideAnimation = ({
34
41
  closeAfter,
35
42
  initialValue,
36
43
  }: UseSlideAnimationProps = {}) => {
37
- const translateValue = useRef(new Animated.Value(0)).current;
44
+ const translateValue = useSharedValue(0);
38
45
  const { isActive } = useAppState();
39
46
 
47
+ const animatedStyle = useAnimatedStyle(() => {
48
+ const slideStyle =
49
+ direction === "up" || direction === "down"
50
+ ? { transform: [{ translateY: translateValue.value }] }
51
+ : { transform: [{ translateX: translateValue.value }] };
52
+
53
+ return slideStyle;
54
+ });
55
+
40
56
  useEffect(() => {
41
57
  if (!isActive && Platform.OS === "ios") {
42
- translateValue.stopAnimation();
58
+ const initialPosition = initialValue || getInitialPosition(direction);
59
+ translateValue.value = initialPosition;
60
+ return;
43
61
  }
44
- }, [isActive]);
45
62
 
46
- useEffect(() => {
47
63
  const initialPosition = initialValue || getInitialPosition(direction);
48
- translateValue.setValue(initialPosition);
64
+ translateValue.value = initialPosition;
49
65
 
50
66
  // Slide-in animation with ease-out effect
51
- Animated.timing(translateValue, {
52
- toValue: 0,
53
- duration,
67
+ translateValue.value = withDelay(
54
68
  delay,
55
- easing: Easing.out(Easing.ease),
56
- useNativeDriver: true,
57
- }).start();
69
+ withTiming(0, {
70
+ duration,
71
+ easing: Easing.out(Easing.ease),
72
+ })
73
+ );
58
74
 
59
75
  if (closeAfter) {
60
76
  const timer = setTimeout(() => {
61
- Animated.timing(translateValue, {
62
- toValue: initialPosition,
77
+ translateValue.value = withTiming(initialPosition, {
63
78
  duration,
64
79
  easing: Easing.out(Easing.ease),
65
- useNativeDriver: true,
66
- }).start();
80
+ });
67
81
  }, closeAfter + duration + delay);
68
82
 
69
83
  return () => {
70
- translateValue.stopAnimation();
71
84
  clearTimeout(timer);
72
85
  };
73
86
  }
74
-
75
- return () => {
76
- translateValue.stopAnimation();
77
- };
78
- }, [translateValue, duration, delay, direction, closeAfter]);
79
-
80
- const slideStyle =
81
- direction === "up" || direction === "down"
82
- ? { transform: [{ translateY: translateValue }] }
83
- : { transform: [{ translateX: translateValue }] };
87
+ }, [
88
+ translateValue,
89
+ duration,
90
+ delay,
91
+ direction,
92
+ closeAfter,
93
+ initialValue,
94
+ isActive,
95
+ ]);
84
96
 
85
97
  return {
86
- animatedStyle: slideStyle,
98
+ animatedStyle,
87
99
  };
88
100
  };
@@ -1,5 +1,12 @@
1
1
  import { useEffect, useRef } from "react";
2
- import { Animated, Platform } from "react-native";
2
+ import { Platform } from "react-native";
3
+ import {
4
+ useAnimatedStyle,
5
+ useSharedValue,
6
+ withDelay,
7
+ withSpring,
8
+ withTiming,
9
+ } from "react-native-reanimated";
3
10
  import useAppState from "./useAppState";
4
11
 
5
12
  interface UseThrownUpAnimationProps {
@@ -9,74 +16,63 @@ interface UseThrownUpAnimationProps {
9
16
 
10
17
  export const useThrownUpAnimation = ({
11
18
  delay = 0,
12
- closeAfter = 3000,
19
+ closeAfter = null,
13
20
  }: UseThrownUpAnimationProps = {}) => {
14
- const translateY = useRef(new Animated.Value(600)).current;
15
- const opacity = useRef(new Animated.Value(0)).current;
21
+ const translateY = useSharedValue(600);
22
+ const opacity = useSharedValue(0);
16
23
  const isUnmounting = useRef(false);
17
24
  const { isActive } = useAppState();
18
25
 
26
+ const animatedStyle = useAnimatedStyle(() => {
27
+ return {
28
+ transform: [{ translateY: translateY.value }],
29
+ opacity: opacity.value,
30
+ };
31
+ });
32
+
19
33
  useEffect(() => {
20
34
  if (!isActive && Platform.OS === "ios") {
21
- translateY.stopAnimation();
22
- opacity.stopAnimation();
35
+ translateY.value = 600;
36
+ opacity.value = 0;
37
+ return;
23
38
  }
24
- }, [isActive]);
25
39
 
26
- useEffect(() => {
27
40
  // Animate up and fade in when component mounts
28
- Animated.parallel([
29
- Animated.spring(translateY, {
30
- toValue: 0,
41
+ translateY.value = withDelay(
42
+ delay,
43
+ withSpring(0, {
31
44
  velocity: 1,
32
- tension: 0.001,
33
- friction: 2,
34
- useNativeDriver: true,
35
- delay,
36
- }),
37
- Animated.timing(opacity, {
38
- toValue: 1,
39
- duration: 500,
40
- useNativeDriver: true,
41
- delay,
42
- }),
43
- ]).start();
45
+ stiffness: 100,
46
+ damping: 15,
47
+ })
48
+ );
49
+
50
+ opacity.value = withDelay(delay, withTiming(1, { duration: 500 }));
44
51
 
45
52
  // Start timer to animate out after duration
46
53
  let timer: NodeJS.Timeout | null = null;
47
54
  if (closeAfter) {
48
55
  timer = setTimeout(() => {
49
56
  if (!isUnmounting.current) {
50
- Animated.parallel([
51
- Animated.spring(translateY, {
52
- toValue: 800,
53
- velocity: 1,
54
- tension: 10,
55
- friction: 7,
56
- useNativeDriver: true,
57
- }),
58
- Animated.timing(opacity, {
59
- toValue: 0,
60
- duration: 500,
61
- useNativeDriver: true,
62
- }),
63
- ]).start();
57
+ translateY.value = withSpring(800, {
58
+ velocity: 1,
59
+ stiffness: 200,
60
+ damping: 20,
61
+ });
62
+ opacity.value = withTiming(0, { duration: 500 });
64
63
  }
65
64
  }, closeAfter);
66
65
  }
67
66
 
68
67
  return () => {
69
68
  if (timer) clearTimeout(timer);
70
- translateY.stopAnimation();
71
- opacity.stopAnimation();
69
+ translateY.value = 600;
70
+ opacity.value = 0;
72
71
  isUnmounting.current = true;
73
72
  };
74
- }, [translateY, opacity, delay, closeAfter]);
73
+ }, [translateY, opacity, delay, closeAfter, isActive]);
75
74
 
76
75
  return {
77
- animatedStyle: {
78
- transform: [{ translateY }],
79
- opacity,
80
- },
76
+ animatedStyle,
81
77
  };
82
78
  };
@@ -25,14 +25,10 @@ export const OTPInput: FC<OTPInputProps> = ({
25
25
  [length]
26
26
  );
27
27
 
28
- console.log("v", value);
29
-
30
28
  const onChangeHandler = (val: string, index: number) => {
31
29
  if (value.length >= length && val.length > 0) return;
32
30
  // Handle pasting of full OTP
33
31
  if (val.length > 1) {
34
- console.log("reached", val);
35
-
36
32
  const digits = val.replace(/\D/g, "").slice(0, length);
37
33
  onChange(digits);
38
34
  if (digits.length === length) {