@dimina-kit/electron-deck 0.1.0-dev.20260616102751 → 0.1.0-dev.20260618090552
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/README.md +26 -24
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/layout-client.d.ts +1 -1
- package/dist/dock-react/dock-view.d.ts +14 -9
- package/dist/dock-react/dock-view.d.ts.map +1 -1
- package/dist/dock-react/drag-redock.d.ts +15 -0
- package/dist/dock-react/drag-redock.d.ts.map +1 -1
- package/dist/dock-react/index.d.ts +2 -2
- package/dist/dock-react/index.d.ts.map +1 -1
- package/dist/dock-react/index.js +197 -39
- package/dist/dock-react/index.js.map +1 -1
- package/dist/{electron-deck-DfFKeFEC.js → electron-deck-CW6gkGS-.js} +4 -4
- package/dist/electron-deck-CW6gkGS-.js.map +1 -0
- package/dist/host/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/deck-app.d.ts +3 -3
- package/dist/layout/index.d.ts +2 -1
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +2 -2
- package/dist/layout/mutations.d.ts.map +1 -1
- package/dist/layout/sanitize.d.ts +27 -0
- package/dist/layout/sanitize.d.ts.map +1 -0
- package/dist/layout/serialize.d.ts.map +1 -1
- package/dist/layout/types.d.ts +49 -7
- package/dist/layout/types.d.ts.map +1 -1
- package/dist/{layout-CZtF0auJ.js → layout-WI8y1hxP.js} +55 -6
- package/dist/layout-WI8y1hxP.js.map +1 -0
- package/dist/main/compositor.d.ts +1 -1
- package/dist/main/index.d.ts +2 -2
- package/dist/main/view-handle.d.ts +8 -8
- package/dist/types.d.ts +2 -2
- package/dist/view-handle-CR-yWNfr.js.map +1 -1
- package/package.json +5 -5
- package/dist/electron-deck-DfFKeFEC.js.map +0 -1
- package/dist/layout-CZtF0auJ.js.map +0 -1
package/dist/dock-react/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as movePanel, c as setSizes, l as splitPanel, n as closePanel, o as setActive, r as extractPanel } from "../layout-
|
|
2
|
-
import { Fragment, useCallback, useEffect, useRef, useState } from "react";
|
|
1
|
+
import { a as movePanel, c as setSizes, l as splitPanel, n as closePanel, o as setActive, r as extractPanel } from "../layout-WI8y1hxP.js";
|
|
2
|
+
import { Fragment, createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
3
3
|
import { Group, Panel, Separator } from "react-resizable-panels";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
//#region src/dock-react/drag-redock.ts
|
|
@@ -89,6 +89,24 @@ function isNoopRedock(dragged, draggedGroupId, target, zone) {
|
|
|
89
89
|
if (zone === "center" && draggedGroupId !== void 0 && draggedGroupId === target.groupId) return true;
|
|
90
90
|
return false;
|
|
91
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Map a pointer x-position over a horizontal tab strip to an insertion index for
|
|
94
|
+
* a within-strip REORDER (the `dropPolicy:'reorder-only'` gesture). The strip is
|
|
95
|
+
* the dragged tab's own group; `tabRects` are the tab buttons' rects in visual
|
|
96
|
+
* order (each `left` is the rect's left edge, `width` its width). The index is
|
|
97
|
+
* the count of tabs whose MIDPOINT the pointer has passed: the LEFT half of a tab
|
|
98
|
+
* inserts BEFORE it, the RIGHT half (and the exact midpoint) inserts AFTER it. A
|
|
99
|
+
* pointer left of the first tab → 0; past the last tab → `tabRects.length`. Pure
|
|
100
|
+
* (no DOM): the caller measures the rects and passes the pointer x. An empty
|
|
101
|
+
* strip or a non-finite pointer → 0.
|
|
102
|
+
*/
|
|
103
|
+
function computeReorderIndex(tabRects, pointerX) {
|
|
104
|
+
if (!Number.isFinite(pointerX)) return 0;
|
|
105
|
+
let index = 0;
|
|
106
|
+
for (const rect of tabRects) if (pointerX >= rect.left + rect.width / 2) index += 1;
|
|
107
|
+
else break;
|
|
108
|
+
return index;
|
|
109
|
+
}
|
|
92
110
|
//#endregion
|
|
93
111
|
//#region src/dock-react/dock-view.tsx
|
|
94
112
|
/**
|
|
@@ -110,6 +128,33 @@ function isNoopRedock(dragged, draggedGroupId, target, zone) {
|
|
|
110
128
|
* tab's `data-deck-tab` attribute (the jsdom seam relies on the latter).
|
|
111
129
|
*/
|
|
112
130
|
var DRAG_PANEL_MIME = "application/x-deck-panel";
|
|
131
|
+
/**
|
|
132
|
+
* The current layout EPOCH — the model's revision, bumped once per committed
|
|
133
|
+
* mutation. `DockView` provides it; descendant panels read it via
|
|
134
|
+
* `useDockLayoutEpoch`.
|
|
135
|
+
*
|
|
136
|
+
* Its reason to exist: a native-view overlay anchored inside a dock panel
|
|
137
|
+
* (a `WebContentsView` tracking its slot's geometry) re-publishes its bounds
|
|
138
|
+
* only on GEOMETRY events (ResizeObserver / window-resize / splitter-drag). A
|
|
139
|
+
* layout mutation that REORDERS a slot without resizing it — flipping a
|
|
140
|
+
* fixed-width simulator column left↔right, moving a region — produces NO such
|
|
141
|
+
* event (a same-size flex reorder fires nothing), so the overlay would freeze
|
|
142
|
+
* at its old position. The epoch is the layout layer's explicit "something
|
|
143
|
+
* moved" signal: a panel hosting a native overlay re-measures (e.g. pulses its
|
|
144
|
+
* view-anchor) when the epoch changes, catching the translate the browser never
|
|
145
|
+
* reports. Default 0 (outside a provider): the consuming effect runs once on
|
|
146
|
+
* mount, which is harmless.
|
|
147
|
+
*/
|
|
148
|
+
var LayoutEpochContext = createContext(0);
|
|
149
|
+
/**
|
|
150
|
+
* Read the current dock layout epoch (the model revision). Re-renders the caller
|
|
151
|
+
* whenever a layout mutation commits. Keyed into a panel's effect deps, it lets
|
|
152
|
+
* a native-overlay host re-measure on a reorder that fires no geometry event.
|
|
153
|
+
* Returns 0 when used outside a `<DockView>`.
|
|
154
|
+
*/
|
|
155
|
+
function useDockLayoutEpoch() {
|
|
156
|
+
return useContext(LayoutEpochContext);
|
|
157
|
+
}
|
|
113
158
|
/** Normalize raw split weights to percentages summing ~100 for `defaultSize`. */
|
|
114
159
|
function toPercentages(sizes) {
|
|
115
160
|
const total = sizes.reduce((a, b) => a + (b > 0 ? b : 0), 0);
|
|
@@ -120,11 +165,11 @@ function toPercentages(sizes) {
|
|
|
120
165
|
return sizes.map((s) => (s > 0 ? s : 0) / total * 100);
|
|
121
166
|
}
|
|
122
167
|
/**
|
|
123
|
-
* Compute the `defaultSize` percentage for each FLEXIBLE
|
|
124
|
-
*
|
|
125
|
-
* from the pool
|
|
126
|
-
*
|
|
127
|
-
* absent from the returned map.
|
|
168
|
+
* Compute the `defaultSize` percentage for each FLEXIBLE child, keyed by its
|
|
169
|
+
* ORIGINAL child index. Px-sized children (a non-null `constraint` — `fixedPx`
|
|
170
|
+
* locked OR `minPx` floored) are EXCLUDED from the pool: their size is px, not a
|
|
171
|
+
* weight, so it must never pollute the flexible siblings' normalization (FIX E1).
|
|
172
|
+
* `constraints[i]` non-null ⇒ child i is px-sized and absent from the returned map.
|
|
128
173
|
*/
|
|
129
174
|
function computeFlexiblePercentages(sizes, constraints) {
|
|
130
175
|
const flexibleIndices = sizes.map((_, i) => i).filter((i) => (constraints?.[i] ?? null) === null);
|
|
@@ -138,10 +183,12 @@ function computeFlexiblePercentages(sizes, constraints) {
|
|
|
138
183
|
function DockView(props) {
|
|
139
184
|
const { model, registry, renderDomPanel, bindNativeSlot } = props;
|
|
140
185
|
const [tree, setTree] = useState(() => model.get());
|
|
186
|
+
const [epoch, setEpoch] = useState(0);
|
|
141
187
|
useEffect(() => {
|
|
142
188
|
setTree(model.get());
|
|
143
189
|
return model.subscribe((snap) => {
|
|
144
190
|
setTree(snap.tree);
|
|
191
|
+
setEpoch(snap.revision);
|
|
145
192
|
});
|
|
146
193
|
}, [model]);
|
|
147
194
|
const handleActivate = useCallback((groupId, panelId) => {
|
|
@@ -155,12 +202,25 @@ function DockView(props) {
|
|
|
155
202
|
const handleApplyLayout = useCallback((splitId, weights) => {
|
|
156
203
|
model.apply((t) => setSizes(t, splitId, weights));
|
|
157
204
|
}, [model]);
|
|
158
|
-
const handleRedock = useCallback((groupId, activePanelId, draggedPanelId, zone) => {
|
|
205
|
+
const handleRedock = useCallback((groupId, activePanelId, draggedPanelId, zone, reorderIndex) => {
|
|
159
206
|
const target = {
|
|
160
207
|
groupId,
|
|
161
208
|
panelId: activePanelId
|
|
162
209
|
};
|
|
163
|
-
|
|
210
|
+
const draggedGroupId = findPanelGroupId(model.get().root, draggedPanelId);
|
|
211
|
+
if (registry.get(activePanelId)?.draggable === false) return;
|
|
212
|
+
if (registry.get(draggedPanelId)?.dropPolicy === "reorder-only") {
|
|
213
|
+
if (draggedGroupId === void 0 || draggedGroupId !== groupId) return;
|
|
214
|
+
if (zone !== "center") return;
|
|
215
|
+
const group = findGroupById(model.get().root, groupId);
|
|
216
|
+
const index = reorderIndex ?? (group ? group.panels.indexOf(activePanelId) : void 0);
|
|
217
|
+
model.apply((t) => movePanel(t, draggedPanelId, {
|
|
218
|
+
groupId,
|
|
219
|
+
index
|
|
220
|
+
}));
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (isNoopRedock(draggedPanelId, draggedGroupId, target, zone)) return;
|
|
164
224
|
const mutation = dropZoneToMutation(zone, draggedPanelId, target);
|
|
165
225
|
if (mutation.kind === "move") {
|
|
166
226
|
model.apply((t) => movePanel(t, mutation.panelId, { groupId: mutation.destGroupId }));
|
|
@@ -171,18 +231,21 @@ function DockView(props) {
|
|
|
171
231
|
if (findPanelGroupId(tree.root, mutation.atPanelId) === void 0) return t;
|
|
172
232
|
return splitPanel(tree, mutation.atPanelId, mutation.dir, mutation.newPanelId, mutation.side);
|
|
173
233
|
});
|
|
174
|
-
}, [model]);
|
|
175
|
-
return /* @__PURE__ */ jsx(
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
234
|
+
}, [model, registry]);
|
|
235
|
+
return /* @__PURE__ */ jsx(LayoutEpochContext.Provider, {
|
|
236
|
+
value: epoch,
|
|
237
|
+
children: renderNode(tree.root, {
|
|
238
|
+
registry,
|
|
239
|
+
renderDomPanel,
|
|
240
|
+
bindNativeSlot,
|
|
241
|
+
onActivate: handleActivate,
|
|
242
|
+
onApplyLayout: handleApplyLayout,
|
|
243
|
+
onRedock: handleRedock,
|
|
244
|
+
onClose: handleClose,
|
|
245
|
+
canClose,
|
|
246
|
+
isPanelInTree
|
|
247
|
+
})
|
|
248
|
+
});
|
|
186
249
|
}
|
|
187
250
|
/** The id of the tab group currently holding `panelId`, or `undefined` if the
|
|
188
251
|
* panel is not in the tree. Used by `handleRedock` to detect a drop back into
|
|
@@ -194,6 +257,17 @@ function findPanelGroupId(node, panelId) {
|
|
|
194
257
|
if (found !== void 0) return found;
|
|
195
258
|
}
|
|
196
259
|
}
|
|
260
|
+
/** The tab-group node with `groupId`, or `undefined`. Used by `handleRedock` to
|
|
261
|
+
* read the live `panels` order of a reorder target (to anchor a same-group
|
|
262
|
+
* reorder on the active panel's current index when the gesture carries no
|
|
263
|
+
* pointer-derived index — e.g. the `__deckHandleDrop` test seam). */
|
|
264
|
+
function findGroupById(node, groupId) {
|
|
265
|
+
if (node.kind === "tabs") return node.id === groupId ? node : void 0;
|
|
266
|
+
for (const child of node.children) {
|
|
267
|
+
const found = findGroupById(child, groupId);
|
|
268
|
+
if (found !== void 0) return found;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
197
271
|
/** Total panels anywhere in the tree. Drives the last-panel close suppression:
|
|
198
272
|
* a GroupView only knows its own node, so DockView computes this global count
|
|
199
273
|
* once and threads the resulting `canClose` boolean down. */
|
|
@@ -243,6 +317,36 @@ var LAYOUT_EPSILON = .5;
|
|
|
243
317
|
* self-healing (the next, larger resize writes back). If that ever matters,
|
|
244
318
|
* scale the tolerance down by the flexible child count. */
|
|
245
319
|
var FLEX_RATIO_TOLERANCE = .1;
|
|
320
|
+
/**
|
|
321
|
+
* The minimum weight a FLEXIBLE child may hold, given how many flexible children
|
|
322
|
+
* share the split (Bug #1). A flexible `<Panel>` has no rrp `minSize` by default
|
|
323
|
+
* (rrp floor is 0%), so a user can drag it to ~0 width; the resize write-back
|
|
324
|
+
* would then persist a ~0 weight and the panel comes back invisible/stuck.
|
|
325
|
+
*
|
|
326
|
+
* The floor is `min(1, floor(90 / flexCount))` — i.e. ~1 weight unit (a flexible
|
|
327
|
+
* split's weights are normalized to percentages downstream, so ~1 reads as ~1%
|
|
328
|
+
* of the flexible pool). With any realistic flexible count this is exactly 1; the
|
|
329
|
+
* `min(1, …)` only matters for a hypothetical 90+ flexible-child split. It is the
|
|
330
|
+
* SAME value used for the rrp `minSize` (A) and the write-back clamp (B) so the
|
|
331
|
+
* two defenses never disagree.
|
|
332
|
+
*/
|
|
333
|
+
function flexibleFloor(flexCount) {
|
|
334
|
+
return Math.min(1, Math.max(.5, Math.floor(90 / Math.max(1, flexCount))));
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Clamp the FLEXIBLE entries of a full-length weights array up to `floor` (Bug #1
|
|
338
|
+
* defense B). Px-sized children (a non-null constraint) are left untouched — their
|
|
339
|
+
* `sizes[i]` is a preserved placeholder, not a live weight. Returns a new array;
|
|
340
|
+
* a weight already ≥ floor is kept verbatim so a healthy ratio is undisturbed.
|
|
341
|
+
*/
|
|
342
|
+
function clampFlexibleWeights(weights, constraints) {
|
|
343
|
+
const flexCount = weights.filter((_, i) => (constraints?.[i] ?? null) === null).length;
|
|
344
|
+
const floor = flexibleFloor(flexCount);
|
|
345
|
+
return weights.map((w, i) => {
|
|
346
|
+
if ((constraints?.[i] ?? null) !== null) return w;
|
|
347
|
+
return Number.isFinite(w) && w >= floor ? w : floor;
|
|
348
|
+
});
|
|
349
|
+
}
|
|
246
350
|
/** Are two panelId→percentage maps equivalent within `epsilon` percentage
|
|
247
351
|
* points? Both maps must cover EXACTLY the `ids` key set — a missing key OR an
|
|
248
352
|
* extra key (a key present in `a`/`b` but absent from `ids`) counts as NOT
|
|
@@ -340,6 +444,8 @@ function SplitView(props) {
|
|
|
340
444
|
const { node, ctx } = props;
|
|
341
445
|
const orientation = node.orientation === "row" ? "horizontal" : "vertical";
|
|
342
446
|
const percentageByIndex = computeFlexiblePercentages(node.sizes, node.constraints);
|
|
447
|
+
const flexCount = node.children.filter((_, i) => (node.constraints?.[i] ?? null) === null).length;
|
|
448
|
+
const flexMinSize = String(flexibleFloor(flexCount));
|
|
343
449
|
const groupRef = useRef(null);
|
|
344
450
|
const nodeRef = useRef(node);
|
|
345
451
|
nodeRef.current = node;
|
|
@@ -347,7 +453,7 @@ function SplitView(props) {
|
|
|
347
453
|
node.children.forEach((child, i) => {
|
|
348
454
|
if (i > 0) items.push(/* @__PURE__ */ jsx(Separator, { "data-deck-resize-handle": "" }, `handle-${i}`));
|
|
349
455
|
const constraint = node.constraints?.[i] ?? null;
|
|
350
|
-
if (constraint) {
|
|
456
|
+
if (constraint?.fixedPx != null) {
|
|
351
457
|
const px = `${constraint.fixedPx}px`;
|
|
352
458
|
items.push(/* @__PURE__ */ jsx(Panel, {
|
|
353
459
|
id: child.id,
|
|
@@ -357,11 +463,24 @@ function SplitView(props) {
|
|
|
357
463
|
groupResizeBehavior: "preserve-pixel-size",
|
|
358
464
|
children: renderNode(child, ctx)
|
|
359
465
|
}, panelKey(child)));
|
|
360
|
-
} else
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
466
|
+
} else if (constraint?.minPx != null) {
|
|
467
|
+
const px = `${constraint.minPx}px`;
|
|
468
|
+
items.push(/* @__PURE__ */ jsx(Panel, {
|
|
469
|
+
id: child.id,
|
|
470
|
+
defaultSize: px,
|
|
471
|
+
minSize: px,
|
|
472
|
+
groupResizeBehavior: "preserve-pixel-size",
|
|
473
|
+
children: renderNode(child, ctx)
|
|
474
|
+
}, panelKey(child)));
|
|
475
|
+
} else {
|
|
476
|
+
const pct = percentageByIndex.get(i);
|
|
477
|
+
items.push(/* @__PURE__ */ jsx(Panel, {
|
|
478
|
+
id: child.id,
|
|
479
|
+
defaultSize: pct != null ? String(pct) : void 0,
|
|
480
|
+
minSize: flexMinSize,
|
|
481
|
+
children: renderNode(child, ctx)
|
|
482
|
+
}, panelKey(child)));
|
|
483
|
+
}
|
|
365
484
|
});
|
|
366
485
|
const handleLayoutChanged = (layout) => {
|
|
367
486
|
const cur = nodeRef.current;
|
|
@@ -373,7 +492,7 @@ function SplitView(props) {
|
|
|
373
492
|
const modelNorm = incoming.indices.map((i) => modelPctByIndex.get(i) ?? 0);
|
|
374
493
|
if (!incoming.ratios.some((r, k) => Math.abs(r - modelNorm[k]) > FLEX_RATIO_TOLERANCE)) return;
|
|
375
494
|
const weights = curChildIds.map((id, i) => isFixedAt(i) ? cur.sizes[i] ?? 1 : layout[id]);
|
|
376
|
-
ctx.onApplyLayout(cur.id, weights);
|
|
495
|
+
ctx.onApplyLayout(cur.id, clampFlexibleWeights(weights, cur.constraints));
|
|
377
496
|
};
|
|
378
497
|
const setSplitRef = (el) => {
|
|
379
498
|
if (el) {
|
|
@@ -381,7 +500,7 @@ function SplitView(props) {
|
|
|
381
500
|
const cur = nodeRef.current;
|
|
382
501
|
const isFixedAt = (i) => (cur.constraints?.[i] ?? null) !== null;
|
|
383
502
|
const next = weights.map((w, i) => isFixedAt(i) ? cur.sizes[i] ?? 1 : w);
|
|
384
|
-
ctx.onApplyLayout(cur.id, next);
|
|
503
|
+
ctx.onApplyLayout(cur.id, clampFlexibleWeights(next, cur.constraints));
|
|
385
504
|
};
|
|
386
505
|
Object.defineProperty(el, "__deckGroupApi", {
|
|
387
506
|
configurable: true,
|
|
@@ -401,9 +520,15 @@ function SplitView(props) {
|
|
|
401
520
|
api.setLayout(targetMap);
|
|
402
521
|
return true;
|
|
403
522
|
}, []);
|
|
523
|
+
const sizesKey = node.sizes.join(",");
|
|
524
|
+
const childCountKey = node.children.length;
|
|
404
525
|
useEffect(() => {
|
|
405
526
|
runSync();
|
|
406
|
-
}, [
|
|
527
|
+
}, [
|
|
528
|
+
sizesKey,
|
|
529
|
+
childCountKey,
|
|
530
|
+
runSync
|
|
531
|
+
]);
|
|
407
532
|
return /* @__PURE__ */ jsx("div", {
|
|
408
533
|
ref: setSplitRef,
|
|
409
534
|
"data-deck-split": node.id,
|
|
@@ -422,7 +547,7 @@ function SplitView(props) {
|
|
|
422
547
|
height: "100%"
|
|
423
548
|
},
|
|
424
549
|
children: items
|
|
425
|
-
})
|
|
550
|
+
}, node.children.length)
|
|
426
551
|
});
|
|
427
552
|
}
|
|
428
553
|
/** Stable React key for a child node (split id or group id). */
|
|
@@ -479,8 +604,37 @@ function GroupView(props) {
|
|
|
479
604
|
setDropZone(null);
|
|
480
605
|
const dragged = e.dataTransfer.getData(DRAG_PANEL_MIME) || e.dataTransfer.getData("text/plain");
|
|
481
606
|
if (!dragged || ctx.registry.get(dragged) === void 0 || !ctx.isPanelInTree(dragged)) return;
|
|
482
|
-
|
|
607
|
+
const reorderIndex = computeReorderIndex(Array.from(e.currentTarget.querySelectorAll("[data-deck-tab]")).map((el) => {
|
|
608
|
+
const r = el.getBoundingClientRect();
|
|
609
|
+
return {
|
|
610
|
+
left: r.left,
|
|
611
|
+
width: r.width
|
|
612
|
+
};
|
|
613
|
+
}), e.clientX);
|
|
614
|
+
ctx.onRedock(node.id, node.active, dragged, zone, reorderIndex);
|
|
615
|
+
};
|
|
616
|
+
const handleTabStripDragOver = (e) => {
|
|
617
|
+
if (!e.dataTransfer.types.includes(DRAG_PANEL_MIME)) return;
|
|
618
|
+
e.preventDefault();
|
|
619
|
+
e.stopPropagation();
|
|
620
|
+
setDropZone(null);
|
|
621
|
+
};
|
|
622
|
+
const handleTabStripDrop = (e) => {
|
|
623
|
+
e.preventDefault();
|
|
624
|
+
e.stopPropagation();
|
|
625
|
+
setDropZone(null);
|
|
626
|
+
const dragged = e.dataTransfer.getData(DRAG_PANEL_MIME) || e.dataTransfer.getData("text/plain");
|
|
627
|
+
if (!dragged || ctx.registry.get(dragged) === void 0 || !ctx.isPanelInTree(dragged)) return;
|
|
628
|
+
const reorderIndex = computeReorderIndex(Array.from(e.currentTarget.querySelectorAll("[data-deck-tab]")).map((el) => {
|
|
629
|
+
const r = el.getBoundingClientRect();
|
|
630
|
+
return {
|
|
631
|
+
left: r.left,
|
|
632
|
+
width: r.width
|
|
633
|
+
};
|
|
634
|
+
}), e.clientX);
|
|
635
|
+
ctx.onRedock(node.id, node.active, dragged, "center", reorderIndex);
|
|
483
636
|
};
|
|
637
|
+
const visibleTabs = node.panels.filter((panelId) => !ctx.registry.get(panelId)?.hideTab);
|
|
484
638
|
return /* @__PURE__ */ jsxs("div", {
|
|
485
639
|
ref: setGroupRef,
|
|
486
640
|
"data-deck-group": node.id,
|
|
@@ -497,16 +651,19 @@ function GroupView(props) {
|
|
|
497
651
|
minHeight: 0
|
|
498
652
|
},
|
|
499
653
|
children: [
|
|
500
|
-
/* @__PURE__ */ jsx("div", {
|
|
654
|
+
visibleTabs.length > 0 ? /* @__PURE__ */ jsx("div", {
|
|
501
655
|
role: "tablist",
|
|
502
656
|
style: { flexShrink: 0 },
|
|
503
|
-
|
|
657
|
+
onDragOver: handleTabStripDragOver,
|
|
658
|
+
onDrop: handleTabStripDrop,
|
|
659
|
+
children: visibleTabs.map((panelId) => {
|
|
504
660
|
const active = panelId === node.active;
|
|
505
|
-
const
|
|
661
|
+
const descriptor = ctx.registry.get(panelId);
|
|
662
|
+
const title = descriptor?.title ?? panelId;
|
|
506
663
|
return /* @__PURE__ */ jsxs("button", {
|
|
507
664
|
type: "button",
|
|
508
665
|
role: "tab",
|
|
509
|
-
draggable: "true",
|
|
666
|
+
draggable: descriptor?.draggable !== false ? "true" : void 0,
|
|
510
667
|
"data-deck-tab": panelId,
|
|
511
668
|
"data-active": active ? "true" : "false",
|
|
512
669
|
onDragStart: (e) => {
|
|
@@ -543,7 +700,7 @@ function GroupView(props) {
|
|
|
543
700
|
}) : null]
|
|
544
701
|
}, panelId);
|
|
545
702
|
})
|
|
546
|
-
}),
|
|
703
|
+
}) : null,
|
|
547
704
|
renderActiveBody(node, ctx),
|
|
548
705
|
dropZone ? /* @__PURE__ */ jsx(DropIndicator, { zone: dropZone }) : null
|
|
549
706
|
]
|
|
@@ -633,7 +790,8 @@ function renderActiveBody(node, ctx) {
|
|
|
633
790
|
return /* @__PURE__ */ jsx("div", {
|
|
634
791
|
"data-deck-panel-body": panelId,
|
|
635
792
|
style: {
|
|
636
|
-
display: active ?
|
|
793
|
+
display: active ? "flex" : "none",
|
|
794
|
+
flexDirection: "column",
|
|
637
795
|
flex: 1,
|
|
638
796
|
minWidth: 0,
|
|
639
797
|
minHeight: 0
|
|
@@ -666,6 +824,6 @@ function NativeSlot(props) {
|
|
|
666
824
|
});
|
|
667
825
|
}
|
|
668
826
|
//#endregion
|
|
669
|
-
export { DockView, computeDropZone, computeFlexiblePercentages, dropZoneToMutation, isNoopRedock, layoutsEquivalent };
|
|
827
|
+
export { DockView, computeDropZone, computeFlexiblePercentages, computeReorderIndex, dropZoneToMutation, isNoopRedock, layoutsEquivalent, useDockLayoutEpoch };
|
|
670
828
|
|
|
671
829
|
//# sourceMappingURL=index.js.map
|