Skip to content

Commit d92b08f

Browse files
committed
chore: setup codegen and example
1 parent 8dc2e39 commit d92b08f

File tree

9 files changed

+12990
-27
lines changed

9 files changed

+12990
-27
lines changed

README.md

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,23 @@ A component that lets you observe value of an Animated.Value or Reanimated Share
44

55
## Installation
66

7-
87
```sh
98
npm install react-native-animated-observer
109
```
1110

12-
1311
## Usage
1412

15-
1613
```js
17-
import { AnimatedObserverView } from "react-native-animated-observer";
14+
import { AnimatedObserverView } from 'react-native-animated-observer';
1815

1916
// ...
2017

21-
<AnimatedObserverView color="tomato" />
18+
<AnimatedObserver from={animatedValue} to={reanimatedSharedValue} />;
2219
```
2320

24-
2521
## Contributing
2622

27-
- [Development workflow](CONTRIBUTING.md#development-workflow)
28-
- [Sending a pull request](CONTRIBUTING.md#sending-a-pull-request)
29-
- [Code of conduct](CODE_OF_CONDUCT.md)
23+
See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
3024

3125
## License
3226

example/babel.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const root = path.resolve(__dirname, '..');
77
module.exports = getConfig(
88
{
99
presets: ['module:@react-native/babel-preset'],
10+
plugins: ['react-native-worklets/plugin'],
1011
},
1112
{ root, pkg }
1213
);

example/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
"@react-native/new-app-screen": "0.81.0",
1414
"react": "19.1.0",
1515
"react-native": "0.81.0",
16-
"react-native-safe-area-context": "^5.5.2"
16+
"react-native-gesture-handler": "^2.28.0",
17+
"react-native-reanimated": "^4.1.0",
18+
"react-native-safe-area-context": "^5.6.1",
19+
"react-native-worklets": "^0.5.0"
1720
},
1821
"devDependencies": {
1922
"@babel/core": "^7.25.2",

example/src/App.tsx

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,74 @@
1-
import { View, StyleSheet } from 'react-native';
2-
import { AnimatedObserverView } from 'react-native-animated-observer';
1+
import React, { useState } from 'react';
2+
import { Pressable, StyleSheet, Text, View } from 'react-native';
3+
import { GestureHandlerRootView } from 'react-native-gesture-handler';
4+
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
5+
import {
6+
AnimatedToReanimated,
7+
AnimatedValueObserver,
8+
PlainValueObserver,
9+
ReanimatedToAnimated,
10+
ReanimatedValueObserver,
11+
} from './Examples';
12+
13+
const screens = {
14+
'Animated to Reanimated': AnimatedToReanimated,
15+
'Reanimated to Animated': ReanimatedToAnimated,
16+
'Plain observer': PlainValueObserver,
17+
'Animated observer': AnimatedValueObserver,
18+
'Reanimated observer': ReanimatedValueObserver,
19+
};
320

421
export default function App() {
22+
const [currentScreen, setCurrentScreen] = useState<
23+
keyof typeof screens | null
24+
>(null);
25+
26+
const ScreenComponent = currentScreen ? screens[currentScreen] : null;
27+
528
return (
6-
<View style={styles.container}>
7-
<AnimatedObserverView color="#32a852" style={styles.box} />
8-
</View>
29+
<GestureHandlerRootView style={styles.container}>
30+
<SafeAreaProvider style={styles.container}>
31+
<SafeAreaView style={styles.container}>
32+
{ScreenComponent ? (
33+
<>
34+
<Pressable
35+
style={styles.button}
36+
onPress={() => setCurrentScreen(null)}
37+
>
38+
<Text>Back</Text>
39+
</Pressable>
40+
<ScreenComponent />
41+
</>
42+
) : (
43+
Object.keys(screens).map((name) => (
44+
<React.Fragment key={name}>
45+
<Pressable
46+
style={styles.button}
47+
onPress={() => setCurrentScreen(name as keyof typeof screens)}
48+
>
49+
<View>
50+
<Text>{name}</Text>
51+
</View>
52+
</Pressable>
53+
<View style={styles.separator} />
54+
</React.Fragment>
55+
))
56+
)}
57+
</SafeAreaView>
58+
</SafeAreaProvider>
59+
</GestureHandlerRootView>
960
);
1061
}
1162

1263
const styles = StyleSheet.create({
1364
container: {
1465
flex: 1,
15-
alignItems: 'center',
16-
justifyContent: 'center',
1766
},
18-
box: {
19-
width: 60,
20-
height: 60,
21-
marginVertical: 20,
67+
button: {
68+
padding: 16,
69+
},
70+
separator: {
71+
height: StyleSheet.hairlineWidth,
72+
backgroundColor: 'rgba(0, 0, 0, 0.2)',
2273
},
2374
});

example/src/Examples.tsx

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
import { useEffect, useRef, useState } from 'react';
2+
import { Animated, StyleSheet, View } from 'react-native';
3+
import {
4+
AnimatedConverter,
5+
AnimatedObserver,
6+
} from 'react-native-animated-observer';
7+
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
8+
import Reanimated, {
9+
useAnimatedStyle,
10+
useSharedValue,
11+
} from 'react-native-reanimated';
12+
13+
export function AnimatedToReanimated() {
14+
const positionAnimated = useState(() => new Animated.Value(0))[0];
15+
const positionReanimated = useSharedValue(0);
16+
17+
const animatedStyle = useAnimatedStyle(() => {
18+
return {
19+
transform: [{ translateY: positionReanimated.get() }],
20+
};
21+
});
22+
23+
return (
24+
<View style={styles.container}>
25+
<Animated.ScrollView
26+
style={styles.container}
27+
contentContainerStyle={styles.content}
28+
onScroll={Animated.event(
29+
[{ nativeEvent: { contentOffset: { y: positionAnimated } } }],
30+
{ useNativeDriver: true }
31+
)}
32+
>
33+
{Array.from({ length: 100 }).map((_, index) => (
34+
<View key={index} style={[styles.line]} />
35+
))}
36+
</Animated.ScrollView>
37+
<Reanimated.View style={[styles.box, styles.reanimated, animatedStyle]} />
38+
<AnimatedConverter from={positionAnimated} to={positionReanimated} />
39+
</View>
40+
);
41+
}
42+
43+
export function ReanimatedToAnimated() {
44+
const positionAnimated = useState(() => new Animated.Value(0))[0];
45+
const positionReanimated = useSharedValue(0);
46+
47+
const pan = Gesture.Pan().onUpdate((e) => {
48+
positionReanimated.set(e.absoluteX);
49+
});
50+
51+
const animatedStyle = useAnimatedStyle(() => {
52+
return {
53+
transform: [{ translateX: positionReanimated.get() }],
54+
};
55+
});
56+
57+
return (
58+
<GestureDetector gesture={pan}>
59+
<View style={styles.container}>
60+
<Reanimated.View
61+
style={[styles.box, styles.reanimated, animatedStyle]}
62+
/>
63+
<Animated.View
64+
style={[
65+
styles.box,
66+
styles.animated,
67+
{
68+
transform: [{ translateX: positionAnimated }],
69+
},
70+
]}
71+
/>
72+
<AnimatedConverter from={positionReanimated} to={positionAnimated} />
73+
</View>
74+
</GestureDetector>
75+
);
76+
}
77+
78+
export function PlainValueObserver() {
79+
const [value, setValue] = useState(0);
80+
81+
useEffect(() => {
82+
const interval = setInterval(() => {
83+
setValue((prev) => prev + 1);
84+
}, 3000);
85+
86+
return () => clearInterval(interval);
87+
}, []);
88+
89+
return (
90+
<AnimatedObserver
91+
value={value}
92+
onValueChange={(e) => {
93+
console.log('PlainObserver onValueChange', e.nativeEvent.value);
94+
}}
95+
/>
96+
);
97+
}
98+
99+
export function AnimatedValueObserver() {
100+
const ref = useRef(0);
101+
const value = useState(() => new Animated.Value(ref.current))[0];
102+
103+
useEffect(() => {
104+
const interval = setInterval(() => {
105+
value.setValue(++ref.current);
106+
}, 3000);
107+
108+
return () => clearInterval(interval);
109+
}, [value]);
110+
111+
return (
112+
<AnimatedObserver
113+
value={value}
114+
onValueChange={(e) => {
115+
console.log('AnimatedObserver onValueChange', e.nativeEvent.value);
116+
}}
117+
/>
118+
);
119+
}
120+
121+
export function ReanimatedValueObserver() {
122+
const value = useSharedValue(0);
123+
124+
useEffect(() => {
125+
const interval = setInterval(() => {
126+
value.set(value.get() + 1);
127+
}, 3000);
128+
129+
return () => clearInterval(interval);
130+
}, [value]);
131+
132+
return (
133+
<AnimatedObserver
134+
value={value}
135+
onValueChange={(e) => {
136+
console.log('ReanimatedObserver onValueChange', e.nativeEvent.value);
137+
}}
138+
/>
139+
);
140+
}
141+
142+
const styles = StyleSheet.create({
143+
container: {
144+
flex: 1,
145+
},
146+
box: {
147+
position: 'absolute',
148+
top: 10,
149+
left: 10,
150+
width: 50,
151+
height: 50,
152+
borderRadius: 5,
153+
},
154+
content: {
155+
gap: 10,
156+
padding: 10,
157+
},
158+
line: {
159+
height: 10,
160+
borderRadius: 5,
161+
backgroundColor: 'rgba(0, 0, 0, 0.1)',
162+
},
163+
reanimated: {
164+
backgroundColor: 'tomato',
165+
},
166+
animated: {
167+
top: 10,
168+
left: 70,
169+
backgroundColor: 'blue',
170+
},
171+
});

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,17 @@
8080
"react": "19.1.0",
8181
"react-native": "0.81.0",
8282
"react-native-builder-bob": "^0.40.13",
83+
"react-native-reanimated": "^4.1.0",
84+
"react-native-worklets": "^0.5.0",
8385
"release-it": "^17.10.0",
8486
"turbo": "^1.10.7",
8587
"typescript": "^5.8.3"
8688
},
8789
"peerDependencies": {
8890
"react": "*",
89-
"react-native": "*"
91+
"react-native": "*",
92+
"react-native-reanimated": "*",
93+
"react-native-worklets": "*"
9094
},
9195
"workspaces": [
9296
"example"
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
1-
import { codegenNativeComponent, type ViewProps } from 'react-native';
1+
import {
2+
codegenNativeComponent,
3+
type CodegenTypes,
4+
type ViewProps,
5+
} from 'react-native';
26

3-
interface NativeProps extends ViewProps {
4-
color?: string;
7+
type ValueChangeEvent = {
8+
value: CodegenTypes.Double;
9+
};
10+
11+
export interface NativeProps extends ViewProps {
12+
tag: string;
13+
value?: CodegenTypes.Double;
14+
onValueChange?: CodegenTypes.DirectEventHandler<ValueChangeEvent>;
515
}
616

717
export default codegenNativeComponent<NativeProps>('AnimatedObserverView');

0 commit comments

Comments
 (0)