An ultra-minimal modular pill-shaped header component (PillHeader / DarkModeHeader) featuring floating glassmorphic pill elements, customizable action buttons, adaptive light/dark theme toggle, and floating mobile menu container.
1"use client";23import * as React from "react";4import Link from "next/link";5import { Moon, Sun } from "lucide-react";6import { useTheme } from "@/components/theme-provider";7import { cn } from "@/lib/utils";8import { Button } from "@/components/ui/button";910const logoMark =11 "https://www.figma.com/api/mcp/asset/97aa703a-9be3-453a-854e-ad260e5f72aa.svg";1213export type PillHeaderProps = {14 variant?: "desktop" | "compact";15 className?: string;16 homeHref?: string;17 onMenuClick?: () => void;18};1920// Backwards compatibility export alias21export type DarkModeHeaderProps = PillHeaderProps;2223const frame =24 "border border-border/80 bg-background/75 backdrop-blur-xl shadow-[0_10px_30px_rgba(15,23,42,0.06)] transition-all duration-200";2526export function PillHeader({27 className,28 homeHref = "/",29 onMenuClick,30}: PillHeaderProps) {31 const { theme, setTheme } = useTheme();32 const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false);3334 const toggleTheme = () => {35 setTheme(theme === "dark" ? "light" : "dark");36 };3738 return (39 <header40 className={cn(41 "inline-flex h-[52px] items-center justify-center text-foreground antialiased relative mt-2",42 "gap-[8px] md:gap-[16px]",43 "rounded-full",4445 className,46 )}47 >48 <Link49 href={homeHref}50 aria-label="UDX home"51 className={cn(52 "flex h-12 w-12 shrink-0 items-center justify-center",53 "rounded-full",54 "border border-border/80 bg-background/85 shadow-[0_8px_20px_rgba(15,23,42,0.05)] transition-all duration-200 hover:bg-accent/60",55 )}56 >57 <svg className="h-5 w-5 shrink-0 text-foreground" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">58 <rect x="3" y="3" width="18" height="18" rx="5" className="fill-primary/10 stroke-primary" strokeWidth="1.5" />59 <path d="M7 8H17M7 12H17M7 16H13" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />60 </svg>61 </Link>6263 <nav64 aria-label="Primary navigation"65 className={cn(66 "hidden md:flex h-12 items-center justify-center gap-1 rounded-full border border-border/80 bg-background/75 px-2 py-1.5 shadow-[0_8px_20px_rgba(15,23,42,0.04)] backdrop-blur-xl",67 )}68 >69 {[70 { label: "Home", href: "#" },71 { label: "About", href: "#about" },72 { label: "Product", href: "#product" },73 ].map((item, index) => (74 <Link75 key={item.label}76 href={item.href}77 className={cn(78 "rounded-full px-3 py-2 text-[13px] font-medium leading-none transition-all duration-200",79 index === 080 ? "bg-accent text-foreground shadow-sm"81 : "text-muted-foreground hover:bg-accent/50 hover:text-foreground",82 )}83 >84 {item.label}85 </Link>86 ))}87 </nav>8889 <div className="flex h-[52px] items-center">90 <button91 type="button"92 onClick={toggleTheme}93 aria-label={`Switch to ${theme === "dark" ? "light" : "dark"} mode`}94 className={cn(95 "relative z-10 -mr-px flex h-12 w-12 shrink-0 items-center justify-center",96 "rounded-full",97 "border border-border/80 bg-background/80 text-foreground shadow-[0_8px_18px_rgba(15,23,42,0.04)] transition-all duration-200 hover:bg-accent/60",98 )}99 >100 {theme === "dark" ? (101 <Sun className="h-4 w-4 stroke-[1.8]" />102 ) : (103 <Moon className="h-4 w-4 stroke-[1.8]" />104 )}105 </button>106107 <div108 className={cn(109 "hidden md:flex relative z-10 h-12 items-center gap-2 justify-center rounded-full border border-border/80 bg-background/80 px-2 py-1.5 shadow-[0_8px_18px_rgba(15,23,42,0.04)] backdrop-blur-xl",110 )}111 >112 <Button113 render={<Link href="#" className="rounded-[inherit]" />}114 >115 Get Started116 </Button>117 <Button118 variant="outline"119 render={<Link href="#" className="rounded-[inherit]" />}120 >121 Login122 </Button>123 </div>124125 <button126 type="button"127 onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}128 aria-label="Open navigation menu"129 className={cn(130 "flex md:hidden h-12 w-12 items-center justify-center",131 "rounded-full",132 "border border-border/80 bg-background/80 text-foreground transition-all duration-200 hover:bg-accent/60 shadow-[0_8px_18px_rgba(15,23,42,0.04)]",133 "relative z-10 -mr-px",134 )}135 >136 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" className="h-4 w-4">137 <path strokeLinecap="round" strokeLinejoin="round" d="M3.75 9h16.5m-16.5 6.75h16.5" />138 </svg>139 </button>140 </div>141142 {isMobileMenuOpen && (143 <div className="absolute top-[calc(100%+10px)] left-0 w-full min-w-[220px] md:hidden rounded-[22px] border border-border/80 bg-card/95 p-4 shadow-[0_20px_45px_rgba(15,23,42,0.08)] backdrop-blur-xl flex flex-col gap-3 z-40">144 <nav className="flex flex-col gap-1.5">145 {[146 { label: "Home", href: "#" },147 { label: "About", href: "#about" },148 { label: "Product", href: "#product" },149 ].map((item) => (150 <Link151 key={item.label}152 href={item.href}153 className="rounded-xl px-3 py-2 text-[14px] font-medium text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground"154 >155 {item.label}156 </Link>157 ))}158 </nav>159 <div className="mt-1 flex flex-col gap-2 border-t border-border/60 pt-3">160 <Button className="w-full rounded-full" render={<Link href="#" className="w-full" />}>161 Get Started162 </Button>163 <Button variant="outline" className="w-full rounded-full" render={<Link href="#" className="w-full" />}>164 Login165 </Button>166 </div>167 </div>168 )}169 </header>170 );171}172173export const DarkModeHeader = PillHeader;174175export default PillHeader;