chakra-ui.png

Chakra-UI Responsive Navigation Bar

Learn how to create a responsive navigation bar using Chakra-UI.

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 on April 25, 2021 (5 months ago) in

#chakra-ui

View Related Posts

  • Advanced Chakra UI

    chakra-ui
  • Chakra-UI Mobile Navbar (Drawer Component)

    chakra-ui

Was this snippet helpful?


Written By Benjamin Carlson

Founder coffeeclass.io

More Articles By Benjamin Carlson


Legal

Terms

Disclaimer

Privacy Policy

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

Powered by

Vercel Logo