"use client"; import { cn } from "@/lib/utils"; import { IconMenu2, IconX } from "@tabler/icons-react"; import { motion, AnimatePresence, useScroll, useMotionValueEvent, } from "motion/react"; import React, { useRef, useState } from "react"; interface NavbarProps { children: React.ReactNode; className?: string; } export const Navbar = ({ children, className }: NavbarProps) => { const ref = useRef(null); const { scrollY } = useScroll({ target: ref, offset: ["start start", "end start"], }); const [visible, setVisible] = useState(false); useMotionValueEvent(scrollY, "change", (latest) => { if (latest > 100) { setVisible(true); } else { setVisible(false); } }); return ( {React.Children.map(children, (child) => React.isValidElement(child) ? React.cloneElement(child, { visible } as { visible: boolean }) : child )} ); }; interface NavBodyProps { children: React.ReactNode; className?: string; visible?: boolean; } export const NavBody = ({ children, className, visible }: NavBodyProps) => { return ( ); }; interface NavItem { name: string; link: string; } interface NavItemsProps { items: NavItem[]; className?: string; onItemClick?: () => void; } export const NavItems = ({ items, className, onItemClick, }: NavItemsProps) => { const [hovered, setHovered] = useState(null); return ( setHovered(null)} className={cn( "absolute inset-0 hidden flex-1 flex-row items-center justify-center space-x-2 text-sm font-medium text-zinc-600 transition duration-200 hover:text-zinc-800 lg:flex lg:space-x-2", className )} > {items.map((item, idx) => ( setHovered(idx)} onClick={onItemClick} className="relative px-4 py-2 text-neutral-600 dark:text-neutral-300" key={`link-${idx}`} href={item.link} > {hovered === idx && ( )} {item.name} ))} ); }; interface MobileNavProps { children: React.ReactNode; className?: string; visible?: boolean; } export const MobileNav = ({ children, className, visible, }: MobileNavProps) => { return ( div:first-child]:text-white [&>div:first-child_a]:text-white [&>div:first-child_svg]:text-white", visible && "bg-black/90", className )} > {children} ); }; interface MobileNavHeaderProps { children: React.ReactNode; className?: string; } export const MobileNavHeader = ({ children, className, }: MobileNavHeaderProps) => { return (
{children}
); }; interface MobileNavMenuProps { children: React.ReactNode; className?: string; isOpen: boolean; onClose: () => void; } export const MobileNavMenu = ({ children, className, isOpen, }: MobileNavMenuProps) => { return ( {isOpen && ( {children} )} ); }; interface MobileNavToggleProps { isOpen: boolean; onClick: () => void; } export const MobileNavToggle = ({ isOpen, onClick }: MobileNavToggleProps) => { return isOpen ? ( ) : ( ); }; interface NavbarLogoProps { href?: string; logoSrc?: string; logoAlt?: string; children?: React.ReactNode; className?: string; } export const NavbarLogo = ({ href = "#", logoSrc, logoAlt = "Logo", children, className, }: NavbarLogoProps) => { return ( {logoSrc ? ( {logoAlt} ) : null} {children} ); }; interface NavbarButtonProps extends React.AnchorHTMLAttributes { href?: string; as?: "a" | "button"; children: React.ReactNode; className?: string; variant?: "primary" | "secondary" | "dark" | "gradient"; } export const NavbarButton = ({ href, as: Tag = "a", children, className, variant = "primary", ...props }: NavbarButtonProps) => { const baseStyles = "px-4 py-2 rounded-full text-sm font-bold relative cursor-pointer transition duration-200 inline-block text-center"; const variantStyles = { primary: "bg-[hsl(198,93%,42%)] text-white border border-white/20 shadow-[inset_0_1px_1px_rgba(255,255,255,0.25),inset_0_2px_2px_rgba(255,255,255,0.2),0_2px_4px_rgba(0,0,0,0.2),0_4px_8px_rgba(0,0,0,0.15)] hover:border-white/40 hover:shadow-[inset_0_1px_1px_rgba(255,255,255,0.3),inset_0_2px_2px_rgba(255,255,255,0.25),0_2px_4px_rgba(0,0,0,0.2),0_4px_8px_rgba(0,0,0,0.15)]", secondary: "bg-transparent shadow-none dark:text-white", dark: "btn !text-white", gradient: "bg-gradient-to-b from-blue-500 to-blue-700 text-white shadow-[0px_2px_0px_0px_rgba(255,255,255,0.3)_inset]", }; const componentProps = Tag === "a" ? { href: href ?? undefined, ...props } : { ...props }; return ( )} > {children} ); };