@tutti-os/workbench-surface 0.0.1 → 0.0.3
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/index.d.ts +6 -1
- package/dist/index.js +417 -132
- package/dist/index.js.map +1 -1
- package/dist/styles/workbench.css +141 -10
- package/dist/styles/workbenchStyle.test.ts +23 -3
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1712,6 +1712,9 @@ function WorkbenchDockFrame({
|
|
|
1712
1712
|
},
|
|
1713
1713
|
registerDockAnchor: (anchorKey, element) => {
|
|
1714
1714
|
genie.registerDockAnchor(anchorKey, element);
|
|
1715
|
+
},
|
|
1716
|
+
shouldAnimateMinimizedDockEnter: (nodeID) => {
|
|
1717
|
+
return genie.shouldAnimateMinimizedDockEnter(nodeID);
|
|
1715
1718
|
}
|
|
1716
1719
|
},
|
|
1717
1720
|
minimizedNodes,
|
|
@@ -2589,6 +2592,7 @@ import { jsx as jsx7 } from "react/jsx-runtime";
|
|
|
2589
2592
|
var genieDurationMs = 400;
|
|
2590
2593
|
var genieMaxDevicePixelRatio = 2;
|
|
2591
2594
|
var genieSnapshotScale = 1;
|
|
2595
|
+
var minimizedDockSlotEnterAnimationMs = 720;
|
|
2592
2596
|
var dockPreviewMaxWidth = 260;
|
|
2593
2597
|
var dockPreviewMaxHeight = 170;
|
|
2594
2598
|
var dockPreviewImageCacheMaxEntries = 96;
|
|
@@ -2868,6 +2872,10 @@ function useWorkbenchGenieAnimation({
|
|
|
2868
2872
|
const rafRef = useRef4(null);
|
|
2869
2873
|
const animationGenerationRef = useRef4(0);
|
|
2870
2874
|
const animationCleanupRef = useRef4(null);
|
|
2875
|
+
const minimizedDockEnterAnimationNodeIdsRef = useRef4(/* @__PURE__ */ new Set());
|
|
2876
|
+
const minimizedDockEnterAnimationTimersRef = useRef4(
|
|
2877
|
+
/* @__PURE__ */ new Map()
|
|
2878
|
+
);
|
|
2871
2879
|
const [isCanvasActive, setIsCanvasActive] = useState4(false);
|
|
2872
2880
|
const [genieHiddenNodeIDs, setGenieHiddenNodeIDs] = useState4(
|
|
2873
2881
|
() => /* @__PURE__ */ new Set()
|
|
@@ -2895,6 +2903,40 @@ function useWorkbenchGenieAnimation({
|
|
|
2895
2903
|
(node) => resolveDockAnchorKey?.(node) ?? node.id,
|
|
2896
2904
|
[resolveDockAnchorKey]
|
|
2897
2905
|
);
|
|
2906
|
+
const releaseMinimizedDockEnterAnimation = useCallback6((nodeID) => {
|
|
2907
|
+
const timer = minimizedDockEnterAnimationTimersRef.current.get(nodeID);
|
|
2908
|
+
if (timer) {
|
|
2909
|
+
clearTimeout(timer);
|
|
2910
|
+
minimizedDockEnterAnimationTimersRef.current.delete(nodeID);
|
|
2911
|
+
}
|
|
2912
|
+
minimizedDockEnterAnimationNodeIdsRef.current.delete(nodeID);
|
|
2913
|
+
}, []);
|
|
2914
|
+
const registerMinimizedDockEnterAnimation = useCallback6(
|
|
2915
|
+
(nodeID) => {
|
|
2916
|
+
releaseMinimizedDockEnterAnimation(nodeID);
|
|
2917
|
+
minimizedDockEnterAnimationNodeIdsRef.current.add(nodeID);
|
|
2918
|
+
},
|
|
2919
|
+
[releaseMinimizedDockEnterAnimation]
|
|
2920
|
+
);
|
|
2921
|
+
const scheduleReleaseMinimizedDockEnterAnimation = useCallback6(
|
|
2922
|
+
(nodeID, delayMs = minimizedDockSlotEnterAnimationMs) => {
|
|
2923
|
+
const existing = minimizedDockEnterAnimationTimersRef.current.get(nodeID);
|
|
2924
|
+
if (existing) {
|
|
2925
|
+
clearTimeout(existing);
|
|
2926
|
+
}
|
|
2927
|
+
minimizedDockEnterAnimationTimersRef.current.set(
|
|
2928
|
+
nodeID,
|
|
2929
|
+
setTimeout(() => {
|
|
2930
|
+
minimizedDockEnterAnimationTimersRef.current.delete(nodeID);
|
|
2931
|
+
minimizedDockEnterAnimationNodeIdsRef.current.delete(nodeID);
|
|
2932
|
+
}, delayMs)
|
|
2933
|
+
);
|
|
2934
|
+
},
|
|
2935
|
+
[]
|
|
2936
|
+
);
|
|
2937
|
+
const shouldAnimateMinimizedDockEnter = useCallback6((nodeID) => {
|
|
2938
|
+
return minimizedDockEnterAnimationNodeIdsRef.current.has(nodeID);
|
|
2939
|
+
}, []);
|
|
2898
2940
|
const hideNodeForGenie = useCallback6((nodeID) => {
|
|
2899
2941
|
setGenieHiddenNodeIDs((current) => {
|
|
2900
2942
|
if (current.has(nodeID)) {
|
|
@@ -3198,6 +3240,7 @@ function useWorkbenchGenieAnimation({
|
|
|
3198
3240
|
clearCanvas();
|
|
3199
3241
|
};
|
|
3200
3242
|
animationCleanupRef.current = cleanupHiddenNode;
|
|
3243
|
+
registerMinimizedDockEnterAnimation(nodeID);
|
|
3201
3244
|
flushSync(() => {
|
|
3202
3245
|
hideNodeForGenie(nodeID);
|
|
3203
3246
|
runMinimize();
|
|
@@ -3206,12 +3249,14 @@ function useWorkbenchGenieAnimation({
|
|
|
3206
3249
|
window.requestAnimationFrame(() => resolve());
|
|
3207
3250
|
});
|
|
3208
3251
|
if (generation !== animationGenerationRef.current) {
|
|
3252
|
+
releaseMinimizedDockEnterAnimation(nodeID);
|
|
3209
3253
|
return;
|
|
3210
3254
|
}
|
|
3211
3255
|
const minimizedTarget = controller.getSnapshot().nodes.find((node) => node.id === nodeID) ?? target;
|
|
3212
3256
|
const anchorKey = resolveAnchorKeyForNode(minimizedTarget);
|
|
3213
3257
|
const dockRect = resolveDockAnchorRect(anchorKey);
|
|
3214
3258
|
if (!dockRect || !isUsableGenieRect(dockRect)) {
|
|
3259
|
+
releaseMinimizedDockEnterAnimation(nodeID);
|
|
3215
3260
|
animationCleanupRef.current = null;
|
|
3216
3261
|
cleanupHiddenNode();
|
|
3217
3262
|
return;
|
|
@@ -3220,12 +3265,14 @@ function useWorkbenchGenieAnimation({
|
|
|
3220
3265
|
direction: "minimize",
|
|
3221
3266
|
dockRect,
|
|
3222
3267
|
onCancel: () => {
|
|
3268
|
+
releaseMinimizedDockEnterAnimation(nodeID);
|
|
3223
3269
|
flushSync(() => {
|
|
3224
3270
|
showNodeForGenie(nodeID);
|
|
3225
3271
|
});
|
|
3226
3272
|
clearCanvas();
|
|
3227
3273
|
},
|
|
3228
3274
|
onComplete: () => {
|
|
3275
|
+
scheduleReleaseMinimizedDockEnterAnimation(nodeID);
|
|
3229
3276
|
flushSync(() => {
|
|
3230
3277
|
showNodeForGenie(nodeID);
|
|
3231
3278
|
});
|
|
@@ -3242,16 +3289,29 @@ function useWorkbenchGenieAnimation({
|
|
|
3242
3289
|
captureNodePreviewImage,
|
|
3243
3290
|
dockPreviewCache,
|
|
3244
3291
|
hideNodeForGenie,
|
|
3292
|
+
registerMinimizedDockEnterAnimation,
|
|
3293
|
+
releaseMinimizedDockEnterAnimation,
|
|
3245
3294
|
resolveAnchorKeyForNode,
|
|
3246
3295
|
resolveDockPreviewCacheKey2,
|
|
3247
3296
|
resolveDockAnchorRect,
|
|
3248
3297
|
resolveNodeElement,
|
|
3249
3298
|
runGenieAnimation,
|
|
3299
|
+
scheduleReleaseMinimizedDockEnterAnimation,
|
|
3250
3300
|
setupCanvas,
|
|
3251
3301
|
showNodeForGenie,
|
|
3252
3302
|
stopAnimation
|
|
3253
3303
|
]
|
|
3254
3304
|
);
|
|
3305
|
+
useEffect3(
|
|
3306
|
+
() => () => {
|
|
3307
|
+
for (const timer of minimizedDockEnterAnimationTimersRef.current.values()) {
|
|
3308
|
+
clearTimeout(timer);
|
|
3309
|
+
}
|
|
3310
|
+
minimizedDockEnterAnimationTimersRef.current.clear();
|
|
3311
|
+
minimizedDockEnterAnimationNodeIdsRef.current.clear();
|
|
3312
|
+
},
|
|
3313
|
+
[]
|
|
3314
|
+
);
|
|
3255
3315
|
return {
|
|
3256
3316
|
genieLayer: typeof document === "undefined" ? null : createPortal(
|
|
3257
3317
|
/* @__PURE__ */ jsx7(
|
|
@@ -3271,7 +3331,8 @@ function useWorkbenchGenieAnimation({
|
|
|
3271
3331
|
),
|
|
3272
3332
|
launchNodeFromAnchor,
|
|
3273
3333
|
minimizeNodeToAnchor,
|
|
3274
|
-
registerDockAnchor
|
|
3334
|
+
registerDockAnchor,
|
|
3335
|
+
shouldAnimateMinimizedDockEnter
|
|
3275
3336
|
};
|
|
3276
3337
|
}
|
|
3277
3338
|
|
|
@@ -4566,8 +4627,11 @@ var WorkbenchHostSessionController = class {
|
|
|
4566
4627
|
return null;
|
|
4567
4628
|
}
|
|
4568
4629
|
const launchSource = resolveWorkbenchHostLaunchSource(input);
|
|
4630
|
+
const currentState = this.controller.getSnapshot();
|
|
4569
4631
|
const request = {
|
|
4570
4632
|
...input,
|
|
4633
|
+
layoutConstraints: currentState.layoutConstraints,
|
|
4634
|
+
surfaceSize: currentState.surfaceSize,
|
|
4571
4635
|
workspaceId: this.input.workspaceId
|
|
4572
4636
|
};
|
|
4573
4637
|
if (launchSource !== null) {
|
|
@@ -5318,11 +5382,11 @@ import { useCallback as useCallback11, useMemo as useMemo6 } from "react";
|
|
|
5318
5382
|
// src/host/WorkbenchHostDock.tsx
|
|
5319
5383
|
import {
|
|
5320
5384
|
useCallback as useCallback10,
|
|
5321
|
-
useEffect as
|
|
5385
|
+
useEffect as useEffect9,
|
|
5322
5386
|
useLayoutEffect as useLayoutEffect4,
|
|
5323
5387
|
useMemo as useMemo5,
|
|
5324
|
-
useRef as
|
|
5325
|
-
useState as
|
|
5388
|
+
useRef as useRef8,
|
|
5389
|
+
useState as useState8
|
|
5326
5390
|
} from "react";
|
|
5327
5391
|
import {
|
|
5328
5392
|
ArrowLeftIcon,
|
|
@@ -5330,10 +5394,7 @@ import {
|
|
|
5330
5394
|
Button as Button4,
|
|
5331
5395
|
ChevronDownIcon,
|
|
5332
5396
|
ChevronUpIcon,
|
|
5333
|
-
|
|
5334
|
-
TooltipContent,
|
|
5335
|
-
TooltipProvider,
|
|
5336
|
-
TooltipTrigger
|
|
5397
|
+
TooltipProvider
|
|
5337
5398
|
} from "@tutti-os/ui-system";
|
|
5338
5399
|
|
|
5339
5400
|
// src/host/dockEntries.ts
|
|
@@ -5437,6 +5498,8 @@ var MAGNIFICATION_SETTLE_EPSILON = 0.2;
|
|
|
5437
5498
|
var MAGNIFICATION_SIZE_EPSILON = 0.2;
|
|
5438
5499
|
var MAX_MAGNIFICATION_STEP_SECONDS = 1 / 30;
|
|
5439
5500
|
var MAGNIFICATION_INFLUENCE_PADDING = 8;
|
|
5501
|
+
var DOCK_MAGNIFICATION_ENTRY_RAMP_MS = 90;
|
|
5502
|
+
var DOCK_MAGNIFICATION_CROSS_AXIS_PADDING = 8;
|
|
5440
5503
|
var dockMagnificationShellBySlot = /* @__PURE__ */ new WeakMap();
|
|
5441
5504
|
function mapDistanceToTargetSize(distance, baseSize = DOCK_ICON_BASE_SIZE, peakSize = DOCK_ICON_PEAK_SIZE, halfRange = DOCK_MAGNIFICATION_HALF_RANGE) {
|
|
5442
5505
|
const absoluteDistance = Math.abs(distance);
|
|
@@ -5446,6 +5509,55 @@ function mapDistanceToTargetSize(distance, baseSize = DOCK_ICON_BASE_SIZE, peakS
|
|
|
5446
5509
|
const influence = 1 - absoluteDistance / halfRange;
|
|
5447
5510
|
return baseSize + (peakSize - baseSize) * influence;
|
|
5448
5511
|
}
|
|
5512
|
+
function applyDockMagnificationEntryRamp(targetSize, baseSize, progress) {
|
|
5513
|
+
const clampedProgress = Math.min(1, Math.max(0, progress));
|
|
5514
|
+
return baseSize + (targetSize - baseSize) * clampedProgress;
|
|
5515
|
+
}
|
|
5516
|
+
function resolveDockMagnificationHitBounds(slotRects, dockPlacement, crossAxisPadding = DOCK_MAGNIFICATION_CROSS_AXIS_PADDING) {
|
|
5517
|
+
if (slotRects.length === 0) {
|
|
5518
|
+
return null;
|
|
5519
|
+
}
|
|
5520
|
+
let mainStart = Number.POSITIVE_INFINITY;
|
|
5521
|
+
let mainEnd = Number.NEGATIVE_INFINITY;
|
|
5522
|
+
let crossStart = Number.POSITIVE_INFINITY;
|
|
5523
|
+
let crossEnd = Number.NEGATIVE_INFINITY;
|
|
5524
|
+
for (const rect of slotRects) {
|
|
5525
|
+
if (dockPlacement === "left") {
|
|
5526
|
+
mainStart = Math.min(mainStart, rect.top);
|
|
5527
|
+
mainEnd = Math.max(mainEnd, rect.bottom);
|
|
5528
|
+
crossStart = Math.min(crossStart, rect.left);
|
|
5529
|
+
crossEnd = Math.max(crossEnd, rect.right);
|
|
5530
|
+
} else {
|
|
5531
|
+
mainStart = Math.min(mainStart, rect.left);
|
|
5532
|
+
mainEnd = Math.max(mainEnd, rect.right);
|
|
5533
|
+
crossStart = Math.min(crossStart, rect.top);
|
|
5534
|
+
crossEnd = Math.max(crossEnd, rect.bottom);
|
|
5535
|
+
}
|
|
5536
|
+
}
|
|
5537
|
+
const effectiveCrossAxisEndPadding = dockPlacement === "left" ? crossAxisPadding + (DOCK_ICON_PEAK_SIZE - DOCK_ICON_BASE_SIZE) : crossAxisPadding;
|
|
5538
|
+
return {
|
|
5539
|
+
crossEnd: crossEnd + effectiveCrossAxisEndPadding,
|
|
5540
|
+
crossStart: crossStart - crossAxisPadding,
|
|
5541
|
+
mainEnd,
|
|
5542
|
+
mainStart
|
|
5543
|
+
};
|
|
5544
|
+
}
|
|
5545
|
+
function isDockMagnificationPointInsideHitBounds({
|
|
5546
|
+
clientX,
|
|
5547
|
+
clientY,
|
|
5548
|
+
dockPlacement,
|
|
5549
|
+
hitBounds
|
|
5550
|
+
}) {
|
|
5551
|
+
if (!hitBounds) {
|
|
5552
|
+
return false;
|
|
5553
|
+
}
|
|
5554
|
+
const mainAxis = dockPlacement === "left" ? clientY : clientX;
|
|
5555
|
+
const crossAxis = dockPlacement === "left" ? clientX : clientY;
|
|
5556
|
+
return mainAxis >= hitBounds.mainStart && mainAxis <= hitBounds.mainEnd && crossAxis >= hitBounds.crossStart && crossAxis <= hitBounds.crossEnd;
|
|
5557
|
+
}
|
|
5558
|
+
function resolveDockMagnificationSlotCenter(rect, dockPlacement, baseSize = DOCK_ICON_BASE_SIZE) {
|
|
5559
|
+
return dockPlacement === "left" ? rect.top + baseSize / 2 : rect.left + baseSize / 2;
|
|
5560
|
+
}
|
|
5449
5561
|
var DOCK_MAGNIFICATION_SPRING_SUBSTEPS = 8;
|
|
5450
5562
|
function advanceDockMagnificationSpring(current, target, deltaSeconds) {
|
|
5451
5563
|
const subDeltaSeconds = deltaSeconds / DOCK_MAGNIFICATION_SPRING_SUBSTEPS;
|
|
@@ -5470,6 +5582,14 @@ function hasAppliedSizeChanged(previous, next) {
|
|
|
5470
5582
|
}
|
|
5471
5583
|
return Math.abs(previous.size - next.size) > MAGNIFICATION_SIZE_EPSILON;
|
|
5472
5584
|
}
|
|
5585
|
+
function resolveDockMagnificationSlotLayoutSize({
|
|
5586
|
+
size
|
|
5587
|
+
}) {
|
|
5588
|
+
return { height: size, width: size };
|
|
5589
|
+
}
|
|
5590
|
+
function isDockMagnificationSlotLayoutLocked(slotElement) {
|
|
5591
|
+
return slotElement.dataset.collapsing === "true" || slotElement.dataset.presence === "entering" || slotElement.dataset.presence === "exiting";
|
|
5592
|
+
}
|
|
5473
5593
|
function resolveDockMagnificationShell(slotElement) {
|
|
5474
5594
|
const cachedShell = dockMagnificationShellBySlot.get(slotElement);
|
|
5475
5595
|
if (cachedShell !== void 0 && (cachedShell === null || slotElement.contains(cachedShell))) {
|
|
@@ -5506,8 +5626,11 @@ function applyDockSlotMagnification(slotElement, size, baseSize, appliedStylesRe
|
|
|
5506
5626
|
return;
|
|
5507
5627
|
}
|
|
5508
5628
|
const scale = nextStyle.size / baseSize;
|
|
5509
|
-
|
|
5510
|
-
|
|
5629
|
+
const layoutSize = resolveDockMagnificationSlotLayoutSize({
|
|
5630
|
+
size: nextStyle.size
|
|
5631
|
+
});
|
|
5632
|
+
slotElement.style.width = `${layoutSize.width}px`;
|
|
5633
|
+
slotElement.style.height = `${layoutSize.height}px`;
|
|
5511
5634
|
shell.style.transform = `scale(${scale})`;
|
|
5512
5635
|
}
|
|
5513
5636
|
function clearDockSlotMagnification(slotElement, appliedStylesRef) {
|
|
@@ -5533,7 +5656,9 @@ function useDockMagnification({
|
|
|
5533
5656
|
);
|
|
5534
5657
|
const animationFrameRef = useRef5(null);
|
|
5535
5658
|
const lastFrameTimeRef = useRef5(null);
|
|
5659
|
+
const entryRampStartedAtRef = useRef5(null);
|
|
5536
5660
|
const restCentersRef = useRef5(null);
|
|
5661
|
+
const hitBoundsRef = useRef5(null);
|
|
5537
5662
|
const slotOrderRef = useRef5([]);
|
|
5538
5663
|
const magnifyActiveRef = useRef5(false);
|
|
5539
5664
|
const setMagnifyActive = useCallback8(
|
|
@@ -5560,14 +5685,25 @@ function useDockMagnification({
|
|
|
5560
5685
|
const captureRestCenters = useCallback8(() => {
|
|
5561
5686
|
const slots = slotRefs.current;
|
|
5562
5687
|
const centers = /* @__PURE__ */ new Map();
|
|
5688
|
+
const slotRects = [];
|
|
5563
5689
|
const order = [];
|
|
5564
5690
|
for (const [anchorKey, slotElement] of slots) {
|
|
5565
5691
|
order.push(anchorKey);
|
|
5566
5692
|
const rect = slotElement.getBoundingClientRect();
|
|
5567
|
-
|
|
5693
|
+
slotRects.push({
|
|
5694
|
+
bottom: rect.bottom,
|
|
5695
|
+
left: rect.left,
|
|
5696
|
+
right: rect.right,
|
|
5697
|
+
top: rect.top
|
|
5698
|
+
});
|
|
5699
|
+
const center = resolveDockMagnificationSlotCenter(rect, dockPlacement);
|
|
5568
5700
|
centers.set(anchorKey, center);
|
|
5569
5701
|
}
|
|
5570
5702
|
slotOrderRef.current = order;
|
|
5703
|
+
hitBoundsRef.current = resolveDockMagnificationHitBounds(
|
|
5704
|
+
slotRects,
|
|
5705
|
+
dockPlacement
|
|
5706
|
+
);
|
|
5571
5707
|
restCentersRef.current = centers;
|
|
5572
5708
|
}, [dockPlacement, slotRefs]);
|
|
5573
5709
|
const runAnimationFrame = useCallback8(
|
|
@@ -5578,6 +5714,7 @@ function useDockMagnification({
|
|
|
5578
5714
|
const pointerAxis = pointerAxisRef.current;
|
|
5579
5715
|
if (pointerAxis !== null) {
|
|
5580
5716
|
captureRestCenters();
|
|
5717
|
+
entryRampStartedAtRef.current ??= frameTime;
|
|
5581
5718
|
}
|
|
5582
5719
|
const slots = slotRefs.current;
|
|
5583
5720
|
const order = slotOrderRef.current;
|
|
@@ -5590,6 +5727,7 @@ function useDockMagnification({
|
|
|
5590
5727
|
let shouldContinue = false;
|
|
5591
5728
|
let allSettled = true;
|
|
5592
5729
|
const influenceRadius = DOCK_MAGNIFICATION_HALF_RANGE + MAGNIFICATION_INFLUENCE_PADDING;
|
|
5730
|
+
const entryRampProgress = pointerAxis === null || entryRampStartedAtRef.current === null ? 1 : (frameTime - entryRampStartedAtRef.current) / DOCK_MAGNIFICATION_ENTRY_RAMP_MS;
|
|
5593
5731
|
for (let index = 0; index < order.length; index += 1) {
|
|
5594
5732
|
const anchorKey = order[index];
|
|
5595
5733
|
if (!anchorKey) {
|
|
@@ -5602,7 +5740,11 @@ function useDockMagnification({
|
|
|
5602
5740
|
const distance = pointerAxis === null ? DOCK_MAGNIFICATION_HALF_RANGE : pointerAxis - center;
|
|
5603
5741
|
const absoluteDistance = Math.abs(distance);
|
|
5604
5742
|
const inRange = absoluteDistance < influenceRadius;
|
|
5605
|
-
const targetSize = inRange ?
|
|
5743
|
+
const targetSize = inRange ? applyDockMagnificationEntryRamp(
|
|
5744
|
+
mapDistanceToTargetSize(distance),
|
|
5745
|
+
DOCK_ICON_BASE_SIZE,
|
|
5746
|
+
entryRampProgress
|
|
5747
|
+
) : DOCK_ICON_BASE_SIZE;
|
|
5606
5748
|
const currentSpring = springsRef.current.get(anchorKey) ?? {
|
|
5607
5749
|
value: DOCK_ICON_BASE_SIZE,
|
|
5608
5750
|
velocity: 0
|
|
@@ -5635,6 +5777,11 @@ function useDockMagnification({
|
|
|
5635
5777
|
if (!slotElement) {
|
|
5636
5778
|
continue;
|
|
5637
5779
|
}
|
|
5780
|
+
if (isDockMagnificationSlotLayoutLocked(slotElement)) {
|
|
5781
|
+
springsRef.current.delete(anchorKey);
|
|
5782
|
+
clearDockSlotMagnification(slotElement, appliedStylesRef.current);
|
|
5783
|
+
continue;
|
|
5784
|
+
}
|
|
5638
5785
|
if (pointerAxis === null && isDockMagnificationSpringSettled(nextSpring, DOCK_ICON_BASE_SIZE)) {
|
|
5639
5786
|
springsRef.current.delete(anchorKey);
|
|
5640
5787
|
clearDockSlotMagnification(slotElement, appliedStylesRef.current);
|
|
@@ -5653,7 +5800,9 @@ function useDockMagnification({
|
|
|
5653
5800
|
shouldContinue = true;
|
|
5654
5801
|
}
|
|
5655
5802
|
if (pointerAxis === null && allSettled) {
|
|
5803
|
+
entryRampStartedAtRef.current = null;
|
|
5656
5804
|
restCentersRef.current = null;
|
|
5805
|
+
hitBoundsRef.current = null;
|
|
5657
5806
|
slotOrderRef.current = [];
|
|
5658
5807
|
setMagnifyActive(false);
|
|
5659
5808
|
}
|
|
@@ -5674,9 +5823,23 @@ function useDockMagnification({
|
|
|
5674
5823
|
}, [runAnimationFrame]);
|
|
5675
5824
|
const handlePointerMove = useCallback8(
|
|
5676
5825
|
(clientX, clientY) => {
|
|
5677
|
-
pendingPointerAxisRef.current = dockPlacement === "left" ? clientY : clientX;
|
|
5678
5826
|
if (restCentersRef.current === null) {
|
|
5679
5827
|
captureRestCenters();
|
|
5828
|
+
}
|
|
5829
|
+
if (!isDockMagnificationPointInsideHitBounds({
|
|
5830
|
+
clientX,
|
|
5831
|
+
clientY,
|
|
5832
|
+
dockPlacement,
|
|
5833
|
+
hitBounds: hitBoundsRef.current
|
|
5834
|
+
})) {
|
|
5835
|
+
pendingPointerAxisRef.current = null;
|
|
5836
|
+
pointerAxisRef.current = null;
|
|
5837
|
+
entryRampStartedAtRef.current = null;
|
|
5838
|
+
scheduleAnimation();
|
|
5839
|
+
return;
|
|
5840
|
+
}
|
|
5841
|
+
pendingPointerAxisRef.current = dockPlacement === "left" ? clientY : clientX;
|
|
5842
|
+
if (!magnifyActiveRef.current) {
|
|
5680
5843
|
setMagnifyActive(true);
|
|
5681
5844
|
}
|
|
5682
5845
|
scheduleAnimation();
|
|
@@ -5693,6 +5856,7 @@ function useDockMagnification({
|
|
|
5693
5856
|
springsRef.current.delete(anchorKey);
|
|
5694
5857
|
restCentersRef.current?.delete(anchorKey);
|
|
5695
5858
|
appliedStylesRef.current.delete(anchorKey);
|
|
5859
|
+
hitBoundsRef.current = null;
|
|
5696
5860
|
slotOrderRef.current = slotOrderRef.current.filter(
|
|
5697
5861
|
(key) => key !== anchorKey
|
|
5698
5862
|
);
|
|
@@ -5707,6 +5871,7 @@ function useDockMagnification({
|
|
|
5707
5871
|
stopAnimation();
|
|
5708
5872
|
pendingPointerAxisRef.current = null;
|
|
5709
5873
|
pointerAxisRef.current = null;
|
|
5874
|
+
entryRampStartedAtRef.current = null;
|
|
5710
5875
|
lastFrameTimeRef.current = null;
|
|
5711
5876
|
}, [stopAnimation]);
|
|
5712
5877
|
const resetMagnification = useCallback8(() => {
|
|
@@ -5717,9 +5882,11 @@ function useDockMagnification({
|
|
|
5717
5882
|
springsRef.current.clear();
|
|
5718
5883
|
appliedStylesRef.current.clear();
|
|
5719
5884
|
restCentersRef.current = null;
|
|
5885
|
+
hitBoundsRef.current = null;
|
|
5720
5886
|
slotOrderRef.current = [];
|
|
5721
5887
|
pointerAxisRef.current = null;
|
|
5722
5888
|
pendingPointerAxisRef.current = null;
|
|
5889
|
+
entryRampStartedAtRef.current = null;
|
|
5723
5890
|
setMagnifyActive(false);
|
|
5724
5891
|
}, [setMagnifyActive, slotRefs, stopAnimation]);
|
|
5725
5892
|
useEffect6(
|
|
@@ -5827,13 +5994,67 @@ function orderWorkbenchMinimizedDockNodes(input) {
|
|
|
5827
5994
|
}).map(({ node }) => node);
|
|
5828
5995
|
}
|
|
5829
5996
|
|
|
5997
|
+
// src/host/minimizedDockStackPromotion.ts
|
|
5998
|
+
import { useEffect as useEffect7, useRef as useRef6, useState as useState6 } from "react";
|
|
5999
|
+
var minimizedDockStackPromotionDurationMs = 520;
|
|
6000
|
+
function detectMinimizedDockStackPromotion(previous, next) {
|
|
6001
|
+
const previousVisibleNodeIds = new Set(
|
|
6002
|
+
previous.filter(
|
|
6003
|
+
(slot) => slot.kind === "node"
|
|
6004
|
+
).map((slot) => slot.node.id)
|
|
6005
|
+
);
|
|
6006
|
+
const previousStackNodeIds = previous.find((slot) => slot.kind === "stack")?.nodes.map((node) => node.id) ?? [];
|
|
6007
|
+
for (const slot of next) {
|
|
6008
|
+
if (slot.kind !== "node") {
|
|
6009
|
+
continue;
|
|
6010
|
+
}
|
|
6011
|
+
if (!previousVisibleNodeIds.has(slot.node.id) && previousStackNodeIds.includes(slot.node.id)) {
|
|
6012
|
+
return slot.node.id;
|
|
6013
|
+
}
|
|
6014
|
+
}
|
|
6015
|
+
return null;
|
|
6016
|
+
}
|
|
6017
|
+
function useMinimizedDockStackPromotion(slots) {
|
|
6018
|
+
const previousSlotsRef = useRef6(slots);
|
|
6019
|
+
const promotionTimerRef = useRef6(null);
|
|
6020
|
+
const [promotedNodeId, setPromotedNodeId] = useState6(null);
|
|
6021
|
+
const [stackDispatching, setStackDispatching] = useState6(false);
|
|
6022
|
+
useEffect7(() => {
|
|
6023
|
+
const promotedNodeId2 = detectMinimizedDockStackPromotion(
|
|
6024
|
+
previousSlotsRef.current,
|
|
6025
|
+
slots
|
|
6026
|
+
);
|
|
6027
|
+
previousSlotsRef.current = slots;
|
|
6028
|
+
if (!promotedNodeId2) {
|
|
6029
|
+
return void 0;
|
|
6030
|
+
}
|
|
6031
|
+
setPromotedNodeId(promotedNodeId2);
|
|
6032
|
+
setStackDispatching(true);
|
|
6033
|
+
if (promotionTimerRef.current !== null) {
|
|
6034
|
+
clearTimeout(promotionTimerRef.current);
|
|
6035
|
+
}
|
|
6036
|
+
promotionTimerRef.current = setTimeout(() => {
|
|
6037
|
+
promotionTimerRef.current = null;
|
|
6038
|
+
setPromotedNodeId(null);
|
|
6039
|
+
setStackDispatching(false);
|
|
6040
|
+
}, minimizedDockStackPromotionDurationMs);
|
|
6041
|
+
return () => {
|
|
6042
|
+
if (promotionTimerRef.current !== null) {
|
|
6043
|
+
clearTimeout(promotionTimerRef.current);
|
|
6044
|
+
promotionTimerRef.current = null;
|
|
6045
|
+
}
|
|
6046
|
+
};
|
|
6047
|
+
}, [slots]);
|
|
6048
|
+
return { promotedNodeId, stackDispatching };
|
|
6049
|
+
}
|
|
6050
|
+
|
|
5830
6051
|
// src/host/WorkbenchHostDockPopup.tsx
|
|
5831
6052
|
import {
|
|
5832
6053
|
forwardRef,
|
|
5833
6054
|
useCallback as useCallback9,
|
|
5834
|
-
useEffect as
|
|
5835
|
-
useRef as
|
|
5836
|
-
useState as
|
|
6055
|
+
useEffect as useEffect8,
|
|
6056
|
+
useRef as useRef7,
|
|
6057
|
+
useState as useState7
|
|
5837
6058
|
} from "react";
|
|
5838
6059
|
import { createPortal as createPortal2 } from "react-dom";
|
|
5839
6060
|
import { Button as Button3, CloseIcon, FileCreateIcon, cn } from "@tutti-os/ui-system";
|
|
@@ -5845,7 +6066,7 @@ var minimizedStackCardWidthPx = 118;
|
|
|
5845
6066
|
var minimizedStackLeftPlacementGapPx = 4;
|
|
5846
6067
|
var minimizedStackLeftDockClearancePx = 2;
|
|
5847
6068
|
var workbenchLeftDockLeftInsetPx = 4;
|
|
5848
|
-
var workbenchLeftDockViewportWidthPx =
|
|
6069
|
+
var workbenchLeftDockViewportWidthPx = 124;
|
|
5849
6070
|
var minimizedStackLeftGutterMinPx = 4;
|
|
5850
6071
|
var minimizedStackLeftPopupNudgeLeftPx = 60;
|
|
5851
6072
|
var minimizedStackLeftPopupNudgeDownPx = 32;
|
|
@@ -5974,7 +6195,7 @@ var dockPopupGridGapPx = 8;
|
|
|
5974
6195
|
var dockPopupPanelPaddingInlinePx = 12;
|
|
5975
6196
|
var dockPopupPanelBorderInlinePx = 2;
|
|
5976
6197
|
var dockPopupPlacementGapPx = 14;
|
|
5977
|
-
var dockPopupMinimizedStackLaunchDisappearMs =
|
|
6198
|
+
var dockPopupMinimizedStackLaunchDisappearMs = 0;
|
|
5978
6199
|
var dockPopupMinimizedStackPopupZIndex = 100300;
|
|
5979
6200
|
var popupCardMagnificationRange = 160;
|
|
5980
6201
|
var popupCardMaxScale = 1.16;
|
|
@@ -6036,11 +6257,11 @@ function WorkbenchHostDockPopup({
|
|
|
6036
6257
|
const resolvedVariant = variant ?? "default";
|
|
6037
6258
|
const isMinimizedStack = resolvedVariant === "minimized-stack";
|
|
6038
6259
|
const createCardCount = showCreateNew === false ? 0 : 1;
|
|
6039
|
-
const cardElementsRef =
|
|
6040
|
-
const minimizedStackViewportRef =
|
|
6041
|
-
const [pointer, setPointer] =
|
|
6042
|
-
const [minimizedStackScrollOffset, setMinimizedStackScrollOffset] =
|
|
6043
|
-
const [capturedPreviewByNodeId, setCapturedPreviewByNodeId] =
|
|
6260
|
+
const cardElementsRef = useRef7(/* @__PURE__ */ new Map());
|
|
6261
|
+
const minimizedStackViewportRef = useRef7(null);
|
|
6262
|
+
const [pointer, setPointer] = useState7(null);
|
|
6263
|
+
const [minimizedStackScrollOffset, setMinimizedStackScrollOffset] = useState7(0);
|
|
6264
|
+
const [capturedPreviewByNodeId, setCapturedPreviewByNodeId] = useState7({});
|
|
6044
6265
|
const columnCount = Math.min(Math.max(items.length + createCardCount, 1), 3);
|
|
6045
6266
|
const popupWidthPx = columnCount * dockPopupCardWidthPx + Math.max(0, columnCount - 1) * dockPopupGridGapPx + dockPopupPanelPaddingInlinePx * 2 + dockPopupPanelBorderInlinePx;
|
|
6046
6267
|
const popupCenterY = anchorRect.top + anchorRect.height / 2;
|
|
@@ -6118,7 +6339,7 @@ function WorkbenchHostDockPopup({
|
|
|
6118
6339
|
},
|
|
6119
6340
|
[]
|
|
6120
6341
|
);
|
|
6121
|
-
|
|
6342
|
+
useEffect8(() => {
|
|
6122
6343
|
if (!isLeftMinimizedStack) {
|
|
6123
6344
|
return;
|
|
6124
6345
|
}
|
|
@@ -6130,7 +6351,7 @@ function WorkbenchHostDockPopup({
|
|
|
6130
6351
|
document.body.removeAttribute("data-desktop-dock-minimized-stack-open");
|
|
6131
6352
|
};
|
|
6132
6353
|
}, [isLeftMinimizedStack]);
|
|
6133
|
-
|
|
6354
|
+
useEffect8(() => {
|
|
6134
6355
|
const handlePointerDown = (event) => {
|
|
6135
6356
|
if (!(event.target instanceof Element)) {
|
|
6136
6357
|
onClose();
|
|
@@ -6156,13 +6377,13 @@ function WorkbenchHostDockPopup({
|
|
|
6156
6377
|
};
|
|
6157
6378
|
}, [onClose]);
|
|
6158
6379
|
const previewCaptureKey = items.map((item) => `${item.node.id}:${item.previewImageUrl ?? ""}`).join("|");
|
|
6159
|
-
|
|
6380
|
+
useEffect8(() => {
|
|
6160
6381
|
if (!isMinimizedStack) {
|
|
6161
6382
|
return;
|
|
6162
6383
|
}
|
|
6163
6384
|
setMinimizedStackScrollOffset(initialMinimizedStackScrollOffset);
|
|
6164
6385
|
}, [initialMinimizedStackScrollOffset, isMinimizedStack, items.length]);
|
|
6165
|
-
|
|
6386
|
+
useEffect8(() => {
|
|
6166
6387
|
if (!isMinimizedStack) {
|
|
6167
6388
|
return;
|
|
6168
6389
|
}
|
|
@@ -6183,7 +6404,7 @@ function WorkbenchHostDockPopup({
|
|
|
6183
6404
|
viewport.addEventListener("wheel", handleWheel, { passive: false });
|
|
6184
6405
|
return () => viewport.removeEventListener("wheel", handleWheel);
|
|
6185
6406
|
}, [isMinimizedStack, minimizedStackMaxScrollOffset]);
|
|
6186
|
-
|
|
6407
|
+
useEffect8(() => {
|
|
6187
6408
|
let cancelled = false;
|
|
6188
6409
|
const missingItems = items.filter(
|
|
6189
6410
|
(item) => !item.previewImageUrl && !capturedPreviewByNodeId[item.node.id]
|
|
@@ -6404,9 +6625,9 @@ var WorkbenchHostDockPopupCard = forwardRef(function WorkbenchHostDockPopupCard2
|
|
|
6404
6625
|
}, ref) {
|
|
6405
6626
|
const title = item.title?.trim() || item.node.title;
|
|
6406
6627
|
const isMinimizedStack = variant === "minimized-stack";
|
|
6407
|
-
const [isLaunching, setIsLaunching] =
|
|
6408
|
-
const launchTimerRef =
|
|
6409
|
-
|
|
6628
|
+
const [isLaunching, setIsLaunching] = useState7(false);
|
|
6629
|
+
const launchTimerRef = useRef7(null);
|
|
6630
|
+
useEffect8(
|
|
6410
6631
|
() => () => {
|
|
6411
6632
|
if (launchTimerRef.current !== null) {
|
|
6412
6633
|
clearTimeout(launchTimerRef.current);
|
|
@@ -6530,7 +6751,12 @@ function stripDockDescriptionTerminalPunctuation(value) {
|
|
|
6530
6751
|
return trimmed.replace(/[。..]+$/u, "");
|
|
6531
6752
|
}
|
|
6532
6753
|
function isDockVisualMutationActive(element) {
|
|
6533
|
-
|
|
6754
|
+
if (!element) {
|
|
6755
|
+
return false;
|
|
6756
|
+
}
|
|
6757
|
+
return element.hasAttribute("data-dock-pointer-active") || element.hasAttribute("data-dock-hover-panel-open") || element.querySelector(
|
|
6758
|
+
'[data-collapsing="true"], [data-presence="entering"], [data-presence="exiting"], [data-stack-dispatching="true"], [data-promoted-from-stack="true"]'
|
|
6759
|
+
) !== null;
|
|
6534
6760
|
}
|
|
6535
6761
|
function WorkbenchHostDock({
|
|
6536
6762
|
context,
|
|
@@ -6550,45 +6776,49 @@ function WorkbenchHostDock({
|
|
|
6550
6776
|
() => new Set(context.minimizedNodes.map((node) => node.id)),
|
|
6551
6777
|
[context.minimizedNodes]
|
|
6552
6778
|
);
|
|
6553
|
-
const dockMeasureRef =
|
|
6554
|
-
const dockItemsRef =
|
|
6555
|
-
const hoverPanelRef =
|
|
6556
|
-
const hoverPanelCloseTimerRef =
|
|
6779
|
+
const dockMeasureRef = useRef8(null);
|
|
6780
|
+
const dockItemsRef = useRef8(null);
|
|
6781
|
+
const hoverPanelRef = useRef8(null);
|
|
6782
|
+
const hoverPanelCloseTimerRef = useRef8(
|
|
6557
6783
|
null
|
|
6558
6784
|
);
|
|
6559
|
-
const hoverPanelOpenTimerRef =
|
|
6785
|
+
const hoverPanelOpenTimerRef = useRef8(
|
|
6560
6786
|
null
|
|
6561
6787
|
);
|
|
6562
|
-
const hoverPanelScheduledPointRef =
|
|
6563
|
-
const
|
|
6564
|
-
|
|
6565
|
-
);
|
|
6566
|
-
const hoverPanelRestTargetRef = useRef7(null);
|
|
6567
|
-
const activeHoverPanelRef = useRef7(
|
|
6788
|
+
const hoverPanelScheduledPointRef = useRef8(null);
|
|
6789
|
+
const hoverPanelRestTargetRef = useRef8(null);
|
|
6790
|
+
const activeHoverPanelRef = useRef8(
|
|
6568
6791
|
null
|
|
6569
6792
|
);
|
|
6570
|
-
const pendingDockStateRefreshRef =
|
|
6571
|
-
const slotRefs =
|
|
6572
|
-
const previousAttentionTokenByEntryId =
|
|
6573
|
-
const attentionTimeouts =
|
|
6793
|
+
const pendingDockStateRefreshRef = useRef8(false);
|
|
6794
|
+
const slotRefs = useRef8(/* @__PURE__ */ new Map());
|
|
6795
|
+
const previousAttentionTokenByEntryId = useRef8(/* @__PURE__ */ new Map());
|
|
6796
|
+
const attentionTimeouts = useRef8(
|
|
6574
6797
|
/* @__PURE__ */ new Map()
|
|
6575
6798
|
);
|
|
6576
|
-
const [activeAttentionEntryIds, setActiveAttentionEntryIds] =
|
|
6577
|
-
const [activePopup, setActivePopup] =
|
|
6578
|
-
const [activeHoverPanel, setActiveHoverPanel] =
|
|
6579
|
-
const [activeMinimizedStackPopup, setActiveMinimizedStackPopup] =
|
|
6580
|
-
const [pendingActionKeys, setPendingActionKeys] =
|
|
6799
|
+
const [activeAttentionEntryIds, setActiveAttentionEntryIds] = useState8(/* @__PURE__ */ new Set());
|
|
6800
|
+
const [activePopup, setActivePopup] = useState8(null);
|
|
6801
|
+
const [activeHoverPanel, setActiveHoverPanel] = useState8(null);
|
|
6802
|
+
const [activeMinimizedStackPopup, setActiveMinimizedStackPopup] = useState8(null);
|
|
6803
|
+
const [pendingActionKeys, setPendingActionKeys] = useState8(
|
|
6581
6804
|
() => /* @__PURE__ */ new Set()
|
|
6582
6805
|
);
|
|
6583
|
-
const [dockFrameSize, setDockFrameSize] =
|
|
6806
|
+
const [dockFrameSize, setDockFrameSize] = useState8(null);
|
|
6584
6807
|
const { triggerDockBounce } = useDockBounce(slotRefs);
|
|
6585
|
-
const [dockScrollState, setDockScrollState] =
|
|
6808
|
+
const [dockScrollState, setDockScrollState] = useState8(() => ({
|
|
6586
6809
|
canScrollBackward: false,
|
|
6587
6810
|
canScrollForward: false,
|
|
6588
6811
|
hasOverflow: false
|
|
6589
6812
|
}));
|
|
6590
|
-
const [dockStateRevision, setDockStateRevision] =
|
|
6591
|
-
const [externalStateRevision, setExternalStateRevision] =
|
|
6813
|
+
const [dockStateRevision, setDockStateRevision] = useState8(0);
|
|
6814
|
+
const [externalStateRevision, setExternalStateRevision] = useState8(0);
|
|
6815
|
+
const [
|
|
6816
|
+
collapsingMinimizedLaunchAnchorKeys,
|
|
6817
|
+
setCollapsingMinimizedLaunchAnchorKeys
|
|
6818
|
+
] = useState8(() => /* @__PURE__ */ new Set());
|
|
6819
|
+
const collapsingMinimizedLaunchTimerRef = useRef8(
|
|
6820
|
+
/* @__PURE__ */ new Map()
|
|
6821
|
+
);
|
|
6592
6822
|
const clearHoverPanelCloseTimer = useCallback10(() => {
|
|
6593
6823
|
if (hoverPanelCloseTimerRef.current === null) {
|
|
6594
6824
|
return;
|
|
@@ -6604,17 +6834,47 @@ function WorkbenchHostDock({
|
|
|
6604
6834
|
hoverPanelOpenTimerRef.current = null;
|
|
6605
6835
|
hoverPanelScheduledPointRef.current = null;
|
|
6606
6836
|
}, []);
|
|
6607
|
-
|
|
6837
|
+
useEffect9(
|
|
6608
6838
|
() => () => {
|
|
6609
6839
|
clearHoverPanelCloseTimer();
|
|
6610
6840
|
clearHoverPanelOpenTimer();
|
|
6611
|
-
for (const timer of
|
|
6841
|
+
for (const timer of collapsingMinimizedLaunchTimerRef.current.values()) {
|
|
6612
6842
|
clearTimeout(timer);
|
|
6613
6843
|
}
|
|
6614
|
-
|
|
6844
|
+
collapsingMinimizedLaunchTimerRef.current.clear();
|
|
6615
6845
|
},
|
|
6616
6846
|
[clearHoverPanelCloseTimer, clearHoverPanelOpenTimer]
|
|
6617
6847
|
);
|
|
6848
|
+
const clearCollapsingMinimizedLaunch = useCallback10((anchorKey) => {
|
|
6849
|
+
const timer = collapsingMinimizedLaunchTimerRef.current.get(anchorKey);
|
|
6850
|
+
if (timer) {
|
|
6851
|
+
clearTimeout(timer);
|
|
6852
|
+
collapsingMinimizedLaunchTimerRef.current.delete(anchorKey);
|
|
6853
|
+
}
|
|
6854
|
+
setCollapsingMinimizedLaunchAnchorKeys((current) => {
|
|
6855
|
+
if (!current.has(anchorKey)) {
|
|
6856
|
+
return current;
|
|
6857
|
+
}
|
|
6858
|
+
const next = new Set(current);
|
|
6859
|
+
next.delete(anchorKey);
|
|
6860
|
+
return next;
|
|
6861
|
+
});
|
|
6862
|
+
}, []);
|
|
6863
|
+
const scheduleCollapsingMinimizedLaunchClear = useCallback10(
|
|
6864
|
+
(anchorKey) => {
|
|
6865
|
+
const existing = collapsingMinimizedLaunchTimerRef.current.get(anchorKey);
|
|
6866
|
+
if (existing) {
|
|
6867
|
+
clearTimeout(existing);
|
|
6868
|
+
}
|
|
6869
|
+
collapsingMinimizedLaunchTimerRef.current.set(
|
|
6870
|
+
anchorKey,
|
|
6871
|
+
setTimeout(() => {
|
|
6872
|
+
clearCollapsingMinimizedLaunch(anchorKey);
|
|
6873
|
+
}, minimizedDockSlotLayoutAnimationMs)
|
|
6874
|
+
);
|
|
6875
|
+
},
|
|
6876
|
+
[clearCollapsingMinimizedLaunch]
|
|
6877
|
+
);
|
|
6618
6878
|
useLayoutEffect4(() => {
|
|
6619
6879
|
const element = dockMeasureRef.current;
|
|
6620
6880
|
if (!element || typeof window === "undefined") {
|
|
@@ -6659,7 +6919,7 @@ function WorkbenchHostDock({
|
|
|
6659
6919
|
pendingDockStateRefreshRef.current = false;
|
|
6660
6920
|
setDockStateRevision((revision) => revision + 1);
|
|
6661
6921
|
}, []);
|
|
6662
|
-
|
|
6922
|
+
useEffect9(() => {
|
|
6663
6923
|
if (!dockStateSource) {
|
|
6664
6924
|
return void 0;
|
|
6665
6925
|
}
|
|
@@ -6693,6 +6953,7 @@ function WorkbenchHostDock({
|
|
|
6693
6953
|
}),
|
|
6694
6954
|
[context.nodes, nodeDefinitions]
|
|
6695
6955
|
);
|
|
6956
|
+
const { promotedNodeId, stackDispatching } = useMinimizedDockStackPromotion(minimizedDockSlots);
|
|
6696
6957
|
const dockItems = useMemo5(
|
|
6697
6958
|
() => createWorkbenchHostDockItems({
|
|
6698
6959
|
minimizedDockSlots,
|
|
@@ -6700,7 +6961,10 @@ function WorkbenchHostDock({
|
|
|
6700
6961
|
}),
|
|
6701
6962
|
[minimizedDockSlots, resolvedEntries]
|
|
6702
6963
|
);
|
|
6703
|
-
const presentDockItems = useDockPresenceItems(
|
|
6964
|
+
const presentDockItems = useDockPresenceItems(
|
|
6965
|
+
dockItems,
|
|
6966
|
+
(nodeId) => context.genie.shouldAnimateMinimizedDockEnter(nodeId)
|
|
6967
|
+
);
|
|
6704
6968
|
const dockWidth = useMemo5(
|
|
6705
6969
|
() => resolveWorkbenchHostDockItemsWidth(dockItems),
|
|
6706
6970
|
[dockItems]
|
|
@@ -6726,7 +6990,7 @@ function WorkbenchHostDock({
|
|
|
6726
6990
|
}
|
|
6727
6991
|
dockMeasureRef.current?.removeAttribute("data-dock-hover-panel-open");
|
|
6728
6992
|
}, []);
|
|
6729
|
-
|
|
6993
|
+
useEffect9(() => {
|
|
6730
6994
|
activeHoverPanelRef.current = activeHoverPanel;
|
|
6731
6995
|
}, [activeHoverPanel]);
|
|
6732
6996
|
const closeHoverPanelImmediate = useCallback10(
|
|
@@ -6857,6 +7121,7 @@ function WorkbenchHostDock({
|
|
|
6857
7121
|
hoverPanelRestTargetRef.current = null;
|
|
6858
7122
|
clearHoverPanelOpenTimer();
|
|
6859
7123
|
closeHoverPanelImmediate();
|
|
7124
|
+
pauseDockMagnification();
|
|
6860
7125
|
if (!anchorKey) {
|
|
6861
7126
|
return false;
|
|
6862
7127
|
}
|
|
@@ -6864,6 +7129,7 @@ function WorkbenchHostDock({
|
|
|
6864
7129
|
if (!slotElement) {
|
|
6865
7130
|
return false;
|
|
6866
7131
|
}
|
|
7132
|
+
clearSlotMagnification(anchorKey);
|
|
6867
7133
|
if (slotElement.dataset.collapsing === "true") {
|
|
6868
7134
|
return true;
|
|
6869
7135
|
}
|
|
@@ -6879,25 +7145,25 @@ function WorkbenchHostDock({
|
|
|
6879
7145
|
slotElement.dataset.collapsing = "true";
|
|
6880
7146
|
return true;
|
|
6881
7147
|
},
|
|
6882
|
-
[
|
|
7148
|
+
[
|
|
7149
|
+
clearHoverPanelOpenTimer,
|
|
7150
|
+
clearSlotMagnification,
|
|
7151
|
+
closeHoverPanelImmediate,
|
|
7152
|
+
pauseDockMagnification
|
|
7153
|
+
]
|
|
6883
7154
|
);
|
|
6884
7155
|
const runDockMinimizedLaunchAfterCollapse = useCallback10(
|
|
6885
7156
|
(anchorKey, launch) => {
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
const timer = setTimeout(() => {
|
|
6895
|
-
minimizedLaunchTimersRef.current.delete(anchorKey);
|
|
6896
|
-
launch();
|
|
6897
|
-
}, dockMinimizedSlotCollapseLaunchDelayMs);
|
|
6898
|
-
minimizedLaunchTimersRef.current.set(anchorKey, timer);
|
|
7157
|
+
beginDockMinimizedInteraction(anchorKey);
|
|
7158
|
+
setCollapsingMinimizedLaunchAnchorKeys((current) => {
|
|
7159
|
+
const next = new Set(current);
|
|
7160
|
+
next.add(anchorKey);
|
|
7161
|
+
return next;
|
|
7162
|
+
});
|
|
7163
|
+
scheduleCollapsingMinimizedLaunchClear(anchorKey);
|
|
7164
|
+
launch();
|
|
6899
7165
|
},
|
|
6900
|
-
[beginDockMinimizedInteraction]
|
|
7166
|
+
[beginDockMinimizedInteraction, scheduleCollapsingMinimizedLaunchClear]
|
|
6901
7167
|
);
|
|
6902
7168
|
const handleDockPointerTravel = useCallback10(
|
|
6903
7169
|
(clientX, clientY) => {
|
|
@@ -6982,7 +7248,7 @@ function WorkbenchHostDock({
|
|
|
6982
7248
|
)
|
|
6983
7249
|
)
|
|
6984
7250
|
);
|
|
6985
|
-
|
|
7251
|
+
useEffect9(() => {
|
|
6986
7252
|
const shouldSubscribe = activePopup !== null || hasMinimizedPreviewCapture;
|
|
6987
7253
|
if (!shouldSubscribe || !externalStateSource?.subscribe) {
|
|
6988
7254
|
return void 0;
|
|
@@ -6991,7 +7257,7 @@ function WorkbenchHostDock({
|
|
|
6991
7257
|
setExternalStateRevision((revision) => revision + 1);
|
|
6992
7258
|
});
|
|
6993
7259
|
}, [activePopup, externalStateSource, hasMinimizedPreviewCapture]);
|
|
6994
|
-
|
|
7260
|
+
useEffect9(() => {
|
|
6995
7261
|
const nextAttentionIds = /* @__PURE__ */ new Set();
|
|
6996
7262
|
for (const entry of renderedDockEntries) {
|
|
6997
7263
|
const nextToken = entry.attentionToken ?? null;
|
|
@@ -7032,7 +7298,7 @@ function WorkbenchHostDock({
|
|
|
7032
7298
|
);
|
|
7033
7299
|
}
|
|
7034
7300
|
}, [renderedDockEntries]);
|
|
7035
|
-
|
|
7301
|
+
useEffect9(
|
|
7036
7302
|
() => () => {
|
|
7037
7303
|
for (const timeout of attentionTimeouts.current.values()) {
|
|
7038
7304
|
globalThis.clearTimeout(timeout);
|
|
@@ -7206,6 +7472,7 @@ function WorkbenchHostDock({
|
|
|
7206
7472
|
"aria-disabled": clickResolution.kind === "blocked" && !resolvedEntry.hasMatchingNodes,
|
|
7207
7473
|
className: "desktop-dock__btn",
|
|
7208
7474
|
"data-interactive": clickResolution.kind === "blocked" && !resolvedEntry.hasMatchingNodes ? "false" : "true",
|
|
7475
|
+
title: entry.label,
|
|
7209
7476
|
type: "button",
|
|
7210
7477
|
onPointerDown: () => {
|
|
7211
7478
|
if (clickResolution.kind === "blocked" && !resolvedEntry.hasMatchingNodes) {
|
|
@@ -7352,17 +7619,7 @@ function WorkbenchHostDock({
|
|
|
7352
7619
|
closeHoverPanelImmediate(entry.id);
|
|
7353
7620
|
handleDockPointerLeave();
|
|
7354
7621
|
},
|
|
7355
|
-
children:
|
|
7356
|
-
/* @__PURE__ */ jsx10(TooltipTrigger, { asChild: true, children: dockButton2 }),
|
|
7357
|
-
/* @__PURE__ */ jsx10(
|
|
7358
|
-
TooltipContent,
|
|
7359
|
-
{
|
|
7360
|
-
side: dockPlacement === "left" ? "right" : "top",
|
|
7361
|
-
sideOffset: 26,
|
|
7362
|
-
children: entry.label
|
|
7363
|
-
}
|
|
7364
|
-
)
|
|
7365
|
-
] })
|
|
7622
|
+
children: dockButton2
|
|
7366
7623
|
},
|
|
7367
7624
|
dockItem.key
|
|
7368
7625
|
);
|
|
@@ -7378,6 +7635,7 @@ function WorkbenchHostDock({
|
|
|
7378
7635
|
"aria-label": i18n.t("minimizedWindows"),
|
|
7379
7636
|
className: "desktop-dock__btn desktop-dock__minimized-btn",
|
|
7380
7637
|
"data-interactive": "true",
|
|
7638
|
+
title: i18n.t("minimizedWindows"),
|
|
7381
7639
|
type: "button",
|
|
7382
7640
|
onPointerDown: () => {
|
|
7383
7641
|
beginDockMinimizedInteraction();
|
|
@@ -7453,17 +7711,8 @@ function WorkbenchHostDock({
|
|
|
7453
7711
|
"data-popup-active": stackPopupActive,
|
|
7454
7712
|
"data-presence": dockItem.presence,
|
|
7455
7713
|
"data-section-id": "minimized",
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
/* @__PURE__ */ jsx10(
|
|
7459
|
-
TooltipContent,
|
|
7460
|
-
{
|
|
7461
|
-
side: dockPlacement === "left" ? "right" : "top",
|
|
7462
|
-
sideOffset: 26,
|
|
7463
|
-
children: i18n.t("minimizedWindows")
|
|
7464
|
-
}
|
|
7465
|
-
)
|
|
7466
|
-
] })
|
|
7714
|
+
"data-stack-dispatching": stackDispatching ? "true" : void 0,
|
|
7715
|
+
children: stackButton
|
|
7467
7716
|
},
|
|
7468
7717
|
dockItem.key
|
|
7469
7718
|
);
|
|
@@ -7475,6 +7724,7 @@ function WorkbenchHostDock({
|
|
|
7475
7724
|
"aria-label": i18n.t("launch", { title: node.title }),
|
|
7476
7725
|
className: "desktop-dock__btn desktop-dock__minimized-btn",
|
|
7477
7726
|
"data-interactive": "true",
|
|
7727
|
+
title: node.title,
|
|
7478
7728
|
type: "button",
|
|
7479
7729
|
onPointerDown: () => {
|
|
7480
7730
|
beginDockMinimizedInteraction(slot.anchorKey);
|
|
@@ -7510,22 +7760,14 @@ function WorkbenchHostDock({
|
|
|
7510
7760
|
{
|
|
7511
7761
|
ref: registerDockSlot(slot.anchorKey),
|
|
7512
7762
|
className: "desktop-dock__slot desktop-dock__slot--minimized",
|
|
7763
|
+
"data-collapsing": collapsingMinimizedLaunchAnchorKeys.has(slot.anchorKey) ? "true" : void 0,
|
|
7513
7764
|
"data-desktop-dock-anchor-key": slot.anchorKey,
|
|
7514
7765
|
"data-desktop-dock-slot": "true",
|
|
7515
7766
|
"data-node-state": "minimized",
|
|
7516
7767
|
"data-presence": dockItem.presence,
|
|
7768
|
+
"data-promoted-from-stack": promotedNodeId === node.id ? "true" : void 0,
|
|
7517
7769
|
"data-section-id": "minimized",
|
|
7518
|
-
children:
|
|
7519
|
-
/* @__PURE__ */ jsx10(TooltipTrigger, { asChild: true, children: dockButton }),
|
|
7520
|
-
/* @__PURE__ */ jsx10(
|
|
7521
|
-
TooltipContent,
|
|
7522
|
-
{
|
|
7523
|
-
side: dockPlacement === "left" ? "right" : "top",
|
|
7524
|
-
sideOffset: 26,
|
|
7525
|
-
children: node.title
|
|
7526
|
-
}
|
|
7527
|
-
)
|
|
7528
|
-
] })
|
|
7770
|
+
children: dockButton
|
|
7529
7771
|
},
|
|
7530
7772
|
dockItem.key
|
|
7531
7773
|
);
|
|
@@ -7698,13 +7940,15 @@ function WorkbenchHostDock({
|
|
|
7698
7940
|
onCreateNew: () => void 0,
|
|
7699
7941
|
onSelectNode: (nodeId) => {
|
|
7700
7942
|
closePopup();
|
|
7701
|
-
|
|
7702
|
-
activeMinimizedStackSlot.anchorKey,
|
|
7943
|
+
const anchorKey = resolveWorkbenchMinimizedDockAnchorKeyForNode({
|
|
7703
7944
|
nodeId,
|
|
7704
|
-
|
|
7945
|
+
slots: minimizedDockSlots
|
|
7946
|
+
}) ?? activeMinimizedStackSlot.anchorKey;
|
|
7947
|
+
runDockMinimizedLaunchAfterCollapse(anchorKey, () => {
|
|
7948
|
+
context.genie.launchNodeFromAnchor(anchorKey, nodeId, () => {
|
|
7705
7949
|
host.focusNode(nodeId);
|
|
7706
|
-
}
|
|
7707
|
-
);
|
|
7950
|
+
});
|
|
7951
|
+
});
|
|
7708
7952
|
},
|
|
7709
7953
|
showCreateNew: false,
|
|
7710
7954
|
resolveDockPreviewCacheKey: (node) => resolveDockPreviewCacheKey(workspaceId, node),
|
|
@@ -7722,10 +7966,10 @@ function WorkbenchHostDockMinimizedNodePreview({
|
|
|
7722
7966
|
node,
|
|
7723
7967
|
workspaceId
|
|
7724
7968
|
}) {
|
|
7725
|
-
const [previewImageUrl, setPreviewImageUrl] =
|
|
7969
|
+
const [previewImageUrl, setPreviewImageUrl] = useState8(
|
|
7726
7970
|
() => readCachedWorkbenchNodePreviewImage(node.id)
|
|
7727
7971
|
);
|
|
7728
|
-
|
|
7972
|
+
useEffect9(() => {
|
|
7729
7973
|
let cancelled = false;
|
|
7730
7974
|
const cachedPreviewImageUrl = readCachedWorkbenchNodePreviewImage(node.id);
|
|
7731
7975
|
setPreviewImageUrl(cachedPreviewImageUrl);
|
|
@@ -7980,19 +8224,48 @@ function createWorkbenchHostDockItems({
|
|
|
7980
8224
|
}
|
|
7981
8225
|
return items;
|
|
7982
8226
|
}
|
|
7983
|
-
function
|
|
7984
|
-
|
|
8227
|
+
function resolveMinimizedDockItemNodeId(item) {
|
|
8228
|
+
if (item.kind !== "minimized" || item.slot.kind !== "node") {
|
|
8229
|
+
return null;
|
|
8230
|
+
}
|
|
8231
|
+
return item.slot.node.id;
|
|
8232
|
+
}
|
|
8233
|
+
function resolveNextDockItemPresence(item, initialized, previousPresence, shouldAnimateMinimizedDockEnter) {
|
|
8234
|
+
if (!initialized) {
|
|
8235
|
+
return "present";
|
|
8236
|
+
}
|
|
8237
|
+
if (item.key === "separator:minimized") {
|
|
8238
|
+
return "present";
|
|
8239
|
+
}
|
|
8240
|
+
if (item.kind === "minimized") {
|
|
8241
|
+
const nodeId = resolveMinimizedDockItemNodeId(item);
|
|
8242
|
+
if (nodeId && shouldAnimateMinimizedDockEnter(nodeId)) {
|
|
8243
|
+
if (previousPresence === "exiting") {
|
|
8244
|
+
return "entering";
|
|
8245
|
+
}
|
|
8246
|
+
return previousPresence ?? "entering";
|
|
8247
|
+
}
|
|
8248
|
+
return "present";
|
|
8249
|
+
}
|
|
8250
|
+
if (previousPresence === "exiting") {
|
|
8251
|
+
return "entering";
|
|
8252
|
+
}
|
|
8253
|
+
return previousPresence ?? "entering";
|
|
8254
|
+
}
|
|
8255
|
+
function useDockPresenceItems(items, shouldAnimateMinimizedDockEnter) {
|
|
8256
|
+
const latestItemsByKey = useRef8(/* @__PURE__ */ new Map());
|
|
7985
8257
|
latestItemsByKey.current = new Map(items.map((item) => [item.key, item]));
|
|
7986
8258
|
const itemKeys = items.map((item) => item.key).join("\0");
|
|
7987
|
-
const [presentItems, setPresentItems] =
|
|
8259
|
+
const [presentItems, setPresentItems] = useState8(
|
|
7988
8260
|
() => items.map((item) => ({
|
|
7989
8261
|
item,
|
|
7990
8262
|
key: item.key,
|
|
7991
8263
|
presence: "present"
|
|
7992
8264
|
}))
|
|
7993
8265
|
);
|
|
7994
|
-
const initialized =
|
|
7995
|
-
|
|
8266
|
+
const initialized = useRef8(false);
|
|
8267
|
+
useEffect9(() => {
|
|
8268
|
+
let nextSettleMs = dockPresenceAnimationMs;
|
|
7996
8269
|
setPresentItems((current) => {
|
|
7997
8270
|
const nextSourceItems = [...latestItemsByKey.current.values()];
|
|
7998
8271
|
const currentByKey = new Map(current.map((item) => [item.key, item]));
|
|
@@ -8033,7 +8306,12 @@ function useDockPresenceItems(items) {
|
|
|
8033
8306
|
nextItems.push({
|
|
8034
8307
|
item,
|
|
8035
8308
|
key: item.key,
|
|
8036
|
-
presence:
|
|
8309
|
+
presence: resolveNextDockItemPresence(
|
|
8310
|
+
item,
|
|
8311
|
+
initialized.current,
|
|
8312
|
+
currentByKey.get(item.key)?.presence,
|
|
8313
|
+
shouldAnimateMinimizedDockEnter
|
|
8314
|
+
)
|
|
8037
8315
|
});
|
|
8038
8316
|
}
|
|
8039
8317
|
for (const currentItem of current) {
|
|
@@ -8048,9 +8326,15 @@ function useDockPresenceItems(items) {
|
|
|
8048
8326
|
});
|
|
8049
8327
|
}
|
|
8050
8328
|
}
|
|
8051
|
-
|
|
8329
|
+
const filteredItems = nextItems.filter(
|
|
8052
8330
|
(item) => nextByKey.has(item.key) || item.presence === "exiting"
|
|
8053
8331
|
);
|
|
8332
|
+
if (filteredItems.some(
|
|
8333
|
+
(item) => item.item.kind === "minimized" && (item.presence === "entering" || item.presence === "exiting")
|
|
8334
|
+
)) {
|
|
8335
|
+
nextSettleMs = minimizedDockSlotLayoutAnimationMs;
|
|
8336
|
+
}
|
|
8337
|
+
return filteredItems;
|
|
8054
8338
|
});
|
|
8055
8339
|
initialized.current = true;
|
|
8056
8340
|
const timeout = globalThis.setTimeout(() => {
|
|
@@ -8059,18 +8343,17 @@ function useDockPresenceItems(items) {
|
|
|
8059
8343
|
(item) => item.presence === "entering" ? { ...item, presence: "present" } : item
|
|
8060
8344
|
)
|
|
8061
8345
|
);
|
|
8062
|
-
},
|
|
8346
|
+
}, nextSettleMs);
|
|
8063
8347
|
return () => globalThis.clearTimeout(timeout);
|
|
8064
|
-
}, [itemKeys]);
|
|
8348
|
+
}, [itemKeys, shouldAnimateMinimizedDockEnter]);
|
|
8065
8349
|
return presentItems.map((presentItem) => {
|
|
8066
8350
|
const latestItem = latestItemsByKey.current.get(presentItem.key);
|
|
8067
8351
|
return latestItem ? { ...presentItem, item: latestItem } : presentItem;
|
|
8068
8352
|
});
|
|
8069
8353
|
}
|
|
8070
8354
|
var DOCK_BOUNCE_MS = 600;
|
|
8071
|
-
var dockMinimizedSlotCollapseLaunchDelayMs = 260;
|
|
8072
8355
|
function useDockBounce(slotRefs) {
|
|
8073
|
-
const timeoutsRef =
|
|
8356
|
+
const timeoutsRef = useRef8(/* @__PURE__ */ new Map());
|
|
8074
8357
|
const clearDockBounce = useCallback10(
|
|
8075
8358
|
(anchorKey) => {
|
|
8076
8359
|
const timeout = timeoutsRef.current.get(anchorKey);
|
|
@@ -8085,7 +8368,7 @@ function useDockBounce(slotRefs) {
|
|
|
8085
8368
|
},
|
|
8086
8369
|
[slotRefs]
|
|
8087
8370
|
);
|
|
8088
|
-
|
|
8371
|
+
useEffect9(
|
|
8089
8372
|
() => () => {
|
|
8090
8373
|
for (const anchorKey of timeoutsRef.current.keys()) {
|
|
8091
8374
|
clearDockBounce(anchorKey);
|
|
@@ -8131,6 +8414,7 @@ var dockHoverPanelOpenDelayMs = 450;
|
|
|
8131
8414
|
var dockHoverPanelHitSlopPx = 12;
|
|
8132
8415
|
var dockHoverPanelPointerRestTolerancePx = 4;
|
|
8133
8416
|
var dockPresenceAnimationMs = 300;
|
|
8417
|
+
var minimizedDockSlotLayoutAnimationMs = 720;
|
|
8134
8418
|
var dockItemsGapPx = 10.8;
|
|
8135
8419
|
var dockItemsHorizontalPaddingPx = 12.6;
|
|
8136
8420
|
var dockSeparatorOuterWidthPx = 8.1;
|
|
@@ -8644,6 +8928,7 @@ export {
|
|
|
8644
8928
|
createWorkbenchSnapshotFromState,
|
|
8645
8929
|
createWorkbenchStateFromSnapshot,
|
|
8646
8930
|
createWorkbenchWindowChromeI18nRuntime,
|
|
8931
|
+
getWorkbenchLayoutFrame,
|
|
8647
8932
|
resolveWorkbenchHostPrepareClose,
|
|
8648
8933
|
useWorkbenchSelector,
|
|
8649
8934
|
workbenchFocusInputActivationType,
|