Responsive Navigation Bar

PreviousNext

Responsive navbar with mobile and desktop views, icon support, and RTL/LTR support

Docs
react-marketcomponent

Preview

Loading preview…
navbar.tsx
"use client"

import * as React from "react"
import Link from "next/link"
import { Menu, X, Home, Settings, User, HelpCircle, BarChart } from "lucide-react"

import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet"

interface NavItem {
  title: string
  href: string
  icon: React.ReactNode
}

interface NavbarProps extends React.HTMLAttributes<HTMLDivElement> {
  items?: NavItem[]
  direction?: "ltr" | "rtl"
  logo?: React.ReactNode
}

export function Navbar({ className, items, direction = "ltr", logo, ...props }: NavbarProps) {
  const [isOpen, setIsOpen] = React.useState(false)

  const defaultItems: NavItem[] = [
    {
      title: "Home",
      href: "/",
      icon: <Home className="h-5 w-5" />,
    },
    {
      title: "Dashboard",
      href: "/dashboard",
      icon: <BarChart className="h-5 w-5" />,
    },
    {
      title: "Profile",
      href: "/profile",
      icon: <User className="h-5 w-5" />,
    },
    {
      title: "Settings",
      href: "/settings",
      icon: <Settings className="h-5 w-5" />,
    },
    {
      title: "Help",
      href: "/help",
      icon: <HelpCircle className="h-5 w-5" />,
    },
  ]

  const navItems = items || defaultItems
  const directionClass = direction === "rtl" ? "text-right" : "text-left"

  return (
    <header className={cn("sticky top-0 z-40 w-full border-b bg-background", className)} dir={direction} {...props}>
      <div className="container flex h-16 items-center">
        <div className="flex items-center justify-between w-full">
          <div className="flex">{logo || <span className="text-xl font-bold">Logo</span>}</div>

          {/* Mobile menu */}
          <Sheet open={isOpen} onOpenChange={setIsOpen}>
            <SheetTrigger asChild className="md:hidden">
              <Button variant="ghost" size="icon" className="md:hidden">
                <Menu className="h-6 w-6" />
                <span className="sr-only">Open menu</span>
              </Button>
            </SheetTrigger>
            <SheetContent side={direction === "rtl" ? "right" : "left"} className={directionClass}>
              <div className="flex flex-col gap-4 py-4">
                <Button variant="ghost" className="justify-end md:hidden" onClick={() => setIsOpen(false)}>
                  <X className="h-6 w-6" />
                  <span className="sr-only">Close menu</span>
                </Button>
                <nav className="flex flex-col gap-3">
                  {navItems.map((item, index) => (
                    <Link
                      key={index}
                      href={item.href}
                      onClick={() => setIsOpen(false)}
                      className={cn(
                        "flex items-center gap-2 rounded-md px-3 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground",
                        direction === "rtl" ? "flex-row-reverse" : "flex-row",
                      )}
                    >
                      {item.icon}
                      <span>{item.title}</span>
                    </Link>
                  ))}
                </nav>
              </div>
            </SheetContent>
          </Sheet>

          {/* Desktop menu */}
          <nav className="hidden md:flex md:gap-4">
            {navItems.map((item, index) => (
              <Link
                key={index}
                href={item.href}
                className={cn(
                  "flex items-center gap-2 rounded-md px-3 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-colors",
                  direction === "rtl" ? "flex-row-reverse" : "flex-row",
                )}
              >
                {item.icon}
                <span>{item.title}</span>
              </Link>
            ))}
          </nav>
        </div>
      </div>
    </header>
  )
}

Installation

npx shadcn@latest add @react-market/simple-responsive-navbar

Usage

import { SimpleResponsiveNavbar } from "@/components/simple-responsive-navbar"
<SimpleResponsiveNavbar />