@omerdlw/base-framework 2.0.1 → 3.0.1

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.
Files changed (104) hide show
  1. package/README.md +4 -1
  2. package/dist/{chunk-XASQT4CQ.js → chunk-66EYJBIP.js} +47 -27
  3. package/dist/chunk-66EYJBIP.js.map +1 -0
  4. package/dist/{chunk-6SG7V77J.js → chunk-HHWRTQKQ.js} +100 -67
  5. package/dist/chunk-HHWRTQKQ.js.map +1 -0
  6. package/dist/chunk-HLL5EHXC.js +485 -0
  7. package/dist/chunk-HLL5EHXC.js.map +1 -0
  8. package/dist/{chunk-6ZJVLUBE.js → chunk-I5GK7VOV.js} +8 -6
  9. package/dist/chunk-I5GK7VOV.js.map +1 -0
  10. package/dist/chunk-RIOKLMYM.js +145 -0
  11. package/dist/chunk-RIOKLMYM.js.map +1 -0
  12. package/dist/{chunk-SKBITB5X.js → chunk-RRAZKP3J.js} +3 -3
  13. package/dist/{chunk-SKBITB5X.js.map → chunk-RRAZKP3J.js.map} +1 -1
  14. package/dist/{chunk-QXR55VVS.js → chunk-TG6NMHXI.js} +241 -162
  15. package/dist/chunk-TG6NMHXI.js.map +1 -0
  16. package/dist/{chunk-A5RE3F6O.js → chunk-WVRMABDN.js} +249 -427
  17. package/dist/chunk-WVRMABDN.js.map +1 -0
  18. package/dist/index.js +7 -5
  19. package/dist/modules/ambient/analyze.d.ts +18 -3
  20. package/dist/modules/ambient/analyze.d.ts.map +1 -1
  21. package/dist/modules/ambient/dom.d.ts +14 -1
  22. package/dist/modules/ambient/dom.d.ts.map +1 -1
  23. package/dist/modules/ambient/hooks.d.ts.map +1 -1
  24. package/dist/modules/ambient/index.d.ts +2 -2
  25. package/dist/modules/ambient/index.d.ts.map +1 -1
  26. package/dist/modules/ambient/index.js +1 -1
  27. package/dist/modules/ambient/server/index.d.ts +1 -1
  28. package/dist/modules/ambient/server/index.d.ts.map +1 -1
  29. package/dist/modules/ambient/server/index.js +2 -2
  30. package/dist/modules/ambient/server/index.js.map +1 -1
  31. package/dist/modules/ambient/settings.d.ts +1 -0
  32. package/dist/modules/ambient/settings.d.ts.map +1 -1
  33. package/dist/modules/ambient/types.d.ts +13 -0
  34. package/dist/modules/ambient/types.d.ts.map +1 -1
  35. package/dist/modules/ambient/worker/index.js +1 -1
  36. package/dist/modules/context-menu/index.js +4 -3
  37. package/dist/modules/dock/cards.d.ts.map +1 -1
  38. package/dist/modules/dock/constants.d.ts +1 -35
  39. package/dist/modules/dock/constants.d.ts.map +1 -1
  40. package/dist/modules/dock/index.js +3 -2
  41. package/dist/modules/dock/motion.d.ts +7 -5
  42. package/dist/modules/dock/motion.d.ts.map +1 -1
  43. package/dist/modules/dock/overlay.d.ts.map +1 -1
  44. package/dist/modules/dock/routing/guards.d.ts +1 -1
  45. package/dist/modules/dock/routing/navigation.d.ts +7 -4
  46. package/dist/modules/dock/routing/navigation.d.ts.map +1 -1
  47. package/dist/modules/dock/runtime/display.d.ts +31 -2
  48. package/dist/modules/dock/runtime/display.d.ts.map +1 -1
  49. package/dist/modules/dock/runtime/dock.d.ts +2 -3
  50. package/dist/modules/dock/runtime/dock.d.ts.map +1 -1
  51. package/dist/modules/dock/runtime/pipeline.d.ts.map +1 -1
  52. package/dist/modules/dock/styles.d.ts +1 -1
  53. package/dist/modules/dock/styles.d.ts.map +1 -1
  54. package/dist/modules/dock/surface/hooks.d.ts.map +1 -1
  55. package/dist/modules/dock/surface/stack.d.ts.map +1 -1
  56. package/dist/modules/dock/types.d.ts +88 -43
  57. package/dist/modules/dock/types.d.ts.map +1 -1
  58. package/dist/modules/index.d.ts +3 -2
  59. package/dist/modules/index.d.ts.map +1 -1
  60. package/dist/modules/index.js +7 -5
  61. package/dist/modules/loading/context.d.ts.map +1 -1
  62. package/dist/modules/loading/index.js +1 -1
  63. package/dist/modules/navigation/constants.d.ts +37 -0
  64. package/dist/modules/navigation/constants.d.ts.map +1 -0
  65. package/dist/modules/navigation/context.d.ts +10 -0
  66. package/dist/modules/navigation/context.d.ts.map +1 -0
  67. package/dist/modules/navigation/hooks.d.ts +29 -0
  68. package/dist/modules/navigation/hooks.d.ts.map +1 -0
  69. package/dist/modules/navigation/index.d.ts +10 -0
  70. package/dist/modules/navigation/index.d.ts.map +1 -0
  71. package/dist/modules/navigation/index.js +81 -0
  72. package/dist/modules/navigation/index.js.map +1 -0
  73. package/dist/modules/navigation/listeners.d.ts +15 -0
  74. package/dist/modules/navigation/listeners.d.ts.map +1 -0
  75. package/dist/modules/navigation/module.d.ts +25 -0
  76. package/dist/modules/navigation/module.d.ts.map +1 -0
  77. package/dist/modules/navigation/navigator.d.ts +8 -0
  78. package/dist/modules/navigation/navigator.d.ts.map +1 -0
  79. package/dist/modules/navigation/settings.d.ts +10 -0
  80. package/dist/modules/navigation/settings.d.ts.map +1 -0
  81. package/dist/modules/navigation/state.d.ts +20 -0
  82. package/dist/modules/navigation/state.d.ts.map +1 -0
  83. package/dist/modules/navigation/types.d.ts +168 -0
  84. package/dist/modules/navigation/types.d.ts.map +1 -0
  85. package/dist/modules/navigation/utils.d.ts +11 -0
  86. package/dist/modules/navigation/utils.d.ts.map +1 -0
  87. package/docs/getting-started.md +2 -0
  88. package/docs/modules/README.md +5 -1
  89. package/docs/modules/ambient.md +9 -6
  90. package/docs/modules/dock.md +31 -13
  91. package/docs/modules/loading.md +2 -2
  92. package/docs/modules/navigation.md +216 -0
  93. package/docs/proposals/navigation.md +209 -0
  94. package/docs/theming.md +1 -1
  95. package/package.json +6 -1
  96. package/templates/AGENTS.md +2 -0
  97. package/templates/motion/dock.ts +83 -15
  98. package/dist/chunk-6SG7V77J.js.map +0 -1
  99. package/dist/chunk-6ZJVLUBE.js.map +0 -1
  100. package/dist/chunk-A5RE3F6O.js.map +0 -1
  101. package/dist/chunk-QXR55VVS.js.map +0 -1
  102. package/dist/chunk-XASQT4CQ.js.map +0 -1
  103. package/dist/modules/dock/routing/transactions.d.ts +0 -21
  104. package/dist/modules/dock/routing/transactions.d.ts.map +0 -1
@@ -1,9 +1,10 @@
1
+ import { NAVIGATION_STATUS, createNavigator } from './chunk-HLL5EHXC.js';
1
2
  import { Z_INDEX } from './chunk-QI3ALLIB.js';
2
3
  import { useNotificationVisible } from './chunk-SYAVGTOX.js';
3
4
  import { useOptionalMediaState, useOptionalMediaActions } from './chunk-R2YGFJDJ.js';
4
- import { useOptionalLoadingActions, useOptionalLoadingState } from './chunk-XASQT4CQ.js';
5
+ import { useOptionalLoadingActions, useOptionalLoadingState } from './chunk-66EYJBIP.js';
5
6
  import { defineThemeSpec, useModuleMotion, useTheme, cssTransition, staggerDelay, gpuTransform, useOptionalModuleMotion } from './chunk-7TAVYJ3A.js';
6
- import { getOrCreateGlobalContext, defineModule, useRegistryEntries, useModuleRegistration } from './chunk-GF7TUX5I.js';
7
+ import { getOrCreateGlobalContext, defineModule, useModule, useRegistryEntries, useModuleRegistration } from './chunk-GF7TUX5I.js';
7
8
  import { createStore, cn, isImageIconSource, clamp, useIsomorphicLayoutEffect, isObject, isPlainObject, trimToNull, shallowEqual, useGlobalEvent, useRequiredContext, globalEvents, toArray, useIsFullscreenStateActive, useClickOutside, report, normalizePath, useStore, createScheduler, EVENT_TYPES, toUserMessage } from './chunk-TV3WEF5G.js';
8
9
  import { Tooltip, Icon, Button, Spinner } from './chunk-3BUP64Q6.js';
9
10
  import React, { createContext, memo, createElement, isValidElement, cloneElement, Suspense, useEffect, useState, useCallback, useMemo, use, useSyncExternalStore, useRef, useLayoutEffect, useReducer, lazy, useContext, useId } from 'react';
@@ -409,54 +410,21 @@ var DOCK_SURFACE_PHASE = Object.freeze({
409
410
  });
410
411
  var VIEWPORT_MARGIN = 24;
411
412
  var DOCK_CARD_DIMENSIONS = Object.freeze({
412
- expandedY: -72,
413
413
  chromeHeight: 20,
414
- collapsedY: -10,
415
- extensionShelfY: -42,
416
- extensionShelfScale: 0.94,
417
414
  extensionShelfHeight: 45,
418
415
  hudHeight: 52,
419
416
  actionGap: 10,
420
417
  height: 68
421
418
  });
422
419
  var DOCK_CARD_LAYOUT = Object.freeze({
423
- collapsed: Object.freeze({
424
- offsetY: DOCK_CARD_DIMENSIONS.collapsedY,
425
- scale: 0.88
426
- }),
427
- expanded: Object.freeze({
428
- offsetY: DOCK_CARD_DIMENSIONS.expandedY,
429
- scale: 1
430
- }),
431
- extensionShelfY: DOCK_CARD_DIMENSIONS.extensionShelfY,
432
- extensionShelfScale: DOCK_CARD_DIMENSIONS.extensionShelfScale,
433
420
  extensionShelfHeight: DOCK_CARD_DIMENSIONS.extensionShelfHeight,
434
421
  chromeHeight: DOCK_CARD_DIMENSIONS.chromeHeight,
435
422
  hudHeight: DOCK_CARD_DIMENSIONS.hudHeight,
436
423
  actionGap: DOCK_CARD_DIMENSIONS.actionGap,
437
424
  baseHeight: DOCK_CARD_DIMENSIONS.height
438
425
  });
439
- var DOCK_TRANSACTION_EVENTS = Object.freeze({
440
- START: "START",
441
- COMPLETE: "COMPLETE",
442
- CANCEL: "CANCEL",
443
- FAIL: "FAIL",
444
- TIME_OUT: "TIME_OUT"
445
- });
446
- var DOCK_TRANSACTION_STATUS = Object.freeze({
447
- PENDING: "pending",
448
- COMPLETED: "completed",
449
- CANCELLED: "cancelled",
450
- FAILED: "failed",
451
- TIMED_OUT: "timed-out"
452
- });
453
- var DOCK_TRANSACTION_REASON = Object.freeze({
454
- GUARD: "guard",
455
- SUPERSEDED: "superseded",
456
- TIME_OUT: "time-out"
457
- });
458
- var DOCK_TRANSACTION_TIMEOUT_MS = 15e3;
459
426
  var DOCK_PREFETCH_INTENT_DELAY_MS = 90;
427
+ var DOCK_PENDING_ROUTE_HOLD_MS = 2500;
460
428
  var DOCK_CONTINUITY_EVENTS = Object.freeze({
461
429
  CLEAR: "CLEAR",
462
430
  CONSUME_RETURN: "CONSUME_RETURN",
@@ -517,7 +485,6 @@ var STATUS_CLEAR_DURATION = 4500;
517
485
  var API_ERROR_BATCH_DELAY = 300;
518
486
  var DOCK_HEIGHT_BUFFER = 16;
519
487
  var HEIGHT_EPSILON = 0.5;
520
- var MAX_VISIBLE_STACKED_CARDS = 3;
521
488
  var dockTheme = defineThemeSpec("dock");
522
489
  var DockContext = getOrCreateGlobalContext(
523
490
  "DockContext",
@@ -1616,10 +1583,6 @@ var DOCK_SURFACE_DRAG_CONSTRAINTS = Object.freeze({
1616
1583
  top: 0,
1617
1584
  bottom: 0
1618
1585
  });
1619
- var DOCK_SURFACE_DRAG_THRESHOLDS = Object.freeze({
1620
- DISMISS_OFFSET_Y: 65,
1621
- DISMISS_VELOCITY_Y: 400
1622
- });
1623
1586
  function toGpuTransform(y = 0, scale = 1, x = 0) {
1624
1587
  return gpuTransform(y, scale, x);
1625
1588
  }
@@ -1655,42 +1618,37 @@ function getDockMediaVolumeThumbAnimateProps(motion2, { isDragging = false } = {
1655
1618
  function getDockMediaVolumeThumbPositionTransition(motion2, { isDragging = false } = {}) {
1656
1619
  return isDragging ? "none" : cssTransition("left", motion2.transitions.mediaVolume);
1657
1620
  }
1658
- function getDockSurfaceStackScale(motion2, surfacePhase) {
1659
- if (surfacePhase === DOCK_SURFACE_PHASE.DISMISSING_ACTION) {
1660
- return motion2.deck.compress.open;
1661
- }
1662
- if (surfacePhase === DOCK_SURFACE_PHASE.CLOSING_ANTICIPATION) {
1663
- return motion2.deck.compress.close;
1664
- }
1665
- return 1;
1621
+ var SURFACE_PHASE_KEYS = Object.freeze({
1622
+ [DOCK_SURFACE_PHASE.IDLE]: "idle",
1623
+ [DOCK_SURFACE_PHASE.DISMISSING_ACTION]: "dismissAction",
1624
+ [DOCK_SURFACE_PHASE.EXPANDING_BODY]: "expandBody",
1625
+ [DOCK_SURFACE_PHASE.OPEN]: "open",
1626
+ [DOCK_SURFACE_PHASE.CLOSING_ANTICIPATION]: "anticipation",
1627
+ [DOCK_SURFACE_PHASE.COLLAPSING_BODY]: "collapseBody",
1628
+ [DOCK_SURFACE_PHASE.RESTORING_HEADER]: "restoreHeader"
1629
+ });
1630
+ function getDockPhaseMotion(motion2, surfacePhase) {
1631
+ const key = surfacePhase && SURFACE_PHASE_KEYS[surfacePhase] || "idle";
1632
+ return motion2.phases[key];
1666
1633
  }
1667
1634
  function getDockStackTransformTransition(motion2, surfacePhase, fallbackTransition) {
1668
- if (surfacePhase === DOCK_SURFACE_PHASE.EXPANDING_BODY) {
1669
- return motion2.transitions.surfaceArrival;
1670
- }
1671
- if (surfacePhase === DOCK_SURFACE_PHASE.DISMISSING_ACTION || surfacePhase === DOCK_SURFACE_PHASE.CLOSING_ANTICIPATION) {
1672
- return motion2.transitions.anticipation;
1673
- }
1674
- return fallbackTransition;
1635
+ return getDockPhaseMotion(motion2, surfacePhase).transform ?? fallbackTransition;
1675
1636
  }
1676
1637
  function getDockStackTransition(motion2, {
1677
1638
  expanded = false,
1678
1639
  resizeDistance = 0,
1679
1640
  surfacePhase = null
1680
1641
  } = {}) {
1681
- if (surfacePhase === DOCK_SURFACE_PHASE.EXPANDING_BODY) {
1682
- return motion2.transitions.expand;
1683
- }
1684
- if (surfacePhase === DOCK_SURFACE_PHASE.OPEN || surfacePhase === DOCK_SURFACE_PHASE.CLOSING_ANTICIPATION) {
1685
- return motion2.transitions.surfaceResize(
1686
- resizeDistance > 0 ? resizeDistance : 260
1687
- );
1688
- }
1689
- if (surfacePhase === DOCK_SURFACE_PHASE.COLLAPSING_BODY || surfacePhase === DOCK_SURFACE_PHASE.RESTORING_HEADER) {
1690
- return motion2.transitions.expand;
1642
+ const { deck } = getDockPhaseMotion(motion2, surfacePhase);
1643
+ if (typeof deck === "function") {
1644
+ return deck(resizeDistance > 0 ? resizeDistance : motion2.deck.resizeFallback);
1691
1645
  }
1646
+ if (deck) return deck;
1692
1647
  return expanded ? motion2.transitions.expand : motion2.transitions.stack;
1693
1648
  }
1649
+ function getDockLayoutTransition(motion2) {
1650
+ return { layout: motion2.transitions.layout };
1651
+ }
1694
1652
  function getDockStackAnimateProps(motion2, {
1695
1653
  width,
1696
1654
  height,
@@ -1701,7 +1659,7 @@ function getDockStackAnimateProps(motion2, {
1701
1659
  }) {
1702
1660
  const safeWidth = Number(width);
1703
1661
  const safeHeight = Number(height);
1704
- const liftAmount = isBreadcrumbsVisible ? -44 : 0;
1662
+ const liftAmount = isBreadcrumbsVisible ? motion2.deck.breadcrumbOffset : 0;
1705
1663
  return {
1706
1664
  width: Math.max(0, Math.round(Number.isFinite(safeWidth) ? safeWidth : 0)),
1707
1665
  height: Math.max(
@@ -1710,9 +1668,9 @@ function getDockStackAnimateProps(motion2, {
1710
1668
  ),
1711
1669
  transform: toGpuTransform(
1712
1670
  liftAmount,
1713
- getDockSurfaceStackScale(motion2, surfacePhase)
1671
+ getDockPhaseMotion(motion2, surfacePhase).scale
1714
1672
  ),
1715
- opacity: isFullscreen ? 0 : 1,
1673
+ opacity: isFullscreen ? motion2.deck.fullscreenOpacity : 1,
1716
1674
  boxShadow: isSurfaceActive ? motion2.deck.elevation.elevated : motion2.deck.elevation.rest,
1717
1675
  pointerEvents: isFullscreen ? "none" : "auto"
1718
1676
  };
@@ -1777,7 +1735,7 @@ function getDockItemExitValues(motion2, {
1777
1735
  return motion2.deck.exit({
1778
1736
  position: safePosition,
1779
1737
  scale: motionValues && Number.isFinite(motionValues.scale) ? motionValues.scale : null,
1780
- y: motionValues && Number.isFinite(motionValues.y) ? motionValues.y : safePosition * DOCK_CARD_DIMENSIONS.collapsedY
1738
+ y: motionValues && Number.isFinite(motionValues.y) ? motionValues.y : safePosition * motion2.deck.stacking.collapsed.offsetY
1781
1739
  });
1782
1740
  }
1783
1741
  function getDockCardContentAnimateProps(motion2, {
@@ -2221,7 +2179,8 @@ function useDockSurfaceShellModel({
2221
2179
  const handleDragEnd = (_event, info) => {
2222
2180
  if (!isActive || !allowSwipeDismiss || typeof onClose !== "function" || !isFullyOpen)
2223
2181
  return;
2224
- if (info.offset.y > DOCK_SURFACE_DRAG_THRESHOLDS.DISMISS_OFFSET_Y || info.velocity.y > DOCK_SURFACE_DRAG_THRESHOLDS.DISMISS_VELOCITY_Y) {
2182
+ const { dismiss } = dockMotion.drag;
2183
+ if (info.offset.y > dismiss.offset || info.velocity.y > dismiss.velocity) {
2225
2184
  onClose();
2226
2185
  }
2227
2186
  };
@@ -2246,12 +2205,12 @@ function useDockSurfaceShellModel({
2246
2205
  const resolvedSurfaceId = surfaceId || "active";
2247
2206
  const bodyVariants = useMemo(() => {
2248
2207
  const { surfaceBody } = dockMotion.variants;
2249
- const { surfaceEnter, surfaceExit, surfaceStep } = dockMotion.transitions;
2208
+ const { surfaceExit } = dockMotion.transitions;
2250
2209
  return {
2251
2210
  hidden: surfaceBody.hidden,
2252
2211
  visible: {
2253
2212
  ...surfaceBody.visible,
2254
- transition: surfacePhase === DOCK_SURFACE_PHASE.EXPANDING_BODY ? surfaceEnter : surfaceStep
2213
+ transition: getDockPhaseMotion(dockMotion, surfacePhase).body
2255
2214
  },
2256
2215
  exit: {
2257
2216
  ...surfaceBody.exit,
@@ -2347,11 +2306,12 @@ function getDockItemCardProps({
2347
2306
  hasExtensions = false,
2348
2307
  isAnchoredToBottom,
2349
2308
  position,
2309
+ stacking,
2350
2310
  theme,
2351
- visibleCount = 3
2311
+ visibleCount = stacking.visible.stack
2352
2312
  }) {
2353
- const { offsetY: collapsedOffsetY, scale: collapsedScale } = DOCK_CARD_LAYOUT.collapsed;
2354
- const { offsetY: expandedOffsetY } = DOCK_CARD_LAYOUT.expanded;
2313
+ const { offsetY: collapsedOffsetY, scale: collapsedScale } = stacking.collapsed;
2314
+ const { offsetY: expandedOffsetY } = stacking.expanded;
2355
2315
  const safeCardStyle = { ...cardStyle };
2356
2316
  delete safeCardStyle.scale;
2357
2317
  delete safeCardStyle.className;
@@ -2359,10 +2319,12 @@ function getDockItemCardProps({
2359
2319
  const isShelf = !expanded && position === 1 && hasExtensions;
2360
2320
  const isHeavyBlur = position < visibleCount || expanded || isShelf;
2361
2321
  const collapsedScaleValue = collapsedScale ** position;
2362
- const y = expanded ? position * expandedOffsetY : isShelf ? DOCK_CARD_LAYOUT.extensionShelfY : position * collapsedOffsetY;
2363
- const shelfScale = DOCK_CARD_LAYOUT.extensionShelfScale ?? 0.94;
2364
- const scale = expanded ? cardScale || 1 : isShelf ? shelfScale : collapsedScaleValue;
2365
- const collapsedOpacity = Math.max(0.1, +(1 - position * 0.2).toFixed(2));
2322
+ const y = expanded ? position * expandedOffsetY : isShelf ? stacking.shelf.offsetY : position * collapsedOffsetY;
2323
+ const scale = expanded ? cardScale || 1 : isShelf ? stacking.shelf.scale : collapsedScaleValue;
2324
+ const collapsedOpacity = Math.max(
2325
+ stacking.collapsed.opacityMin,
2326
+ +(1 - position * stacking.collapsed.opacityStep).toFixed(2)
2327
+ );
2366
2328
  const opacity = expanded || isShelf ? 1 : position < visibleCount ? collapsedOpacity : 0;
2367
2329
  return {
2368
2330
  className: cn(theme.slots.card, cardStyle?.className),
@@ -2644,6 +2606,10 @@ function removeInactiveLoadingItems(items = [], activeItem = null) {
2644
2606
  (item) => !item?.isLoading || isSameItem(item, activeItem)
2645
2607
  );
2646
2608
  }
2609
+ function stackRank(item) {
2610
+ if (typeof item.stackOrder === "number") return item.stackOrder;
2611
+ return item.path === "/" ? Number.POSITIVE_INFINITY : 0;
2612
+ }
2647
2613
  function reorderItemsWithActiveFirst(items, activeIndex) {
2648
2614
  if (activeIndex === -1) return items;
2649
2615
  const active = items[activeIndex];
@@ -2651,7 +2617,7 @@ function reorderItemsWithActiveFirst(items, activeIndex) {
2651
2617
  ...items.slice(0, activeIndex),
2652
2618
  ...items.slice(activeIndex + 1)
2653
2619
  ];
2654
- rest.sort((a, b) => a.path === "/" ? 1 : b.path === "/" ? -1 : 0);
2620
+ rest.sort((a, b) => stackRank(a) - stackRank(b));
2655
2621
  return [active, ...rest];
2656
2622
  }
2657
2623
  function shouldRenderInlineAction({
@@ -3027,210 +2993,6 @@ function openDockGuardConfirmation({
3027
2993
  }
3028
2994
  });
3029
2995
  }
3030
- function createDockTransactionState() {
3031
- return { active: null, last: null };
3032
- }
3033
- function createDockTransaction({
3034
- from = "",
3035
- id,
3036
- source = "dock",
3037
- startedAt = Date.now(),
3038
- to = ""
3039
- }) {
3040
- return {
3041
- from: String(from || ""),
3042
- id,
3043
- source,
3044
- startedAt,
3045
- status: DOCK_TRANSACTION_STATUS.PENDING,
3046
- to: String(to || "")
3047
- };
3048
- }
3049
- function settleDockTransaction(transaction, action, status) {
3050
- return {
3051
- ...transaction,
3052
- endedAt: action.endedAt ?? Date.now(),
3053
- error: action.error ?? null,
3054
- reason: action.reason ?? null,
3055
- status
3056
- };
3057
- }
3058
- var TRANSACTION_STATUS_MAP = Object.freeze({
3059
- [DOCK_TRANSACTION_EVENTS.COMPLETE]: DOCK_TRANSACTION_STATUS.COMPLETED,
3060
- [DOCK_TRANSACTION_EVENTS.CANCEL]: DOCK_TRANSACTION_STATUS.CANCELLED,
3061
- [DOCK_TRANSACTION_EVENTS.FAIL]: DOCK_TRANSACTION_STATUS.FAILED,
3062
- [DOCK_TRANSACTION_EVENTS.TIME_OUT]: DOCK_TRANSACTION_STATUS.TIMED_OUT
3063
- });
3064
- function dockTransactionReducer(state, action) {
3065
- if (action?.type === DOCK_TRANSACTION_EVENTS.START) {
3066
- const nextTransaction = action.transaction;
3067
- if (nextTransaction?.id == null) return state;
3068
- const supersededTransaction = state.active ? settleDockTransaction(
3069
- state.active,
3070
- { reason: DOCK_TRANSACTION_REASON.SUPERSEDED },
3071
- DOCK_TRANSACTION_STATUS.CANCELLED
3072
- ) : state.last;
3073
- return { active: nextTransaction, last: supersededTransaction };
3074
- }
3075
- const newStatus = action ? TRANSACTION_STATUS_MAP[action.type] : void 0;
3076
- if (newStatus && action && state.active && state.active.id === action.id) {
3077
- return {
3078
- active: null,
3079
- last: settleDockTransaction(state.active, action, newStatus)
3080
- };
3081
- }
3082
- return state;
3083
- }
3084
- function useDockTransactions({
3085
- onTransactionEvent = null,
3086
- onTimeout = null,
3087
- timeoutMs = DOCK_TRANSACTION_TIMEOUT_MS
3088
- } = {}) {
3089
- const [state, dispatch] = useReducer(
3090
- dockTransactionReducer,
3091
- void 0,
3092
- createDockTransactionState
3093
- );
3094
- const activeTransactionRef = useRef(null);
3095
- const nextTransactionIdRef = useRef(0);
3096
- const timeoutRef = useRef(null);
3097
- const onTimeoutRef = useRef(onTimeout);
3098
- const onTransactionEventRef = useRef(onTransactionEvent);
3099
- useEffect(() => {
3100
- onTimeoutRef.current = onTimeout;
3101
- }, [onTimeout]);
3102
- useEffect(() => {
3103
- onTransactionEventRef.current = onTransactionEvent;
3104
- }, [onTransactionEvent]);
3105
- const clearTransactionTimeout = useCallback(() => {
3106
- if (timeoutRef.current !== null) {
3107
- clearTimeout(timeoutRef.current);
3108
- timeoutRef.current = null;
3109
- }
3110
- }, []);
3111
- const settleTransaction = useCallback(
3112
- (id, type, details = {}) => {
3113
- const activeTransaction = activeTransactionRef.current;
3114
- if (!activeTransaction || activeTransaction.id !== id) return false;
3115
- clearTransactionTimeout();
3116
- activeTransactionRef.current = null;
3117
- const event = { ...details, endedAt: Date.now(), id, type };
3118
- const settledTransaction = settleDockTransaction(
3119
- activeTransaction,
3120
- event,
3121
- TRANSACTION_STATUS_MAP[type] || DOCK_TRANSACTION_STATUS.TIMED_OUT
3122
- );
3123
- dispatch(event);
3124
- onTransactionEventRef.current?.({
3125
- transaction: settledTransaction,
3126
- type
3127
- });
3128
- return true;
3129
- },
3130
- [clearTransactionTimeout]
3131
- );
3132
- const beginTransaction = useCallback(
3133
- ({
3134
- from,
3135
- source,
3136
- to
3137
- } = {}) => {
3138
- const activeTransaction = activeTransactionRef.current;
3139
- if (activeTransaction) {
3140
- settleTransaction(
3141
- activeTransaction.id,
3142
- DOCK_TRANSACTION_EVENTS.CANCEL,
3143
- { reason: DOCK_TRANSACTION_REASON.SUPERSEDED }
3144
- );
3145
- }
3146
- const transaction = createDockTransaction({
3147
- from,
3148
- id: ++nextTransactionIdRef.current,
3149
- source,
3150
- to
3151
- });
3152
- activeTransactionRef.current = transaction;
3153
- dispatch({ transaction, type: DOCK_TRANSACTION_EVENTS.START });
3154
- onTransactionEventRef.current?.({
3155
- transaction,
3156
- type: DOCK_TRANSACTION_EVENTS.START
3157
- });
3158
- const safeTimeout = Number(timeoutMs);
3159
- if (Number.isFinite(safeTimeout) && safeTimeout > 0) {
3160
- timeoutRef.current = setTimeout(() => {
3161
- if (!settleTransaction(
3162
- transaction.id,
3163
- DOCK_TRANSACTION_EVENTS.TIME_OUT,
3164
- { reason: DOCK_TRANSACTION_REASON.TIME_OUT }
3165
- ))
3166
- return;
3167
- onTimeoutRef.current?.(transaction);
3168
- }, safeTimeout);
3169
- }
3170
- return transaction;
3171
- },
3172
- [settleTransaction, timeoutMs]
3173
- );
3174
- const completeTransaction = useCallback(
3175
- (id) => settleTransaction(id, DOCK_TRANSACTION_EVENTS.COMPLETE),
3176
- [settleTransaction]
3177
- );
3178
- const cancelTransaction = useCallback(
3179
- (id, reason = null) => settleTransaction(id, DOCK_TRANSACTION_EVENTS.CANCEL, { reason }),
3180
- [settleTransaction]
3181
- );
3182
- const cancelActiveTransaction = useCallback(
3183
- (reason = null) => activeTransactionRef.current ? cancelTransaction(activeTransactionRef.current.id, reason) : false,
3184
- [cancelTransaction]
3185
- );
3186
- const failTransaction = useCallback(
3187
- (id, error) => settleTransaction(id, DOCK_TRANSACTION_EVENTS.FAIL, { error }),
3188
- [settleTransaction]
3189
- );
3190
- const completeTransactionForPath = useCallback(
3191
- (pathname) => {
3192
- const activeTransaction = activeTransactionRef.current;
3193
- if (!activeTransaction || !isSamePath(activeTransaction.to, pathname))
3194
- return false;
3195
- return completeTransaction(activeTransaction.id);
3196
- },
3197
- [completeTransaction]
3198
- );
3199
- const isTransactionCurrent = useCallback(
3200
- (id) => activeTransactionRef.current?.id === id,
3201
- []
3202
- );
3203
- useEffect(() => {
3204
- return () => {
3205
- clearTransactionTimeout();
3206
- activeTransactionRef.current = null;
3207
- };
3208
- }, [clearTransactionTimeout]);
3209
- return useMemo(
3210
- () => ({
3211
- activeTransaction: state.active,
3212
- beginTransaction,
3213
- cancelActiveTransaction,
3214
- cancelTransaction,
3215
- completeTransaction,
3216
- completeTransactionForPath,
3217
- failTransaction,
3218
- isTransactionCurrent,
3219
- lastTransaction: state.last
3220
- }),
3221
- [
3222
- state.active,
3223
- state.last,
3224
- beginTransaction,
3225
- cancelActiveTransaction,
3226
- cancelTransaction,
3227
- completeTransaction,
3228
- completeTransactionForPath,
3229
- failTransaction,
3230
- isTransactionCurrent
3231
- ]
3232
- );
3233
- }
3234
2996
 
3235
2997
  // src/modules/dock/routing/navigation.ts
3236
2998
  function getRoutePolicyOverrides(item) {
@@ -3305,7 +3067,8 @@ function createDockTopology(items = [], { pathname = "" } = {}) {
3305
3067
  };
3306
3068
  }
3307
3069
  function useRoutePrefetch(router, {
3308
- intentDelayMs = DOCK_PREFETCH_INTENT_DELAY_MS
3070
+ intentDelayMs = DOCK_PREFETCH_INTENT_DELAY_MS,
3071
+ navigator: navigator2 = null
3309
3072
  } = {}) {
3310
3073
  const routeStatesRef = useRef(/* @__PURE__ */ new Map());
3311
3074
  const cancelRoutePrefetch = useCallback((href) => {
@@ -3317,7 +3080,7 @@ function useRoutePrefetch(router, {
3317
3080
  }, []);
3318
3081
  const prefetchRoute = useCallback(
3319
3082
  (href, { immediate = false } = {}) => {
3320
- if (!isSafeInternalHref(href) || typeof router?.prefetch !== "function")
3083
+ if (!isSafeInternalHref(href) || !navigator2 && typeof router?.prefetch !== "function")
3321
3084
  return false;
3322
3085
  const routeState = routeStatesRef.current.get(href);
3323
3086
  if (routeState?.isPrefetched || routeState?.timeoutId != null)
@@ -3326,6 +3089,11 @@ function useRoutePrefetch(router, {
3326
3089
  const currentState = routeStatesRef.current.get(href);
3327
3090
  if (!currentState) return;
3328
3091
  currentState.timeoutId = null;
3092
+ if (navigator2) {
3093
+ routeStatesRef.current.delete(href);
3094
+ navigator2.prefetch(href);
3095
+ return;
3096
+ }
3329
3097
  currentState.isPrefetched = true;
3330
3098
  try {
3331
3099
  router.prefetch(href, {
@@ -3352,7 +3120,7 @@ function useRoutePrefetch(router, {
3352
3120
  else nextState.timeoutId = setTimeout(startPrefetch, delay);
3353
3121
  return true;
3354
3122
  },
3355
- [intentDelayMs, router]
3123
+ [intentDelayMs, navigator2, router]
3356
3124
  );
3357
3125
  useEffect(() => {
3358
3126
  const routeStates = routeStatesRef.current;
@@ -3430,6 +3198,25 @@ function emitDockEvent(eventType, data = {}) {
3430
3198
  ...data
3431
3199
  });
3432
3200
  }
3201
+ function useDockNavigator(router) {
3202
+ const shared = useModule("navigation");
3203
+ const [own] = useState(
3204
+ () => shared ? null : createNavigator({ router })
3205
+ );
3206
+ useEffect(() => {
3207
+ own?.setRouter(router);
3208
+ }, [own, router]);
3209
+ useEffect(() => own ? () => own.dispose() : void 0, [own]);
3210
+ return useMemo(
3211
+ () => own ?? { ...shared.actions, dispose: () => {
3212
+ }, store: shared.store },
3213
+ [own, shared]
3214
+ );
3215
+ }
3216
+ var selectTrips = (state) => ({
3217
+ active: state.active,
3218
+ last: state.last
3219
+ });
3433
3220
  function useDockNavigation() {
3434
3221
  const pathname = usePathname();
3435
3222
  const { locationKey, syncLocationKey } = useDockLocationKey();
@@ -3446,95 +3233,78 @@ function useDockNavigation() {
3446
3233
  "useDockNavigation",
3447
3234
  "DockProvider"
3448
3235
  );
3236
+ const navigator2 = useDockNavigator(router);
3237
+ const { active: activeTransaction, last: lastTransaction } = useStore(
3238
+ navigator2.store,
3239
+ selectTrips,
3240
+ shallowEqual
3241
+ );
3449
3242
  const previousLocationKeyRef = useRef(locationKey);
3450
- const handleTransactionTimeout = useCallback(() => {
3451
- clearPreparedRouteReset();
3452
- stopLoading();
3453
- }, [clearPreparedRouteReset, stopLoading]);
3454
- const {
3455
- activeTransaction,
3456
- beginTransaction,
3457
- cancelActiveTransaction,
3458
- cancelTransaction,
3459
- completeTransactionForPath,
3460
- failTransaction,
3461
- isTransactionCurrent,
3462
- lastTransaction
3463
- } = useDockTransactions({
3464
- onTimeout: handleTransactionTimeout
3465
- });
3243
+ const settledTripRef = useRef(lastTransaction);
3244
+ useEffect(() => {
3245
+ if (settledTripRef.current === lastTransaction) return;
3246
+ settledTripRef.current = lastTransaction;
3247
+ if (!lastTransaction) return;
3248
+ if (lastTransaction.status === NAVIGATION_STATUS.COMPLETED) {
3249
+ syncLocationKey();
3250
+ } else if (lastTransaction.status === NAVIGATION_STATUS.TIMED_OUT || lastTransaction.status === NAVIGATION_STATUS.FAILED) {
3251
+ clearPreparedRouteReset();
3252
+ stopLoading();
3253
+ }
3254
+ }, [clearPreparedRouteReset, lastTransaction, stopLoading, syncLocationKey]);
3466
3255
  const cancelDock = useCallback(
3467
3256
  (reason = "guard") => {
3468
- cancelActiveTransaction(reason);
3257
+ navigator2.cancel(reason);
3469
3258
  clearPreparedRouteReset();
3470
3259
  closeSurface({ cancelled: true, reason, success: false });
3471
3260
  },
3472
- [cancelActiveTransaction, clearPreparedRouteReset, closeSurface]
3261
+ [clearPreparedRouteReset, closeSurface, navigator2]
3473
3262
  );
3474
3263
  const commitDock = useCallback(
3475
- ({
3264
+ async ({
3265
+ force = false,
3476
3266
  from,
3477
3267
  href,
3268
+ item,
3478
3269
  routePolicy,
3479
- source = "dock",
3480
- transaction = null
3270
+ source = "dock"
3481
3271
  }) => {
3482
- const activeRouteTransaction = transaction || beginTransaction({ from, source, to: href });
3483
- if (!isTransactionCurrent(activeRouteTransaction.id)) return false;
3484
- try {
3485
- continuity?.remember?.(from);
3272
+ const result = await navigator2.navigate(href, {
3273
+ force,
3274
+ guard: guards.count() > 0 ? () => guards.check(href, from) : void 0,
3275
+ onCommit: () => {
3276
+ continuity?.remember?.(from);
3277
+ blurActiveElement();
3278
+ prepareRouteReset(routePolicy);
3279
+ emitDockEvent(DOCK_EVENTS.NAVIGATE_START, { from, to: href });
3280
+ },
3281
+ source
3282
+ });
3283
+ if (result.ok) {
3284
+ emitDockEvent(DOCK_EVENTS.NAVIGATE, { from, item, to: href });
3285
+ return true;
3286
+ }
3287
+ if (result.blocked) {
3486
3288
  blurActiveElement();
3487
- prepareRouteReset(routePolicy);
3488
- emitDockEvent(DOCK_EVENTS.NAVIGATE_START, { from, to: href });
3489
- router.push(href);
3490
- emitDockEvent(DOCK_EVENTS.NAVIGATE, {
3289
+ openDockGuardConfirmation({
3290
+ closeSurface,
3291
+ commit: (confirmed) => void commitDock({ ...confirmed, force: true }).catch(
3292
+ (error) => report("Dock route transition", error)
3293
+ ),
3491
3294
  from,
3492
- item: void 0,
3493
- to: href
3295
+ href,
3296
+ message: result.blocked.message,
3297
+ routePolicy
3494
3298
  });
3495
- if (typeof window !== "undefined") {
3496
- const currentUrl = new URL(window.location.href);
3497
- const destinationUrl = new URL(href, window.location.origin);
3498
- if (normalizePath(currentUrl.pathname) === normalizePath(destinationUrl.pathname)) {
3499
- window.requestAnimationFrame(() => {
3500
- const currentLocKey = getDockLocationKey({
3501
- hash: window.location.hash,
3502
- pathname: window.location.pathname,
3503
- search: window.location.search
3504
- });
3505
- if (!isSamePath(currentLocKey, href) || !completeTransactionForPath(currentLocKey))
3506
- return;
3507
- emitDockEvent(DOCK_EVENTS.NAVIGATE_END, {
3508
- duration: void 0,
3509
- from,
3510
- to: currentLocKey
3511
- });
3512
- previousLocationKeyRef.current = currentLocKey;
3513
- syncLocationKey();
3514
- stopLoading();
3515
- });
3516
- }
3517
- }
3518
- return true;
3519
- } catch (error) {
3520
- clearPreparedRouteReset();
3521
- failTransaction(activeRouteTransaction.id, error);
3522
- stopLoading();
3523
- report("Dock route transition", error);
3524
- return false;
3525
3299
  }
3300
+ return false;
3526
3301
  },
3527
3302
  [
3528
- beginTransaction,
3529
- clearPreparedRouteReset,
3530
- completeTransactionForPath,
3303
+ closeSurface,
3531
3304
  continuity,
3532
- failTransaction,
3533
- isTransactionCurrent,
3534
- prepareRouteReset,
3535
- router,
3536
- stopLoading,
3537
- syncLocationKey
3305
+ guards,
3306
+ navigator2,
3307
+ prepareRouteReset
3538
3308
  ]
3539
3309
  );
3540
3310
  const navigate = useCallback(
@@ -3550,62 +3320,27 @@ function useDockNavigation() {
3550
3320
  return false;
3551
3321
  }
3552
3322
  if (isSamePath(href, from)) return false;
3553
- const transaction = beginTransaction({ from, source, to: href });
3554
3323
  try {
3555
- if (!force && guards.count() > 0) {
3556
- const guardResult = await guards.check(href, from);
3557
- if (!isTransactionCurrent(transaction.id)) return false;
3558
- if (guardResult.blocked) {
3559
- cancelTransaction(transaction.id, "guard");
3560
- blurActiveElement();
3561
- openDockGuardConfirmation({
3562
- closeSurface,
3563
- commit: commitDock,
3564
- from,
3565
- href,
3566
- message: guardResult.message,
3567
- routePolicy
3568
- });
3569
- return false;
3570
- }
3571
- }
3572
- return commitDock({
3573
- from,
3574
- href,
3575
- routePolicy,
3576
- source,
3577
- transaction
3578
- });
3324
+ return await commitDock({ force, from, href, routePolicy, source });
3579
3325
  } catch (error) {
3580
- failTransaction(transaction.id, error);
3581
3326
  stopLoading();
3582
- report("Dock navigation guard", error);
3327
+ report("Dock navigation", error);
3583
3328
  return false;
3584
3329
  }
3585
3330
  },
3586
- [
3587
- guards,
3588
- beginTransaction,
3589
- cancelTransaction,
3590
- commitDock,
3591
- failTransaction,
3592
- isTransactionCurrent,
3593
- closeSurface,
3594
- locationKey,
3595
- stopLoading
3596
- ]
3331
+ [commitDock, locationKey, stopLoading]
3597
3332
  );
3598
3333
  useEffect(() => {
3334
+ navigator2.arrive(locationKey);
3599
3335
  if (previousLocationKeyRef.current === locationKey) return;
3600
3336
  emitDockEvent(DOCK_EVENTS.NAVIGATE_END, {
3601
3337
  duration: void 0,
3602
3338
  from: previousLocationKeyRef.current,
3603
3339
  to: locationKey
3604
3340
  });
3605
- completeTransactionForPath(locationKey);
3606
3341
  previousLocationKeyRef.current = locationKey;
3607
3342
  stopLoading();
3608
- }, [completeTransactionForPath, locationKey, stopLoading]);
3343
+ }, [locationKey, navigator2, stopLoading]);
3609
3344
  return {
3610
3345
  activeTransaction,
3611
3346
  cancelDock,
@@ -3902,7 +3637,10 @@ function useDockCardItemModel({
3902
3637
  const [isHovered, setIsHovered] = useState(false);
3903
3638
  const pathname = usePathname();
3904
3639
  const router = useRouter();
3905
- const { cancelRoutePrefetch, prefetchRoute } = useRoutePrefetch(router);
3640
+ const navigation = useModule("navigation");
3641
+ const { cancelRoutePrefetch, prefetchRoute } = useRoutePrefetch(router, {
3642
+ navigator: navigation?.actions
3643
+ });
3906
3644
  const hasMedia = useDockHasMedia();
3907
3645
  const isTopHudActive = Boolean(isTop && isHudActive);
3908
3646
  const isCurrentActive = Boolean(
@@ -3984,7 +3722,7 @@ function useDockCardItemModel({
3984
3722
  hidden: headerRestore.hidden,
3985
3723
  visible: {
3986
3724
  ...visible,
3987
- transition: item.surfacePhase === DOCK_SURFACE_PHASE.COLLAPSING_BODY ? dockMotion.transitions.surfaceEnter : visible.transition
3725
+ transition: getDockPhaseMotion(dockMotion, item.surfacePhase).headerReturn ?? visible.transition
3988
3726
  },
3989
3727
  exit: headerRestore.exit
3990
3728
  };
@@ -4048,7 +3786,7 @@ function useDockCardItemModel({
4048
3786
  !expanded && position > 0 && !isExtensionShelf
4049
3787
  );
4050
3788
  const isCollapsedGhostCard = Boolean(
4051
- !expanded && position >= MAX_VISIBLE_STACKED_CARDS && !isExtensionShelf
3789
+ !expanded && position >= dockMotion.deck.stacking.visible.stack && !isExtensionShelf
4052
3790
  );
4053
3791
  const {
4054
3792
  className: cardClassName,
@@ -4062,7 +3800,8 @@ function useDockCardItemModel({
4062
3800
  cardScale: itemStyle.scale,
4063
3801
  theme,
4064
3802
  isAnchoredToBottom: item.isSurface,
4065
- visibleCount: item.isStatus && !isStackHovered ? 1 : hasExtensions && !expanded ? 2 : 3,
3803
+ stacking: dockMotion.deck.stacking,
3804
+ visibleCount: item.isStatus && !isStackHovered ? dockMotion.deck.stacking.visible.status : hasExtensions && !expanded ? dockMotion.deck.stacking.visible.extensions : dockMotion.deck.stacking.visible.stack,
4066
3805
  hasExtensions
4067
3806
  });
4068
3807
  const cardDelay = useMemo(
@@ -6053,27 +5792,31 @@ function buildDockItems({
6053
5792
  return filterDockItems(flattenedItems, searchQuery);
6054
5793
  return flattenedItems;
6055
5794
  }
6056
- function resolveBaseActiveItem({
5795
+ function resolveBaseActiveItemMatch({
6057
5796
  rawItems,
6058
5797
  dockItems,
6059
5798
  pathname,
6060
5799
  isNotFoundPage
6061
5800
  }) {
6062
5801
  const normalizedPathname = normalizePath(pathname);
5802
+ const matched = (item) => ({
5803
+ item,
5804
+ isFallback: false
5805
+ });
6063
5806
  const selectedDataSource = dockItems.find(
6064
5807
  (item) => item.isDataSource && item.isSelected
6065
5808
  );
6066
- if (selectedDataSource) return selectedDataSource;
5809
+ if (selectedDataSource) return matched(selectedDataSource);
6067
5810
  if (isNotFoundPage)
6068
- return rawItems.find(isNotFoundItem) || rawItems[0] || null;
5811
+ return matched(rawItems.find(isNotFoundItem) || rawItems[0] || null);
6069
5812
  const matchInDock = dockItems.find(
6070
5813
  (item) => isSamePath(item.path, normalizedPathname) || item.targetPath && isSamePath(item.targetPath, normalizedPathname)
6071
5814
  );
6072
- if (matchInDock) return matchInDock;
5815
+ if (matchInDock) return matched(matchInDock);
6073
5816
  const matchInRaw = rawItems.find(
6074
5817
  (item) => isSamePath(item.path, normalizedPathname) || item.targetPath && isSamePath(item.targetPath, normalizedPathname)
6075
5818
  );
6076
- if (matchInRaw) return matchInRaw;
5819
+ if (matchInRaw) return matched(matchInRaw);
6077
5820
  let prefixMatchedRawItem = null;
6078
5821
  let longestPrefixLength = -1;
6079
5822
  for (let i = 0; i < rawItems.length; i++) {
@@ -6084,11 +5827,65 @@ function resolveBaseActiveItem({
6084
5827
  }
6085
5828
  }
6086
5829
  if (prefixMatchedRawItem) {
6087
- return dockItems.find(
5830
+ const item = dockItems.find(
6088
5831
  (entry) => isSamePath(entry?.path, prefixMatchedRawItem?.path) || entry?.name && entry.name === prefixMatchedRawItem?.name
6089
5832
  ) || prefixMatchedRawItem;
5833
+ return {
5834
+ item,
5835
+ isFallback: normalizePath(prefixMatchedRawItem.path) === "/"
5836
+ };
6090
5837
  }
6091
- return rawItems[0] || null;
5838
+ return { item: rawItems[0] || null, isFallback: true };
5839
+ }
5840
+ function selectPendingRouteItem({
5841
+ match,
5842
+ heldItem,
5843
+ pathname,
5844
+ isHolding
5845
+ }) {
5846
+ if (!match.isFallback || !isHolding || !heldItem) return match.item;
5847
+ if (heldItem.path && isSamePath(heldItem.path, pathname)) return match.item;
5848
+ return heldItem;
5849
+ }
5850
+ function usePendingRouteHold(pathname, match, {
5851
+ holdMs = DOCK_PENDING_ROUTE_HOLD_MS,
5852
+ isNavigating = false
5853
+ } = {}) {
5854
+ const normalizedPathname = normalizePath(pathname);
5855
+ const [lastMatched, setLastMatched] = useState(
5856
+ () => match.isFallback ? null : match.item
5857
+ );
5858
+ const [hold, setHold] = useState(() => ({
5859
+ isOpen: false,
5860
+ pathname: normalizedPathname
5861
+ }));
5862
+ if (!match.isFallback && match.item !== lastMatched) {
5863
+ setLastMatched(match.item);
5864
+ }
5865
+ if (hold.pathname !== normalizedPathname) {
5866
+ setHold({ isOpen: true, pathname: normalizedPathname });
5867
+ }
5868
+ useEffect(() => {
5869
+ if (!hold.isOpen || isNavigating) return;
5870
+ const timer = setTimeout(
5871
+ () => setHold(
5872
+ (current) => current.pathname === hold.pathname ? { ...current, isOpen: false } : current
5873
+ ),
5874
+ holdMs
5875
+ );
5876
+ return () => clearTimeout(timer);
5877
+ }, [hold, holdMs, isNavigating]);
5878
+ const selected = selectPendingRouteItem({
5879
+ heldItem: lastMatched,
5880
+ isHolding: hold.isOpen && hold.pathname === normalizedPathname,
5881
+ match,
5882
+ pathname: normalizedPathname
5883
+ });
5884
+ const isHeld = selected !== match.item;
5885
+ return useMemo(
5886
+ () => isHeld && selected ? { ...selected, isRoutePending: true } : selected,
5887
+ [isHeld, selected]
5888
+ );
6092
5889
  }
6093
5890
  function resolveActiveItem({
6094
5891
  rawItems,
@@ -6103,14 +5900,15 @@ function resolveActiveItem({
6103
5900
  actionStackClass,
6104
5901
  surfaceActions,
6105
5902
  isPageLoading,
6106
- attention
5903
+ attention,
5904
+ baseActiveItem: resolvedBaseActiveItem
6107
5905
  }) {
6108
- const baseActiveItem = resolveBaseActiveItem({
5906
+ const baseActiveItem = resolvedBaseActiveItem !== void 0 ? resolvedBaseActiveItem : resolveBaseActiveItemMatch({
6109
5907
  rawItems,
6110
5908
  dockItems,
6111
5909
  pathname,
6112
5910
  isNotFoundPage
6113
- });
5911
+ }).item;
6114
5912
  if (!baseActiveItem) return null;
6115
5913
  if (attention?.kind === DOCK_ATTENTION_KIND.SURFACE)
6116
5914
  return applySurfaceToDockItem(
@@ -6162,7 +5960,7 @@ function useDockItems() {
6162
5960
  );
6163
5961
  return { rawItems };
6164
5962
  }
6165
- function useDockDisplay(overridePathname) {
5963
+ function useDockDisplay(overridePathname, { isNavigating = false } = {}) {
6166
5964
  const routerPathname = usePathname();
6167
5965
  const pathname = overridePathname || routerPathname;
6168
5966
  const loadingState = useDockLoadingState();
@@ -6242,8 +6040,21 @@ function useDockDisplay(overridePathname) {
6242
6040
  () => buildDockItems({ rawItems, expanded, searchQuery, isNotFoundPage }),
6243
6041
  [rawItems, expanded, searchQuery, isNotFoundPage]
6244
6042
  );
6043
+ const baseMatch = useMemo(
6044
+ () => resolveBaseActiveItemMatch({
6045
+ rawItems,
6046
+ dockItems,
6047
+ pathname,
6048
+ isNotFoundPage
6049
+ }),
6050
+ [rawItems, dockItems, pathname, isNotFoundPage]
6051
+ );
6052
+ const baseActiveItem = usePendingRouteHold(pathname, baseMatch, {
6053
+ isNavigating
6054
+ });
6245
6055
  const activeItem = useMemo(
6246
6056
  () => resolveActiveItem({
6057
+ baseActiveItem,
6247
6058
  rawItems,
6248
6059
  dockItems,
6249
6060
  pathname,
@@ -6268,6 +6079,7 @@ function useDockDisplay(overridePathname) {
6268
6079
  attention
6269
6080
  }),
6270
6081
  [
6082
+ baseActiveItem,
6271
6083
  rawItems,
6272
6084
  dockItems,
6273
6085
  pathname,
@@ -6320,8 +6132,15 @@ function useDockLayout({
6320
6132
  const routePathname = usePathname();
6321
6133
  const pathname = overridePathname || routePathname;
6322
6134
  const { displayItems, displayActiveIndex } = useMemo(() => {
6323
- const items = dockItems || [];
6324
- const activeIndex = findDockItemIndex(items, activeItem ?? null, pathname);
6135
+ const registeredItems = dockItems || [];
6136
+ const registeredIndex = findDockItemIndex(
6137
+ registeredItems,
6138
+ activeItem ?? null,
6139
+ pathname
6140
+ );
6141
+ const isHeldOutsideStack = registeredIndex === -1 && Boolean(activeItem?.isRoutePending);
6142
+ const items = isHeldOutsideStack ? [activeItem, ...registeredItems] : registeredItems;
6143
+ const activeIndex = isHeldOutsideStack ? 0 : registeredIndex;
6325
6144
  const itemsWithActiveItem = replaceActiveItem(
6326
6145
  items,
6327
6146
  activeIndex,
@@ -6346,8 +6165,7 @@ function useDockLayout({
6346
6165
  }, [pathname, dockItems, activeItem]);
6347
6166
  return {
6348
6167
  displayItems,
6349
- activeIndex: displayActiveIndex,
6350
- MAX_VISIBLE_STACKED_CARDS
6168
+ activeIndex: displayActiveIndex
6351
6169
  };
6352
6170
  }
6353
6171
  function useDock() {
@@ -6376,7 +6194,9 @@ function useDock() {
6376
6194
  pathname
6377
6195
  } = core;
6378
6196
  const effectivePathname = activeTransaction?.to ? normalizePath(activeTransaction.to) : pathname;
6379
- const display = useDockDisplay(effectivePathname);
6197
+ const display = useDockDisplay(effectivePathname, {
6198
+ isNavigating: Boolean(activeTransaction)
6199
+ });
6380
6200
  const { dockItems, activeItem, statusState, attention, topology } = display;
6381
6201
  const isHudModeActive = attention?.kind === DOCK_ATTENTION_KIND.HUD || attention?.kind === DOCK_ATTENTION_KIND.OPERATION;
6382
6202
  const isSurfaceActive = Boolean(activeItem?.isSurface);
@@ -6829,7 +6649,7 @@ var DockCardBanner = memo(function DockCardBanner2({
6829
6649
  const resolvedPosition = bannerPosition || bannerObj?.position || bannerObj?.bannerPosition || "center 45%";
6830
6650
  const resolvedSize = bannerSize || bannerObj?.size || bannerObj?.bannerSize || "cover";
6831
6651
  const resolvedRepeat = bannerRepeat || bannerObj?.repeat || bannerObj?.bannerRepeat || "no-repeat";
6832
- const resolvedOpacity = bannerOpacity ?? bannerObj?.opacity ?? bannerObj?.bannerOpacity ?? 0.95;
6652
+ const resolvedOpacity = bannerOpacity ?? bannerObj?.opacity ?? bannerObj?.bannerOpacity ?? dockMotion.opacity.banner;
6833
6653
  return /* @__PURE__ */ jsxs(
6834
6654
  motion.div,
6835
6655
  {
@@ -6971,9 +6791,9 @@ var DockDescription = memo(function DockDescription2({
6971
6791
  const theme = useDockTheme();
6972
6792
  if (text == null || text === "") return null;
6973
6793
  const { className, inlineStyle } = splitStyle(style);
6974
- const { opacity = 0.7, ...restStyle } = inlineStyle;
6794
+ const { opacity = dockMotion.opacity.description, ...restStyle } = inlineStyle;
6975
6795
  const isMultiline = Number(maxLines) > 1;
6976
- const targetOpacity = typeof opacity === "number" ? opacity : 0.7;
6796
+ const targetOpacity = typeof opacity === "number" ? opacity : dockMotion.opacity.description;
6977
6797
  const sharedClass = cn(theme.slots.descriptionText, className);
6978
6798
  const sharedStyle = {
6979
6799
  opacity: targetOpacity,
@@ -7537,7 +7357,7 @@ var DockSurfaceControls = memo(function DockSurfaceControls2({
7537
7357
  const isControlsVisible = Boolean(
7538
7358
  isBodyVisible && (activeItem ? activeItem.isSurface !== false : true) && activeControlKeys.length > 0
7539
7359
  );
7540
- const targetY = hasExtensions ? DOCK_CARD_LAYOUT.extensionShelfY - DOCK_CARD_LAYOUT.collapsed.offsetY : 0;
7360
+ const targetY = hasExtensions ? dockMotion.deck.stacking.shelf.offsetY - dockMotion.deck.stacking.collapsed.offsetY : 0;
7541
7361
  return /* @__PURE__ */ jsx(AnimatePresence, { children: isControlsVisible && /* @__PURE__ */ jsx(
7542
7362
  motion.div,
7543
7363
  {
@@ -7606,6 +7426,7 @@ var DockSurfaceControls = memo(function DockSurfaceControls2({
7606
7426
  motion.div,
7607
7427
  {
7608
7428
  layout: "position",
7429
+ transition: getDockLayoutTransition(dockMotion),
7609
7430
  variants: dockMotion.variants.controlsClose,
7610
7431
  initial: "hidden",
7611
7432
  animate: "visible",
@@ -8180,7 +8001,7 @@ var DockCardItem = memo(function DockCardItem2({
8180
8001
  initial: "hidden",
8181
8002
  animate: item.surfacePhase === DOCK_SURFACE_PHASE.DISMISSING_ACTION ? "hidden" : "visible",
8182
8003
  exit: layerExit,
8183
- transition: item.surfacePhase === DOCK_SURFACE_PHASE.DISMISSING_ACTION ? dockMotion.transitions.anticipation : dockMotion.transitions.headerSwap,
8004
+ transition: getDockPhaseMotion(dockMotion, item.surfacePhase).header,
8184
8005
  style: { ...DOCK_COMPOSITOR_STYLE, willChange: "transform" },
8185
8006
  className: theme.slots.cardStandard,
8186
8007
  children: item.isLoading ? /* @__PURE__ */ jsx(LoadingItemContent, {}) : /* @__PURE__ */ jsx(
@@ -8417,6 +8238,7 @@ var DockBreadcrumbsCard = memo(function DockBreadcrumbsCard2({
8417
8238
  motion.div,
8418
8239
  {
8419
8240
  layout: "position",
8241
+ transition: getDockLayoutTransition(dockMotion),
8420
8242
  className: theme.slots.breadcrumbsItem,
8421
8243
  children: [
8422
8244
  isLast ? /* @__PURE__ */ jsx("span", { className: theme.slots.breadcrumbsCurrent, children: crumb.title }) : /* @__PURE__ */ jsx(
@@ -8496,7 +8318,7 @@ function Dock() {
8496
8318
  "data-controls-hidden": expanded || activeItem?.isSurface ? "true" : "false",
8497
8319
  style: {
8498
8320
  ...theme.styles.stack,
8499
- transformOrigin: "50% 100%"
8321
+ transformOrigin: dockMotion.deck.origin
8500
8322
  },
8501
8323
  initial: false,
8502
8324
  animate: getDockStackAnimateProps(dockMotion, {
@@ -9885,7 +9707,7 @@ var dockModule = defineModule({
9885
9707
  context: DockContext,
9886
9708
  Provider: DockModuleProvider,
9887
9709
  Overlay: Dock,
9888
- uses: ["loading", "media", "notification"],
9710
+ uses: ["loading", "media", "navigation", "notification"],
9889
9711
  registry: {
9890
9712
  cleanupDelayMs: 600,
9891
9713
  keyPolicy: "path",
@@ -9901,5 +9723,5 @@ var dockModule = defineModule({
9901
9723
  });
9902
9724
 
9903
9725
  export { DOCK_EVENTS, DOCK_HUD_PRIORITY, DOCK_HUD_RENDER_MODE, DOCK_HUD_VARIANT, Dock, DockCardBanner, DockCardHeader, DockDescription, DockIcon, DockProvider, DockSurfaceAction, DockSurfaceExtension, DockSurfaceHeaderButton, DockTitle, ErrorActions, GuardActions, createDockGuardRegistry, createErrorStatus, createGuardStatus, createInlineSurfaceEntry, createSurfaceEntryDefinition, createSurfaceFlowBuilder, defineBreadcrumb, defineDockAction, defineHud, defineStepSurface, defineSurface, dockModule, dockTheme, isValidBannerUrl, useDock, useDockActionClass, useDockActions, useDockBanner, useDockConfig, useDockContextActions, useDockDimensions, useDockGuard, useDockHeight, useDockHud, useDockMotion, useDockRegistration, useDockSelector, useDockState, useDockTheme, useHud, useOptionalDockActions, useOptionalDockState, useSurface, useSurfaceAction, useSurfaceDimensions, useSurfaceFlow, useSurfaceHeader, useSurfaceId, useSurfaceReturn, useSurfaceStep };
9904
- //# sourceMappingURL=chunk-A5RE3F6O.js.map
9905
- //# sourceMappingURL=chunk-A5RE3F6O.js.map
9726
+ //# sourceMappingURL=chunk-WVRMABDN.js.map
9727
+ //# sourceMappingURL=chunk-WVRMABDN.js.map