react-burger-menu is 何

# はじめに

`react-burger-menu` は簡単にバーガーメニューを作成できるReactのライブラリらしいです。
Next.jsの開発でバーガーメニュー作りたいなと思って調べたら出てきて使って見たらよかったので紹介します。

## 使い方
一応公式のREADME置いときます。
https://github.com/negomi/react-burger-menu

## 1. インストール(Installation)
以下のコマンドでインストールを行う

```
npm install react-burger-menu --save

or

yarn add react-burger-menu
```
TypeScriptを使っている方は以下のコマンドでインストール

```
npm install @types/react-burger-menu --save

or 

yarn add @types/react-burger-menu
```

## 2. 利用方法(Usage)
### アニメーション(animation)について
`react-burger-menu`では以下のようなアニメーションを選択できます。
 
・`slide`
・`stack`
・`elastic`
・`bubble`
・`push`
・`pushRotate`
・`scaleDown`
・`scaleRotate`
・`fallDown`
・`reveal`

実際のアニメーションは公式が出しているサイトで見れます。
(https://negomi.github.io/react-burger-menu/)

使用する際は, ファイル内で以下のようにimportします。

```
import { slide as Menu } from 'react-burger-menu'
```

この時, `slide`以外のアニメーションを使いたい場合は上で記述したアニメーションに適宜書き換えれば変更することができます。

### プロパティ(Properties)について
#### `Page wrapper`

ページの残りをラップする要素は以下のように`Menu`コンポーネントの後に配置し, idを一致させる。

```
<Menu pageWrapId={ "page-wrap" } />
<main id="page-wrap">
・
・
・
</main>
```


#### `Outer container`

全てのコンテンツをラップする親要素がある場合は, 親要素のidを`outerContainerId`と以下のように一致させる。

```
<div id="outer-container">
 <Menu pageWrapId={ "page-wrap" } outerContainerId={ "outer-container" } />
 <main id="page-wrap">
 ・
 ・
 ・
 </main>
</div>
```
アニメーションの種類によってこれらのプロパティを指定しなければならない場合があるので, それらを以下の表で示しました。
`slide`, `stack`, `bubble`以外は基本的に指定する感じです。

| Animation | `pageWrapId` | `outerContainerId` |
:----:|:----:|:----:
|slide |  |  |
|stack |  |  |
|elastic | ✔︎ | ✔︎ |
|bubble |  |  |
|push | ✔︎ | ✔︎ |
|pushRotate| ✔︎ | ✔︎ |
|scaleDown| ✔︎ | ✔︎ |
|scaleRotate | ✔︎ | ✔︎ |
|fallDown | ✔︎ | ✔︎ |
|reveal | ✔︎ | ✔︎ |

#### `Position`

バーガーメニューアイコンの位置を指定できます。
デフォルトではアイコンは左に配置されるようになっていますが, 、右側に配置したい場合は以下のように指定できます。

```
<Menu right />
```

#### `Width`

メニューの幅を以下のように指定できます。デフォルトは `300` です。

```
<Menu width={ 280 } />
<Menu width={ "280px" } />
<Menu width={ "20%" } />
```

#### `Open state`

メニューの開閉の状態を`isOpen`で制御します。
デフォルトは`false`です。

#### `Open menu handler`

ボタンなどを押してメニューを開く関数を渡すときに使用します。

```
<Menu onOpen={ handleOnOpen } />
```

#### `Close menu handler`

ボタンやオーバーレイ(overlay)の部分などを押したときにメニューを閉じる関数を渡す時に使用します。

```
<Menu onClose={ handleOnClose } />
```
`onOpen`と`onClose`はプロパティとして含めなくてもデフォルトで最低限の動作はしてくれます。
しかし,
`onOpen`や`onClose`を使うときは, 渡す関数内で必ず自身でメニューの開閉を処理するようにしなければなりません。

### `State change`

`onStateChange`はコールバック関数を受け取り, メニューが開いているか閉じているかを検出することができます。`onStateChange`に渡すコールバック関数の引数は, 最新の状態を保持するオブジェクトとなります。

```
let isMenuOpen = (state) => {
  return state.isOpen;
};

<Menu onStateChange={ isMenuOpen } />
```

#### `Close on Escape` 

`disableCloseOnEsc`プロパティを使用することで, Escキーを押した時にメニューが閉じる動作を無効にすることができます。これにより, レスポンシブメニューなどでメニューを常時開いておきたい場合などに便利です。

```
<Menu disableCloseOnEsc />
```

#### `Custom keydown handler`

`customOnKeyDown`プロパティは, キーを押した際のメニューの状態を細かく制御することができます。例としては, 以下のようにMenuコンポーネントのインスタンスを複数使用している場合にEscキーを一度押すだけで全てのインスタンスを閉じる(メニューを全て閉じる)機能を実装する際に役立ちます。

```
const [areMenusOpen, setAreMenusOpen] = useState(false);

const closeAllMenusOnEsc = (event) => {
  event = event || window.event;
  if (event.key === 'Escape' || event.keycode === 27) {
    setAreMenusOpen(false);
  }
};

<MenuFirst customOnKeyDown={closeAllMenusOnEsc} isOpen={areMenusOpen} />
<MenuSecond customOnKeyDown={closeAllMenusOnEsc} isOpen={areMenusOpen} />
```
※このプロパティを使用するとデフォルトのEscキーでメニューを閉じる機能が無効になるため, 
例えばshiftキーを押したときにメニューを閉じる機能を実装した場合, Escキーは機能を失います。Escキーを使用したい場合は, 自身で関数内に処理を追加で記述する必要があります。


#### `Overlay`

`noOverlay`プロパティを使用することで, デフォルトのオーバーレイ(overlay)をオフにすることができます。

```
<Menu noOverlay />
```

また, `disableOverlayClick`を使用することでオーバーレイ(overlay)を押した際のイベント(メニューが閉じるなど)を無効にすることができます。プロパティはブール値である必要があります。

```
<Menu disableOverlayClick />
<Menu disableOverlayClick={ () => shouldDisableOverlayClick() } />
```

#### `Transitions`

`noTransition`プロパティを使用することで, 全てのトランジションやアニメーションを無効にすることができます。

```
<Menu noTransition />
```

#### `Custom icons`

`customBurgerIcon`, `customCrossIcon`プロパティを使用することでデフォルトのバーガーアイコンとクロスアイコンを独自に置き換えることができます。

```
<Menu customBurgerIcon={ <img src="img/icon.svg" > } />
<Menu customCrossIcon={ <img src="img/cross-icon.svg" > } />
```
また, 各プロパティに`false`を渡すことでアイコン要素を無効にすることもできます。その場合は, ボタンなどを独自に作成して`isOpen`プロパティでメニューの開閉を制御します。

#### `Custom ID and/or classNames`

Menuコンポーネントのプロパティとして`id`と`className`を指定することができます。

```
<Menu id={ "side-bar" } className={ "my-menu" } />
```

また, メニュー全体の各要素に対してプロパティとして`className`を指定することができます。(以下のclassNameは適当に考えたものです)

```
<Menu 
  burgerButtonClassName={ "burger-button" }
  burgerBarClassName={ "burger-bars" }
  crossButtonClassName={ "cross-button" } 
  crossClassName={ "burger-cross" }
  menuClassName={ "burger-menu" }
  morphShapeClassName={ "burger-morph-shape" }
  itemListClassName={ "burger-item-list" }
  overlayClassName={ "burger-overlay" }
/>
```
また, `html`, `body`要素に対して`className`を指定することもできます。

```
<Menu htmlClassName={ "html" } />
<Menu bodyClassName={ "body" } />
```

#### `Focusing the first menu item`

デフォルトではメニューを開いた際にリストの最初の項目がフォーカスされた状態となっているため, `disableAutoFocus`プロパティを使用することで無効にすることができます。

```
<Menu disableAutoFocus />
```

#### `Custom item list element`

メニューのリストは, `nav`要素にラップされており, ナビゲーションを使用しない場合は`itemListElement`プロパティで`div`を指定します。

```
<Menu itemListElement />
```
#### `Styling`

Menuコンポーネントは内部的にスタイルやアニメーションなどの処理を行います。
以下はバーガーメニューのスタイリングの例です。

##### `CSS`
Menuコンポーネントは以下のクラスを持ちます。

```
/* バーガーボタンの位置とサイズ */
.bm-burger-button {
  position: fixed;
  width: 36px;
  height: 30px;
  left: 36px;
  top: 36px;
}

/* バーガボタンのバーのスタイル */
.bm-burger-bars {
  background: #373a47;
}

/* バーガーボタンのホバー */
.bm-burger-bars-hover {
  background: #a90000;
}

/* クロスボタンの位置とサイズ */
.bm-cross-button {
  height: 24px;
  width: 24px;
}

/* クロスボタンのカラー・形状 */
.bm-cross {
  background: #bdc3c7;
}

/*
サイドバーのラッパースタイル - アニメーションが壊れる可能性があるため触るときは注意
*/
.bm-menu-wrap {
  position: fixed;
  height: 100%;
}

/* サイドバーのスタイル */
.bm-menu {
  background: #373a47;
  padding: 2.5em 1.5em 0;
  font-size: 1.15em;
}

/* bubbleやelasticで必要なモーフの形状 */
.bm-morph-shape {
  fill: #373a47;
}

/* メニューリストのラッパースタイル*/
.bm-item-list {
  color: #b8b7ad;
  padding: 0.8em;
}

/* 個々のリストのスタイル */
.bm-item {
  display: inline-block;
}

/* オーバーレイ(overlay)のスタイリング */
.bm-overlay {
  background: rgba(0, 0, 0, 0.3);
}

```

##### `CSS in JS`
Menuコンポーネントに以下の`styles`オブジェクトを渡すことでスタイリングができます。

```
const styles = {
  bmBurgerButton: {
    position: 'fixed',
    width: '36px',
    height: '30px',
    left: '36px',
    top: '36px'
  },
  bmBurgerBars: {
    background: '#373a47'
  },
  bmBurgerBarsHover: {
    background: '#a90000'
  },
  bmCrossButton: {
    height: '24px',
    width: '24px'
  },
  bmCross: {
    background: '#bdc3c7'
  },
  bmMenuWrap: {
    position: 'fixed',
    height: '100%'
  },
  bmMenu: {
    background: '#373a47',
    padding: '2.5em 1.5em 0',
    fontSize: '1.15em'
  },
  bmMorphShape: {
    fill: '#373a47'
  },
  bmItemList: {
    color: '#b8b7ad',
    padding: '0.8em'
  },
  bmItem: {
    display: 'inline-block'
  },
  bmOverlay: {
    background: 'rgba(0, 0, 0, 0.3)'
  }
}

<Menu styles={ styles } />
```

## 最後に

なんかほぼ公式を和訳してちょっと脚色した感じなので, もし間違いなどあれば教えてい頂けますと幸いです。