dockview-react 4.11.0 → 4.13.0

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 4.11.0
3
+ * @version 4.13.0
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -1264,11 +1264,13 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
1264
1264
  document.removeEventListener('pointermove', onPointerMove);
1265
1265
  document.removeEventListener('pointerup', end);
1266
1266
  document.removeEventListener('pointercancel', end);
1267
+ document.removeEventListener('contextmenu', end);
1267
1268
  this._onDidSashEnd.fire(undefined);
1268
1269
  };
1269
1270
  document.addEventListener('pointermove', onPointerMove);
1270
1271
  document.addEventListener('pointerup', end);
1271
1272
  document.addEventListener('pointercancel', end);
1273
+ document.addEventListener('contextmenu', end);
1272
1274
  };
1273
1275
  sash.addEventListener('pointerdown', onPointerStart);
1274
1276
  const sashItem = {
@@ -3751,8 +3753,8 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3751
3753
  /**
3752
3754
  * Create a component from a serialized object.
3753
3755
  */
3754
- fromJSON(data) {
3755
- this.component.fromJSON(data);
3756
+ fromJSON(data, options) {
3757
+ this.component.fromJSON(data, options);
3756
3758
  }
3757
3759
  /**
3758
3760
  * Create a serialized object of the current component.
@@ -4983,6 +4985,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4983
4985
  }
4984
4986
  if (doRender) {
4985
4987
  const focusTracker = trackFocus(container);
4988
+ this.focusTracker = focusTracker;
4986
4989
  const disposable = new CompositeDisposable();
4987
4990
  disposable.addDisposables(focusTracker, focusTracker.onDidFocus(() => this._onDidFocus.fire()), focusTracker.onDidBlur(() => this._onDidBlur.fire()));
4988
4991
  this.disposable.value = disposable;
@@ -5010,6 +5013,16 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5010
5013
  this.disposable.dispose();
5011
5014
  super.dispose();
5012
5015
  }
5016
+ /**
5017
+ * Refresh the focus tracker state to handle cases where focus state
5018
+ * gets out of sync due to programmatic panel activation
5019
+ */
5020
+ refreshFocusState() {
5021
+ var _a;
5022
+ if ((_a = this.focusTracker) === null || _a === void 0 ? void 0 : _a.refreshState) {
5023
+ this.focusTracker.refreshState();
5024
+ }
5025
+ }
5013
5026
  }
5014
5027
 
5015
5028
  function addGhostImage(dataTransfer, ghostElement, options) {
@@ -5119,7 +5132,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5119
5132
  }
5120
5133
  }
5121
5134
 
5122
- class WillShowOverlayLocationEvent {
5135
+ class DockviewWillShowOverlayLocationEvent {
5123
5136
  get kind() {
5124
5137
  return this.options.kind;
5125
5138
  }
@@ -5467,7 +5480,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5467
5480
  index: this._tabs.findIndex((x) => x.value === tab),
5468
5481
  });
5469
5482
  }), tab.onWillShowOverlay((event) => {
5470
- this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
5483
+ this._onWillShowOverlay.fire(new DockviewWillShowOverlayLocationEvent(event, {
5471
5484
  kind: 'tab',
5472
5485
  panel: this.group.activePanel,
5473
5486
  api: this.accessor.api,
@@ -5631,7 +5644,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5631
5644
  index: this.tabs.size,
5632
5645
  });
5633
5646
  }), this.voidContainer.onWillShowOverlay((event) => {
5634
- this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
5647
+ this._onWillShowOverlay.fire(new DockviewWillShowOverlayLocationEvent(event, {
5635
5648
  kind: 'header_space',
5636
5649
  panel: this.group.activePanel,
5637
5650
  api: this.accessor.api,
@@ -6025,7 +6038,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6025
6038
  }), this.tabsContainer.onWillShowOverlay((event) => {
6026
6039
  this._onWillShowOverlay.fire(event);
6027
6040
  }), this.contentContainer.dropTarget.onWillShowOverlay((event) => {
6028
- this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
6041
+ this._onWillShowOverlay.fire(new DockviewWillShowOverlayLocationEvent(event, {
6029
6042
  kind: 'content',
6030
6043
  panel: this.activePanel,
6031
6044
  api: this._api,
@@ -6336,8 +6349,11 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6336
6349
  this._activePanel = panel;
6337
6350
  if (panel) {
6338
6351
  this.tabsContainer.setActivePanel(panel);
6352
+ this.contentContainer.openPanel(panel);
6339
6353
  panel.layout(this._width, this._height);
6340
6354
  this.updateMru(panel);
6355
+ // Refresh focus state to handle programmatic activation without DOM focus change
6356
+ this.contentContainer.refreshFocusState();
6341
6357
  this._onDidActivePanelChange.fire({
6342
6358
  panel,
6343
6359
  });
@@ -6698,7 +6714,19 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6698
6714
  this.onDidLocationChange = this._onDidLocationChange.event;
6699
6715
  this._onDidActivePanelChange = new Emitter();
6700
6716
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
6701
- this.addDisposables(this._onDidLocationChange, this._onDidActivePanelChange);
6717
+ this.addDisposables(this._onDidLocationChange, this._onDidActivePanelChange, this._onDidVisibilityChange.event((event) => {
6718
+ // When becoming visible, apply any pending size change
6719
+ if (event.isVisible && this._pendingSize) {
6720
+ super.setSize(this._pendingSize);
6721
+ this._pendingSize = undefined;
6722
+ }
6723
+ }));
6724
+ }
6725
+ setSize(event) {
6726
+ // Always store the requested size
6727
+ this._pendingSize = Object.assign({}, event);
6728
+ // Apply the size change immediately
6729
+ super.setSize(event);
6702
6730
  }
6703
6731
  close() {
6704
6732
  if (!this._group) {
@@ -7167,6 +7195,18 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7167
7195
  params: this._params,
7168
7196
  });
7169
7197
  }
7198
+ updateFromStateModel(state) {
7199
+ var _a, _b, _c;
7200
+ this._maximumHeight = state.maximumHeight;
7201
+ this._minimumHeight = state.minimumHeight;
7202
+ this._maximumWidth = state.maximumWidth;
7203
+ this._minimumWidth = state.minimumWidth;
7204
+ this.update({ params: (_a = state.params) !== null && _a !== void 0 ? _a : {} });
7205
+ this.setTitle((_b = state.title) !== null && _b !== void 0 ? _b : this.id);
7206
+ this.setRenderer((_c = state.renderer) !== null && _c !== void 0 ? _c : this.accessor.renderer);
7207
+ // state.contentComponent;
7208
+ // state.tabComponent;
7209
+ }
7170
7210
  updateParentGroup(group, options) {
7171
7211
  this._group = group;
7172
7212
  this.api.group = this._group;
@@ -7638,13 +7678,16 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7638
7678
  let right = undefined;
7639
7679
  let width = undefined;
7640
7680
  const moveTop = () => {
7641
- top = clamp(y, -Number.MAX_VALUE, startPosition.originalY +
7681
+ // When dragging top handle, constrain top position to prevent oversizing
7682
+ const maxTop = startPosition.originalY +
7642
7683
  startPosition.originalHeight >
7643
7684
  containerRect.height
7644
- ? this.getMinimumHeight(containerRect.height)
7685
+ ? Math.max(0, containerRect.height -
7686
+ Overlay.MINIMUM_HEIGHT)
7645
7687
  : Math.max(0, startPosition.originalY +
7646
7688
  startPosition.originalHeight -
7647
- Overlay.MINIMUM_HEIGHT));
7689
+ Overlay.MINIMUM_HEIGHT);
7690
+ top = clamp(y, 0, maxTop);
7648
7691
  height =
7649
7692
  startPosition.originalY +
7650
7693
  startPosition.originalHeight -
@@ -7655,22 +7698,27 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7655
7698
  top =
7656
7699
  startPosition.originalY -
7657
7700
  startPosition.originalHeight;
7658
- height = clamp(y - top, top < 0 &&
7659
- typeof this.options
7660
- .minimumInViewportHeight === 'number'
7701
+ // When dragging bottom handle, constrain height to container height
7702
+ const minHeight = top < 0 &&
7703
+ typeof this.options.minimumInViewportHeight ===
7704
+ 'number'
7661
7705
  ? -top +
7662
7706
  this.options.minimumInViewportHeight
7663
- : Overlay.MINIMUM_HEIGHT, Number.MAX_VALUE);
7707
+ : Overlay.MINIMUM_HEIGHT;
7708
+ const maxHeight = containerRect.height - Math.max(0, top);
7709
+ height = clamp(y - top, minHeight, maxHeight);
7664
7710
  bottom = containerRect.height - top - height;
7665
7711
  };
7666
7712
  const moveLeft = () => {
7667
- left = clamp(x, -Number.MAX_VALUE, startPosition.originalX +
7713
+ const maxLeft = startPosition.originalX +
7668
7714
  startPosition.originalWidth >
7669
7715
  containerRect.width
7670
- ? this.getMinimumWidth(containerRect.width)
7716
+ ? Math.max(0, containerRect.width -
7717
+ Overlay.MINIMUM_WIDTH) // Prevent extending beyong right edge
7671
7718
  : Math.max(0, startPosition.originalX +
7672
7719
  startPosition.originalWidth -
7673
- Overlay.MINIMUM_WIDTH));
7720
+ Overlay.MINIMUM_WIDTH);
7721
+ left = clamp(x, 0, maxLeft); // min is 0 (Not -Infinity) to prevent dragging beyond left edge
7674
7722
  width =
7675
7723
  startPosition.originalX +
7676
7724
  startPosition.originalWidth -
@@ -7681,12 +7729,15 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7681
7729
  left =
7682
7730
  startPosition.originalX -
7683
7731
  startPosition.originalWidth;
7684
- width = clamp(x - left, left < 0 &&
7685
- typeof this.options
7686
- .minimumInViewportWidth === 'number'
7732
+ // When dragging right handle, constrain width to container width
7733
+ const minWidth = left < 0 &&
7734
+ typeof this.options.minimumInViewportWidth ===
7735
+ 'number'
7687
7736
  ? -left +
7688
7737
  this.options.minimumInViewportWidth
7689
- : Overlay.MINIMUM_WIDTH, Number.MAX_VALUE);
7738
+ : Overlay.MINIMUM_WIDTH;
7739
+ const maxWidth = containerRect.width - Math.max(0, left);
7740
+ width = clamp(x - left, minWidth, maxWidth);
7690
7741
  right = containerRect.width - left - width;
7691
7742
  };
7692
7743
  switch (direction) {
@@ -8516,7 +8567,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
8516
8567
  // option only available when no panels in primary grid
8517
8568
  return;
8518
8569
  }
8519
- this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
8570
+ this._onWillShowOverlay.fire(new DockviewWillShowOverlayLocationEvent(event, {
8520
8571
  kind: 'edge',
8521
8572
  panel: undefined,
8522
8573
  api: this._api,
@@ -8930,7 +8981,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
8930
8981
  : (_e = (_d = this.options.floatingGroupBounds) === null || _d === void 0 ? void 0 : _d.minimumHeightWithinViewport) !== null && _e !== void 0 ? _e : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE }));
8931
8982
  const el = group.element.querySelector('.dv-void-container');
8932
8983
  if (!el) {
8933
- throw new Error('failed to find drag handle');
8984
+ throw new Error('dockview: failed to find drag handle');
8934
8985
  }
8935
8986
  overlay.setupDrag(el, {
8936
8987
  inDragMode: typeof (options === null || options === void 0 ? void 0 : options.inDragMode) === 'boolean'
@@ -9002,7 +9053,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9002
9053
  case 'right':
9003
9054
  return this.createGroupAtLocation([this.gridview.length], undefined, options); // insert into last position
9004
9055
  default:
9005
- throw new Error(`unsupported position ${position}`);
9056
+ throw new Error(`dockview: unsupported position ${position}`);
9006
9057
  }
9007
9058
  }
9008
9059
  updateOptions(options) {
@@ -9148,15 +9199,48 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9148
9199
  }
9149
9200
  return result;
9150
9201
  }
9151
- fromJSON(data) {
9202
+ fromJSON(data, options) {
9152
9203
  var _a, _b;
9204
+ const existingPanels = new Map();
9205
+ let tempGroup;
9206
+ if (options === null || options === void 0 ? void 0 : options.reuseExistingPanels) {
9207
+ /**
9208
+ * What are we doing here?
9209
+ *
9210
+ * 1. Create a temporary group to hold any panels that currently exist and that also exist in the new layout
9211
+ * 2. Remove that temporary group from the group mapping so that it doesn't get cleared when we clear the layout
9212
+ */
9213
+ tempGroup = this.createGroup();
9214
+ this._groups.delete(tempGroup.api.id);
9215
+ const newPanels = Object.keys(data.panels);
9216
+ for (const panel of this.panels) {
9217
+ if (newPanels.includes(panel.api.id)) {
9218
+ existingPanels.set(panel.api.id, panel);
9219
+ }
9220
+ }
9221
+ this.movingLock(() => {
9222
+ Array.from(existingPanels.values()).forEach((panel) => {
9223
+ this.moveGroupOrPanel({
9224
+ from: {
9225
+ groupId: panel.api.group.api.id,
9226
+ panelId: panel.api.id,
9227
+ },
9228
+ to: {
9229
+ group: tempGroup,
9230
+ position: 'center',
9231
+ },
9232
+ keepEmptyGroups: true,
9233
+ });
9234
+ });
9235
+ });
9236
+ }
9153
9237
  this.clear();
9154
9238
  if (typeof data !== 'object' || data === null) {
9155
- throw new Error('serialized layout must be a non-null object');
9239
+ throw new Error('dockview: serialized layout must be a non-null object');
9156
9240
  }
9157
9241
  const { grid, panels, activeGroup } = data;
9158
9242
  if (grid.root.type !== 'branch' || !Array.isArray(grid.root.data)) {
9159
- throw new Error('root must be of type branch');
9243
+ throw new Error('dockview: root must be of type branch');
9160
9244
  }
9161
9245
  try {
9162
9246
  // take note of the existing dimensions
@@ -9165,7 +9249,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9165
9249
  const createGroupFromSerializedState = (data) => {
9166
9250
  const { id, locked, hideHeader, views, activeView } = data;
9167
9251
  if (typeof id !== 'string') {
9168
- throw new Error('group id must be of type string');
9252
+ throw new Error('dockview: group id must be of type string');
9169
9253
  }
9170
9254
  const group = this.createGroup({
9171
9255
  id,
@@ -9180,17 +9264,38 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9180
9264
  * In running this section first we avoid firing lots of 'add' events in the event of a failure
9181
9265
  * due to a corruption of input data.
9182
9266
  */
9183
- const panel = this._deserializer.fromJSON(panels[child], group);
9184
- createdPanels.push(panel);
9267
+ const existingPanel = existingPanels.get(child);
9268
+ if (tempGroup && existingPanel) {
9269
+ this.movingLock(() => {
9270
+ tempGroup.model.removePanel(existingPanel);
9271
+ });
9272
+ createdPanels.push(existingPanel);
9273
+ existingPanel.updateFromStateModel(panels[child]);
9274
+ }
9275
+ else {
9276
+ const panel = this._deserializer.fromJSON(panels[child], group);
9277
+ createdPanels.push(panel);
9278
+ }
9185
9279
  }
9186
9280
  for (let i = 0; i < views.length; i++) {
9187
9281
  const panel = createdPanels[i];
9188
9282
  const isActive = typeof activeView === 'string' &&
9189
9283
  activeView === panel.id;
9190
- group.model.openPanel(panel, {
9191
- skipSetActive: !isActive,
9192
- skipSetGroupActive: true,
9193
- });
9284
+ const hasExisting = existingPanels.has(panel.api.id);
9285
+ if (hasExisting) {
9286
+ this.movingLock(() => {
9287
+ group.model.openPanel(panel, {
9288
+ skipSetActive: !isActive,
9289
+ skipSetGroupActive: true,
9290
+ });
9291
+ });
9292
+ }
9293
+ else {
9294
+ group.model.openPanel(panel, {
9295
+ skipSetActive: !isActive,
9296
+ skipSetGroupActive: true,
9297
+ });
9298
+ }
9194
9299
  }
9195
9300
  if (!group.activePanel && group.panels.length > 0) {
9196
9301
  group.model.openPanel(group.panels[group.panels.length - 1], {
@@ -9229,7 +9334,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9229
9334
  setTimeout(() => {
9230
9335
  this.addPopoutGroup(group, {
9231
9336
  position: position !== null && position !== void 0 ? position : undefined,
9232
- overridePopoutGroup: gridReferenceGroup ? group : undefined,
9337
+ overridePopoutGroup: gridReferenceGroup
9338
+ ? group
9339
+ : undefined,
9233
9340
  referenceGroup: gridReferenceGroup
9234
9341
  ? this.getPanel(gridReferenceGroup)
9235
9342
  : undefined,
@@ -9315,11 +9422,11 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9315
9422
  addPanel(options) {
9316
9423
  var _a, _b;
9317
9424
  if (this.panels.find((_) => _.id === options.id)) {
9318
- throw new Error(`panel with id ${options.id} already exists`);
9425
+ throw new Error(`dockview: panel with id ${options.id} already exists`);
9319
9426
  }
9320
9427
  let referenceGroup;
9321
9428
  if (options.position && options.floating) {
9322
- throw new Error('you can only provide one of: position, floating as arguments to .addPanel(...)');
9429
+ throw new Error('dockview: you can only provide one of: position, floating as arguments to .addPanel(...)');
9323
9430
  }
9324
9431
  const initial = {
9325
9432
  width: options.initialWidth,
@@ -9333,7 +9440,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9333
9440
  : options.position.referencePanel;
9334
9441
  index = options.position.index;
9335
9442
  if (!referencePanel) {
9336
- throw new Error(`referencePanel '${options.position.referencePanel}' does not exist`);
9443
+ throw new Error(`dockview: referencePanel '${options.position.referencePanel}' does not exist`);
9337
9444
  }
9338
9445
  referenceGroup = this.findGroup(referencePanel);
9339
9446
  }
@@ -9344,7 +9451,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9344
9451
  : options.position.referenceGroup;
9345
9452
  index = options.position.index;
9346
9453
  if (!referenceGroup) {
9347
- throw new Error(`referenceGroup '${options.position.referenceGroup}' does not exist`);
9454
+ throw new Error(`dockview: referenceGroup '${options.position.referenceGroup}' does not exist`);
9348
9455
  }
9349
9456
  }
9350
9457
  else {
@@ -9456,7 +9563,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9456
9563
  }) {
9457
9564
  const group = panel.group;
9458
9565
  if (!group) {
9459
- throw new Error(`cannot remove panel ${panel.id}. it's missing a group.`);
9566
+ throw new Error(`dockview: cannot remove panel ${panel.id}. it's missing a group.`);
9460
9567
  }
9461
9568
  group.model.removePanel(panel, {
9462
9569
  skipSetActiveGroup: options.skipSetActiveGroup,
@@ -9505,11 +9612,11 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9505
9612
  ? this.panels.find((panel) => panel.id === options.referencePanel)
9506
9613
  : options.referencePanel;
9507
9614
  if (!referencePanel) {
9508
- throw new Error(`reference panel ${options.referencePanel} does not exist`);
9615
+ throw new Error(`dockview: reference panel ${options.referencePanel} does not exist`);
9509
9616
  }
9510
9617
  referenceGroup = this.findGroup(referencePanel);
9511
9618
  if (!referenceGroup) {
9512
- throw new Error(`reference group for reference panel ${options.referencePanel} does not exist`);
9619
+ throw new Error(`dockview: reference group for reference panel ${options.referencePanel} does not exist`);
9513
9620
  }
9514
9621
  }
9515
9622
  else if (isGroupOptionsWithGroup(options)) {
@@ -9518,7 +9625,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9518
9625
  ? (_a = this._groups.get(options.referenceGroup)) === null || _a === void 0 ? void 0 : _a.value
9519
9626
  : options.referenceGroup;
9520
9627
  if (!referenceGroup) {
9521
- throw new Error(`reference group ${options.referenceGroup} does not exist`);
9628
+ throw new Error(`dockview: reference group ${options.referenceGroup} does not exist`);
9522
9629
  }
9523
9630
  }
9524
9631
  else {
@@ -9586,7 +9693,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9586
9693
  }
9587
9694
  return floatingGroup.group;
9588
9695
  }
9589
- throw new Error('failed to find floating group');
9696
+ throw new Error('dockview: failed to find floating group');
9590
9697
  }
9591
9698
  if (group.api.location.type === 'popout') {
9592
9699
  const selectedGroup = this._popoutGroups.find((_) => _.popoutGroup === group);
@@ -9617,7 +9724,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9617
9724
  this.updateWatermark();
9618
9725
  return selectedGroup.popoutGroup;
9619
9726
  }
9620
- throw new Error('failed to find popout group');
9727
+ throw new Error('dockview: failed to find popout group');
9621
9728
  }
9622
9729
  const re = super.doRemoveGroup(group, options);
9623
9730
  if (!(options === null || options === void 0 ? void 0 : options.skipActive)) {
@@ -9648,7 +9755,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9648
9755
  ? (_a = this._groups.get(sourceGroupId)) === null || _a === void 0 ? void 0 : _a.value
9649
9756
  : undefined;
9650
9757
  if (!sourceGroup) {
9651
- throw new Error(`Failed to find group id ${sourceGroupId}`);
9758
+ throw new Error(`dockview: Failed to find group id ${sourceGroupId}`);
9652
9759
  }
9653
9760
  if (sourceItemId === undefined) {
9654
9761
  /**
@@ -9673,9 +9780,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9673
9780
  skipSetActiveGroup: true,
9674
9781
  }));
9675
9782
  if (!removedPanel) {
9676
- throw new Error(`No panel with id ${sourceItemId}`);
9783
+ throw new Error(`dockview: No panel with id ${sourceItemId}`);
9677
9784
  }
9678
- if (sourceGroup.model.size === 0) {
9785
+ if (!options.keepEmptyGroups && sourceGroup.model.size === 0) {
9679
9786
  // remove the group and do not set a new group as active
9680
9787
  this.doRemoveGroup(sourceGroup, { skipActive: true });
9681
9788
  }
@@ -9685,7 +9792,8 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9685
9792
  var _a;
9686
9793
  return destinationGroup.model.openPanel(removedPanel, {
9687
9794
  index: destinationIndex,
9688
- skipSetActive: ((_a = options.skipSetActive) !== null && _a !== void 0 ? _a : false) && !isDestinationGroupEmpty,
9795
+ skipSetActive: ((_a = options.skipSetActive) !== null && _a !== void 0 ? _a : false) &&
9796
+ !isDestinationGroupEmpty,
9689
9797
  skipSetGroupActive: true,
9690
9798
  });
9691
9799
  });
@@ -9696,6 +9804,13 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9696
9804
  panel: removedPanel,
9697
9805
  from: sourceGroup,
9698
9806
  });
9807
+ /**
9808
+ * Update overlay positions after DOM layout completes to prevent 0×0 dimensions.
9809
+ * With defaultRenderer="always" this results in panel content not showing after move operations.
9810
+ */
9811
+ requestAnimationFrame(() => {
9812
+ this.overlayRenderContainer.updateAllPositions();
9813
+ });
9699
9814
  }
9700
9815
  else {
9701
9816
  /**
@@ -9740,7 +9855,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9740
9855
  }));
9741
9856
  this.doRemoveGroup(sourceGroup, { skipActive: true });
9742
9857
  const newGroup = this.createGroupAtLocation(targetLocation);
9743
- this.movingLock(() => newGroup.model.openPanel(removedPanel));
9858
+ this.movingLock(() => newGroup.model.openPanel(removedPanel, {
9859
+ skipSetActive: true,
9860
+ }));
9744
9861
  this.doSetGroupAndPanelActive(newGroup);
9745
9862
  this._onDidMovePanel.fire({
9746
9863
  panel: this.getGroupPanel(sourceItemId),
@@ -9773,7 +9890,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9773
9890
  skipSetActiveGroup: true,
9774
9891
  }));
9775
9892
  if (!removedPanel) {
9776
- throw new Error(`No panel with id ${sourceItemId}`);
9893
+ throw new Error(`dockview: No panel with id ${sourceItemId}`);
9777
9894
  }
9778
9895
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
9779
9896
  const group = this.createGroupAtLocation(dropLocation);
@@ -9828,7 +9945,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9828
9945
  case 'floating': {
9829
9946
  const selectedFloatingGroup = this._floatingGroups.find((x) => x.group === from);
9830
9947
  if (!selectedFloatingGroup) {
9831
- throw new Error('failed to find floating group');
9948
+ throw new Error('dockview: failed to find floating group');
9832
9949
  }
9833
9950
  selectedFloatingGroup.dispose();
9834
9951
  break;
@@ -9836,7 +9953,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9836
9953
  case 'popout': {
9837
9954
  const selectedPopoutGroup = this._popoutGroups.find((x) => x.popoutGroup === from);
9838
9955
  if (!selectedPopoutGroup) {
9839
- throw new Error('failed to find popout group');
9956
+ throw new Error('dockview: failed to find popout group');
9840
9957
  }
9841
9958
  // Remove from popout groups list to prevent automatic restoration
9842
9959
  const index = this._popoutGroups.indexOf(selectedPopoutGroup);
@@ -12005,6 +12122,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
12005
12122
  exports.DockviewReact = DockviewReact;
12006
12123
  exports.DockviewUnhandledDragOverEvent = DockviewUnhandledDragOverEvent;
12007
12124
  exports.DockviewWillDropEvent = DockviewWillDropEvent;
12125
+ exports.DockviewWillShowOverlayLocationEvent = DockviewWillShowOverlayLocationEvent;
12008
12126
  exports.DraggablePaneviewPanel = DraggablePaneviewPanel;
12009
12127
  exports.Gridview = Gridview;
12010
12128
  exports.GridviewApi = GridviewApi;