Skip to content
This repository was archived by the owner on Feb 25, 2020. It is now read-only.

Commit 031d947

Browse files
committed
feat: export types for ScreenProps amd ScreenComponent
1 parent b9443ab commit 031d947

17 files changed

+337
-172
lines changed

.eslintrc

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
"rules": {
1616
"import/named": "off",
17+
"import/default": "off",
18+
"import/namespace": "off",
1719
"react-native/no-inline-styles": "off"
1820
}
1921
}

example/App.js renamed to example/App.tsx

+31-11
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import * as React from 'react';
2-
// eslint-disable-next-line no-unused-vars
3-
import { View, TouchableOpacity, FlatList, I18nManager } from 'react-native';
2+
import { View, TouchableOpacity, FlatList } from 'react-native';
43
import {
54
ThemeContext,
65
ThemeColors,
76
Themed,
87
createAppContainer,
8+
SupportedThemes,
99
} from 'react-navigation';
10-
import { createStackNavigator } from 'react-navigation-stack';
10+
import {
11+
createStackNavigator,
12+
NavigationStackOptions,
13+
NavigationStackProp,
14+
NavigationStackScreenProps,
15+
} from 'react-navigation-stack';
1116
import { MaterialCommunityIcons } from '@expo/vector-icons';
1217
import { List, Divider } from 'react-native-paper';
1318

@@ -17,9 +22,13 @@ import StyledDrawer from './src/StyledDrawer';
1722
import GestureInteraction from './src/GestureInteraction';
1823
import RTLDrawer from './src/RTLDrawer';
1924

20-
// I18nManager.forceRTL(false);
25+
type Item = {
26+
component: React.ComponentType;
27+
title: string;
28+
routeName: string;
29+
};
2130

22-
const data = [
31+
const data: Item[] = [
2332
{
2433
component: SimpleDrawer,
2534
title: 'Simple - persistent routes like tabs',
@@ -48,9 +57,14 @@ const data = [
4857
},
4958
];
5059

51-
class Row extends React.PureComponent {
60+
class Row extends React.PureComponent<{
61+
navigation: NavigationStackProp;
62+
item: Item;
63+
}> {
5264
static contextType = ThemeContext;
5365

66+
context: SupportedThemes = 'light';
67+
5468
render() {
5569
let { item, navigation } = this.props;
5670

@@ -65,15 +79,16 @@ class Row extends React.PureComponent {
6579
}
6680
}
6781

68-
class Home extends React.Component {
82+
class Home extends React.Component<NavigationStackScreenProps> {
6983
static contextType = ThemeContext;
7084

7185
static navigationOptions = {
7286
title: 'Examples',
7387
};
7488

75-
_keyExtractor = item => item.routeName;
76-
_renderItem = ({ item }) => {
89+
_keyExtractor = (item: Item) => item.routeName;
90+
91+
_renderItem = ({ item }: { item: Item }) => {
7792
return <Row item={item} navigation={this.props.navigation} />;
7893
};
7994

@@ -95,7 +110,12 @@ class Home extends React.Component {
95110
const MainNavigator = createStackNavigator(
96111
{
97112
Home: createStackNavigator({ Home }),
98-
...data.reduce((acc, it) => {
113+
...data.reduce<{
114+
[key: string]: {
115+
screen: React.ComponentType<any>;
116+
navigationOptions: NavigationStackOptions;
117+
};
118+
}>((acc, it) => {
99119
acc[it.routeName] = {
100120
screen: it.component,
101121
navigationOptions: {
@@ -118,7 +138,7 @@ const MainNavigator = createStackNavigator(
118138
const Navigation = createAppContainer(MainNavigator);
119139

120140
const App = () => {
121-
let [theme, setTheme] = React.useState('light');
141+
let [theme, setTheme] = React.useState<SupportedThemes>('light');
122142

123143
return (
124144
<View style={{ flex: 1 }}>

example/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
"react-native-paper": "^2.2.0",
2121
"react-native-reanimated": "~1.1.0",
2222
"react-native-webview": "~5.12.0",
23-
"react-navigation": "^4.0.3",
24-
"react-navigation-stack": "^1.4.0"
23+
"react-navigation": "^4.0.4",
24+
"react-navigation-stack": "^1.7.3"
2525
},
2626
"devDependencies": {
2727
"babel-plugin-module-resolver": "^3.2.0",

example/src/GestureInteraction.js renamed to example/src/GestureInteraction.tsx

+30-32
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,42 @@ import { withNavigation } from 'react-navigation';
44
import {
55
createDrawerNavigator,
66
DrawerGestureContext,
7+
NavigationDrawerProp,
78
} from 'react-navigation-drawer';
89
import MapView from 'react-native-maps';
910
import { WebView } from 'react-native-webview';
1011
import { NativeViewGestureHandler } from 'react-native-gesture-handler';
1112

12-
@withNavigation
13-
class ContainerWithButtons extends React.Component {
14-
render() {
15-
return (
16-
<View style={{ flex: 1 }}>
17-
{this.props.children}
18-
<View
19-
style={{
20-
position: 'absolute',
21-
paddingBottom: 30,
22-
bottom: 0,
23-
paddingTop: 10,
24-
paddingHorizontal: 10,
25-
left: 0,
26-
flexDirection: 'row',
27-
right: 0,
28-
backgroundColor: 'rgba(255,255,255,0.7)',
29-
justifyContent: 'space-between',
30-
}}
31-
>
32-
<Button
33-
title="Open drawer"
34-
onPress={() => this.props.navigation.openDrawer()}
35-
/>
36-
<Button
37-
title="Go back"
38-
onPress={() => this.props.navigation.navigate('Home')}
39-
/>
40-
</View>
13+
const ContainerWithButtons = withNavigation(
14+
({
15+
children,
16+
navigation,
17+
}: {
18+
children: React.ReactNode;
19+
navigation: NavigationDrawerProp;
20+
}) => (
21+
<View style={{ flex: 1 }}>
22+
{children}
23+
<View
24+
style={{
25+
position: 'absolute',
26+
paddingBottom: 30,
27+
bottom: 0,
28+
paddingTop: 10,
29+
paddingHorizontal: 10,
30+
left: 0,
31+
flexDirection: 'row',
32+
right: 0,
33+
backgroundColor: 'rgba(255,255,255,0.7)',
34+
justifyContent: 'space-between',
35+
}}
36+
>
37+
<Button title="Open drawer" onPress={() => navigation.openDrawer()} />
38+
<Button title="Go back" onPress={() => navigation.navigate('Home')} />
4139
</View>
42-
);
43-
}
44-
}
40+
</View>
41+
)
42+
);
4543

4644
const MapScreen = () => (
4745
<ContainerWithButtons>

example/src/ParallaxDrawer.js renamed to example/src/ParallaxDrawer.tsx

+87-40
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,40 @@ import {
77
StyleSheet,
88
View,
99
} from 'react-native';
10-
import { ThemeColors, useTheme, Themed, SafeAreaView } from 'react-navigation';
11-
import { createStackNavigator } from 'react-navigation-stack';
12-
import { createDrawerNavigator } from 'react-navigation-drawer';
10+
import {
11+
ThemeColors,
12+
useTheme,
13+
Themed,
14+
SafeAreaView,
15+
NavigationRoute,
16+
} from 'react-navigation';
17+
import {
18+
createStackNavigator,
19+
NavigationStackScreenComponent,
20+
NavigationStackProp,
21+
} from 'react-navigation-stack';
22+
import {
23+
createDrawerNavigator,
24+
DrawerContentComponentProps,
25+
NavigationDrawerOptions,
26+
NavigationDrawerProp,
27+
} from 'react-navigation-drawer';
1328
import Animated from 'react-native-reanimated';
1429
import { MaterialIcons } from '@expo/vector-icons';
1530

16-
const SampleText = ({ children }) => <Themed.Text>{children}</Themed.Text>;
31+
type Params = { drawerLockMode: 'unlocked' | 'locked-open' | 'locked-closed' };
32+
33+
const SampleText = ({ children }: { children: React.ReactNode }) => (
34+
<Themed.Text>{children}</Themed.Text>
35+
);
1736

18-
const MyNavScreen = ({ navigation, banner }) => {
37+
const MyNavScreen = ({
38+
navigation,
39+
banner,
40+
}: {
41+
navigation: NavigationStackProp<NavigationRoute, Params>;
42+
banner: string;
43+
}) => {
1944
let theme = useTheme();
2045

2146
return (
@@ -109,20 +134,22 @@ const MyNavScreen = ({ navigation, banner }) => {
109134
);
110135
};
111136

112-
const InboxScreen = ({ navigation }) => (
113-
<MyNavScreen banner="Inbox Screen" navigation={navigation} />
114-
);
137+
const InboxScreen: NavigationStackScreenComponent<Params> = ({
138+
navigation,
139+
}) => <MyNavScreen banner="Inbox Screen" navigation={navigation} />;
140+
115141
InboxScreen.navigationOptions = {
116142
headerTitle: 'Inbox',
117143
};
118144

119-
const EmailScreen = ({ navigation }) => (
120-
<MyNavScreen banner="Email Screen" navigation={navigation} />
121-
);
145+
const EmailScreen: NavigationStackScreenComponent<Params> = ({
146+
navigation,
147+
}) => <MyNavScreen banner="Email Screen" navigation={navigation} />;
148+
149+
const DraftsScreen: NavigationStackScreenComponent<Params> = ({
150+
navigation,
151+
}) => <MyNavScreen banner="Drafts Screen" navigation={navigation} />;
122152

123-
const DraftsScreen = ({ navigation }) => (
124-
<MyNavScreen banner="Drafts Screen" navigation={navigation} />
125-
);
126153
DraftsScreen.navigationOptions = {
127154
headerTitle: 'Drafts',
128155
};
@@ -133,19 +160,23 @@ const InboxStack = createStackNavigator(
133160
Email: { screen: EmailScreen },
134161
},
135162
{
136-
navigationOptions: ({ navigation }) => ({
137-
drawerLabel: 'Inbox',
138-
drawerLockMode: (
139-
navigation.state.routes[navigation.state.index].params || {}
140-
).drawerLockMode,
141-
drawerIcon: ({ tintColor }) => (
142-
<MaterialIcons
143-
name="move-to-inbox"
144-
size={24}
145-
style={{ color: tintColor }}
146-
/>
147-
),
148-
}),
163+
navigationOptions: ({ navigation }) => {
164+
const options: NavigationDrawerOptions = {
165+
drawerLabel: 'Inbox',
166+
drawerLockMode: (
167+
navigation.state.routes[navigation.state.index].params || {}
168+
).drawerLockMode,
169+
drawerIcon: ({ tintColor }) => (
170+
<MaterialIcons
171+
name="move-to-inbox"
172+
size={24}
173+
style={{ color: tintColor }}
174+
/>
175+
),
176+
};
177+
178+
return options;
179+
},
149180
}
150181
);
151182

@@ -155,19 +186,27 @@ const DraftsStack = createStackNavigator(
155186
Email: { screen: EmailScreen },
156187
},
157188
{
158-
navigationOptions: ({ navigation }) => ({
159-
drawerLabel: 'Drafts',
160-
drawerLockMode: (
161-
navigation.state.routes[navigation.state.index].params || {}
162-
).drawerLockMode,
163-
drawerIcon: ({ tintColor }) => (
164-
<MaterialIcons name="drafts" size={24} style={{ color: tintColor }} />
165-
),
166-
}),
189+
navigationOptions: ({ navigation }) => {
190+
const options: NavigationDrawerOptions = {
191+
drawerLabel: 'Drafts',
192+
drawerLockMode: (
193+
navigation.state.routes[navigation.state.index].params || {}
194+
).drawerLockMode,
195+
drawerIcon: ({ tintColor }) => (
196+
<MaterialIcons name="drafts" size={24} style={{ color: tintColor }} />
197+
),
198+
};
199+
200+
return options;
201+
},
167202
}
168203
);
169204

170-
const DrawerContents = ({ drawerOpenProgress, navigation }) => {
205+
const DrawerContents = ({
206+
drawerOpenProgress,
207+
descriptors,
208+
navigation,
209+
}: DrawerContentComponentProps) => {
171210
// `contentComponent` is passed an Animated.Value called drawerOpenProgress
172211
// that can be used to do interesting things like a simple parallax drawe
173212
const translateX = Animated.interpolate(drawerOpenProgress, {
@@ -179,15 +218,23 @@ const DrawerContents = ({ drawerOpenProgress, navigation }) => {
179218
<Animated.View style={{ transform: [{ translateX }] }}>
180219
<ScrollView>
181220
<SafeAreaView forceInset={{ top: 'always' }}>
182-
<DrawerItem navigation={navigation} item="Drafts" />
183-
<DrawerItem navigation={navigation} item="Email" />
221+
{navigation.state.routes.map(route => (
222+
<DrawerItem
223+
key={route.key}
224+
navigation={descriptors[route.key].navigation}
225+
item={route.routeName}
226+
/>
227+
))}
184228
</SafeAreaView>
185229
</ScrollView>
186230
</Animated.View>
187231
);
188232
};
189233

190-
const DrawerItem = props => {
234+
const DrawerItem = (props: {
235+
navigation: NavigationDrawerProp;
236+
item: string;
237+
}) => {
191238
return (
192239
<TouchableOpacity onPress={() => props.navigation.navigate(props.item)}>
193240
<Themed.Text style={{ padding: 10, fontSize: 18, fontWeight: '600' }}>

0 commit comments

Comments
 (0)