From 80d5a5de0b836f70c5fe90f6946f4e7c05bb89ea Mon Sep 17 00:00:00 2001 From: KinfeMichael Tariku <65047246+Kinfe123@users.noreply.github.com> Date: Fri, 21 Mar 2025 15:41:10 +0300 Subject: [PATCH] docs: add branding assets (#1900) * feat: branding with multiple variant --------- Co-authored-by: Bereket Engida --- docs/app/layout.tsx | 2 + docs/components/logo-context-menu.tsx | 205 ++++++++++++++++++ docs/components/nav-bar.tsx | 69 +++++- .../branding/better-auth-brand-assets.zip | Bin 0 -> 20251 bytes .../public/branding/better-auth-logo-dark.png | Bin 0 -> 2261 bytes .../public/branding/better-auth-logo-dark.svg | 8 + .../branding/better-auth-logo-light.png | Bin 0 -> 2254 bytes .../branding/better-auth-logo-light.svg | 8 + .../better-auth-logo-wordmark-dark.png | Bin 0 -> 5488 bytes .../better-auth-logo-wordmark-dark.svg | 9 + .../better-auth-logo-wordmark-light.png | Bin 0 -> 5947 bytes .../better-auth-logo-wordmark-light.svg | 9 + 12 files changed, 302 insertions(+), 8 deletions(-) create mode 100644 docs/components/logo-context-menu.tsx create mode 100644 docs/public/branding/better-auth-brand-assets.zip create mode 100644 docs/public/branding/better-auth-logo-dark.png create mode 100644 docs/public/branding/better-auth-logo-dark.svg create mode 100644 docs/public/branding/better-auth-logo-light.png create mode 100644 docs/public/branding/better-auth-logo-light.svg create mode 100644 docs/public/branding/better-auth-logo-wordmark-dark.png create mode 100644 docs/public/branding/better-auth-logo-wordmark-dark.svg create mode 100644 docs/public/branding/better-auth-logo-wordmark-light.png create mode 100644 docs/public/branding/better-auth-logo-wordmark-light.svg diff --git a/docs/app/layout.tsx b/docs/app/layout.tsx index 83a89c33da..7bf0ab074e 100644 --- a/docs/app/layout.tsx +++ b/docs/app/layout.tsx @@ -8,6 +8,7 @@ import { GeistSans } from "geist/font/sans"; import { baseUrl, createMetadata } from "@/lib/metadata"; import { Analytics } from "@vercel/analytics/react"; import { ThemeProvider } from "@/components/theme-provider"; +import { Toaster } from "@/components/ui/sonner"; export const metadata = createMetadata({ title: { @@ -53,6 +54,7 @@ export default function Layout({ children }: { children: ReactNode }) { {children} + diff --git a/docs/components/logo-context-menu.tsx b/docs/components/logo-context-menu.tsx new file mode 100644 index 0000000000..787218b9e3 --- /dev/null +++ b/docs/components/logo-context-menu.tsx @@ -0,0 +1,205 @@ +"use client"; + +import type React from "react"; +import { useState, useRef, useEffect } from "react"; +import { Code, Image, Type } from "lucide-react"; +import { toast } from "sonner"; +import { useTheme } from "next-themes"; +import type { StaticImageData } from "next/image"; + +interface LogoAssets { + darkSvg: string; + whiteSvg: string; + darkWordmark: string; + whiteWordmark: string; + darkPng: StaticImageData; + whitePng: StaticImageData; +} + +interface ContextMenuProps { + logo: React.ReactNode; + logoAssets: LogoAssets; +} + +export default function LogoContextMenu({ + logo, + logoAssets, +}: ContextMenuProps) { + const [showMenu, setShowMenu] = useState(false); + const menuRef = useRef(null); + const logoRef = useRef(null); + const { theme } = useTheme(); + + const handleContextMenu = (e: React.MouseEvent) => { + e.preventDefault(); + const rect = logoRef.current?.getBoundingClientRect(); + if (rect) { + setShowMenu(true); + } + }; + + const copySvgToClipboard = (svgContent: string, type: string) => { + navigator.clipboard + .writeText(svgContent) + .then(() => { + toast.success("", { + description: `${type} copied to clipboard`, + }); + }) + .catch((err) => { + toast.error("", { + description: `Failed to copy ${type} to clipboard`, + }); + }); + setShowMenu(false); + }; + + const downloadPng = (pngData: StaticImageData, fileName: string) => { + const link = document.createElement("a"); + link.href = pngData.src; + link.download = fileName; + + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + toast.success(`Downloading the asset...`); + + setShowMenu(false); + }; + + const downloadAllAssets = () => { + const link = document.createElement("a"); + link.href = "/branding/better-auth-brand-assets.zip"; + link.download = "better-auth-branding-assets.zip"; + + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + toast.success("Downloading all assets..."); + setShowMenu(false); + }; + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (menuRef.current && !menuRef.current.contains(event.target as Node)) { + setShowMenu(false); + } + }; + + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, []); + + const getAsset = (darkAsset: T, lightAsset: T): T => { + return theme === "dark" ? darkAsset : lightAsset; + }; + + return ( +
+
+ {logo} +
+ + {showMenu && ( +
+
+
+ +
+ + +
+ +
+ +
+
+
+ )} +
+ ); +} diff --git a/docs/components/nav-bar.tsx b/docs/components/nav-bar.tsx index 54306c44ce..084b1ea554 100644 --- a/docs/components/nav-bar.tsx +++ b/docs/components/nav-bar.tsx @@ -3,20 +3,73 @@ import { ThemeToggle } from "@/components/theme-toggler"; import { NavbarMobile, NavbarMobileBtn } from "./nav-mobile"; import { NavLink } from "./nav-link"; import { Logo } from "./logo"; - +import LogoContextMenu from "./logo-context-menu"; +import DarkPng from "../public/branding/better-auth-logo-dark.png"; +import WhitePng from "../public/branding/better-auth-logo-light.png"; export const Navbar = () => { + const logoAssets = { + darkSvg: ` + + + + + + + + + `, + whiteSvg: ` + + + + + + + + + `, + darkWordmark: ` + + + + + + + + + + `, + whiteWordmark: ` + + + + + + + + + + `, + darkPng: DarkPng, + whitePng: WhitePng, + }; return ( -
-