Hamburger Menu (Chakra UI version).

Hamburger Menu (Chakra UI version).

Hamburger Menu Chakra UI version.

This is my way to create Hamburger Menu using Next.js and Chakra UI CSS framework. Check this out!

Setup

  • Create a Next.js project setup with the following syntax.
    $ npx create-next-app --example with-chakra-ui my-app

    # or

    $ yarn create-next-app --example with-chakra-ui my-app
  • Then open the project we just created into your favorite code editor.
  • Then go to the src/components folder, and open the DarkModeSwitch.js file.

Snippets Assets

Imports

  • Next we will start by importing everything we need.
import React, { useState } from 'react'
import { useColorMode, Switch, Flex, Button, IconButton } from '@chakra-ui/react'
import { HamburgerIcon, CloseIcon } from '@chakra-ui/icons'
import Link from 'next/link'

Settings the Desktop Content and Mobile Content

  • Next, wrap everything inside of a Flex element. Then, add the below code.
<Flex>
<Flex position="fixed" top="1rem" right="1rem" align="center">
  {/* Desktop */}
  <Flex>
    <Link href="/" passHref>
      <Button as="a" variant="ghost" aria-label="Home" my={5} w="100%">
        Home
      </Button>
    </Link>

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

    <Link href="/contact" passHref>
      <Button as="a" variant="ghost" aria-label="Contact" my={5} w="100%">
        Contact
      </Button>
    </Link>
  </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
  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">
    <Link href="/" passHref>
      <Button as="a" variant="ghost" aria-label="Home" my={5} w="100%">
        Home
      </Button>
    </Link>

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

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

Using useState to Open and Close Navigation

  • Now that we have content, we need a way to show it. We can use useState for this case. Before the return statement, add the following:
const [display, changeDisplay] = useState('none')
  • Now we have a variable display set initially to none, and a method changeDisplay we can use to change it.
<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! Let's add styles to the Flex.
<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 Complete Code

Here's the complete code.

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>
  )
}

Follow Me!

Github Instagram Twitter Linkedin Email