import type { Extension } from "@codemirror/state"; import type { EditorTheme } from "@/stores/settingsStore"; type CodeMirrorStyleSpec = Parameters[0]; /** Load a CodeMirror theme extension by theme name. */ export async function loadEditorTheme(theme: EditorTheme): Promise { switch (theme) { case "one-dark": return (await import("@codemirror/theme-one-dark")).oneDark; case "vscode-dark": return (await import("@uiw/codemirror-theme-vscode")).vscodeDark; case "vscode-light": return (await import("@uiw/codemirror-theme-vscode")).vscodeLight; case "nord": return (await import("@uiw/codemirror-theme-nord")).nord; case "okaidia": return (await import("@uiw/codemirror-theme-okaidia")).okaidia; case "material": return (await import("@uiw/codemirror-theme-material")).materialDark; case "duotone-light": return (await import("@uiw/codemirror-theme-duotone")).duotoneLight; case "duotone-dark": return (await import("@uiw/codemirror-theme-duotone")).duotoneDark; case "xcode": return (await import("@uiw/codemirror-theme-xcode")).xcodeLight; default: return (await import("@codemirror/theme-one-dark")).oneDark; } } /** Build a CodeMirror theme extension for font size + font family. */ export function editorFontTheme( EditorView: typeof import("@codemirror/view").EditorView, size: number, family: string, opts?: { fixedHeight?: boolean; scrollable?: boolean }, ): Extension { return EditorView.theme({ "&": { ...(opts?.fixedHeight ? { height: "100%" } : {}), fontSize: `${size}px`, }, ...(opts?.scrollable ? { ".cm-scroller": { overflow: "auto" } } : {}), ".cm-content": { fontFamily: family }, ".cm-gutters": { borderRight: "0 !important", position: "relative", }, ".cm-gutters:after": { background: "rgba(148, 163, 184, 0.38)", bottom: "0", content: "''", pointerEvents: "none", position: "absolute", right: "0", top: "0", width: "1px", zIndex: "10", }, ".cm-lineNumbers .cm-gutterElement": { paddingRight: "16px", }, }); } export function buildSqlCompletionThemeRules(): CodeMirrorStyleSpec { return { ".cm-tooltip.cm-tooltip-autocomplete": { background: "#24272c", border: "1px solid rgba(10, 12, 16, 0.95)", borderRadius: "10px", boxShadow: "0 18px 42px rgba(0, 0, 0, 0.46), 0 0 0 1px rgba(255, 255, 255, 0.08) inset, 0 1px 0 rgba(255, 255, 255, 0.06) inset", color: "rgba(202, 207, 217, 0.95)", fontFamily: "var(--font-mono, 'JetBrains Mono', 'SF Mono', monospace)", minWidth: "420px", overflow: "hidden", padding: "6px 0", }, ".cm-tooltip.cm-tooltip-autocomplete > ul": { maxHeight: "340px", minWidth: "420px", padding: "0 7px 0 !important", scrollbarColor: "rgba(148, 153, 162, 0.42) transparent", scrollbarWidth: "thin", }, ".cm-tooltip.cm-tooltip-autocomplete > ul > li": { alignItems: "center", borderRadius: "6px", color: "rgba(199, 204, 214, 0.92)", display: "flex", fontSize: "16px", fontWeight: "760", height: "34px", letterSpacing: "0", lineHeight: "34px", padding: "0 18px !important", transition: "background-color 90ms ease, color 90ms ease", }, ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": { background: "rgba(70, 75, 84, 0.86) !important", color: "rgba(231, 235, 243, 0.98) !important", }, ".cm-completionIcon": { display: "none !important", height: "0", margin: "0", paddingRight: "0 !important", width: "0", }, ".cm-completionLabel": { color: "inherit", fontFamily: "var(--font-mono, 'JetBrains Mono', 'SF Mono', monospace)", fontSize: "16px", fontWeight: "760", letterSpacing: "0", }, ".cm-completionMatchedText": { color: "#5794f9", fontWeight: "860", textDecoration: "none", }, ".cm-completionDetail": { color: "rgba(184, 188, 198, 0.92)", fontSize: "16px", fontWeight: "760", fontStyle: "normal", marginLeft: "12px", opacity: "1", }, }; } export function sqlCompletionTheme(EditorView: typeof import("@codemirror/view").EditorView): Extension { return EditorView.theme(buildSqlCompletionThemeRules()); }