import { cn } from "@/lib/utils"; import { IconLayoutNavbarCollapse } from "@tabler/icons-react"; import { AnimatePresence, MotionValue, motion, useMotionValue, useSpring, useTransform, } from "motion/react"; import { useRef, useState } from "react"; export const FloatingDock = ({ items, desktopClassName, mobileClassName, }: { items: { title: string; icon: React.ReactNode; href: string }[]; desktopClassName?: string; mobileClassName?: string; }) => { return ( <> ); }; const FloatingDockMobile = ({ items, className, }: { items: { title: string; icon: React.ReactNode; href: string }[]; className?: string; }) => { const [open, setOpen] = useState(false); return (
{open && ( {items.map((item, idx) => (
{item.icon}
))}
)}
); }; const FloatingDockDesktop = ({ items, className, }: { items: { title: string; icon: React.ReactNode; href: string }[]; className?: string; }) => { let mouseX = useMotionValue(Infinity); return ( mouseX.set(e.pageX)} onMouseLeave={() => mouseX.set(Infinity)} className={cn( "mx-auto hidden h-16 items-end gap-4 rounded-2xl bg-gray-50 px-4 pb-3 md:flex dark:bg-neutral-900", className, )} > {items.map((item) => ( ))} ); }; function IconContainer({ mouseX, title, icon, href, }: { mouseX: MotionValue; title: string; icon: React.ReactNode; href: string; }) { let ref = useRef(null); let distance = useTransform(mouseX, (val) => { let bounds = ref.current?.getBoundingClientRect() ?? { x: 0, width: 0 }; return val - bounds.x - bounds.width / 2; }); let widthTransform = useTransform(distance, [-150, 0, 150], [40, 80, 40]); let heightTransform = useTransform(distance, [-150, 0, 150], [40, 80, 40]); let widthTransformIcon = useTransform(distance, [-150, 0, 150], [20, 40, 20]); let heightTransformIcon = useTransform( distance, [-150, 0, 150], [20, 40, 20], ); let width = useSpring(widthTransform, { mass: 0.1, stiffness: 150, damping: 12, }); let height = useSpring(heightTransform, { mass: 0.1, stiffness: 150, damping: 12, }); let widthIcon = useSpring(widthTransformIcon, { mass: 0.1, stiffness: 150, damping: 12, }); let heightIcon = useSpring(heightTransformIcon, { mass: 0.1, stiffness: 150, damping: 12, }); const [hovered, setHovered] = useState(false); return ( setHovered(true)} onMouseLeave={() => setHovered(false)} className="relative flex aspect-square items-center justify-center rounded-full bg-gray-200 dark:bg-neutral-800" > {hovered && ( {title} )} {icon} ); }