react-native-easy-navigation v0.0.3
react-native-easy-navigation
Simple and fast navigation for react-native
Note: Needs
react-native-reanimatedandreact-native-gesture-handler!
Table of Contents
Why this instead of react-navigation or wix-navigation?
Well, in most cases I guess the best option this to choose one of above but I created this lib so I could create apps faster with less worry about the navigation part.
This lib is super flexible. The only required component to use is NavigationProvider. The rest is just there for getting started faster.
Features
- Supports left-to-right transitions for ios and android
- Same transitions on both ios and android
- Drawer support
- Tabs support
- Supports push, replace and pop screens
- Regular screens
- Half panels
- Modals
- Layovers
Installation
Follow the instructions how to install react-native-gesture-handler and react-native-reanimated. Nothing else is required. Read Usage to get started using the navigation.
Usage
const Home = () => {
const router = useRouter()
return (
<Screen title="Home">
<Button onPress={() => router.navigateToArticle({ title: 'Article 1', id: 1 })} title="Go to Article 1"/>
<Button onPress={() => router.navigateToArticle({ title: 'Article 2', id: 2 })} title="Go to Article 2"/>
</Screen>
)
}
const Profile = () => {
const router = useRouter()
return (
<Screen title="Profile">
<Button onPress={() => router.navigateToMyModal({ text: 'Modal: This is a prop passed to the Modal screen' })} title="Open modal"/>
<Button onPress={() => router.navigateToMyHalfPanel({ text: 'HalfPanel: This is a prop passed to the Modal screen' })} title="Open half panel"/>
</Screen>
)
}
const Article = ({ title, id }) => {
const router = useRouter()
return (
<Screen title={title || 'Article'}>
<Text>Fetch article with ID = {id}</Text>
<Button onPress={router.pop} title="Custom go back button"/>
<Button onPress={() => router.replace('Article', { props: { title: 'Article 3 - Replaced', id: 3 } })} title="Replace with Article 3"/>
<Button onPress={() => router.push('Article', { props: { title: 'Article 4 - Push', id: 3 } })} title="Push with Article 4"/>
<Button onPress={() => router.push('Article', { props: { title: 'Article 4 - Push', id: 3 } })} title="Push with Article 4"/>
</Screen>
)
}
const Modal = ({ text, type }) => {
return (
<Screen title={type}>
<Text>{text}</Text>
</Screen>
)
}
const Drawer = ({ text, type }) => {
return (
<View style={{ flex: 1 }}>
<Text>My drawer</Text>
</View>
)
}
const App = () => {
return (
<NavigationProvider
initial="Home"
routes={{
Home: { Component: Home },
Profile: {
Component: Profile,
statusBar: {
barStyle: 'light-content',
},
header: {
backgroundColor: '#000',
color: '#fff'
}
},
Article: { Component: Article },
Drawer: { Component: Drawer },
}}
router={{
// Creates helper functions that we can get from `useRouter`-hook
// The params to the functions will be passed as props to the component
// Ex. `navigateToArticle({ id: 1, title: 'My article' })`
navigateToHome: { name: 'Home' },
navigateToProfile: { name: 'Profile' },
navigateToArticle: { name: 'Article' },
navigateToMyModal: { name: 'Modal' }
navigateToMyHalfPanel: { name: 'Modal' },
openDrawer: { name: 'Drawer', mode: 'drawer' },
}}
renderTab={(route) => {
// Will be called for each route
// If current route is Article we do not want to display the tabs
if (route.name === 'Article') {
return null
}
// You can also create an array of all your tab items and then just map them.
// Tabs and Tabs.Item is just some helper components,
// You can easily create your own and then navigate to what ever you want
return <Tabs>
<Tabs.Item
route="Home"
icon={active => (
<Ionicons
name={icon}
size={26}
color={active ? "#007aff" : "black"}
/>
)}
label={active => (
<Text style={{ color: active ? "#007aff" : "black" }}>
Home
</Text>
)}
badge={() => <Tabs.Badge number={3} />}
/>
<Tabs.Item
route="Home"
icon={active => (
<Ionicons
name={icon}
size={26}
color={active ? "#007aff" : "black"}
/>
)}
label={active => (
<Text style={{ color: active ? "#007aff" : "black" }}>
Home
</Text>
)}
badge={() => <Tabs.Badge number={3} />}
/>
</Tabs>
}}
/>
)
}Components
NavigationProvider
<NavigationProvider
router={{
// define shortcuts naviigation functions
navigateToArticle: {
name: 'Article'
},
}}
routes={{
Home: {
name: 'Home',
statusBar: {
barStyle: 'light-content|dark-content'
},
mode: 'replace|push|drawer|overlay',
// ignore header if you don't wrap your views with the <Screen> component
header: {
backgroundColor: '#000',
color: '#fff',
}
},
Article: {
name: 'Article',
},
}}
// renderTab gets called for each route
// here you can do some conditional render
renderTab={(route, router) => {
if (route.name !== 'Home') {
return null
}
return (
<Tabs>
<Tabs.Item
route="Home"
icon={active => (<Icon name="home"/>)}
label={active => <Text>Home</Text>)}
badge={() => <Tabs.Badge number={3} />}
/>
</Tabs>
)
}}
>Screen
You can wrap all your main views with the Screen component. This component will add a header with a title and a back button (if you are deeper then the first screen).
const Home = () => (
<Screen title="Home">
{/* rest of your view */}
</Screen>
)Hooks
useScreen
This is help full to get information from the screen you are at.
const Home = () => {
const {
showBackButton,
screen: {
id,
name,
mode,
animated,
statusBar: { barStyle },
header: {
backgroundColor,
color,
}
}
} = useScreen()
return null
}useRouter
If you want to navigate this is the hook!
const Home = () => {
const {
push,
pop,
replace,
reset,
// and all the shortcuts you defined in <NavigationProvider router={} />
navigateToArticle,
} = useRouter()
return (
<>
<Button
title="Push"
onPress={() => push('Article', {
props: { id: 1 },
mode: '',
statusBar: {},
header: {},
animated: true
})}
/>
<Button
title="Shortcut"
onPress={() => navigateToArticle({ id: 1 })}
/>
</>
)
}