diff --git a/demo/index.ts b/demo/index.ts index ae2c533..67915b0 100644 --- a/demo/index.ts +++ b/demo/index.ts @@ -3,10 +3,12 @@ import { PostgreSQL, sql } from "@codemirror/lang-sql"; import { type EditorState, StateEffect, StateField } from "@codemirror/state"; import { keymap } from "@codemirror/view"; import { basicSetup, EditorView } from "codemirror"; -import { NodeSqlParser } from "../src/index.js"; -import { cteCompletionSource } from "../src/sql/cte-completion-source.js"; -import { sqlExtension } from "../src/sql/extension.js"; -import { DefaultSqlTooltipRenders } from "../src/sql/hover.js"; +import { + cteCompletionSource, + DefaultSqlTooltipRenders, + NodeSqlParser, + sqlExtension, +} from "../src/index.js"; import { type Schema, tableTooltipRenderer } from "./custom-renderers.js"; // Default SQL content for the demo diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index 564d52d..793aced 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -8,12 +8,13 @@ describe("index.ts exports", () => { const sortedExports = Object.keys(exports).sort(); expect(sortedExports).toMatchInlineSnapshot(` [ + "DefaultSqlTooltipRenders", "NodeSqlParser", "SqlStructureAnalyzer", "cteCompletionSource", + "defaultSqlHoverTheme", "sqlExtension", "sqlHover", - "sqlHoverTheme", "sqlLinter", "sqlStructureGutter", ] diff --git a/src/index.ts b/src/index.ts index 168e6c3..d5f81d5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,7 +7,7 @@ export type { SqlHoverConfig, SqlKeywordInfo, } from "./sql/hover.js"; -export { sqlHover, sqlHoverTheme } from "./sql/hover.js"; +export { DefaultSqlTooltipRenders, defaultSqlHoverTheme, sqlHover } from "./sql/hover.js"; export { NodeSqlParser } from "./sql/parser.js"; export type { SqlStatement } from "./sql/structure-analyzer.js"; export { SqlStructureAnalyzer } from "./sql/structure-analyzer.js"; diff --git a/src/sql/__tests__/hover-integration.test.ts b/src/sql/__tests__/hover-integration.test.ts index 9b52dd5..e0114ac 100644 --- a/src/sql/__tests__/hover-integration.test.ts +++ b/src/sql/__tests__/hover-integration.test.ts @@ -1,7 +1,7 @@ import type { Completion } from "@codemirror/autocomplete"; import type { SQLNamespace } from "@codemirror/lang-sql"; import { describe, expect, it, vi } from "vitest"; -import { sqlHover, sqlHoverTheme } from "../hover.js"; +import { defaultSqlHoverTheme, sqlHover } from "../hover.js"; import { resolveNamespaceItem } from "../namespace-utils.js"; // Helper function to create completion objects @@ -73,7 +73,7 @@ describe("Hover Integration Tests", () => { it("should create hover theme without errors", () => { expect(() => { - sqlHoverTheme(); + defaultSqlHoverTheme(); }).not.toThrow(); }); diff --git a/src/sql/extension.ts b/src/sql/extension.ts index e04d9b6..25e4236 100644 --- a/src/sql/extension.ts +++ b/src/sql/extension.ts @@ -1,6 +1,6 @@ import type { Extension } from "@codemirror/state"; import { type SqlLinterConfig, sqlLinter } from "./diagnostics.js"; -import { type SqlHoverConfig, sqlHover, sqlHoverTheme } from "./hover.js"; +import { defaultSqlHoverTheme, type SqlHoverConfig, sqlHover } from "./hover.js"; import { type SqlGutterConfig, sqlStructureGutter } from "./structure-extension.js"; /** @@ -68,7 +68,9 @@ export function sqlExtension(config: SqlExtensionConfig = {}): Extension[] { if (enableHover) { extensions.push(sqlHover(hoverConfig)); - extensions.push(sqlHoverTheme()); + hoverConfig?.theme + ? extensions.push(hoverConfig.theme) + : extensions.push(defaultSqlHoverTheme()); } return extensions; diff --git a/src/sql/hover.ts b/src/sql/hover.ts index 49a416b..ee401e6 100644 --- a/src/sql/hover.ts +++ b/src/sql/hover.ts @@ -125,6 +125,8 @@ export interface SqlHoverConfig { /** Custom renderer for column items */ column?: (data: NamespaceTooltipData) => string; }; + /** Custom CSS theme for hover tooltips */ + theme?: Extension; } /** @@ -504,8 +506,51 @@ export const DefaultSqlTooltipRenders = { /** * Default CSS styles for hover tooltips */ -export const sqlHoverTheme = (): Extension => - EditorView.theme({ +export const defaultSqlHoverTheme = (theme: "light" | "dark" = "light"): Extension => { + // Theme-dependent color variables + const lightTheme = { + tooltipBg: "#ffffff", + tooltipBorder: "#e5e7eb", + tooltipText: "#374151", + tooltipTypeBg: "#f3f4f6", + tooltipTypeText: "#6b7280", + tooltipChildren: "#6b7280", + codeBg: "#f9fafb", + codeText: "#1f2937", + strong: "#111827", + em: "#6b7280", + header: "#111827", + info: "#374151", + related: "#374151", + path: "#374151", + example: "#374151", + columns: "#374151", + syntax: "#374151", + }; + + const darkTheme = { + tooltipBg: "#1f2937", + tooltipBorder: "#374151", + tooltipText: "#f9fafb", + tooltipTypeBg: "#374151", + tooltipTypeText: "#9ca3af", + tooltipChildren: "#9ca3af", + codeBg: "#374151", + codeText: "#f3f4f6", + strong: "#ffffff", + em: "#9ca3af", + header: "#ffffff", + info: "#d1d5db", + related: "#d1d5db", + path: "#d1d5db", + example: "#d1d5db", + columns: "#d1d5db", + syntax: "#d1d5db", + }; + + const colors = theme === "dark" ? darkTheme : lightTheme; + + return EditorView.theme({ ".cm-sql-hover-tooltip": { padding: "8px 12px", backgroundColor: "#ffffff", @@ -516,112 +561,71 @@ export const sqlHoverTheme = (): Extension => lineHeight: "1.4", maxWidth: "320px", fontFamily: "system-ui, -apple-system, sans-serif", + color: colors.tooltipText, }, ".cm-sql-hover-tooltip .sql-hover-header": { marginBottom: "6px", display: "flex", alignItems: "center", gap: "6px", + color: colors.header, }, ".cm-sql-hover-tooltip .sql-hover-type": { fontSize: "11px", padding: "2px 6px", - backgroundColor: "#f3f4f6", - color: "#6b7280", + backgroundColor: colors.tooltipTypeBg, + color: colors.tooltipTypeText, borderRadius: "4px", fontWeight: "500", }, ".cm-sql-hover-tooltip .sql-hover-description": { - color: "#374151", + color: colors.info, marginBottom: "8px", }, ".cm-sql-hover-tooltip .sql-hover-syntax": { marginBottom: "8px", - color: "#374151", + color: colors.syntax, }, ".cm-sql-hover-tooltip .sql-hover-example": { marginBottom: "4px", - color: "#374151", + color: colors.example, }, ".cm-sql-hover-tooltip .sql-hover-columns": { marginBottom: "4px", - color: "#374151", + color: colors.columns, }, ".cm-sql-hover-tooltip .sql-hover-related": { marginBottom: "4px", - color: "#374151", + color: colors.related, }, ".cm-sql-hover-tooltip .sql-hover-path": { marginBottom: "4px", - color: "#374151", + color: colors.path, }, ".cm-sql-hover-tooltip .sql-hover-info": { marginBottom: "4px", - color: "#374151", + color: colors.info, }, ".cm-sql-hover-tooltip .sql-hover-children": { marginBottom: "4px", - color: "#6b7280", + color: colors.tooltipChildren, fontSize: "12px", }, ".cm-sql-hover-tooltip code": { - backgroundColor: "#f9fafb", + backgroundColor: colors.codeBg, padding: "1px 4px", borderRadius: "3px", fontSize: "12px", fontFamily: "ui-monospace, 'SF Mono', 'Monaco', 'Cascadia Code', 'Roboto Mono', monospace", - color: "#1f2937", + color: colors.codeText, }, ".cm-sql-hover-tooltip strong": { fontWeight: "600", - color: "#111827", + color: colors.strong, }, ".cm-sql-hover-tooltip em": { fontStyle: "italic", - color: "#6b7280", - }, - // Dark theme support - ".cm-editor.cm-focused.cm-dark .cm-sql-hover-tooltip": { - backgroundColor: "#1f2937", - borderColor: "#374151", - color: "#f9fafb", - }, - ".cm-editor.cm-focused.cm-dark .cm-sql-hover-tooltip .sql-hover-type": { - backgroundColor: "#374151", - color: "#9ca3af", - }, - ".cm-editor.cm-focused.cm-dark .cm-sql-hover-tooltip .sql-hover-description": { - color: "#d1d5db", - }, - ".cm-editor.cm-focused.cm-dark .cm-sql-hover-tooltip .sql-hover-syntax": { - color: "#d1d5db", - }, - ".cm-editor.cm-focused.cm-dark .cm-sql-hover-tooltip .sql-hover-example": { - color: "#d1d5db", - }, - ".cm-editor.cm-focused.cm-dark .cm-sql-hover-tooltip .sql-hover-columns": { - color: "#d1d5db", - }, - ".cm-editor.cm-focused.cm-dark .cm-sql-hover-tooltip .sql-hover-related": { - color: "#d1d5db", - }, - ".cm-editor.cm-focused.cm-dark .cm-sql-hover-tooltip .sql-hover-path": { - color: "#d1d5db", - }, - ".cm-editor.cm-focused.cm-dark .cm-sql-hover-tooltip .sql-hover-info": { - color: "#d1d5db", - }, - ".cm-editor.cm-focused.cm-dark .cm-sql-hover-tooltip .sql-hover-children": { - color: "#9ca3af", - }, - ".cm-editor.cm-focused.cm-dark .cm-sql-hover-tooltip code": { - backgroundColor: "#374151", - color: "#f3f4f6", - }, - ".cm-editor.cm-focused.cm-dark .cm-sql-hover-tooltip strong": { - color: "#ffffff", - }, - ".cm-editor.cm-focused.cm-dark .cm-sql-hover-tooltip em": { - color: "#9ca3af", + color: colors.em, }, }); +};