mirror of
https://github.com/jnsahaj/tweakcn.git
synced 2026-08-28 23:02:07 +08:00
112 lines
3.9 KiB
TypeScript
112 lines
3.9 KiB
TypeScript
"use client";
|
|
|
|
import GitHubIcon from "@/assets/github.svg";
|
|
import Logo from "@/assets/logo.svg";
|
|
import { Button } from "@/components/ui/button";
|
|
import { useGithubStars } from "@/hooks/use-github-stars";
|
|
import { cn } from "@/lib/utils";
|
|
import { formatCompactNumber } from "@/utils/format";
|
|
import { Menu, X } from "lucide-react";
|
|
import { motion } from "motion/react";
|
|
import Link from "next/link";
|
|
import { ThemeToggle } from "./theme-toggle";
|
|
|
|
interface FigmaHeaderProps {
|
|
isScrolled: boolean;
|
|
mobileMenuOpen: boolean;
|
|
setMobileMenuOpen: (open: boolean) => void;
|
|
}
|
|
|
|
export function FigmaHeader({ isScrolled, mobileMenuOpen, setMobileMenuOpen }: FigmaHeaderProps) {
|
|
const { stargazersCount } = useGithubStars("jnsahaj", "tweakcn");
|
|
|
|
return (
|
|
<header
|
|
className={cn(
|
|
"sticky top-0 z-50 w-full backdrop-blur-lg",
|
|
isScrolled ? "bg-background/90 border-border/20 border-b shadow-xs" : "bg-transparent"
|
|
)}
|
|
>
|
|
<div className="container mx-auto flex h-16 items-center justify-between px-4 md:px-6">
|
|
<Link href="/">
|
|
<div className="flex items-center gap-2 font-bold">
|
|
<Logo className="size-6" />
|
|
<span className="hidden lg:block">tweakcn</span>
|
|
</div>
|
|
</Link>
|
|
|
|
<div className="hidden cursor-pointer items-center gap-4 md:flex">
|
|
<motion.div
|
|
initial={{ opacity: 0, scale: 0.9 }}
|
|
animate={{ opacity: 1, scale: 1 }}
|
|
transition={{ duration: 0.3, delay: 0.2 }}
|
|
>
|
|
<Button variant="ghost" asChild>
|
|
<a
|
|
href="https://github.com/jnsahaj/tweakcn"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="font-semibold"
|
|
>
|
|
<GitHubIcon className="size-5" />
|
|
{stargazersCount > 0 && formatCompactNumber(stargazersCount)}
|
|
</a>
|
|
</Button>
|
|
</motion.div>
|
|
|
|
<motion.div
|
|
initial={{ opacity: 0, scale: 0.9 }}
|
|
animate={{ opacity: 1, scale: 1 }}
|
|
transition={{ duration: 0.3, delay: 0.3 }}
|
|
>
|
|
<ThemeToggle
|
|
variant="secondary"
|
|
size="icon"
|
|
className="rounded-full transition-transform hover:scale-105"
|
|
/>
|
|
</motion.div>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-2 md:hidden">
|
|
<ThemeToggle variant="ghost" size="icon" />
|
|
<Button variant="ghost" size="icon" onClick={() => setMobileMenuOpen(!mobileMenuOpen)}>
|
|
{mobileMenuOpen ? <X className="size-5" /> : <Menu className="size-5" />}
|
|
<span className="sr-only">Toggle menu</span>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mobile menu - simplified */}
|
|
{mobileMenuOpen && (
|
|
<motion.div
|
|
initial={{ opacity: 0, y: -20 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
exit={{ opacity: 0, y: -20 }}
|
|
className="bg-background/95 absolute inset-x-0 top-16 border-b backdrop-blur-lg md:hidden"
|
|
>
|
|
<div className="container mx-auto flex flex-col gap-4 px-4 py-4">
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 10 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.3, delay: 0.1 }}
|
|
className="border-border/30 border-t pt-2"
|
|
>
|
|
<Button variant="ghost" asChild className="w-full justify-start">
|
|
<a
|
|
href="https://github.com/jnsahaj/tweakcn"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
onClick={() => setMobileMenuOpen(false)}
|
|
>
|
|
<GitHubIcon className="mr-2 size-5" />
|
|
GitHub {stargazersCount > 0 && `(${formatCompactNumber(stargazersCount)})`}
|
|
</a>
|
|
</Button>
|
|
</motion.div>
|
|
</div>
|
|
</motion.div>
|
|
)}
|
|
</header>
|
|
);
|
|
}
|