diff --git a/apps/common-app/src/new_api/index.tsx b/apps/common-app/src/new_api/index.tsx index 95e6191211..55e7a71eec 100644 --- a/apps/common-app/src/new_api/index.tsx +++ b/apps/common-app/src/new_api/index.tsx @@ -14,7 +14,7 @@ import SwitchTextInputExample from './components/switchAndInput'; import TouchableExample from './components/touchable'; import TouchableStressExample from './components/touchable_stress'; import ContextMenuExample from './hover_mouse/context_menu'; -import HoverIconsExample from './hover_mouse/hover'; +import HoverPositioningExample from './hover_mouse/hover'; import HoverableIconsExample from './hover_mouse/hoverable_icons'; import MouseButtonsExample from './hover_mouse/mouse_buttons'; import StylusDataExample from './hover_mouse/stylus_data'; @@ -83,7 +83,7 @@ export const NEW_EXAMPLES: ExamplesSection[] = [ component: ContextMenuExample, unsupportedPlatforms: new Set(['android', 'ios', 'macos']), }, - { name: 'Hover Icons', component: HoverIconsExample }, + { name: 'Hover Positioning', component: HoverPositioningExample }, { name: 'Hoverable Icons', component: HoverableIconsExample }, { name: 'Mouse Buttons', component: MouseButtonsExample }, ], diff --git a/apps/common-app/src/new_api/showcase/shared_value/index.tsx b/apps/common-app/src/new_api/showcase/shared_value/index.tsx index 01f5fde635..c9fa0c376a 100644 --- a/apps/common-app/src/new_api/showcase/shared_value/index.tsx +++ b/apps/common-app/src/new_api/showcase/shared_value/index.tsx @@ -1,10 +1,9 @@ import React from 'react'; -import { Text, View } from 'react-native'; +import { StyleSheet, Text, View } from 'react-native'; import { GestureDetector, - useLongPressGesture, - usePanGesture, - useSimultaneousGestures, + Touchable, + useTapGesture, } from 'react-native-gesture-handler'; import Animated, { interpolateColor, @@ -15,76 +14,62 @@ import Animated, { import { COLORS, commonStyles } from '../../../common'; -export default function PanExample() { - const translateX = useSharedValue(0); - const translateY = useSharedValue(0); - const colorProgress = useSharedValue(0); - const offsetX = useSharedValue(0); - const offsetY = useSharedValue(0); - const maxLongPressDistance = useSharedValue(20); - const panGesture = usePanGesture({ - onBegin: () => { - colorProgress.value = withTiming(1, { duration: 150 }); - }, - onUpdate: (event) => { - translateX.value = offsetX.value + event.translationX; - translateY.value = offsetY.value + event.translationY; - maxLongPressDistance.value = Math.abs(event.translationY) * 2 + 20; - }, - onFinalize: () => { - offsetX.value = translateX.value; - offsetY.value = translateY.value; - }, - }); +export default function SharedValueConfigExample() { + const numberOfTaps = useSharedValue(1); + const flashProgress = useSharedValue(0); - const longPressGesture = useLongPressGesture({ - onBegin: () => { - colorProgress.value = withTiming(1, { - duration: 100, - }); - }, + const tap = useTapGesture({ + numberOfTaps, onActivate: () => { - colorProgress.value = withTiming(2, { - duration: 100, - }); + flashProgress.value = 1; + flashProgress.value = withTiming(0, { duration: 400 }); }, - onFinalize: () => { - colorProgress.value = withTiming(0, { - duration: 100, - }); - }, - minDuration: 1000, - maxDistance: maxLongPressDistance, }); - const gestures = useSimultaneousGestures(longPressGesture, panGesture); - const animatedStyle = useAnimatedStyle(() => { - const backgroundColor = interpolateColor( - colorProgress.value, - [0, 1, 2], - [COLORS.NAVY, COLORS.PURPLE, COLORS.KINDA_BLUE] - ); - return { - transform: [ - { translateX: translateX.value }, - { translateY: translateY.value }, - ], - backgroundColor, - }; - }); + const boxStyle = useAnimatedStyle(() => ({ + backgroundColor: interpolateColor( + flashProgress.value, + [0, 1], + [COLORS.NAVY, COLORS.KINDA_BLUE] + ), + })); return ( - - - - - - - - The ball has simultanous pan and longPress gestures. Upon update pan - changes minDistance of longPress, such that longPress will fail if is - moved horizontally. - + + + + + + { + numberOfTaps.value += 1; + }}> + Increment required taps + ); } + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + gap: 24, + }, + + button: { + paddingHorizontal: 24, + paddingVertical: 12, + backgroundColor: COLORS.PURPLE, + borderRadius: 8, + }, + buttonLabel: { + color: '#fff', + fontSize: 16, + fontWeight: '600', + }, +}); diff --git a/apps/common-app/src/new_api/showcase/state_manager/index.tsx b/apps/common-app/src/new_api/showcase/state_manager/index.tsx index 980550a569..5d91763777 100644 --- a/apps/common-app/src/new_api/showcase/state_manager/index.tsx +++ b/apps/common-app/src/new_api/showcase/state_manager/index.tsx @@ -1,11 +1,9 @@ import React from 'react'; -import { View } from 'react-native'; -import type { LongPressGesture } from 'react-native-gesture-handler'; +import { StyleSheet, Text, View } from 'react-native'; import { GestureDetector, - GestureHandlerRootView, GestureStateManager, - useLongPressGesture, + usePanGesture, } from 'react-native-gesture-handler'; import Animated, { useAnimatedStyle, @@ -15,83 +13,95 @@ import Animated, { import { COLORS, commonStyles } from '../../../common'; -export default function TwoPressables() { - const isActivated = [ - useSharedValue(0), - useSharedValue(0), - useSharedValue(0), - useSharedValue(0), - ]; - const gestures: LongPressGesture[] = []; +export default function GestureStateManagerExample() { + const upperPanActive = useSharedValue(0); + const bottomPanActive = useSharedValue(0); - const createGestureConfig = (index: number) => ({ + const bottomPan = usePanGesture({ onActivate: () => { - 'worklet'; - isActivated[index].value = 1; - console.log(`Box ${index}: long pressed`); + bottomPanActive.value = 1; + }, + onFinalize: () => { + bottomPanActive.value = withTiming(0, { duration: 300 }); + }, + minDistance: 50, + }); - const nextIndex = index + 1; - if (nextIndex < gestures.length) { - const nextGesture = gestures[nextIndex]; - if (nextGesture) { - GestureStateManager.activate(nextGesture.handlerTag); - } - } + const upperPan = usePanGesture({ + onActivate: () => { + upperPanActive.value = 1; + GestureStateManager.activate(bottomPan.handlerTag); }, onFinalize: () => { - 'worklet'; - isActivated[index].value = 0; - const nextIndex = index + 1; - if (nextIndex < gestures.length) { - const nextGesture = gestures[nextIndex]; - if (nextGesture) { - GestureStateManager.deactivate(nextGesture.handlerTag); - } - } + upperPanActive.value = withTiming(0, { duration: 300 }); + GestureStateManager.deactivate(bottomPan.handlerTag); }, - disableReanimated: true, }); - const g0 = useLongPressGesture(createGestureConfig(0)); - const g1 = useLongPressGesture(createGestureConfig(1)); - const g2 = useLongPressGesture(createGestureConfig(2)); - const g3 = useLongPressGesture(createGestureConfig(3)); + const upperPanStyle = useAnimatedStyle(() => ({ + backgroundColor: COLORS.PURPLE, + transform: [{ scale: withTiming(upperPanActive.value === 1 ? 0.9 : 1) }], + opacity: withTiming(upperPanActive.value === 1 ? 0.6 : 1), + })); - gestures[0] = g0; - gestures[1] = g1; - gestures[2] = g2; - gestures[3] = g3; + const bottomPanStyle = useAnimatedStyle(() => ({ + backgroundColor: COLORS.GREEN, + transform: [{ scale: withTiming(bottomPanActive.value === 1 ? 0.9 : 1) }], + opacity: withTiming(bottomPanActive.value === 1 ? 0.6 : 1), + })); - const colors = [COLORS.PURPLE, COLORS.NAVY, COLORS.GREEN, COLORS.RED]; + return ( + + GestureStateManager - function Box({ index }: { index: number }) { - const animatedStyle = useAnimatedStyle(() => ({ - opacity: isActivated[index].value === 1 ? 0.5 : 1, - transform: [ - { scale: withTiming(isActivated[index].value === 1 ? 0.95 : 1) }, - ], - })); + + + + Box A — pan me - return ( - - + + - ); - } - return ( - - - - - - - - + Box B — touch me, then pan A + + + Touch Box B to begin its pan gesture, then pan Box A. Box A calls{' '} + GestureStateManager.activate on Box + B's gesture. Box B must have a pointer on its surface to be managed + by StateManager. + + ); } + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + gap: 16, + }, + title: { + fontSize: 20, + fontWeight: '700', + color: COLORS.NAVY, + marginBottom: 8, + }, + boxLabel: { + fontSize: 13, + opacity: 0.6, + color: COLORS.NAVY, + }, + hint: { + fontSize: 13, + opacity: 0.5, + textAlign: 'center', + paddingHorizontal: 32, + marginTop: 8, + color: COLORS.NAVY, + }, + code: { + fontFamily: 'monospace', + fontSize: 12, + }, +});