continue re-design

This commit is contained in:
Developers Digest
2025-09-05 13:06:17 -04:00
parent b96d048dbd
commit 836b085f75
270 changed files with 32269 additions and 5182 deletions
@@ -0,0 +1,216 @@
"use client";
import copy from "copy-to-clipboard";
import { animate, cubicBezier } from "motion";
import { AnimatePresence, motion } from "motion/react";
import Link from "next/link";
import { useCallback, useEffect, useRef, useState } from "react";
import FirecrawlIcon from "@/components/shared/firecrawl-icon/firecrawl-icon";
import Logo from "@/components/shared/header/_svg/Logo";
import { useHeaderContext } from "@/components/shared/header/HeaderContext";
import { cn } from "@/utils/cn";
import Download from "./_svg/Download";
import Guidelines from "./_svg/Guidelines";
import Icon from "./_svg/Icon";
export default function HeaderBrandKit() {
const [open, setOpen] = useState(false);
const { dropdownContent, clearDropdown } = useHeaderContext();
useEffect(() => {
document.addEventListener("click", () => {
setOpen(false);
});
}, [open]);
useEffect(() => {
if (dropdownContent) {
setOpen(false);
}
}, [dropdownContent]);
return (
<div className="relative">
<Link
className="flex items-center gap-2 relative brand-kit-menu"
href="/"
onContextMenu={(e) => {
e.preventDefault();
setOpen(!open);
if (!open) {
clearDropdown(true);
}
}}
>
<FirecrawlIcon className="size-28 -top-2 relative" />
<Logo />
</Link>
<AnimatePresence initial={false} mode="popLayout">
{open && <Menu setOpen={setOpen} />}
</AnimatePresence>
</div>
);
}
const Menu = ({ setOpen }: { setOpen: (open: boolean) => void }) => {
const backgroundRef = useRef<HTMLDivElement>(null);
const timeoutRef = useRef<number | null>(null);
const onMouseEnter = useCallback((e: React.MouseEvent<HTMLButtonElement>) => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
const t = e.target as HTMLElement;
const target =
t instanceof HTMLButtonElement
? t
: (t.closest("button") as HTMLButtonElement);
if (backgroundRef.current) {
animate(backgroundRef.current, { scale: 0.98, opacity: 1 }).then(() => {
if (backgroundRef.current) {
animate(backgroundRef.current!, { scale: 1 });
}
});
animate(
backgroundRef.current,
{
y: target.offsetTop - 4,
},
{
ease: cubicBezier(0.1, 0.1, 0.25, 1),
duration: 0.2,
},
);
}
}, []);
const onMouseLeave = useCallback(() => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
timeoutRef.current = window.setTimeout(() => {
if (backgroundRef.current) {
animate(backgroundRef.current, { scale: 1, opacity: 0 });
}
}, 100);
}, []);
return (
<motion.div
animate={{ opacity: 1, y: 0, scale: 1, filter: "blur(0px)" }}
className="absolute w-220 whitespace-nowrap rounded-16 p-4 bg-white left-0 top-[calc(100%+8px)] z-[2000] border border-border-faint"
exit={{ opacity: 0, y: 8, scale: 0.98, filter: "blur(1px)" }}
initial={{ opacity: 0, y: -6, filter: "blur(1px)" }}
style={{
boxShadow:
"0px 12px 24px rgba(0, 0, 0, 0.08), 0px 4px 8px rgba(0, 0, 0, 0.04)",
}}
transition={{
ease: cubicBezier(0.1, 0.1, 0.25, 1),
duration: 0.2,
}}
>
<div
className="absolute top-4 opacity-0 z-[2] pointer-events-none inset-x-4 bg-black-alpha-4 rounded-8 h-32"
ref={backgroundRef}
/>
<Button
onClick={() => {
window.open("/", "_blank");
setOpen(false);
}}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
<svg
className="w-16 h-16"
fill="none"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 4.5V12.5C12 13.0523 11.5523 13.5 11 13.5H4C3.44772 13.5 3 13.0523 3 12.5V4.5C3 3.94772 3.44772 3.5 4 3.5H7.5M10.5 2.5H13.5M13.5 2.5V5.5M13.5 2.5L8.5 7.5"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.25"
/>
</svg>
Open in new tab
</Button>
<div className="px-8 py-4">
<div className="h-1 w-full bg-black-alpha-5" />
</div>
<Button
onClick={() => {
copy(`<svg fill="none" height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg">
<path
d="M13.7605 6.61389C13.138 6.79867 12.6687 7.21667 12.3251 7.67073C12.2513 7.76819 12.0975 7.69495 12.1268 7.57552C12.7848 4.86978 11.9155 2.6209 9.20582 1.51393C9.06836 1.4576 8.92527 1.58097 8.96132 1.72519C10.1939 6.67417 5.00941 6.25673 5.66459 11.8671C5.67585 11.9634 5.56769 12.0293 5.48882 11.973C5.2432 11.7967 4.96885 11.4288 4.78069 11.1702C4.72548 11.0942 4.60605 11.1156 4.5807 11.2063C4.43085 11.7482 4.35986 12.2586 4.35986 12.7656C4.35986 14.7373 5.37333 16.473 6.90734 17.4791C6.99522 17.5366 7.10789 17.4543 7.07804 17.3535C6.99917 17.0887 6.95466 16.8093 6.95128 16.5203C6.95128 16.3429 6.96255 16.1615 6.99015 15.9925C7.05438 15.5677 7.20197 15.1632 7.44985 14.7948C8.29995 13.5188 10.0041 12.2862 9.73199 10.6125C9.71453 10.5066 9.83959 10.4368 9.91846 10.5094C11.119 11.6063 11.3567 13.0817 11.1595 14.405C11.1426 14.5199 11.2868 14.5813 11.3595 14.4912C11.5432 14.2613 11.7674 14.0596 12.0113 13.9081C12.0722 13.8703 12.1533 13.8991 12.1764 13.9667C12.3121 14.3616 12.5138 14.7323 12.7042 15.1029C12.9318 15.5485 13.0529 16.0573 13.0338 16.5958C13.0242 16.8578 12.9808 17.1113 12.9082 17.3524C12.8772 17.4543 12.9887 17.5394 13.0783 17.4808C14.6134 16.4747 15.6275 14.739 15.6275 12.7662C15.6275 12.0806 15.5075 11.4085 15.2804 10.7787C14.8044 9.45766 13.5966 8.46561 13.9019 6.74403C13.9166 6.66178 13.8405 6.59023 13.7605 6.61389Z"
fill="#262626"
/>
</svg>`);
setOpen(false);
}}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
<Icon />
Copy logo as SVG
</Button>
<Button
onClick={() => {
setOpen(false);
}}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
<Download />
Download brand assets
</Button>
<div className="px-8 py-4">
<div className="h-1 w-full bg-black-alpha-5" />
</div>
<Button
onClick={() => {
setOpen(false);
}}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
<Guidelines />
Visit brand guidelines
</Button>
</motion.div>
);
};
const Button = (attributes: React.ButtonHTMLAttributes<HTMLButtonElement>) => {
return (
<button
{...attributes}
className={cn(
"flex gap-8 w-full items-center text-label-small group text-accent-black p-6",
attributes.className,
)}
>
{attributes.children}
</button>
);
};
@@ -0,0 +1,20 @@
export default function Download() {
return (
<svg
fill="none"
height="20"
viewBox="0 0 20 20"
width="20"
xmlns="http://www.w3.org/2000/svg"
>
<path
className="group-hover:stroke-heat-100 duration-[200ms] transition-all"
d="M12.8334 10.8334L10.4715 13.1953C10.2111 13.4557 9.78904 13.4557 9.52869 13.1953L7.16675 10.8334M10.0001 3.83337V13.1667M14.8334 16.1667H5.16675"
stroke="#262626"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.25"
/>
</svg>
);
}
@@ -0,0 +1,20 @@
export default function Guidelines() {
return (
<svg
fill="none"
height="20"
viewBox="0 0 20 20"
width="20"
xmlns="http://www.w3.org/2000/svg"
>
<path
className="group-hover:stroke-heat-100 duration-[200ms] transition-all"
d="M10.0001 7.16663C10.0001 6.06206 10.8955 5.16663 12.0001 5.16663H15.8334C16.3857 5.16663 16.8334 5.61434 16.8334 6.16663V13.8333C16.8334 14.3856 16.3857 14.8333 15.8334 14.8333H12.1847C11.7311 14.8333 11.2865 14.9427 10.9006 15.1812C10.5148 15.4197 10.2029 15.7609 10.0001 16.1666M10.0001 7.16663C10.0001 6.06206 9.10465 5.16663 8.00008 5.16663H4.16675C3.61446 5.16663 3.16675 5.61434 3.16675 6.16663V13.8333C3.16675 14.3856 3.61446 14.8333 4.16675 14.8333H7.81541C8.26902 14.8333 8.71367 14.9427 9.09953 15.1812C9.48539 15.4197 9.79722 15.7609 10.0001 16.1666M10.0001 7.16663V16.1666"
stroke="#262626"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.25"
/>
</svg>
);
}
@@ -0,0 +1,17 @@
export default function Icon() {
return (
<svg
fill="none"
height="20"
viewBox="0 0 20 20"
width="20"
xmlns="http://www.w3.org/2000/svg"
>
<path
className="group-hover:fill-heat-100 duration-[200ms] transition-all"
d="M13.7605 6.61389C13.138 6.79867 12.6687 7.21667 12.3251 7.67073C12.2513 7.76819 12.0975 7.69495 12.1268 7.57552C12.7848 4.86978 11.9155 2.6209 9.20582 1.51393C9.06836 1.4576 8.92527 1.58097 8.96132 1.72519C10.1939 6.67417 5.00941 6.25673 5.66459 11.8671C5.67585 11.9634 5.56769 12.0293 5.48882 11.973C5.2432 11.7967 4.96885 11.4288 4.78069 11.1702C4.72548 11.0942 4.60605 11.1156 4.5807 11.2063C4.43085 11.7482 4.35986 12.2586 4.35986 12.7656C4.35986 14.7373 5.37333 16.473 6.90734 17.4791C6.99522 17.5366 7.10789 17.4543 7.07804 17.3535C6.99917 17.0887 6.95466 16.8093 6.95128 16.5203C6.95128 16.3429 6.96255 16.1615 6.99015 15.9925C7.05438 15.5677 7.20197 15.1632 7.44985 14.7948C8.29995 13.5188 10.0041 12.2862 9.73199 10.6125C9.71453 10.5066 9.83959 10.4368 9.91846 10.5094C11.119 11.6063 11.3567 13.0817 11.1595 14.405C11.1426 14.5199 11.2868 14.5813 11.3595 14.4912C11.5432 14.2613 11.7674 14.0596 12.0113 13.9081C12.0722 13.8703 12.1533 13.8991 12.1764 13.9667C12.3121 14.3616 12.5138 14.7323 12.7042 15.1029C12.9318 15.5485 13.0529 16.0573 13.0338 16.5958C13.0242 16.8578 12.9808 17.1113 12.9082 17.3524C12.8772 17.4543 12.9887 17.5394 13.0783 17.4808C14.6134 16.4747 15.6275 14.739 15.6275 12.7662C15.6275 12.0806 15.5075 11.4085 15.2804 10.7787C14.8044 9.45766 13.5966 8.46561 13.9019 6.74403C13.9166 6.66178 13.8405 6.59023 13.7605 6.61389Z"
fill="#262626"
/>
</svg>
);
}