2019-01-27に更新

GatsbyJSにドロワーメニューを追加する

ドロワーメニューを追加したい。

カテゴリーをドロワーメニューで表示したい欲が出てきたので実装する。
しかし、ドロワーを1から書くにはJSの理解レベルが足りない。
そこで今回はMaterialUIに泣きついた。

やったこと

  • Material-UIのインストール
  • Headerを実装
  • categorylistを作成

Material-UIのインストール

npm install --save @material-ui/core
npm install --save @material-ui/icons

Headerを実装

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import Drawer from '@material-ui/core/Drawer';
import { Link } from 'gatsby';

const styles = {
  list: {
    width: 250,
  },
  root: {
    flexGrow: 1,
  },
  menuButton: {
    marginLeft: -12,
    marginRight: 20,
  },
};

class Header extends Component {
  state = {
    left: false,
  };

  toggleDrawer = (side, open) => () => {
    this.setState({
      [side]: open,
    });
  };

  render () {
    const { classes } = this.props;

    const sideList = (
      <div className={classes.list}>
        <List>
          <Link to="/">
            <ListItem button>
              <ListItemText primary="Home" />
            </ListItem>
          </Link>
          <Link to="/about">
            <ListItem button>
              <ListItemText primary="About" />
            </ListItem>
          </Link>
        </List>
      </div>
    );

    return (
      <div className={classes.root}>
        <AppBar position="relative" color="inherit">
          <Toolbar>
            <IconButton className={classes.menuButton} color="inherit" aria-label="Menu" onClick={this.toggleDrawer('left', true)}>
              <MenuIcon />
            </IconButton>
            <Drawer open={this.state.left} onClose={this.toggleDrawer('left', false)}>
              <div
                tabIndex={0}
                role="button"
                onClick={this.toggleDrawer('left', false)}
                onKeyDown={this.toggleDrawer('left', false)}
              >
                {sideList}
              </div>
            </Drawer>
            <strong>
              <Link to="/" style={{ boxShadow: 'none', textDecoration: 'none', color: 'inherit', fontFamily: 'Montserrat, sans-serif', }}>Post Bank Extra</Link>
            </strong>
          </Toolbar>
        </AppBar>
      </div>
    );
  }
}

Header.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(Header);

これにあとは自分のカテゴリーリストを載せる。

カテゴリーリストの実装

import React from 'react'
import { StaticQuery, graphql } from 'gatsby'
import ListItem from '@material-ui/core/ListItem';
import Button from '@material-ui/core/Button';
import ListItemText from '@material-ui/core/ListItemText';

const CategoryLists = () => (
  <StaticQuery
    query={graphql`
    query{
        allMarkdownRemark(filter: {frontmatter: {pagetype: {eq: "category"}}}) {
          edges{
            node{
              frontmatter{
                categoryslug
                categoryname
              }
            }
          }
        }
      }
    `}

    render={(data) => {
      const posts = data.allMarkdownRemark.edges
      return (
      <div>
      {posts.map(({ node }) => {
          return (
            <ListItem button key={node.frontmatter.categoryslug}>
              <ListItemText primary={node.frontmatter.categoryname}></ListItemText>
            </ListItem>
          )
        })}
      </div>
      );
    }}
  />
)
export default CategoryLists

そして組み込む

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import Drawer from '@material-ui/core/Drawer';
import { Link } from 'gatsby';
import CategoryLists from  '../categorylists';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faHome,faUtensils,faQuestion} from '@fortawesome/free-solid-svg-icons'

const styles = {
  list: {
    width: 250,
  },
  root: {
    flexGrow: 1,
  },
  menuButton: {
    marginLeft: -12,
    marginRight: 20,
  },
};

class Header extends Component {
  state = {
    left: false,
  };

  toggleDrawer = (side, open) => () => {
    this.setState({
      [side]: open,
    });
  };

  render () {
    const { classes } = this.props;

    const sideList = (
      <div className={classes.list}>
        <List>
          <Link to="/">
            <ListItem button>
            <FontAwesomeIcon icon={faHome} />
              <ListItemText primary="Home" />
            </ListItem>
          </Link>
          <CategoryLists />
          <Link to="/about">
            <ListItem button>
            <FontAwesomeIcon icon={faQuestion} />
              <ListItemText primary="About" />
            </ListItem>
          </Link>
        </List>
      </div>
    );

    return (
      <div className={classes.root}>
        <AppBar position="relative" color="inherit">
          <Toolbar>
            <IconButton className={classes.menuButton} color="inherit" aria-label="Menu" onClick={this.toggleDrawer('left', true)}>
              <MenuIcon />
            </IconButton>
            <Drawer open={this.state.left} onClose={this.toggleDrawer('left', false)}>
              <div
                tabIndex={0}
                role="button"
                onClick={this.toggleDrawer('left', false)}
                onKeyDown={this.toggleDrawer('left', false)}
              >
                {sideList}
              </div>
            </Drawer>
            <strong>
              <Link to="/" style={{ boxShadow: 'none', textDecoration: 'none', color: 'inherit', fontFamily: 'Montserrat, sans-serif', }}>corydoras</Link>
            </strong>
          </Toolbar>
        </AppBar>
      </div>
    );
  }
}

Header.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(Header);

StaticQueryで実装。便利。

実働

020-1.png
よし!動いた!

出来なかったこと

frontmatterにicon設定してリストレンダリングしようとしましたができませんでした。

Originally published at www.corylog.com

view_list [連載] ブロガー向けGatsby講座
第17回 GatsbyJSでMrakdown内でコンポーネントを使う
第18回 GatsbyJSでカテゴリー機能を実装する
第19回 GatsbyJSにドロワーメニューを追加する
第20回 GatsbyJSに画像付きカードメニューを作成する
第21回 GatsbyJSにソーシャルボタンを追加する

aocory

Crieitはβバージョンで開発中です。進捗は公式Twitterアカウントをフォローして確認してください。 興味がある方は是非記事の投稿もお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

関連記事

コメント