Skip to content

Commit 71ab149

Browse files
authored
Change components implementation (#3800)
## Description This PR changes components implementations to use new hooks API. > [!WARNING] > It requires changes in module on iOS - call `createGestureHandler` immediately, not adding operation block. ## Test plan Example apps
1 parent 80006ff commit 71ab149

File tree

37 files changed

+1654
-488
lines changed

37 files changed

+1654
-488
lines changed

apps/common-app/App.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ import LongPressExample from './src/simple/longPress';
7676
import ManualExample from './src/simple/manual';
7777
import SimpleFling from './src/simple/fling';
7878

79+
import FlatListExample from './src/components/flatlist';
80+
import ScrollViewExample from './src/components/scrollview';
81+
import ButtonsExample from './src/components/buttons';
82+
import SwitchTextInputExample from './src/components/switchAndInput';
83+
7984
import { Icon } from '@swmansion/icons';
8085

8186
interface Example {
@@ -114,6 +119,15 @@ const EXAMPLES: ExamplesSection[] = [
114119
},
115120
],
116121
},
122+
{
123+
sectionTitle: 'Components',
124+
data: [
125+
{ name: 'FlatList example', component: FlatListExample },
126+
{ name: 'ScrollView example', component: ScrollViewExample },
127+
{ name: 'Buttons example', component: ButtonsExample },
128+
{ name: 'Switch & TextInput', component: SwitchTextInputExample },
129+
],
130+
},
117131
{
118132
sectionTitle: 'Basic examples',
119133
data: [

apps/common-app/src/basic/pagerAndDrawer/index.android.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React, { Component } from 'react';
33
import { StyleSheet, Text, View } from 'react-native';
44
import {
55
createNativeWrapper,
6-
DrawerLayoutAndroid,
6+
LegacyDrawerLayoutAndroid,
77
} from 'react-native-gesture-handler';
88

99
const WrappedViewPagerAndroid = createNativeWrapper(ViewPagerAndroid, {
@@ -35,22 +35,22 @@ export default class Example extends Component {
3535
return (
3636
<WrappedViewPagerAndroid style={styles.container}>
3737
<View>
38-
<DrawerLayoutAndroid
38+
<LegacyDrawerLayoutAndroid
3939
drawerWidth={200}
4040
drawerPosition="left"
4141
renderNavigationView={() => navigationView}>
4242
<Page backgroundColor="gray" text="First 🙈" />
43-
</DrawerLayoutAndroid>
43+
</LegacyDrawerLayoutAndroid>
4444
</View>
4545
<Page backgroundColor="yellow" text="Second 🙉" />
4646
<Page backgroundColor="blue" text="Third 🙊" />
4747
<View>
48-
<DrawerLayoutAndroid
48+
<LegacyDrawerLayoutAndroid
4949
drawerWidth={200}
5050
drawerPosition="right"
5151
renderNavigationView={() => navigationView}>
5252
<Page backgroundColor="blue" text="Fourth 😎" />
53-
</DrawerLayoutAndroid>
53+
</LegacyDrawerLayoutAndroid>
5454
</View>
5555
</WrappedViewPagerAndroid>
5656
);
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { StyleSheet, Text } from 'react-native';
2+
import {
3+
BaseButton,
4+
BorderlessButton,
5+
GestureHandlerRootView,
6+
RectButton,
7+
} from 'react-native-gesture-handler';
8+
9+
type ButtonWrapperProps = {
10+
ButtonComponent:
11+
| typeof BaseButton
12+
| typeof RectButton
13+
| typeof BorderlessButton;
14+
15+
color: string;
16+
};
17+
18+
function ButtonWrapper({ ButtonComponent, color }: ButtonWrapperProps) {
19+
return (
20+
<ButtonComponent
21+
style={[styles.button, { backgroundColor: color }]}
22+
onPress={() => console.log(`[${ButtonComponent.name}] onPress`)}
23+
onLongPress={() => {
24+
console.log(`[${ButtonComponent.name}] onLongPress`);
25+
}}>
26+
<Text style={styles.buttonText}>{ButtonComponent.name}</Text>
27+
</ButtonComponent>
28+
);
29+
}
30+
31+
export default function ButtonsExample() {
32+
return (
33+
<GestureHandlerRootView style={styles.container}>
34+
<ButtonWrapper ButtonComponent={BaseButton} color="#2196F3" />
35+
<ButtonWrapper ButtonComponent={RectButton} color="#f44336" />
36+
<ButtonWrapper ButtonComponent={BorderlessButton} color="#ff9800" />
37+
</GestureHandlerRootView>
38+
);
39+
}
40+
41+
const styles = StyleSheet.create({
42+
container: {
43+
flex: 1,
44+
alignItems: 'center',
45+
justifyContent: 'space-around',
46+
},
47+
button: {
48+
width: 200,
49+
height: 50,
50+
borderRadius: 15,
51+
52+
display: 'flex',
53+
alignItems: 'center',
54+
justifyContent: 'space-around',
55+
},
56+
57+
buttonText: {
58+
color: 'white',
59+
fontSize: 16,
60+
},
61+
});
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import React, { useRef, useState } from 'react';
2+
import { View, Text, StyleSheet } from 'react-native';
3+
import {
4+
FlatList,
5+
RefreshControl,
6+
GestureHandlerRootView,
7+
} from 'react-native-gesture-handler';
8+
9+
const DATA = Array.from({ length: 20 }, (_, i) => ({
10+
id: i.toString(),
11+
title: `Item ${i + 1}`,
12+
}));
13+
14+
const Item = ({ title }: { title: string }) => (
15+
<View style={styles.item}>
16+
<Text style={styles.title}>{title}</Text>
17+
</View>
18+
);
19+
20+
export default function FlatListExample() {
21+
const [refreshing, setRefreshing] = useState(false);
22+
23+
const ref = useRef<FlatList>(null);
24+
25+
const onRefresh = () => {
26+
setRefreshing(true);
27+
console.log(ref.current);
28+
setTimeout(() => {
29+
setRefreshing(false);
30+
}, 1500);
31+
};
32+
33+
return (
34+
<GestureHandlerRootView>
35+
<FlatList
36+
refreshControl={
37+
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
38+
}
39+
ref={ref}
40+
data={DATA}
41+
keyExtractor={(item) => item.id}
42+
renderItem={({ item }) => <Item title={item.title} />}
43+
contentContainerStyle={styles.container}
44+
/>
45+
</GestureHandlerRootView>
46+
);
47+
}
48+
49+
const styles = StyleSheet.create({
50+
container: {
51+
paddingVertical: 16,
52+
},
53+
item: {
54+
backgroundColor: '#f9c2ff',
55+
padding: 20,
56+
marginVertical: 8,
57+
marginHorizontal: 16,
58+
borderRadius: 8,
59+
},
60+
title: {
61+
fontSize: 18,
62+
},
63+
});
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React, { useRef, useState } from 'react';
2+
import { Text, StyleSheet, View } from 'react-native';
3+
import { ScrollView, RefreshControl } from 'react-native-gesture-handler';
4+
5+
const DATA = Array.from({ length: 20 }, (_, i) => ({
6+
id: i.toString(),
7+
title: `Item ${i + 1}`,
8+
}));
9+
10+
const Item = ({ title }: { title: string }) => (
11+
<View style={styles.item}>
12+
<Text style={styles.title}>{title}</Text>
13+
</View>
14+
);
15+
16+
export default function ScrollViewExample() {
17+
const [refreshing, setRefreshing] = useState(false);
18+
19+
const ref = useRef<ScrollView>(null);
20+
21+
const onRefresh = () => {
22+
setRefreshing(true);
23+
console.log(ref.current);
24+
setTimeout(() => {
25+
setRefreshing(false);
26+
}, 1500);
27+
};
28+
29+
return (
30+
<ScrollView
31+
contentContainerStyle={styles.container}
32+
ref={ref}
33+
refreshControl={
34+
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
35+
}>
36+
{DATA.map((item) => (
37+
<Item key={item.id} title={item.title} />
38+
))}
39+
</ScrollView>
40+
);
41+
}
42+
43+
const styles = StyleSheet.create({
44+
container: {
45+
padding: 24,
46+
},
47+
item: {
48+
backgroundColor: '#f9c2ff',
49+
padding: 20,
50+
marginVertical: 8,
51+
marginHorizontal: 16,
52+
borderRadius: 8,
53+
},
54+
title: {
55+
fontSize: 18,
56+
},
57+
});
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import React, { useState } from 'react';
2+
import { StyleSheet, Text, View } from 'react-native';
3+
import type { NativeGestureEvent } from 'react-native-gesture-handler';
4+
import {
5+
TextInput,
6+
LegacyTextInput,
7+
Switch,
8+
LegacySwitch,
9+
} from 'react-native-gesture-handler';
10+
11+
export default function SwitchTextInputExample() {
12+
const [switchOn, setSwitchOn] = useState(false);
13+
const [legacySwitchOn, setLegacySwitchOn] = useState(false);
14+
15+
return (
16+
<View style={styles.container}>
17+
<Text style={styles.title}>Components Playground</Text>
18+
19+
<View style={styles.row}>
20+
<View style={styles.card}>
21+
<Text style={styles.cardTitle}>TextInput</Text>
22+
<TextInput
23+
onBegin={() => console.log('[TextInput] onBegin')}
24+
onActivate={() => console.log('[TextInput] onActivate')}
25+
onFinalize={(_: NativeGestureEvent, s: boolean) =>
26+
console.log('[TextInput] onFinalize', s)
27+
}
28+
style={styles.input}
29+
placeholder="Type here..."
30+
/>
31+
</View>
32+
33+
<View style={styles.card}>
34+
<Text style={styles.cardTitle}>LegacyTextInput</Text>
35+
<LegacyTextInput
36+
onBegan={() => console.log('[LegacyTextInput] onBegan')}
37+
onActivated={() => console.log('[LegacyTextInput] onActivated')}
38+
onEnded={(e: any) =>
39+
console.log('[LegacyTextInput] onEnded', e.nativeEvent?.state)
40+
}
41+
style={styles.input}
42+
placeholder="Type here..."
43+
/>
44+
</View>
45+
</View>
46+
47+
<View style={[styles.row, { marginTop: 16 }]}>
48+
<View style={styles.card}>
49+
<Text style={styles.cardTitle}>Switch (new)</Text>
50+
<View style={styles.switchRow}>
51+
<Switch
52+
onBegin={() => console.log('[Switch] onBegin')}
53+
onFinalize={(_: NativeGestureEvent, s: boolean) =>
54+
console.log('[Switch] onFinalize', s)
55+
}
56+
value={switchOn}
57+
onValueChange={(v: boolean) => {
58+
console.log('[Switch] onValueChange', v);
59+
setSwitchOn(v);
60+
}}
61+
/>
62+
<Text style={styles.switchLabel}>{switchOn ? 'On' : 'Off'}</Text>
63+
</View>
64+
</View>
65+
66+
<View style={styles.card}>
67+
<Text style={styles.cardTitle}>LegacySwitch</Text>
68+
<View style={styles.switchRow}>
69+
<LegacySwitch
70+
onBegan={() => console.log('[LegacySwitch] onBegan')}
71+
onEnded={(e: any) =>
72+
console.log('[LegacySwitch] onEnded', e.nativeEvent?.state)
73+
}
74+
value={legacySwitchOn}
75+
onValueChange={(v: boolean) => {
76+
console.log('[LegacySwitch] onValueChange', v);
77+
setLegacySwitchOn(v);
78+
}}
79+
/>
80+
<Text style={styles.switchLabel}>
81+
{legacySwitchOn ? 'On' : 'Off'}
82+
</Text>
83+
</View>
84+
</View>
85+
</View>
86+
87+
<Text style={styles.hint}>
88+
Open console to see gesture callback logs.
89+
</Text>
90+
</View>
91+
);
92+
}
93+
94+
const styles = StyleSheet.create({
95+
container: {
96+
padding: 20,
97+
alignItems: 'center',
98+
},
99+
title: {
100+
fontSize: 20,
101+
fontWeight: '600',
102+
marginBottom: 16,
103+
},
104+
row: {
105+
width: '100%',
106+
flexDirection: 'row',
107+
justifyContent: 'space-between',
108+
},
109+
card: {
110+
flex: 1,
111+
backgroundColor: '#fff',
112+
borderRadius: 8,
113+
padding: 12,
114+
marginHorizontal: 8,
115+
shadowColor: '#000',
116+
shadowOpacity: 0.06,
117+
shadowRadius: 6,
118+
elevation: 2,
119+
alignItems: 'center',
120+
},
121+
cardTitle: {
122+
fontSize: 14,
123+
fontWeight: '600',
124+
marginBottom: 8,
125+
},
126+
input: {
127+
height: 40,
128+
width: '100%',
129+
borderColor: '#e1e1e1',
130+
borderWidth: 1,
131+
borderRadius: 6,
132+
paddingHorizontal: 10,
133+
},
134+
switchRow: {
135+
flexDirection: 'row',
136+
alignItems: 'center',
137+
gap: 12,
138+
},
139+
switchLabel: {
140+
marginLeft: 12,
141+
fontSize: 14,
142+
},
143+
hint: {
144+
marginTop: 18,
145+
color: '#666',
146+
fontSize: 12,
147+
},
148+
});

0 commit comments

Comments
 (0)