アプリのマニュアルを作成するのに流行りのSSGをやりたかったのでGatsbyに挑戦してみました。CSSは使い慣れたBulmaを選択。いつも通りBulmaのサイトにあるサンプルをコピペしたが、モバイルの場合にハンバーガーメニューが動かなかった。
コピペ+JSX向けに修正
returnの内容はJSXで記載する必要があるため、下記のように書き換えた。これだけでは動かない。
- class要素をclassNameへ名称変更
- リンクをaタグからLinkタグへ書き換え
- hrやimgタグのような閉じる必要のないタグの末尾にスラッシュを追加
navigation.js
import React from "react";
import { Link } from "gatsby";
const Navigation = () => {
return (
<nav className="navbar" role="navigation" aria-label="main navigation">
<div className="navbar-brand">
<Link className="navbar-item" to="https://bulma.io">
<img
src="https://bulma.io/images/bulma-logo.png"
width="112"
height="28"
/>
</Link>
<a
role="button"
className="navbar-burger"
aria-label="menu"
aria-expanded="false"
data-target="navbarBasicExample"
>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="navbarBasicExample" className="navbar-menu">
<div className="navbar-start">
<Link className="navbar-item" to="#">Home</Link>
<Link className="navbar-item" to="#">Documentation</Link>
<div className="navbar-item has-dropdown is-hoverable">
<Link className="navbar-link" to="#">More</Link>
<div className="navbar-dropdown">
<Link className="navbar-item" to="#">About</Link>
<Link className="navbar-item" to="#">Jobs</Link>
<Link className="navbar-item" to="#">Contact</Link>
<hr className="navbar-divider" />
<Link className="navbar-item" to="#">Report an issue</Link>
</div>
</div>
</div>
<div className="navbar-end">
<div className="navbar-item">
<div className="buttons">
<Link className="button is-primary" to="#">
<strong>Sign up</strong>
</Link>
<Link className="button is-light" to="#">Log in</Link>
</div>
</div>
</div>
</div>
</nav>
);
};
export default Navigation;
修正した内容
ハンバーガーメニューをタップした時にメニューが開くよう明示的にコーディングしてやる必要がある。
やったことは下記の通り。
- useStateでタップの状態を設定
- ハンバーガーメニューのaタグにタップイベントで上記のステートを変更する処理を追加。同時にclassNameでisActiveがtrueであれば
is-active
を追加する -
navbar-menu
が設定されたdivタグに、モバイルの場合is-active
が付与されるように設定
2についてはNavbar burger、3についてはNavbar menuに説明がある。しっかりとドキュメントを読めば書いてあった。
navigation.js
import React from "react";
import { Link } from "gatsby";
const Navigation = () => {
const [isActive, setisActive] = React.useState(false);
return (
<nav className="navbar" role="navigation" aria-label="main navigation">
<div className="navbar-brand">
<Link className="navbar-item" to="https://bulma.io">
<img
src="https://bulma.io/images/bulma-logo.png"
width="112"
height="28"
/>
</Link>
<a
onClick={() => {
setisActive(!isActive)
}}
role="button"
className={`navbar-burger burger ${isActive ? 'is-active' : ''}`}
aria-label="menu"
aria-expanded="false"
data-target="navbarBasicExample"
>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="navbarBasicExample" className={`navbar-menu ${isActive ? 'is-active' : ''}`}>
<div className="navbar-start">
<Link className="navbar-item" to="#">Home</Link>
<Link className="navbar-item" to="#">Documentation</Link>
<div className="navbar-item has-dropdown is-hoverable">
<Link className="navbar-link" to="#">More</Link>
<div className="navbar-dropdown">
<Link className="navbar-item" to="#">About</Link>
<Link className="navbar-item" to="#">Jobs</Link>
<Link className="navbar-item" to="#">Contact</Link>
<hr className="navbar-divider" />
<Link className="navbar-item" to="#">Report an issue</Link>
</div>
</div>
</div>
<div className="navbar-end">
<div className="navbar-item">
<div className="buttons">
<Link className="button is-primary" to="#">
<strong>Sign up</strong>
</Link>
<Link className="button is-light" to="#">Log in</Link>
</div>
</div>
</div>
</div>
</nav>
);
};
export default Navigation;
参考