mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-21 03:55:51 +00:00
fix(editor): anchor wrapped line numbers via inline style
This commit is contained in:
+1
-2
@@ -192,7 +192,7 @@ describe("SQL completion theme", () => {
|
||||
});
|
||||
|
||||
describe("editor gutters", () => {
|
||||
it("anchors line numbers to the first visual row of wrapped lines", () => {
|
||||
it("keeps single line numbers vertically centered in the base rule", () => {
|
||||
const rules = buildEditorFontThemeRules();
|
||||
|
||||
expect(rules[".cm-lineNumbers .cm-gutterElement"]).toMatchObject({
|
||||
@@ -200,6 +200,5 @@ describe("editor gutters", () => {
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
});
|
||||
expect(rules[".cm-lineNumbers .cm-gutterElement.cm-db-wrapped-line-number"]).toMatchObject({ alignItems: "flex-start" });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { Compartment, EditorState } from "@codemirror/state";
|
||||
import { EditorView, GutterMarker, gutter, lineNumbers } from "@codemirror/view";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { buildQueryEditorLineNumbersExtension, isWrappedLineNumberGutter } from "@/lib/editor/queryEditorLineNumbers";
|
||||
import { buildQueryEditorLineNumbersExtension, isWrappedLineNumberGutter, setQueryEditorLineNumberAlignment } from "@/lib/editor/queryEditorLineNumbers";
|
||||
|
||||
class StatementRunMarker extends GutterMarker {}
|
||||
|
||||
@@ -47,6 +47,21 @@ describe("query editor line numbers", () => {
|
||||
expect(isWrappedLineNumberGutter(42, 20.8)).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps wrapped-line alignment when CodeMirror rebuilds a gutter marker class", () => {
|
||||
const element = document.createElement("div");
|
||||
element.className = "cm-gutterElement";
|
||||
|
||||
setQueryEditorLineNumberAlignment(element, true);
|
||||
// GutterElement#setMarkers owns and replaces className for active-line and
|
||||
// selection marker changes. The measured alignment must survive it.
|
||||
element.className = "cm-gutterElement cm-activeLineGutter";
|
||||
|
||||
expect(element.style.alignItems).toBe("flex-start");
|
||||
|
||||
setQueryEditorLineNumberAlignment(element, false);
|
||||
expect(element.style.alignItems).toBe("");
|
||||
});
|
||||
|
||||
it("keeps line selection behavior when enabled", () => {
|
||||
const { selectLine, view } = createEditor(true);
|
||||
const lineNumber = view.dom.querySelector<HTMLElement>(".cm-lineNumbers .cm-gutterElement");
|
||||
|
||||
@@ -810,6 +810,10 @@ export function buildEditorFontThemeRules(opts?: { fixedHeight?: boolean; scroll
|
||||
width: "1px",
|
||||
zIndex: "10",
|
||||
},
|
||||
// Single lines render vertically centered here. Wrapped lines are anchored
|
||||
// to the first visual row by createQueryEditorLineNumberAlignmentExtension,
|
||||
// which sets an inline `align-items: flex-start` (inline style survives
|
||||
// CodeMirror's className rebuild, unlike a toggled class).
|
||||
".cm-lineNumbers .cm-gutterElement": {
|
||||
alignItems: "center",
|
||||
cursor: "pointer",
|
||||
@@ -818,9 +822,6 @@ export function buildEditorFontThemeRules(opts?: { fixedHeight?: boolean; scroll
|
||||
paddingRight: "8px",
|
||||
userSelect: "none",
|
||||
},
|
||||
".cm-lineNumbers .cm-gutterElement.cm-db-wrapped-line-number": {
|
||||
alignItems: "flex-start",
|
||||
},
|
||||
".cm-run-statement-gutter": {
|
||||
minWidth: "28px",
|
||||
},
|
||||
|
||||
@@ -4,8 +4,6 @@ import type { lineNumbers } from "@codemirror/view";
|
||||
type LineNumbersFactory = typeof lineNumbers;
|
||||
type LineNumbersConfig = NonNullable<Parameters<LineNumbersFactory>[0]>;
|
||||
|
||||
export const WRAPPED_LINE_NUMBER_GUTTER_CLASS = "cm-db-wrapped-line-number";
|
||||
|
||||
export function isWrappedLineNumberGutter(gutterHeight: number, lineHeight: number): boolean {
|
||||
return gutterHeight > lineHeight + 1;
|
||||
}
|
||||
@@ -14,6 +12,13 @@ export function buildQueryEditorLineNumbersExtension(factory: LineNumbersFactory
|
||||
return enabled && factory ? factory(config) : [];
|
||||
}
|
||||
|
||||
export function setQueryEditorLineNumberAlignment(element: HTMLElement, wrapped: boolean): void {
|
||||
// CodeMirror rebuilds gutter class names as marker state changes. Keep this
|
||||
// measured layout state inline so selection and active-line updates cannot
|
||||
// restore the base centered alignment for a wrapped line.
|
||||
element.style.alignItems = wrapped ? "flex-start" : "";
|
||||
}
|
||||
|
||||
export function createQueryEditorLineNumberAlignmentExtension(ViewPlugin: typeof import("@codemirror/view").ViewPlugin): Extension {
|
||||
return ViewPlugin.fromClass(
|
||||
class {
|
||||
@@ -44,7 +49,7 @@ export function createQueryEditorLineNumberAlignmentExtension(ViewPlugin: typeof
|
||||
},
|
||||
write: (measurements) => {
|
||||
this.measureScheduled = false;
|
||||
for (const { element, wrapped } of measurements) element.classList.toggle(WRAPPED_LINE_NUMBER_GUTTER_CLASS, wrapped);
|
||||
for (const { element, wrapped } of measurements) setQueryEditorLineNumberAlignment(element, wrapped);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user