dockview-react 8.4.0 → 8.4.1

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.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview-react
3
- * @version 8.4.0
3
+ * @version 8.4.1
4
4
  * @link https://github.com/dockview/dockview
5
5
  * @license MIT
6
6
  */
@@ -51,7 +51,7 @@ react_dom = __toESM(react_dom);
51
51
  //#region ../dockview-core/dist/package/main.esm.mjs
52
52
  /**
53
53
  * dockview-core
54
- * @version 8.4.0
54
+ * @version 8.4.1
55
55
  * @link https://github.com/dockview/dockview
56
56
  * @license MIT
57
57
  */
@@ -372,21 +372,29 @@ react_dom = __toESM(react_dom);
372
372
  }
373
373
  };
374
374
  function watchElementResize(element, cb) {
375
+ const pendingFrames = /* @__PURE__ */ new Set();
375
376
  const observer = new ResizeObserver((entires) => {
376
377
  /**
377
378
  * Fast browser window resize produces Error: ResizeObserver loop limit exceeded.
378
379
  * The error isn't visible in browser console, doesn't affect functionality, but degrades performance.
379
380
  * See https://stackoverflow.com/questions/49384120/resizeobserver-loop-limit-exceeded/58701523#58701523
380
381
  */
381
- requestAnimationFrame(() => {
382
+ let ran = false;
383
+ let frame;
384
+ frame = requestAnimationFrame(() => {
385
+ ran = true;
386
+ if (frame !== void 0) pendingFrames.delete(frame);
382
387
  const firstEntry = entires[0];
383
388
  cb(firstEntry);
384
389
  });
390
+ if (!ran) pendingFrames.add(frame);
385
391
  });
386
392
  observer.observe(element);
387
393
  return { dispose: () => {
388
394
  observer.unobserve(element);
389
395
  observer.disconnect();
396
+ for (const frame of pendingFrames) cancelAnimationFrame(frame);
397
+ pendingFrames.clear();
390
398
  } };
391
399
  }
392
400
  const removeClasses = (element, ...classes) => {
@@ -10089,16 +10097,21 @@ react_dom = __toESM(react_dom);
10089
10097
  y: event.clientY,
10090
10098
  zIndex: (relativeParent === null || relativeParent === void 0 ? void 0 : relativeParent.style.zIndex) ? `calc(${relativeParent.style.zIndex} * 2)` : void 0
10091
10099
  };
10092
- const context = this.createOverflowRenderContext(root, anchor);
10100
+ const { context, rowRenderers } = this.createOverflowRenderContext(root, anchor);
10093
10101
  const advancedOverflow = this.accessor.advancedOverflowService;
10094
- if (advancedOverflow) advancedOverflow.renderOverflow({
10095
- group: this.group,
10096
- overflowTabs: [...this._overflowTabs],
10097
- overflowTabGroups: [...this._overflowTabGroups],
10098
- pinnedOverflowTabs: [...this._overflowPinnedTabs],
10099
- context
10100
- });
10101
- else context.open(this.renderFreeOverflowList(context));
10102
+ try {
10103
+ if (advancedOverflow) advancedOverflow.renderOverflow({
10104
+ group: this.group,
10105
+ overflowTabs: [...this._overflowTabs],
10106
+ overflowTabGroups: [...this._overflowTabGroups],
10107
+ pinnedOverflowTabs: [...this._overflowPinnedTabs],
10108
+ context
10109
+ });
10110
+ else context.open(this.renderFreeOverflowList(context));
10111
+ } catch (err) {
10112
+ rowRenderers.dispose();
10113
+ throw err;
10114
+ }
10102
10115
  }));
10103
10116
  }
10104
10117
  /**
@@ -10119,6 +10132,7 @@ react_dom = __toESM(react_dom);
10119
10132
  if (overflowGroupSet.has(tg.id)) for (const pid of tg.panelIds) panelToGroup.set(pid, tg);
10120
10133
  }
10121
10134
  const popup = () => this.accessor.getPopupServiceForGroup(this.group);
10135
+ const rowRenderers = new CompositeDisposable();
10122
10136
  const buildGroupHeader = (tg) => {
10123
10137
  const groupHeader = document.createElement("div");
10124
10138
  groupHeader.className = "dv-tabs-overflow-group-header";
@@ -10148,69 +10162,87 @@ react_dom = __toESM(react_dom);
10148
10162
  return groupHeader;
10149
10163
  };
10150
10164
  return {
10151
- overflowGroupIdForPanel: (panelId) => {
10152
- var _panelToGroup$get;
10153
- return (_panelToGroup$get = panelToGroup.get(panelId)) === null || _panelToGroup$get === void 0 ? void 0 : _panelToGroup$get.id;
10154
- },
10155
- buildGroupHeader: (tabGroupId) => {
10156
- const tg = groupById.get(tabGroupId);
10157
- if (!tg || !overflowGroupSet.has(tg.id)) return;
10158
- return buildGroupHeader(tg);
10159
- },
10160
- buildPinnedHeader: () => {
10161
- const header = document.createElement("div");
10162
- header.className = "dv-tabs-overflow-group-header dv-tabs-overflow-pinned-header";
10163
- const glyph = createPinButton();
10164
- glyph.classList.add("dv-tabs-overflow-pinned-icon");
10165
- header.appendChild(glyph);
10166
- const labelSpan = document.createElement("span");
10167
- labelSpan.className = "dv-tabs-overflow-group-label";
10168
- labelSpan.textContent = "Pinned";
10169
- header.appendChild(labelSpan);
10170
- return header;
10171
- },
10172
- buildRow: (panelId) => {
10173
- const panel = this.group.panels.find((p) => p.id === panelId);
10174
- if (!panel) return;
10175
- const tab = this.tabs.tabs.find((t) => t.panel.id === panelId);
10176
- const tg = panelToGroup.get(panelId);
10177
- const child = panel.view.createTabRenderer("headerOverflow").element;
10178
- const wrapper = document.createElement("div");
10179
- toggleClass(wrapper, "dv-tab", true);
10180
- toggleClass(wrapper, "dv-active-tab", panel.api.isActive);
10181
- toggleClass(wrapper, "dv-inactive-tab", !panel.api.isActive);
10182
- if (tg) toggleClass(wrapper, "dv-tab--grouped", true);
10183
- const doActivate = () => {
10184
- if (tg === null || tg === void 0 ? void 0 : tg.collapsed) tg.expand();
10185
- tab === null || tab === void 0 || tab.element.scrollIntoView({
10186
- block: "nearest",
10187
- inline: "nearest"
10165
+ context: {
10166
+ overflowGroupIdForPanel: (panelId) => {
10167
+ var _panelToGroup$get;
10168
+ return (_panelToGroup$get = panelToGroup.get(panelId)) === null || _panelToGroup$get === void 0 ? void 0 : _panelToGroup$get.id;
10169
+ },
10170
+ buildGroupHeader: (tabGroupId) => {
10171
+ const tg = groupById.get(tabGroupId);
10172
+ if (!tg || !overflowGroupSet.has(tg.id)) return;
10173
+ return buildGroupHeader(tg);
10174
+ },
10175
+ buildPinnedHeader: () => {
10176
+ const header = document.createElement("div");
10177
+ header.className = "dv-tabs-overflow-group-header dv-tabs-overflow-pinned-header";
10178
+ const glyph = createPinButton();
10179
+ glyph.classList.add("dv-tabs-overflow-pinned-icon");
10180
+ header.appendChild(glyph);
10181
+ const labelSpan = document.createElement("span");
10182
+ labelSpan.className = "dv-tabs-overflow-group-label";
10183
+ labelSpan.textContent = "Pinned";
10184
+ header.appendChild(labelSpan);
10185
+ return header;
10186
+ },
10187
+ buildRow: (panelId) => {
10188
+ const panel = this.group.panels.find((p) => p.id === panelId);
10189
+ if (!panel) return;
10190
+ const tab = this.tabs.tabs.find((t) => t.panel.id === panelId);
10191
+ const tg = panelToGroup.get(panelId);
10192
+ const tabComponent = panel.view.createTabRenderer("headerOverflow");
10193
+ let rowDisposed = false;
10194
+ const disposeRow = Disposable.from(() => {
10195
+ if (!rowDisposed) {
10196
+ var _tabComponent$dispose;
10197
+ rowDisposed = true;
10198
+ (_tabComponent$dispose = tabComponent.dispose) === null || _tabComponent$dispose === void 0 || _tabComponent$dispose.call(tabComponent);
10199
+ }
10188
10200
  });
10189
- this.accessor.withOrigin("user", () => panel.api.setActive());
10190
- };
10191
- wrapper.addEventListener("click", (event) => {
10192
- popup().close();
10193
- if (event.defaultPrevented) return;
10194
- doActivate();
10195
- });
10196
- wrapper.appendChild(child);
10197
- return {
10198
- element: wrapper,
10199
- panel,
10200
- activate: () => {
10201
+ if (rowRenderers.isDisposed) disposeRow.dispose();
10202
+ else rowRenderers.addDisposables(disposeRow);
10203
+ const child = tabComponent.element;
10204
+ const wrapper = document.createElement("div");
10205
+ toggleClass(wrapper, "dv-tab", true);
10206
+ toggleClass(wrapper, "dv-active-tab", panel.api.isActive);
10207
+ toggleClass(wrapper, "dv-inactive-tab", !panel.api.isActive);
10208
+ if (tg) toggleClass(wrapper, "dv-tab--grouped", true);
10209
+ const doActivate = () => {
10210
+ if (tg === null || tg === void 0 ? void 0 : tg.collapsed) tg.expand();
10211
+ tab === null || tab === void 0 || tab.element.scrollIntoView({
10212
+ block: "nearest",
10213
+ inline: "nearest"
10214
+ });
10215
+ this.accessor.withOrigin("user", () => panel.api.setActive());
10216
+ };
10217
+ wrapper.addEventListener("click", (event) => {
10201
10218
  popup().close();
10219
+ if (event.defaultPrevented) return;
10202
10220
  doActivate();
10203
- }
10204
- };
10205
- },
10206
- open: (body) => {
10207
- popup().openPopover(body, anchor);
10221
+ });
10222
+ wrapper.appendChild(child);
10223
+ return {
10224
+ element: wrapper,
10225
+ panel,
10226
+ activate: () => {
10227
+ popup().close();
10228
+ doActivate();
10229
+ },
10230
+ dispose: () => {
10231
+ rowRenderers.removeDisposable(disposeRow);
10232
+ disposeRow.dispose();
10233
+ }
10234
+ };
10235
+ },
10236
+ open: (body) => {
10237
+ popup().openPopover(body, anchor, { onClose: () => rowRenderers.dispose() });
10238
+ },
10239
+ close: () => popup().close(),
10240
+ focusTrigger: () => {
10241
+ root.tabIndex = -1;
10242
+ root.focus();
10243
+ }
10208
10244
  },
10209
- close: () => popup().close(),
10210
- focusTrigger: () => {
10211
- root.tabIndex = -1;
10212
- root.focus();
10213
- }
10245
+ rowRenderers
10214
10246
  };
10215
10247
  }
10216
10248
  /**
@@ -11121,6 +11153,7 @@ react_dom = __toESM(react_dom);
11121
11153
  this.tabsContainer.setRightActionsElement(element);
11122
11154
  }
11123
11155
  setActive(isGroupActive, force = false) {
11156
+ if (this.isDisposed) return;
11124
11157
  if (!force && this.isActive === isGroupActive) return;
11125
11158
  this._isGroupActive = isGroupActive;
11126
11159
  toggleClass(this.container, "dv-active-group", isGroupActive);
@@ -14084,13 +14117,14 @@ react_dom = __toESM(react_dom);
14084
14117
  * menu passes the `tabGroup`. No-op when no renderer could be created (no
14085
14118
  * factory configured, or the factory declined the component).
14086
14119
  */
14087
- appendComponentItem(menuEl, item, identity, group, close) {
14120
+ appendComponentItem(menuEl, item, identity, group, close, renderers) {
14088
14121
  var _this$accessor$option4, _this$accessor$option5;
14089
14122
  const renderer = (_this$accessor$option4 = (_this$accessor$option5 = this.accessor.options).createContextMenuItemComponent) === null || _this$accessor$option4 === void 0 ? void 0 : _this$accessor$option4.call(_this$accessor$option5, {
14090
14123
  id: nextContextMenuItemId(),
14091
14124
  component: item.component
14092
14125
  });
14093
14126
  if (!renderer) return;
14127
+ renderers.addDisposables(renderer);
14094
14128
  renderer.init(_objectSpread2$1(_objectSpread2$1({}, identity), {}, {
14095
14129
  group,
14096
14130
  api: this.accessor.api,
@@ -14141,9 +14175,9 @@ react_dom = __toESM(react_dom);
14141
14175
  * default row; an item carrying none of the three renders nothing. Shared
14142
14176
  * by both menus, which differ only in `identity`.
14143
14177
  */
14144
- appendConfigItem(menuEl, item, identity, group, close) {
14178
+ appendConfigItem(menuEl, item, identity, group, close, renderers) {
14145
14179
  if (item.element) menuEl.appendChild(item.element);
14146
- else if (item.component) this.appendComponentItem(menuEl, item, identity, group, close);
14180
+ else if (item.component) this.appendComponentItem(menuEl, item, identity, group, close, renderers);
14147
14181
  else if (item.label) menuEl.appendChild(buildItem(item.label, close, () => {
14148
14182
  var _item$action;
14149
14183
  return (_item$action = item.action) === null || _item$action === void 0 ? void 0 : _item$action.call(item);
@@ -14155,22 +14189,28 @@ react_dom = __toESM(react_dom);
14155
14189
  event.preventDefault();
14156
14190
  const popupService = this.accessor.getPopupServiceForGroup(group);
14157
14191
  const close = () => popupService.close();
14192
+ const renderers = new CompositeDisposable();
14158
14193
  const menuEl = document.createElement("div");
14159
14194
  menuEl.className = "dv-context-menu";
14160
14195
  menuEl.setAttribute("role", "menu");
14161
- for (const item of items) {
14162
- if (isItemConfig(item)) {
14163
- this.appendConfigItem(menuEl, item, { panel }, group, close);
14164
- continue;
14196
+ try {
14197
+ for (const item of items) {
14198
+ if (isItemConfig(item)) {
14199
+ this.appendConfigItem(menuEl, item, { panel }, group, close, renderers);
14200
+ continue;
14201
+ }
14202
+ const el = this.buildBuiltInTabItem(item, panel, group, close);
14203
+ if (el) menuEl.appendChild(el);
14165
14204
  }
14166
- const el = this.buildBuiltInTabItem(item, panel, group, close);
14167
- if (el) menuEl.appendChild(el);
14205
+ } catch (err) {
14206
+ renderers.dispose();
14207
+ throw err;
14168
14208
  }
14169
14209
  popupService.openPopover(menuEl, {
14170
14210
  x: event.clientX,
14171
14211
  y: event.clientY,
14172
14212
  zIndex: popoverZIndexFor(event.target, group)
14173
- });
14213
+ }, { onClose: () => renderers.dispose() });
14174
14214
  }
14175
14215
  showForChip(tabGroup, group, event) {
14176
14216
  if (!this.accessor.options.getTabGroupChipContextMenuItems) return;
@@ -14184,22 +14224,28 @@ react_dom = __toESM(react_dom);
14184
14224
  event.preventDefault();
14185
14225
  const popupService = this.accessor.getPopupServiceForGroup(group);
14186
14226
  const close = () => popupService.close();
14227
+ const renderers = new CompositeDisposable();
14187
14228
  const menuEl = document.createElement("div");
14188
14229
  menuEl.className = "dv-context-menu";
14189
14230
  menuEl.setAttribute("role", "menu");
14190
- for (const item of items) if (item === "separator") menuEl.appendChild(buildSeparator());
14191
- else if (item === "rename") menuEl.appendChild(buildRenameInput(tabGroup));
14192
- else if (item === "colorPicker") menuEl.appendChild(buildColorPicker(tabGroup, this.accessor.tabGroupColorPalette));
14193
- else if (item === "collapse") menuEl.appendChild(this.buildCollapseItem(tabGroup, close));
14194
- else if (item === "close") menuEl.appendChild(buildItem("Close All", close, () => {
14195
- group.panels.filter((p) => tabGroup.containsPanel(p.id)).forEach((p) => p.api.close());
14196
- }));
14197
- else if (isItemConfig(item)) this.appendConfigItem(menuEl, item, { tabGroup }, group, close);
14231
+ try {
14232
+ for (const item of items) if (item === "separator") menuEl.appendChild(buildSeparator());
14233
+ else if (item === "rename") menuEl.appendChild(buildRenameInput(tabGroup));
14234
+ else if (item === "colorPicker") menuEl.appendChild(buildColorPicker(tabGroup, this.accessor.tabGroupColorPalette));
14235
+ else if (item === "collapse") menuEl.appendChild(this.buildCollapseItem(tabGroup, close));
14236
+ else if (item === "close") menuEl.appendChild(buildItem("Close All", close, () => {
14237
+ group.panels.filter((p) => tabGroup.containsPanel(p.id)).forEach((p) => p.api.close());
14238
+ }));
14239
+ else if (isItemConfig(item)) this.appendConfigItem(menuEl, item, { tabGroup }, group, close, renderers);
14240
+ } catch (err) {
14241
+ renderers.dispose();
14242
+ throw err;
14243
+ }
14198
14244
  popupService.openPopover(menuEl, {
14199
14245
  x: event.clientX,
14200
14246
  y: event.clientY,
14201
14247
  zIndex: popoverZIndexFor(event.target, group)
14202
- });
14248
+ }, { onClose: () => renderers.dispose() });
14203
14249
  }
14204
14250
  };
14205
14251
  const ContextMenuModule = defineModule({
@@ -14483,6 +14529,7 @@ react_dom = __toESM(react_dom);
14483
14529
  const observerDisposable = new MutableDisposable();
14484
14530
  const correctLayerPosition = () => {
14485
14531
  if (panel.api.location.type === "floating") queueMicrotask(() => {
14532
+ if (disposable.isDisposed) return;
14486
14533
  const floatingGroup = this.accessor.getFloatingWindowForGroup(panel.api.group);
14487
14534
  if (!floatingGroup) return;
14488
14535
  const element = floatingGroup.overlay.element;
@@ -14708,7 +14755,7 @@ react_dom = __toESM(react_dom);
14708
14755
  newRoot.prepend(this._element);
14709
14756
  this._root = newRoot;
14710
14757
  }
14711
- openPopover(element, position) {
14758
+ openPopover(element, position, options) {
14712
14759
  var _position$zIndex;
14713
14760
  this.close();
14714
14761
  const wrapper = this._window.document.createElement("div");
@@ -14723,14 +14770,14 @@ react_dom = __toESM(react_dom);
14723
14770
  this._element.appendChild(wrapper);
14724
14771
  this._active = wrapper;
14725
14772
  const POINTERDOWN_GRACE_MS = 200;
14726
- this._activeDisposable.value = createDismissableLayer({
14773
+ this._activeDisposable.value = new CompositeDisposable(createDismissableLayer({
14727
14774
  window: this._window,
14728
14775
  onDismiss: () => this.close(),
14729
14776
  elements: () => this._active ? [this._active] : [],
14730
14777
  keys: ["Enter"],
14731
14778
  pointerDownGraceMs: POINTERDOWN_GRACE_MS,
14732
14779
  resize: true
14733
- });
14780
+ }), (options === null || options === void 0 ? void 0 : options.onClose) ? Disposable.from(options.onClose) : Disposable.NONE);
14734
14781
  this._window.requestAnimationFrame(() => {
14735
14782
  shiftAbsoluteElementIntoView(wrapper, this._root);
14736
14783
  });
@@ -16033,7 +16080,9 @@ react_dom = __toESM(react_dom);
16033
16080
  this._onWillDrop = new Emitter();
16034
16081
  this.onWillDrop = this._onWillDrop.event;
16035
16082
  this._mutationDepth = 0;
16083
+ this._syncMutationDepth = 0;
16036
16084
  this._pendingLocationChanges = /* @__PURE__ */ new Map();
16085
+ this._openingPopoutWindows = /* @__PURE__ */ new Set();
16037
16086
  this._origin = "user";
16038
16087
  this._originDepth = 0;
16039
16088
  this._onWillMutateLayout = new Emitter();
@@ -16117,6 +16166,10 @@ react_dom = __toESM(react_dom);
16117
16166
  });
16118
16167
  }));
16119
16168
  this.popupService = new PopupService(this.element);
16169
+ this.addDisposables(this.popupService, Disposable.from(() => {
16170
+ for (const opening of this._openingPopoutWindows) opening.dispose();
16171
+ this._openingPopoutWindows.clear();
16172
+ }));
16120
16173
  this._api = new DockviewApi(this);
16121
16174
  this.disableResizing = true;
16122
16175
  this.element.remove();
@@ -16265,9 +16318,15 @@ react_dom = __toESM(react_dom);
16265
16318
  const popoutWindowDisposable = new CompositeDisposable(_window, _window.onDidClose(() => {
16266
16319
  popoutWindowDisposable.dispose();
16267
16320
  }));
16321
+ this._openingPopoutWindows.add(popoutWindowDisposable);
16268
16322
  const openError = getPopoutUrlError(popoutUrl);
16269
16323
  return (openError ? Promise.resolve(null) : _window.open()).then((popoutContainer) => {
16270
16324
  var _options$referenceGro, _options$overridePopo4;
16325
+ this._openingPopoutWindows.delete(popoutWindowDisposable);
16326
+ if (this.isDisposed) {
16327
+ popoutWindowDisposable.dispose();
16328
+ return false;
16329
+ }
16271
16330
  if (_window.isDisposed) {
16272
16331
  const failure = _window.failure;
16273
16332
  if (failure && !this.isDisposed) {
@@ -16461,6 +16520,7 @@ react_dom = __toESM(react_dom);
16461
16520
  for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
16462
16521
  return true;
16463
16522
  }).catch((err) => {
16523
+ this._openingPopoutWindows.delete(popoutWindowDisposable);
16464
16524
  console.error("dockview: failed to create popout.", err);
16465
16525
  return false;
16466
16526
  });
@@ -17000,6 +17060,7 @@ react_dom = __toESM(react_dom);
17000
17060
  group.dispose();
17001
17061
  this._groups.delete(group.id);
17002
17062
  this._onDidRemoveGroup.fire(group);
17063
+ this.activateFallbackGroupIfRemoved(group);
17003
17064
  });
17004
17065
  }
17005
17066
  setEdgeGroupCollapsed(group, collapsed) {
@@ -17196,6 +17257,7 @@ react_dom = __toESM(react_dom);
17196
17257
  const record = this._groups.get(temporaryGroup.api.id);
17197
17258
  this._groups.delete(temporaryGroup.api.id);
17198
17259
  temporaryGroupDisposables.push(Disposable.from(() => {
17260
+ var _this$headerActionsSe2;
17199
17261
  /**
17200
17262
  * Reclaim the group's own resources, never its panels.
17201
17263
  * Staging is driven by the ids in `data.panels` while
@@ -17213,6 +17275,7 @@ react_dom = __toESM(react_dom);
17213
17275
  for (const panel of temporaryGroup.panels.slice()) temporaryGroup.model.removePanel(panel);
17214
17276
  });
17215
17277
  record === null || record === void 0 || record.disposable.dispose();
17278
+ (_this$headerActionsSe2 = this.headerActionsService) === null || _this$headerActionsSe2 === void 0 || _this$headerActionsSe2.disposeGroup(temporaryGroup);
17216
17279
  temporaryGroup.dispose();
17217
17280
  }));
17218
17281
  return temporaryGroup;
@@ -17877,9 +17940,12 @@ react_dom = __toESM(react_dom);
17877
17940
  */
17878
17941
  mutation(kind, func) {
17879
17942
  const close = this.openMutation(kind);
17943
+ this._syncMutationDepth++;
17880
17944
  try {
17881
17945
  return func();
17882
17946
  } finally {
17947
+ this._syncMutationDepth--;
17948
+ if (this._syncMutationDepth === 0) this.releaseDisposedActiveGroup();
17883
17949
  close();
17884
17950
  }
17885
17951
  }
@@ -17926,6 +17992,7 @@ react_dom = __toESM(react_dom);
17926
17992
  return () => {
17927
17993
  this._mutationDepth--;
17928
17994
  if (this._mutationDepth === 0) {
17995
+ this.releaseDisposedActiveGroup();
17929
17996
  this.flushLocationChanges();
17930
17997
  this._onDidMutateLayout.fire({
17931
17998
  kind,
@@ -17934,6 +18001,11 @@ react_dom = __toESM(react_dom);
17934
18001
  }
17935
18002
  };
17936
18003
  }
18004
+ /** Covers removals with `skipActive` that disposed the active group. */
18005
+ releaseDisposedActiveGroup() {
18006
+ var _this$_activeGroup;
18007
+ if (!this.isDisposed && ((_this$_activeGroup = this._activeGroup) === null || _this$_activeGroup === void 0 ? void 0 : _this$_activeGroup.model.isDisposed)) this.activateFallbackGroupIfRemoved(this._activeGroup);
18008
+ }
17937
18009
  /**
17938
18010
  * Coalesce a panel's `onDidLocationChange` to the end of the enclosing
17939
18011
  * transaction, or fire it immediately when no transaction is in flight.
@@ -18071,7 +18143,7 @@ react_dom = __toESM(react_dom);
18071
18143
  skipSetActiveGroup: true
18072
18144
  }));
18073
18145
  if (!removedPanel) throw new Error(`dockview: No panel with id ${sourceItemId}`);
18074
- if (!options.keepEmptyGroups && sourceGroup.model.size === 0) this.doRemoveGroup(sourceGroup, { skipActive: true });
18146
+ if (!options.keepEmptyGroups && sourceGroup.model.size === 0 && sourceGroup !== destinationGroup) this.doRemoveGroup(sourceGroup, { skipActive: true });
18075
18147
  const isDestinationGroupEmpty = destinationGroup.model.size === 0;
18076
18148
  this.movingLock(() => {
18077
18149
  var _options$skipSetActiv;
@@ -18236,6 +18308,7 @@ react_dom = __toESM(react_dom);
18236
18308
  const from = options.from.group;
18237
18309
  const to = options.to.group;
18238
18310
  const target = options.to.position;
18311
+ if (target === "center" && from === to) return;
18239
18312
  let source = from;
18240
18313
  let mergedPanels;
18241
18314
  if (target === "center") {
@@ -19255,6 +19328,7 @@ react_dom = __toESM(react_dom);
19255
19328
  const queue = [];
19256
19329
  const width = this.width;
19257
19330
  const height = this.height;
19331
+ this.paneview.dispose();
19258
19332
  this.paneview = new Paneview(this.element, {
19259
19333
  orientation: "VERTICAL",
19260
19334
  descriptor: {
@@ -19318,7 +19392,11 @@ react_dom = __toESM(react_dom);
19318
19392
  clear() {
19319
19393
  for (const [_, value] of this._viewDisposables.entries()) value.dispose();
19320
19394
  this._viewDisposables.clear();
19395
+ const width = this.width;
19396
+ const height = this.height;
19321
19397
  this.paneview.dispose();
19398
+ this.paneview = new Paneview(this.element, { orientation: "VERTICAL" });
19399
+ this.layout(width, height);
19322
19400
  }
19323
19401
  doAddPanel(panel) {
19324
19402
  const disposable = new CompositeDisposable(panel.onDidDrop((event) => {