BlogWorkAboutFree ToolsNewsletter
BlogWorkAboutFree ToolsNewsletter
All articles

Create a responsive NavBar React component with Chakra UI

Build a fully-responsive NavBar React Js component for your landing page's header section with Chakra UI v1.0.

Written by Jim Raptis

Dec 17, 2020 • 5 min

Create a responsive NavBar React component with Chakra UI
📖
TLDR: It's a step-by-step guide to building a Chakra UI v1.0 fully-responsive NavBar (aka Header or Top Navigation bar) React Js component for your landing page header section.

✏️ EDITED TO SUPPORT VERSION 1.0

For impatient folks (like me), you can 🎁 Grab the Github repository right now.

Every landing page needs a robust navigation bar (or header) component that adapts to all the different displays.

In this tutorial, we'll build together a NavBar component using the Chakra UI library in React.

Installation

We'll create a new project using create-react-app and name it header-chakra-ui (or anything).

npx create-react-app header-chakra-ui
cd header-chakra-ui

Next, we'll install the Chakra UI library and its dependencies.

npm i @chakra-ui/react @emotion/react @emotion/styled framer-motion

# or

yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion

For setting up the Chakra UI with React we'll need its ChakraProvider and optionally a custom theme. You can check my previous article about the complete installation.

GRAB THE 10% OFFER FOR ODIN TEMPLATE
GRAB THE 10% OFFER FOR ODIN TEMPLATE

Define the variants

We need three different variants for our NavBar components. One for each of the main device sizes (mobile, tablet, desktop).

notion image

A good practice, I usually follow before jumping into coding, is to separate the individual parts (or components) that compose the design.

In the specific case, we'll need three basic sub-components:

  1. The Logo
  1. The MenuToggle button\\ (which is not visible on the desktop version), and
  1. The MenuLinks are distributed horizontally on desktop and tablet screens and vertically on mobiles.

To help you visualize this process with more clarity, I highlighted the components in the image below.

notion image

To implement these 3 variants, we'll use the Chakra UI responsive styles. Learn how they work at the official Chakra UI docs.

Create the Logo component

To simplify the tutorial, I add a Text component as a Logo and wrap it with a Box. But you can add an Image or an SVG icon as well.

import React from "react"
import { Box, Text } from "@chakra-ui/react"

export default function Logo(props) {
  return (
    <Box {...props}>
      <Text fontSize="lg" fontWeight="bold">
        Logo
      </Text>
    </Box>
  )
}

Create the MenuToggle button

The MenuToggle button is the button at the top right corner of our interface. Its' purpose is to toggle the visibility of the MenuLink component for mobile and tablet devices.

When the menu is open, we need to show the close icon. When the menu is closed, we must show the menu icon.

Also, we need to set the display attribute to none for screens larger than the md breakpoint (desktop devices).

import React from "react"
import { Box } from "@chakra-ui/react"

const MenuToggle = ({ toggle, isOpen }) => {
  return (
    <Box display={{ base: "block", md: "none" }} onClick={toggle}>
      {isOpen ? <CloseIcon /> : <MenuIcon />}
    </Box>
  )
}

I highly recommended installing the react-icons library to add the two icons into your application. Otherwise, we can

Since, the isOpen variable and the toggle function need to be accessible by the parent component as well (conditionally render the MenuLinks), we define it there and pass them as props to the MenuToggle component.

const Header = () => {
  const [isOpen, setIsOpen] = React.useState(false)

  const toggle = () => setIsOpen(!isOpen)

  return(
    ...
    <MenuToggle toggle={toggle} isOpen={isOpen}
    ...
  )
}

Build the MenuLinks components

It's the part of the NavBar that includes the navigation links and CTA button(s).

To make it robust, we need to create another sub-component, the MenuItem component and fine-tune the styling props of the container.

The MenuItem is a simple component that wraps the passed child with a Link component. For this tutorial, I use the Link component from Chakra UI. But you may use the Link component from your desired framework/library eg. Next.js, Gatsby, react-router.

const MenuItem = ({ children, isLast, to = "/", ...rest }) => {
  return (
    <Link href={to}>
      <Text display="block" {...rest}>
        {children}
      </Text>
    </Link>
  )
}

Then, we need to stack the MenuItem components horizontally or vertically, depending on the active screen size.

To achieve this tricky goal, we use the Stack component that automatically adjusts the spacing between its children.

<Stack
  spacing={8}
  align="center"
  justify={["center", "space-between", "flex-end", "flex-end"]}
  direction={["column", "row", "row", "row"]}
  pt={[4, 4, 0, 0]}
>
  <MenuItem to="/">Home</MenuItem>
  <MenuItem to="/how">How It Works</MenuItem>
  ...
</Stack>

As you can see, we adjust its direction and justify properties according to our desired breakpoints.

The final step here is to wrap the Stack component with a Box. The goal here is to force the MenuLinks component to a new line by changing the display and flex-basis CSS rules on mobile and tablet screens.

<Box
  display={{ base: isOpen ? "block" : "none", md: "block" }}
  flexBasis={{ base: "100%", md: "auto" }}
>
  ...
</Box>

And the NavBarContainer

Basically, it's the component that wraps everything else.

You can tweak the background and text color of the NavBar, add padding around it!

The space-between attribute of the Flex component makes sure content will be aligned on the edges eg. Logo on the left and Menu on the right.

const NavBarContainer = ({ children, ...props }) => {
  return (
    <Flex
      as="nav"
      align="center"
      justify="space-between"
      wrap="wrap"
      w="100%"
      mb={8}
      p={8}
      bg={["primary.500", "primary.500", "transparent", "transparent"]}
      color={["white", "white", "primary.700", "primary.700"]}
      {...props}
    >
      {children}
    </Flex>
  )
}

And you have a robust, fully-responsive NavBar component for your landing page or application.

Sum up

The final NavBar component looks pretty simple and clean, huh?!

const NavBar = (props) => {
  const [isOpen, setIsOpen] = React.useState(false)

  const toggle = () => setIsOpen(!isOpen)

  return (
    <NavBarContainer {...props}>
      <Logo
        w="100px"
        color={["white", "white", "primary.500", "primary.500"]}
      />
      <MenuToggle toggle={toggle} isOpen={isOpen} />
      <MenuLinks isOpen={isOpen} />
    </NavBarContainer>
  )
}

🎁 Grab the Github repository

Don't miss out on the upcoming exciting posts about Chakra UI by subscribing to my newsletter.

If you liked this post, you can follow me on Twitter where I share daily tips about bootstraping, product development, and UI/UX design tips.

More articles like this:

Jim Raptis

© 2022