import { useEffect, useState } from "react"; import { Surface, Text } from "@cloudflare/kumo"; import { CodeIcon } from "@phosphor-icons/react"; import { createHighlighter, type Highlighter } from "shiki"; import { useTheme } from "../hooks/useTheme"; let highlighterPromise: Promise | null = null; function getHighlighter() { if (!highlighterPromise) { highlighterPromise = createHighlighter({ themes: ["github-light", "github-dark"], langs: ["typescript", "json"] }); } return highlighterPromise; } export interface CodeSection { title: string; description: string; code: string; } interface CodeExplanationProps { sections: CodeSection[]; } export function HighlightedCode({ code, lang = "typescript" }: { code: string; lang?: "typescript" | "json"; }) { const { resolvedMode } = useTheme(); const theme = resolvedMode === "dark" ? "github-dark" : "github-light"; const [html, setHtml] = useState(""); useEffect(() => { let cancelled = false; getHighlighter().then((h) => { if (cancelled) return; setHtml(h.codeToHtml(code, { lang, theme })); }); return () => { cancelled = true; }; }, [code, lang, theme]); if (!html) { return (
        {code}
      
); } return (
); } export function HighlightedJson({ data }: { data: unknown }) { const code = JSON.stringify(data, null, 2); return ; } export function CodeExplanation({ sections }: CodeExplanationProps) { return (
How it works
{sections.map((section, i) => (
{section.title}

{section.description}

))}
); }