routing via Navigator

This commit is contained in:
Bart Akeley 2017-03-05 18:09:01 -06:00
parent 91e9c4ff91
commit 5907b666b1
9 changed files with 253 additions and 103 deletions

View file

@ -4,62 +4,21 @@
* @flow
*/
import React, { Component } from "react";
import { AppRegistry, Navigator, Text, View, UIManager } from "react-native";
import { ThemeProvider, Toolbar } from "react-native-material-ui";
import uiTheme from "./js/ui-theme";
import SideMenu from "react-native-side-menu";
import DrawerMenu from "./js/DrawerMenu";
import React, { Component } from 'react';
import { AppRegistry, Navigator, UIManager } from 'react-native';
import routes from './js/routes';
import App from './js/App';
UIManager.setLayoutAnimationEnabledExperimental &&
UIManager.setLayoutAnimationEnabledExperimental(true);
UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);
export default class AreThereCookies extends Component {
state = { drawerOpen: false };
static displayName = 'AreThereCookies';
toggleSideMenu = () => {
this.setState(({ drawerOpen }) => ({ drawerOpen: !drawerOpen }));
};
renderScene = (route, navigator) => <App route={route} navigator={navigator} />;
setSideMenuOpen = (drawerOpen: boolean) => {
this.setState({ drawerOpen });
};
render() {
const { drawerOpen } = this.state;
return (
<ThemeProvider uiTheme={uiTheme}>
<Navigator
initialRoute={{ title: "AreThereCookies?", index: 0 }}
renderScene={(route, navigator) => {
const menu = <DrawerMenu navigator={navigator} route={route} />;
return (
<SideMenu
menu={menu}
isOpen={drawerOpen}
onChange={this.setSideMenuOpen}
>
<View style={{ flex: 1 }}>
<Toolbar
leftElement="menu"
onLeftElementPress={this.toggleSideMenu}
centerElement="Are There Cookies?"
searchable={{
autoFocus: true,
placeholder: "Search (todo)"
}}
/>
<View style={{ flex: 1, backgroundColor: "lightblue" }}>
<Text>Scene content will go here...</Text>
</View>
</View>
</SideMenu>
);
}}
/>
</ThemeProvider>
);
}
render() {
return <Navigator initialRoute={routes.food} renderScene={this.renderScene} />;
}
}
AppRegistry.registerComponent("AreThereCookies", () => AreThereCookies);
AppRegistry.registerComponent('AreThereCookies', () => AreThereCookies);

66
js/App.js Normal file
View file

@ -0,0 +1,66 @@
//@flow
import React, { Component } from 'react';
import { View } from 'react-native';
import { ThemeProvider, Toolbar } from 'react-native-material-ui';
import theme from './ui-theme';
import SideMenu from 'react-native-side-menu';
import DrawerMenu from './pages/DrawerMenu';
import { routingContextTypes } from './routes';
type Props = {
route: Object,
navigator: Object,
};
type State = {
drawerOpen: boolean,
};
export default class App extends Component {
state = { drawerOpen: false };
props: Props;
state: State;
getChildContext() {
const { navigator, route } = this.props;
return { navigator, route };
}
toggleSideMenu = () => {
this.setState(({ drawerOpen }) => ({ drawerOpen: !drawerOpen }));
};
setSideMenuOpen = (drawerOpen: boolean) => {
this.setState({ drawerOpen });
};
render() {
const { navigator, route } = this.props;
const { drawerOpen } = this.state;
return (
<ThemeProvider uiTheme={theme}>
<SideMenu
menu={<DrawerMenu navigator={navigator} route={route} />}
isOpen={drawerOpen}
onChange={this.setSideMenuOpen}
>
<View style={theme.page.container}>
<Toolbar
leftElement="menu"
onLeftElementPress={this.toggleSideMenu}
centerElement="Are There Cookies?"
searchable={{
autoFocus: true,
placeholder: 'Search (todo)',
}}
/>
<route.component />
</View>
</SideMenu>
</ThemeProvider>
);
}
}
App.childContextTypes = routingContextTypes;

View file

@ -1,39 +0,0 @@
// @flow
import React, { Component } from "react";
import { Drawer, Avatar } from "react-native-material-ui";
type Props = {
navigator: Object,
route: { index: number, title: string, page: string }
};
export default class DrawerMenu extends Component {
static displayName = "DrawerMenu";
props: Props;
render() {
return (
<Drawer>
<Drawer.Header>
<Drawer.Header.Account
avatar={<Avatar icon="person" />}
footer={{
dense: true,
centerElement: { primaryText: "User Name" }
}}
/>
</Drawer.Header>
<Drawer.Section
divider
items={[
{ icon: "local-pizza", value: "Food" },
{ icon: "domain", value: "Places" },
{ icon: "stars", value: "Faves" },
{ icon: "exit-to-app", value: "Logout" }
]}
/>
</Drawer>
);
}
}

50
js/pages/DrawerMenu.js Normal file
View file

@ -0,0 +1,50 @@
// @flow
import React, { Component } from 'react';
import { Drawer, Avatar } from 'react-native-material-ui';
import routes from '../routes';
type Props = {
navigator: Object,
route: Object,
};
export default class DrawerMenu extends Component {
static displayName = 'DrawerMenu';
props: Props;
chooseItem = routeKey => () => {
if (routeKey === 'logout') {
navigator.immediatelyResetRouteStack();
}
const { navigator } = this.props;
const newRoute = routes[routeKey];
navigator.replace(newRoute);
};
render() {
return (
<Drawer>
<Drawer.Header>
<Drawer.Header.Account
avatar={<Avatar icon="person" />}
footer={{
dense: true,
centerElement: { primaryText: 'User Name' },
}}
/>
</Drawer.Header>
<Drawer.Section
divider
items={[
{ icon: routes.food.icon, value: routes.food.title, onPress: this.chooseItem('food') },
{ icon: routes.places.icon, value: routes.places.title, onPress: this.chooseItem('places') },
{ icon: routes.faves.icon, value: routes.faves.title, onPress: this.chooseItem('faves') },
{ icon: 'exit-to-app', value: 'Logout', onPress: this.chooseItem('logout') },
]}
/>
</Drawer>
);
}
}

23
js/pages/Faves.js Normal file
View file

@ -0,0 +1,23 @@
// @flow
import React, { Component } from 'react';
import { Text, View } from 'react-native';
import theme from '../ui-theme';
type Props = {
route: Object,
navigator: Object,
};
export default class Faves extends Component {
static displayName = 'Faves';
props: Props;
render() {
return (
<View style={theme.page.container}>
<Text>Faves!</Text>
</View>
);
}
}

23
js/pages/Food.js Normal file
View file

@ -0,0 +1,23 @@
// @flow
import React, { Component } from 'react';
import { Text, View } from 'react-native';
import theme from '../ui-theme';
type Props = {
route: Object,
navigator: Object,
};
export default class Food extends Component {
static displayName = 'Food';
props: Props;
render() {
return (
<View style={theme.page.container}>
<Text>Food!</Text>
</View>
);
}
}

23
js/pages/Places.js Normal file
View file

@ -0,0 +1,23 @@
// @flow
import React, { Component } from 'react';
import { Text, View } from 'react-native';
import theme from '../ui-theme';
type Props = {
route: Object,
navigator: Object,
};
export default class Places extends Component {
static displayName = 'Places';
props: Props;
render() {
return (
<View style={theme.page.container}>
<Text>Places!</Text>
</View>
);
}
}

42
js/routes.js Normal file
View file

@ -0,0 +1,42 @@
// @flow
import { PropTypes } from 'react';
import Food from './pages/Food';
import Places from './pages/Places';
import Faves from './pages/Faves';
const {
shape,
func,
string,
} = PropTypes;
export default {
food: {
title: 'Food',
component: Food,
icon: 'local-pizza',
},
places: {
title: 'Places',
component: Places,
icon: 'domain',
},
faves: {
title: 'Faves',
component: Faves,
icon: 'stars',
},
};
export const routingContextTypes = {
navigator: shape({
push: func,
replace: func,
immediatelyResetRouteStack: func,
}),
route: shape({
title: string,
component: func,
icon: string,
}),
};

View file

@ -3,18 +3,21 @@
* Default theme for reference:
* https://github.com/xotahal/react-native-material-ui/blob/master/src/styles/themes/light.js
*/
import { COLOR } from "react-native-material-ui";
import { COLOR } from 'react-native-material-ui';
export default {
palette: {
primaryColor: COLOR.orange500,
accentColor: COLOR.teal500,
disabledColor: COLOR.grey500
},
toolbar: {
titleText: { color: COLOR.grey800 },
leftElement: { color: COLOR.grey800 },
rightElement: { color: COLOR.grey800 },
container: { backgroundColor: COLOR.grey200, height: 50 }
}
palette: {
primaryColor: COLOR.orange500,
accentColor: COLOR.teal500,
disabledColor: COLOR.grey500,
},
toolbar: {
titleText: { color: COLOR.grey800 },
leftElement: { color: COLOR.grey800 },
rightElement: { color: COLOR.grey800 },
container: { backgroundColor: COLOR.grey200, height: 50 },
},
page: {
container: { flex: 1, backgroundColor: COLOR.white },
},
};