@grafloria/element 0.4.3 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grafloria/element",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "type": "module",
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
@@ -111,6 +111,8 @@ export function bindDashboardSplit(api, group, options = {}) {
111
111
  w: api.container.clientWidth || 0,
112
112
  h: api.container.clientHeight || 0,
113
113
  });
114
+ /** Reentrancy guard: our own frame write must not re-project through bounds:changed. */
115
+ let writing = false;
114
116
  /** FLUID: the frame is the container, both axes. Returns true when it changed. */
115
117
  const applyFluidFrame = () => {
116
118
  if (!fluid || disposed)
@@ -124,7 +126,13 @@ export function bindDashboardSplit(api, group, options = {}) {
124
126
  return false;
125
127
  designW = box.w;
126
128
  designH = height;
127
- diagram.runSystemWrite(() => group.setFrame({ x: f.x, y: f.y, width: box.w, height }));
129
+ writing = true;
130
+ try {
131
+ diagram.runSystemWrite(() => group.setFrame({ x: f.x, y: f.y, width: box.w, height }));
132
+ }
133
+ finally {
134
+ writing = false;
135
+ }
128
136
  return true;
129
137
  };
130
138
  // -- the tree ---------------------------------------------------------------
@@ -840,6 +848,32 @@ export function bindDashboardSplit(api, group, options = {}) {
840
848
  api.container.addEventListener('focusin', onFocusIn);
841
849
  api.container.addEventListener('keydown', onKey);
842
850
  // -- observers --------------------------------------------------------------
851
+ // THE GROUP'S FRAME IS THE BOARD. When it moves — a view parked off-camera by
852
+ // showView, a container re-slotted by its parent, an external resize — the
853
+ // widgets must follow, exactly as the grid binder's do. Without this the
854
+ // parked view's hosts stayed on camera under the shown view (the Angular
855
+ // conformance drive: the sales cards bleeding through the ops tab). Member
856
+ // churn re-reconciles the tree the same way.
857
+ const groupSubs = [
858
+ group.on('bounds:changed', (() => {
859
+ if (disposed || writing)
860
+ return;
861
+ project();
862
+ api.render();
863
+ })),
864
+ group.on('member:added', (() => {
865
+ if (disposed)
866
+ return;
867
+ project(reconcile());
868
+ api.render();
869
+ })),
870
+ group.on('member:removed', (() => {
871
+ if (disposed)
872
+ return;
873
+ project(reconcile());
874
+ api.render();
875
+ })),
876
+ ];
843
877
  const containerObserver = fluid && typeof ResizeObserver !== 'undefined'
844
878
  ? new ResizeObserver(() => {
845
879
  if (disposed)
@@ -1023,6 +1057,8 @@ export function bindDashboardSplit(api, group, options = {}) {
1023
1057
  api.container.removeEventListener('keydown', onKey);
1024
1058
  containerObserver === null || containerObserver === void 0 ? void 0 : containerObserver.disconnect();
1025
1059
  hostObserver === null || hostObserver === void 0 ? void 0 : hostObserver.disconnect();
1060
+ for (const off of groupSubs)
1061
+ off();
1026
1062
  for (const el of dividerEls)
1027
1063
  el.remove();
1028
1064
  dividerEls.length = 0;