branch:
CodeExplanation.tsx
2649 bytesRaw
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<Highlighter> | 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 (
      <pre className="font-mono text-sm p-3 rounded-md bg-kumo-base border border-kumo-fill overflow-x-auto leading-relaxed">
        <code>{code}</code>
      </pre>
    );
  }

  return (
    <div
      className="rounded-md overflow-x-auto text-sm [&_pre]:p-3 [&_pre]:!bg-kumo-base [&_pre]:!leading-relaxed border border-kumo-fill"
      dangerouslySetInnerHTML={{ __html: html }}
    />
  );
}

export function HighlightedJson({ data }: { data: unknown }) {
  const code = JSON.stringify(data, null, 2);
  return <HighlightedCode code={code} lang="json" />;
}

export function CodeExplanation({ sections }: CodeExplanationProps) {
  return (
    <Surface className="rounded-lg ring ring-kumo-line mt-6">
      <div className="flex items-center gap-2 px-4 py-3 border-b border-kumo-line">
        <CodeIcon size={18} className="text-kumo-subtle" />
        <Text variant="secondary" size="sm" bold>
          How it works
        </Text>
      </div>

      <div className="px-4 pb-4 space-y-6 pt-4">
        {sections.map((section, i) => (
          <div key={i}>
            <Text bold size="sm">
              {section.title}
            </Text>
            <p className="text-sm text-kumo-subtle mt-1 mb-3 leading-relaxed">
              {section.description}
            </p>
            <HighlightedCode code={section.code} />
          </div>
        ))}
      </div>
    </Surface>
  );
}