- new design system in globals.css: warm graphite surfaces, ivory text, honey accent; semantic status/data-type/syntax tokens replacing hardcoded colors - IBM Plex Mono as the universal UI font (sans + mono), tabular numerals - custom CodeMirror SQL theme (src/lib/editor-theme.ts) matching the palette - data grid: zebra striping + honey row hover, stronger sticky header - route status dots, JSON syntax, EXPLAIN cost, schema-tree icons and the read/write toggle through the new tokens - TUSK wordmark in the toolbar
103 lines
4.2 KiB
TypeScript
103 lines
4.2 KiB
TypeScript
import { EditorView } from "@codemirror/view";
|
|
import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
import { tags as t } from "@lezer/highlight";
|
|
import type { Extension } from "@codemirror/state";
|
|
|
|
/* ───────────────────────────────────────────────────────────
|
|
Tusk "Graphite & Honey" CodeMirror theme.
|
|
Palette mirrors the design tokens in styles/globals.css so the
|
|
SQL editor sits seamlessly inside the warm graphite workstation.
|
|
─────────────────────────────────────────────────────────── */
|
|
|
|
const c = {
|
|
bg: "oklch(0.186 0.006 75)",
|
|
surface: "oklch(0.205 0.007 75)",
|
|
fg: "oklch(0.9 0.013 80)",
|
|
faint: "oklch(0.52 0.012 75)",
|
|
gutter: "oklch(0.46 0.011 75)",
|
|
gutterActive: "oklch(0.74 0.012 80)",
|
|
cursor: "oklch(0.84 0.13 82)",
|
|
selection: "oklch(0.808 0.124 82 / 22%)",
|
|
activeLine: "oklch(0.808 0.124 82 / 5%)",
|
|
activeGutter: "oklch(0.808 0.124 82 / 9%)",
|
|
matchBg: "oklch(0.808 0.124 82 / 18%)",
|
|
|
|
// syntax
|
|
keyword: "oklch(0.82 0.125 82)", // honey — SELECT, FROM, WHERE
|
|
string: "oklch(0.76 0.13 152)", // green
|
|
number: "oklch(0.74 0.12 222)", // cyan-blue
|
|
func: "oklch(0.74 0.15 305)", // violet — built-ins
|
|
type: "oklch(0.74 0.12 200)", // teal-cyan — types
|
|
comment: "oklch(0.5 0.012 75)", // muted, italic
|
|
operator: "oklch(0.74 0.013 80)",
|
|
bracket: "oklch(0.66 0.012 78)",
|
|
invalid: "oklch(0.66 0.2 24)",
|
|
};
|
|
|
|
const tuskEditorTheme = EditorView.theme(
|
|
{
|
|
"&": {
|
|
color: c.fg,
|
|
backgroundColor: c.bg,
|
|
},
|
|
".cm-content": {
|
|
caretColor: c.cursor,
|
|
fontFamily: "var(--font-mono)",
|
|
padding: "8px 0",
|
|
},
|
|
".cm-cursor, .cm-dropCursor": { borderLeftColor: c.cursor, borderLeftWidth: "2px" },
|
|
"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection":
|
|
{ backgroundColor: c.selection },
|
|
".cm-activeLine": { backgroundColor: c.activeLine },
|
|
".cm-gutters": {
|
|
backgroundColor: c.bg,
|
|
color: c.gutter,
|
|
border: "none",
|
|
borderRight: "1px solid oklch(0.34 0.011 75 / 50%)",
|
|
},
|
|
".cm-activeLineGutter": {
|
|
backgroundColor: c.activeGutter,
|
|
color: c.gutterActive,
|
|
},
|
|
".cm-foldGutter .cm-gutterElement": { color: c.faint },
|
|
".cm-selectionMatch": { backgroundColor: c.matchBg },
|
|
"&.cm-focused .cm-matchingBracket": {
|
|
backgroundColor: c.matchBg,
|
|
outline: "1px solid oklch(0.808 0.124 82 / 45%)",
|
|
borderRadius: "2px",
|
|
},
|
|
".cm-line": { padding: "0 4px 0 8px" },
|
|
".cm-scroller": { fontFamily: "var(--font-mono)" },
|
|
".cm-panels": { backgroundColor: c.surface, color: c.fg },
|
|
".cm-searchMatch": {
|
|
backgroundColor: "oklch(0.78 0.135 65 / 28%)",
|
|
outline: "1px solid oklch(0.78 0.135 65 / 50%)",
|
|
},
|
|
".cm-searchMatch.cm-searchMatch-selected": {
|
|
backgroundColor: "oklch(0.808 0.124 82 / 35%)",
|
|
},
|
|
},
|
|
{ dark: true }
|
|
);
|
|
|
|
const tuskHighlightStyle = HighlightStyle.define([
|
|
{ tag: [t.keyword, t.operatorKeyword, t.modifier], color: c.keyword, fontWeight: "500" },
|
|
{ tag: [t.string, t.special(t.string), t.character], color: c.string },
|
|
{ tag: [t.number, t.bool, t.null], color: c.number },
|
|
{ tag: [t.function(t.variableName), t.function(t.propertyName)], color: c.func },
|
|
{ tag: [t.typeName, t.className, t.namespace], color: c.type },
|
|
{ tag: [t.comment, t.lineComment, t.blockComment], color: c.comment, fontStyle: "italic" },
|
|
{ tag: [t.operator, t.compareOperator, t.arithmeticOperator, t.logicOperator], color: c.operator },
|
|
{ tag: [t.bracket, t.paren, t.squareBracket, t.brace, t.punctuation], color: c.bracket },
|
|
{ tag: [t.propertyName, t.attributeName], color: c.fg },
|
|
{ tag: [t.variableName, t.name], color: c.fg },
|
|
{ tag: [t.definitionKeyword], color: c.keyword, fontWeight: "500" },
|
|
{ tag: [t.invalid], color: c.invalid, textDecoration: "underline wavy" },
|
|
]);
|
|
|
|
/** Full Tusk editor theme: base UI styling + SQL syntax highlighting. */
|
|
export const tuskEditorExtensions: Extension = [
|
|
tuskEditorTheme,
|
|
syntaxHighlighting(tuskHighlightStyle),
|
|
];
|