Drawer component for React
July 31, 2019 ยท View on GitHub
Back to Polythene Drawer main page
Drawer component for React
Options
Usage
To show a Drawer as permanent side menu:
import React from "react"
import { Dialog, List } from "polythene-react"
const NavigationList = () =>
<List>
{/* see Try Out example */}
</List
})
<Drawer permanent>
<NavigationList />
</Drawer>
Invoking a Drawer
A Drawer is composed from a Dialog, so it shares many options and behaviors, but invoking a drawer is different from calling a dialog. Because drawers may be used more locally then dialogs, showing and hiding a drawer involves managing a show state locally (for example in a component state).
Maintaining the show state gives you the control when the drawer may be closed (for example to create a persistent drawer).
Important: to keep local state in sync with the drawer component, you almost always need to add option didHide. This callback function notifies when the drawer has closed, so the local show state can be reset to false.
Using local state:
import React from "react"
import { Drawer, List, ListTile, Button } from "polythene-react"
const NavigationList = ({ navItemClick }) =>
<List>
{/* see Try Out example */}
</List
})
class AppDrawer extends Component {
constructor(props) {
super(props)
this.state = {
show: false
}
}
render() {
return (
<div>
<Button
raised
label="Show"
events={{
onClick: () => this.setState({ show: true })
}}
/>
<Drawer
show={this.state.show}
didHide={() => this.setState({ show: false })}
>
<NavigationList
navItemClick={() => this.setState({ show: false })}
/>
</Drawer>
</div>
)
}
}
Types of drawer
The Material Design specification (version 2) describes 3 types of navigation drawer:
- Standard drawer
- Modal drawer
- Bottom drawer
The Polythene Drawer component offers the possibility to deviate from this, for example by combining options to create different drawers - for example a sliding drawer with a backdrop but no modal behavior.
Standard drawer
Presented on the same plane as the content. Can be permanently visible or dismissible. To be used on tablet and desktop only; use a modal drawer on mobile.
How to create this:
- Use option
permanent: trueto keep the drawer on the page; by default this creates a side menu with a height of 100% - Use option
push: trueto make the drawer push the content next to it; structurally the drawer must be placed next to the content - for example in a flex container - Optionally use:
border: true- to demarcate the drawer from the contentmini: true- instead ofpush, that will show a small part of the drawer (a strip of icons), and reveals the full menu when expanding (MD1); this assumes you have a navigation list with icons as "front"floating: true- to display the drawer as a "floating" block (instead of full height) (MD1)
Modal drawer
Presented floating on top of most of the UI. An overlay blocks interaction with the content below.
How to create this:
- Use option
cover: true - Use
modal: trueto prevent clicking on the background (technically: the touch layer, which does not have a color) - Optionally use:
fixed: true- to show the drawer on top of all other content (except for dialogs and notifications); the drawer can be created at a deeper level than the root component by giving it a CSS styleposition:fixedbackdrop: true- to show a tinted backdropshadowDepth- a number between 0 and 5 to set the shadow depth; 1 is a good default value
Bottom drawer
Not implemented
Other options
anchor: "end"- places the drawer at the right/opposite side
Responsive drawer
Changing drawer type based on screen size
If we want to make a drawer that is optimized for 3 breakpoints, we need to pass it 3 behaviors. For example:
- Small screen: cover
- Medium screen: push or mini
- Large screen: standard or floating
One way to create this drawer is to create 3 separate Drawer instances and only show them at the appropriate breakpoint, either using CSS with show/hide classes or with a conditional in the JavaScript code that toggles with screen size changes.
A simpler approach is to create a theme CSS for each breakpoint using Polythene's theme functions.
If we focus on the small screen first, we pass the theme options cover and backdrop, alongside a mediaQuery option:
import { DrawerCSS } from "polythene-css"
const breakPointSmall = 480
DrawerCSS.addStyle(
".small-screen-cover-drawer",
{
cover: true,
backdrop: true,
},
{
mediaQuery: `@media all and (max-width: ${breakPointDrawerSmall}px)`
}
)
We do the same for the other breakpoints:
const breakPointDrawerSmall = 650;
const breakPointDrawerMedium = 900;
DrawerCSS.addStyle(
".medium-screen-mini-drawer",
{
mini: true,
border: true,
},
{
mediaQuery: `@media all and (min-width: ${breakPointDrawerSmall + 1}px) and (max-width: ${breakPointDrawerMedium}px)`
}
)
DrawerCSS.addStyle(
".large-screen-floating-drawer",
{
permanent: true,
floating: true,
shadowDepth: 1,
border_radius: 4
},
{
mediaQuery: `@media all and (min-width: ${breakPointDrawerMedium + 1}px)`
}
)
We pass the classnames to the Drawer. And because we need the drawer to be available all the time, we pass permanent to the Drawer instance:
<Drawer
className="small-screen-cover-drawer medium-screen-mini-drawer large-screen-floating-drawer"
permanent
// ...
/>
For small and medium screen sizes we still need a button to invoke the drawer.
You can find a full working example at the Try Out button.
Appearance
Navigation style
To create a "navigation style" list, pass option navigation to List Tile elements.
Styling
Below are examples how to change the Drawer appearance, either with a theme or with CSS.
You can find more information about theming in Theming.
Themed component
import { DrawerCSS } from "polythene-css"
DrawerCSS.addStyle(".themed-drawer", {
color_light_background: "rgba(69, 45, 157, 1)",
color_light_text: "#fff",
color_light_backdrop_background: "rgba(69, 45, 157, .5)"
})
<Drawer
className="themed-drawer"
// ...
>
As demonstrated in responsive drawer above, some behaviors can be set using a theme (replacing component options):
DrawerCSS.addStyle(
".themed-mini-drawer",
{
mini: true,
border: false,
shadow_depth: 3,
}
)
CSS
Change CSS using the Drawer CSS classes.
Class names can be imported with:
import classes from "polythene-css-classes/drawer"
Style
Some style attributes can be set using option style. For example:
<Drawer
style={{
backgroundColor: "#EF6C00",
color: "#fff"
}}
>
RTL (right-to-left) support
The direction of Drawer content and animations are reversed when the Drawer is contained within an element that either:
- has attribute
dir="rtl" - has className
pe-rtl
Dark or light tone
If the component - or a component's parent - has option tone set to "dark", the component will be rendered with light colors on dark.
- Use
tone: "dark"to render light on dark - Use
tone: "light"to locally render normally when dark tone is set
Transitions
See Transitions