dockview-react 4.11.0 → 4.12.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.12.0
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -3755,8 +3755,8 @@
3755
3755
  /**
3756
3756
  * Create a component from a serialized object.
3757
3757
  */
3758
- fromJSON(data) {
3759
- this.component.fromJSON(data);
3758
+ fromJSON(data, options) {
3759
+ this.component.fromJSON(data, options);
3760
3760
  }
3761
3761
  /**
3762
3762
  * Create a serialized object of the current component.
@@ -4987,6 +4987,7 @@
4987
4987
  }
4988
4988
  if (doRender) {
4989
4989
  const focusTracker = trackFocus(container);
4990
+ this.focusTracker = focusTracker;
4990
4991
  const disposable = new CompositeDisposable();
4991
4992
  disposable.addDisposables(focusTracker, focusTracker.onDidFocus(() => this._onDidFocus.fire()), focusTracker.onDidBlur(() => this._onDidBlur.fire()));
4992
4993
  this.disposable.value = disposable;
@@ -5014,6 +5015,16 @@
5014
5015
  this.disposable.dispose();
5015
5016
  super.dispose();
5016
5017
  }
5018
+ /**
5019
+ * Refresh the focus tracker state to handle cases where focus state
5020
+ * gets out of sync due to programmatic panel activation
5021
+ */
5022
+ refreshFocusState() {
5023
+ var _a;
5024
+ if ((_a = this.focusTracker) === null || _a === void 0 ? void 0 : _a.refreshState) {
5025
+ this.focusTracker.refreshState();
5026
+ }
5027
+ }
5017
5028
  }
5018
5029
 
5019
5030
  function addGhostImage(dataTransfer, ghostElement, options) {
@@ -6340,8 +6351,11 @@
6340
6351
  this._activePanel = panel;
6341
6352
  if (panel) {
6342
6353
  this.tabsContainer.setActivePanel(panel);
6354
+ this.contentContainer.openPanel(panel);
6343
6355
  panel.layout(this._width, this._height);
6344
6356
  this.updateMru(panel);
6357
+ // Refresh focus state to handle programmatic activation without DOM focus change
6358
+ this.contentContainer.refreshFocusState();
6345
6359
  this._onDidActivePanelChange.fire({
6346
6360
  panel,
6347
6361
  });
@@ -7171,6 +7185,18 @@
7171
7185
  params: this._params,
7172
7186
  });
7173
7187
  }
7188
+ updateFromStateModel(state) {
7189
+ var _a, _b, _c;
7190
+ this._maximumHeight = state.maximumHeight;
7191
+ this._minimumHeight = state.minimumHeight;
7192
+ this._maximumWidth = state.maximumWidth;
7193
+ this._minimumWidth = state.minimumWidth;
7194
+ this.update({ params: (_a = state.params) !== null && _a !== void 0 ? _a : {} });
7195
+ this.setTitle((_b = state.title) !== null && _b !== void 0 ? _b : this.id);
7196
+ this.setRenderer((_c = state.renderer) !== null && _c !== void 0 ? _c : this.accessor.renderer);
7197
+ // state.contentComponent;
7198
+ // state.tabComponent;
7199
+ }
7174
7200
  updateParentGroup(group, options) {
7175
7201
  this._group = group;
7176
7202
  this.api.group = this._group;
@@ -8934,7 +8960,7 @@
8934
8960
  : (_e = (_d = this.options.floatingGroupBounds) === null || _d === void 0 ? void 0 : _d.minimumHeightWithinViewport) !== null && _e !== void 0 ? _e : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE }));
8935
8961
  const el = group.element.querySelector('.dv-void-container');
8936
8962
  if (!el) {
8937
- throw new Error('failed to find drag handle');
8963
+ throw new Error('dockview: failed to find drag handle');
8938
8964
  }
8939
8965
  overlay.setupDrag(el, {
8940
8966
  inDragMode: typeof (options === null || options === void 0 ? void 0 : options.inDragMode) === 'boolean'
@@ -9006,7 +9032,7 @@
9006
9032
  case 'right':
9007
9033
  return this.createGroupAtLocation([this.gridview.length], undefined, options); // insert into last position
9008
9034
  default:
9009
- throw new Error(`unsupported position ${position}`);
9035
+ throw new Error(`dockview: unsupported position ${position}`);
9010
9036
  }
9011
9037
  }
9012
9038
  updateOptions(options) {
@@ -9152,15 +9178,48 @@
9152
9178
  }
9153
9179
  return result;
9154
9180
  }
9155
- fromJSON(data) {
9181
+ fromJSON(data, options) {
9156
9182
  var _a, _b;
9183
+ const existingPanels = new Map();
9184
+ let tempGroup;
9185
+ if (options === null || options === void 0 ? void 0 : options.reuseExistingPanels) {
9186
+ /**
9187
+ * What are we doing here?
9188
+ *
9189
+ * 1. Create a temporary group to hold any panels that currently exist and that also exist in the new layout
9190
+ * 2. Remove that temporary group from the group mapping so that it doesn't get cleared when we clear the layout
9191
+ */
9192
+ tempGroup = this.createGroup();
9193
+ this._groups.delete(tempGroup.api.id);
9194
+ const newPanels = Object.keys(data.panels);
9195
+ for (const panel of this.panels) {
9196
+ if (newPanels.includes(panel.api.id)) {
9197
+ existingPanels.set(panel.api.id, panel);
9198
+ }
9199
+ }
9200
+ this.movingLock(() => {
9201
+ Array.from(existingPanels.values()).forEach((panel) => {
9202
+ this.moveGroupOrPanel({
9203
+ from: {
9204
+ groupId: panel.api.group.api.id,
9205
+ panelId: panel.api.id,
9206
+ },
9207
+ to: {
9208
+ group: tempGroup,
9209
+ position: 'center',
9210
+ },
9211
+ keepEmptyGroups: true,
9212
+ });
9213
+ });
9214
+ });
9215
+ }
9157
9216
  this.clear();
9158
9217
  if (typeof data !== 'object' || data === null) {
9159
- throw new Error('serialized layout must be a non-null object');
9218
+ throw new Error('dockview: serialized layout must be a non-null object');
9160
9219
  }
9161
9220
  const { grid, panels, activeGroup } = data;
9162
9221
  if (grid.root.type !== 'branch' || !Array.isArray(grid.root.data)) {
9163
- throw new Error('root must be of type branch');
9222
+ throw new Error('dockview: root must be of type branch');
9164
9223
  }
9165
9224
  try {
9166
9225
  // take note of the existing dimensions
@@ -9169,7 +9228,7 @@
9169
9228
  const createGroupFromSerializedState = (data) => {
9170
9229
  const { id, locked, hideHeader, views, activeView } = data;
9171
9230
  if (typeof id !== 'string') {
9172
- throw new Error('group id must be of type string');
9231
+ throw new Error('dockview: group id must be of type string');
9173
9232
  }
9174
9233
  const group = this.createGroup({
9175
9234
  id,
@@ -9184,17 +9243,38 @@
9184
9243
  * In running this section first we avoid firing lots of 'add' events in the event of a failure
9185
9244
  * due to a corruption of input data.
9186
9245
  */
9187
- const panel = this._deserializer.fromJSON(panels[child], group);
9188
- createdPanels.push(panel);
9246
+ const existingPanel = existingPanels.get(child);
9247
+ if (tempGroup && existingPanel) {
9248
+ this.movingLock(() => {
9249
+ tempGroup.model.removePanel(existingPanel);
9250
+ });
9251
+ createdPanels.push(existingPanel);
9252
+ existingPanel.updateFromStateModel(panels[child]);
9253
+ }
9254
+ else {
9255
+ const panel = this._deserializer.fromJSON(panels[child], group);
9256
+ createdPanels.push(panel);
9257
+ }
9189
9258
  }
9190
9259
  for (let i = 0; i < views.length; i++) {
9191
9260
  const panel = createdPanels[i];
9192
9261
  const isActive = typeof activeView === 'string' &&
9193
9262
  activeView === panel.id;
9194
- group.model.openPanel(panel, {
9195
- skipSetActive: !isActive,
9196
- skipSetGroupActive: true,
9197
- });
9263
+ const hasExisting = existingPanels.has(panel.api.id);
9264
+ if (hasExisting) {
9265
+ this.movingLock(() => {
9266
+ group.model.openPanel(panel, {
9267
+ skipSetActive: !isActive,
9268
+ skipSetGroupActive: true,
9269
+ });
9270
+ });
9271
+ }
9272
+ else {
9273
+ group.model.openPanel(panel, {
9274
+ skipSetActive: !isActive,
9275
+ skipSetGroupActive: true,
9276
+ });
9277
+ }
9198
9278
  }
9199
9279
  if (!group.activePanel && group.panels.length > 0) {
9200
9280
  group.model.openPanel(group.panels[group.panels.length - 1], {
@@ -9233,7 +9313,9 @@
9233
9313
  setTimeout(() => {
9234
9314
  this.addPopoutGroup(group, {
9235
9315
  position: position !== null && position !== void 0 ? position : undefined,
9236
- overridePopoutGroup: gridReferenceGroup ? group : undefined,
9316
+ overridePopoutGroup: gridReferenceGroup
9317
+ ? group
9318
+ : undefined,
9237
9319
  referenceGroup: gridReferenceGroup
9238
9320
  ? this.getPanel(gridReferenceGroup)
9239
9321
  : undefined,
@@ -9319,11 +9401,11 @@
9319
9401
  addPanel(options) {
9320
9402
  var _a, _b;
9321
9403
  if (this.panels.find((_) => _.id === options.id)) {
9322
- throw new Error(`panel with id ${options.id} already exists`);
9404
+ throw new Error(`dockview: panel with id ${options.id} already exists`);
9323
9405
  }
9324
9406
  let referenceGroup;
9325
9407
  if (options.position && options.floating) {
9326
- throw new Error('you can only provide one of: position, floating as arguments to .addPanel(...)');
9408
+ throw new Error('dockview: you can only provide one of: position, floating as arguments to .addPanel(...)');
9327
9409
  }
9328
9410
  const initial = {
9329
9411
  width: options.initialWidth,
@@ -9337,7 +9419,7 @@
9337
9419
  : options.position.referencePanel;
9338
9420
  index = options.position.index;
9339
9421
  if (!referencePanel) {
9340
- throw new Error(`referencePanel '${options.position.referencePanel}' does not exist`);
9422
+ throw new Error(`dockview: referencePanel '${options.position.referencePanel}' does not exist`);
9341
9423
  }
9342
9424
  referenceGroup = this.findGroup(referencePanel);
9343
9425
  }
@@ -9348,7 +9430,7 @@
9348
9430
  : options.position.referenceGroup;
9349
9431
  index = options.position.index;
9350
9432
  if (!referenceGroup) {
9351
- throw new Error(`referenceGroup '${options.position.referenceGroup}' does not exist`);
9433
+ throw new Error(`dockview: referenceGroup '${options.position.referenceGroup}' does not exist`);
9352
9434
  }
9353
9435
  }
9354
9436
  else {
@@ -9460,7 +9542,7 @@
9460
9542
  }) {
9461
9543
  const group = panel.group;
9462
9544
  if (!group) {
9463
- throw new Error(`cannot remove panel ${panel.id}. it's missing a group.`);
9545
+ throw new Error(`dockview: cannot remove panel ${panel.id}. it's missing a group.`);
9464
9546
  }
9465
9547
  group.model.removePanel(panel, {
9466
9548
  skipSetActiveGroup: options.skipSetActiveGroup,
@@ -9509,11 +9591,11 @@
9509
9591
  ? this.panels.find((panel) => panel.id === options.referencePanel)
9510
9592
  : options.referencePanel;
9511
9593
  if (!referencePanel) {
9512
- throw new Error(`reference panel ${options.referencePanel} does not exist`);
9594
+ throw new Error(`dockview: reference panel ${options.referencePanel} does not exist`);
9513
9595
  }
9514
9596
  referenceGroup = this.findGroup(referencePanel);
9515
9597
  if (!referenceGroup) {
9516
- throw new Error(`reference group for reference panel ${options.referencePanel} does not exist`);
9598
+ throw new Error(`dockview: reference group for reference panel ${options.referencePanel} does not exist`);
9517
9599
  }
9518
9600
  }
9519
9601
  else if (isGroupOptionsWithGroup(options)) {
@@ -9522,7 +9604,7 @@
9522
9604
  ? (_a = this._groups.get(options.referenceGroup)) === null || _a === void 0 ? void 0 : _a.value
9523
9605
  : options.referenceGroup;
9524
9606
  if (!referenceGroup) {
9525
- throw new Error(`reference group ${options.referenceGroup} does not exist`);
9607
+ throw new Error(`dockview: reference group ${options.referenceGroup} does not exist`);
9526
9608
  }
9527
9609
  }
9528
9610
  else {
@@ -9590,7 +9672,7 @@
9590
9672
  }
9591
9673
  return floatingGroup.group;
9592
9674
  }
9593
- throw new Error('failed to find floating group');
9675
+ throw new Error('dockview: failed to find floating group');
9594
9676
  }
9595
9677
  if (group.api.location.type === 'popout') {
9596
9678
  const selectedGroup = this._popoutGroups.find((_) => _.popoutGroup === group);
@@ -9621,7 +9703,7 @@
9621
9703
  this.updateWatermark();
9622
9704
  return selectedGroup.popoutGroup;
9623
9705
  }
9624
- throw new Error('failed to find popout group');
9706
+ throw new Error('dockview: failed to find popout group');
9625
9707
  }
9626
9708
  const re = super.doRemoveGroup(group, options);
9627
9709
  if (!(options === null || options === void 0 ? void 0 : options.skipActive)) {
@@ -9652,7 +9734,7 @@
9652
9734
  ? (_a = this._groups.get(sourceGroupId)) === null || _a === void 0 ? void 0 : _a.value
9653
9735
  : undefined;
9654
9736
  if (!sourceGroup) {
9655
- throw new Error(`Failed to find group id ${sourceGroupId}`);
9737
+ throw new Error(`dockview: Failed to find group id ${sourceGroupId}`);
9656
9738
  }
9657
9739
  if (sourceItemId === undefined) {
9658
9740
  /**
@@ -9677,9 +9759,9 @@
9677
9759
  skipSetActiveGroup: true,
9678
9760
  }));
9679
9761
  if (!removedPanel) {
9680
- throw new Error(`No panel with id ${sourceItemId}`);
9762
+ throw new Error(`dockview: No panel with id ${sourceItemId}`);
9681
9763
  }
9682
- if (sourceGroup.model.size === 0) {
9764
+ if (!options.keepEmptyGroups && sourceGroup.model.size === 0) {
9683
9765
  // remove the group and do not set a new group as active
9684
9766
  this.doRemoveGroup(sourceGroup, { skipActive: true });
9685
9767
  }
@@ -9689,7 +9771,8 @@
9689
9771
  var _a;
9690
9772
  return destinationGroup.model.openPanel(removedPanel, {
9691
9773
  index: destinationIndex,
9692
- skipSetActive: ((_a = options.skipSetActive) !== null && _a !== void 0 ? _a : false) && !isDestinationGroupEmpty,
9774
+ skipSetActive: ((_a = options.skipSetActive) !== null && _a !== void 0 ? _a : false) &&
9775
+ !isDestinationGroupEmpty,
9693
9776
  skipSetGroupActive: true,
9694
9777
  });
9695
9778
  });
@@ -9744,7 +9827,9 @@
9744
9827
  }));
9745
9828
  this.doRemoveGroup(sourceGroup, { skipActive: true });
9746
9829
  const newGroup = this.createGroupAtLocation(targetLocation);
9747
- this.movingLock(() => newGroup.model.openPanel(removedPanel));
9830
+ this.movingLock(() => newGroup.model.openPanel(removedPanel, {
9831
+ skipSetActive: true,
9832
+ }));
9748
9833
  this.doSetGroupAndPanelActive(newGroup);
9749
9834
  this._onDidMovePanel.fire({
9750
9835
  panel: this.getGroupPanel(sourceItemId),
@@ -9777,7 +9862,7 @@
9777
9862
  skipSetActiveGroup: true,
9778
9863
  }));
9779
9864
  if (!removedPanel) {
9780
- throw new Error(`No panel with id ${sourceItemId}`);
9865
+ throw new Error(`dockview: No panel with id ${sourceItemId}`);
9781
9866
  }
9782
9867
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
9783
9868
  const group = this.createGroupAtLocation(dropLocation);
@@ -9832,7 +9917,7 @@
9832
9917
  case 'floating': {
9833
9918
  const selectedFloatingGroup = this._floatingGroups.find((x) => x.group === from);
9834
9919
  if (!selectedFloatingGroup) {
9835
- throw new Error('failed to find floating group');
9920
+ throw new Error('dockview: failed to find floating group');
9836
9921
  }
9837
9922
  selectedFloatingGroup.dispose();
9838
9923
  break;
@@ -9840,7 +9925,7 @@
9840
9925
  case 'popout': {
9841
9926
  const selectedPopoutGroup = this._popoutGroups.find((x) => x.popoutGroup === from);
9842
9927
  if (!selectedPopoutGroup) {
9843
- throw new Error('failed to find popout group');
9928
+ throw new Error('dockview: failed to find popout group');
9844
9929
  }
9845
9930
  // Remove from popout groups list to prevent automatic restoration
9846
9931
  const index = this._popoutGroups.indexOf(selectedPopoutGroup);