ReactHustle

How to Create a Responsive Navbar in React with TailwindCSS + DaisyUI

Jasser Mark Arioste

Jasser Mark Arioste

How to Create a Responsive Navbar in React with TailwindCSS + DaisyUI

In this tutorial, I'll show you how to easily implement a responsive navbar layout in react using tailwindcss and DaisyUI.

What is TailwindCSS? #

Tailwind CSS is an open source CSS framework. The main feature of this library is that, unlike other CSS frameworks like Bootstrap, it does not provide a series of predefined classes for elements such as buttons or tables. Instead, it creates a list of "utility" CSS classes that can be used to style each element by mixing and matching
- wikipedia.org

While tailwindcss can be used to create components in any imaginable way, the weakness is its low level classes sometimes makes it hard for beginners to create a consistent ui. And that's where daisyUI comes in!

What is DaisyUI? #

DaisyUI is a high-level component library for tailwindcss. While tailwindcss uses low level classes, DaisyUI uses high level classes to build components, some examples are btn, modal, dropdown, badge, etc. We can still use the low level classes provided by tailwind if we want to tweak the components from daisyUI. I think that this combination of low-level classes (tailwind) + high-level classes (daisyUI) makes building components a lot faster and results in a more maintainable code. 

What is a Responsive Navbar Component? #

A responsive navbar component is a navigation component that allows users to easily navigate to your website. It shows a horizontal navigation bar for desktop users showing the full menu. On mobile, it only shows a menu button, that pulls in a drawer. Sometimes it can be tricky to implement especially when you take into account mobile + desktop + html semantics. In this tutorial we'll take a look on how to implement it using daisyUI. Okay with that out of the way, lets start!

There are 2 main components that we need to create for the responsive navbar component. 

  1. DrawerLayout 
  2. Navbar - Desktop and Mobile

We will create a  next.js project to implement the component in this tutorial.

Step 0: Project Setup #

Lets create a new project using next.js cli:

npx create-next-app --ts navbar-example && cd navbar-example
1

Install tailwindcss + daisyUI dependencies:

yarn add tailwindcss daisyui autoprefixer postcss
1

Initialize tailwind into the project

npx tailwindcss init -p
1

Modify the generated tailwindcss.config.js and add content array to tell tailwind where our components are located. and add daisyui as one of the plugins:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [require("daisyui")],
}
1234567891011

Delete everything inside globals.css file and add tailwind utility classes.

#globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
1234

Modify index.tsx to make use of tailwind classes

//index.tsx

import type { NextPage } from "next";
import Head from "next/head";

const Home: NextPage = () => {
  return (
    <div className="container mx-auto">
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main>
        <h1 className="text-2xl">
          Welcome to <a href="https://nextjs.org">Next.js!</a>
        </h1>
      </main>
    </div>
  );
};

export default Home;
123456789101112131415161718192021222324

Run the project

yarn dev
1

Step 1: Implementing the DrawerLayout component #

Creating the DrawerLayout component.

First we implement the drawer layout component before adding a navbar. The DrawerLayout component will be the outermost layout component that covers the inner layout component.

//components/DrawerLayout.tsx
import React from "react";

type Props = {
  children: React.ReactNode;
};

const DrawerLayout = ({ children }: Props) => {
  return (
    <div className="drawer">
      <input
        id="app-drawer"
        type="checkbox"
        className="drawer-toggle"
        checked
      />
      <div className="drawer-content flex flex-col">{children}</div>
      <div className="drawer-side">
        <label htmlFor="app-drawer" className="drawer-overlay"></label>
        <ul className="menu p-4 overflow-y-auto w-80 bg-base-100">
          <li>
            <a>Sidebar Item 1</a>
          </li>
          <li>
            <a>Sidebar Item 2</a>
          </li>
        </ul>
      </div>
    </div>
  );
};

export default DrawerLayout;
123456789101112131415161718192021222324252627282930313233

Use the DrawerLayout component in app.tsx

...
import DrawerLayout from "../components/DrawerLayout";

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <DrawerLayout>
      <Component {...pageProps} />
    </DrawerLayout>
  );
}
...
1234567891011

Current output:

A drawer component that always shows.

Notice that currently the DrawerComponent is always shown. That's because we added a checked property in #app-drawer element. The #app-drawer element will reflect the state of our DrawerComponent

Adding a toggle functionality for our DrawerComponent

I'd like to use SessionStorage to store the state for our DrawerComponent so first let's install usehooks-ts package so that we can use the useSessionStorage custom hook. With this, we can toggle the state from anywhere in our application.

yarn add usehooks-ts@2.6.0
1

Adding the state:

//components/DrawerComponent.tsx
import React from "react";
import { useSessionStorage } from "usehooks-ts";

type Props = {
  children: React.ReactNode;
};

const DrawerLayout = ({ children }: Props) => {
  //initialize state here. we use a key and a default state
  const [open, setOpen] = useSessionStorage("drawer", false);
  return (
    <div className="drawer">
      <input
        id="app-drawer"
        type="checkbox"
        className="drawer-toggle"
        // checked property will now reflect our open state
        checked={open}
      />
      <div className="drawer-content flex flex-col">{children}</div>
      <div className="drawer-side">
        <label
          className="drawer-overlay"
          // add a onClick handler here to close the drawer
          onClick={() => setOpen(false)}
        ></label>
        <ul className="menu p-4 overflow-y-auto w-80 bg-base-100">
          <li>
            <a>Sidebar Item 1</a>
          </li>
          <li>
            <a>Sidebar Item 2</a>
          </li>
        </ul>
      </div>
    </div>
  );
};

export default DrawerLayout;
1234567891011121314151617181920212223242526272829303132333435363738394041

Toggling the component from inside our app

Inside index.tsx lets create a button and use useSessionStorage to toggle the state of our DrawerComponent:

//pages/index.tsx
import type { NextPage } from "next";
import { useSessionStorage } from "usehooks-ts";

const Home: NextPage = () => {
  const [, setOpen] = useSessionStorage("drawer", false);
  const toggleDrawer = () => setOpen((prev) => !prev);
  return (
    <div className="container mx-auto">
      <h1 className="text-2xl">
        Welcome to <a href="https://nextjs.org">Next.js!</a>
      </h1>
      <button className="btn" onClick={toggleDrawer}>
        Toggle Drawer
      </button>
    </div>
  );
};

export default Home;

1234567891011121314151617181920

Here's the current output. Later on we'll be toggling the drawer through the menu icon from inside the navbar component.

Current output with toggle drawer

Step 2: Implementing the Navbar component #

For this step we'll now create a navbar component that shows the menu list. Let's create a components/Navbar.tsx file and copy-paste the code below

//components/Navbar.tsx

import React from "react";
import { useSessionStorage } from "usehooks-ts";

const Navbar = () => {
  // toggle our drawer using useSessionStorage global state
  const [, setOpen] = useSessionStorage("drawer", false);
  const toggleDrawer = () => setOpen((prev) => !prev);
  return (
    <div className="w-full navbar bg-neutral">
      {/* Mobile menu button only shows for lg and below devices */}
      <div className="flex-none lg:hidden">
        <label className="btn btn-square btn-ghost" onClick={toggleDrawer}>
          <svg
            xmlns="http://www.w3.org/2000/svg"
            fill="none"
            viewBox="0 0 24 24"
            className="inline-block w-6 h-6 stroke-current"
          >
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth="2"
              d="M4 6h16M4 12h16M4 18h16"
            ></path>
          </svg>
        </label>
      </div>
      {/* Website logo */}
      <div className="flex-1 px-2 mx-2">React Hustle</div>
      {/* Desktop menu only shows for lg and up devices */}
      <div className="flex-none hidden lg:block">
        <ul className="menu menu-horizontal">
          <li>
            <a>Home </a>
          </li>
          <li>
            <a>About</a>
          </li>
          <li>
            <a>Contact</a>
          </li>
        </ul>
      </div>
    </div>
  );
};

export default Navbar;
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950

Lets use the Navbar inside the DrawerLayout component

//components/DrawerLayout.tsx

...
import Navbar from "./Navbar";
...
const DrawerLayout = ({ children }: Props) => {
      ...
      <div className="drawer-content flex flex-col">
        <Navbar />
        {children}
      </div>
      ...
}
...
1234567891011121314

That's all let's see the final output!

Final Step: Let's see the output! #

Mobile

Responsive sidebar for mobile in react using daisyui

Desktop

Responsive navbar for desktop in react using daisyui

Conclusion #

We've successfully created a responsive navbar component using tailwindcss + daisyUI and a utility package called usehooks-ts for react. For further learning, you may modify the navbar so that the menu items are dynamic.

If you like this tutorial, please subscribe to our newsletter below  and get amazing tutorials like this directly to your inbox!

Resources #

usehooks-ts Docs - https://usehooks-ts.com/

Share this post!

Related Posts