From 370944f443cb997ef71dda0c8ef6f4e92bea87d7 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Wed, 15 Apr 2026 02:05:41 +0200 Subject: feat: new-release notice and colocate changelog under domain --- apps/web/src/lib/changelog/components/release.tsx | 153 ++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 apps/web/src/lib/changelog/components/release.tsx (limited to 'apps/web/src/lib/changelog/components/release.tsx') diff --git a/apps/web/src/lib/changelog/components/release.tsx b/apps/web/src/lib/changelog/components/release.tsx new file mode 100644 index 00000000..475b0a6d --- /dev/null +++ b/apps/web/src/lib/changelog/components/release.tsx @@ -0,0 +1,153 @@ +import type { ReactNode } from "react"; +import Link from "next/link"; +import { cn } from "@/utils/ui"; +import { ReactMarkdownWrapper } from "@/components/ui/react-markdown-wrapper"; +import { + getSectionTitle, + groupAndOrderChanges, + isSectionCollapsible, + type Change, + type Release, +} from "../utils"; +import { ArrowRightIcon } from "@hugeicons/core-free-icons"; +import { HugeiconsIcon } from "@hugeicons/react"; + +export function ReleaseArticle({ + variant, + isLatest, + children, +}: { + variant: "list" | "detail"; + isLatest?: boolean; + children: ReactNode; +}) { + if (variant === "list") { + return ( +
+
+
+
+
{children}
+
+ ); + } + + return
{children}
; +} + +export function ReleaseMeta({ release }: { release: Release }) { + return ( + + {release.version} — {release.date} + + ); +} + +const titleSizes: Record<"h1" | "h2", string> = { + h1: "text-4xl", + h2: "text-2xl", +}; + +export function ReleaseTitle({ + as: As, + href, + children, +}: { + as: "h1" | "h2"; + href?: string; + children: ReactNode; +}) { + return ( + + {href ? ( + + {children} + + ) : ( + children + )} + + ); +} + +export function ReleaseDescription({ children }: { children: ReactNode }) { + return ( +

+ {children} +

+ ); +} + +export function ReleaseChanges({ release }: { release: Release }) { + const { grouped, orderedTypes } = groupAndOrderChanges({ + changes: release.changes, + }); + + return ( +
+ {orderedTypes.map((type) => ( + + ))} +
+ ); +} + +function ReleaseChangeSection({ + type, + changes, +}: { + type: string; + changes: Change[]; +}) { + const title = getSectionTitle({ type }); + + if (isSectionCollapsible({ type })) { + return ( +
+ + {title}: + + + +
+ ); + } + + return ( +
+

{title}:

+ +
+ ); +} + +function ReleaseChangeList({ + changes, + className, +}: { + changes: Change[]; + className?: string; +}) { + return ( + + ); +} -- cgit v1.3.1