- development
- typescript
- react
- hooks
- bulma
Aug 16, 2020 @ 7:05 AM
Aug 22, 2020 @ 10:12 PM
Overview
Summary
Here is the Navbar documentation from Bulma. When I copied the example code from the documentation and clicked the menu, nothing happened.
I learned that you need to add the is-active
className to both the navbar-burger and the navbar-menu when the hamburger menu is clicked for anything to happen. We can easily implement this using the useState
hook.
Example
You can view the full code for my header.tsx
file here.
Add the useState
hook
Let's add a new state variable called active
to manage the hamburger menu state in our Component.
import React, { useState } from "react";
const Header = () => {
const [active, setActive] = useState(false);
};
Animate the burger and show the menu
Quick note about the navbar-burger
.
The
navbar-burger
has to contain three empty span tags in order to visualize the hamburger lines or the cross (when active). | Source
Now let's control the states of these elements with our state variable. If the is-active
className is added on the navbar-burger
, the burger will animate into a cross. Setting the is-active
className on the navbar-menu
will make the menu visible. We can add it using template literals like so:
{
/* The navbar-burger */
}
<a
role="button"
className={`navbar-burger burger ${active && "is-active"}`}
onClick={() => {
setActive(!active);
}}
>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>;
{
/* The navbar-menu */
}
<div className={`navbar-menu ${active && "is-active"}`}>
<div className="navbar-start">
<Link to="/til" className="navbar-item">
Today I Learned
</Link>
</div>
</div>;
Add the onClick
function
Don't forget to add the onClick
function to the navbar-burger
so that we can set the active
state when it is clicked.
And thats it! 🥳
Full source code
import React, { ReactElement, useState } from "react";
import { Link } from "gatsby";
interface Props {
siteTitle: string;
}
const Header = ({ siteTitle = "Home" }: Props): ReactElement => {
const [active, setActive] = useState(false);
return (
<header>
<nav role="navigation" aria-label="main navigation">
<div className="navbar-brand">
{/* Main links */}
<Link to="/" className="navbar-item">
{siteTitle}
</Link>
<Link to="/til" className="is-hidden-touch navbar-item">
Today I Learned
</Link>
{/* The navbar-burger */}
<a
role="button"
className={`navbar-burger burger ${active && "is-active"}`}
aria-label="menu"
aria-expanded="false"
onClick={() => {
setActive(!active);
}}
>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
{/* The navbar-menu */}
{active && (
<div
className={`navbar-menu has-background-black-bis ${
active && "is-active"
}`}
>
<div className="navbar-start">
<Link to="/til" className="navbar-item">
Today I Learned
</Link>
</div>
</div>
)}
</nav>
</header>
);
};
export default Header;