Files
reui-blocks/blocks/navbar29.tsx
T

192 lines
6.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { AnimatePresence, motion } from "framer-motion";
import { ArrowUpRight } from "lucide-react";
import { useState } from "react";
import { cn } from "@/lib/utils";
const NAV_ITEMS = [
{ label: "خانه", href: "#" },
{ label: "ماژول‌ها", href: "#" },
{ label: "تغییرات نسخه", href: "#" },
{ label: "تماس", href: "#" },
];
const MEGA_MENU_ITEMS = [
[
{ label: "خانه", href: "#" },
{ label: "درباره ما", href: "#" },
{ label: "راه‌حل‌ها", href: "#" },
{ label: "مطالعات موردی", href: "#" },
{ label: "وبلاگ", href: "#" },
{ label: "تماس", href: "#" },
],
[
{ label: "ویژگی‌ها", href: "#" },
{ label: "ماژول", href: "#" },
{ label: "قالب کمپین", href: "#" },
{ label: "نمونه‌های جریان", href: "#" },
{ label: "منابع", href: "#" },
{ label: "پشتیبانی", href: "#" },
],
[
{ label: "قیمت‌گذاری", href: "#" },
{ label: "سازمانی", href: "#" },
{ label: "شراکت‌ها", href: "#" },
{ label: "فرصت‌های شغلی", href: "#" },
{ label: "مطبوعات", href: "#" },
{ label: "حقوقی", href: "#" },
],
[
{ label: "توییتر", href: "#" },
{ label: "وضعیت سرویس", href: "#" },
{ label: "انجمن", href: "#" },
{ label: "لینکدین", href: "#" },
{ label: "یوتیوب", href: "#" },
{ label: "خبرنامه", href: "#" },
],
];
const MOBILE_NAV_ITEMS = [
{ label: "خانه", href: "#" },
{ label: "درباره ما", href: "#" },
{ label: "راه‌حل‌ها", href: "#" },
{ label: "مطالعات موردی", href: "#" },
{ label: "وبلاگ", href: "#" },
{ label: "تماس", href: "#" },
{ label: "ورود", href: "#" },
{ label: "قیمت‌گذاری", href: "#" },
];
const FOOTER_LINKS = [
{ label: "حریم خصوصی", href: "#" },
{ label: "شرایط استفاده", href: "#" },
];
const COMPANY_LINKS = [
{ label: "+۱ (۱۲۰) ۲۳۳-۱۲۳۱", href: "#" },
{ label: "۱۴۰۴© برندلینک", href: "#" },
];
interface Navbar29Props {
className?: string;
}
const Navbar29 = ({ className }: Navbar29Props) => {
const [isOpen, setIsOpen] = useState(false);
return (
<section dir="rtl" lang="fa" className={cn("text-right", className)}>
<nav className="relative overflow-visible">
<ul className="relative z-1 flex w-full items-center justify-between gap-4 p-6 text-lg font-semibold tracking-tight">
<li className="w-35">برندلینک</li>
{NAV_ITEMS.map((item) => (
<li key={item.label} className="hidden w-32 lg:block">
<a
href={item.href}
className="transition-colors hover:text-foreground/70"
>
{item.label}
</a>
</li>
))}
<li className="lg:w-14">
<Menu setIsOpen={setIsOpen} isOpen={isOpen} />
</li>
</ul>
<AnimatePresence mode="popLayout">
{isOpen && (
<motion.div
className="absolute top-0 w-full bg-muted px-6 pt-30 pb-10 text-right"
initial={{ clipPath: "inset(0 0 100% 0)" }}
animate={{ clipPath: "inset(0% 0 0 0)" }}
exit={{ clipPath: "inset(0 0 100% 0)" }}
transition={{
duration: 0.35,
ease: [0.4, 0.0, 0.2, 1],
}}
>
<div className="flex lg:hidden">
<ul className="flex w-full flex-col gap-5 text-xl font-semibold tracking-tight">
{MOBILE_NAV_ITEMS.map((item) => (
<li key={item.label}>
<a href={item.href}>{item.label}</a>
</li>
))}
</ul>
</div>
<div className="hidden w-full items-center justify-between gap-4 lg:flex">
<div className="w-35 opacity-0">برندلینک</div>
{MEGA_MENU_ITEMS.map((section, sectionIndex) => (
<ul key={sectionIndex} className="space-y-5">
{section.map((item) => (
<li
key={item.label}
className={cn(
"group flex w-32 items-center gap-1 text-foreground/40 hover:text-foreground",
)}
>
<a href={item.href}>{item.label}</a>
<ArrowUpRight className="size-4 translate-y-2 opacity-0 transition-all ease-out group-hover:translate-y-0 group-hover:opacity-100 rtl:rotate-180" />
</li>
))}
</ul>
))}
<div className="w-14" />
</div>
<div className="mt-40 flex w-full flex-col items-center justify-between gap-2 text-sm lg:flex-row lg:gap-4 lg:text-base">
<div className="flex items-center gap-4 lg:gap-10">
{COMPANY_LINKS.map((item) => (
<p key={item.label}>{item.label}</p>
))}
</div>
<div className="flex items-center gap-4 lg:gap-10">
{FOOTER_LINKS.map((item) => (
<p key={item.label}>{item.label}</p>
))}
</div>
</div>
</motion.div>
)}
</AnimatePresence>
</nav>
</section>
);
};
export { Navbar29 };
const Menu = ({
className,
setIsOpen,
isOpen,
}: {
className?: string;
setIsOpen: (value: boolean | ((prev: boolean) => boolean)) => void;
isOpen: boolean;
}) => {
return (
<button
type="button"
className={cn(
"relative flex h-2 w-8 flex-col items-center justify-center gap-2 after:absolute after:h-12 after:w-full lg:w-14",
className,
)}
onClick={() => setIsOpen((x: boolean) => !x)}
aria-expanded={isOpen}
aria-label={isOpen ? "بستن منو" : "باز کردن منو"}
>
<motion.div
animate={{ y: isOpen ? 0 : 5, rotate: isOpen ? 45 : 0 }}
className="absolute h-0.5 w-full bg-foreground"
/>
<motion.div
animate={{ y: isOpen ? 0 : -5, rotate: isOpen ? -45 : 0 }}
className="absolute h-0.5 w-full bg-foreground"
/>
</button>
);
};