@tutti-os/workbench-surface 0.0.17 → 0.0.18

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.js CHANGED
@@ -1708,9 +1708,16 @@ function WorkbenchDockFrame({
1708
1708
  const nodes = useWorkbenchSelector(
1709
1709
  selectDockNodes
1710
1710
  );
1711
+ const minimizedNodesWithPending = useMemo2(
1712
+ () => mergePendingMinimizedDockNode(
1713
+ nodes.filter((node) => node.isMinimized),
1714
+ genie.pendingMinimizedNode
1715
+ ),
1716
+ [genie.pendingMinimizedNode, nodes]
1717
+ );
1711
1718
  const minimizedNodes = useMemo2(
1712
- () => nodes.filter((node) => node.isMinimized),
1713
- [nodes]
1719
+ () => minimizedNodesWithPending.filter((node) => node.isMinimized),
1720
+ [minimizedNodesWithPending]
1714
1721
  );
1715
1722
  const focusedNodeId = useWorkbenchSelector(
1716
1723
  (state) => selectFocusedWorkbenchNode(state)?.id ?? null
@@ -1752,6 +1759,9 @@ function WorkbenchDockFrame({
1752
1759
  },
1753
1760
  shouldAnimateMinimizedDockEnter: (nodeID) => {
1754
1761
  return genie.shouldAnimateMinimizedDockEnter(nodeID);
1762
+ },
1763
+ isPendingMinimizedDockNode: (nodeID) => {
1764
+ return genie.isPendingMinimizedDockNode(nodeID);
1755
1765
  }
1756
1766
  },
1757
1767
  minimizedNodes,
@@ -1761,6 +1771,16 @@ function WorkbenchDockFrame({
1761
1771
  )
1762
1772
  ] });
1763
1773
  }
1774
+ function mergePendingMinimizedDockNode(nodes, pendingNode) {
1775
+ if (!pendingNode) {
1776
+ return nodes;
1777
+ }
1778
+ const existingNode = nodes.find((node) => node.id === pendingNode.id);
1779
+ if (existingNode?.isMinimized) {
1780
+ return nodes;
1781
+ }
1782
+ return [...nodes.filter((node) => node.id !== pendingNode.id), pendingNode];
1783
+ }
1764
1784
 
1765
1785
  // src/react/WorkbenchNodeLayer.tsx
1766
1786
  import { memo, useMemo as useMemo3 } from "react";
@@ -2635,6 +2655,7 @@ function renderGenieScanlines(context, viewportWidth, viewportHeight, frame) {
2635
2655
  // src/react/useWorkbenchGenieAnimation.tsx
2636
2656
  import { jsx as jsx7 } from "react/jsx-runtime";
2637
2657
  var genieDurationMs = 400;
2658
+ var scaleMinimizeDurationMs = 220;
2638
2659
  var genieMaxDevicePixelRatio = 2;
2639
2660
  var genieSnapshotScale = 1;
2640
2661
  var minimizedDockSlotEnterAnimationMs = 720;
@@ -2864,20 +2885,16 @@ async function captureWorkbenchNodePreviewImage(nodeID, options = {}) {
2864
2885
  writeCachedWorkbenchNodePreviewImage(nodeID, previewImageUrl);
2865
2886
  return previewImageUrl;
2866
2887
  }
2867
- async function captureWorkbenchNodePreviewImageForNode(node, input = {}) {
2888
+ async function captureProvidedWorkbenchNodePreviewImageForNode(node, input = {}) {
2868
2889
  const previewImageUrl = await Promise.resolve(
2869
2890
  input.captureNodePreviewImage?.(node) ?? null
2870
2891
  ).catch(() => null);
2871
- if (previewImageUrl) {
2872
- writeCachedWorkbenchNodePreviewImage(node.id, previewImageUrl);
2873
- persistWorkbenchNodePreviewImage(node, previewImageUrl, input);
2874
- return previewImageUrl;
2892
+ if (!previewImageUrl) {
2893
+ return null;
2875
2894
  }
2876
- const capturedPreviewImageUrl = await captureWorkbenchNodePreviewImage(
2877
- node.id
2878
- );
2879
- persistWorkbenchNodePreviewImage(node, capturedPreviewImageUrl, input);
2880
- return capturedPreviewImageUrl;
2895
+ writeCachedWorkbenchNodePreviewImage(node.id, previewImageUrl);
2896
+ persistWorkbenchNodePreviewImage(node, previewImageUrl, input);
2897
+ return previewImageUrl;
2881
2898
  }
2882
2899
  function persistWorkbenchNodePreviewImage(node, previewImageUrl, input) {
2883
2900
  if (!previewImageUrl || !input.dockPreviewCache) {
@@ -2917,8 +2934,10 @@ function useWorkbenchGenieAnimation({
2917
2934
  captureNodePreviewImage,
2918
2935
  controller,
2919
2936
  dockPreviewCache,
2937
+ minimizeAnimation = "scale",
2920
2938
  resolveDockAnchorKey,
2921
- resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2
2939
+ resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2,
2940
+ shouldCaptureNodePreviewImage
2922
2941
  }) {
2923
2942
  const dockAnchorElementsRef = useRef4(/* @__PURE__ */ new Map());
2924
2943
  const canvasRef = useRef4(null);
@@ -2933,6 +2952,7 @@ function useWorkbenchGenieAnimation({
2933
2952
  const [genieHiddenNodeIDs, setGenieHiddenNodeIDs] = useState4(
2934
2953
  () => /* @__PURE__ */ new Set()
2935
2954
  );
2955
+ const [pendingMinimizedNode, setPendingMinimizedNode] = useState4(null);
2936
2956
  const registerDockAnchor = useCallback6(
2937
2957
  (anchorKey, element) => {
2938
2958
  if (element) {
@@ -3008,6 +3028,11 @@ function useWorkbenchGenieAnimation({
3008
3028
  return next;
3009
3029
  });
3010
3030
  }, []);
3031
+ const clearPendingMinimizedNode = useCallback6((nodeID) => {
3032
+ setPendingMinimizedNode(
3033
+ (current) => current?.id === nodeID ? null : current
3034
+ );
3035
+ }, []);
3011
3036
  const setupCanvas = useCallback6(() => {
3012
3037
  const canvas = canvasRef.current;
3013
3038
  if (!canvas) {
@@ -3120,10 +3145,102 @@ function useWorkbenchGenieAnimation({
3120
3145
  },
3121
3146
  [setupCanvas, stopAnimation]
3122
3147
  );
3148
+ const runScaleWindowAnimation = useCallback6(
3149
+ ({
3150
+ direction,
3151
+ dockRect,
3152
+ nodeElement,
3153
+ onCancel,
3154
+ onComplete,
3155
+ skipStop
3156
+ }) => {
3157
+ if (!skipStop) {
3158
+ stopAnimation();
3159
+ }
3160
+ const windowRect = viewportRectFromElement(nodeElement);
3161
+ if (!isUsableGenieRect(windowRect) || !isUsableGenieRect(dockRect)) {
3162
+ onComplete();
3163
+ return;
3164
+ }
3165
+ const generation = animationGenerationRef.current;
3166
+ const fromCenter = centerPointFromRect(windowRect);
3167
+ const toCenter = centerPointFromRect(dockRect);
3168
+ const targetScale = Math.max(
3169
+ 0.04,
3170
+ Math.min(
3171
+ 0.32,
3172
+ dockRect.width / Math.max(1, windowRect.width),
3173
+ dockRect.height / Math.max(1, windowRect.height)
3174
+ )
3175
+ );
3176
+ const previousPointerEvents = nodeElement.style.pointerEvents;
3177
+ const previousTransformOrigin = nodeElement.style.transformOrigin;
3178
+ const previousVisibility = nodeElement.style.visibility;
3179
+ const previousZIndex = nodeElement.style.zIndex;
3180
+ nodeElement.style.pointerEvents = "none";
3181
+ nodeElement.style.transformOrigin = "center center";
3182
+ nodeElement.style.visibility = "visible";
3183
+ nodeElement.style.zIndex = "var(--z-workbench-genie)";
3184
+ const dockTransform = `translate3d(${toCenter.x - fromCenter.x}px, ${toCenter.y - fromCenter.y}px, 0) scale(${targetScale})`;
3185
+ const windowTransform = "translate3d(0, 0, 0) scale(1)";
3186
+ const keyframes = direction === "open" ? [
3187
+ {
3188
+ opacity: 0,
3189
+ transform: dockTransform
3190
+ },
3191
+ {
3192
+ opacity: 1,
3193
+ transform: windowTransform
3194
+ }
3195
+ ] : [
3196
+ {
3197
+ opacity: 1,
3198
+ transform: windowTransform
3199
+ },
3200
+ {
3201
+ opacity: 0,
3202
+ transform: dockTransform
3203
+ }
3204
+ ];
3205
+ const animation = nodeElement.animate(keyframes, {
3206
+ duration: scaleMinimizeDurationMs,
3207
+ easing: "cubic-bezier(0.4, 0, 0.2, 1)",
3208
+ fill: "forwards"
3209
+ });
3210
+ const restoreElement = () => {
3211
+ animation.cancel();
3212
+ nodeElement.style.pointerEvents = previousPointerEvents;
3213
+ nodeElement.style.transformOrigin = previousTransformOrigin;
3214
+ nodeElement.style.visibility = previousVisibility;
3215
+ nodeElement.style.zIndex = previousZIndex;
3216
+ };
3217
+ animationCleanupRef.current = () => {
3218
+ restoreElement();
3219
+ onCancel();
3220
+ };
3221
+ animation.finished.then(() => {
3222
+ if (generation !== animationGenerationRef.current) {
3223
+ return;
3224
+ }
3225
+ animationCleanupRef.current = null;
3226
+ restoreElement();
3227
+ onComplete();
3228
+ }).catch(() => {
3229
+ if (generation !== animationGenerationRef.current) {
3230
+ return;
3231
+ }
3232
+ animationCleanupRef.current = null;
3233
+ restoreElement();
3234
+ onComplete();
3235
+ });
3236
+ },
3237
+ [stopAnimation]
3238
+ );
3123
3239
  useEffect3(() => () => stopAnimation(false), [stopAnimation]);
3124
3240
  const startOpenOrRestoreAnimation = useCallback6(
3125
3241
  async (nodeID, anchorKey, generation, dockRectFallback) => {
3126
- if (shouldReduceMotion()) {
3242
+ const effectiveMinimizeAnimation = shouldReduceMotion() ? "off" : minimizeAnimation;
3243
+ if (effectiveMinimizeAnimation === "off") {
3127
3244
  animationCleanupRef.current = null;
3128
3245
  showNodeForGenie(nodeID);
3129
3246
  return;
@@ -3135,6 +3252,32 @@ function useWorkbenchGenieAnimation({
3135
3252
  const resolvedDockRect = resolveDockAnchorRect(anchorKey);
3136
3253
  const dockRect = resolvedDockRect && isUsableGenieRect(resolvedDockRect) ? resolvedDockRect : dockRectFallback;
3137
3254
  const nodeElement = resolveNodeElement(nodeID);
3255
+ if (effectiveMinimizeAnimation === "scale") {
3256
+ if (!dockRect || !nodeElement || !isUsableGenieRect(dockRect)) {
3257
+ animationCleanupRef.current = null;
3258
+ showNodeForGenie(nodeID);
3259
+ return;
3260
+ }
3261
+ flushSync(() => {
3262
+ showNodeForGenie(nodeID);
3263
+ });
3264
+ runScaleWindowAnimation({
3265
+ direction: "open",
3266
+ dockRect,
3267
+ nodeElement,
3268
+ onCancel: () => {
3269
+ flushSync(() => {
3270
+ showNodeForGenie(nodeID);
3271
+ });
3272
+ },
3273
+ onComplete: () => {
3274
+ flushSync(() => {
3275
+ showNodeForGenie(nodeID);
3276
+ });
3277
+ }
3278
+ });
3279
+ return;
3280
+ }
3138
3281
  const captureTarget = nodeElement ? resolveWorkbenchCaptureElement(nodeElement) : null;
3139
3282
  if (!dockRect || !nodeElement || !captureTarget || !isUsableGenieRect(dockRect)) {
3140
3283
  animationCleanupRef.current = null;
@@ -3173,9 +3316,11 @@ function useWorkbenchGenieAnimation({
3173
3316
  },
3174
3317
  [
3175
3318
  clearCanvas,
3319
+ minimizeAnimation,
3176
3320
  resolveDockAnchorRect,
3177
3321
  resolveNodeElement,
3178
3322
  runGenieAnimation,
3323
+ runScaleWindowAnimation,
3179
3324
  showNodeForGenie
3180
3325
  ]
3181
3326
  );
@@ -3192,6 +3337,16 @@ function useWorkbenchGenieAnimation({
3192
3337
  });
3193
3338
  return;
3194
3339
  }
3340
+ const effectiveMinimizeAnimation = shouldReduceMotion() ? "off" : minimizeAnimation;
3341
+ if (effectiveMinimizeAnimation === "off") {
3342
+ stopAnimation();
3343
+ flushSync(() => {
3344
+ showNodeForGenie(nodeID);
3345
+ });
3346
+ void Promise.resolve(launch()).catch(() => {
3347
+ });
3348
+ return;
3349
+ }
3195
3350
  stopAnimation();
3196
3351
  const dockRectFallback = resolveDockAnchorRect(anchorKey);
3197
3352
  hideNodeForGenie(nodeID);
@@ -3216,6 +3371,7 @@ function useWorkbenchGenieAnimation({
3216
3371
  clearCanvas,
3217
3372
  controller,
3218
3373
  hideNodeForGenie,
3374
+ minimizeAnimation,
3219
3375
  resolveDockAnchorRect,
3220
3376
  showNodeForGenie,
3221
3377
  startOpenOrRestoreAnimation,
@@ -3230,23 +3386,137 @@ function useWorkbenchGenieAnimation({
3230
3386
  return;
3231
3387
  }
3232
3388
  const runMinimize = minimize ?? (() => controller.commands.minimizeNode(nodeID));
3233
- if (shouldReduceMotion()) {
3234
- const wasFocusedForCapture2 = isFocusedWorkbenchNode(
3235
- controller,
3236
- nodeID
3237
- );
3238
- if (!wasFocusedForCapture2) {
3389
+ const effectiveMinimizeAnimation = shouldReduceMotion() ? "off" : minimizeAnimation;
3390
+ const shouldCapturePreview = shouldCaptureNodePreviewImage?.(target) ?? true;
3391
+ if (effectiveMinimizeAnimation === "off") {
3392
+ stopAnimation();
3393
+ let frameID = null;
3394
+ let timerID = null;
3395
+ let minimizeCommitted2 = false;
3396
+ const commitMinimize2 = () => {
3397
+ if (minimizeCommitted2) {
3398
+ return;
3399
+ }
3400
+ minimizeCommitted2 = true;
3401
+ if (frameID !== null) {
3402
+ window.cancelAnimationFrame(frameID);
3403
+ frameID = null;
3404
+ }
3405
+ if (timerID !== null) {
3406
+ clearTimeout(timerID);
3407
+ timerID = null;
3408
+ }
3409
+ animationCleanupRef.current = null;
3410
+ flushSync(() => {
3411
+ clearPendingMinimizedNode(nodeID);
3412
+ showNodeForGenie(nodeID);
3413
+ runMinimize();
3414
+ });
3415
+ scheduleReleaseMinimizedDockEnterAnimation(nodeID);
3416
+ };
3417
+ animationCleanupRef.current = () => {
3418
+ releaseMinimizedDockEnterAnimation(nodeID);
3419
+ commitMinimize2();
3420
+ };
3421
+ registerMinimizedDockEnterAnimation(nodeID);
3422
+ flushSync(() => {
3423
+ hideNodeForGenie(nodeID);
3424
+ setPendingMinimizedNode({
3425
+ ...target,
3426
+ isMinimized: true,
3427
+ minimizedAtUnixMs: Date.now()
3428
+ });
3429
+ });
3430
+ if (shouldCapturePreview) {
3431
+ void captureProvidedWorkbenchNodePreviewImageForNode(target, {
3432
+ captureNodePreviewImage,
3433
+ dockPreviewCache,
3434
+ resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2
3435
+ });
3436
+ }
3437
+ frameID = window.requestAnimationFrame(() => {
3438
+ frameID = null;
3439
+ timerID = setTimeout(commitMinimize2, 0);
3440
+ });
3441
+ return;
3442
+ }
3443
+ if (effectiveMinimizeAnimation === "scale") {
3444
+ stopAnimation();
3445
+ const generation2 = animationGenerationRef.current;
3446
+ const nodeElement2 = resolveNodeElement(nodeID);
3447
+ if (!nodeElement2) {
3448
+ runMinimize();
3449
+ return;
3450
+ }
3451
+ const wasFocusedForCapture2 = shouldCapturePreview && isFocusedWorkbenchNode(controller, nodeID);
3452
+ if (shouldCapturePreview && !wasFocusedForCapture2) {
3239
3453
  flushSync(() => {
3240
3454
  controller.commands.focusNode(nodeID);
3241
3455
  });
3242
3456
  await waitForNextAnimationFrame();
3457
+ if (generation2 !== animationGenerationRef.current) {
3458
+ return;
3459
+ }
3243
3460
  }
3244
- await captureWorkbenchNodePreviewImageForNode(target, {
3245
- captureNodePreviewImage,
3246
- dockPreviewCache,
3247
- resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2
3461
+ if (shouldCapturePreview) {
3462
+ void captureProvidedWorkbenchNodePreviewImageForNode(target, {
3463
+ captureNodePreviewImage,
3464
+ dockPreviewCache,
3465
+ resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2
3466
+ });
3467
+ }
3468
+ let minimizeCommitted2 = false;
3469
+ const commitMinimize2 = () => {
3470
+ if (minimizeCommitted2) {
3471
+ return;
3472
+ }
3473
+ minimizeCommitted2 = true;
3474
+ runMinimize();
3475
+ };
3476
+ const cleanupPendingMinimize = () => {
3477
+ releaseMinimizedDockEnterAnimation(nodeID);
3478
+ flushSync(() => {
3479
+ clearPendingMinimizedNode(nodeID);
3480
+ commitMinimize2();
3481
+ });
3482
+ };
3483
+ const pendingMinimizedNode3 = {
3484
+ ...target,
3485
+ isMinimized: true,
3486
+ minimizedAtUnixMs: Date.now()
3487
+ };
3488
+ registerMinimizedDockEnterAnimation(nodeID);
3489
+ flushSync(() => {
3490
+ setPendingMinimizedNode(pendingMinimizedNode3);
3491
+ });
3492
+ animationCleanupRef.current = cleanupPendingMinimize;
3493
+ await waitForNextAnimationFrame();
3494
+ if (generation2 !== animationGenerationRef.current) {
3495
+ return;
3496
+ }
3497
+ const anchorKey2 = resolveAnchorKeyForNode(pendingMinimizedNode3);
3498
+ const dockRect2 = resolveDockAnchorRect(anchorKey2);
3499
+ if (!nodeElement2.isConnected || !dockRect2 || !isUsableGenieRect(dockRect2)) {
3500
+ cleanupPendingMinimize();
3501
+ return;
3502
+ }
3503
+ runScaleWindowAnimation({
3504
+ direction: "minimize",
3505
+ dockRect: dockRect2,
3506
+ nodeElement: nodeElement2,
3507
+ onCancel: () => {
3508
+ cleanupPendingMinimize();
3509
+ },
3510
+ onComplete: () => {
3511
+ animationCleanupRef.current = null;
3512
+ flushSync(() => {
3513
+ clearPendingMinimizedNode(nodeID);
3514
+ commitMinimize2();
3515
+ });
3516
+ scheduleReleaseMinimizedDockEnterAnimation(nodeID);
3517
+ },
3518
+ skipStop: true
3248
3519
  });
3249
- runMinimize();
3250
3520
  return;
3251
3521
  }
3252
3522
  stopAnimation();
@@ -3309,46 +3579,57 @@ function useWorkbenchGenieAnimation({
3309
3579
  resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2
3310
3580
  });
3311
3581
  }
3312
- const cleanupHiddenNode = () => {
3582
+ let minimizeCommitted = false;
3583
+ const commitMinimize = () => {
3584
+ if (minimizeCommitted) {
3585
+ return;
3586
+ }
3587
+ minimizeCommitted = true;
3588
+ runMinimize();
3589
+ };
3590
+ const pendingMinimizedNode2 = {
3591
+ ...target,
3592
+ isMinimized: true,
3593
+ minimizedAtUnixMs: Date.now()
3594
+ };
3595
+ const cleanupPendingGenieMinimize = () => {
3596
+ releaseMinimizedDockEnterAnimation(nodeID);
3313
3597
  flushSync(() => {
3598
+ clearPendingMinimizedNode(nodeID);
3314
3599
  showNodeForGenie(nodeID);
3600
+ commitMinimize();
3315
3601
  });
3316
3602
  clearCanvas();
3317
3603
  };
3318
- animationCleanupRef.current = cleanupHiddenNode;
3604
+ animationCleanupRef.current = cleanupPendingGenieMinimize;
3319
3605
  registerMinimizedDockEnterAnimation(nodeID);
3320
3606
  flushSync(() => {
3607
+ setPendingMinimizedNode(pendingMinimizedNode2);
3321
3608
  hideNodeForGenie(nodeID);
3322
- runMinimize();
3323
3609
  });
3324
3610
  await waitForNextAnimationFrame();
3325
3611
  if (generation !== animationGenerationRef.current) {
3326
- releaseMinimizedDockEnterAnimation(nodeID);
3327
3612
  return;
3328
3613
  }
3329
- const minimizedTarget = controller.getSnapshot().nodes.find((node) => node.id === nodeID) ?? target;
3330
- const anchorKey = resolveAnchorKeyForNode(minimizedTarget);
3614
+ const anchorKey = resolveAnchorKeyForNode(pendingMinimizedNode2);
3331
3615
  const dockRect = resolveDockAnchorRect(anchorKey);
3332
3616
  if (!dockRect || !isUsableGenieRect(dockRect)) {
3333
- releaseMinimizedDockEnterAnimation(nodeID);
3334
3617
  animationCleanupRef.current = null;
3335
- cleanupHiddenNode();
3618
+ cleanupPendingGenieMinimize();
3336
3619
  return;
3337
3620
  }
3338
3621
  runGenieAnimation({
3339
3622
  direction: "minimize",
3340
3623
  dockRect,
3341
3624
  onCancel: () => {
3342
- releaseMinimizedDockEnterAnimation(nodeID);
3343
- flushSync(() => {
3344
- showNodeForGenie(nodeID);
3345
- });
3346
- clearCanvas();
3625
+ cleanupPendingGenieMinimize();
3347
3626
  },
3348
3627
  onComplete: () => {
3349
3628
  scheduleReleaseMinimizedDockEnterAnimation(nodeID);
3350
3629
  flushSync(() => {
3630
+ clearPendingMinimizedNode(nodeID);
3351
3631
  showNodeForGenie(nodeID);
3632
+ commitMinimize();
3352
3633
  });
3353
3634
  clearCanvas();
3354
3635
  },
@@ -3361,8 +3642,10 @@ function useWorkbenchGenieAnimation({
3361
3642
  clearCanvas,
3362
3643
  controller,
3363
3644
  captureNodePreviewImage,
3645
+ clearPendingMinimizedNode,
3364
3646
  dockPreviewCache,
3365
3647
  hideNodeForGenie,
3648
+ minimizeAnimation,
3366
3649
  registerMinimizedDockEnterAnimation,
3367
3650
  releaseMinimizedDockEnterAnimation,
3368
3651
  resolveAnchorKeyForNode,
@@ -3370,7 +3653,9 @@ function useWorkbenchGenieAnimation({
3370
3653
  resolveDockAnchorRect,
3371
3654
  resolveNodeElement,
3372
3655
  runGenieAnimation,
3656
+ runScaleWindowAnimation,
3373
3657
  scheduleReleaseMinimizedDockEnterAnimation,
3658
+ shouldCaptureNodePreviewImage,
3374
3659
  setupCanvas,
3375
3660
  showNodeForGenie,
3376
3661
  stopAnimation
@@ -3403,8 +3688,13 @@ function useWorkbenchGenieAnimation({
3403
3688
  (nodeID) => genieHiddenNodeIDs.has(nodeID),
3404
3689
  [genieHiddenNodeIDs]
3405
3690
  ),
3691
+ isPendingMinimizedDockNode: useCallback6(
3692
+ (nodeID) => pendingMinimizedNode?.id === nodeID,
3693
+ [pendingMinimizedNode]
3694
+ ),
3406
3695
  launchNodeFromAnchor,
3407
3696
  minimizeNodeToAnchor,
3697
+ pendingMinimizedNode,
3408
3698
  registerDockAnchor,
3409
3699
  shouldAnimateMinimizedDockEnter
3410
3700
  };
@@ -3421,6 +3711,7 @@ function WorkbenchSurface({
3421
3711
  interactive,
3422
3712
  layoutConstraints,
3423
3713
  missionControlPhase,
3714
+ minimizeAnimation,
3424
3715
  presentation,
3425
3716
  renderBackdrop,
3426
3717
  renderBottomChrome,
@@ -3435,6 +3726,7 @@ function WorkbenchSurface({
3435
3726
  resolveDockAnchorKey,
3436
3727
  resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2,
3437
3728
  shortcutsEnabled,
3729
+ shouldCaptureNodePreviewImage,
3438
3730
  wallpaper,
3439
3731
  windowChromeMode,
3440
3732
  windowChromeI18n
@@ -3449,6 +3741,7 @@ function WorkbenchSurface({
3449
3741
  interactive,
3450
3742
  layoutConstraints,
3451
3743
  missionControlPhase,
3744
+ minimizeAnimation,
3452
3745
  presentation,
3453
3746
  renderBackdrop,
3454
3747
  renderBottomChrome,
@@ -3463,6 +3756,7 @@ function WorkbenchSurface({
3463
3756
  resolveDockAnchorKey,
3464
3757
  resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2,
3465
3758
  shortcutsEnabled,
3759
+ shouldCaptureNodePreviewImage,
3466
3760
  wallpaper,
3467
3761
  windowChromeMode,
3468
3762
  windowChromeI18n
@@ -3477,6 +3771,7 @@ function WorkbenchSurfaceInner({
3477
3771
  interactive = true,
3478
3772
  layoutConstraints,
3479
3773
  missionControlPhase,
3774
+ minimizeAnimation,
3480
3775
  presentation,
3481
3776
  renderBackdrop,
3482
3777
  renderBottomChrome,
@@ -3491,6 +3786,7 @@ function WorkbenchSurfaceInner({
3491
3786
  resolveDockAnchorKey,
3492
3787
  resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2,
3493
3788
  shortcutsEnabled,
3789
+ shouldCaptureNodePreviewImage,
3494
3790
  wallpaper,
3495
3791
  windowChromeMode,
3496
3792
  windowChromeI18n
@@ -3507,8 +3803,10 @@ function WorkbenchSurfaceInner({
3507
3803
  captureNodePreviewImage,
3508
3804
  controller,
3509
3805
  dockPreviewCache,
3806
+ minimizeAnimation,
3510
3807
  resolveDockAnchorKey,
3511
- resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2
3808
+ resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2,
3809
+ shouldCaptureNodePreviewImage
3512
3810
  });
3513
3811
  useWorkbenchShortcuts((shortcutsEnabled ?? true) && interactive);
3514
3812
  useEffect4(() => {
@@ -4769,6 +5067,11 @@ var WorkbenchHostSessionController = class {
4769
5067
  this.restoreAndFocusNode(nodeId);
4770
5068
  });
4771
5069
  }
5070
+ minimizeNode(nodeId) {
5071
+ this.runWhenReady(this.loadGeneration, () => {
5072
+ this.controller.commands.minimizeNode(nodeId);
5073
+ });
5074
+ }
4772
5075
  exitFullscreenNode(nodeId) {
4773
5076
  this.runWhenReady(this.loadGeneration, () => {
4774
5077
  this.controller.commands.exitFullscreen(nodeId);
@@ -6244,7 +6547,7 @@ function resolveWorkbenchMinimizedDockAnchorKeyForNode(input) {
6244
6547
  }
6245
6548
  function isWorkbenchMinimizedDockEligibleNode(input) {
6246
6549
  const definition = input.nodeDefinitions.get(input.node.data.typeId);
6247
- return definition?.window?.minimizedDock?.kind === "snapshot";
6550
+ return definition?.window?.minimizedDock !== void 0;
6248
6551
  }
6249
6552
  function orderWorkbenchMinimizedDockNodes(input) {
6250
6553
  return input.nodes.map((node, index) => ({ index, node })).filter(
@@ -7452,6 +7755,7 @@ function WorkbenchHostDock({
7452
7755
  /* @__PURE__ */ new Map()
7453
7756
  );
7454
7757
  const previousAttentionTokenByEntryId = useRef8(/* @__PURE__ */ new Map());
7758
+ const dockEntryClickThrottleUntilRef = useRef8(/* @__PURE__ */ new Map());
7455
7759
  const attentionTimeouts = useRef8(
7456
7760
  /* @__PURE__ */ new Map()
7457
7761
  );
@@ -7626,9 +7930,9 @@ function WorkbenchHostDock({
7626
7930
  const minimizedDockSlots = useMemo5(
7627
7931
  () => resolveWorkbenchMinimizedDockSlots({
7628
7932
  nodeDefinitions,
7629
- nodes: context.nodes
7933
+ nodes: context.minimizedNodes
7630
7934
  }),
7631
- [context.nodes, nodeDefinitions]
7935
+ [context.minimizedNodes, nodeDefinitions]
7632
7936
  );
7633
7937
  const { promotedNodeId, stackDispatching } = useMinimizedDockStackPromotion(minimizedDockSlots);
7634
7938
  const dockItems = useMemo5(
@@ -7999,6 +8303,19 @@ function WorkbenchHostDock({
7999
8303
  triggerDockBounce
8000
8304
  ]
8001
8305
  );
8306
+ const isDockEntryClickThrottled = useCallback10(
8307
+ (anchorKey) => {
8308
+ const throttledUntil = dockEntryClickThrottleUntilRef.current.get(anchorKey);
8309
+ return throttledUntil !== void 0 && Date.now() < throttledUntil;
8310
+ },
8311
+ []
8312
+ );
8313
+ const claimDockEntryClick = useCallback10((anchorKey) => {
8314
+ dockEntryClickThrottleUntilRef.current.set(
8315
+ anchorKey,
8316
+ Date.now() + DOCK_ENTRY_CLICK_THROTTLE_MS
8317
+ );
8318
+ }, []);
8002
8319
  const beginDockMinimizedInteraction = useCallback10(
8003
8320
  (anchorKey) => {
8004
8321
  hoverPanelRestTargetRef.current = null;
@@ -8156,9 +8473,13 @@ function WorkbenchHostDock({
8156
8473
  }, [dockPlacement, presentDockItems.length, updateDockScrollState]);
8157
8474
  const hasMinimizedPreviewCapture = minimizedDockSlots.some(
8158
8475
  (slot) => minimizedDockSlotNodes(slot).some(
8159
- (node) => Boolean(
8160
- nodeDefinitions.get(node.data.typeId)?.window?.minimizedDock?.capturePreview
8161
- )
8476
+ (node) => (() => {
8477
+ if (context.genie.isPendingMinimizedDockNode(node.id)) {
8478
+ return false;
8479
+ }
8480
+ const minimizedDock = nodeDefinitions.get(node.data.typeId)?.window?.minimizedDock;
8481
+ return minimizedDock?.kind === "snapshot" && Boolean(minimizedDock.capturePreview);
8482
+ })()
8162
8483
  )
8163
8484
  );
8164
8485
  useEffect9(() => {
@@ -8222,7 +8543,8 @@ function WorkbenchHostDock({
8222
8543
  );
8223
8544
  const captureMinimizedNodePreview = useCallback10(
8224
8545
  async (node) => {
8225
- const capturePreview = nodeDefinitions.get(node.data.typeId)?.window?.minimizedDock?.capturePreview;
8546
+ const minimizedDock = nodeDefinitions.get(node.data.typeId)?.window?.minimizedDock;
8547
+ const capturePreview = minimizedDock?.kind === "snapshot" ? minimizedDock.capturePreview : void 0;
8226
8548
  const externalState = readWorkbenchHostExternalState({
8227
8549
  externalStateSource,
8228
8550
  node,
@@ -8250,6 +8572,41 @@ function WorkbenchHostDock({
8250
8572
  workspaceId
8251
8573
  ]
8252
8574
  );
8575
+ const provideMinimizedNodePreview = useCallback10(
8576
+ (node) => {
8577
+ const minimizedDock = nodeDefinitions.get(node.data.typeId)?.window?.minimizedDock;
8578
+ if (minimizedDock?.kind !== "component") {
8579
+ return null;
8580
+ }
8581
+ const externalState = readWorkbenchHostExternalState({
8582
+ externalStateSource,
8583
+ node,
8584
+ workspaceId
8585
+ });
8586
+ return minimizedDock.providePreview({
8587
+ externalNodeState: externalState.externalNodeState,
8588
+ externalWorkspaceState: externalState.externalWorkspaceState,
8589
+ host,
8590
+ isFocused: context.focusedNodeId === node.id,
8591
+ isMinimized: node.isMinimized,
8592
+ node
8593
+ });
8594
+ },
8595
+ [
8596
+ context.focusedNodeId,
8597
+ externalStateSource,
8598
+ host,
8599
+ nodeDefinitions,
8600
+ workspaceId
8601
+ ]
8602
+ );
8603
+ const provideMinimizedNodePreviewForNode = useCallback10(
8604
+ (node) => {
8605
+ const minimizedDock = nodeDefinitions.get(node.data.typeId)?.window?.minimizedDock;
8606
+ return minimizedDock?.kind === "component" ? provideMinimizedNodePreview : void 0;
8607
+ },
8608
+ [nodeDefinitions, provideMinimizedNodePreview]
8609
+ );
8253
8610
  if (dockItems.length === 0 && presentDockItems.length === 0) {
8254
8611
  return null;
8255
8612
  }
@@ -8413,9 +8770,19 @@ function WorkbenchHostDock({
8413
8770
  if (clickResolution.kind === "blocked") {
8414
8771
  return;
8415
8772
  }
8773
+ if (isDockEntryClickThrottled(anchorKey)) {
8774
+ return;
8775
+ }
8416
8776
  beginDockIconInteraction(anchorKey);
8417
8777
  },
8418
8778
  onClick: (event) => {
8779
+ if (clickResolution.kind === "blocked") {
8780
+ return;
8781
+ }
8782
+ if (isDockEntryClickThrottled(anchorKey)) {
8783
+ return;
8784
+ }
8785
+ claimDockEntryClick(anchorKey);
8419
8786
  logWorkbenchDockDebug("dock.click", debugDiagnostics, {
8420
8787
  anchorKey,
8421
8788
  clickResolution,
@@ -8509,8 +8876,6 @@ function WorkbenchHostDock({
8509
8876
  })
8510
8877
  );
8511
8878
  return;
8512
- case "blocked":
8513
- return;
8514
8879
  }
8515
8880
  },
8516
8881
  children: /* @__PURE__ */ jsxs6(
@@ -8683,9 +9048,12 @@ function WorkbenchHostDock({
8683
9048
  className: `desktop-dock__minimized-stack-layer desktop-dock__minimized-stack-layer--${index}`,
8684
9049
  dockPreviewCache,
8685
9050
  node: node2,
9051
+ providePreview: provideMinimizedNodePreviewForNode(
9052
+ node2
9053
+ ),
8686
9054
  workspaceId
8687
9055
  },
8688
- node2.id
9056
+ minimizedDockPreviewFreezeKey(node2)
8689
9057
  );
8690
9058
  }
8691
9059
  return /* @__PURE__ */ jsx10(
@@ -8753,6 +9121,7 @@ function WorkbenchHostDock({
8753
9121
  );
8754
9122
  }
8755
9123
  const node = slot.node;
9124
+ const isPendingMinimizedNode = context.genie.isPendingMinimizedDockNode(node.id);
8756
9125
  const labelTooltipTarget = dockLabelTooltipTarget(
8757
9126
  `minimized-node:${node.id}`,
8758
9127
  node.title
@@ -8763,8 +9132,12 @@ function WorkbenchHostDock({
8763
9132
  "aria-label": i18n.t("launch", { title: node.title }),
8764
9133
  className: "desktop-dock__btn desktop-dock__minimized-btn",
8765
9134
  "data-interactive": "true",
9135
+ disabled: isPendingMinimizedNode,
8766
9136
  type: "button",
8767
9137
  onPointerDown: () => {
9138
+ if (isPendingMinimizedNode) {
9139
+ return;
9140
+ }
8768
9141
  const restoreIntent = resolveWorkbenchMinimizedDockRestoreIntent({
8769
9142
  nodeId: node.id,
8770
9143
  slots: minimizedDockSlots,
@@ -8780,6 +9153,9 @@ function WorkbenchHostDock({
8780
9153
  beginDockMinimizedInteraction();
8781
9154
  },
8782
9155
  onClick: () => {
9156
+ if (isPendingMinimizedNode) {
9157
+ return;
9158
+ }
8783
9159
  const restoreIntent = resolveWorkbenchMinimizedDockRestoreIntent({
8784
9160
  nodeId: node.id,
8785
9161
  slots: minimizedDockSlots,
@@ -8809,11 +9185,14 @@ function WorkbenchHostDock({
8809
9185
  children: /* @__PURE__ */ jsx10(
8810
9186
  WorkbenchHostDockMinimizedNodePreview,
8811
9187
  {
8812
- capturePreview: captureMinimizedNodePreview,
8813
- dockPreviewCache,
9188
+ capturePreview: isPendingMinimizedNode ? void 0 : captureMinimizedNodePreview,
9189
+ deferPreview: isPendingMinimizedNode,
9190
+ dockPreviewCache: isPendingMinimizedNode ? void 0 : dockPreviewCache,
8814
9191
  node,
9192
+ providePreview: isPendingMinimizedNode ? void 0 : provideMinimizedNodePreviewForNode(node),
8815
9193
  workspaceId
8816
- }
9194
+ },
9195
+ minimizedDockPreviewFreezeKey(node)
8817
9196
  )
8818
9197
  }
8819
9198
  );
@@ -8828,6 +9207,7 @@ function WorkbenchHostDock({
8828
9207
  "data-dock-label-tooltip-key": labelTooltipTarget.key,
8829
9208
  "data-dock-label-tooltip-label": labelTooltipTarget.label,
8830
9209
  "data-node-state": "minimized",
9210
+ "data-pending-minimize": isPendingMinimizedNode ? "true" : void 0,
8831
9211
  "data-presence": dockItem.presence,
8832
9212
  "data-promoted-from-stack": promotedNodeId === node.id ? "true" : void 0,
8833
9213
  "data-section-id": "minimized",
@@ -9055,6 +9435,7 @@ function WorkbenchHostDock({
9055
9435
  node,
9056
9436
  workspaceId
9057
9437
  });
9438
+ const minimizedDock = nodeDefinitions.get(node.data.typeId)?.window?.minimizedDock;
9058
9439
  return {
9059
9440
  externalNodeState: externalState.externalNodeState,
9060
9441
  externalWorkspaceState: externalState.externalWorkspaceState,
@@ -9062,10 +9443,8 @@ function WorkbenchHostDock({
9062
9443
  isFocused: context.focusedNodeId === node.id,
9063
9444
  isMinimized: true,
9064
9445
  node,
9065
- preview: nodeDefinitions.get(node.data.typeId)?.window?.minimizedDock?.capturePreview ? null : (() => {
9066
- const previewImageUrl = readCachedWorkbenchNodePreviewImage(
9067
- node.id
9068
- );
9446
+ preview: minimizedDock?.kind === "component" ? provideMinimizedNodePreview(node) ?? null : minimizedDock?.kind === "snapshot" && minimizedDock.capturePreview ? null : (() => {
9447
+ const previewImageUrl = readCachedWorkbenchNodePreviewImage(node.id);
9069
9448
  return previewImageUrl ? { kind: "image", src: previewImageUrl } : null;
9070
9449
  })(),
9071
9450
  previewRevision: null,
@@ -9133,14 +9512,69 @@ function WorkbenchHostDock({
9133
9512
  function WorkbenchHostDockMinimizedNodePreview({
9134
9513
  capturePreview,
9135
9514
  className,
9515
+ deferPreview = false,
9136
9516
  dockPreviewCache,
9137
9517
  node,
9518
+ providePreview,
9138
9519
  workspaceId
9139
9520
  }) {
9521
+ const [componentPreview, setComponentPreview] = useState8(void 0);
9140
9522
  const [previewImageUrl, setPreviewImageUrl] = useState8(
9141
- () => readCachedWorkbenchNodePreviewImage(node.id)
9523
+ () => deferPreview || providePreview ? null : readCachedWorkbenchNodePreviewImage(node.id)
9142
9524
  );
9143
9525
  useEffect9(() => {
9526
+ if (deferPreview || !providePreview || componentPreview !== void 0) {
9527
+ return void 0;
9528
+ }
9529
+ let cancelled = false;
9530
+ let frameId = null;
9531
+ let idleId = null;
9532
+ let timeoutId = null;
9533
+ const setDeferredComponentPreview = () => {
9534
+ if (cancelled) {
9535
+ return;
9536
+ }
9537
+ setComponentPreview(providePreview(node) ?? null);
9538
+ };
9539
+ const scheduler = globalThis;
9540
+ if (typeof scheduler.requestIdleCallback === "function") {
9541
+ idleId = scheduler.requestIdleCallback(setDeferredComponentPreview, {
9542
+ timeout: 250
9543
+ });
9544
+ } else if (typeof scheduler.requestAnimationFrame === "function") {
9545
+ frameId = scheduler.requestAnimationFrame(() => {
9546
+ frameId = null;
9547
+ timeoutId = globalThis.setTimeout(setDeferredComponentPreview, 0);
9548
+ });
9549
+ } else {
9550
+ timeoutId = globalThis.setTimeout(setDeferredComponentPreview, 0);
9551
+ }
9552
+ return () => {
9553
+ cancelled = true;
9554
+ if (idleId !== null && typeof scheduler.cancelIdleCallback === "function") {
9555
+ scheduler.cancelIdleCallback(idleId);
9556
+ }
9557
+ if (frameId !== null && typeof scheduler.cancelAnimationFrame === "function") {
9558
+ scheduler.cancelAnimationFrame(frameId);
9559
+ }
9560
+ if (timeoutId !== null) {
9561
+ globalThis.clearTimeout(timeoutId);
9562
+ }
9563
+ };
9564
+ }, [
9565
+ componentPreview,
9566
+ deferPreview,
9567
+ node.data.instanceId,
9568
+ node.data.instanceKey,
9569
+ node.data.typeId,
9570
+ node.id,
9571
+ node.minimizedAtUnixMs,
9572
+ providePreview
9573
+ ]);
9574
+ useEffect9(() => {
9575
+ if (deferPreview || providePreview) {
9576
+ return void 0;
9577
+ }
9144
9578
  let cancelled = false;
9145
9579
  const cachedPreviewImageUrl = readCachedWorkbenchNodePreviewImage(node.id);
9146
9580
  setPreviewImageUrl(cachedPreviewImageUrl);
@@ -9182,14 +9616,22 @@ function WorkbenchHostDockMinimizedNodePreview({
9182
9616
  };
9183
9617
  }, [
9184
9618
  capturePreview,
9619
+ deferPreview,
9185
9620
  dockPreviewCache,
9186
9621
  node.data.instanceId,
9187
9622
  node.data.instanceKey,
9188
9623
  node.data.typeId,
9189
9624
  node.id,
9190
9625
  node.minimizedAtUnixMs,
9626
+ providePreview,
9191
9627
  workspaceId
9192
9628
  ]);
9629
+ if (deferPreview) {
9630
+ return renderMinimizedDockPreviewPlaceholder(className);
9631
+ }
9632
+ if (componentPreview) {
9633
+ return renderMinimizedDockPreviewContent(componentPreview, className);
9634
+ }
9193
9635
  if (previewImageUrl) {
9194
9636
  return /* @__PURE__ */ jsx10(
9195
9637
  "span",
@@ -9212,6 +9654,9 @@ function WorkbenchHostDockMinimizedNodePreview({
9212
9654
  }
9213
9655
  );
9214
9656
  }
9657
+ return renderMinimizedDockPreviewPlaceholder(className);
9658
+ }
9659
+ function renderMinimizedDockPreviewPlaceholder(className) {
9215
9660
  return /* @__PURE__ */ jsxs6(
9216
9661
  "span",
9217
9662
  {
@@ -9225,6 +9670,78 @@ function WorkbenchHostDockMinimizedNodePreview({
9225
9670
  }
9226
9671
  );
9227
9672
  }
9673
+ function renderMinimizedDockPreviewContent(preview, className) {
9674
+ if (preview.kind === "image") {
9675
+ return /* @__PURE__ */ jsx10(
9676
+ "span",
9677
+ {
9678
+ className: [
9679
+ "desktop-dock__minimized-preview",
9680
+ "desktop-dock__minimized-preview--snapshot",
9681
+ className
9682
+ ].filter(Boolean).join(" "),
9683
+ "aria-hidden": "true",
9684
+ children: /* @__PURE__ */ jsx10(
9685
+ "img",
9686
+ {
9687
+ alt: "",
9688
+ className: "desktop-dock__minimized-preview-image",
9689
+ draggable: false,
9690
+ src: preview.src
9691
+ }
9692
+ )
9693
+ }
9694
+ );
9695
+ }
9696
+ return /* @__PURE__ */ jsx10(
9697
+ WorkbenchHostDockFrozenComponentPreview,
9698
+ {
9699
+ className,
9700
+ preview
9701
+ }
9702
+ );
9703
+ }
9704
+ function WorkbenchHostDockFrozenComponentPreview({
9705
+ className,
9706
+ preview
9707
+ }) {
9708
+ const sourceRef = useRef8(null);
9709
+ const [frozenMarkup, setFrozenMarkup] = useState8(null);
9710
+ useLayoutEffect5(() => {
9711
+ if (frozenMarkup !== null) {
9712
+ return;
9713
+ }
9714
+ setFrozenMarkup(sourceRef.current?.innerHTML ?? "");
9715
+ }, [frozenMarkup]);
9716
+ return /* @__PURE__ */ jsx10(
9717
+ "span",
9718
+ {
9719
+ className: [
9720
+ "desktop-dock__minimized-preview",
9721
+ "desktop-dock__minimized-preview--component",
9722
+ className
9723
+ ].filter(Boolean).join(" "),
9724
+ "aria-hidden": "true",
9725
+ children: frozenMarkup === null ? /* @__PURE__ */ jsx10(
9726
+ "span",
9727
+ {
9728
+ ref: sourceRef,
9729
+ className: "desktop-dock__minimized-preview-freeze-source",
9730
+ children: preview.element
9731
+ }
9732
+ ) : /* @__PURE__ */ jsx10(
9733
+ "span",
9734
+ {
9735
+ className: "desktop-dock__minimized-preview-frozen-content",
9736
+ dangerouslySetInnerHTML: { __html: frozenMarkup }
9737
+ }
9738
+ )
9739
+ }
9740
+ );
9741
+ }
9742
+ function minimizedDockPreviewFreezeKey(node) {
9743
+ return `${node.id}:${node.minimizedAtUnixMs ?? "pending"}`;
9744
+ }
9228
9745
  function dockEntryHasHoverPanel(entry) {
9229
9746
  return Boolean(entry.state?.reason?.trim()) || (entry.hoverActions?.length ?? 0) > 0;
9230
9747
  }
@@ -9838,6 +10355,7 @@ function dockWallpaperToneMapsEqual(left, right) {
9838
10355
  return true;
9839
10356
  }
9840
10357
  var DOCK_BOUNCE_MS = 600;
10358
+ var DOCK_ENTRY_CLICK_THROTTLE_MS = DOCK_BOUNCE_MS;
9841
10359
  function useDockBounce(slotRefs) {
9842
10360
  const timeoutsRef = useRef8(/* @__PURE__ */ new Map());
9843
10361
  const clearDockBounce = useCallback10(
@@ -10140,7 +10658,8 @@ function useWorkbenchHostSurfaceRenderers(input) {
10140
10658
  const captureNodePreviewImage = useCallback11(
10141
10659
  async (node) => {
10142
10660
  const definition = input.nodeDefinitionByType.get(node.data.typeId);
10143
- const capturePreview = definition?.window?.minimizedDock?.capturePreview;
10661
+ const minimizedDock = definition?.window?.minimizedDock;
10662
+ const capturePreview = minimizedDock?.kind === "snapshot" ? minimizedDock.capturePreview : void 0;
10144
10663
  const snapshot = input.hostSession.getSnapshot();
10145
10664
  const externalState = readWorkbenchHostExternalState({
10146
10665
  externalStateSource: input.externalStateSource,
@@ -10305,17 +10824,30 @@ function useWorkbenchHostSurfaceRenderers(input) {
10305
10824
  },
10306
10825
  [input.nodeDefinitionByType]
10307
10826
  );
10827
+ const shouldCaptureNodePreviewImage = useCallback11(
10828
+ (node) => {
10829
+ const minimizedDock = input.nodeDefinitionByType.get(node.data.typeId)?.window?.minimizedDock;
10830
+ return minimizedDock?.kind !== "component";
10831
+ },
10832
+ [input.nodeDefinitionByType]
10833
+ );
10308
10834
  const resolveDockAnchorKey = useCallback11(
10309
10835
  (node) => {
10310
10836
  if (node.isMinimized && isWorkbenchMinimizedDockEligibleNode({
10311
10837
  node,
10312
10838
  nodeDefinitions: input.nodeDefinitionByType
10313
10839
  })) {
10840
+ const snapshotNodes = input.hostSession.getSnapshot().nodes;
10841
+ const slotNodes = snapshotNodes.some(
10842
+ (snapshotNode) => snapshotNode.id === node.id
10843
+ ) ? snapshotNodes.map(
10844
+ (snapshotNode) => snapshotNode.id === node.id ? node : snapshotNode
10845
+ ) : [...snapshotNodes, node];
10314
10846
  const minimizedAnchorKey = resolveWorkbenchMinimizedDockAnchorKeyForNode({
10315
10847
  nodeId: node.id,
10316
10848
  slots: resolveWorkbenchMinimizedDockSlots({
10317
10849
  nodeDefinitions: input.nodeDefinitionByType,
10318
- nodes: input.hostSession.getSnapshot().nodes
10850
+ nodes: slotNodes
10319
10851
  })
10320
10852
  });
10321
10853
  if (minimizedAnchorKey) {
@@ -10358,6 +10890,7 @@ function useWorkbenchHostSurfaceRenderers(input) {
10358
10890
  renderTopChrome,
10359
10891
  renderWindowActions,
10360
10892
  renderWindowHeader,
10893
+ shouldCaptureNodePreviewImage,
10361
10894
  shouldKeepMinimizedNodeMounted,
10362
10895
  resolveDockAnchorKey,
10363
10896
  resolveDockPreviewCacheKey: resolveDockPreviewCacheKey2,
@@ -10537,6 +11070,7 @@ function WorkbenchHost({
10537
11070
  i18n,
10538
11071
  layoutConstraints,
10539
11072
  missionControl,
11073
+ minimizeAnimation,
10540
11074
  nodes,
10541
11075
  onDockEntryAction,
10542
11076
  onDockEntryClick,
@@ -10639,6 +11173,7 @@ function WorkbenchHost({
10639
11173
  interactive: !isHydrating,
10640
11174
  layoutConstraints,
10641
11175
  missionControlPhase: missionControlPresence.phase,
11176
+ minimizeAnimation,
10642
11177
  presentation: missionControlState?.presentation ?? null,
10643
11178
  renderBackdrop: missionControlRenderedState ? () => /* @__PURE__ */ jsx13(
10644
11179
  WorkbenchMissionControlBackdrop,
@@ -10666,6 +11201,7 @@ function WorkbenchHost({
10666
11201
  resolveFullscreenHeaderMode: surfaceRenderers.resolveFullscreenHeaderMode,
10667
11202
  resolveDockAnchorKey: surfaceRenderers.resolveDockAnchorKey,
10668
11203
  shortcutsEnabled,
11204
+ shouldCaptureNodePreviewImage: surfaceRenderers.shouldCaptureNodePreviewImage,
10669
11205
  wallpaper,
10670
11206
  windowChromeI18n,
10671
11207
  windowChromeMode: surfaceRenderers.windowChromeMode