Skip to content

Commit 4158a25

Browse files
[fix] preserve tooltips when promoting widgets to subgraph inputs
Subgraph promoted widgets were losing their tooltip information during the promotion process. This fix ensures that widget tooltips are preserved when widgets are promoted from internal nodes to subgraph inputs, maintaining consistency with the tooltip display system. - Add tooltip getter/setter to promoted widget properties in SubgraphNode - Add comprehensive test coverage for tooltip preservation scenarios - Handle undefined tooltips gracefully
1 parent abf93d2 commit 4158a25

File tree

2 files changed

+110
-1
lines changed

2 files changed

+110
-1
lines changed

src/subgraph/SubgraphNode.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,13 @@ export class SubgraphNode extends LGraphNode implements BaseLGraph {
216216
set label(value) {
217217
console.warn("Promoted widget: setting label is not allowed", this, value)
218218
},
219+
get tooltip() {
220+
// Preserve the original widget's tooltip for promoted widgets
221+
return widget.tooltip
222+
},
223+
set tooltip(value) {
224+
console.warn("Promoted widget: setting tooltip is not allowed", this, value)
225+
},
219226
})
220227

221228
this.widgets.push(promotedWidget)

test/subgraph/SubgraphWidgetPromotion.test.ts

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { ISlotType } from "@/interfaces"
22
import type { TWidgetType } from "@/types/widgets"
33

4-
import { describe, expect, it } from "vitest"
4+
import { describe, expect, it, vi } from "vitest"
55

66
import { LGraphNode, Subgraph } from "@/litegraph"
77
import { BaseWidget } from "@/widgets/BaseWidget"
@@ -14,6 +14,7 @@ function createNodeWithWidget(
1414
widgetType: TWidgetType = "number",
1515
widgetValue: any = 42,
1616
slotType: ISlotType = "number",
17+
tooltip?: string,
1718
) {
1819
const node = new LGraphNode(title)
1920
const input = node.addInput("value", slotType)
@@ -26,6 +27,7 @@ function createNodeWithWidget(
2627
y: 0,
2728
options: widgetType === "number" ? { min: 0, max: 100, step: 1 } : {},
2829
node,
30+
tooltip,
2931
})
3032
node.widgets = [widget]
3133
input.widget = { name: widget.name }
@@ -244,4 +246,104 @@ describe("SubgraphWidgetPromotion", () => {
244246
expect(subgraphNode.widgets).toHaveLength(0)
245247
})
246248
})
249+
250+
describe("Tooltip Promotion", () => {
251+
it("should preserve widget tooltip when promoting", () => {
252+
const subgraph = createTestSubgraph({
253+
inputs: [{ name: "value", type: "number" }],
254+
})
255+
256+
const originalTooltip = "This is a test tooltip"
257+
const { node } = createNodeWithWidget("Test Node", "number", 42, "number", originalTooltip)
258+
const subgraphNode = setupPromotedWidget(subgraph, node)
259+
260+
// The promoted widget should preserve the original tooltip
261+
expect(subgraphNode.widgets).toHaveLength(1)
262+
expect(subgraphNode.widgets[0].tooltip).toBe(originalTooltip)
263+
})
264+
265+
it("should handle widgets with no tooltip", () => {
266+
const subgraph = createTestSubgraph({
267+
inputs: [{ name: "value", type: "number" }],
268+
})
269+
270+
const { node } = createNodeWithWidget("Test Node", "number", 42, "number")
271+
const subgraphNode = setupPromotedWidget(subgraph, node)
272+
273+
// The promoted widget should have undefined tooltip
274+
expect(subgraphNode.widgets).toHaveLength(1)
275+
expect(subgraphNode.widgets[0].tooltip).toBeUndefined()
276+
})
277+
278+
it("should preserve tooltips for multiple promoted widgets", () => {
279+
const subgraph = createTestSubgraph({
280+
inputs: [
281+
{ name: "input1", type: "number" },
282+
{ name: "input2", type: "string" },
283+
],
284+
})
285+
286+
// Create node with multiple widgets with different tooltips
287+
const multiWidgetNode = new LGraphNode("Multi Widget Node")
288+
const numInput = multiWidgetNode.addInput("num", "number")
289+
const strInput = multiWidgetNode.addInput("str", "string")
290+
291+
const widget1 = new BaseWidget({
292+
name: "widget1",
293+
type: "number",
294+
value: 10,
295+
y: 0,
296+
options: {},
297+
node: multiWidgetNode,
298+
tooltip: "Number widget tooltip",
299+
})
300+
301+
const widget2 = new BaseWidget({
302+
name: "widget2",
303+
type: "string",
304+
value: "hello",
305+
y: 40,
306+
options: {},
307+
node: multiWidgetNode,
308+
tooltip: "String widget tooltip",
309+
})
310+
311+
multiWidgetNode.widgets = [widget1, widget2]
312+
numInput.widget = { name: widget1.name }
313+
strInput.widget = { name: widget2.name }
314+
subgraph.add(multiWidgetNode)
315+
316+
// Connect both inputs
317+
subgraph.inputNode.slots[0].connect(multiWidgetNode.inputs[0], multiWidgetNode)
318+
subgraph.inputNode.slots[1].connect(multiWidgetNode.inputs[1], multiWidgetNode)
319+
320+
// Create SubgraphNode
321+
const subgraphNode = createTestSubgraphNode(subgraph)
322+
323+
// Both widgets should preserve their tooltips
324+
expect(subgraphNode.widgets).toHaveLength(2)
325+
expect(subgraphNode.widgets[0].tooltip).toBe("Number widget tooltip")
326+
expect(subgraphNode.widgets[1].tooltip).toBe("String widget tooltip")
327+
})
328+
329+
it("should preserve original tooltip after promotion", () => {
330+
const subgraph = createTestSubgraph({
331+
inputs: [{ name: "value", type: "number" }],
332+
})
333+
334+
const originalTooltip = "Original tooltip"
335+
const { node } = createNodeWithWidget("Test Node", "number", 42, "number", originalTooltip)
336+
const subgraphNode = setupPromotedWidget(subgraph, node)
337+
338+
const promotedWidget = subgraphNode.widgets[0]
339+
340+
// The promoted widget should preserve the original tooltip
341+
expect(promotedWidget.tooltip).toBe(originalTooltip)
342+
343+
// The promoted widget should still function normally
344+
expect(promotedWidget.name).toBe("value") // Uses subgraph input name
345+
expect(promotedWidget.type).toBe("number")
346+
expect(promotedWidget.value).toBe(42)
347+
})
348+
})
247349
})

0 commit comments

Comments
 (0)