Skip to content
This repository has been archived by the owner on Oct 30, 2022. It is now read-only.

Latest commit

 

History

History
343 lines (245 loc) · 17.7 KB

drawer.md

File metadata and controls

343 lines (245 loc) · 17.7 KB

Back to Polythene Drawer main page

Drawer component for React

Options

Drawer 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: 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 content
    • mini: true - instead of push, 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: 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 style position:fixed
    • backdrop: true - to show a tinted backdrop
    • shadowDepth - 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