@hoddy-ui/core 1.1.4 → 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.
- package/README.md +95 -16
- package/next/package.json +3 -3
- package/package.json +6 -4
- package/src/Components/Animators/Animator.tsx +1 -1
- package/src/Components/Animators/hooks/useAppState.ts +4 -11
- package/src/Components/Animators/hooks/useBlinkAnimation.ts +31 -24
- package/src/Components/Animators/hooks/useFadeAnimation.ts +30 -26
- package/src/Components/Animators/hooks/useFloatAnimation.ts +67 -57
- package/src/Components/Animators/hooks/useGrowAnimation.ts +40 -28
- package/src/Components/Animators/hooks/useRollAnimation.ts +73 -57
- package/src/Components/Animators/hooks/useSlideAnimation.ts +41 -29
- package/src/Components/Animators/hooks/useThrownUpAnimation.ts +40 -44
- package/src/Components/OTPInput.tsx +0 -4
- package/src/Components/Popup.tsx +93 -76
- package/src/types.ts +3 -0
- package/src/Components/Animators/README.md +0 -137
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import { useEffect
|
|
2
|
-
import {
|
|
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 =
|
|
22
|
+
closeAfter = null,
|
|
16
23
|
initialScale = 0,
|
|
17
24
|
}: UseGrowAnimationProps = {}) => {
|
|
18
|
-
const scale =
|
|
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.
|
|
36
|
+
scale.value = initialScale;
|
|
37
|
+
return;
|
|
24
38
|
}
|
|
25
|
-
}, [isActive]);
|
|
26
39
|
|
|
27
|
-
useEffect(() => {
|
|
28
40
|
// Start grow-in animation with easing
|
|
29
|
-
|
|
30
|
-
toValue: 1,
|
|
31
|
-
duration,
|
|
41
|
+
scale.value = withDelay(
|
|
32
42
|
delay,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
|
64
|
+
animatedStyle,
|
|
53
65
|
};
|
|
54
66
|
};
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
import { useEffect
|
|
2
|
-
import {
|
|
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 =
|
|
24
|
+
closeAfter = null,
|
|
17
25
|
initialTranslateY = 100,
|
|
18
26
|
initialRotate = "0deg",
|
|
19
27
|
}: UseRollAnimationProps = {}) => {
|
|
20
|
-
const translateY =
|
|
21
|
-
const rotate =
|
|
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
|
-
|
|
27
|
-
|
|
50
|
+
translateY.value = initialTranslateY;
|
|
51
|
+
rotate.value = 0;
|
|
52
|
+
return;
|
|
28
53
|
}
|
|
29
|
-
}, [isActive]);
|
|
30
54
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
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
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
|
2
|
-
import {
|
|
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 =
|
|
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
|
-
|
|
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.
|
|
64
|
+
translateValue.value = initialPosition;
|
|
49
65
|
|
|
50
66
|
// Slide-in animation with ease-out effect
|
|
51
|
-
|
|
52
|
-
toValue: 0,
|
|
53
|
-
duration,
|
|
67
|
+
translateValue.value = withDelay(
|
|
54
68
|
delay,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
62
|
-
toValue: initialPosition,
|
|
77
|
+
translateValue.value = withTiming(initialPosition, {
|
|
63
78
|
duration,
|
|
64
79
|
easing: Easing.out(Easing.ease),
|
|
65
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
|
98
|
+
animatedStyle,
|
|
87
99
|
};
|
|
88
100
|
};
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { useEffect, useRef } from "react";
|
|
2
|
-
import {
|
|
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 =
|
|
19
|
+
closeAfter = null,
|
|
13
20
|
}: UseThrownUpAnimationProps = {}) => {
|
|
14
|
-
const translateY =
|
|
15
|
-
const opacity =
|
|
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.
|
|
22
|
-
opacity.
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
41
|
+
translateY.value = withDelay(
|
|
42
|
+
delay,
|
|
43
|
+
withSpring(0, {
|
|
31
44
|
velocity: 1,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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.
|
|
71
|
-
opacity.
|
|
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) {
|