import type { Monaco } from "@monaco-editor/react"; import type { editor } from "monaco-editor"; // MDX language configuration export function configureMDX(monaco: Monaco) { // Register MDX as a language monaco.languages.register({ id: "mdx" }); // Set up MDX tokenizer (extends markdown with JSX) monaco.languages.setMonarchTokensProvider("mdx", { defaultToken: "", tokenPostfix: ".mdx", tokenizer: { root: [ // JSX tags [/<\/?[\w-]+/, "tag"], // JSX expressions [/\{[^}]+\}/, "variable"], // Frontmatter [/^---$/, "meta"], // Headers [/^#{1,6}\s.*$/, "keyword"], // Bold [/\*\*[^*]+\*\*/, "strong"], // Italic [/\*[^*]+\*/, "emphasis"], // Inline code [/`[^`]+`/, "string"], // Code blocks [/^```\w*$/, "string"], // Links [/\[[^\]]+\]\([^)]+\)/, "string.link"], // Comments [/{\/\*[\s\S]*?\*\/}/, "comment"], ], }, }); } // Custom themes matching shadcn neutral export function defineEditorThemes(monaco: Monaco) { // Dark theme - transparent background to inherit from parent container monaco.editor.defineTheme("editor-dark", { base: "vs-dark", inherit: true, rules: [ { token: "tag", foreground: "93c5fd" }, // blue-300 { token: "variable", foreground: "fcd34d" }, // yellow-300 { token: "keyword", foreground: "f9fafb" }, // gray-50 { token: "string", foreground: "a5b4fc" }, // indigo-300 { token: "strong", foreground: "f9fafb", fontStyle: "bold" }, { token: "emphasis", foreground: "f9fafb", fontStyle: "italic" }, { token: "meta", foreground: "737373" }, // neutral-500 { token: "comment", foreground: "525252" }, // neutral-600 { token: "string.link", foreground: "60a5fa" }, // blue-400 ], colors: { "editor.background": "#00000000", // transparent - inherits from parent "editor.foreground": "#fafafa", // neutral-50 "editor.lineHighlightBackground": "#26262680", // neutral-800 with alpha "editor.selectionBackground": "#3b82f620", // blue-500/20 "editorLineNumber.foreground": "#737373", // neutral-500 "editorLineNumber.activeForeground": "#a3a3a3", // neutral-400 "editorGutter.background": "#00000000", // transparent - inherits from parent "editorCursor.foreground": "#fafafa", // neutral-50 "editor.inactiveSelectionBackground": "#3b82f610", "editorIndentGuide.background": "#26262680", "editorIndentGuide.activeBackground": "#404040", "editorWidget.background": "#262626", // neutral-800 "editorWidget.border": "#404040", // neutral-700 "editorSuggestWidget.background": "#262626", "editorSuggestWidget.border": "#404040", "editorSuggestWidget.selectedBackground": "#3b82f620", "scrollbar.shadow": "#00000000", "scrollbarSlider.background": "#52525280", "scrollbarSlider.hoverBackground": "#525252", "scrollbarSlider.activeBackground": "#737373", }, }); // Light theme - use explicit light background colors // Note: Transparent backgrounds (#00000000) cause rendering issues in light mode // because Monaco's internal layers don't properly inherit the parent background. // Using explicit colors ensures consistent rendering in both modes. monaco.editor.defineTheme("editor-light", { base: "vs", inherit: true, rules: [ { token: "tag", foreground: "2563eb" }, // blue-600 { token: "variable", foreground: "ca8a04" }, // yellow-600 { token: "keyword", foreground: "171717" }, // neutral-900 { token: "string", foreground: "4f46e5" }, // indigo-600 { token: "strong", foreground: "171717", fontStyle: "bold" }, { token: "emphasis", foreground: "171717", fontStyle: "italic" }, { token: "meta", foreground: "737373" }, // neutral-500 { token: "comment", foreground: "a3a3a3" }, // neutral-400 { token: "string.link", foreground: "2563eb" }, // blue-600 ], colors: { "editor.background": "#ffffff", // white - explicit for light mode "editor.foreground": "#171717", // neutral-900 "editor.lineHighlightBackground": "#f5f5f5", // neutral-100 "editor.selectionBackground": "#3b82f640", // blue-500/25 "editorLineNumber.foreground": "#a3a3a3", // neutral-400 "editorLineNumber.activeForeground": "#525252", // neutral-600 "editorGutter.background": "#ffffff", // white - explicit for light mode "editorCursor.foreground": "#171717", // neutral-900 "editor.inactiveSelectionBackground": "#3b82f620", "editorIndentGuide.background": "#e5e5e5", // neutral-200 "editorIndentGuide.activeBackground": "#d4d4d4", // neutral-300 "editorWidget.background": "#ffffff", // white "editorWidget.border": "#e5e5e5", // neutral-200 "editorSuggestWidget.background": "#ffffff", "editorSuggestWidget.border": "#e5e5e5", "editorSuggestWidget.selectedBackground": "#3b82f630", "scrollbar.shadow": "#00000000", "scrollbarSlider.background": "#d4d4d480", // neutral-300 with alpha "scrollbarSlider.hoverBackground": "#a3a3a3", // neutral-400 "scrollbarSlider.activeBackground": "#737373", // neutral-500 }, }); } // Default editor options export const editorOptions: editor.IStandaloneEditorConstructionOptions = { fontFamily: "Berkeley Mono, JetBrains Mono, Menlo, Monaco, monospace", fontSize: 14, lineHeight: 1.6, fontLigatures: true, tabSize: 2, insertSpaces: true, wordWrap: "on", minimap: { enabled: false }, scrollBeyondLastLine: false, renderLineHighlight: "line", cursorBlinking: "smooth", cursorSmoothCaretAnimation: "on", smoothScrolling: true, lineNumbers: "on", glyphMargin: false, folding: true, padding: { top: 16, bottom: 16 }, scrollbar: { vertical: "auto", horizontal: "auto", verticalScrollbarSize: 10, horizontalScrollbarSize: 10, }, overviewRulerBorder: false, hideCursorInOverviewRuler: true, renderWhitespace: "none", guides: { indentation: true, bracketPairs: false, }, bracketPairColorization: { enabled: false, }, };