Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"@fontsource-variable/geist": "^5.2.9",
"@fontsource-variable/geist-mono": "^5.2.8",
"@fontsource-variable/inter": "^5.2.8",
"@fontsource-variable/jetbrains-mono": "^5.2.8",
"@tailwindcss/vite": "^4.3.0",
"@tanstack/svelte-hotkeys": "^0.10.0",
"@tauri-apps/plugin-autostart": "^2.5.1",
Expand Down
9 changes: 8 additions & 1 deletion src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@import "tw-animate-css";
@import "@fontsource-variable/geist";
@import "@fontsource-variable/geist-mono";
@import "@fontsource-variable/jetbrains-mono";
@import "@fontsource-variable/inter";
@import "./lib/themes/app-themes.css";

Expand All @@ -13,7 +14,13 @@
--app-zoom: 1;
--app-font-size: 14px;
--editor-font-size: 14px;
--editor-line-height: 24px;
/* 1.5 ratio — matches VS Code / Cursor's default editor line height. */
--editor-line-height: 21px;
/* Dedicated code font for Monaco editors, kept independent of the app's UI /
data-grid mono (`--font-mono`) — same separation VS Code makes between its
"editor font" and everything else. JetBrains Mono is a true code typeface:
heavier, even rhythm, designed ligatures. */
--editor-font-family: "JetBrains Mono Variable", "Geist Mono Variable", ui-monospace, monospace;
}

/* JSON colorizer tokens (highlightJson) — dark-friendly defaults, light override
Expand Down
4 changes: 2 additions & 2 deletions src/lib/components/JsonCellLightbox.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import CheckCheck from '@lucide/svelte/icons/check-check'
import Braces from '@lucide/svelte/icons/braces'
import * as monaco from 'monaco-editor'
import { configureMonacoWorkers, monacoFontFamily } from '$lib/monaco-env.js'
import { configureMonacoWorkers, editorFontFamily } from '$lib/monaco-env.js'
import { defineStrokeMonacoThemes, monacoThemeId, readEditorFontOptions } from '$lib/monaco-themes.js'
import { normalizeThemeId } from '$lib/themes/registry.js'

Expand Down Expand Up @@ -57,7 +57,7 @@
readOnly: true,
automaticLayout: true,
minimap: { enabled: false },
fontFamily: monacoFontFamily(),
fontFamily: editorFontFamily(),
fontSize,
lineHeight,
fontLigatures: false,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/components/JsonViewer.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script>
import { onMount } from 'svelte'
import * as monaco from 'monaco-editor'
import { configureMonacoWorkers, monacoFontFamily } from '$lib/monaco-env.js'
import { configureMonacoWorkers, editorFontFamily } from '$lib/monaco-env.js'
import { defineStrokeMonacoThemes, monacoThemeId, readEditorFontOptions } from '$lib/monaco-themes.js'
import { normalizeThemeId } from '$lib/themes/registry.js'
import Table2 from '@lucide/svelte/icons/table-2'
Expand Down Expand Up @@ -111,7 +111,7 @@
// forever; a ResizeObserver (below) handles relayout without the polling.
automaticLayout: false,
minimap: { enabled: false },
fontFamily: monacoFontFamily(),
fontFamily: editorFontFamily(),
fontSize,
lineHeight,
fontLigatures: false,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/components/JsonViewerPage.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script>
import { onMount, tick, untrack } from 'svelte'
import * as monaco from 'monaco-editor'
import { configureMonacoWorkers, monacoFontFamily } from '$lib/monaco-env.js'
import { configureMonacoWorkers, editorFontFamily } from '$lib/monaco-env.js'
import { defineStrokeMonacoThemes, monacoThemeId, readEditorFontOptions } from '$lib/monaco-themes.js'
import { normalizeThemeId } from '$lib/themes/registry.js'
import ResizeHandle from './ResizeHandle.svelte'
Expand Down Expand Up @@ -222,7 +222,7 @@
// page is open. A ResizeObserver fires only when the size actually changes.
automaticLayout: false,
minimap: { enabled: false },
fontFamily: monacoFontFamily(),
fontFamily: editorFontFamily(),
fontLigatures: false,
fontWeight: 'normal',
scrollBeyondLastLine: false,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/components/OrmRunner.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script>
import { onMount, untrack } from "svelte";
import * as monaco from "monaco-editor";
import { configureMonacoWorkers, monacoFontFamily } from "$lib/monaco-env.js";
import { configureMonacoWorkers, editorFontFamily } from "$lib/monaco-env.js";
import {
defineStrokeMonacoThemes,
monacoThemeId,
Expand Down Expand Up @@ -479,7 +479,7 @@
// even while this tab is hidden. ResizeObserver fires only on real resizes.
automaticLayout: false,
minimap: { enabled: false },
fontFamily: monacoFontFamily(),
fontFamily: editorFontFamily(),
fontSize,
lineHeight,
fontLigatures: false,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/components/SecuritySqlModal.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script>
import { onMount } from 'svelte'
import * as monaco from 'monaco-editor'
import { configureMonacoWorkers } from '$lib/monaco-env.js'
import { configureMonacoWorkers, editorFontFamily } from '$lib/monaco-env.js'
import { registerMonacoSqlFormatter } from '$lib/format-sql.js'
import {
defineStrokeMonacoThemes,
Expand Down Expand Up @@ -44,7 +44,7 @@
theme: monacoThemeId(currentTheme()),
automaticLayout: true,
minimap: { enabled: false },
fontFamily: '"Geist Mono Variable", ui-monospace, monospace',
fontFamily: editorFontFamily(),
fontSize,
lineHeight,
fontLigatures: false,
Expand Down
14 changes: 11 additions & 3 deletions src/lib/components/Sidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -721,12 +721,16 @@
bind:this={scrollContainerEl}
bind:clientHeight={sidebarHeight}
class="app-scroll min-h-0 w-full flex-1 overflow-y-auto"
role="none"
onscroll={onSidebarScroll}
onclick={(e) => {
if (selectedItems.size > 0 && !/** @type {Element} */(e.target).closest?.('li')) {
clearSelection()
}
}}
onkeydown={(e) => {
if (e.key === 'Escape' && selectedItems.size > 0) clearSelection()
}}
>
{#if loadingTables}
<div
Expand Down Expand Up @@ -971,9 +975,8 @@
{/if}
</button>
{#if tablesOpen}
<ul
bind:this={tableListEl}
class="flex w-full min-w-full flex-col gap-0.5 px-1.5 pb-1"
<div
role="none"
onkeydown={(e) => {
if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return
const btns = /** @type {HTMLButtonElement[]} */ ([...(tableListEl?.querySelectorAll('button') ?? [])])
Expand All @@ -984,6 +987,10 @@
else if (i === 0) filterEl?.focus()
else btns[i - 1]?.focus()
}}
>
<ul
bind:this={tableListEl}
class="flex w-full min-w-full flex-col gap-0.5 px-1.5 pb-1"
>
{#if regularTables.length === 0 && tables.length > 0}
<li
Expand Down Expand Up @@ -1148,6 +1155,7 @@
{#if virtBotPad > 0}<li style="height:{virtBotPad}px;flex-shrink:0" aria-hidden="true"></li>{/if}
{/if}
</ul>
</div>
{/if}
{/if}

Expand Down
62 changes: 36 additions & 26 deletions src/lib/components/SqlEditor.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script>
import { onMount } from 'svelte'
import * as monaco from 'monaco-editor'
import { configureMonacoWorkers, monacoFontFamily } from '$lib/monaco-env.js'
import { configureMonacoWorkers, editorFontFamily } from '$lib/monaco-env.js'
import { registerMonacoSqlFormatter } from '$lib/format-sql.js'
import { registerMonacoSqlCompletion } from '$lib/monaco-sql-complete.js'
import {
Expand Down Expand Up @@ -118,11 +118,12 @@
// unmounted). A ResizeObserver fires only on actual size changes. See below.
automaticLayout: false,
minimap: { enabled: false },
fontFamily: monacoFontFamily(),
fontFamily: editorFontFamily(),
fontSize,
lineHeight,
fontLigatures: true,
fontWeight: '400',
fontWeight: '450',
letterSpacing: 0.2,
padding: { top: 14, bottom: 14 },
scrollBeyondLastLine: false,
wordWrap: 'on',
Expand All @@ -139,9 +140,12 @@
overviewRulerLanes: 0,
hideCursorInOverviewRuler: true,
overviewRulerBorder: false,
cursorStyle: 'line',
cursorWidth: 2,
cursorBlinking: 'smooth',
cursorSmoothCaretAnimation: 'on',
smoothScrolling: true,
fixedOverflowWidgets: true,
quickSuggestions: { other: true, comments: false, strings: true },
quickSuggestionsDelay: 50,
suggestOnTriggerCharacters: true,
Expand Down Expand Up @@ -194,12 +198,19 @@
}
document.addEventListener('keydown', docRunHandler, { capture: true, passive: false })

// Monaco measures char widths at init time. If Geist Mono Variable isn't
// loaded yet (slow on Linux/Windows), it caches fallback-font widths and
// never self-corrects even after the font visually arrives.
document.fonts.ready.then(() => {
try { editor?.remeasureFonts?.() } catch { /* API not available in this Monaco build */ }
})
// Monaco caches glyph widths at init time. If the primary monospace font
// hasn't loaded yet (font-display:swap means it may arrive after CSS parse),
// Monaco uses fallback metrics and never self-corrects. Explicitly loading the
// font and then calling remeasureFonts + layout forces correct re-measurement.
const remeasure = () => {
try {
// remeasureFonts is a STATIC method on monaco.editor, not on the instance.
monaco.editor.remeasureFonts()
requestAnimationFrame(() => editor?.layout())
} catch { /* API not available in this Monaco build */ }
}
// Wait for the editor's primary font specifically before remeasuring.
document.fonts.load(`450 ${fontSize}px "JetBrains Mono Variable"`).then(remeasure, remeasure)

editor.onDidChangeModelContent(() => {
const next = editor?.getValue() ?? ''
Expand Down Expand Up @@ -262,88 +273,87 @@
border-radius: inherit;
}

.sql-editor-host :global(.monaco-editor .view-lines),
.sql-editor-host :global(.monaco-editor .view-line) {
font-weight: 400 !important;
}

.sql-editor-host :global(.monaco-editor .monaco-editor-background) {
outline: none !important;
}

/* ── Suggestion widget ──────────────────────────────────────────────── */
/* fixedOverflowWidgets:true moves these to <body>, so no host ancestor.
Widgets lose the editor's inherited font — set it explicitly. */

.sql-editor-host :global(.suggest-widget) {
:global(.suggest-widget) {
font-family: var(--editor-font-family) !important;
border-radius: 10px !important;
overflow: hidden !important;
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.25) !important;
}

/* Details panel (right side when expanded) */
.sql-editor-host :global(.suggest-widget .suggest-widget-details) {
:global(.suggest-widget .suggest-widget-details) {
border-radius: 0 10px 10px 0 !important;
border-left-width: 1px !important;
}

/* Each row: uniform height + horizontal padding */
.sql-editor-host :global(.suggest-widget .monaco-list-row) {
:global(.suggest-widget .monaco-list-row) {
border-radius: 0 !important;
padding-left: 8px !important;
padding-right: 8px !important;
}

/* Label text: slightly tighter tracking for mono */
.sql-editor-host :global(.suggest-widget .monaco-list-row .label-name) {
:global(.suggest-widget .monaco-list-row .label-name) {
letter-spacing: -0.01em;
}

/* Detail text on right side of each row */
.sql-editor-host :global(.suggest-widget .details-label) {
:global(.suggest-widget .details-label) {
opacity: 0.45 !important;
font-size: 0.8em !important;
}

/* The full documentation text in expanded detail panel */
.sql-editor-host :global(.suggest-widget .suggest-widget-details .docs) {
:global(.suggest-widget .suggest-widget-details .docs) {
opacity: 0.8;
font-size: 0.82em !important;
line-height: 1.5 !important;
padding: 4px 2px !important;
}

/* Signature text (bold param names etc.) */
.sql-editor-host :global(.suggest-widget .suggest-widget-details .signature) {
:global(.suggest-widget .suggest-widget-details .signature) {
font-size: 0.85em !important;
letter-spacing: -0.01em;
}

/* ── Parameter hints (shows while typing fn args) ───────────────────── */

.sql-editor-host :global(.parameter-hints-widget) {
:global(.parameter-hints-widget) {
font-family: var(--editor-font-family) !important;
border-radius: 8px !important;
overflow: hidden !important;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4) !important;
}

.sql-editor-host :global(.parameter-hints-widget .phContent) {
:global(.parameter-hints-widget .phContent) {
font-size: 0.85em !important;
padding: 4px 8px !important;
}

/* ── Hover widget ───────────────────────────────────────────────────── */

.sql-editor-host :global(.monaco-hover) {
:global(.monaco-hover) {
border-radius: 8px !important;
overflow: hidden !important;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4) !important;
}

/* ── Thin scrollbar inside suggestion list ──────────────────────────── */

.sql-editor-host :global(.suggest-widget .monaco-scrollable-element > .scrollbar.vertical) {
:global(.suggest-widget .monaco-scrollable-element > .scrollbar.vertical) {
width: 4px !important;
}
.sql-editor-host :global(.suggest-widget .monaco-scrollable-element > .scrollbar.horizontal) {
:global(.suggest-widget .monaco-scrollable-element > .scrollbar.horizontal) {
height: 4px !important;
}
</style>
2 changes: 1 addition & 1 deletion src/lib/components/StudioShell.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3469,7 +3469,7 @@ let rowSearch = $state('')
stroke-dasharray="44 220" stroke-linecap="round"
class="text-foreground/20" />
</svg>
<div class="flex size-[72px] items-center justify-center rounded-[20px] border border-border/60 bg-card ring-1 ring-inset ring-white/[0.04] shadow-[0_10px_30px_-14px_rgba(0,0,0,0.7)]">
<div class="flex size-[72px] items-center justify-center rounded-full border border-border/60 bg-card ring-1 ring-inset ring-white/[0.04] shadow-[0_10px_30px_-14px_rgba(0,0,0,0.7)]">
<Logo class="size-9" />
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions src/lib/components/VirtualColumnsPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
<div
class="flex h-full shrink-0 flex-col border-l border-border/40 bg-panel text-[13px]"
style="width: {panelWidth}px"
role="none"
onkeydown={(e) => {
if (e.key !== 'Escape') return
if (formOpen) { e.stopPropagation(); cancelForm() }
Expand Down
Loading
Loading