/ app / src / components / ui / navbar-menu.tsx
navbar-menu.tsx
  1  "use client";
  2  import React from "react";
  3  import { motion } from "framer-motion";
  4  import Link from "next/link";
  5  import Image from "next/image";
  6  
  7  const transition = {
  8    type: "spring",
  9    mass: 0.5,
 10    damping: 11.5,
 11    stiffness: 100,
 12    restDelta: 0.001,
 13    restSpeed: 0.001,
 14  };
 15  
 16  export const MenuItem = ({
 17    setActive,
 18    active,
 19    item,
 20    children,
 21  }: {
 22    setActive: (item: string) => void;
 23    active: string | null;
 24    item: string;
 25    children?: React.ReactNode;
 26  }) => {
 27    return (
 28      <div onMouseEnter={() => setActive(item)} className="relative ">
 29        <motion.p
 30          transition={{ duration: 0.3 }}
 31          className="cursor-pointer text-black hover:opacity-[0.9] dark:text-white"
 32        >
 33          {item}
 34        </motion.p>
 35        {active !== null && (
 36          <motion.div
 37            initial={{ opacity: 0, scale: 0.85, y: 10 }}
 38            animate={{ opacity: 1, scale: 1, y: 0 }}
 39            transition={transition}
 40          >
 41            {active === item && (
 42              <div className="absolute top-[calc(100%_+_1.7rem)] left-1/2 transform -translate-x-1/2">
 43                <motion.div
 44                  transition={transition}
 45                  layoutId="active" // layoutId ensures smooth animation
 46                  className="bg-white dark:bg-black backdrop-blur-sm rounded-2xl overflow-hidden border border-black/[0.2] dark:border-white/[0.2] shadow-xl"
 47                >
 48                  <motion.div
 49                    layout // layout ensures smooth animation
 50                    className="w-max h-full p-4"
 51                  >
 52                    {children}
 53                  </motion.div>
 54                </motion.div>
 55              </div>
 56            )}
 57          </motion.div>
 58        )}
 59      </div>
 60    );
 61  };
 62  
 63  export const Menu = ({
 64    setActive,
 65    children,
 66  }: {
 67    setActive: (item: string | null) => void;
 68    children: React.ReactNode;
 69  }) => {
 70    return (
 71      <nav
 72        onMouseLeave={() => setActive(null)} // resets the state
 73        className="relative rounded-full boder border-transparent dark:bg-black dark:border-white/[0.2] bg-white shadow-input flex justify-center space-x-4 px-8 py-6 "
 74      >
 75        {children}
 76      </nav>
 77    );
 78  };
 79  
 80  export const ProductItem = ({
 81    title,
 82    description,
 83    href,
 84    src,
 85  }: {
 86    title: string;
 87    description: string;
 88    href: string;
 89    src: string;
 90  }) => {
 91    return (
 92      <Link href={href} className="flex space-x-2">
 93        <Image
 94          src={src}
 95          width={140}
 96          height={70}
 97          alt={title}
 98          className="flex-shrink-0 rounded-md shadow-2xl"
 99        />
100        <div>
101          <h4 className="text-xl font-bold mb-1 text-black dark:text-white">
102            {title}
103          </h4>
104          <p className="text-neutral-700 text-sm max-w-[10rem] dark:text-neutral-300">
105            {description}
106          </p>
107        </div>
108      </Link>
109    );
110  };
111  
112  export const HoveredLink = ({ children, ...rest }: any) => {
113    return (
114      <Link
115        {...rest}
116        className="text-neutral-700 dark:text-neutral-200 hover:text-black "
117      >
118        {children}
119      </Link>
120    );
121  };