| 1 | import Link from "next/link"; |
| 2 | import type { RatatuiCopy } from "@/lib/content/ratatui"; |
| 3 | import heroEntry from "@/public/ratatui/entries/showcase-work.json"; |
| 4 | import type { EntryPreview } from "@/lib/ratatui/catalogue"; |
| 5 | import "./hero.css"; |
| 6 | |
| 7 | const HERO_PROFILE = "dark-truecolor"; |
| 8 | const HERO_SIZE = "native"; |
| 9 | |
| 10 | /** |
| 11 | * The hub hero: one real library render, painted with the page HTML. |
| 12 | * |
| 13 | * The SVG is a generated Ratatui buffer, sanitized by the exporter and |
| 14 | * validated by catalogue.test.ts (no scripts, handlers or external refs), |
| 15 | * so it is safe to inline. Inlining keeps the hero visible with no client |
| 16 | * fetch and no layout shift: the viewBox fixes the aspect ratio. |
| 17 | */ |
| 18 | export function RatatuiHero({ locale, copy }: { locale: string; copy: RatatuiCopy }) { |
| 19 | const preview = (heroEntry as EntryPreview).previews[HERO_PROFILE][HERO_SIZE]; |
| 20 | const narrow = (heroEntry as EntryPreview).previews[HERO_PROFILE]["40"]; |
| 21 | const width = (heroEntry as EntryPreview).width; |
| 22 | const height = (heroEntry as EntryPreview).height; |
| 23 | return ( |
| 24 | <section className="rat-hero" aria-label={copy.heroLabel}> |
| 25 | <figure className="rat-hero-frame"> |
| 26 | <div |
| 27 | className="rat-hero-terminal rat-hero-wide" |
| 28 | role="img" |
| 29 | aria-label={copy.heroAlt} |
| 30 | tabIndex={0} |
| 31 | dir="ltr" |
| 32 | dangerouslySetInnerHTML={{ __html: preview }} |
| 33 | /> |
| 34 | <div |
| 35 | className="rat-hero-terminal rat-hero-narrow" |
| 36 | role="img" |
| 37 | aria-label={copy.heroAlt} |
| 38 | tabIndex={0} |
| 39 | dir="ltr" |
| 40 | dangerouslySetInnerHTML={{ __html: narrow }} |
| 41 | /> |
| 42 | <figcaption className="rat-hero-caption"> |
| 43 | <span className="rat-hero-wide">{copy.heroCaption.replace("{width}", String(width)).replace("{height}", String(height))}</span> |
| 44 | <span className="rat-hero-narrow">{copy.heroCaption.replace("{width}", "40").replace("{height}", String(height))}</span> |
| 45 | <span className="rat-hero-links"> |
| 46 | <a href="#ratatui-explorer">{copy.heroOpenExplorer} ↓</a> |
| 47 | <Link href={`/${locale}/ratatui/showcase-work`}>{copy.heroOpenComponent} →</Link> |
| 48 | </span> |
| 49 | </figcaption> |
| 50 | </figure> |
| 51 | </section> |
| 52 | ); |
| 53 | } |
| 54 |