- Diterbitkan pada
Hamburger Menu (TailwindCSS & ChakraUI).
- Penulis
- Nama
- Naufal Akbar Nugroho
Table of Contents
Hamburger Menu (TailwindCSS).
Ini adalah cara saya membuat Hamburger Menu
menggunakan kerangka kerja CSS React.js
dan TailwindCSS
.
Memulai
- Buat setup proyek
React.js
dengan sintaks berikut.
cmd
$ npx create-react-app my-app
# atau
$ yarn create-react-app my-app
- Siapkan TailwindCSS. Baca selengkapnya tentang langkah-langkahnya
- Kemudian buka proyek yang baru saja kita buat ke
editor kode
favorit Anda. - Selanjutnya install package yaitu
react-router-dom
, berikut sintaksnya. Selengkapnya tentang react-router-dom
cmd
$ npm install react-router-dom@6
#atau
$ yarn add react-router-dom@6
- Kemudian masuk ke folder
src
, dan buat foldercomponent
, lalu buat fileNavbars.js
.
Impor
- Selanjutnya kita akan mulai dengan mengimpor semua yang kita butuhkan.
src/components/Navbars.js
import React, { useState } from "react";
import { Link } from "react-router-dom";
Menggunakan useState untuk Membuka dan Menutup Navigasi
- Sekarang kita memiliki konten, kita perlu cara untuk menunjukkannya. Kita dapat menggunakan
useState
untuk kasus ini. Sebelum pernyataan return, tambahkan berikut ini:
src/components/Navbars.js
const [isMenuOpen, setIsMenuOpen] = useState(false);
Mengatur Konten Desktop dan Konten Seluler
- Selanjutnya kita membuat komponen Navbars. Ikuti kode di bawah ini.
src/components/Navbars.js
<div className="py-8">
<div className="bg-blue-800 fixed left-0 right-0 top-0 z-50 shadow-lg">
<div className="px-4 py-5 mx-auto sm:max-w-xl md:max-w-full lg:max-w-screen-xl md:px-24 lg:px-8">
<div className="relative flex items-center justify-between">
<Link to="/" className="inline-flex items-center">
<span className="ml-2 text-xl font-medium text-white">Naufal Akbar</span>
</Link>
<ul className="flex items-center hidden space-x-8 lg:flex">
<li>
<Link to="/" className="tracking-wide text-gray-100 transition-colors duration-200 hover:text-gray-300">
Home
</Link>
</li>
<li>
<Link to="/about" className="tracking-wide text-gray-100 transition-colors duration-200 hover:text-gray-300">
About
</Link>
</li>
<li>
<Link to="/skill" className="tracking-wide text-gray-100 transition-colors duration-200 hover:text-gray-300">
Skills
</Link>
</li>
<li>
<Link to="/project" className="tracking-wide text-gray-100 transition-colors duration-200 hover:text-gray-300">
Project
</Link>
</li>
<li>
<Link to="/blog" className="tracking-wide text-gray-100 transition-colors duration-200 hover:text-gray-300">
Blog
</Link>
</li>
<li>
<Link to="/contact" className="tracking-wide text-gray-100 transition-colors duration-200 hover:text-gray-300">
Contact
</Link>
</li>
</ul>
<div className="lg:hidden">
<button aria-label="Open Menu" title="Open Menu" className="p-2 -mr-1 transition duration-200 roundedfocus:outline-none focus:shadow-outline" onClick={() => setIsMenuOpen(true)}>
<svg className="w-5 text-gray-600" viewBox="0 0 24 24">
<path fill="#ffffff" d="M23,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h22c0.6,0,1,0.4,1,1S23.6,13,23,13z" />
<path fill="#ffffff" d="M23,6H1C0.4,6,0,5.6,0,5s0.4-1,1-1h22c0.6,0,1,0.4,1,1S23.6,6,23,6z" />
<path fill="#ffffff" d="M23,20H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h22c0.6,0,1,0.4,1,1S23.6,20,23,20z" />
</svg>
</button>
{isMenuOpen && (
<div className="absolute top-0 left-0 w-full z-10">
<div className="p-5 bg-gray-900 border rounded shadow-sm">
<div className="flex items-center justify-between mb-4">
<div>
<Link to="/" aria-label="Company" title="Company" className="inline-flex items-center">
<span className="ml-2 text-xl font-bold tracking-wide text-white">Naufal Akbar</span>
</Link>
</div>
<div>
<button
aria-label="Close Menu"
title="Close Menu"
className="p-2 -mt-2 -mr-2 transition duration-200 rounded hover:bg-gray-200 focus:bg-gray-200focus:outline-none focus:shadow-outline"
onClick={() => setIsMenuOpen(false)}
>
<svg className="w-5 text-gray-600" viewBox="0 0 24 24">
<path
fill="currentColor"
d="M19.7,4.3c-0.4-0.4-1-0.4-1.4,0L12,10.6L5.7,4.3c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l6.3,6.3l-6.3,6.3 c-0.4,0.4-0.4,1,0,1.4C4.5,19.9,4.7,20,5,20s0.5-0.1,0.7-0.3l6.3-6.3l6.3,6.3c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3 c0.4-0.4,0.4-1,0-1.4L13.4,12l6.3-6.3C20.1,5.3,20.1,4.7,19.7,4.3z"
/>
</svg>
</button>
</div>
</div>
<nav>
<ul className="space-y-4">
<li>
<Link to="/" className="font-medium tracking-wide text-gray-400 transition-colors duration-200hover:text-primary-focus">
Home
</Link>
</li>
<li>
<Link to="/about" className="font-medium tracking-wide text-gray-400 transition-colors duration-200hover:text-primary-focus">
About
</Link>
</li>
<li>
<Link to="/skill" className="font-medium tracking-wide text-gray-400 transition-colors duration-200hover:text-primary-focus">
Skills
</Link>
</li>
<li>
<Link to="/project" className="font-medium tracking-wide text-gray-400 transition-colors duration-200hover:text-primary-focus">
Project
</Link>
</li>
<li>
<Link to="/blog" className="font-medium tracking-wide text-gray-400 transition-colors duration-200hover:text-primary-focus">
Blog
</Link>
</li>
<li>
<Link to="/contact" className="font-medium tracking-wide text-gray-400 transition-colors duration-200hover:text-primary-focus">
Contact
</Link>
</li>
</ul>
</nav>
</div>
</div>
)}
</div>
</div>
</div>
</div>
</div>
Kode Lenkap
Berikut kode lengkapnya.
src/components/Navbars.js
import React, { useState } from "react";
import { Link } from "react-router-dom";
function Navbars() {
const [isMenuOpen, setIsMenuOpen] = useState(false);
return (
<div className="py-8">
<div className="bg-blue-800 fixed left-0 right-0 top-0 z-50 shadow-lg">
<div className="px-4 py-5 mx-auto sm:max-w-xl md:max-w-full lg:max-w-screen-xl md:px-24 lg:px-8">
<div className="relative flex items-center justify-between">
<Link to="/" className="inline-flex items-center">
<span className="ml-2 text-xl font-medium text-white">Naufal Akbar</span>
</Link>
<ul className="flex items-center hidden space-x-8 lg:flex">
<li>
<Link to="/" className="tracking-wide text-gray-100 transition-colors duration-200 hover:text-gray-300">
Home
</Link>
</li>
<li>
<Link to="/about" className="tracking-wide text-gray-100 transition-colors duration-200 hover:text-gray-300">
About
</Link>
</li>
<li>
<Link to="/skill" className="tracking-wide text-gray-100 transition-colors duration-200 hover:text-gray-300">
Skills
</Link>
</li>
<li>
<Link to="/project" className="tracking-wide text-gray-100 transition-colors duration-200 hover:text-gray-300">
Project
</Link>
</li>
<li>
<Link to="/blog" className="tracking-wide text-gray-100 transition-colors duration-200 hover:text-gray-300">
Blog
</Link>
</li>
<li>
<Link to="/contact" className="tracking-wide text-gray-100 transition-colors duration-200 hover:text-gray-300">
Contact
</Link>
</li>
</ul>
<div className="lg:hidden">
<button aria-label="Open Menu" title="Open Menu" className="p-2 -mr-1 transition duration-200 rounded focus:outline-none focus:shadow-outline" onClick={() => setIsMenuOpen(true)}>
<svg className="w-5 text-gray-600" viewBox="0 0 24 24">
<path fill="#ffffff" d="M23,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h22c0.6,0,1,0.4,1,1S23.6,13,23,13z" />
<path fill="#ffffff" d="M23,6H1C0.4,6,0,5.6,0,5s0.4-1,1-1h22c0.6,0,1,0.4,1,1S23.6,6,23,6z" />
<path fill="#ffffff" d="M23,20H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h22c0.6,0,1,0.4,1,1S23.6,20,23,20z" />
</svg>
</button>
{isMenuOpen && (
<div className="absolute top-0 left-0 w-full z-10">
<div className="p-5 bg-gray-900 border rounded shadow-sm">
<div className="flex items-center justify-between mb-4">
<div>
<Link to="/" aria-label="Company" title="Company" className="inline-flex items-center">
<span className="ml-2 text-xl font-bold tracking-wide text-white">Naufal Akbar</span>
</Link>
</div>
<div>
<button
aria-label="Close Menu"
title="Close Menu"
className="p-2 -mt-2 -mr-2 transition duration-200 rounded hover:bg-gray-200 focus:bg-gray-200 focus:outline-none focus:shadow-outline"
onClick={() => setIsMenuOpen(false)}
>
<svg className="w-5 text-gray-600" viewBox="0 0 24 24">
<path
fill="currentColor"
d="M19.7,4.3c-0.4-0.4-1-0.4-1.4,0L12,10.6L5.7,4.3c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l6.3,6.3l-6.3,6.3 c-0.4,0.4-0.4,1,0,1.4C4.5,19.9,4.7,20,5,20s0.5-0.1,0.7-0.3l6.3-6.3l6.3,6.3c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3 c0.4-0.4,0.4-1,0-1.4L13.4,12l6.3-6.3C20.1,5.3,20.1,4.7,19.7,4.3z"
/>
</svg>
</button>
</div>
</div>
<nav>
<ul className="space-y-4">
<li>
<Link to="/" className="font-medium tracking-wide text-gray-400 transition-colors duration-200 hover:text-primary-focus">
Home
</Link>
</li>
<li>
<Link to="/about" className="font-medium tracking-wide text-gray-400 transition-colors duration-200 hover:text-primary-focus">
About
</Link>
</li>
<li>
<Link to="/skill" className="font-medium tracking-wide text-gray-400 transition-colors duration-200 hover:text-primary-focus">
Skills
</Link>
</li>
<li>
<Link to="/project" className="font-medium tracking-wide text-gray-400 transition-colors duration-200 hover:text-primary-focus">
Project
</Link>
</li>
<li>
<Link to="/blog" className="font-medium tracking-wide text-gray-400 transition-colors duration-200 hover:text-primary-focus">
Blog
</Link>
</li>
<li>
<Link to="/contact" className="font-medium tracking-wide text-gray-400 transition-colors duration-200 hover:text-primary-focus">
Contact
</Link>
</li>
</ul>
</nav>
</div>
</div>
)}
</div>
</div>
</div>
</div>
</div>
);
}
export default Navbars;
Hamburger Menu (ChakraUI).
Ini adalah cara saya membuat Hamburger Menu
menggunakan framework CSS Next.js
dan Chakra UI
.
Memulai
- Buat pengaturan proyek
Next.js
dengan sintaks berikut.
cmd
$ npx create-next-app --example with-chakra-ui my-app
# atau
$ yarn create-next-app --example with-chakra-ui my-app
- Kemudian buka proyek yang baru saja kita buat ke
editor kode
favorit Anda. - Kemudian buka folder
src/components
, dan buka fileDarkModeSwitch.js
.
Impor
- Selanjutnya kita akan mulai dengan mengimpor semua yang kita butuhkan.
src/components/DarkModeSwitch.js
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'
Mengatur Konten Desktop dan Konten Seluler
- Selanjutnya, bungkus semuanya di dalam elemen
Flex
. Kemudian, tambahkan kode di bawah ini.
src/components/DarkModeSwitch.js
<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>
Menggunakan useState untuk Membuka dan Menutup Navigasi
- Sekarang kita memiliki konten, kita perlu cara untuk menunjukkannya. Kita dapat menggunakan
useState
untuk kasus ini. Sebelum pernyataan return, tambahkan berikut ini:
src/components/DarkModeSwitch.js
const [display, changeDisplay] = useState('none')
- Sekarang kita memiliki tampilan variabel yang awalnya disetel ke none, dan metode
changeDisplay
dapat kita gunakan untuk mengubahnya.
src/components/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
/>
- Sekarang kita harus bisa membuka dan menutup menu! Mari tambahkan gaya ke
Flex
.
src/components/DarkModeSwitch.js
<Flex
w="100vw"
display={display}
bgColor="gray.50"
zIndex={20}
h="100vh"
pos="fixed"
top="0"
left="0"
overflowY="auto"
flexDir="column"
>
Styling penting yang kita tambahkan:
- Mengatur ketinggian ke 100vh
- Mengatur lebar ke 100vw
- Mengatur posisi ke tetap
- Membuat z-index 20 jadi diatas konten halaman
- Mengatur atas dan kiri ke 0
- Mengatur tampilan ke variabel tampilan dinamis kita.
Kode Lengkap
Berikut kode lengkapnya.
src/components/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>
)
}