How can I make a panel in a container to overflow the container's bounds?

Hi,
I have a node template defined as such

$(go.Node, "Auto", { zOrder: 1 },
      $(go.Shape, "RoundedRectangle", { stroke: "#424242" }, new go.Binding("fill", "color")),
      $(go.Panel, "Auto" ,
        $(go.Panel, "Vertical", textBlocks.defaultgroup(),
          $(go.Panel, "Spot", { name: "CodePanel", stretch: go.GraphObject.None, visible: false }, textBlocks.node())
        ),
      )
)

The panel named “CodePanel” is invisible by default, and is made visible upon user clicking on the parent node. The node is nested inside a container group, and as the “CodePanel” becomes visible, the size of the node increases, and consequently the size of the container Group also increases to accommodate this node. However, I want is such that when the node size increases upon the CodePanel becoming visible, the size of the container Group should remain the same, and the node may overflow its container’s bounds. I do realise that this might mean that the container Group would remain a fixed size all the time, and while dragging its contents outside its bounds, those contents would also overshoot its bounds. I do not want that, I just want a node upon its expansion to overshoot its parent’s bounds.
Is there a way to achieve this or is it not possible here?

Typically its much better to design your node so that you are toggling some panel’s opacity (between 0 and 1) instead of visible (between false and true) so that you don’t run into remeasure considerations, which can complicate all kinds of things, including groups and layouts and invalidating links. Can you do that instead?

Here is an example of the said node when the additional panel is hidden:


Here is that same node with that text panel visible:

If I were to simply tweak the opacity instead of toggling the visibility, then a node by default would be so big with so much empty space, in its collapsed state. That would not work.

You could override the undocumented method Group.computeMemberBounds.

For your information, the built-in implementation of that method is defined as follows:

  protected computeMemberBounds(result: Rect): Rect {
    if (!(this.part instanceof Group)) {
      result.setTo(0, 0, 0, 0);
      return result;
    }

    const sg = this.part;
    let minx = Infinity;
    let miny = Infinity;
    let maxx = -Infinity;
    let maxy = -Infinity;

    const itr = sg.memberParts;
    while (itr.next()) {
      const m = itr.value;
      if (!m.isVisible()) continue;
      if (m instanceof Link) {
        if (!sg.computesBoundsIncludingLinks) continue;
        // ignore links connecting with this Group
        if (m.fromNode === sg || m.toNode === sg) continue;
      }
      const b = m.actualBounds; // if this is an "expanded" node, use its collapsed bounds instead
      if (b.left < minx) minx = b.left;
      if (b.top < miny) miny = b.top;
      if (b.right > maxx) maxx = b.right;
      if (b.bottom > maxy) maxy = b.bottom;
    }

    if (!isFinite(minx) || !isFinite(miny)) {
      const loc = sg.location;
      result.setTo(loc.x, loc.y, 0, 0);
    } else {
      result.setTo(minx, miny, maxx - minx, maxy - miny);
    }
    return result;
  }