dockview-react 8.6.0 → 8.6.2
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/dist/dockview-react.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* dockview-react
|
|
3
|
-
* @version 8.6.
|
|
3
|
+
* @version 8.6.2
|
|
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.6.
|
|
54
|
+
* @version 8.6.2
|
|
55
55
|
* @link https://github.com/dockview/dockview
|
|
56
56
|
* @license MIT
|
|
57
57
|
*/
|
|
@@ -725,7 +725,7 @@ react_dom = __toESM(react_dom);
|
|
|
725
725
|
resizeTimeout = setTimeout(() => {
|
|
726
726
|
cb();
|
|
727
727
|
}, DEBOUCE_DELAY);
|
|
728
|
-
}));
|
|
728
|
+
}), Disposable.from(() => clearTimeout(resizeTimeout)));
|
|
729
729
|
}
|
|
730
730
|
function shiftAbsoluteElementIntoView(element, root, options) {
|
|
731
731
|
var _options$buffer;
|
|
@@ -2259,12 +2259,20 @@ react_dom = __toESM(react_dom);
|
|
|
2259
2259
|
if (candiateNode instanceof BranchNode) return findLeaf(candiateNode.children[last ? candiateNode.children.length - 1 : 0], last);
|
|
2260
2260
|
throw new Error("invalid node");
|
|
2261
2261
|
}
|
|
2262
|
+
/**
|
|
2263
|
+
* The sizing to re-add a branch's child with, so a hidden child stays hidden
|
|
2264
|
+
* (with its cached size) instead of coming back visible at size 0.
|
|
2265
|
+
*/
|
|
2266
|
+
function childSizing(node, index, size, scale = 1) {
|
|
2267
|
+
const cachedVisibleSize = node.getChildCachedVisibleSize(index);
|
|
2268
|
+
return cachedVisibleSize === void 0 ? size : Sizing.Invisible(Math.round(cachedVisibleSize * scale));
|
|
2269
|
+
}
|
|
2262
2270
|
function cloneNode(node, size, orthogonalSize) {
|
|
2263
2271
|
if (node instanceof BranchNode) {
|
|
2264
2272
|
const result = new BranchNode(node.orientation, node.proportionalLayout, node.styles, size, orthogonalSize, node.disabled, node.margin);
|
|
2265
2273
|
for (let i = node.children.length - 1; i >= 0; i--) {
|
|
2266
2274
|
const child = node.children[i];
|
|
2267
|
-
result.addChild(cloneNode(child, child.size, child.orthogonalSize), child.size, 0, true);
|
|
2275
|
+
result.addChild(cloneNode(child, child.size, child.orthogonalSize), childSizing(node, i, child.size), 0, true);
|
|
2268
2276
|
}
|
|
2269
2277
|
return result;
|
|
2270
2278
|
} else return new LeafNode(node.view, node.orientation, orthogonalSize);
|
|
@@ -2273,13 +2281,14 @@ react_dom = __toESM(react_dom);
|
|
|
2273
2281
|
if (node instanceof BranchNode) {
|
|
2274
2282
|
const result = new BranchNode(orthogonal(node.orientation), node.proportionalLayout, node.styles, size, orthogonalSize, node.disabled, node.margin);
|
|
2275
2283
|
let totalSize = 0;
|
|
2284
|
+
const cachedSizeScale = node.size === 0 ? 1 : size / node.size;
|
|
2276
2285
|
for (let i = node.children.length - 1; i >= 0; i--) {
|
|
2277
2286
|
const child = node.children[i];
|
|
2278
2287
|
const childSize = child instanceof BranchNode ? child.orthogonalSize : child.size;
|
|
2279
2288
|
let newSize = node.size === 0 ? 0 : Math.round(size * childSize / node.size);
|
|
2280
2289
|
totalSize += newSize;
|
|
2281
2290
|
if (i === 0) newSize += size - totalSize;
|
|
2282
|
-
result.addChild(flipNode(child, orthogonalSize, newSize), newSize, 0, true);
|
|
2291
|
+
result.addChild(flipNode(child, orthogonalSize, newSize), childSizing(node, i, newSize, cachedSizeScale), 0, true);
|
|
2283
2292
|
}
|
|
2284
2293
|
return result;
|
|
2285
2294
|
} else return new LeafNode(node.view, orthogonal(node.orientation), orthogonalSize);
|
|
@@ -2765,7 +2774,8 @@ react_dom = __toESM(react_dom);
|
|
|
2765
2774
|
sizes.splice(parentIndex, 1, ...sibling.children.map((c) => c.size));
|
|
2766
2775
|
for (let i = 0; i < sibling.children.length; i++) {
|
|
2767
2776
|
const child = sibling.children[i];
|
|
2768
|
-
|
|
2777
|
+
const childSize = childSizing(sibling, i, child.size);
|
|
2778
|
+
grandParent.addChild(child, !isSiblingVisible && typeof childSize === "number" ? Sizing.Invisible(childSize) : childSize, parentIndex + i);
|
|
2769
2779
|
}
|
|
2770
2780
|
/**
|
|
2771
2781
|
* clean down the branch node since we need to dipose of it and
|
|
@@ -3943,6 +3953,33 @@ react_dom = __toESM(react_dom);
|
|
|
3943
3953
|
return this.component.withOrigin("api", () => this.component.addGroup(options));
|
|
3944
3954
|
}
|
|
3945
3955
|
/**
|
|
3956
|
+
* Serialize one group together with the state of every panel it holds.
|
|
3957
|
+
* The result is self-contained and can be rehydrated with
|
|
3958
|
+
* `addGroupFromJSON`, on this instance or another one.
|
|
3959
|
+
*/
|
|
3960
|
+
serializeGroup(group) {
|
|
3961
|
+
return this.component.serializeGroup(group);
|
|
3962
|
+
}
|
|
3963
|
+
/**
|
|
3964
|
+
* Rebuild a group from `serializeGroup` output and add it to the live
|
|
3965
|
+
* layout, positioned as for `addGroup`, leaving the rest of the layout
|
|
3966
|
+
* untouched. Throws before changing anything if a panel id is already in
|
|
3967
|
+
* use.
|
|
3968
|
+
*/
|
|
3969
|
+
addGroupFromJSON(data, options) {
|
|
3970
|
+
return this.component.withOrigin("api", () => this.component.addGroupFromJSON(data, options));
|
|
3971
|
+
}
|
|
3972
|
+
/**
|
|
3973
|
+
* Add a panel from its `toJSON()` state, placed as `addPanel` places
|
|
3974
|
+
* one: the counterpart to `panel.toJSON()` for a single tab moving
|
|
3975
|
+
* between layouts or instances, as `addGroupFromJSON` is to
|
|
3976
|
+
* `serializeGroup`. Throws before changing anything if the panel id is
|
|
3977
|
+
* already in use.
|
|
3978
|
+
*/
|
|
3979
|
+
addPanelFromJSON(state, options) {
|
|
3980
|
+
return this.component.withOrigin("api", () => this.component.addPanelFromJSON(state, options));
|
|
3981
|
+
}
|
|
3982
|
+
/**
|
|
3946
3983
|
* Close all groups and panels.
|
|
3947
3984
|
*/
|
|
3948
3985
|
closeAllGroups() {
|
|
@@ -5937,6 +5974,9 @@ react_dom = __toESM(react_dom);
|
|
|
5937
5974
|
get element() {
|
|
5938
5975
|
return this._element;
|
|
5939
5976
|
}
|
|
5977
|
+
get dimensions() {
|
|
5978
|
+
return this._dimensions;
|
|
5979
|
+
}
|
|
5940
5980
|
constructor(accessor, group) {
|
|
5941
5981
|
var _this$accessor$resolv, _this$accessor, _this$accessor$resolv2, _this$accessor2, _this$accessor$onDidO, _this$accessor$onDidO2, _this$accessor3;
|
|
5942
5982
|
super();
|
|
@@ -5947,12 +5987,14 @@ react_dom = __toESM(react_dom);
|
|
|
5947
5987
|
this.onDidFocus = this._onDidFocus.event;
|
|
5948
5988
|
this._onDidBlur = new Emitter();
|
|
5949
5989
|
this.onDidBlur = this._onDidBlur.event;
|
|
5990
|
+
this._onDidDimensionsChange = new Emitter();
|
|
5991
|
+
this.onDidDimensionsChange = this._onDidDimensionsChange.event;
|
|
5950
5992
|
this._element = document.createElement("div");
|
|
5951
5993
|
this._element.className = "dv-content-container";
|
|
5952
5994
|
this._element.tabIndex = -1;
|
|
5953
5995
|
this._element.id = nextContentId();
|
|
5954
5996
|
this._element.setAttribute("role", "tabpanel");
|
|
5955
|
-
this.addDisposables(this._onDidFocus, this._onDidBlur);
|
|
5997
|
+
this.addDisposables(this._onDidFocus, this._onDidBlur, this._onDidDimensionsChange);
|
|
5956
5998
|
const getOverrideTarget = () => {
|
|
5957
5999
|
var _group$dropTargetCont;
|
|
5958
6000
|
return (_group$dropTargetCont = group.dropTargetContainer) === null || _group$dropTargetCont === void 0 ? void 0 : _group$dropTargetCont.model;
|
|
@@ -6061,7 +6103,15 @@ react_dom = __toESM(react_dom);
|
|
|
6061
6103
|
if (this.panel === panel) return;
|
|
6062
6104
|
this.renderPanel(panel);
|
|
6063
6105
|
}
|
|
6064
|
-
layout(
|
|
6106
|
+
layout(width, height) {
|
|
6107
|
+
var _this$_dimensions;
|
|
6108
|
+
if (((_this$_dimensions = this._dimensions) === null || _this$_dimensions === void 0 ? void 0 : _this$_dimensions.width) === width && this._dimensions.height === height) return;
|
|
6109
|
+
this._dimensions = {
|
|
6110
|
+
width,
|
|
6111
|
+
height
|
|
6112
|
+
};
|
|
6113
|
+
this._onDidDimensionsChange.fire(this._dimensions);
|
|
6114
|
+
}
|
|
6065
6115
|
closePanel() {
|
|
6066
6116
|
if (this.panel) {
|
|
6067
6117
|
if (this.panel.api.renderer === "onlyWhenVisible") {
|
|
@@ -6910,6 +6960,7 @@ react_dom = __toESM(react_dom);
|
|
|
6910
6960
|
className: void 0,
|
|
6911
6961
|
noPanelsOverlay: void 0,
|
|
6912
6962
|
closeEmptyGroups: void 0,
|
|
6963
|
+
groupIdGenerator: void 0,
|
|
6913
6964
|
dndEdges: void 0,
|
|
6914
6965
|
dropPositionResolver: void 0,
|
|
6915
6966
|
dndCompass: void 0,
|
|
@@ -10438,6 +10489,15 @@ react_dom = __toESM(react_dom);
|
|
|
10438
10489
|
get panel() {
|
|
10439
10490
|
return this.options.panel;
|
|
10440
10491
|
}
|
|
10492
|
+
/**
|
|
10493
|
+
* For a drop on a group's tab bar, the tab index the drop landed at:
|
|
10494
|
+
* where a panel added in response belongs (`addPanel`'s `index`, or
|
|
10495
|
+
* `addGroupFromJSON` with `direction: 'within'`). `undefined` for a
|
|
10496
|
+
* drop on a group's content or a layout edge.
|
|
10497
|
+
*/
|
|
10498
|
+
get index() {
|
|
10499
|
+
return this.options.index;
|
|
10500
|
+
}
|
|
10441
10501
|
get group() {
|
|
10442
10502
|
return this.options.group;
|
|
10443
10503
|
}
|
|
@@ -10526,7 +10586,6 @@ react_dom = __toESM(react_dom);
|
|
|
10526
10586
|
return (_this$_headerPosition = this._headerPosition) !== null && _this$_headerPosition !== void 0 ? _this$_headerPosition : "top";
|
|
10527
10587
|
}
|
|
10528
10588
|
set headerPosition(value) {
|
|
10529
|
-
var _this$_activePanel;
|
|
10530
10589
|
this._headerPosition = value;
|
|
10531
10590
|
this.invalidateHeaderSize();
|
|
10532
10591
|
removeClasses(this.container, "dv-groupview-header-top", "dv-groupview-header-bottom", "dv-groupview-header-left", "dv-groupview-header-right");
|
|
@@ -10536,10 +10595,7 @@ react_dom = __toESM(react_dom);
|
|
|
10536
10595
|
this._headerDirection = direction;
|
|
10537
10596
|
this.tabsContainer.direction = direction;
|
|
10538
10597
|
this.header.direction = direction;
|
|
10539
|
-
if (
|
|
10540
|
-
const { width, height } = this.contentDimensions();
|
|
10541
|
-
this._activePanel.layout(width, height);
|
|
10542
|
-
}
|
|
10598
|
+
if (this.panels.length > 0) this.layoutContent();
|
|
10543
10599
|
this.updateHeaderActions();
|
|
10544
10600
|
if (previousDirection !== void 0 && previousDirection !== direction) {
|
|
10545
10601
|
var _this$groupPanel;
|
|
@@ -11042,10 +11098,7 @@ react_dom = __toESM(react_dom);
|
|
|
11042
11098
|
this.panels.forEach((panel) => {
|
|
11043
11099
|
this.rerender(panel);
|
|
11044
11100
|
});
|
|
11045
|
-
if (this.
|
|
11046
|
-
const { width, height } = this.contentDimensions();
|
|
11047
|
-
this._activePanel.layout(width, height);
|
|
11048
|
-
}
|
|
11101
|
+
if (this.panels.length > 0) this.layoutContent();
|
|
11049
11102
|
}
|
|
11050
11103
|
get renderContainer() {
|
|
11051
11104
|
var _this$_overwriteRende;
|
|
@@ -11092,10 +11145,10 @@ react_dom = __toESM(react_dom);
|
|
|
11092
11145
|
return this.tabsContainer.indexOf(panel.id);
|
|
11093
11146
|
}
|
|
11094
11147
|
toJSON() {
|
|
11095
|
-
var _this$
|
|
11148
|
+
var _this$_activePanel;
|
|
11096
11149
|
const result = {
|
|
11097
11150
|
views: this.tabsContainer.panels,
|
|
11098
|
-
activeView: (_this$
|
|
11151
|
+
activeView: (_this$_activePanel = this._activePanel) === null || _this$_activePanel === void 0 ? void 0 : _this$_activePanel.id,
|
|
11099
11152
|
id: this.id
|
|
11100
11153
|
};
|
|
11101
11154
|
if (this.locked !== false) result.locked = this.locked;
|
|
@@ -11133,8 +11186,8 @@ react_dom = __toESM(react_dom);
|
|
|
11133
11186
|
init(_params) {}
|
|
11134
11187
|
update(_params) {}
|
|
11135
11188
|
focus() {
|
|
11136
|
-
var _this$
|
|
11137
|
-
(_this$
|
|
11189
|
+
var _this$_activePanel2;
|
|
11190
|
+
(_this$_activePanel2 = this._activePanel) === null || _this$_activePanel2 === void 0 || _this$_activePanel2.focus();
|
|
11138
11191
|
}
|
|
11139
11192
|
openPanel(panel, options = {}) {
|
|
11140
11193
|
if (typeof options.index !== "number" || options.index > this.panels.length) options.index = this.panels.length;
|
|
@@ -11192,12 +11245,24 @@ react_dom = __toESM(react_dom);
|
|
|
11192
11245
|
this.updateContainer();
|
|
11193
11246
|
}
|
|
11194
11247
|
layout(width, height) {
|
|
11195
|
-
var _this$_activePanel4;
|
|
11196
11248
|
this._width = width;
|
|
11197
11249
|
this._height = height;
|
|
11198
|
-
|
|
11199
|
-
|
|
11200
|
-
|
|
11250
|
+
this.layoutContent();
|
|
11251
|
+
}
|
|
11252
|
+
/**
|
|
11253
|
+
* Apply the current content box (group box minus header extent) to the
|
|
11254
|
+
* content container and the active panel. Every path that can change that
|
|
11255
|
+
* box goes through here so the container's recorded dimensions, which size
|
|
11256
|
+
* overlay-rendered panels, never lag the active panel's. Callers other
|
|
11257
|
+
* than `layout()` skip it for a group with no panels: there is nothing to
|
|
11258
|
+
* size, and measuring the header of a group that is not in the document
|
|
11259
|
+
* yet (the constructor sets `headerPosition`) would cache a zero extent.
|
|
11260
|
+
*/
|
|
11261
|
+
layoutContent() {
|
|
11262
|
+
var _this$_activePanel3;
|
|
11263
|
+
const { width, height } = this.contentDimensions();
|
|
11264
|
+
this.contentContainer.layout(width, height);
|
|
11265
|
+
if ((_this$_activePanel3 = this._activePanel) === null || _this$_activePanel3 === void 0 ? void 0 : _this$_activePanel3.layout) this._activePanel.layout(width, height);
|
|
11201
11266
|
}
|
|
11202
11267
|
/**
|
|
11203
11268
|
* Re-run the group's layout with its current dimensions. Used to propagate a
|
|
@@ -11290,8 +11355,7 @@ react_dom = __toESM(react_dom);
|
|
|
11290
11355
|
this.tabsContainer.setActivePanel(panel);
|
|
11291
11356
|
this.contentContainer.setLabelledBy(this.tabsContainer.getTabId(panel.id));
|
|
11292
11357
|
this.contentContainer.openPanel(panel);
|
|
11293
|
-
|
|
11294
|
-
panel.layout(width, height);
|
|
11358
|
+
this.layoutContent();
|
|
11295
11359
|
this.updateMru(panel);
|
|
11296
11360
|
this.contentContainer.refreshFocusState();
|
|
11297
11361
|
this._onDidActivePanelChange.fire({
|
|
@@ -11303,8 +11367,8 @@ react_dom = __toESM(react_dom);
|
|
|
11303
11367
|
}
|
|
11304
11368
|
/** Label the group region with its active panel's title (the WAI-ARIA region name). */
|
|
11305
11369
|
updateAccessibleLabel() {
|
|
11306
|
-
var _this$
|
|
11307
|
-
const title = (_this$
|
|
11370
|
+
var _this$_activePanel4;
|
|
11371
|
+
const title = (_this$_activePanel4 = this._activePanel) === null || _this$_activePanel4 === void 0 ? void 0 : _this$_activePanel4.title;
|
|
11308
11372
|
if (title) this.container.setAttribute("aria-label", title);
|
|
11309
11373
|
else this.container.removeAttribute("aria-label");
|
|
11310
11374
|
}
|
|
@@ -11369,6 +11433,7 @@ react_dom = __toESM(react_dom);
|
|
|
11369
11433
|
nativeEvent: event,
|
|
11370
11434
|
position,
|
|
11371
11435
|
panel,
|
|
11436
|
+
index,
|
|
11372
11437
|
getData: () => getPanelData(),
|
|
11373
11438
|
kind: getKind(),
|
|
11374
11439
|
group: this.groupPanel,
|
|
@@ -11414,6 +11479,7 @@ react_dom = __toESM(react_dom);
|
|
|
11414
11479
|
nativeEvent: event,
|
|
11415
11480
|
position,
|
|
11416
11481
|
panel,
|
|
11482
|
+
index,
|
|
11417
11483
|
getData: () => getPanelData(),
|
|
11418
11484
|
group: this.groupPanel,
|
|
11419
11485
|
api: this._api
|
|
@@ -14350,6 +14416,15 @@ react_dom = __toESM(react_dom);
|
|
|
14350
14416
|
element.tabIndex = -1;
|
|
14351
14417
|
return element;
|
|
14352
14418
|
}
|
|
14419
|
+
/**
|
|
14420
|
+
* Write an inline pixel length only when it differs from what is already set,
|
|
14421
|
+
* so a pass that re-derives geometry already in place leaves the element's
|
|
14422
|
+
* style clean and the next measurement does not relayout the overlay subtree.
|
|
14423
|
+
*/
|
|
14424
|
+
function setPixels(style, property, value) {
|
|
14425
|
+
const next = `${value}px`;
|
|
14426
|
+
if (style[property] !== next) style[property] = next;
|
|
14427
|
+
}
|
|
14353
14428
|
var OverlayRenderContainer = class extends CompositeDisposable {
|
|
14354
14429
|
constructor(element, accessor) {
|
|
14355
14430
|
super();
|
|
@@ -14468,6 +14543,32 @@ react_dom = __toESM(react_dom);
|
|
|
14468
14543
|
const generation = mapEntry.generation;
|
|
14469
14544
|
const focusContainer = mapEntry.element;
|
|
14470
14545
|
const contentElement = panel.view.content.element;
|
|
14546
|
+
/**
|
|
14547
|
+
* Size the overlay from the layout engine's numbers (the content box
|
|
14548
|
+
* the group model also hands to `panel.layout()`): a style write with
|
|
14549
|
+
* no forced layout, so the content has its real box before anything
|
|
14550
|
+
* can measure it, and `.dv-render-overlay`'s 100%/100% default is never
|
|
14551
|
+
* observed. Hidden panels are sized too: their content is laid out
|
|
14552
|
+
* (hidden by `visibility`) and must not keep the root's box.
|
|
14553
|
+
*
|
|
14554
|
+
* Only while the overlay is not on screen at a measured position,
|
|
14555
|
+
* i.e. hidden or not yet positioned. Once it is, the frame pass owns
|
|
14556
|
+
* the whole box: size and position must change together, and group
|
|
14557
|
+
* layouts driven from an animation frame would otherwise paint one
|
|
14558
|
+
* frame at the new size and the old position. Likewise not while the
|
|
14559
|
+
* peek force-shows the overlay, whose geometry belongs to
|
|
14560
|
+
* `repositionPanelOverlay`: the collapsed group's own layouts describe
|
|
14561
|
+
* the strip, not the peek. A zero box (a container awaiting layout) is
|
|
14562
|
+
* skipped too: whether 0x0 is a real collapse is the frame pass's call.
|
|
14563
|
+
*/
|
|
14564
|
+
const applySize = (size) => {
|
|
14565
|
+
if (!size || size.width <= 0 || size.height <= 0) return;
|
|
14566
|
+
const entry = this.map[panel.api.id];
|
|
14567
|
+
if (!entry || entry.forceVisible || entry.positioned && panel.api.isVisible) return;
|
|
14568
|
+
setPixels(focusContainer.style, "width", size.width);
|
|
14569
|
+
setPixels(focusContainer.style, "height", size.height);
|
|
14570
|
+
};
|
|
14571
|
+
applySize(referenceContainer.dimensions);
|
|
14471
14572
|
if (contentElement.parentElement !== focusContainer) focusContainer.appendChild(contentElement);
|
|
14472
14573
|
if (focusContainer.parentElement !== this.element) this.element.appendChild(focusContainer);
|
|
14473
14574
|
const resize = () => {
|
|
@@ -14507,10 +14608,10 @@ react_dom = __toESM(react_dom);
|
|
|
14507
14608
|
}
|
|
14508
14609
|
entry.retainPreviousGeometry = false;
|
|
14509
14610
|
entry.positioned = true;
|
|
14510
|
-
focusContainer.style
|
|
14511
|
-
focusContainer.style
|
|
14512
|
-
focusContainer.style
|
|
14513
|
-
focusContainer.style
|
|
14611
|
+
setPixels(focusContainer.style, "left", left);
|
|
14612
|
+
setPixels(focusContainer.style, "top", top);
|
|
14613
|
+
setPixels(focusContainer.style, "width", width);
|
|
14614
|
+
setPixels(focusContainer.style, "height", height);
|
|
14514
14615
|
if (panel.api.isVisible || forceVisible) {
|
|
14515
14616
|
focusContainer.style.visibility = "";
|
|
14516
14617
|
focusContainer.style.pointerEvents = "";
|
|
@@ -14626,6 +14727,9 @@ react_dom = __toESM(react_dom);
|
|
|
14626
14727
|
if (!panel.api.isVisible) return;
|
|
14627
14728
|
resize();
|
|
14628
14729
|
}),
|
|
14730
|
+
referenceContainer.onDidDimensionsChange((size) => {
|
|
14731
|
+
applySize(size);
|
|
14732
|
+
}),
|
|
14629
14733
|
panel.api.onDidLocationChange(() => {
|
|
14630
14734
|
correctLayerPosition();
|
|
14631
14735
|
})
|
|
@@ -15591,6 +15695,8 @@ react_dom = __toESM(react_dom);
|
|
|
15591
15695
|
/** A never-firing history-change event, the fallback `onDidChangeHistory`
|
|
15592
15696
|
* returns when the LayoutHistory module is absent. */
|
|
15593
15697
|
const NO_LAYOUT_HISTORY_CHANGES = NO_EVENT;
|
|
15698
|
+
/** How many live ids a custom `groupIdGenerator` may return before giving up. */
|
|
15699
|
+
const MAX_GROUP_ID_ATTEMPTS = 100;
|
|
15594
15700
|
var DockviewComponent = class extends BaseGrid {
|
|
15595
15701
|
fireDidCreateTabGroup(event) {
|
|
15596
15702
|
this._onDidCreateTabGroup.fire(event);
|
|
@@ -17440,7 +17546,7 @@ react_dom = __toESM(react_dom);
|
|
|
17440
17546
|
if (typeof id !== "string") throw new TypeError("dockview: group id must be of type string");
|
|
17441
17547
|
const group = this.createGroup({
|
|
17442
17548
|
id,
|
|
17443
|
-
locked:
|
|
17549
|
+
locked: locked !== null && locked !== void 0 ? locked : false,
|
|
17444
17550
|
hideHeader: !!hideHeader,
|
|
17445
17551
|
headerPosition
|
|
17446
17552
|
});
|
|
@@ -17713,6 +17819,32 @@ react_dom = __toESM(react_dom);
|
|
|
17713
17819
|
addPanel(options) {
|
|
17714
17820
|
return this.mutation("add", () => this._doAddPanel(options));
|
|
17715
17821
|
}
|
|
17822
|
+
/**
|
|
17823
|
+
* Add a panel from its `toJSON()` state, placed as `addPanel` places
|
|
17824
|
+
* one: the counterpart to `panel.toJSON()` for a single tab moving
|
|
17825
|
+
* between layouts or instances, as `addGroupFromJSON` is to
|
|
17826
|
+
* `serializeGroup`. Throws before changing anything if the panel id is
|
|
17827
|
+
* already in use.
|
|
17828
|
+
*/
|
|
17829
|
+
addPanelFromJSON(state, options) {
|
|
17830
|
+
if (!state.contentComponent) throw new Error(`dockview: serialized panel ${state.id} has no contentComponent`);
|
|
17831
|
+
return this.mutation("add", () => {
|
|
17832
|
+
const panel = this._doAddPanel(_objectSpread2$1(_objectSpread2$1({}, options), {}, {
|
|
17833
|
+
id: state.id,
|
|
17834
|
+
component: state.contentComponent,
|
|
17835
|
+
tabComponent: state.tabComponent,
|
|
17836
|
+
title: state.title,
|
|
17837
|
+
renderer: state.renderer,
|
|
17838
|
+
params: state.params,
|
|
17839
|
+
minimumWidth: state.minimumWidth,
|
|
17840
|
+
minimumHeight: state.minimumHeight,
|
|
17841
|
+
maximumWidth: state.maximumWidth,
|
|
17842
|
+
maximumHeight: state.maximumHeight
|
|
17843
|
+
}));
|
|
17844
|
+
if (state.pinned) this.setPanelPinned(panel, true);
|
|
17845
|
+
return panel;
|
|
17846
|
+
});
|
|
17847
|
+
}
|
|
17716
17848
|
_doAddPanel(options) {
|
|
17717
17849
|
if (this.panels.some((_) => _.id === options.id)) throw new Error(`dockview: panel with id ${options.id} already exists`);
|
|
17718
17850
|
let referenceGroup;
|
|
@@ -17854,6 +17986,152 @@ react_dom = __toESM(react_dom);
|
|
|
17854
17986
|
addGroup(options) {
|
|
17855
17987
|
return this.mutation("add", () => this._doAddGroup(options));
|
|
17856
17988
|
}
|
|
17989
|
+
/**
|
|
17990
|
+
* Serialize one group and the state of every panel it holds. The result
|
|
17991
|
+
* is self-contained: `addGroupFromJSON` on any dockview instance rebuilds
|
|
17992
|
+
* the group from it, with the same tab order, active tab, panel titles,
|
|
17993
|
+
* parameters and renderers.
|
|
17994
|
+
*/
|
|
17995
|
+
serializeGroup(group) {
|
|
17996
|
+
const panels = {};
|
|
17997
|
+
for (const panel of group.panels) panels[panel.id] = panel.toJSON();
|
|
17998
|
+
return {
|
|
17999
|
+
group: group.model.toJSON(),
|
|
18000
|
+
panels
|
|
18001
|
+
};
|
|
18002
|
+
}
|
|
18003
|
+
/**
|
|
18004
|
+
* Rebuild a group from `serializeGroup` output and add it to the live
|
|
18005
|
+
* layout at `options` (as for `addGroup`), without touching the rest of
|
|
18006
|
+
* the layout. This is the counterpart to `fromJSON`, which replaces the
|
|
18007
|
+
* whole layout, for moving one group between layouts or instances.
|
|
18008
|
+
*
|
|
18009
|
+
* With `direction: 'within'` and a reference group or panel, no group is
|
|
18010
|
+
* created: the serialized panels are merged into that group, in their
|
|
18011
|
+
* order, at `index` if given, and the serialized active panel becomes
|
|
18012
|
+
* the group's. The serialized group's own shape (id, locked, header,
|
|
18013
|
+
* tab groups) does not apply then. This is what a drop on a group's
|
|
18014
|
+
* centre or tab bar calls for, and the only form that works against a
|
|
18015
|
+
* floating or edge group, which has no grid neighbours.
|
|
18016
|
+
*
|
|
18017
|
+
* A panel id that is already live throws, as `addPanel` does, before
|
|
18018
|
+
* anything is changed. A group id that is already live is reassigned with
|
|
18019
|
+
* a warning, as `addGroup` does.
|
|
18020
|
+
*/
|
|
18021
|
+
addGroupFromJSON(data, options) {
|
|
18022
|
+
this.validateSerializedGroup(data);
|
|
18023
|
+
return this.mutation("add", () => this._doAddGroupFromJSON(data, options));
|
|
18024
|
+
}
|
|
18025
|
+
/**
|
|
18026
|
+
* Refuse an envelope that cannot be applied cleanly, before any mutation
|
|
18027
|
+
* is opened, so a refused call leaves no trace in the layout or its
|
|
18028
|
+
* events.
|
|
18029
|
+
*/
|
|
18030
|
+
validateSerializedGroup(data) {
|
|
18031
|
+
const state = data === null || data === void 0 ? void 0 : data.group;
|
|
18032
|
+
if (typeof (state === null || state === void 0 ? void 0 : state.id) !== "string") throw new TypeError("dockview: group id must be of type string");
|
|
18033
|
+
if (!Array.isArray(state.views)) throw new TypeError(`dockview: serialized group ${state.id} has no views`);
|
|
18034
|
+
for (const id of state.views) {
|
|
18035
|
+
var _data$panels;
|
|
18036
|
+
if (!((_data$panels = data.panels) === null || _data$panels === void 0 ? void 0 : _data$panels[id])) throw new Error(`dockview: serialized group ${state.id} is missing panel state for ${id}`);
|
|
18037
|
+
if (this.panels.some((panel) => panel.id === id)) throw new Error(`dockview: panel with id ${id} already exists`);
|
|
18038
|
+
}
|
|
18039
|
+
}
|
|
18040
|
+
_doAddGroupFromJSON(data, options) {
|
|
18041
|
+
var _options$direction;
|
|
18042
|
+
const { id, locked, hideHeader, headerPosition, constraints, activeView, tabGroups } = data.group;
|
|
18043
|
+
if (options && ((_options$direction = options.direction) !== null && _options$direction !== void 0 ? _options$direction : "within") === "within") {
|
|
18044
|
+
const target = this.resolveReferenceGroup(options);
|
|
18045
|
+
if (target) return this.mergeGroupFromJSON(data, target, options);
|
|
18046
|
+
}
|
|
18047
|
+
const groupOptions = {
|
|
18048
|
+
id,
|
|
18049
|
+
locked: locked !== null && locked !== void 0 ? locked : false,
|
|
18050
|
+
hideHeader: !!hideHeader,
|
|
18051
|
+
headerPosition,
|
|
18052
|
+
constraints,
|
|
18053
|
+
initialWidth: options === null || options === void 0 ? void 0 : options.initialWidth,
|
|
18054
|
+
initialHeight: options === null || options === void 0 ? void 0 : options.initialHeight,
|
|
18055
|
+
skipSetActive: true
|
|
18056
|
+
};
|
|
18057
|
+
const group = this.addEmptyGroupAt(groupOptions, options);
|
|
18058
|
+
let panels;
|
|
18059
|
+
try {
|
|
18060
|
+
panels = this.deserializePanels(data, group);
|
|
18061
|
+
} catch (err) {
|
|
18062
|
+
this.doRemoveGroup(group, { skipActive: true });
|
|
18063
|
+
throw err;
|
|
18064
|
+
}
|
|
18065
|
+
for (const panel of panels) group.model.openPanel(panel, {
|
|
18066
|
+
skipSetActive: panel.id !== activeView,
|
|
18067
|
+
skipSetGroupActive: true
|
|
18068
|
+
});
|
|
18069
|
+
if (tabGroups && tabGroups.length > 0) group.model.restoreTabGroups(tabGroups);
|
|
18070
|
+
if (!group.activePanel && group.panels.length > 0) group.model.openPanel(group.panels[group.panels.length - 1], { skipSetGroupActive: true });
|
|
18071
|
+
if (!(options === null || options === void 0 ? void 0 : options.skipSetActive)) this.doSetGroupAndPanelActive(group);
|
|
18072
|
+
return group;
|
|
18073
|
+
}
|
|
18074
|
+
/**
|
|
18075
|
+
* Add an empty group at the placement `options` names, or append it
|
|
18076
|
+
* when they name none.
|
|
18077
|
+
*/
|
|
18078
|
+
addEmptyGroupAt(groupOptions, options) {
|
|
18079
|
+
if (options !== void 0 && (isGroupOptionsWithPanel(options) || isGroupOptionsWithGroup(options) || typeof options.direction === "string")) return this._doAddGroup(_objectSpread2$1(_objectSpread2$1({}, options), groupOptions));
|
|
18080
|
+
const group = this.createGroup(groupOptions);
|
|
18081
|
+
this.doAddGroup(group);
|
|
18082
|
+
return group;
|
|
18083
|
+
}
|
|
18084
|
+
/**
|
|
18085
|
+
* Create every panel of a serialized group in `group`, in tab order,
|
|
18086
|
+
* before any is opened, so a corrupt panel state fails before a single
|
|
18087
|
+
* add event has fired (the ordering `fromJSON` uses). On failure the
|
|
18088
|
+
* panels made so far are disposed and the error rethrown.
|
|
18089
|
+
*/
|
|
18090
|
+
deserializePanels(data, group) {
|
|
18091
|
+
const panels = [];
|
|
18092
|
+
try {
|
|
18093
|
+
for (const child of data.group.views) panels.push(this._deserializer.fromJSON(data.panels[child], group));
|
|
18094
|
+
} catch (err) {
|
|
18095
|
+
for (const panel of panels) panel.dispose();
|
|
18096
|
+
throw err;
|
|
18097
|
+
}
|
|
18098
|
+
return panels;
|
|
18099
|
+
}
|
|
18100
|
+
/**
|
|
18101
|
+
* The group an `AddGroupOptions` placement names, or `undefined` for an
|
|
18102
|
+
* absolute placement. Throws for a reference that names nothing.
|
|
18103
|
+
*/
|
|
18104
|
+
resolveReferenceGroup(options) {
|
|
18105
|
+
if (isGroupOptionsWithPanel(options)) {
|
|
18106
|
+
const referencePanelId = typeof options.referencePanel === "string" ? options.referencePanel : options.referencePanel.id;
|
|
18107
|
+
const referencePanel = this.getGroupPanel(referencePanelId);
|
|
18108
|
+
if (!referencePanel) throw new Error(`dockview: reference panel ${referencePanelId} does not exist`);
|
|
18109
|
+
return referencePanel.group;
|
|
18110
|
+
}
|
|
18111
|
+
if (isGroupOptionsWithGroup(options)) {
|
|
18112
|
+
const referenceId = typeof options.referenceGroup === "string" ? options.referenceGroup : options.referenceGroup.id;
|
|
18113
|
+
const referenceGroup = this.getPanel(referenceId);
|
|
18114
|
+
if (!referenceGroup) throw new Error(`dockview: reference group ${referenceId} does not exist`);
|
|
18115
|
+
return referenceGroup;
|
|
18116
|
+
}
|
|
18117
|
+
}
|
|
18118
|
+
/**
|
|
18119
|
+
* The `direction: 'within'` form of `addGroupFromJSON`: the serialized
|
|
18120
|
+
* panels join `target` rather than a group of their own.
|
|
18121
|
+
*/
|
|
18122
|
+
mergeGroupFromJSON(data, target, options) {
|
|
18123
|
+
const { activeView } = data.group;
|
|
18124
|
+
const index = options.index;
|
|
18125
|
+
this.deserializePanels(data, target).forEach((panel, offset) => {
|
|
18126
|
+
target.model.openPanel(panel, {
|
|
18127
|
+
index: index === void 0 ? void 0 : index + offset,
|
|
18128
|
+
skipSetActive: panel.id !== activeView,
|
|
18129
|
+
skipSetGroupActive: true
|
|
18130
|
+
});
|
|
18131
|
+
});
|
|
18132
|
+
if (!options.skipSetActive) this.doSetGroupAndPanelActive(target);
|
|
18133
|
+
return target;
|
|
18134
|
+
}
|
|
17857
18135
|
_doAddGroup(options) {
|
|
17858
18136
|
if (options) {
|
|
17859
18137
|
let referenceGroup;
|
|
@@ -18558,10 +18836,26 @@ react_dom = __toESM(react_dom);
|
|
|
18558
18836
|
if (group && this.hasMaximizedGroup() && !this.isMaximizedGroup(group)) this.exitMaximizedGroup();
|
|
18559
18837
|
if (!this._moving && activePanel !== ((_this$_onDidActivePan2 = this._onDidActivePanelChange.value) === null || _this$_onDidActivePan2 === void 0 ? void 0 : _this$_onDidActivePan2.panel)) this.fireActivePanelChange(activePanel);
|
|
18560
18838
|
}
|
|
18839
|
+
/**
|
|
18840
|
+
* The id for a group created without one: from `groupIdGenerator` when
|
|
18841
|
+
* the option is set, else the sequential counter. An id already in use is
|
|
18842
|
+
* skipped. The counter never repeats, so it can skip any number of live
|
|
18843
|
+
* ids (a restored layout may hold many); a custom generator is given a
|
|
18844
|
+
* bounded number of tries so a broken one cannot hang the call.
|
|
18845
|
+
*/
|
|
18561
18846
|
getNextGroupId() {
|
|
18562
|
-
|
|
18563
|
-
|
|
18564
|
-
|
|
18847
|
+
const generate = this.options.groupIdGenerator;
|
|
18848
|
+
if (!generate) {
|
|
18849
|
+
let id = this.nextGroupId.next();
|
|
18850
|
+
while (this._groups.has(id)) id = this.nextGroupId.next();
|
|
18851
|
+
return id;
|
|
18852
|
+
}
|
|
18853
|
+
for (let attempt = 0; attempt < MAX_GROUP_ID_ATTEMPTS; attempt++) {
|
|
18854
|
+
const id = generate();
|
|
18855
|
+
if (typeof id !== "string" || id.length === 0) throw new TypeError("dockview: groupIdGenerator must return a non-empty string");
|
|
18856
|
+
if (!this._groups.has(id)) return id;
|
|
18857
|
+
}
|
|
18858
|
+
throw new Error(`dockview: groupIdGenerator returned an id already in use ${MAX_GROUP_ID_ATTEMPTS} times in a row`);
|
|
18565
18859
|
}
|
|
18566
18860
|
createGroup(options) {
|
|
18567
18861
|
var _options;
|
|
@@ -18571,10 +18865,7 @@ react_dom = __toESM(react_dom);
|
|
|
18571
18865
|
console.warn(`dockview: Duplicate group id ${options === null || options === void 0 ? void 0 : options.id}. reassigning group id to avoid errors`);
|
|
18572
18866
|
id = void 0;
|
|
18573
18867
|
}
|
|
18574
|
-
if (!id)
|
|
18575
|
-
id = this.nextGroupId.next();
|
|
18576
|
-
while (this._groups.has(id)) id = this.nextGroupId.next();
|
|
18577
|
-
}
|
|
18868
|
+
if (!id) id = this.getNextGroupId();
|
|
18578
18869
|
const view = new DockviewGroupPanel(this, id, options);
|
|
18579
18870
|
view.init({
|
|
18580
18871
|
params: {},
|