Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Created December 6, 2016 19:16
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save ryanflorence/5ddf54857aa145454d67f751e7a98858 to your computer and use it in GitHub Desktop.
Save ryanflorence/5ddf54857aa145454d67f751e7a98858 to your computer and use it in GitHub Desktop.
import React, { Component, PropTypes } from 'react'
import {
Text,
View,
ScrollView
} from 'react-native'
import Redirect from 'react-router/Redirect'
import Match from 'react-router/Match'
////////////////////////////////////////////////////////////
import NativeRouter from './NativeRouter'
import Nav from './Nav'
import MatchStack from './StackMatch'
////////////////////////////////////////////////////////////
class MatchTabs extends React.Component {
render() {
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
{this.props.children}
</View>
<View style={{ flexDirection: 'row', alignItems: 'center', borderTopWidth: 1, borderTopColor: '#ddd' }}>
{React.Children.map(this.props.children, (child) => (
<Match pattern={child.props.pathname} children={({ matched }) => (
<Nav to={child.props.pathname} style={{ flex: 1, padding: 20 }}>
{child.props.renderTab({ isActive: matched })}
</Nav>
)}/>
))}
</View>
</View>
)
}
}
class MatchTab extends React.Component {
render() {
const { renderContent, pathname } = this.props
return (
<Match pattern={pathname} render={renderContent}/>
)
}
}
////////////////////////////////////////////////////////////
const stuff = [
{ path: 'one', label: 'One' },
{ path: 'two', label: 'Two' },
{ path: 'three', label: 'Three' },
{ path: 'four', label: 'Four' }
]
const blue = 'hsl(200, 50%, 50%)'
class RecursiveItem extends Component {
render() {
const { pathname, rootPath } = this.props
const pattern = rootPath ? rootPath : `${pathname}/:id`
return (
<MatchStack
isRoot={!!rootPath}
pattern={pattern}
renderTitle={({ pathname }) => (
<Text style={{ textAlign: 'center' }} ellipsizeMode="middle" numberOfLines={1}>
{pathname}
</Text>
)}
renderContent={({ pathname }) => (
<ScrollView style={{ flex: 1, backgroundColor: 'white' }}>
{stuff.map(thing => (
<View key={thing.path} style={{ borderBottomWidth: 1, borderColor: '#ddd' }}>
<Nav replace={true} to={`${pathname}/${thing.path}`} underlayColor="#f0f0f0">
<Text style={{ padding: 15 }}>{thing.label}</Text>
</Nav>
</View>
))}
</ScrollView>
)}
renderChild={(props) => (
<RecursiveItem {...props}/>
)}
/>
)
}
}
const App = () => (
<NativeRouter>
<View style={{ flex: 1, marginTop: 20 }}>
<Match pattern="/" exactly render={() => <Redirect to="/home"/>}/>
<MatchTabs>
<MatchTab pathname="/home"
renderContent={(props) => (
<RecursiveItem rootPath="/home"/>
)}
renderTab={({ isActive }) => (
<Text style={{ color: isActive ? blue : null }}>Home</Text>
)}
/>
<MatchTab pathname="/notifications"
renderContent={(props) => (
<View><Text style={{ fontSize: 30 }}>Notifications</Text></View>
)}
renderTab={({ isActive }) => (
<Text style={{ color: isActive ? blue : null }}>Notifications</Text>
)}
/>
<MatchTab pathname="/messages"
renderContent={(props) => (
<RecursiveItem rootPath="/messages"/>
)}
renderTab={({ isActive }) => (
<Text style={{ color: isActive ? blue : null }}>Messages</Text>
)}
/>
</MatchTabs>
</View>
</NativeRouter>
)
export default App
@ryanflorence
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment