You don’t set or bind TextBlock.editable, so is the only way the user gets to edit the text is by your calling CommandHandler.editTextBlock?
There’s no binding on the Shape.figure property, so it’s not surprising that you need to programmatically update the shape at various times.
Your code to modify that Shape.figure (and also its stroke) seems to be reasonable. But I’m wondering if your canceling the text editing is automatically restoring the Shape properties, as part of the undoing process.
Here’s an example of how you could implement the LineDown/LineUp shape figure to be controlled by whether or not the TextEditingTool is operating:
<!DOCTYPE html>
<html>
<head>
<title>Minimal GoJS Sample</title>
<!-- Copyright 1998-2025 by Northwoods Software Corporation. -->
</head>
<body>
<div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:400px"></div>
<textarea id="mySavedModel" style="width:100%;height:250px"></textarea>
<script src="https://cdn.jsdelivr.net/npm/gojs/release/go-debug.js"></script>
<script id="code">
class CustomTextEditingTool extends go.TextEditingTool {
doActivate() {
super.doActivate();
if (this.textBlock !== null) {
this.diagram.commit(() => {
const shp = this.textBlock.panel.findObject("SHP");
if (shp !== null) shp.figure = "LineUp";
}, null); // null means skipsUndoManager
}
}
doDeactivate() {
if (this.textBlock !== null) {
this.diagram.commit(() => {
const shp = this.textBlock.panel.findObject("SHP");
if (shp !== null) shp.figure = "LineDown";
}, null);
}
super.doDeactivate();
}
}
const myDiagram =
new go.Diagram("myDiagramDiv", {
textEditingTool: new CustomTextEditingTool(),
"undoManager.isEnabled": true,
"ModelChanged": e => { // just for demonstration purposes,
if (e.isTransactionFinished) { // show the model data in the page's TextArea
document.getElementById("mySavedModel").textContent = e.model.toJson();
}
}
});
myDiagram.nodeTemplate =
new go.Node("Auto")
.add(
new go.Shape({ fill: "white" })
.bind("fill", "color"),
new go.Panel("Horizontal", {
margin: 8,
click: (e, pnl) => {
if (e.diagram.currentTool instanceof go.TextEditingTool) {
e.diagram.currentTool.doCancel();
} else {
e.diagram.commandHandler.editTextBlock(pnl.findObject("TB"));
}
}
})
.add(
new go.TextBlock({ name: "TB" })
.bindTwoWay("text"),
new go.Shape("LineDown", { name: "SHP", width: 12, height: 12, margin: 4, background: "transparent" })
)
);
myDiagram.model = new go.GraphLinksModel(
[
{ key: 1, text: "Alpha", color: "lightblue" },
{ key: 2, text: "Beta", color: "orange" },
{ key: 3, text: "Gamma", color: "lightgreen" },
{ key: 4, text: "Delta", color: "pink" }
],
[
{ from: 1, to: 2 },
{ from: 1, to: 3 },
{ from: 2, to: 2 },
{ from: 3, to: 4 },
{ from: 4, to: 1 }
]);
</script>
</body>
</html>