@codeimplants/ui-kit 1.0.0 → 1.0.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.
@@ -1,16 +1,8 @@
1
- import React, { useEffect } from 'react';
2
- import Animated, {
3
- useSharedValue,
4
- useAnimatedProps,
5
- withRepeat,
6
- withSequence,
7
- withTiming,
8
- Easing,
9
- } from 'react-native-reanimated';
10
- import Svg, { Path, Circle, G } from 'react-native-svg';
1
+ import React, { useEffect, useRef } from 'react';
2
+ import { Animated, Easing } from 'react-native';
3
+ import Svg, { Path, Circle } from 'react-native-svg';
11
4
 
12
5
  const AnimatedPath = Animated.createAnimatedComponent(Path);
13
- const AnimatedCircle = Animated.createAnimatedComponent(Circle);
14
6
 
15
7
  interface AnimatedCrashProps {
16
8
  size?: number;
@@ -25,88 +17,80 @@ export const AnimatedCrash: React.FC<AnimatedCrashProps> = ({
25
17
  size = 64,
26
18
  color = '#EF4444',
27
19
  }) => {
28
- const scatter1 = useSharedValue(0);
29
- const scatter2 = useSharedValue(0);
30
- const scatter3 = useSharedValue(0);
31
- const opacity = useSharedValue(1);
20
+ const scatter1 = useRef(new Animated.Value(0)).current;
21
+ const scatter2 = useRef(new Animated.Value(0)).current;
22
+ const scatter3 = useRef(new Animated.Value(0)).current;
32
23
 
33
24
  useEffect(() => {
34
- scatter1.value = withRepeat(
35
- withSequence(
36
- withTiming(1, { duration: 1200, easing: Easing.out(Easing.cubic) }),
37
- withTiming(0, { duration: 800, easing: Easing.in(Easing.cubic) })
38
- ),
39
- -1,
40
- false
41
- );
25
+ const createAnimation = (value: Animated.Value, durationOut: number, durationIn: number) => {
26
+ return Animated.loop(
27
+ Animated.sequence([
28
+ Animated.timing(value, {
29
+ toValue: 1,
30
+ duration: durationOut,
31
+ easing: Easing.out(Easing.cubic),
32
+ useNativeDriver: true,
33
+ }),
34
+ Animated.timing(value, {
35
+ toValue: 0,
36
+ duration: durationIn,
37
+ easing: Easing.in(Easing.cubic),
38
+ useNativeDriver: true,
39
+ }),
40
+ ])
41
+ );
42
+ };
42
43
 
43
- scatter2.value = withRepeat(
44
- withSequence(
45
- withTiming(1, { duration: 1300, easing: Easing.out(Easing.cubic) }),
46
- withTiming(0, { duration: 700, easing: Easing.in(Easing.cubic) })
47
- ),
48
- -1,
49
- false
50
- );
44
+ createAnimation(scatter1, 1200, 800).start();
45
+ createAnimation(scatter2, 1300, 700).start();
46
+ createAnimation(scatter3, 1100, 900).start();
47
+ }, [scatter1, scatter2, scatter3]);
51
48
 
52
- scatter3.value = withRepeat(
53
- withSequence(
54
- withTiming(1, { duration: 1100, easing: Easing.out(Easing.cubic) }),
55
- withTiming(0, { duration: 900, easing: Easing.in(Easing.cubic) })
56
- ),
57
- -1,
58
- false
59
- );
49
+ const style1 = {
50
+ transform: [
51
+ { translateX: scatter1.interpolate({ inputRange: [0, 1], outputRange: [0, -8] }) },
52
+ { translateY: scatter1.interpolate({ inputRange: [0, 1], outputRange: [0, -8] }) },
53
+ ],
54
+ opacity: scatter1.interpolate({ inputRange: [0, 1], outputRange: [1, 0.5] }),
55
+ };
60
56
 
61
- opacity.value = withRepeat(
62
- withSequence(
63
- withTiming(0.3, { duration: 1000 }),
64
- withTiming(1, { duration: 1000 })
65
- ),
66
- -1,
67
- true
68
- );
69
- }, []);
57
+ const style2 = {
58
+ transform: [
59
+ { translateX: scatter2.interpolate({ inputRange: [0, 1], outputRange: [0, 8] }) },
60
+ { translateY: scatter2.interpolate({ inputRange: [0, 1], outputRange: [0, -6] }) },
61
+ ],
62
+ opacity: scatter2.interpolate({ inputRange: [0, 1], outputRange: [1, 0.5] }),
63
+ };
70
64
 
71
- const animatedProps1 = useAnimatedProps(() => ({
72
- transform: `translate(${scatter1.value * -8}, ${scatter1.value * -8})`,
73
- opacity: 1 - scatter1.value * 0.5,
74
- }));
75
-
76
- const animatedProps2 = useAnimatedProps(() => ({
77
- transform: `translate(${scatter2.value * 8}, ${scatter2.value * -6})`,
78
- opacity: 1 - scatter2.value * 0.5,
79
- }));
80
-
81
- const animatedProps3 = useAnimatedProps(() => ({
82
- transform: `translate(${scatter3.value * -6}, ${scatter3.value * 8})`,
83
- opacity: 1 - scatter3.value * 0.5,
84
- }));
65
+ const style3 = {
66
+ transform: [
67
+ { translateX: scatter3.interpolate({ inputRange: [0, 1], outputRange: [0, -6] }) },
68
+ { translateY: scatter3.interpolate({ inputRange: [0, 1], outputRange: [0, 8] }) },
69
+ ],
70
+ opacity: scatter3.interpolate({ inputRange: [0, 1], outputRange: [1, 0.5] }),
71
+ };
85
72
 
86
73
  return (
87
74
  <Svg width={size} height={size} viewBox="0 0 64 64" fill="none">
88
75
  {/* Piece 1 - Top left */}
89
76
  <AnimatedPath
90
- animatedProps={animatedProps1}
91
77
  d="M20 16 L28 20 L24 28 L16 24 Z"
92
78
  fill={color}
93
- opacity={0.8}
79
+ style={style1 as any}
94
80
  />
95
81
 
96
82
  {/* Piece 2 - Top right */}
97
83
  <AnimatedPath
98
- animatedProps={animatedProps2}
99
84
  d="M36 20 L44 16 L48 24 L40 28 Z"
100
85
  fill={color}
101
- opacity={0.8}
86
+ style={style2 as any}
102
87
  />
103
88
 
104
89
  {/* Piece 3 - Bottom */}
105
90
  <AnimatedPath
106
- animatedProps={animatedProps3}
107
91
  d="M24 36 L40 36 L38 48 L26 48 Z"
108
92
  fill={color}
109
- opacity={0.8}
93
+ style={style3 as any}
110
94
  />
111
95
 
112
96
  {/* Center crack */}
@@ -1,16 +1,8 @@
1
- import React, { useEffect } from 'react';
2
- import Animated, {
3
- useSharedValue,
4
- useAnimatedProps,
5
- withRepeat,
6
- withSequence,
7
- withTiming,
8
- Easing,
9
- } from 'react-native-reanimated';
10
- import Svg, { Path, Rect, G } from 'react-native-svg';
1
+ import React, { useEffect, useRef } from 'react';
2
+ import { Animated, Easing } from 'react-native';
3
+ import Svg, { Path, G } from 'react-native-svg';
11
4
 
12
5
  const AnimatedG = Animated.createAnimatedComponent(G);
13
- const AnimatedPath = Animated.createAnimatedComponent(Path);
14
6
 
15
7
  interface AnimatedInvalidDataProps {
16
8
  size?: number;
@@ -25,39 +17,30 @@ export const AnimatedInvalidData: React.FC<AnimatedInvalidDataProps> = ({
25
17
  size = 64,
26
18
  color = '#EF4444',
27
19
  }) => {
28
- const glitch = useSharedValue(0);
29
- const opacity = useSharedValue(1);
20
+ const glitch = useRef(new Animated.Value(0)).current;
21
+ const opacity = useRef(new Animated.Value(1)).current;
30
22
 
31
23
  useEffect(() => {
32
- glitch.value = withRepeat(
33
- withSequence(
34
- withTiming(0, { duration: 2000 }),
35
- withTiming(3, { duration: 100, easing: Easing.linear }),
36
- withTiming(0, { duration: 100 }),
37
- withTiming(-2, { duration: 100 }),
38
- withTiming(0, { duration: 100 })
39
- ),
40
- -1,
41
- false
42
- );
24
+ Animated.loop(
25
+ Animated.sequence([
26
+ Animated.timing(glitch, { toValue: 0, duration: 2000, useNativeDriver: true }),
27
+ Animated.timing(glitch, { toValue: 3, duration: 100, easing: Easing.linear, useNativeDriver: true }),
28
+ Animated.timing(glitch, { toValue: 0, duration: 100, useNativeDriver: true }),
29
+ Animated.timing(glitch, { toValue: -2, duration: 100, useNativeDriver: true }),
30
+ Animated.timing(glitch, { toValue: 0, duration: 100, useNativeDriver: true }),
31
+ ])
32
+ ).start();
43
33
 
44
- opacity.value = withRepeat(
45
- withSequence(
46
- withTiming(1, { duration: 2000 }),
47
- withTiming(0.7, { duration: 100 }),
48
- withTiming(1, { duration: 100 }),
49
- withTiming(0.8, { duration: 100 }),
50
- withTiming(1, { duration: 100 })
51
- ),
52
- -1,
53
- false
54
- );
55
- }, []);
56
-
57
- const animatedProps = useAnimatedProps(() => ({
58
- transform: `translateX(${glitch.value})`,
59
- opacity: opacity.value,
60
- }));
34
+ Animated.loop(
35
+ Animated.sequence([
36
+ Animated.timing(opacity, { toValue: 1, duration: 2000, useNativeDriver: true }),
37
+ Animated.timing(opacity, { toValue: 0.7, duration: 100, useNativeDriver: true }),
38
+ Animated.timing(opacity, { toValue: 1, duration: 100, useNativeDriver: true }),
39
+ Animated.timing(opacity, { toValue: 0.8, duration: 100, useNativeDriver: true }),
40
+ Animated.timing(opacity, { toValue: 1, duration: 100, useNativeDriver: true }),
41
+ ])
42
+ ).start();
43
+ }, [glitch, opacity]);
61
44
 
62
45
  return (
63
46
  <Svg width={size} height={size} viewBox="0 0 64 64" fill="none">
@@ -79,7 +62,10 @@ export const AnimatedInvalidData: React.FC<AnimatedInvalidDataProps> = ({
79
62
 
80
63
  {/* Glitched content lines */}
81
64
  <AnimatedG
82
- animatedProps={animatedProps}
65
+ style={{
66
+ transform: [{ translateX: glitch }],
67
+ opacity: opacity,
68
+ } as any}
83
69
  >
84
70
  <Path
85
71
  d="M22 24 L42 24"
@@ -1,12 +1,6 @@
1
- import React, { useEffect } from 'react';
2
- import Animated, {
3
- useSharedValue,
4
- useAnimatedProps,
5
- withRepeat,
6
- withTiming,
7
- Easing,
8
- } from 'react-native-reanimated';
9
- import Svg, { Path, Circle, G } from 'react-native-svg';
1
+ import React, { useEffect, useRef } from 'react';
2
+ import { Animated, Easing } from 'react-native';
3
+ import Svg, { Path, Circle } from 'react-native-svg';
10
4
 
11
5
  const AnimatedPath = Animated.createAnimatedComponent(Path);
12
6
  const AnimatedCircle = Animated.createAnimatedComponent(Circle);
@@ -24,66 +18,102 @@ export const AnimatedAlert: React.FC<AnimatedAlertProps> = ({
24
18
  size = 64,
25
19
  color = '#F59E0B',
26
20
  }) => {
27
- const rotation = useSharedValue(0);
28
- const ringPulse = useSharedValue(1);
21
+ const rotation = useRef(new Animated.Value(0)).current;
22
+ const ringPulse = useRef(new Animated.Value(0)).current;
29
23
 
30
24
  useEffect(() => {
31
- rotation.value = withRepeat(
32
- withTiming(10, { duration: 150, easing: Easing.inOut(Easing.ease) }),
33
- -1,
34
- true
35
- );
25
+ Animated.loop(
26
+ Animated.sequence([
27
+ Animated.timing(rotation, {
28
+ toValue: 1,
29
+ duration: 150,
30
+ easing: Easing.inOut(Easing.ease),
31
+ useNativeDriver: true,
32
+ }),
33
+ Animated.timing(rotation, {
34
+ toValue: -1,
35
+ duration: 150,
36
+ easing: Easing.inOut(Easing.ease),
37
+ useNativeDriver: true,
38
+ }),
39
+ ])
40
+ ).start();
36
41
 
37
- ringPulse.value = withRepeat(
38
- withTiming(1.3, { duration: 1000, easing: Easing.out(Easing.ease) }),
39
- -1,
40
- false
41
- );
42
- }, []);
42
+ Animated.loop(
43
+ Animated.timing(ringPulse, {
44
+ toValue: 1,
45
+ duration: 1000,
46
+ easing: Easing.out(Easing.ease),
47
+ useNativeDriver: true,
48
+ })
49
+ ).start();
50
+ }, [rotation, ringPulse]);
43
51
 
44
- const bellProps = useAnimatedProps(() => ({
45
- transform: `rotate(${rotation.value} 32 24)`,
46
- }));
52
+ const bellStyle = {
53
+ transform: [
54
+ { translateX: 32 },
55
+ { translateY: 24 },
56
+ { rotate: rotation.interpolate({
57
+ inputRange: [-1, 1],
58
+ outputRange: ['-10deg', '10deg'],
59
+ }) },
60
+ { translateX: -32 },
61
+ { translateY: -24 },
62
+ ],
63
+ };
47
64
 
48
- const ringProps = useAnimatedProps(() => ({
49
- opacity: 1 - (ringPulse.value - 1) / 0.3,
50
- r: 28 * ringPulse.value,
51
- }));
65
+ const ringStyle = {
66
+ opacity: ringPulse.interpolate({
67
+ inputRange: [0, 1],
68
+ outputRange: [1, 0],
69
+ }),
70
+ transform: [
71
+ { translateX: 32 },
72
+ { translateY: 28 },
73
+ { scale: ringPulse.interpolate({
74
+ inputRange: [0, 1],
75
+ outputRange: [0.8, 1.3],
76
+ }) },
77
+ { translateX: -32 },
78
+ { translateY: -28 },
79
+ ],
80
+ };
52
81
 
53
82
  return (
54
83
  <Svg width={size} height={size} viewBox="0 0 64 64" fill="none">
55
84
  {/* Ring pulse effect */}
56
85
  <AnimatedCircle
57
- animatedProps={ringProps}
58
86
  cx="32"
59
87
  cy="28"
88
+ r="28"
60
89
  stroke={color}
61
90
  strokeWidth="2"
62
91
  fill="none"
92
+ style={ringStyle as any}
63
93
  />
64
94
 
65
95
  {/* Bell body */}
66
96
  <AnimatedPath
67
- animatedProps={bellProps}
68
97
  d="M20 28 C20 20, 26 14, 32 14 C38 14, 44 20, 44 28 L44 36 C44 38, 46 40, 48 40 L16 40 C18 40, 20 38, 20 36 Z"
69
98
  fill={color}
70
99
  opacity={0.9}
100
+ style={bellStyle as any}
71
101
  />
72
102
 
73
103
  {/* Bell clapper */}
74
104
  <AnimatedPath
75
- animatedProps={bellProps}
76
105
  d="M32 40 L32 44"
77
106
  stroke={color}
78
107
  strokeWidth="2"
79
108
  strokeLinecap="round"
109
+ style={bellStyle as any}
80
110
  />
81
111
  <AnimatedCircle
82
- animatedProps={bellProps}
83
112
  cx="32"
84
113
  cy="46"
85
114
  r="2"
86
115
  fill={color}
116
+ style={bellStyle as any}
87
117
  />
88
118
 
89
119
  {/* Bell top */}
@@ -1,13 +1,6 @@
1
- import React, { useEffect } from 'react';
2
- import Animated, {
3
- useSharedValue,
4
- useAnimatedProps,
5
- withRepeat,
6
- withSequence,
7
- withTiming,
8
- Easing,
9
- } from 'react-native-reanimated';
10
- import Svg, { Path, Circle, G } from 'react-native-svg';
1
+ import React, { useEffect, useRef } from 'react';
2
+ import { Animated, Easing } from 'react-native';
3
+ import Svg, { Path, G } from 'react-native-svg';
11
4
 
12
5
  const AnimatedG = Animated.createAnimatedComponent(G);
13
6
  const AnimatedPath = Animated.createAnimatedComponent(Path);
@@ -25,39 +18,45 @@ export const AnimatedEmergency: React.FC<AnimatedEmergencyProps> = ({
25
18
  size = 64,
26
19
  color = '#DC2626',
27
20
  }) => {
28
- const flash = useSharedValue(0);
29
- const rotate = useSharedValue(0);
21
+ const flash = useRef(new Animated.Value(0)).current;
22
+ const rotate = useRef(new Animated.Value(0)).current;
30
23
 
31
24
  useEffect(() => {
32
- flash.value = withRepeat(
33
- withSequence(
34
- withTiming(1, { duration: 300 }),
35
- withTiming(0, { duration: 300 })
36
- ),
37
- -1,
38
- false
39
- );
25
+ Animated.loop(
26
+ Animated.sequence([
27
+ Animated.timing(flash, { toValue: 1, duration: 300, useNativeDriver: true }),
28
+ Animated.timing(flash, { toValue: 0, duration: 300, useNativeDriver: true }),
29
+ ])
30
+ ).start();
40
31
 
41
- rotate.value = withRepeat(
42
- withTiming(360, { duration: 2000, easing: Easing.linear }),
43
- -1,
44
- false
45
- );
46
- }, []);
32
+ Animated.loop(
33
+ Animated.timing(rotate, {
34
+ toValue: 1,
35
+ duration: 2000,
36
+ easing: Easing.linear,
37
+ useNativeDriver: true,
38
+ })
39
+ ).start();
40
+ }, [flash, rotate]);
47
41
 
48
- const flashProps = useAnimatedProps(() => ({
49
- opacity: flash.value,
50
- }));
51
-
52
- const rotateProps = useAnimatedProps(() => ({
53
- transform: `rotate(${rotate.value} 32 24)`,
54
- }));
42
+ const rotateStyle = {
43
+ transform: [
44
+ { translateX: 32 },
45
+ { translateY: 24 },
46
+ { rotate: rotate.interpolate({
47
+ inputRange: [0, 1],
48
+ outputRange: ['0deg', '360deg'],
49
+ }) },
50
+ { translateX: -32 },
51
+ { translateY: -24 },
52
+ ],
53
+ };
55
54
 
56
55
  return (
57
56
  <Svg width={size} height={size} viewBox="0 0 64 64" fill="none">
58
57
  {/* Flash rays */}
59
58
  <AnimatedG
60
- animatedProps={rotateProps}
59
+ style={rotateStyle as any}
61
60
  >
62
61
  <Path
63
62
  d="M32 8 L32 16 M48 16 L42 22 M54 32 L46 32 M48 48 L42 42 M32 56 L32 48 M16 48 L22 42 M10 32 L18 32 M16 16 L22 22"
@@ -77,9 +76,11 @@ export const AnimatedEmergency: React.FC<AnimatedEmergencyProps> = ({
77
76
 
78
77
  {/* Siren top (light) */}
79
78
  <AnimatedPath
80
- animatedProps={flashProps}
81
79
  d="M26 24 L32 16 L38 24 Z"
82
80
  fill={color}
81
+ style={{
82
+ opacity: flash,
83
+ } as any}
83
84
  />
84
85
 
85
86
  {/* Siren base */}
@@ -1,11 +1,5 @@
1
- import React, { useEffect } from 'react';
2
- import Animated, {
3
- useSharedValue,
4
- useAnimatedProps,
5
- withRepeat,
6
- withTiming,
7
- Easing,
8
- } from 'react-native-reanimated';
1
+ import React, { useEffect, useRef } from 'react';
2
+ import { Animated, Easing } from 'react-native';
9
3
  import Svg, { Circle, Path } from 'react-native-svg';
10
4
 
11
5
  const AnimatedCircle = Animated.createAnimatedComponent(Circle);
@@ -24,31 +18,59 @@ export const AnimatedTimeout: React.FC<AnimatedTimeoutProps> = ({
24
18
  size = 64,
25
19
  color = '#F59E0B',
26
20
  }) => {
27
- const rotation = useSharedValue(0);
28
- const pulse = useSharedValue(1);
21
+ const rotation = useRef(new Animated.Value(0)).current;
22
+ const pulse = useRef(new Animated.Value(1)).current;
29
23
 
30
24
  useEffect(() => {
31
- rotation.value = withRepeat(
32
- withTiming(360, { duration: 2000, easing: Easing.linear }),
33
- -1,
34
- false
35
- );
25
+ Animated.loop(
26
+ Animated.timing(rotation, {
27
+ toValue: 1,
28
+ duration: 2000,
29
+ easing: Easing.linear,
30
+ useNativeDriver: true,
31
+ })
32
+ ).start();
36
33
 
37
- pulse.value = withRepeat(
38
- withTiming(1.2, { duration: 800, easing: Easing.inOut(Easing.ease) }),
39
- -1,
40
- true
41
- );
42
- }, []);
34
+ Animated.loop(
35
+ Animated.sequence([
36
+ Animated.timing(pulse, {
37
+ toValue: 1.2,
38
+ duration: 800,
39
+ easing: Easing.inOut(Easing.ease),
40
+ useNativeDriver: true,
41
+ }),
42
+ Animated.timing(pulse, {
43
+ toValue: 1,
44
+ duration: 800,
45
+ easing: Easing.inOut(Easing.ease),
46
+ useNativeDriver: true,
47
+ }),
48
+ ])
49
+ ).start();
50
+ }, [rotation, pulse]);
43
51
 
44
- const clockHandProps = useAnimatedProps(() => ({
45
- transform: `rotate(${rotation.value} 32 32)`,
46
- }));
52
+ const clockHandStyle = {
53
+ transform: [
54
+ { translateX: 32 },
55
+ { translateY: 32 },
56
+ { rotate: rotation.interpolate({
57
+ inputRange: [0, 1],
58
+ outputRange: ['0deg', '360deg'],
59
+ }) },
60
+ { translateX: -32 },
61
+ { translateY: -32 },
62
+ ],
63
+ };
47
64
 
48
- const warningProps = useAnimatedProps(() => ({
49
- transform: `scale(${pulse.value})`,
50
- transformOrigin: '48 16',
51
- }));
65
+ const warningStyle = {
66
+ transform: [
67
+ { translateX: 48 },
68
+ { translateY: 16 },
69
+ { scale: pulse },
70
+ { translateX: -48 },
71
+ { translateY: -16 },
72
+ ],
73
+ };
52
74
 
53
75
  return (
54
76
  <Svg width={size} height={size} viewBox="0 0 64 64" fill="none">
@@ -73,11 +95,11 @@ export const AnimatedTimeout: React.FC<AnimatedTimeoutProps> = ({
73
95
 
74
96
  {/* Clock hands */}
75
97
  <AnimatedPath
76
- animatedProps={clockHandProps}
77
98
  d="M32 32 L32 20"
78
99
  stroke={color}
79
100
  strokeWidth="2.5"
80
101
  strokeLinecap="round"
102
+ style={clockHandStyle as any}
81
103
  />
82
104
  <Path
83
105
  d="M32 32 L38 32"
@@ -96,11 +118,11 @@ export const AnimatedTimeout: React.FC<AnimatedTimeoutProps> = ({
96
118
 
97
119
  {/* Warning indicator */}
98
120
  <AnimatedCircle
99
- animatedProps={warningProps}
100
121
  cx="48"
101
122
  cy="16"
102
123
  r="6"
103
124
  fill={color}
125
+ style={warningStyle as any}
104
126
  />
105
127
  <Path
106
128
  d="M48 13 L48 16 M48 18 L48 18.5"
@@ -1,12 +1,6 @@
1
- import React, { useEffect } from 'react';
2
- import Animated, {
3
- useSharedValue,
4
- useAnimatedProps,
5
- withRepeat,
6
- withTiming,
7
- Easing,
8
- } from 'react-native-reanimated';
9
- import Svg, { Path, Circle, G } from 'react-native-svg';
1
+ import React, { useEffect, useRef } from 'react';
2
+ import { Animated, Easing } from 'react-native';
3
+ import Svg, { Path, G } from 'react-native-svg';
10
4
 
11
5
  const AnimatedG = Animated.createAnimatedComponent(G);
12
6
 
@@ -23,20 +17,26 @@ export const AnimatedPermission: React.FC<AnimatedPermissionProps> = ({
23
17
  size = 64,
24
18
  color = '#3B82F6',
25
19
  }) => {
26
- const scale = useSharedValue(1);
20
+ const scale = useRef(new Animated.Value(1)).current;
27
21
 
28
22
  useEffect(() => {
29
- scale.value = withRepeat(
30
- withTiming(1.1, { duration: 1500, easing: Easing.inOut(Easing.ease) }),
31
- -1,
32
- true
33
- );
34
- }, []);
35
-
36
- const animatedProps = useAnimatedProps(() => ({
37
- transform: `scale(${scale.value})`,
38
- transformOrigin: '32 32',
39
- }));
23
+ Animated.loop(
24
+ Animated.sequence([
25
+ Animated.timing(scale, {
26
+ toValue: 1.1,
27
+ duration: 1500,
28
+ easing: Easing.inOut(Easing.ease),
29
+ useNativeDriver: true,
30
+ }),
31
+ Animated.timing(scale, {
32
+ toValue: 1,
33
+ duration: 1500,
34
+ easing: Easing.inOut(Easing.ease),
35
+ useNativeDriver: true,
36
+ }),
37
+ ])
38
+ ).start();
39
+ }, [scale]);
40
40
 
41
41
  return (
42
42
  <Svg width={size} height={size} viewBox="0 0 64 64" fill="none">
@@ -57,7 +57,9 @@ export const AnimatedPermission: React.FC<AnimatedPermissionProps> = ({
57
57
 
58
58
  {/* Checkmark */}
59
59
  <AnimatedG
60
- animatedProps={animatedProps}
60
+ style={{
61
+ transform: [{ scale: scale }],
62
+ } as any}
61
63
  >
62
64
  <Path
63
65
  d="M24 30 L30 36 L42 24"