"use client"; import { Button } from "@mdxui/primitives/button"; import { Card } from "@mdxui/primitives/card"; import { cn } from "@mdxui/primitives/lib/utils"; import { AlertCircle, Edit3, Eye, Split } from "lucide-react"; import type React from "react"; import { useCallback, useEffect, useState } from "react"; import { createHighlighter, type Highlighter } from "shiki"; export interface MDXEditorProps { /** Initial MDX content */ initialValue?: string; /** Callback when content changes */ onChange?: (value: string) => void; /** Placeholder text */ placeholder?: string; /** Default view mode */ defaultMode?: "edit" | "preview" | "split"; /** Height of the editor */ height?: string | number; /** Additional CSS class */ className?: string; /** Whether the editor is read-only */ readOnly?: boolean; /** Custom preview renderer */ renderPreview?: (mdx: string) => Promise | React.ReactNode; /** Available components for MDX */ components?: Record>; /** Show syntax errors */ showErrors?: boolean; } export const MDXEditor: React.FC = ({ initialValue = "", onChange, placeholder = "# Start writing MDX\n\nImport and use React components...", defaultMode = "split", height = 500, className, readOnly = false, renderPreview, components: _components = {}, showErrors = true, }) => { const [content, setContent] = useState(initialValue); const [mode, setMode] = useState<"edit" | "preview" | "split">(defaultMode); const [highlighter, setHighlighter] = useState(null); const [previewContent, setPreviewContent] = useState(null); const [error, setError] = useState(null); useEffect(() => { createHighlighter({ themes: ["github-dark"], langs: ["mdx", "jsx", "tsx"], }).then(setHighlighter); }, []); const handleChange = useCallback( (value: string) => { setContent(value); onChange?.(value); setError(null); }, [onChange], ); useEffect(() => { if (mode === "preview" || mode === "split") { if (renderPreview) { Promise.resolve(renderPreview(content)) .then((result) => { setPreviewContent(result); setError(null); }) .catch((err) => { setError(err.message || "Failed to render MDX"); setPreviewContent(null); }); } else { // Default preview using syntax highlighting setPreviewContent(
{content || placeholder}
, ); } } }, [content, mode, renderPreview, placeholder]); const highlightedCode = highlighter ? highlighter.codeToHtml(content || placeholder, { lang: "mdx", theme: "github-dark", }) : ""; const toolbar = (
); const editorArea = (