"use client"; import type { JSX } from "react"; import { bundledLanguages, codeToHast, type BundledLanguage, } from "shiki/bundle/web"; import { Fragment, useLayoutEffect, useState } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; import { toJsxRuntime } from "hast-util-to-jsx-runtime"; import { safe } from "ts-safe"; import { cn } from "lib/utils"; import { useTheme } from "next-themes"; import { Button } from "ui/button"; import { CheckIcon, CopyIcon } from "lucide-react"; import JsonView from "ui/json-view"; import { useCopy } from "@/hooks/use-copy"; import dynamic from "next/dynamic"; // Dynamically import MermaidDiagram component const MermaidDiagram = dynamic( () => import("./mermaid-diagram").then((mod) => mod.MermaidDiagram), { loading: () => (
mermaid
Loading Mermaid renderer...
), ssr: false, }, ); const PurePre = ({ children, className, code, lang, }: { children: any; className?: string; code: string; lang: string; }) => { const { copied, copy } = useCopy(); return (
      
{lang}
{children}
); }; export async function Highlight( code: string, lang: BundledLanguage | (string & {}), theme: string, ) { const parsed: BundledLanguage = ( bundledLanguages[lang] ? lang : "md" ) as BundledLanguage; if (lang === "json") { return ( ); } if (lang === "mermaid") { return ( ); } const out = await codeToHast(code, { lang: parsed, theme, }); return toJsxRuntime(out, { Fragment, jsx, jsxs, components: { pre: (props) => , }, }) as JSX.Element; } export function PreBlock({ children }: { children: any }) { const code = children.props.children; const { theme } = useTheme(); const language = children.props.className?.split("-")?.[1] || "bash"; const [loading, setLoading] = useState(true); const [component, setComponent] = useState( {children} , ); useLayoutEffect(() => { safe() .map(() => Highlight( code, language, theme == "dark" ? "dark-plus" : "github-light", ), ) .ifOk(setComponent) .watch(() => setLoading(false)); }, [theme, language, code]); // For other code blocks, render as before return (
{component}
); }