Installation
Install dependencies
npm i motion clsx tailwind-merge
Add util file
import { ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
Copy the source code
components/ui/floating-navbar.tsx
"use client";
import React, { useState } from "react";
import {
motion,
AnimatePresence,
useScroll,
useMotionValueEvent,
} from "motion/react";
import { cn } from "@/lib/utils";
import Link from "next/link";
export const FloatingNav = ({
navItems,
className,
}: {
navItems: {
name: string;
link: string;
icon?: JSX.Element;
}[];
className?: string;
}) => {
const { scrollYProgress } = useScroll();
const [visible, setVisible] = useState(false);
useMotionValueEvent(scrollYProgress, "change", (current) => {
// Check if current is not undefined and is a number
if (typeof current === "number") {
let direction = current! - scrollYProgress.getPrevious()!;
if (scrollYProgress.get() < 0.05) {
setVisible(false);
} else {
if (direction < 0) {
setVisible(true);
} else {
setVisible(false);
}
}
}
});
return (
<AnimatePresence mode="wait">
<motion.div
initial={{
opacity: 1,
y: -100,
}}
animate={{
y: visible ? 0 : -100,
opacity: visible ? 1 : 0,
}}
transition={{
duration: 0.2,
}}
className={cn(
"flex max-w-fit fixed top-10 inset-x-0 mx-auto border border-transparent dark:border-white/[0.2] rounded-full dark:bg-black bg-white shadow-[0px_2px_3px_-1px_rgba(0,0,0,0.1),0px_1px_0px_0px_rgba(25,28,33,0.02),0px_0px_0px_1px_rgba(25,28,33,0.08)] z-[5000] pr-2 pl-8 py-2 items-center justify-center space-x-4",
className
)}
>
{navItems.map((navItem: any, idx: number) => (
<Link
key={`link=${idx}`}
href={navItem.link}
className={cn(
"relative dark:text-neutral-50 items-center flex space-x-1 text-neutral-600 dark:hover:text-neutral-300 hover:text-neutral-500"
)}
>
<span className="block sm:hidden">{navItem.icon}</span>
<span className="hidden sm:block text-sm">{navItem.name}</span>
</Link>
))}
<button className="border text-sm font-medium relative border-neutral-200 dark:border-white/[0.2] text-black dark:text-white px-4 py-2 rounded-full">
<span>Login</span>
<span className="absolute inset-x-0 w-1/2 mx-auto -bottom-px bg-gradient-to-r from-transparent via-blue-500 to-transparent h-px" />
</button>
</motion.div>
</AnimatePresence>
);
};
Props
Prop name | Type | Description |
---|---|---|
className | string | The class name of the child component. |
navItems | {name: string, link: string, icon: ReactNode} | The navigation items you want to render in the navbar |
Build websites faster and 10x better than your competitors with Aceternity UI Pro
With the best in class components and templates, stand out from the crowd and get more attention to your website. Trusted by founders and entrepreneurs from all over the world.
Excellent communication and professionalism from the start and
throughout. Happily and calmly accepted and entertained a few additional
out-of-scope requests as well. Good open-...
Henrik Söderlund
Former CTO at Creme Digital