From d8eb587860553c48b3e7f8605a78b40d8b774c91 Mon Sep 17 00:00:00 2001 From: Felix Turner Date: Thu, 25 Sep 2025 12:57:31 -0700 Subject: [PATCH 1/2] [refactor] Remove font sizing from themes and workflow serialization - Remove NODE_TEXT_SIZE, NODE_SUBTEXT_SIZE, and GROUP_TEXT_SIZE from all palette JSON files - Make font sizes hardcoded constants in LiteGraphGlobal instead of theme-configurable - Remove font_size from group serialization/deserialization to prevent workflow overrides - Update schemas and tests to reflect font size removal from themes - Ensure themes only contain colors, making them the single source of truth for colors only This change prevents themes and saved workflows from overriding font sizes, ensuring consistent typography controlled by hardcoded constants. Also prevents layout issues if the font sizes are changed from the default. --- browser_tests/tests/colorPalette.spec.ts | 6 ------ src/assets/palettes/arc.json | 3 --- src/assets/palettes/dark.json | 3 --- src/assets/palettes/github.json | 3 --- src/assets/palettes/light.json | 3 --- src/assets/palettes/nord.json | 3 --- src/assets/palettes/solarized.json | 3 --- src/components/graph/TitleEditor.vue | 4 +++- src/lib/litegraph/src/LGraphCanvas.ts | 3 +-- src/lib/litegraph/src/LGraphGroup.ts | 6 ++---- src/lib/litegraph/src/LiteGraphGlobal.ts | 3 +-- src/schemas/colorPaletteSchema.ts | 3 --- .../litegraph/core/__snapshots__/litegraph.test.ts.snap | 3 +-- 13 files changed, 8 insertions(+), 38 deletions(-) diff --git a/browser_tests/tests/colorPalette.spec.ts b/browser_tests/tests/colorPalette.spec.ts index 6dd53c194f..75255356aa 100644 --- a/browser_tests/tests/colorPalette.spec.ts +++ b/browser_tests/tests/colorPalette.spec.ts @@ -38,16 +38,13 @@ const customColorPalettes: Record = { CLEAR_BACKGROUND_COLOR: '#222222', NODE_TITLE_COLOR: 'rgba(255,255,255,.75)', NODE_SELECTED_TITLE_COLOR: '#FFF', - NODE_TEXT_SIZE: 14, NODE_TEXT_COLOR: '#b8b8b8', - NODE_SUBTEXT_SIZE: 12, NODE_DEFAULT_COLOR: 'rgba(0,0,0,.8)', NODE_DEFAULT_BGCOLOR: 'rgba(22,22,22,.8)', NODE_DEFAULT_BOXCOLOR: 'rgba(255,255,255,.75)', NODE_DEFAULT_SHAPE: 'box', NODE_BOX_OUTLINE_COLOR: '#236692', DEFAULT_SHADOW_COLOR: 'rgba(0,0,0,0)', - DEFAULT_GROUP_FONT: 24, WIDGET_BGCOLOR: '#242424', WIDGET_OUTLINE_COLOR: '#333', WIDGET_TEXT_COLOR: '#a3a3a8', @@ -102,16 +99,13 @@ const customColorPalettes: Record = { CLEAR_BACKGROUND_COLOR: '#000', NODE_TITLE_COLOR: 'rgba(255,255,255,.75)', NODE_SELECTED_TITLE_COLOR: '#FFF', - NODE_TEXT_SIZE: 14, NODE_TEXT_COLOR: '#b8b8b8', - NODE_SUBTEXT_SIZE: 12, NODE_DEFAULT_COLOR: 'rgba(0,0,0,.8)', NODE_DEFAULT_BGCOLOR: 'rgba(22,22,22,.8)', NODE_DEFAULT_BOXCOLOR: 'rgba(255,255,255,.75)', NODE_DEFAULT_SHAPE: 'box', NODE_BOX_OUTLINE_COLOR: '#236692', DEFAULT_SHADOW_COLOR: 'rgba(0,0,0,0)', - DEFAULT_GROUP_FONT: 24, WIDGET_BGCOLOR: '#242424', WIDGET_OUTLINE_COLOR: '#333', WIDGET_TEXT_COLOR: '#a3a3a8', diff --git a/src/assets/palettes/arc.json b/src/assets/palettes/arc.json index 756491ae5f..3ba1a529ed 100644 --- a/src/assets/palettes/arc.json +++ b/src/assets/palettes/arc.json @@ -34,9 +34,7 @@ "CLEAR_BACKGROUND_COLOR": "#2b2f38", "NODE_TITLE_COLOR": "#b2b7bd", "NODE_SELECTED_TITLE_COLOR": "#FFF", - "NODE_TEXT_SIZE": 14, "NODE_TEXT_COLOR": "#AAA", - "NODE_SUBTEXT_SIZE": 12, "NODE_DEFAULT_COLOR": "#2b2f38", "NODE_DEFAULT_BGCOLOR": "#242730", "NODE_DEFAULT_BOXCOLOR": "#6e7581", @@ -45,7 +43,6 @@ "NODE_BYPASS_BGCOLOR": "#FF00FF", "NODE_ERROR_COLOUR": "#E00", "DEFAULT_SHADOW_COLOR": "rgba(0,0,0,0.5)", - "DEFAULT_GROUP_FONT": 22, "WIDGET_BGCOLOR": "#2b2f38", "WIDGET_OUTLINE_COLOR": "#6e7581", "WIDGET_TEXT_COLOR": "#DDD", diff --git a/src/assets/palettes/dark.json b/src/assets/palettes/dark.json index 508ec58047..20402db0d2 100644 --- a/src/assets/palettes/dark.json +++ b/src/assets/palettes/dark.json @@ -25,10 +25,8 @@ "CLEAR_BACKGROUND_COLOR": "#222", "NODE_TITLE_COLOR": "#999", "NODE_SELECTED_TITLE_COLOR": "#FFF", - "NODE_TEXT_SIZE": 14, "NODE_TEXT_COLOR": "#AAA", "NODE_TEXT_HIGHLIGHT_COLOR": "#FFF", - "NODE_SUBTEXT_SIZE": 12, "NODE_DEFAULT_COLOR": "#333", "NODE_DEFAULT_BGCOLOR": "#353535", "NODE_DEFAULT_BOXCOLOR": "#666", @@ -37,7 +35,6 @@ "NODE_BYPASS_BGCOLOR": "#FF00FF", "NODE_ERROR_COLOUR": "#E00", "DEFAULT_SHADOW_COLOR": "rgba(0,0,0,0.5)", - "DEFAULT_GROUP_FONT": 24, "WIDGET_BGCOLOR": "#222", "WIDGET_OUTLINE_COLOR": "#666", "WIDGET_TEXT_COLOR": "#DDD", diff --git a/src/assets/palettes/github.json b/src/assets/palettes/github.json index 91a0a62efd..133e4155d5 100644 --- a/src/assets/palettes/github.json +++ b/src/assets/palettes/github.json @@ -34,9 +34,7 @@ "CLEAR_BACKGROUND_COLOR": "#040506", "NODE_TITLE_COLOR": "#999", "NODE_SELECTED_TITLE_COLOR": "#e5eaf0", - "NODE_TEXT_SIZE": 14, "NODE_TEXT_COLOR": "#bcc2c8", - "NODE_SUBTEXT_SIZE": 12, "NODE_DEFAULT_COLOR": "#161b22", "NODE_DEFAULT_BGCOLOR": "#13171d", "NODE_DEFAULT_BOXCOLOR": "#30363d", @@ -45,7 +43,6 @@ "NODE_BYPASS_BGCOLOR": "#FF00FF", "NODE_ERROR_COLOUR": "#E00", "DEFAULT_SHADOW_COLOR": "rgba(0,0,0,0.5)", - "DEFAULT_GROUP_FONT": 24, "WIDGET_BGCOLOR": "#161b22", "WIDGET_OUTLINE_COLOR": "#30363d", "WIDGET_TEXT_COLOR": "#bcc2c8", diff --git a/src/assets/palettes/light.json b/src/assets/palettes/light.json index fcacbd282c..9c9d3aec56 100644 --- a/src/assets/palettes/light.json +++ b/src/assets/palettes/light.json @@ -26,10 +26,8 @@ "CLEAR_BACKGROUND_COLOR": "lightgray", "NODE_TITLE_COLOR": "#222", "NODE_SELECTED_TITLE_COLOR": "#000", - "NODE_TEXT_SIZE": 14, "NODE_TEXT_COLOR": "#444", "NODE_TEXT_HIGHLIGHT_COLOR": "#1e293b", - "NODE_SUBTEXT_SIZE": 12, "NODE_DEFAULT_COLOR": "#F7F7F7", "NODE_DEFAULT_BGCOLOR": "#F5F5F5", "NODE_DEFAULT_BOXCOLOR": "#CCC", @@ -38,7 +36,6 @@ "NODE_BYPASS_BGCOLOR": "#FF00FF", "NODE_ERROR_COLOUR": "#E00", "DEFAULT_SHADOW_COLOR": "rgba(0,0,0,0.1)", - "DEFAULT_GROUP_FONT": 24, "WIDGET_BGCOLOR": "#D4D4D4", "WIDGET_OUTLINE_COLOR": "#999", "WIDGET_TEXT_COLOR": "#222", diff --git a/src/assets/palettes/nord.json b/src/assets/palettes/nord.json index 89f7fad743..9cf0f62d51 100644 --- a/src/assets/palettes/nord.json +++ b/src/assets/palettes/nord.json @@ -34,9 +34,7 @@ "CLEAR_BACKGROUND_COLOR": "#212732", "NODE_TITLE_COLOR": "#999", "NODE_SELECTED_TITLE_COLOR": "#e5eaf0", - "NODE_TEXT_SIZE": 14, "NODE_TEXT_COLOR": "#bcc2c8", - "NODE_SUBTEXT_SIZE": 12, "NODE_DEFAULT_COLOR": "#2e3440", "NODE_DEFAULT_BGCOLOR": "#161b22", "NODE_DEFAULT_BOXCOLOR": "#545d70", @@ -45,7 +43,6 @@ "NODE_BYPASS_BGCOLOR": "#FF00FF", "NODE_ERROR_COLOUR": "#E00", "DEFAULT_SHADOW_COLOR": "rgba(0,0,0,0.5)", - "DEFAULT_GROUP_FONT": 24, "WIDGET_BGCOLOR": "#2e3440", "WIDGET_OUTLINE_COLOR": "#545d70", "WIDGET_TEXT_COLOR": "#bcc2c8", diff --git a/src/assets/palettes/solarized.json b/src/assets/palettes/solarized.json index 4b456c4034..3b9a96594b 100644 --- a/src/assets/palettes/solarized.json +++ b/src/assets/palettes/solarized.json @@ -19,9 +19,7 @@ "litegraph_base": { "NODE_TITLE_COLOR": "#fdf6e3", "NODE_SELECTED_TITLE_COLOR": "#A9D400", - "NODE_TEXT_SIZE": 14, "NODE_TEXT_COLOR": "#657b83", - "NODE_SUBTEXT_SIZE": 12, "NODE_DEFAULT_COLOR": "#094656", "NODE_DEFAULT_BGCOLOR": "#073642", "NODE_DEFAULT_BOXCOLOR": "#839496", @@ -30,7 +28,6 @@ "NODE_BYPASS_BGCOLOR": "#FF00FF", "NODE_ERROR_COLOUR": "#E00", "DEFAULT_SHADOW_COLOR": "rgba(0,0,0,0.5)", - "DEFAULT_GROUP_FONT": 24, "WIDGET_BGCOLOR": "#002b36", "WIDGET_OUTLINE_COLOR": "#839496", "WIDGET_TEXT_COLOR": "#fdf6e3", diff --git a/src/components/graph/TitleEditor.vue b/src/components/graph/TitleEditor.vue index e5505fac5a..67c46c4ef7 100644 --- a/src/components/graph/TitleEditor.vue +++ b/src/components/graph/TitleEditor.vue @@ -83,7 +83,9 @@ watch( pos: group.pos, size: [group.size[0], group.titleHeight] }) - inputFontStyle.value = { fontSize: `${group.font_size * scale}px` } + inputFontStyle.value = { + fontSize: `${LiteGraph.GROUP_TEXT_SIZE * scale}px` + } } else if (target instanceof LGraphNode) { const node = target const [x, y] = node.getBounding() diff --git a/src/lib/litegraph/src/LGraphCanvas.ts b/src/lib/litegraph/src/LGraphCanvas.ts index 0cf68e3f79..c68989cba7 100644 --- a/src/lib/litegraph/src/LGraphCanvas.ts +++ b/src/lib/litegraph/src/LGraphCanvas.ts @@ -2567,8 +2567,7 @@ export class LGraphCanvas } pointer.finally = () => (this.resizingGroup = null) } else { - const f = group.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE - const headerHeight = f * 1.4 + const headerHeight = LiteGraph.GROUP_TEXT_SIZE * 1.4 if ( isInRectangle( x, diff --git a/src/lib/litegraph/src/LGraphGroup.ts b/src/lib/litegraph/src/LGraphGroup.ts index f00f302e6a..12b962379a 100644 --- a/src/lib/litegraph/src/LGraphGroup.ts +++ b/src/lib/litegraph/src/LGraphGroup.ts @@ -39,7 +39,7 @@ export class LGraphGroup implements Positionable, IPinnable, IColorable { color?: string title: string font?: string - font_size: number = LiteGraph.DEFAULT_GROUP_FONT || 24 + font_size: number = LiteGraph.GROUP_TEXT_SIZE _bounding: Float32Array = new Float32Array([ 10, 10, @@ -148,7 +148,6 @@ export class LGraphGroup implements Positionable, IPinnable, IColorable { this._bounding.set(o.bounding) this.color = o.color this.flags = o.flags || this.flags - if (o.font_size) this.font_size = o.font_size } serialize(): ISerialisedGroup { @@ -158,7 +157,6 @@ export class LGraphGroup implements Positionable, IPinnable, IColorable { title: this.title, bounding: [...b], color: this.color, - font_size: this.font_size, flags: this.flags } } @@ -170,7 +168,7 @@ export class LGraphGroup implements Positionable, IPinnable, IColorable { */ draw(graphCanvas: LGraphCanvas, ctx: CanvasRenderingContext2D): void { const { padding, resizeLength, defaultColour } = LGraphGroup - const font_size = this.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE + const font_size = LiteGraph.GROUP_TEXT_SIZE const [x, y] = this._pos const [width, height] = this._size diff --git a/src/lib/litegraph/src/LiteGraphGlobal.ts b/src/lib/litegraph/src/LiteGraphGlobal.ts index 5d762799a8..f4a12c21c1 100644 --- a/src/lib/litegraph/src/LiteGraphGlobal.ts +++ b/src/lib/litegraph/src/LiteGraphGlobal.ts @@ -64,8 +64,7 @@ export class LiteGraphGlobal { DEFAULT_FONT = 'Arial' DEFAULT_SHADOW_COLOR = 'rgba(0,0,0,0.5)' - DEFAULT_GROUP_FONT = 24 - DEFAULT_GROUP_FONT_SIZE?: any + GROUP_TEXT_SIZE = 24 GROUP_FONT = 'Arial' WIDGET_BGCOLOR = '#222' diff --git a/src/schemas/colorPaletteSchema.ts b/src/schemas/colorPaletteSchema.ts index 88b7974866..e96572ed5f 100644 --- a/src/schemas/colorPaletteSchema.ts +++ b/src/schemas/colorPaletteSchema.ts @@ -26,10 +26,8 @@ const litegraphBaseSchema = z.object({ CLEAR_BACKGROUND_COLOR: z.string(), NODE_TITLE_COLOR: z.string(), NODE_SELECTED_TITLE_COLOR: z.string(), - NODE_TEXT_SIZE: z.number(), NODE_TEXT_COLOR: z.string(), NODE_TEXT_HIGHLIGHT_COLOR: z.string(), - NODE_SUBTEXT_SIZE: z.number(), NODE_DEFAULT_COLOR: z.string(), NODE_DEFAULT_BGCOLOR: z.string(), NODE_DEFAULT_BOXCOLOR: z.string(), @@ -44,7 +42,6 @@ const litegraphBaseSchema = z.object({ NODE_BYPASS_BGCOLOR: z.string(), NODE_ERROR_COLOUR: z.string(), DEFAULT_SHADOW_COLOR: z.string(), - DEFAULT_GROUP_FONT: z.number(), WIDGET_BGCOLOR: z.string(), WIDGET_OUTLINE_COLOR: z.string(), WIDGET_TEXT_COLOR: z.string(), diff --git a/tests-ui/tests/litegraph/core/__snapshots__/litegraph.test.ts.snap b/tests-ui/tests/litegraph/core/__snapshots__/litegraph.test.ts.snap index 5302edcbc6..d656500a9e 100644 --- a/tests-ui/tests/litegraph/core/__snapshots__/litegraph.test.ts.snap +++ b/tests-ui/tests/litegraph/core/__snapshots__/litegraph.test.ts.snap @@ -21,8 +21,6 @@ LiteGraphGlobal { "ContextMenu": [Function], "CurveEditor": [Function], "DEFAULT_FONT": "Arial", - "DEFAULT_GROUP_FONT": 24, - "DEFAULT_GROUP_FONT_SIZE": undefined, "DEFAULT_POSITION": [ 100, 100, @@ -34,6 +32,7 @@ LiteGraphGlobal { "EVENT_LINK_COLOR": "#A86", "GRID_SHAPE": 6, "GROUP_FONT": "Arial", + "GROUP_TEXT_SIZE": 24, "Globals": {}, "HIDDEN_LINK": -1, "INPUT": 1, From 3b32ac1098311274f265cf1ae635d791ff58580b Mon Sep 17 00:00:00 2001 From: Felix Turner Date: Thu, 25 Sep 2025 13:16:34 -0700 Subject: [PATCH 2/2] [feat] Improve group title layout to better match node titles - Reduce GROUP_TEXT_SIZE from 24 to 20px for better proportions - Use NODE_TITLE_HEIGHT (30px) for group title area height consistently - Center text vertically in title area with left padding (font_size / 2) - Update LGraphCanvas header height calculation to use NODE_TITLE_HEIGHT - Update test snapshots to reflect new GROUP_TEXT_SIZE value This gives more whitespace around group titles and fixes the odd group title height of ~3.3 grid units --- src/lib/litegraph/src/LGraphCanvas.ts | 2 +- src/lib/litegraph/src/LGraphGroup.ts | 10 ++++++---- src/lib/litegraph/src/LiteGraphGlobal.ts | 2 +- .../core/__snapshots__/litegraph.test.ts.snap | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/lib/litegraph/src/LGraphCanvas.ts b/src/lib/litegraph/src/LGraphCanvas.ts index c68989cba7..4eaa10ac86 100644 --- a/src/lib/litegraph/src/LGraphCanvas.ts +++ b/src/lib/litegraph/src/LGraphCanvas.ts @@ -2567,7 +2567,7 @@ export class LGraphCanvas } pointer.finally = () => (this.resizingGroup = null) } else { - const headerHeight = LiteGraph.GROUP_TEXT_SIZE * 1.4 + const headerHeight = LiteGraph.NODE_TITLE_HEIGHT if ( isInRectangle( x, diff --git a/src/lib/litegraph/src/LGraphGroup.ts b/src/lib/litegraph/src/LGraphGroup.ts index 12b962379a..c9f3afc1d7 100644 --- a/src/lib/litegraph/src/LGraphGroup.ts +++ b/src/lib/litegraph/src/LGraphGroup.ts @@ -116,7 +116,7 @@ export class LGraphGroup implements Positionable, IPinnable, IColorable { } get titleHeight() { - return this.font_size * 1.4 + return LiteGraph.NODE_TITLE_HEIGHT } get children(): ReadonlySet { @@ -179,7 +179,7 @@ export class LGraphGroup implements Positionable, IPinnable, IColorable { ctx.fillStyle = color ctx.strokeStyle = color ctx.beginPath() - ctx.rect(x + 0.5, y + 0.5, width, font_size * 1.4) + ctx.rect(x + 0.5, y + 0.5, width, LiteGraph.NODE_TITLE_HEIGHT) ctx.fill() // Group background, border @@ -201,11 +201,13 @@ export class LGraphGroup implements Positionable, IPinnable, IColorable { // Title ctx.font = `${font_size}px ${LiteGraph.GROUP_FONT}` ctx.textAlign = 'left' + ctx.textBaseline = 'middle' ctx.fillText( this.title + (this.pinned ? '📌' : ''), - x + padding, - y + font_size + x + font_size / 2, + y + LiteGraph.NODE_TITLE_HEIGHT / 2 + 1 ) + ctx.textBaseline = 'alphabetic' if (LiteGraph.highlight_selected_group && this.selected) { strokeShape(ctx, this._bounding, { diff --git a/src/lib/litegraph/src/LiteGraphGlobal.ts b/src/lib/litegraph/src/LiteGraphGlobal.ts index f4a12c21c1..7abed2eea5 100644 --- a/src/lib/litegraph/src/LiteGraphGlobal.ts +++ b/src/lib/litegraph/src/LiteGraphGlobal.ts @@ -64,7 +64,7 @@ export class LiteGraphGlobal { DEFAULT_FONT = 'Arial' DEFAULT_SHADOW_COLOR = 'rgba(0,0,0,0.5)' - GROUP_TEXT_SIZE = 24 + GROUP_TEXT_SIZE = 20 GROUP_FONT = 'Arial' WIDGET_BGCOLOR = '#222' diff --git a/tests-ui/tests/litegraph/core/__snapshots__/litegraph.test.ts.snap b/tests-ui/tests/litegraph/core/__snapshots__/litegraph.test.ts.snap index d656500a9e..1d16cf4aae 100644 --- a/tests-ui/tests/litegraph/core/__snapshots__/litegraph.test.ts.snap +++ b/tests-ui/tests/litegraph/core/__snapshots__/litegraph.test.ts.snap @@ -32,7 +32,7 @@ LiteGraphGlobal { "EVENT_LINK_COLOR": "#A86", "GRID_SHAPE": 6, "GROUP_FONT": "Arial", - "GROUP_TEXT_SIZE": 24, + "GROUP_TEXT_SIZE": 20, "Globals": {}, "HIDDEN_LINK": -1, "INPUT": 1,