どうもこんにちは、たくびー(@takubii)です。
今回はReactでハンバーガーメニューの実装を行ったので備忘録として記事にしたいと思います。
昨今だとライブラリなどであるかもしれませんが、今回はライブラリを使わずReactの機能とWeb標準のみで実装しています。
簡単に説明
ロジックが多いですが、少し凝ったことをしていて、アニメーションが始まった時にサイドバーが出現し、終わった時に消えるようにしています。
サイドバー展開中はコンテンツにオーバーレイを被せることでコンテンツへのクリックを制限しています。
また、オーバーレイ自体に触るとサイドバーが消えるようになっているので少しユーザーフレンドリーかなと思います。
実装
アイコンはBootstrap Iconを使用しています。
jsx
export const App = () => {
const [menuOpen, setMenuOpen] = useState(false);
const toggleMenu = () => {
const sidebar = document.querySelector('.sidebar');
if (!menuOpen) {
sidebar.style.display = 'block';
setTimeout(() => {
setMenuOpen(true);
}, 10);
} else {
setMenuOpen(false);
}
}
const closeMenu = () => {
setMenuOpen(false);
}
useEffect(() => {
const sidebar = document.querySelector('.sidebar');
const handleTransitionEnd = () => {
if (!menuOpen) {
sidebar.style.display = 'none';
}
};
sidebar.addEventListener('transitionend', handleTransitionEnd);
return () => {
sidebar.removeEventListener('transitionend', handleTransitionEnd);
};
}, [menuOpen]);
<div className='header'>
<div className='hamburger-menu' onClick={toggleMenu}>
<i className='bi bi-list'></i>
</div>
</div>
{menuOpen && <div className='overlay' onClick={closeMenu}></div>}
<div className={`sidebar ${menuOpen ? 'open' : ''}`} style={{ display: 'none' }}>
<div className='hamburger-menu-close' onClick={toggleMenu}>
<i className='bi bi-x-lg'></i>
</div>
<p>test1</p>
<p>test2</p>
<p>test3</p>
</div>
<div className='contents'>
</div>
}
css
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 999;
}
.sidebar {
position: fixed;
top: 0;
width: 250px;
height: 100%;
background: white;
transform: translateX(-100%);
transition: transform 0.3s ease-in-out;
z-index: 1000;
}
.sidebar.open {
transform: translateX(0);
}
.sidebar .hamburger-menu-close {
display: inline-block;
}
終わりに
横から出てくるタイプのハンバーガーメニューはいろいろな場所で目にしますが、実際に実装してみると結構手間がかかるなと思いました。
車輪の再発明になっているかもしれませんが、もし実装で困っている方の助けになれば幸いです。
それでは今回はこのあたりで締めたいと思います。
ここまで読んでいただきありがとうございます。
また機会があればお会いしましょう。