@tutti-os/workbench-surface 0.0.3 → 0.0.4

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
@@ -7016,6 +7016,23 @@ function WorkbenchHostDock({
7016
7016
  setDockHoverPanelOpen
7017
7017
  ]
7018
7018
  );
7019
+ const scheduleHoverPanelClose = useCallback10(
7020
+ (entryId) => {
7021
+ clearHoverPanelOpenTimer();
7022
+ clearHoverPanelCloseTimer();
7023
+ hoverPanelCloseTimerRef.current = setTimeout(() => {
7024
+ hoverPanelCloseTimerRef.current = null;
7025
+ closeHoverPanelImmediate(entryId);
7026
+ handleDockPointerLeave();
7027
+ }, dockHoverPanelCloseDelayMs);
7028
+ },
7029
+ [
7030
+ clearHoverPanelCloseTimer,
7031
+ clearHoverPanelOpenTimer,
7032
+ closeHoverPanelImmediate,
7033
+ handleDockPointerLeave
7034
+ ]
7035
+ );
7019
7036
  const showHoverPanel = useCallback10(
7020
7037
  (entryId, anchorKey, anchorElement) => {
7021
7038
  const dockElement = dockMeasureRef.current;
@@ -7079,6 +7096,38 @@ function WorkbenchHostDock({
7079
7096
  },
7080
7097
  []
7081
7098
  );
7099
+ const isPointerInsideActiveHoverPanelRegion = useCallback10(
7100
+ (clientX, clientY) => {
7101
+ const activeHoverPanel2 = activeHoverPanelRef.current;
7102
+ if (!activeHoverPanel2) {
7103
+ return false;
7104
+ }
7105
+ const anchorSlot = slotRefs.current.get(activeHoverPanel2.anchorKey);
7106
+ const panel = hoverPanelRef.current;
7107
+ if (!anchorSlot || !panel || !anchorSlot.isConnected || !panel.isConnected) {
7108
+ return false;
7109
+ }
7110
+ const anchorRect = anchorSlot.getBoundingClientRect();
7111
+ const panelRect = panel.getBoundingClientRect();
7112
+ return rectContainsPoint(
7113
+ anchorRect,
7114
+ clientX,
7115
+ clientY,
7116
+ dockHoverPanelHitSlopPx
7117
+ ) || rectContainsPoint(
7118
+ panelRect,
7119
+ clientX,
7120
+ clientY,
7121
+ dockHoverPanelHitSlopPx
7122
+ ) || rectContainsPoint(
7123
+ createHoverPanelBridgeRect(anchorRect, panelRect),
7124
+ clientX,
7125
+ clientY,
7126
+ dockHoverPanelBridgeSlopPx
7127
+ );
7128
+ },
7129
+ []
7130
+ );
7082
7131
  const scheduleHoverPanelAtPointAfterRest = useCallback10(
7083
7132
  (clientX, clientY) => {
7084
7133
  const scheduledPoint = hoverPanelScheduledPointRef.current;
@@ -7168,7 +7217,11 @@ function WorkbenchHostDock({
7168
7217
  const handleDockPointerTravel = useCallback10(
7169
7218
  (clientX, clientY) => {
7170
7219
  if (activeHoverPanelRef.current !== null) {
7171
- closeHoverPanelImmediate();
7220
+ if (isPointerInsideActiveHoverPanelRegion(clientX, clientY)) {
7221
+ clearHoverPanelCloseTimer();
7222
+ return;
7223
+ }
7224
+ scheduleHoverPanelClose(activeHoverPanelRef.current.entryId);
7172
7225
  handleDockPointerLeave();
7173
7226
  return;
7174
7227
  }
@@ -7176,9 +7229,11 @@ function WorkbenchHostDock({
7176
7229
  scheduleHoverPanelAtPointAfterRest(clientX, clientY);
7177
7230
  },
7178
7231
  [
7179
- closeHoverPanelImmediate,
7232
+ clearHoverPanelCloseTimer,
7180
7233
  handleDockPointerMove,
7181
7234
  handleDockPointerLeave,
7235
+ isPointerInsideActiveHoverPanelRegion,
7236
+ scheduleHoverPanelClose,
7182
7237
  scheduleHoverPanelAtPointAfterRest
7183
7238
  ]
7184
7239
  );
@@ -7814,7 +7869,7 @@ function WorkbenchHostDock({
7814
7869
  if (relatedTarget instanceof Node && anchorSlot?.contains(relatedTarget)) {
7815
7870
  return;
7816
7871
  }
7817
- closeHoverPanelImmediate(activeHoverPanel.entryId);
7872
+ scheduleHoverPanelClose(activeHoverPanel.entryId);
7818
7873
  handleDockPointerLeave();
7819
7874
  }
7820
7875
  }
@@ -8254,7 +8309,11 @@ function resolveNextDockItemPresence(item, initialized, previousPresence, should
8254
8309
  }
8255
8310
  function useDockPresenceItems(items, shouldAnimateMinimizedDockEnter) {
8256
8311
  const latestItemsByKey = useRef8(/* @__PURE__ */ new Map());
8312
+ const shouldAnimateMinimizedDockEnterRef = useRef8(
8313
+ shouldAnimateMinimizedDockEnter
8314
+ );
8257
8315
  latestItemsByKey.current = new Map(items.map((item) => [item.key, item]));
8316
+ shouldAnimateMinimizedDockEnterRef.current = shouldAnimateMinimizedDockEnter;
8258
8317
  const itemKeys = items.map((item) => item.key).join("\0");
8259
8318
  const [presentItems, setPresentItems] = useState8(
8260
8319
  () => items.map((item) => ({
@@ -8310,7 +8369,7 @@ function useDockPresenceItems(items, shouldAnimateMinimizedDockEnter) {
8310
8369
  item,
8311
8370
  initialized.current,
8312
8371
  currentByKey.get(item.key)?.presence,
8313
- shouldAnimateMinimizedDockEnter
8372
+ shouldAnimateMinimizedDockEnterRef.current
8314
8373
  )
8315
8374
  });
8316
8375
  }
@@ -8345,7 +8404,7 @@ function useDockPresenceItems(items, shouldAnimateMinimizedDockEnter) {
8345
8404
  );
8346
8405
  }, nextSettleMs);
8347
8406
  return () => globalThis.clearTimeout(timeout);
8348
- }, [itemKeys, shouldAnimateMinimizedDockEnter]);
8407
+ }, [itemKeys]);
8349
8408
  return presentItems.map((presentItem) => {
8350
8409
  const latestItem = latestItemsByKey.current.get(presentItem.key);
8351
8410
  return latestItem ? { ...presentItem, item: latestItem } : presentItem;
@@ -8411,8 +8470,27 @@ function resolveWorkbenchHostDockItemsWidth(items) {
8411
8470
  return itemWidth + gapWidth + dockItemsHorizontalPaddingPx;
8412
8471
  }
8413
8472
  var dockHoverPanelOpenDelayMs = 450;
8473
+ var dockHoverPanelCloseDelayMs = 160;
8414
8474
  var dockHoverPanelHitSlopPx = 12;
8475
+ var dockHoverPanelBridgeSlopPx = 6;
8415
8476
  var dockHoverPanelPointerRestTolerancePx = 4;
8477
+ function rectContainsPoint(rect, clientX, clientY, slopPx = 0) {
8478
+ return clientX >= rect.left - slopPx && clientX <= rect.right + slopPx && clientY >= rect.top - slopPx && clientY <= rect.bottom + slopPx;
8479
+ }
8480
+ function createHoverPanelBridgeRect(anchor, panel) {
8481
+ if (anchor.right <= panel.left || panel.right <= anchor.left) {
8482
+ const left2 = Math.min(anchor.right, panel.right);
8483
+ const right2 = Math.max(anchor.left, panel.left);
8484
+ const top2 = Math.max(anchor.top, panel.top);
8485
+ const bottom2 = Math.min(anchor.bottom, panel.bottom);
8486
+ return new DOMRect(left2, top2, right2 - left2, Math.max(0, bottom2 - top2));
8487
+ }
8488
+ const left = Math.max(anchor.left, panel.left);
8489
+ const right = Math.min(anchor.right, panel.right);
8490
+ const top = Math.min(anchor.bottom, panel.bottom);
8491
+ const bottom = Math.max(anchor.top, panel.top);
8492
+ return new DOMRect(left, top, Math.max(0, right - left), bottom - top);
8493
+ }
8416
8494
  var dockPresenceAnimationMs = 300;
8417
8495
  var minimizedDockSlotLayoutAnimationMs = 720;
8418
8496
  var dockItemsGapPx = 10.8;