はじめに
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 } />
最後に
なんかほぼ公式を和訳してちょっと脚色した感じなので, もし間違いなどあれば教えてい頂けますと幸いです。