Skip to content

Commit 381b5c7

Browse files
[fix] Preserve tooltips when promoting widgets to subgraph inputs (#1174)
1 parent abf93d2 commit 381b5c7

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)