Spaces:
Running
Running
File size: 4,454 Bytes
21a686e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
"use client";
import { cn } from "@/lib/utils";
import { IconMenu2, IconX } from "@tabler/icons-react";
import { motion, AnimatePresence } from "motion/react";
import Image from "next/image";
import Link from "next/link";
import React, { useState } from "react";
export function SimpleNavbarWithHoverEffects() {
return <Navbar />;
}
const Navbar = () => {
const navItems = [
{ name: "Work", link: "#" },
{ name: "Services", link: "#" },
{ name: "Pricing", link: "#" },
{ name: "Contact", link: "#" },
];
return (
<div className="w-full">
<DesktopNav navItems={navItems} />
<MobileNav navItems={navItems} />
</div>
);
};
const DesktopNav = ({ navItems }: any) => {
const [hovered, setHovered] = useState<number | null>(null);
return (
<motion.div
onMouseLeave={() => {
setHovered(null);
}}
className={cn(
"relative z-[60] mx-auto hidden w-full max-w-7xl flex-row items-center justify-between self-start rounded-full bg-white px-4 py-2 lg:flex dark:bg-neutral-950",
"sticky inset-x-0 top-40"
)}
>
<Logo />
<div className="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">
{navItems.map((navItem: any, idx: number) => (
<Link
onMouseEnter={() => setHovered(idx)}
className="relative px-4 py-2 text-neutral-600 dark:text-neutral-300"
key={`link=${idx}`}
href={navItem.link}
>
{hovered === idx && (
<motion.div
layoutId="hovered"
className="absolute inset-0 h-full w-full rounded-full bg-gray-100 dark:bg-neutral-800"
/>
)}
<span className="relative z-20">{navItem.name}</span>
</Link>
))}
</div>
<button className="hidden rounded-full bg-black px-8 py-2 text-sm font-bold text-white shadow-[0px_-2px_0px_0px_rgba(255,255,255,0.4)_inset] md:block dark:bg-white dark:text-black">
Book a call
</button>
</motion.div>
);
};
const MobileNav = ({ navItems }: any) => {
const [open, setOpen] = useState(false);
return (
<>
<motion.div
animate={{ borderRadius: open ? "4px" : "2rem" }}
key={String(open)}
className="relative mx-auto flex w-full max-w-[calc(100vw-2rem)] flex-col items-center justify-between bg-white px-4 py-2 lg:hidden dark:bg-neutral-950"
>
<div className="flex w-full flex-row items-center justify-between">
<Logo />
{open ? (
<IconX
className="text-black dark:text-white"
onClick={() => setOpen(!open)}
/>
) : (
<IconMenu2
className="text-black dark:text-white"
onClick={() => setOpen(!open)}
/>
)}
</div>
<AnimatePresence>
{open && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="absolute inset-x-0 top-16 z-20 flex w-full flex-col items-start justify-start gap-4 rounded-lg bg-white px-4 py-8 dark:bg-neutral-950"
>
{navItems.map((navItem: any, idx: number) => (
<Link
key={`link=${idx}`}
href={navItem.link}
className="relative text-neutral-600 dark:text-neutral-300"
>
<motion.span className="block">{navItem.name} </motion.span>
</Link>
))}
<button className="w-full rounded-lg bg-black px-8 py-2 font-medium text-white shadow-[0px_-2px_0px_0px_rgba(255,255,255,0.4)_inset] dark:bg-white dark:text-black">
Book a call
</button>
</motion.div>
)}
</AnimatePresence>
</motion.div>
</>
);
};
const Logo = () => {
return (
<Link
href="/"
className="relative z-20 mr-4 flex items-center space-x-2 px-2 py-1 text-sm font-normal text-black"
>
<Image
src="https://assets.aceternity.com/logo-dark.png"
alt="logo"
width={30}
height={30}
/>
<span className="font-medium text-black dark:text-white">DevStudio</span>
</Link>
);
};
|