Back to Polythene Drawer main page
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>
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>
)
}
}
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.
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: true
to keep the drawer on the page; by default this creates a side menu with a height of 100% - Use option
push: true
to 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)
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: true
to 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:fixed
backdrop: true
- to show a tinted backdropshadowDepth
- a number between 0 and 5 to set the shadow depth; 1 is a good default value
Not implemented
anchor: "end"
- places the drawer at the right/opposite side
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.
To create a "navigation style" list, pass option navigation
to List Tile elements.
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.
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,
}
)
Change CSS using the Drawer CSS classes.
Class names can be imported with:
import classes from "polythene-css-classes/drawer"
Some style attributes can be set using option style
. For example:
<Drawer
style={{
backgroundColor: "#EF6C00",
color: "#fff"
}}
>
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
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
See Transitions