91 lines
2.7 KiB
TypeScript
91 lines
2.7 KiB
TypeScript
"use client";
|
|
import { useState } from "react";
|
|
import {
|
|
motion,
|
|
AnimatePresence,
|
|
useScroll,
|
|
useMotionValueEvent,
|
|
} from "motion/react";
|
|
import { Link } from "react-router-dom";
|
|
import { cn } from "@/lib/utils";
|
|
import { Button } from "../Button";
|
|
|
|
|
|
export const FloatingNav = ({
|
|
navItems,
|
|
className,
|
|
}: {
|
|
navItems: {
|
|
name: string;
|
|
link: string;
|
|
icon?: JSX.Element;
|
|
}[];
|
|
className?: string;
|
|
}) => {
|
|
const { scrollYProgress } = useScroll();
|
|
|
|
const [visible, setVisible] = useState(true);
|
|
|
|
useMotionValueEvent(scrollYProgress, "change", (current) => {
|
|
if (typeof current === "number") {
|
|
const previous = scrollYProgress.getPrevious();
|
|
// Check if previous is a number to avoid errors
|
|
if (typeof previous === "number" && current > previous) {
|
|
setVisible(false); // Scrolling down
|
|
} else {
|
|
setVisible(true); // Scrolling up or at the top
|
|
}
|
|
}
|
|
});
|
|
|
|
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-xl dark:bg-black bg-gray-700/50 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-4 pl-8 py-2 items-center justify-center space-x-12",
|
|
className
|
|
)}
|
|
>
|
|
{navItems.map((navItem, idx: number) => (
|
|
<Link
|
|
key={`link=${idx}`}
|
|
to={navItem.link}
|
|
className={cn(
|
|
"relative dark:text-neutral-50 items-center flex space-x-1 text-neutral-200 dark:hover:text-neutral-300 hover:text-cyan-500"
|
|
)}
|
|
>
|
|
<span className="block sm:hidden">{navItem.icon}</span>
|
|
<span className="hidden sm:block text-sm">{navItem.name}</span>
|
|
</Link>
|
|
))}
|
|
<div className="flex items-center gap-6">
|
|
<a
|
|
href="https://threefold.info/mycelium_network/docs/"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className={cn(
|
|
"relative dark:text-neutral-50 items-center flex space-x-1 text-neutral-200 dark:hover:text-neutral-300 hover:text-cyan-500"
|
|
)}
|
|
>
|
|
<span className="hidden sm:block text-sm">Docs</span>
|
|
</a>
|
|
<Button to="/download" variant="solid" color="cyan">
|
|
Get Mycelium
|
|
</Button>
|
|
</div>
|
|
</motion.div>
|
|
</AnimatePresence>
|
|
);
|
|
};
|