Chakra-UI Responsive Navigation Bar

Chakra-UI Responsive Navigation Bar

4 min read · 790 words · Shared April 25, 2021 by

Article Summary: Create a responsive navigation bar using Chakra-UI. Mobile responsive, add animation using framer motion.

Introduction

If you are familiar with Bootstrap, you know how easy it is to create a responsive nav-bar. In Chakra-UI, there is no built in, out of the box solution. In this snippet, we will create a responsive nav-bar component that you can use in your React app.

Setup

We will be using Next.js in this example but it works for any react based framework. Navigate to the Next.js GitHub repo and clone their starter example using Chakra-UI. If you don't want to leave this page the command is:

yarn create next-app --example with-chakra-ui with-chakra-ui-app

Open this in your preferred IDE - mine is VSCode. Inside of src/components, open up the DarkModeSwitch component. This is the only file we will be modifying.

Imports

We will start by importing everything we need.

DarkModeSwitch.js
import { useState } from 'react'
import {
  useColorMode,
  Switch,
  Flex,
  Button,
  IconButton
} from '@chakra-ui/react'
import { HamburgerIcon, CloseIcon } from '@chakra-ui/icons'
import NextLink from 'next/link'

Adding Desktop Content

First, wrap everything inside of a Flex element. Then, add the below code.

DarkModeSwitch.js
<Flex>
<Flex position="fixed" top="1rem" right="1rem" align="center">
  {/* Desktop */}
  <Flex>
    <NextLink href="/" passHref>
      <Button as="a" variant="ghost" aria-label="Home" my={5} w="100%">
        Home
      </Button>
    </NextLink>

    <NextLink href="/about" passHref>
      <Button as="a" variant="ghost" aria-label="About" my={5} w="100%">
        About
      </Button>
    </NextLink>

    <NextLink href="/contact" passHref>
      <Button as="a" variant="ghost" aria-label="Contact" my={5} w="100%">
        Contact
      </Button>
    </NextLink>
  </Flex>

  {/* Mobile */}
  <IconButton
    aria-label="Open Menu"
    size="lg"
    mr={2}
    icon={<HamburgerIcon />}
    onClick={}
  />
  <Switch color="green" isChecked={isDark} onChange={toggleColorMode} />
</Flex>
{/* Mobile Content */}
</Flex>

Adding Mobile Content

This is simply our desktop nav bar. We will add the mobile content below the comment. Let's do that now.

DarkModeSwitch.js
{/* Code above */}

{/* Mobile Content */}
<Flex
  bgColor="gray.50"
  overflowY="auto"
  flexDir="column"
>
  <Flex justify="flex-end">
    <IconButton
      mt={2}
      mr={2}
      aria-label="Open Menu"
      size="lg"
      icon={<CloseIcon />}
      onClick={}
    />
  </Flex>

  <Flex flexDir="column" align="center">
    <NextLink href="/" passHref>
      <Button as="a" variant="ghost" aria-label="Home" my={5} w="100%">
        Home
      </Button>
    </NextLink>

    <NextLink href="/about" passHref>
      <Button as="a" variant="ghost" aria-label="About" my={5} w="100%">
        About
      </Button>
    </NextLink>

    <NextLink href="/contact" passHref>
      <Button as="a" variant="ghost" aria-label="Contact" my={5} w="100%">
        Contact
      </Button>
    </NextLink>
  </Flex>
</Flex>

Now that we have content, we need a way to show it. We can use useState for this. Before the return statement, add the following:

DarkModeSwitch.js
const [display, changeDisplay] = useState('none')

We now have a variable display set initially to none, and a method changeDisplay we can use to change it.

Let's add this to our code. Note, I am only writing the components that we are changing below.

DarkModeSwitch.js
<IconButton
          aria-label="Open Menu"
          size="lg"
          mr={2}
          icon={
            <HamburgerIcon />
          }
          onClick={() => changeDisplay('flex')} // added line
        />

<Flex
  display={display} // added line
  bgColor="gray.50"
  overflowY="auto"
  flexDir="column"
>

<IconButton
            mt={2}
            mr={2}
            aria-label="Open Menu"
            size="lg"
            icon={
              <CloseIcon />
            }
            onClick={() => changeDisplay('none')} // added line
          />

Now we should be able to open and close the menu! It looks a bit messy though. Let's add styles to the Flex.

DarkModeSwitch.js
<Flex
  w="100vw"
  display={display}
  bgColor="gray.50"
  zIndex={20}
  h="100vh"
  pos="fixed"
  top="0"
  left="0"
  overflowY="auto"
  flexDir="column"
>

The important styles we added:

  • Setting the height to 100vh
  • Setting the width to 100vw
  • Setting the position to fixed
  • Making z-index 20 so it is above the page content
  • Setting top and left to 0
  • Setting the display to our dynamic display variable.

The rest is subjective.

Completed Code

And that's it! Here is the completed code:

DarkModeSwitch.js
import { useState } from 'react'
import {
  useColorMode,
  Switch,
  Flex,
  Button,
  IconButton
} from '@chakra-ui/react'
import { HamburgerIcon, CloseIcon } from '@chakra-ui/icons'
import NextLink from 'next/link'


export const DarkModeSwitch = () => {
  const { colorMode, toggleColorMode } = useColorMode()
  const isDark = colorMode === 'dark'
  const [display, changeDisplay] = useState('none')
  return (
    <Flex>
      <Flex
        position="fixed"
        top="1rem"
        right="1rem"
        align="center"
      >
        {/* Desktop */}
        <Flex
          display={['none', 'none', 'flex','flex']}
        >
          <NextLink href="/" passHref>
            <Button
              as="a"
              variant="ghost"
              aria-label="Home"
              my={5}
              w="100%"
            >
              Home
                    </Button>
          </NextLink>

          <NextLink href="/about" passHref>
            <Button
              as="a"
              variant="ghost"
              aria-label="About"
              my={5}
              w="100%"
            >
              About
                    </Button>
          </NextLink>

          <NextLink href="/contact" passHref>
            <Button
              as="a"
              variant="ghost"
              aria-label="Contact"
              my={5}
              w="100%"
            >
              Contact
                    </Button>
          </NextLink>
        </Flex>

        {/* Mobile */}
        <IconButton
          aria-label="Open Menu"
          size="lg"
          mr={2}
          icon={
            <HamburgerIcon />
          }
          onClick={() => changeDisplay('flex')}
          display={['flex', 'flex', 'none', 'none']}
        />
        <Switch
          color="green"
          isChecked={isDark}
          onChange={toggleColorMode}
        />
      </Flex>

      {/* Mobile Content */}
      <Flex
        w='100vw'
        display={display}
        bgColor="gray.50"
        zIndex={20}
        h="100vh"
        pos="fixed"
        top="0"
        left="0"
        zIndex={20}
        overflowY="auto"
        flexDir="column"
      >
        <Flex justify="flex-end">
          <IconButton
            mt={2}
            mr={2}
            aria-label="Open Menu"
            size="lg"
            icon={
              <CloseIcon />
            }
            onClick={() => changeDisplay('none')}
          />
        </Flex>

        <Flex
          flexDir="column"
          align="center"
        >
          <NextLink href="/" passHref>
            <Button
              as="a"
              variant="ghost"
              aria-label="Home"
              my={5}
              w="100%"
            >
              Home
                    </Button>
          </NextLink>

          <NextLink href="/about" passHref>
            <Button
              as="a"
              variant="ghost"
              aria-label="About"
              my={5}
              w="100%"
            >
              About
                    </Button>
          </NextLink>

          <NextLink href="/contact" passHref>
            <Button
              as="a"
              variant="ghost"
              aria-label="Contact"
              my={5}
              w="100%"
            >
              Contact
            </Button>
          </NextLink>
        </Flex>
      </Flex>
    </Flex>
  )
}

Published April 25, 2021

Related Tags

    #chakra-ui

Related Posts

Chakra UI Menu Dropdown on Hover · October 27, 2021
Build A Todo Web App Using Next.js, Firebase, Chakra UI + React Hooks · September 26, 2021
Advanced Chakra UI · August 29, 2021
Chakra-UI Mobile Navbar (Drawer Component) · August 2, 2021

Email Newsletter

On This Page

Introduction

Setup

Imports

Adding Desktop Content

Adding Mobile Content

Using useState To Open And Close Navigation

Completed Code

View Related Posts

October 27, 2021

chakra-ui.png

Chakra UI Menu Dropdown on Hover

September 26, 2021

firebase.png
Build A Todo Web App Using Next.js, Firebase, Chakra UI + React Hooks

Build A Todo Web App Using Next.js, Firebase, Chakra UI + React Hooks

August 29, 2021

chakra-ui.png

Advanced Chakra UI

August 2, 2021

chakra-ui.png

Chakra-UI Mobile Navbar (Drawer Component)


Loading author data...

    Legal

    Terms

    Disclaimer

    Privacy Policy


    Carlson Technologies Logo© Copyright 2021 - 2022, Carlson Technologies LLC. All Rights Reserved.