diff --git a/apps/basic-example/Gemfile.lock b/apps/basic-example/Gemfile.lock index 3e46c77c15..9f9cbc5984 100644 --- a/apps/basic-example/Gemfile.lock +++ b/apps/basic-example/Gemfile.lock @@ -5,15 +5,18 @@ GEM base64 nkf rexml - activesupport (7.1.4.2) + activesupport (7.1.5.1) base64 + benchmark (>= 0.3) bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) mutex_m + securerandom (>= 0.3) tzinfo (~> 2.0) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) @@ -21,9 +24,9 @@ GEM httpclient (~> 2.8, >= 2.8.3) json (>= 1.5.1) atomos (0.1.3) - base64 (0.2.0) - benchmark (0.4.0) - bigdecimal (3.1.9) + base64 (0.3.0) + benchmark (0.4.1) + bigdecimal (3.2.2) claide (1.1.0) cocoapods (1.15.2) addressable (~> 2.8) @@ -64,8 +67,8 @@ GEM cocoapods-try (1.2.0) colored2 (3.1.2) concurrent-ruby (1.3.3) - connection_pool (2.5.1) - drb (2.2.1) + connection_pool (2.5.3) + drb (2.2.3) escape (0.0.4) ethon (0.16.0) ffi (>= 1.15.0) @@ -77,7 +80,7 @@ GEM mutex_m i18n (1.14.7) concurrent-ruby (~> 1.0) - json (2.10.2) + json (2.12.2) logger (1.7.0) minitest (5.25.5) molinillo (0.8.0) @@ -89,6 +92,7 @@ GEM public_suffix (4.0.7) rexml (3.4.1) ruby-macho (2.5.1) + securerandom (0.3.2) typhoeus (1.4.1) ethon (>= 0.9.0) tzinfo (2.0.6) diff --git a/apps/basic-example/ios/Podfile.lock b/apps/basic-example/ios/Podfile.lock index 27ba11a5e7..d784023016 100644 --- a/apps/basic-example/ios/Podfile.lock +++ b/apps/basic-example/ios/Podfile.lock @@ -2678,7 +2678,7 @@ SPEC CHECKSUMS: RNReanimated: 25060745a200605462ff56cf488411db066631ce RNWorklets: 9bb08cb0ef718ce063f61ca18f95f57aec9b9673 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - Yoga: 0c4b7d2aacc910a1f702694fa86be830386f4ceb + Yoga: 395b5d614cd7cbbfd76b05d01bd67230a6ad004e PODFILE CHECKSUM: d05778d3a61b8d49242579ea0aa864580fbb1f64 diff --git a/apps/basic-example/src/App.tsx b/apps/basic-example/src/App.tsx index 8f5193ee0c..fceb9a2ba2 100644 --- a/apps/basic-example/src/App.tsx +++ b/apps/basic-example/src/App.tsx @@ -4,55 +4,47 @@ import { GestureHandlerRootView } from 'react-native-gesture-handler'; import Navigator from './Navigator'; -import ComponentsScreen from './ComponentsScreen'; -import FinalScreen from './FinalScreen'; -import GestureCompositionScreen from './GestureCompositionScreen'; -import HomeScreen from './HomeScreen'; -import ViewFlatteningScreen from './ViewFlatteningScreen'; +import NativeDetector from './NativeDetector'; +import RuntimeDecoration from './RuntimeDecoration'; -const Stack = Navigator.create(); - -Stack.setRoutes({ - home: { - component: HomeScreen, - title: 'RNGH FabricExample', - rightButtonAction: () => { - Stack.navigateTo('gestureComposition'); - }, - }, - gestureComposition: { - component: GestureCompositionScreen, - title: 'Gesture Composition', - rightButtonAction: () => { - Stack.navigateTo('components'); - }, - }, - components: { - component: ComponentsScreen, - title: 'Components', - rightButtonAction: () => { - Stack.navigateTo('viewFlattening'); - }, +const EXAMPLES = [ + { + name: 'Runtime Decoration', + component: RuntimeDecoration, }, - viewFlattening: { - component: ViewFlatteningScreen, - title: 'View Flattening', - rightButtonAction: () => { - Stack.navigateTo('final'); - }, + { + name: 'Native Detector', + component: NativeDetector, }, - final: { - component: FinalScreen, - title: 'Final Screen', - }, -}); +]; + +const Stack = Navigator.create(); +Stack.setRoutes( + Object.fromEntries( + EXAMPLES.map((example, index) => [ + example.name.toLowerCase().replace(/\s+/g, ''), + { + component: example.component, + title: example.name, + rightButtonAction: + index === EXAMPLES.length - 1 + ? undefined + : () => { + Stack.navigateTo( + EXAMPLES[index + 1].name.toLowerCase().replace(/\s+/g, '') + ); + }, + }, + ]) + ) +); export default function App() { return ( - + ); diff --git a/apps/basic-example/src/ComponentsScreen.tsx b/apps/basic-example/src/ComponentsScreen.tsx deleted file mode 100644 index 8a3eb59fd9..0000000000 --- a/apps/basic-example/src/ComponentsScreen.tsx +++ /dev/null @@ -1,193 +0,0 @@ -import React from 'react'; -import { - FlatList, - Gesture, - GestureDetector, - ScrollView, - Switch, - TextInput, - TouchableNativeFeedback, - TouchableOpacity, -} from 'react-native-gesture-handler'; -import { StyleSheet, Text, View } from 'react-native'; - -import { COLORS } from './colors'; - -function SwitchDemo() { - const [value, setValue] = React.useState(false); - - const pan = Gesture.Pan() - .onBegin(() => console.log('onBegin')) - .onUpdate(() => console.log('onUpdate')) // doesn't work on iOS - .onFinalize(() => console.log('onFinalize')); - - return ( - - RNGH Switch - - setValue(!value)} /> - - - ); -} - -function TextInputDemo() { - const [value, setValue] = React.useState('Hello!'); - - const pan = Gesture.Pan() - .onBegin(() => console.log('onBegin')) - .onUpdate(() => console.log('onUpdate')) - .onFinalize(() => console.log('onFinalize')); - - return ( - - RNGH TextInput - - - - - ); -} - -function TouchableNativeFeedbackDemo() { - return ( - - RNGH TouchableNativeFeedback - console.log('onPressIn')} - onPressOut={() => console.log('onPressOut')} - onLongPress={() => console.log('onLongPress')}> - - - - ); -} - -function TouchableOpacityDemo() { - return ( - - RNGH TouchableOpacity - console.log('onPressIn')} - onPressOut={() => console.log('onPressOut')} - onLongPress={() => console.log('onLongPress')}> - - - - ); -} - -function ScrollViewDemo() { - const pan = Gesture.Pan().onUpdate((e) => console.log('onUpdate', e.x, e.y)); - - return ( - - RNGH ScrollView - - - {Object.values(COLORS).map((color) => ( - - ))} - - - - Dragging here should not scroll - - - - - - - ); -} - -function FlatListDemo() { - return ( - - RNGH FlatList - - ( - - - - )} - keyExtractor={(e) => e} - /> - - - ); -} - -export default function ComponentsScreen() { - return ( - - - Gesture Handler also provides a set of components that support gestures. - - - - - - - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: 'center', - justifyContent: 'center', - }, - bold: { - fontWeight: 'bold', - textAlign: 'center', - marginHorizontal: 20, - }, - textInput: { - borderWidth: 1, - borderStyle: 'solid', - borderColor: 'darkgray', - width: 135, - padding: 10, - }, - text: { - marginVertical: 3, - }, - demo: { - marginVertical: 3, - alignItems: 'center', - }, - smallBox: { - width: 50, - height: 50, - }, - largeBox: { - width: 100, - height: 100, - }, - panBox: { - width: 100, - height: 75, - backgroundColor: 'lightgray', - alignItems: 'center', - justifyContent: 'center', - }, - panText: { - textAlign: 'center', - }, -}); diff --git a/apps/basic-example/src/FinalScreen.tsx b/apps/basic-example/src/FinalScreen.tsx deleted file mode 100644 index 9e65cf8135..0000000000 --- a/apps/basic-example/src/FinalScreen.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import React from 'react'; -import { Image, StyleSheet, Text, View } from 'react-native'; -// @ts-ignore TODO: remove once there is a .d.ts file with definitions -import openURLInBrowser from 'react-native/Libraries/Core/Devtools/openURLInBrowser'; - -import { COLORS } from './colors'; - -const SOFTWARE_MANSION_LOGO_URL = - 'https://pbs.twimg.com/profile_images/1243176655172009986/Jgdl2m15_400x400.jpg'; -const SOFTWARE_MANSION_TWITTER_URL = 'https://twitter.com/swmansion/'; - -export default function FinalScreen() { - return ( - - - React Native Gesture Handler is developed by Software Mansion. - - - We are actively porting React Native libraries to Fabric, including - React Native Screens and Reanimated. - - - Follow us on Twitter and stay tuned! @swmansion - - openURLInBrowser(SOFTWARE_MANSION_TWITTER_URL)}> - - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: 'center', - justifyContent: 'center', - backgroundColor: COLORS.NAVY, - }, - text: { - textAlign: 'center', - color: 'white', - fontSize: 21, - marginHorizontal: 20, - marginVertical: 10, - }, - bold: { - fontWeight: 'bold', - }, - logo: { - width: 250, - height: 250, - }, -}); diff --git a/apps/basic-example/src/GestureCompositionScreen.tsx b/apps/basic-example/src/GestureCompositionScreen.tsx deleted file mode 100644 index 2eb920c62f..0000000000 --- a/apps/basic-example/src/GestureCompositionScreen.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import React from 'react'; -import { StyleSheet, Text, View } from 'react-native'; -import { Gesture, GestureDetector } from 'react-native-gesture-handler'; - -import { COLORS } from './colors'; - -function RaceDemo() { - const pan = Gesture.Pan() - .onStart(() => console.log('pan onStart')) - .onUpdate(() => console.log('pan onUpdate')) - .onEnd(() => console.log('pan onEnd')); - - const longPress = Gesture.LongPress() - .onStart(() => console.log('longPress onStart')) - .onEnd(() => console.log('longPress onEnd')); - - return ( - - - Gesture.Race(pan, longPress) - the first gesture that meets its - activation criteria will activate - - - - - - ); -} - -function ExclusiveDemo() { - const singleTap = Gesture.Tap().onStart(() => console.log('single tap!')); - const doubleTap = Gesture.Tap() - .onStart(() => console.log('double tap!')) - .numberOfTaps(2); - - return ( - - - Gesture.Exclusive(doubleTap, singleTap) - the second gesture will wait - for the failure of the first one - - - - - - ); -} - -function SimultaneousDemo() { - const pinch = Gesture.Pinch() - .onStart(() => console.log('pinch onStart')) - .onUpdate(() => console.log('pinch onUpdate')) - .onEnd(() => console.log('pinch onEnd')); - const rotation = Gesture.Rotation() - .onStart(() => console.log('rotation onStart')) - .onUpdate(() => console.log('rotation onUpdate')) - .onEnd(() => console.log('rotation onEnd')); - - return ( - - - Gesture.Simultaneous(pinch, rotation) - both gestures can activate and - process touches at the same time - - - - - - ); -} - -export default function ComponentsScreen() { - return ( - - - Gesture Handler provides a simple API for using multiple gestures at - once in different configurations. - - - - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: 'center', - justifyContent: 'center', - }, - bold: { - fontWeight: 'bold', - textAlign: 'center', - marginHorizontal: 20, - }, - text: { - marginVertical: 3, - marginHorizontal: 10, - textAlign: 'center', - }, - demo: { - marginVertical: 3, - alignItems: 'center', - }, - largeBox: { - width: 100, - height: 100, - }, - largerBox: { - width: 150, - height: 150, - }, -}); diff --git a/apps/basic-example/src/NativeDetector.tsx b/apps/basic-example/src/NativeDetector.tsx new file mode 100644 index 0000000000..b5cfc7b3b3 --- /dev/null +++ b/apps/basic-example/src/NativeDetector.tsx @@ -0,0 +1,57 @@ +import * as React from 'react'; +import { Animated, Button, useAnimatedValue } from 'react-native'; +import { + GestureHandlerRootView, + NativeDetector, + useGesture, +} from 'react-native-gesture-handler'; + +export default function App() { + const [visible, setVisible] = React.useState(true); + + const value = useAnimatedValue(0); + const event = Animated.event( + [{ nativeEvent: { handlerData: { translationX: value } } }], + { + useNativeDriver: true, + } + ); + + const gesture = useGesture('PanGestureHandler', { + onGestureHandlerAnimatedEvent: event, + onGestureHandlerEvent: (e: any) => + console.log('onGestureHandlerEvent', e.nativeEvent), + }); + + return ( + +