Tube Light Navbar
A sleek, interactive navigation bar with a dynamic lighting effect, perfect for modern UIs.
Installation
- 1
Install Dependencies
npm i framer-motion lucide-react
- 2
lib/utils.ts
import { clsx, type ClassValue } from "clsx" import { twMerge } from "tailwind-merge" export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) }
- 3
Copy the source code
@/components/ui/tubelight-navbar.tsx
"use client" import React, { useEffect, useState } from "react" import { motion } from "framer-motion" import Link from "next/link" import { LucideIcon } from "lucide-react" import { cn } from "@/lib/utils" interface NavItem { name: string url: string icon: LucideIcon } interface NavBarProps { items: NavItem[] className?: string } export function NavBar({ items, className }: NavBarProps) { const [activeTab, setActiveTab] = useState(items[0].name) const [isMobile, setIsMobile] = useState(false) useEffect(() => { const handleResize = () => { setIsMobile(window.innerWidth < 768) } handleResize() window.addEventListener("resize", handleResize) return () => window.removeEventListener("resize", handleResize) }, []) return ( <div className={cn( "fixed bottom-0 sm:top-0 left-1/2 -translate-x-1/2 z-[200] mb-6 sm:pt-6 h-max", className, )} > <div className="flex items-center gap-3 bg-background/5 border border-border backdrop-blur-lg py-1 px-1 rounded-full shadow-lg"> {items.map((item) => { const Icon = item.icon const isActive = activeTab === item.name return ( <Link key={item.name} href={item.url} onClick={() => setActiveTab(item.name)} className={cn( "relative cursor-pointer text-sm font-semibold px-6 py-2 rounded-full transition-colors", "text-foreground/80 hover:text-primary", isActive && "bg-muted text-primary", )} > <span className="hidden md:inline">{item.name}</span> <span className="md:hidden"> <Icon size={18} strokeWidth={2.5} /> </span> {isActive && ( <motion.div layoutId="lamp" className="absolute inset-0 w-full bg-primary/5 rounded-full -z-10" initial={false} transition={{ type: "spring", stiffness: 300, damping: 30, }} > <div className="absolute -top-2 left-1/2 -translate-x-1/2 w-8 h-1 bg-primary rounded-t-full"> <div className="absolute w-12 h-6 bg-primary/20 rounded-full blur-md -top-2 -left-2" /> <div className="absolute w-8 h-6 bg-primary/20 rounded-full blur-md -top-1" /> <div className="absolute w-4 h-4 bg-primary/20 rounded-full blur-sm top-0 left-2" /> </div> </motion.div> )} </Link> ) })} </div> </div> ) }
Props
NavBarProps
Prop | Type | Default | Description |
---|---|---|---|
className | string | undefined | Optional custom class names for styling. |
items | NavItem[] | [] | An array of navigation items containing name, URL, and icon. |
NavItem
Prop | Type | Default | Description |
---|---|---|---|
name | string | undefined | The label for the navigation item. |
url | string | undefined | The destination URL for the navigation item. |
icon | LucideIcon | undefined | The icon representing the navigation item. |
The inspiration for this component is directly taken from Serenity UI