Skip to content

Commit bff6777

Browse files
authored
Update examples (#4208)
## Description This PR does 3 things: - Changes name of `Hover icons` example as it was not relevant - Updates `GestureStateManager` example - Updates `SharedValue` example >[!NOTE] > I've wanted to add `numberOfTaps` counter, as well as render counter in the `SharedValue` example but I've encountered some problems with Reanimated so I dropped it for now 😞 ## Test plan Test new examples
1 parent 72d5c45 commit bff6777

3 files changed

Lines changed: 133 additions & 138 deletions

File tree

apps/common-app/src/new_api/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import SwitchTextInputExample from './components/switchAndInput';
1515
import TouchableExample from './components/touchable';
1616
import TouchableStressExample from './components/touchable_stress';
1717
import ContextMenuExample from './hover_mouse/context_menu';
18-
import HoverIconsExample from './hover_mouse/hover';
18+
import HoverPositioningExample from './hover_mouse/hover';
1919
import HoverableIconsExample from './hover_mouse/hoverable_icons';
2020
import MouseButtonsExample from './hover_mouse/mouse_buttons';
2121
import StylusDataExample from './hover_mouse/stylus_data';
@@ -84,7 +84,7 @@ export const NEW_EXAMPLES: ExamplesSection[] = [
8484
component: ContextMenuExample,
8585
unsupportedPlatforms: new Set(['android', 'ios', 'macos']),
8686
},
87-
{ name: 'Hover Icons', component: HoverIconsExample },
87+
{ name: 'Hover Positioning', component: HoverPositioningExample },
8888
{ name: 'Hoverable Icons', component: HoverableIconsExample },
8989
{ name: 'Mouse Buttons', component: MouseButtonsExample },
9090
],
Lines changed: 52 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import React from 'react';
2-
import { Text, View } from 'react-native';
2+
import { StyleSheet, Text, View } from 'react-native';
33
import {
44
GestureDetector,
5-
useLongPressGesture,
6-
usePanGesture,
7-
useSimultaneousGestures,
5+
Touchable,
6+
useTapGesture,
87
} from 'react-native-gesture-handler';
98
import Animated, {
109
interpolateColor,
@@ -15,76 +14,62 @@ import Animated, {
1514

1615
import { COLORS, commonStyles } from '../../../common';
1716

18-
export default function PanExample() {
19-
const translateX = useSharedValue(0);
20-
const translateY = useSharedValue(0);
21-
const colorProgress = useSharedValue(0);
22-
const offsetX = useSharedValue(0);
23-
const offsetY = useSharedValue(0);
24-
const maxLongPressDistance = useSharedValue(20);
25-
const panGesture = usePanGesture({
26-
onBegin: () => {
27-
colorProgress.value = withTiming(1, { duration: 150 });
28-
},
29-
onUpdate: (event) => {
30-
translateX.value = offsetX.value + event.translationX;
31-
translateY.value = offsetY.value + event.translationY;
32-
maxLongPressDistance.value = Math.abs(event.translationY) * 2 + 20;
33-
},
34-
onFinalize: () => {
35-
offsetX.value = translateX.value;
36-
offsetY.value = translateY.value;
37-
},
38-
});
17+
export default function SharedValueConfigExample() {
18+
const numberOfTaps = useSharedValue(1);
19+
const flashProgress = useSharedValue(0);
3920

40-
const longPressGesture = useLongPressGesture({
41-
onBegin: () => {
42-
colorProgress.value = withTiming(1, {
43-
duration: 100,
44-
});
45-
},
21+
const tap = useTapGesture({
22+
numberOfTaps,
4623
onActivate: () => {
47-
colorProgress.value = withTiming(2, {
48-
duration: 100,
49-
});
24+
flashProgress.value = 1;
25+
flashProgress.value = withTiming(0, { duration: 400 });
5026
},
51-
onFinalize: () => {
52-
colorProgress.value = withTiming(0, {
53-
duration: 100,
54-
});
55-
},
56-
minDuration: 1000,
57-
maxDistance: maxLongPressDistance,
5827
});
5928

60-
const gestures = useSimultaneousGestures(longPressGesture, panGesture);
61-
const animatedStyle = useAnimatedStyle(() => {
62-
const backgroundColor = interpolateColor(
63-
colorProgress.value,
64-
[0, 1, 2],
65-
[COLORS.NAVY, COLORS.PURPLE, COLORS.KINDA_BLUE]
66-
);
67-
return {
68-
transform: [
69-
{ translateX: translateX.value },
70-
{ translateY: translateY.value },
71-
],
72-
backgroundColor,
73-
};
74-
});
29+
const boxStyle = useAnimatedStyle(() => ({
30+
backgroundColor: interpolateColor(
31+
flashProgress.value,
32+
[0, 1],
33+
[COLORS.NAVY, COLORS.KINDA_BLUE]
34+
),
35+
}));
7536

7637
return (
77-
<View style={commonStyles.centerView}>
78-
<View>
79-
<GestureDetector gesture={gestures}>
80-
<Animated.View style={[commonStyles.ball, animatedStyle]} />
81-
</GestureDetector>
82-
</View>
83-
<Text style={commonStyles.instructions}>
84-
The ball has simultanous pan and longPress gestures. Upon update pan
85-
changes minDistance of longPress, such that longPress will fail if is
86-
moved horizontally.
87-
</Text>
38+
<View style={styles.container}>
39+
<GestureDetector gesture={tap}>
40+
<Animated.View style={[commonStyles.box, boxStyle]} />
41+
</GestureDetector>
42+
43+
<Touchable
44+
style={styles.button}
45+
activeOpacity={0.6}
46+
animationDuration={{ in: 80, out: 200 }}
47+
onPress={() => {
48+
numberOfTaps.value += 1;
49+
}}>
50+
<Text style={styles.buttonLabel}>Increment required taps</Text>
51+
</Touchable>
8852
</View>
8953
);
9054
}
55+
56+
const styles = StyleSheet.create({
57+
container: {
58+
flex: 1,
59+
justifyContent: 'center',
60+
alignItems: 'center',
61+
gap: 24,
62+
},
63+
64+
button: {
65+
paddingHorizontal: 24,
66+
paddingVertical: 12,
67+
backgroundColor: COLORS.PURPLE,
68+
borderRadius: 8,
69+
},
70+
buttonLabel: {
71+
color: '#fff',
72+
fontSize: 16,
73+
fontWeight: '600',
74+
},
75+
});
Lines changed: 79 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import React from 'react';
2-
import { View } from 'react-native';
3-
import type { LongPressGesture } from 'react-native-gesture-handler';
2+
import { StyleSheet, Text, View } from 'react-native';
43
import {
54
GestureDetector,
6-
GestureHandlerRootView,
75
GestureStateManager,
8-
useLongPressGesture,
6+
usePanGesture,
97
} from 'react-native-gesture-handler';
108
import Animated, {
119
useAnimatedStyle,
@@ -15,83 +13,95 @@ import Animated, {
1513

1614
import { COLORS, commonStyles } from '../../../common';
1715

18-
export default function TwoPressables() {
19-
const isActivated = [
20-
useSharedValue(0),
21-
useSharedValue(0),
22-
useSharedValue(0),
23-
useSharedValue(0),
24-
];
25-
const gestures: LongPressGesture[] = [];
16+
export default function GestureStateManagerExample() {
17+
const upperPanActive = useSharedValue(0);
18+
const bottomPanActive = useSharedValue(0);
2619

27-
const createGestureConfig = (index: number) => ({
20+
const bottomPan = usePanGesture({
2821
onActivate: () => {
29-
'worklet';
30-
isActivated[index].value = 1;
31-
console.log(`Box ${index}: long pressed`);
22+
bottomPanActive.value = 1;
23+
},
24+
onFinalize: () => {
25+
bottomPanActive.value = withTiming(0, { duration: 300 });
26+
},
27+
minDistance: 50,
28+
});
3229

33-
const nextIndex = index + 1;
34-
if (nextIndex < gestures.length) {
35-
const nextGesture = gestures[nextIndex];
36-
if (nextGesture) {
37-
GestureStateManager.activate(nextGesture.handlerTag);
38-
}
39-
}
30+
const upperPan = usePanGesture({
31+
onActivate: () => {
32+
upperPanActive.value = 1;
33+
GestureStateManager.activate(bottomPan.handlerTag);
4034
},
4135
onFinalize: () => {
42-
'worklet';
43-
isActivated[index].value = 0;
44-
const nextIndex = index + 1;
45-
if (nextIndex < gestures.length) {
46-
const nextGesture = gestures[nextIndex];
47-
if (nextGesture) {
48-
GestureStateManager.deactivate(nextGesture.handlerTag);
49-
}
50-
}
36+
upperPanActive.value = withTiming(0, { duration: 300 });
37+
GestureStateManager.deactivate(bottomPan.handlerTag);
5138
},
52-
disableReanimated: true,
5339
});
5440

55-
const g0 = useLongPressGesture(createGestureConfig(0));
56-
const g1 = useLongPressGesture(createGestureConfig(1));
57-
const g2 = useLongPressGesture(createGestureConfig(2));
58-
const g3 = useLongPressGesture(createGestureConfig(3));
41+
const upperPanStyle = useAnimatedStyle(() => ({
42+
backgroundColor: COLORS.PURPLE,
43+
transform: [{ scale: withTiming(upperPanActive.value === 1 ? 0.9 : 1) }],
44+
opacity: withTiming(upperPanActive.value === 1 ? 0.6 : 1),
45+
}));
5946

60-
gestures[0] = g0;
61-
gestures[1] = g1;
62-
gestures[2] = g2;
63-
gestures[3] = g3;
47+
const bottomPanStyle = useAnimatedStyle(() => ({
48+
backgroundColor: COLORS.GREEN,
49+
transform: [{ scale: withTiming(bottomPanActive.value === 1 ? 0.9 : 1) }],
50+
opacity: withTiming(bottomPanActive.value === 1 ? 0.6 : 1),
51+
}));
6452

65-
const colors = [COLORS.PURPLE, COLORS.NAVY, COLORS.GREEN, COLORS.RED];
53+
return (
54+
<View style={styles.container}>
55+
<Text style={styles.title}>GestureStateManager</Text>
6656

67-
function Box({ index }: { index: number }) {
68-
const animatedStyle = useAnimatedStyle(() => ({
69-
opacity: isActivated[index].value === 1 ? 0.5 : 1,
70-
transform: [
71-
{ scale: withTiming(isActivated[index].value === 1 ? 0.95 : 1) },
72-
],
73-
}));
57+
<GestureDetector gesture={upperPan}>
58+
<Animated.View style={[commonStyles.box, upperPanStyle]} />
59+
</GestureDetector>
60+
<Text style={styles.boxLabel}>Box A — pan me</Text>
7461

75-
return (
76-
<GestureDetector gesture={gestures[index]}>
77-
<Animated.View
78-
style={[
79-
commonStyles.box,
80-
{ backgroundColor: colors[index] },
81-
animatedStyle,
82-
]}
83-
/>
62+
<GestureDetector gesture={bottomPan}>
63+
<Animated.View style={[commonStyles.box, bottomPanStyle]} />
8464
</GestureDetector>
85-
);
86-
}
87-
return (
88-
<GestureHandlerRootView>
89-
<View style={commonStyles.centerView}>
90-
<Box index={0} />
91-
<Box index={1} />
92-
<Box index={2} />
93-
<Box index={3} />
94-
</View>
95-
</GestureHandlerRootView>
65+
<Text style={styles.boxLabel}>Box B — touch me, then pan A</Text>
66+
67+
<Text style={styles.hint}>
68+
Touch Box B to begin its pan gesture, then pan Box A. Box A calls{' '}
69+
<Text style={styles.code}>GestureStateManager.activate</Text> on Box
70+
B&apos;s gesture. Box B must have a pointer on its surface to be managed
71+
by StateManager.
72+
</Text>
73+
</View>
9674
);
9775
}
76+
77+
const styles = StyleSheet.create({
78+
container: {
79+
flex: 1,
80+
justifyContent: 'center',
81+
alignItems: 'center',
82+
gap: 16,
83+
},
84+
title: {
85+
fontSize: 20,
86+
fontWeight: '700',
87+
color: COLORS.NAVY,
88+
marginBottom: 8,
89+
},
90+
boxLabel: {
91+
fontSize: 13,
92+
opacity: 0.6,
93+
color: COLORS.NAVY,
94+
},
95+
hint: {
96+
fontSize: 13,
97+
opacity: 0.5,
98+
textAlign: 'center',
99+
paddingHorizontal: 32,
100+
marginTop: 8,
101+
color: COLORS.NAVY,
102+
},
103+
code: {
104+
fontFamily: 'monospace',
105+
fontSize: 12,
106+
},
107+
});

0 commit comments

Comments
 (0)