fix(editor): refine completion popup styling

This commit is contained in:
t8y2 2026-05-22 16:53:53 +08:00
parent b0a4061484
commit ac32914797
3 changed files with 58 additions and 37 deletions

View File

@ -719,7 +719,7 @@ onMounted(async () => {
if (!editorRef.value) return;
const [
{ EditorView, keymap, rectangularSelection, hoverTooltip, showTooltip, Decoration },
{ EditorView, keymap, rectangularSelection, hoverTooltip, showTooltip, Decoration, tooltips },
{ EditorState, Compartment, Prec, StateEffect, StateField },
{ sql, MSSQL, MySQL, PostgreSQL, SQLDialect },
{ basicSetup },
@ -825,6 +825,7 @@ onMounted(async () => {
}),
basicSetup,
sql({ dialect }),
tooltips({ parent: document.body }),
autocompletion({
activateOnTyping: true,
override: [

View File

@ -91,40 +91,41 @@ export function editorFontTheme(
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",
background: "var(--popover)",
border: "1px solid color-mix(in oklch, var(--border) 82%, var(--foreground) 18%)",
borderRadius: "8px",
boxShadow: "0 8px 18px rgb(0 0 0 / 0.14)",
color: "var(--popover-foreground)",
fontFamily: `var(${EDITOR_FONT_FAMILY_CSS_VAR}, var(--font-mono, monospace))`,
maxWidth: "min(520px, calc(100vw - 24px))",
minWidth: "min(280px, calc(100vw - 24px))",
overflow: "hidden",
padding: "6px 0",
padding: "4px 0",
},
".cm-tooltip.cm-tooltip-autocomplete > ul": {
maxHeight: "340px",
minWidth: "420px",
padding: "0 7px 0 !important",
scrollbarColor: "rgba(148, 153, 162, 0.42) transparent",
maxHeight: "min(280px, calc(100vh - 32px))",
minWidth: "min(280px, calc(100vw - 24px))",
padding: "0 4px 0 !important",
scrollbarColor: "color-mix(in oklch, var(--muted-foreground) 44%, transparent) transparent",
scrollbarWidth: "thin",
},
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {
alignItems: "center",
borderRadius: "6px",
color: "rgba(199, 204, 214, 0.92)",
color: "var(--popover-foreground)",
display: "flex",
fontSize: "16px",
fontWeight: "760",
height: "34px",
fontSize: `clamp(12px, var(${EDITOR_FONT_SIZE_CSS_VAR}, 13px), 14px)`,
fontWeight: "520",
height: "28px",
letterSpacing: "0",
lineHeight: "34px",
padding: "0 18px !important",
lineHeight: "28px",
padding: "0 10px !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",
background: "color-mix(in oklch, var(--primary) 14%, var(--popover)) !important",
color: "var(--popover-foreground) !important",
outline: "1px solid color-mix(in oklch, var(--primary) 22%, transparent)",
},
".cm-completionIcon": {
display: "none !important",
@ -135,22 +136,22 @@ export function buildSqlCompletionThemeRules(): CodeMirrorStyleSpec {
},
".cm-completionLabel": {
color: "inherit",
fontFamily: "var(--font-mono, 'JetBrains Mono', 'SF Mono', monospace)",
fontSize: "16px",
fontWeight: "760",
fontFamily: `var(${EDITOR_FONT_FAMILY_CSS_VAR}, var(--font-mono, monospace))`,
fontSize: `clamp(12px, var(${EDITOR_FONT_SIZE_CSS_VAR}, 13px), 14px)`,
fontWeight: "520",
letterSpacing: "0",
},
".cm-completionMatchedText": {
color: "#5794f9",
fontWeight: "860",
color: "oklch(0.62 0.19 255)",
fontWeight: "700",
textDecoration: "none",
},
".cm-completionDetail": {
color: "rgba(184, 188, 198, 0.92)",
fontSize: "16px",
fontWeight: "760",
color: "color-mix(in oklch, var(--popover-foreground) 68%, var(--popover))",
fontSize: `clamp(11px, calc(var(${EDITOR_FONT_SIZE_CSS_VAR}, 13px) - 1px), 13px)`,
fontWeight: "500",
fontStyle: "normal",
marginLeft: "12px",
marginLeft: "10px",
opacity: "1",
},
};

View File

@ -1,4 +1,5 @@
import { strict as assert } from "node:assert";
import { readFileSync } from "node:fs";
import test from "node:test";
import {
buildEditorFontThemeRules,
@ -10,7 +11,18 @@ import {
test("sql completion theme styles the autocomplete popup", () => {
const rules = buildSqlCompletionThemeRules();
assert.ok(rules[".cm-tooltip.cm-tooltip-autocomplete"]);
assert.deepEqual(rules[".cm-tooltip.cm-tooltip-autocomplete"], {
background: "var(--popover)",
border: "1px solid color-mix(in oklch, var(--border) 82%, var(--foreground) 18%)",
borderRadius: "8px",
boxShadow: "0 8px 18px rgb(0 0 0 / 0.14)",
color: "var(--popover-foreground)",
fontFamily: `var(${EDITOR_FONT_FAMILY_CSS_VAR}, var(--font-mono, monospace))`,
maxWidth: "min(520px, calc(100vw - 24px))",
minWidth: "min(280px, calc(100vw - 24px))",
overflow: "hidden",
padding: "4px 0",
});
assert.deepEqual(rules[".cm-completionIcon"], {
display: "none !important",
height: "0",
@ -20,18 +32,25 @@ test("sql completion theme styles the autocomplete popup", () => {
});
assert.deepEqual(rules[".cm-completionLabel"], {
color: "inherit",
fontFamily: "var(--font-mono, 'JetBrains Mono', 'SF Mono', monospace)",
fontSize: "16px",
fontWeight: "760",
fontFamily: `var(${EDITOR_FONT_FAMILY_CSS_VAR}, var(--font-mono, monospace))`,
fontSize: `clamp(12px, var(${EDITOR_FONT_SIZE_CSS_VAR}, 13px), 14px)`,
fontWeight: "520",
letterSpacing: "0",
});
assert.equal(rules[".cm-completionMatchedText"]?.color, "#5794f9");
assert.equal(rules[".cm-completionMatchedText"]?.color, "oklch(0.62 0.19 255)");
assert.equal(
rules[".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]"]?.background,
"rgba(70, 75, 84, 0.86) !important",
"color-mix(in oklch, var(--primary) 14%, var(--popover)) !important",
);
});
test("query editor portals CodeMirror tooltips outside clipped editor panes", () => {
const source = readFileSync("apps/desktop/src/components/editor/QueryEditor.vue", "utf8");
assert.match(source, /tooltips/);
assert.match(source, /tooltips\(\{\s*parent:\s*document\.body\s*\}\)/s);
});
test("editor font theme reads size and family from CSS variables", () => {
const rules = buildEditorFontThemeRules({ fixedHeight: true, scrollable: true });