Drawer
Navigation drawers provide access to destinations in your app. - Material Docs
import { Drawer } from 'material-bread';
Component #
There three types of drawers:
modal
, push
, and permanent
. All types can show at appbar height or be clipped underneath. Below is an example of a modal
drawer that is not clipped.Jon Snow
Knows nothing
Inbox
Outbox
Favorites
Page Title
This is a page
Click the menu button to open the drawer
Click outside the drawer to close it
Live Editing
class DrawerPage extends React.Component { constructor(props) { super(props) this.state = { isOpen: false } } render() { const DrawerContent = () => { return ( <View> <DrawerHeader title={'Jon Snow'} subtitle={'Knows nothing'} /> <DrawerSection bottomDivider> <DrawerItem text={'Inbox'} icon={'mail'} active /> <DrawerItem text={'Outbox'} icon={'send'} /> <DrawerItem text={'Favorites'} icon={'favorite'} /> </DrawerSection> </View> ); }; const PageContent = () => { return ( <View style={{ marginTop: 20, alignItems: 'center', width: '100%', flex: 1 }}> <Heading type={4} style={{ marginBottom: 20 }}> This is a page </Heading> <BodyText text={'Click the menu button to open the drawer'} /> <BodyText text={'Click outside the drawer to close it'} /> </View> ); }; const AppbarContent = isOpen => { return ( <Appbar barType={'normal'} title={'Page Title'} navigation={'menu'} onNavigation={() => this.setState({ isOpen: !this.state.isOpen })} actionItems={[{ name: 'search' }, { name: 'more-vert' }]} /> ); }; const styles = { container: { zIndex: 1, border: '1px solid rgba(0,0,0,.12)' }, body: { backgroundColor: '#eee', height: 500, flex: 1 }, }; return ( <View style={styles.container}> <Drawer open={this.state.isOpen} pageHeight={500} scrimStyles={{position: 'absolute'}} drawerContent={<DrawerContent />} onClose={() => this.setState({ isOpen: false })} animationTime={250}> <View style={styles.body}> <AppbarContent /> <PageContent /> </View> </Drawer> </View> ); } }
Usage #
The
Drawer
component needs to wrap each page it will be displayed on. Usually this can be defined as a base layout in your root App.js
file. You must provide an onClose
function if you want to close the Drawer
by clicking outside.import React, { Component } from 'react';
import { View } from 'react-native';
import { Drawer, DrawerItem, DrawerHeader, DrawerSection, Appbar, Heading, BodyText } from 'material-bread';
const DrawerContent = () => {
return (
<View>
<DrawerHeader title={'Jon Snow'} subtitle={'Knows nothing'} />
<DrawerSection bottomDivider>
<DrawerItem text={'Inbox'} icon={'mail'} active />
<DrawerItem text={'Outbox'} icon={'send'} />
<DrawerItem text={'Favorites'} icon={'favorite'} />
</DrawerSection>
</View>
);
};
const PageContent = () => {
return (
<View style={{ marginTop: 20, alignItems: 'center', width: '100%', flex: 1 }}>
<Heading type={4} style={{ marginBottom: 20 }}>
This is a page
</Heading>
<BodyText text={'Click the menu button to open the drawer'} />
<BodyText text={'Click outside the drawer to close it'} />
</View>
);
};
const AppbarContent = isOpen => {
return (
<Appbar
barType={'normal'}
title={'Page Title'}
navigation={'menu'}
onNavigation={() => this.setState({ isOpen: !this.state.isOpen })}
actionItems={[{ name: 'search' }, { name: 'more-vert' }]}
/>
);
};
const styles = {
container: {
width: '100%',
},
body: {
backgroundColor: '#eee',
},
};
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
isOpen: false
}
}
render() {
return (
<View style={styles.container}>
<Drawer
open={this.state.isOpen}
drawerContent={<DrawerContent />}
onClose={() => this.setState({ isOpen: false })}
animationTime={250}>
<View style={styles.body}>
<AppbarContent />
<PageContent />
</View>
</Drawer>
</View>
);
}
}
Props #
Name
Description
Type
Default
animationTime
How long the drawer animation should be, in ms
number
200
appbar
Render appbar above drawer and page content for clipping purposes
node
contentContainerStyle
Styles wrapper around page content
object
drawerContent
Components displayed inside the drawer
node
drawerStyle
Styles drawer
object
fullHeight
Drawer takes up full height of the page so conent is not scrolled
bool
false
onClose
Callback when clicking outside of drawer
func
pageHeight
Override calculated pageHeight, useful for demos as shown
number
ScreenHeight
pageWidth
Override calculated pageWidth, useful pages that do not take up full space
number
ScreenWidth
position
Position of drawer
string
absolute
open
Whether drawer is shown or hidden
bool
false
style
Styles container element
object
scrim
Whether scrim is shown
bool
true
scrimColor
Color of scrim
object
black
scrimOpacity
The ending opacity for the scim
number
.4
scrimStyles
Styles for scrim
object
type
Determines the type of drawer from modal, push, and permanenent
string
modal
width
Specific drawer width in pixels, will override widthPercentage
number
240
widthPercentage
Percentage of pageWidth the drawer should take up
0-1
.40
Demos #
You can see even more examples in the Storybook environment.
Clipped #
Simply move the
Appbar
component into the appbar
prop and it will dispaly above the Drawer
and Scrim
Jon Snow
Knows nothing
Inbox
Outbox
Favorites
Page Title
This is a page
Click the menu button to open the drawer
Click outside the drawer to close it
Live Editing
class DrawerPage extends React.Component { constructor(props) { super(props) this.state = { isOpen: false } } render() { const styles = { container: { zIndex: 1, border: '1px solid rgba(0,0,0,.12)' }, body: { backgroundColor: '#eee', height: 400, minHeight: 400, width: '100%', flex: 1, paddingTop: 20, alignItems: 'center', }, }; const DrawerContent = () => { return ( <View> <DrawerHeader title={'Jon Snow'} subtitle={'Knows nothing'} /> <DrawerSection bottomDivider> <DrawerItem text={'Inbox'} icon={'mail'} active /> <DrawerItem text={'Outbox'} icon={'send'} /> <DrawerItem text={'Favorites'} icon={'favorite'} /> </DrawerSection> </View> ); }; const PageContent = () => { return ( <View style={styles.body}> <Heading type={4} style={{ marginBottom: 20 }}> This is a page </Heading> <BodyText text={'Click the menu button to open the drawer'} /> <BodyText text={'Click outside the drawer to close it'} /> </View> ); }; const AppbarContent = () => { return ( <Appbar barType={'normal'} title={'Page Title'} navigation={'menu'} onNavigation={() => this.setState({ isOpen: !this.state.isOpen })} actionItems={[{ name: 'search' }, { name: 'more-vert' }]} /> ); }; return ( <View style={styles.container}> <Drawer open={this.state.isOpen} pageHeight={500} scrimStyles={{position: 'absolute'}} drawerContent={<DrawerContent />} onClose={() => this.setState({ isOpen: false })} appbar={<AppbarContent />} > <PageContent /> </Drawer> </View> ); } }
Push #
The
push
type pushes the content to the right rather than overlaying on top of it like modal
type. This example shows under the Appbar
, but you can easily move it as a child instead of in the appbar
and it will push the whole page.Jon Snow
Knows nothing
Inbox
Outbox
Favorites
Page Title
This is a page
Click the menu button to open the drawer
Click outside the drawer to close it
Live Editing
class DrawerPage extends React.Component { constructor(props) { super(props) this.state = { isOpen: false } } render() { const DrawerContent = () => { return ( <View> <DrawerHeader title={'Jon Snow'} subtitle={'Knows nothing'} /> <DrawerSection bottomDivider> <DrawerItem text={'Inbox'} icon={'mail'} active /> <DrawerItem text={'Outbox'} icon={'send'} /> <DrawerItem text={'Favorites'} icon={'favorite'} /> </DrawerSection> </View> ); }; const PageContent = () => { return ( <View style={styles.body}> <Heading type={4} style={{ marginBottom: 20 }}> This is a page </Heading> <BodyText text={'Click the menu button to open the drawer'} /> <BodyText text={'Click outside the drawer to close it'} /> </View> ); }; const AppbarContent = () => { return ( <Appbar barType={'normal'} title={'Page Title'} navigation={'menu'} onNavigation={() => this.setState({ isOpen: !this.state.isOpen })} actionItems={[{ name: 'search' }, { name: 'more-vert' }]} /> ); }; const styles = { container: { zIndex: 1, border: '1px solid rgba(0,0,0,.12)' }, body: { backgroundColor: '#eee', height: 400, minHeight: 400, width: '100%', flex: 1, paddingTop: 20, alignItems: 'center', }, }; return ( <View style={styles.container}> <Drawer open={this.state.isOpen} pageHeight={500} scrimStyles={{position: 'absolute'}} drawerContent={<DrawerContent />} onClose={() => this.setState({ isOpen: false })} appbar={<AppbarContent />} type={'push'} > <PageContent /> </Drawer> </View> ); } }
Permanent #
The
permanent
type is similiar to the push
type because there are no overlays, but instead of pushing the content to the right, it changes the width of the content to accommodate the drawer width. Toggling the drawer now changes the width of the page rather than the position left. As with the other types you can clip the drawer under the Appbar
.Jon Snow
Knows nothing
Inbox
Outbox
Favorites
Page Title
This is a page
Click the menu button to open the drawer
Click outside the drawer to close it
Live Editing
class DrawerPage extends React.Component { constructor(props) { super(props) this.state = { isOpen: true } } render() { const DrawerContent = () => { return ( <View> <DrawerHeader title={'Jon Snow'} subtitle={'Knows nothing'} /> <DrawerSection bottomDivider> <DrawerItem text={'Inbox'} icon={'mail'} active /> <DrawerItem text={'Outbox'} icon={'send'} /> <DrawerItem text={'Favorites'} icon={'favorite'} /> </DrawerSection> </View> ); }; const PageContent = () => { return ( <View style={styles.body}> <Heading type={4} style={{ marginBottom: 20 }}> This is a page </Heading> <BodyText text={'Click the menu button to open the drawer'} /> <BodyText text={'Click outside the drawer to close it'} /> </View> ); }; const AppbarContent = () => { return ( <Appbar barType={'normal'} title={'Page Title'} navigation={'menu'} onNavigation={() => this.setState({ isOpen: !this.state.isOpen })} actionItems={[{ name: 'search' }, { name: 'more-vert' }]} /> ); }; const styles = { container: { zIndex: 1, border: '1px solid rgba(0,0,0,.12)' }, body: { backgroundColor: '#eee', height: 400, minHeight: 400, width: '100%', flex: 1, alignItems: 'center', paddingTop: 20 }, }; return ( <View style={[styles.container, { width: 'auto' }]}> <Drawer open={this.state.isOpen} pageHeight={500} scrimStyles={{position: 'absolute'}} drawerContent={<DrawerContent />} onClose={() => store.set({ isOpen: false })} type={'permanent'} > <View style={{width: '100%'}}> <AppbarContent /> <PageContent /> </View> </Drawer> </View> ); } }