"use client"; import "@/style/mdx.css"; import "katex/dist/katex.min.css"; import remarkGfm from "remark-gfm"; import remarkMath from "remark-math"; import rehypeKatex from "rehype-katex"; import { useTheme } from "next-themes"; // import rehypeSlug from "rehype-slug"; import rehypePretty from "rehype-pretty-code"; import { Skeleton } from "@/components/ui/skeleton"; import { serialize } from "next-mdx-remote/serialize"; import { useCallback, useEffect, useState } from "react"; import { CircleAlert, TriangleAlert } from "lucide-react"; import { CodeBlockWithCopy } from "./mdx/code-block-with-copy"; // import rehypeAutolinkHeadings from "rehype-autolink-headings"; import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"; import { MDXRemote, MDXRemoteSerializeResult } from "next-mdx-remote"; interface MdxPreviewProps { source: string; } export default function MdxPreview({ source }: MdxPreviewProps) { const { resolvedTheme } = useTheme(); const [error, setError] = useState(null); const [isLoading, setIsLoading] = useState(true); const [mdxSource, setMdxSource] = useState(null); const components = { // Define your custom components here // For example: // Test: ({ name }: { name: string }) =>

Test Component: {name}

, pre: CodeBlockWithCopy, }; const getMdxSource = useCallback(async () => { setIsLoading(true); setError(null); try { const mdxSource = await serialize(source, { mdxOptions: { rehypePlugins: [ // rehypeSlug, // [ // rehypeAutolinkHeadings, // { // behavior: "wrap", // properties: { // className: ["subheading-anchor"], // ariaLabel: "Link to section", // }, // }, // ], [ rehypePretty, { theme: resolvedTheme === "light" ? "github-light-default" : "github-dark-default", keepBackground: false, }, ], rehypeKatex, ], remarkPlugins: [remarkGfm, remarkMath], }, }); setMdxSource(mdxSource); } catch (error) { console.error("Failed to serialize Mdx:", error); setError("Failed to load mdx content."); } finally { setIsLoading(false); } }, [source, resolvedTheme]); // Delay the serialize process to the next event loop to avoid flickering // when copying code to the editor and the MDX preview shrinks. useEffect(() => { const timeoutId = setTimeout(() => { getMdxSource(); // Execute serializeMdx in the next event loop }, 0); return () => clearTimeout(timeoutId); // Cleanup timeout on component unmount }, [getMdxSource]); if (isLoading) { return ; } if (error) { return (

); } if (!source) { return (

); } return (
); }