react-panel-layout 0.6.0 → 0.7.0

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 (258) hide show
  1. package/dist/{FloatingPanelFrame-SgYLc6Ud.js → FloatingPanelFrame-3eU9AwPo.js} +2 -2
  2. package/dist/{FloatingPanelFrame-SgYLc6Ud.js.map → FloatingPanelFrame-3eU9AwPo.js.map} +1 -1
  3. package/dist/FloatingWindow-Bw2djgpz.js +1542 -0
  4. package/dist/FloatingWindow-Bw2djgpz.js.map +1 -0
  5. package/dist/FloatingWindow-Cvyokf0m.cjs +2 -0
  6. package/dist/FloatingWindow-Cvyokf0m.cjs.map +1 -0
  7. package/dist/GridLayout-B4aCqSyd.js +947 -0
  8. package/dist/{GridLayout-BltqeCPK.js.map → GridLayout-B4aCqSyd.js.map} +1 -1
  9. package/dist/GridLayout-DNOClFzz.cjs +2 -0
  10. package/dist/{GridLayout-B4VRsC0r.cjs.map → GridLayout-DNOClFzz.cjs.map} +1 -1
  11. package/dist/{HorizontalDivider-WF1k_qND.js → HorizontalDivider-DdxzfV0l.js} +3 -3
  12. package/dist/{HorizontalDivider-WF1k_qND.js.map → HorizontalDivider-DdxzfV0l.js.map} +1 -1
  13. package/dist/{HorizontalDivider-B5Z-KZLk.cjs → HorizontalDivider-_pgV4Mcv.cjs} +2 -2
  14. package/dist/{HorizontalDivider-B5Z-KZLk.cjs.map → HorizontalDivider-_pgV4Mcv.cjs.map} +1 -1
  15. package/dist/PanelSystem-B8Igvnb2.cjs +3 -0
  16. package/dist/PanelSystem-B8Igvnb2.cjs.map +1 -0
  17. package/dist/{PanelSystem-Dr1TBhxM.js → PanelSystem-DDUSFjXD.js} +209 -248
  18. package/dist/PanelSystem-DDUSFjXD.js.map +1 -0
  19. package/dist/ResizeHandle-CBcAS918.cjs +2 -0
  20. package/dist/{ResizeHandle-CScipO5l.cjs.map → ResizeHandle-CBcAS918.cjs.map} +1 -1
  21. package/dist/{ResizeHandle-CdA_JYfN.js → ResizeHandle-CXjc1meV.js} +28 -29
  22. package/dist/{ResizeHandle-CdA_JYfN.js.map → ResizeHandle-CXjc1meV.js.map} +1 -1
  23. package/dist/SwipePivotTabBar-DWrCuwEI.js +411 -0
  24. package/dist/SwipePivotTabBar-DWrCuwEI.js.map +1 -0
  25. package/dist/SwipePivotTabBar-fjjXkpj7.cjs +2 -0
  26. package/dist/SwipePivotTabBar-fjjXkpj7.cjs.map +1 -0
  27. package/dist/components/gesture/SwipeSafeZone.d.ts +40 -0
  28. package/dist/components/window/Drawer.d.ts +4 -1
  29. package/dist/components/window/DrawerLayers.d.ts +1 -1
  30. package/dist/components/window/DrawerRevealContext.d.ts +61 -0
  31. package/dist/components/window/drawerRevealAnimationUtils.d.ts +212 -0
  32. package/dist/components/window/drawerStyles.d.ts +74 -0
  33. package/dist/components/window/drawerSwipeConfig.d.ts +29 -0
  34. package/dist/components/window/useDrawerSwipeTransform.d.ts +29 -0
  35. package/dist/components/window/useDrawerTransform.d.ts +68 -0
  36. package/dist/components/window/useRevealDrawerTransform.d.ts +56 -0
  37. package/dist/config.cjs +1 -1
  38. package/dist/config.cjs.map +1 -1
  39. package/dist/config.js +9 -8
  40. package/dist/config.js.map +1 -1
  41. package/dist/constants/styles.d.ts +17 -0
  42. package/dist/dialog/index.d.ts +69 -0
  43. package/dist/floating.js +1 -1
  44. package/dist/grid.cjs +1 -1
  45. package/dist/grid.js +2 -2
  46. package/dist/hooks/gesture/testing/createGestureSimulator.d.ts +7 -0
  47. package/dist/hooks/gesture/types.d.ts +48 -5
  48. package/dist/hooks/gesture/utils.d.ts +19 -0
  49. package/dist/hooks/useAnimationFrame.d.ts +2 -0
  50. package/dist/hooks/useOperationContinuity.d.ts +64 -0
  51. package/dist/hooks/useResizeObserver.d.ts +33 -1
  52. package/dist/hooks/useSharedElementTransition.d.ts +112 -0
  53. package/dist/hooks/useSwipeContentTransform.d.ts +9 -2
  54. package/dist/index.cjs +1 -1
  55. package/dist/index.js +7 -7
  56. package/dist/modules/dialog/AlertDialog.d.ts +9 -0
  57. package/dist/modules/dialog/DialogContainer.d.ts +37 -0
  58. package/dist/modules/dialog/Modal.d.ts +26 -0
  59. package/dist/modules/dialog/SwipeDialogContainer.d.ts +16 -0
  60. package/dist/modules/dialog/dialogAnimationUtils.d.ts +113 -0
  61. package/dist/modules/dialog/types.d.ts +183 -0
  62. package/dist/modules/dialog/useDialog.d.ts +39 -0
  63. package/dist/modules/dialog/useDialogContainer.d.ts +47 -0
  64. package/dist/modules/dialog/useDialogSwipeInput.d.ts +70 -0
  65. package/dist/modules/dialog/useDialogTransform.d.ts +82 -0
  66. package/dist/modules/drawer/drawerStateMachine.d.ts +168 -0
  67. package/dist/modules/drawer/revealDrawerConstants.d.ts +33 -0
  68. package/dist/modules/drawer/revealDrawerStateMachine.d.ts +146 -0
  69. package/dist/modules/drawer/strategies/index.d.ts +8 -0
  70. package/dist/modules/drawer/strategies/overlayStrategy.d.ts +12 -0
  71. package/dist/modules/drawer/strategies/revealStrategy.d.ts +12 -0
  72. package/dist/modules/drawer/strategies/types.d.ts +116 -0
  73. package/dist/modules/drawer/types.d.ts +74 -0
  74. package/dist/modules/drawer/useDrawerSwipeInput.d.ts +24 -0
  75. package/dist/modules/pivot/SwipePivotTabBar.d.ts +3 -0
  76. package/dist/modules/stack/SwipeStackContent.d.ts +6 -3
  77. package/dist/modules/stack/SwipeStackOutlet.d.ts +4 -4
  78. package/dist/modules/stack/computeSwipeStackTransform.d.ts +1 -1
  79. package/dist/panels.cjs +1 -1
  80. package/dist/panels.js +1 -1
  81. package/dist/pivot.cjs +1 -1
  82. package/dist/pivot.js +1 -1
  83. package/dist/resizer.cjs +1 -1
  84. package/dist/resizer.js +2 -2
  85. package/dist/stack.cjs +1 -1
  86. package/dist/stack.cjs.map +1 -1
  87. package/dist/stack.js +480 -780
  88. package/dist/stack.js.map +1 -1
  89. package/dist/sticky-header/calculateStickyMetrics.d.ts +28 -0
  90. package/dist/sticky-header.cjs +1 -1
  91. package/dist/sticky-header.cjs.map +1 -1
  92. package/dist/sticky-header.js +59 -51
  93. package/dist/sticky-header.js.map +1 -1
  94. package/dist/{styles-DPPuJ0sf.js → styles-NkjuMOVS.js} +13 -13
  95. package/dist/{styles-DPPuJ0sf.js.map → styles-NkjuMOVS.js.map} +1 -1
  96. package/dist/styles-qf6ptVLD.cjs.map +1 -1
  97. package/dist/types.d.ts +30 -0
  98. package/dist/useAnimationFrame-BZ6D2lMq.cjs +2 -0
  99. package/dist/useAnimationFrame-BZ6D2lMq.cjs.map +1 -0
  100. package/dist/useAnimationFrame-Bg4e-H8O.js +394 -0
  101. package/dist/useAnimationFrame-Bg4e-H8O.js.map +1 -0
  102. package/dist/useDocumentPointerEvents-DXxw3qWj.js +54 -0
  103. package/dist/useDocumentPointerEvents-DXxw3qWj.js.map +1 -0
  104. package/dist/useDocumentPointerEvents-DxDSOtip.cjs +2 -0
  105. package/dist/useDocumentPointerEvents-DxDSOtip.cjs.map +1 -0
  106. package/dist/window/index.d.ts +2 -0
  107. package/dist/window.cjs +1 -1
  108. package/dist/window.cjs.map +1 -1
  109. package/dist/window.js +114 -103
  110. package/dist/window.js.map +1 -1
  111. package/package.json +6 -1
  112. package/src/components/gesture/SwipeSafeZone.tsx +70 -0
  113. package/src/components/grid/GridLayout.tsx +110 -38
  114. package/src/components/window/Drawer.tsx +353 -162
  115. package/src/components/window/DrawerLayers.tsx +54 -11
  116. package/src/components/window/DrawerRevealContext.spec.ts +20 -0
  117. package/src/components/window/DrawerRevealContext.tsx +99 -0
  118. package/src/components/window/drawerRevealAnimationUtils.spec.ts +375 -0
  119. package/src/components/window/drawerRevealAnimationUtils.ts +415 -0
  120. package/src/components/window/drawerStyles.spec.ts +302 -0
  121. package/src/components/window/drawerStyles.ts +252 -0
  122. package/src/components/window/drawerSwipeConfig.spec.ts +131 -0
  123. package/src/components/window/drawerSwipeConfig.ts +112 -0
  124. package/src/components/window/useDrawerSwipeTransform.ts +67 -0
  125. package/src/components/window/useDrawerTransform.ts +505 -0
  126. package/src/components/window/useRevealDrawerTransform.spec.ts +1936 -0
  127. package/src/components/window/useRevealDrawerTransform.ts +105 -0
  128. package/src/constants/styles.ts +19 -0
  129. package/src/demo/components/FullscreenDemoPage.tsx +47 -0
  130. package/src/demo/fullscreenRoutes.tsx +32 -0
  131. package/src/demo/index.tsx +5 -0
  132. package/src/demo/pages/Dialog/alerts/index.tsx +22 -0
  133. package/src/demo/pages/Dialog/card/index.tsx +22 -0
  134. package/src/demo/pages/Dialog/components/AlertDialogDemo.tsx +124 -0
  135. package/src/demo/pages/Dialog/components/CardExpandDemo.module.css +243 -0
  136. package/src/demo/pages/Dialog/components/CardExpandDemo.tsx +219 -0
  137. package/src/demo/pages/Dialog/components/CustomAlertDialogDemo.tsx +219 -0
  138. package/src/demo/pages/Dialog/components/DialogDemos.module.css +77 -0
  139. package/src/demo/pages/Dialog/components/ModalBasics.tsx +45 -0
  140. package/src/demo/pages/Dialog/components/SwipeDialogDemo.module.css +77 -0
  141. package/src/demo/pages/Dialog/components/SwipeDialogDemo.tsx +181 -0
  142. package/src/demo/pages/Dialog/custom-alert/index.tsx +22 -0
  143. package/src/demo/pages/Dialog/modal/index.tsx +17 -0
  144. package/src/demo/pages/Dialog/swipe/index.tsx +22 -0
  145. package/src/demo/pages/Drawer/components/DrawerBasics.module.css +6 -1
  146. package/src/demo/pages/Drawer/components/DrawerBasics.tsx +14 -4
  147. package/src/demo/pages/Drawer/components/DrawerReveal.module.css +157 -0
  148. package/src/demo/pages/Drawer/components/DrawerReveal.tsx +128 -0
  149. package/src/demo/pages/Drawer/components/DrawerSwipe.module.css +316 -0
  150. package/src/demo/pages/Drawer/components/DrawerSwipe.tsx +178 -0
  151. package/src/demo/pages/Drawer/reveal/index.tsx +17 -0
  152. package/src/demo/pages/Drawer/reveal-fullscreen/index.tsx +135 -0
  153. package/src/demo/pages/Drawer/reveal-fullscreen/styles.module.css +233 -0
  154. package/src/demo/pages/Drawer/swipe/index.tsx +17 -0
  155. package/src/demo/pages/Pivot/components/SwipeTabsPivot.tsx +54 -23
  156. package/src/demo/pages/Pivot/swipe-debug/index.tsx +1 -1
  157. package/src/demo/pages/Stack/components/StackBasics.spec.tsx +156 -0
  158. package/src/demo/pages/Stack/components/StackBasics.tsx +179 -95
  159. package/src/demo/pages/Stack/components/StackTablet.spec.tsx +110 -0
  160. package/src/demo/pages/Stack/components/StackTablet.tsx +42 -21
  161. package/src/demo/routes.tsx +24 -1
  162. package/src/dialog/index.ts +85 -0
  163. package/src/hooks/gesture/testing/createGestureSimulator.spec.ts +68 -64
  164. package/src/hooks/gesture/testing/createGestureSimulator.ts +113 -37
  165. package/src/hooks/gesture/types.ts +83 -6
  166. package/src/hooks/gesture/useEdgeSwipeInput.spec.ts +22 -14
  167. package/src/hooks/gesture/useNativeGestureGuard.spec.ts +99 -31
  168. package/src/hooks/gesture/useNativeGestureGuard.ts +3 -1
  169. package/src/hooks/gesture/utils.ts +102 -0
  170. package/src/hooks/useAnimatedVisibility.spec.ts +44 -24
  171. package/src/hooks/useAnimatedVisibility.ts +28 -2
  172. package/src/hooks/useAnimationFrame.ts +8 -0
  173. package/src/hooks/useOperationContinuity.spec.ts +394 -0
  174. package/src/hooks/useOperationContinuity.ts +135 -0
  175. package/src/hooks/useResizeObserver.spec.tsx +277 -0
  176. package/src/hooks/useResizeObserver.tsx +108 -39
  177. package/src/hooks/useScrollContainer.ts +4 -10
  178. package/src/hooks/useSharedElementTransition.ts +354 -0
  179. package/src/hooks/useSwipeContentTransform.spec.ts +18 -18
  180. package/src/hooks/useSwipeContentTransform.ts +166 -28
  181. package/src/modules/dialog/AlertDialog.spec.tsx +387 -0
  182. package/src/modules/dialog/AlertDialog.tsx +221 -0
  183. package/src/modules/dialog/DialogContainer.spec.tsx +228 -0
  184. package/src/modules/dialog/DialogContainer.tsx +188 -0
  185. package/src/modules/dialog/Modal.spec.tsx +220 -0
  186. package/src/modules/dialog/Modal.tsx +182 -0
  187. package/src/modules/dialog/SwipeDialogContainer.tsx +208 -0
  188. package/src/modules/dialog/dialogAnimationUtils.spec.ts +252 -0
  189. package/src/modules/dialog/dialogAnimationUtils.ts +297 -0
  190. package/src/modules/dialog/types.ts +186 -0
  191. package/src/modules/dialog/useDialog.spec.tsx +447 -0
  192. package/src/modules/dialog/useDialog.ts +214 -0
  193. package/src/modules/dialog/useDialogContainer.spec.ts +339 -0
  194. package/src/modules/dialog/useDialogContainer.ts +150 -0
  195. package/src/modules/dialog/useDialogSwipeInput.spec.ts +178 -0
  196. package/src/modules/dialog/useDialogSwipeInput.ts +350 -0
  197. package/src/modules/dialog/useDialogTransform.spec.ts +403 -0
  198. package/src/modules/dialog/useDialogTransform.ts +407 -0
  199. package/src/modules/drawer/drawerStateMachine.ts +500 -0
  200. package/src/modules/drawer/revealDrawerConstants.ts +38 -0
  201. package/src/modules/drawer/revealDrawerStateMachine.spec.ts +558 -0
  202. package/src/modules/drawer/revealDrawerStateMachine.ts +197 -0
  203. package/src/modules/drawer/strategies/index.ts +9 -0
  204. package/src/modules/drawer/strategies/overlayStrategy.ts +133 -0
  205. package/src/modules/drawer/strategies/revealStrategy.ts +111 -0
  206. package/src/modules/drawer/strategies/types.ts +160 -0
  207. package/src/modules/drawer/types.ts +102 -0
  208. package/src/modules/drawer/useDrawerSwipeInput.spec.ts +566 -0
  209. package/src/modules/drawer/useDrawerSwipeInput.ts +402 -0
  210. package/src/modules/panels/rendering/ContentRegistry.spec.tsx +21 -14
  211. package/src/modules/pivot/SwipePivotContent.position.spec.tsx +12 -8
  212. package/src/modules/pivot/SwipePivotContent.spec.tsx +66 -25
  213. package/src/modules/pivot/SwipePivotContent.tsx +2 -2
  214. package/src/modules/pivot/SwipePivotTabBar.spec.tsx +85 -68
  215. package/src/modules/pivot/SwipePivotTabBar.tsx +75 -15
  216. package/src/modules/pivot/scaleInputState.spec.ts +11 -2
  217. package/src/modules/pivot/usePivot.spec.ts +17 -3
  218. package/src/modules/pivot/usePivotSwipeInput.spec.ts +182 -123
  219. package/src/modules/stack/SwipeStackContent.spec.tsx +387 -100
  220. package/src/modules/stack/SwipeStackContent.tsx +43 -33
  221. package/src/modules/stack/SwipeStackOutlet.spec.tsx +14 -16
  222. package/src/modules/stack/SwipeStackOutlet.tsx +6 -6
  223. package/src/modules/stack/computeSwipeStackTransform.spec.ts +5 -5
  224. package/src/modules/stack/computeSwipeStackTransform.ts +3 -3
  225. package/src/modules/stack/swipeTransitionContinuity.spec.tsx +1133 -0
  226. package/src/modules/stack/useStackAnimationState.spec.ts +3 -1
  227. package/src/modules/stack/useStackAnimationState.ts +18 -13
  228. package/src/modules/stack/useStackNavigation.spec.ts +198 -3
  229. package/src/modules/stack/useStackNavigation.tsx +113 -56
  230. package/src/modules/stack/useStackSwipeInput.spec.ts +65 -32
  231. package/src/modules/stack/useStackSwipeInput.ts +1 -1
  232. package/src/sticky-header/StickyArea.tsx +29 -57
  233. package/src/sticky-header/calculateStickyMetrics.spec.ts +105 -0
  234. package/src/sticky-header/calculateStickyMetrics.ts +50 -0
  235. package/src/types.ts +33 -0
  236. package/src/window/index.ts +2 -0
  237. package/dist/FloatingWindow-BpdOpg_L.js +0 -400
  238. package/dist/FloatingWindow-BpdOpg_L.js.map +0 -1
  239. package/dist/FloatingWindow-TCDNY5gE.cjs +0 -2
  240. package/dist/FloatingWindow-TCDNY5gE.cjs.map +0 -1
  241. package/dist/GridLayout-B4VRsC0r.cjs +0 -2
  242. package/dist/GridLayout-BltqeCPK.js +0 -927
  243. package/dist/PanelSystem-Bs8bQwQF.cjs +0 -3
  244. package/dist/PanelSystem-Bs8bQwQF.cjs.map +0 -1
  245. package/dist/PanelSystem-Dr1TBhxM.js.map +0 -1
  246. package/dist/ResizeHandle-CScipO5l.cjs +0 -2
  247. package/dist/SwipePivotTabBar-BGO9X94m.js +0 -407
  248. package/dist/SwipePivotTabBar-BGO9X94m.js.map +0 -1
  249. package/dist/SwipePivotTabBar-BrQismcZ.cjs +0 -2
  250. package/dist/SwipePivotTabBar-BrQismcZ.cjs.map +0 -1
  251. package/dist/useDocumentPointerEvents-CKdhGXd0.js +0 -46
  252. package/dist/useDocumentPointerEvents-CKdhGXd0.js.map +0 -1
  253. package/dist/useDocumentPointerEvents-ChqrKXDk.cjs +0 -2
  254. package/dist/useDocumentPointerEvents-ChqrKXDk.cjs.map +0 -1
  255. package/dist/useEffectEvent-Dp7HLCf0.js +0 -13
  256. package/dist/useEffectEvent-Dp7HLCf0.js.map +0 -1
  257. package/dist/useEffectEvent-huSsGUnl.cjs +0 -2
  258. package/dist/useEffectEvent-huSsGUnl.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FloatingWindow-Bw2djgpz.js","sources":["../src/components/gesture/SwipeSafeZone.tsx","../src/modules/drawer/types.ts","../src/modules/drawer/useDrawerSwipeInput.ts","../src/components/window/drawerStyles.ts","../src/components/window/drawerSwipeConfig.ts","../src/utils/typedActions.ts","../src/modules/drawer/revealDrawerConstants.ts","../src/modules/drawer/drawerStateMachine.ts","../src/modules/drawer/strategies/types.ts","../src/components/window/drawerRevealAnimationUtils.ts","../src/modules/drawer/strategies/revealStrategy.ts","../src/modules/drawer/strategies/overlayStrategy.ts","../src/components/window/useDrawerTransform.ts","../src/components/window/useDrawerSwipeTransform.ts","../src/components/window/DrawerRevealContext.tsx","../src/components/window/useRevealDrawerTransform.ts","../src/components/window/Drawer.tsx","../src/hooks/useTransitionState.ts","../src/modules/window/useDrawerState.ts","../src/components/window/DrawerLayers.tsx","../src/modules/grid/GridLayoutContext.tsx","../src/PanelSystemContext.tsx","../src/modules/grid/LayerInstanceContext.tsx","../src/components/window/PopupLayerPortal.tsx","../src/components/window/FloatingWindow.tsx"],"sourcesContent":["/**\n * @file SwipeSafeZone component\n *\n * A wrapper component that marks an area as exempt from swipe gesture detection.\n * Content inside this zone will not trigger swipe-to-close or other swipe gestures.\n *\n * Use this for:\n * - Scrollable content areas\n * - Input fields and text areas\n * - Interactive elements that need drag/swipe for their own purposes\n */\nimport * as React from \"react\";\n\n/**\n * Data attribute used to identify swipe-safe zones.\n * Swipe gesture handlers should check for this attribute on target elements.\n */\nexport const SWIPE_SAFE_ZONE_ATTR = \"data-swipe-safe-zone\";\n\nexport type SwipeSafeZoneProps = {\n /** Content to render inside the safe zone */\n children: React.ReactNode;\n /** Additional CSS class name */\n className?: string;\n /** Additional inline styles */\n style?: React.CSSProperties;\n};\n\n/**\n * SwipeSafeZone marks an area where swipe gestures should not be triggered.\n *\n * @example\n * ```tsx\n * <SwipeSafeZone>\n * <ScrollableList items={items} />\n * </SwipeSafeZone>\n * ```\n */\nexport const SwipeSafeZone: React.FC<SwipeSafeZoneProps> = ({\n children,\n className,\n style,\n}) => {\n return (\n <div\n className={className}\n style={style}\n data-swipe-safe-zone=\"true\"\n >\n {children}\n </div>\n );\n};\n\n/**\n * Check if an element is inside a SwipeSafeZone.\n */\nexport function isInSwipeSafeZone(element: HTMLElement, container: HTMLElement): boolean {\n // eslint-disable-next-line no-restricted-syntax -- loop variable requires let\n let current: HTMLElement | null = element;\n\n while (current && current !== container) {\n if (current.hasAttribute(SWIPE_SAFE_ZONE_ATTR)) {\n return true;\n }\n current = current.parentElement;\n }\n\n return false;\n}\n","/**\n * @file Type definitions for Drawer swipe gesture handling.\n */\nimport type * as React from \"react\";\nimport type { ContinuousOperationState } from \"../../hooks/gesture/types.js\";\n\n/**\n * Direction for drawer anchor (same as anchor edge).\n */\nexport type DrawerSwipeDirection = \"left\" | \"right\" | \"top\" | \"bottom\";\n\n/**\n * Options for useDrawerSwipeInput hook.\n */\nexport type UseDrawerSwipeInputOptions = {\n /** Container ref for edge detection zone (e.g., GridLayout container) */\n edgeContainerRef: React.RefObject<HTMLElement | null>;\n /** Drawer content ref (for close gesture) */\n drawerContentRef: React.RefObject<HTMLElement | null>;\n /** Drawer direction (anchor edge) */\n direction: DrawerSwipeDirection;\n /** Whether the drawer is currently open */\n isOpen: boolean;\n /** Callback when swipe should open the drawer */\n onSwipeOpen: () => void;\n /** Callback when swipe should close the drawer */\n onSwipeClose: () => void;\n /** Whether edge swipe to open is enabled. @default true */\n enableEdgeSwipeOpen?: boolean;\n /** Whether swipe to close is enabled. @default true */\n enableSwipeClose?: boolean;\n /** Width of edge detection zone in pixels. @default 20 */\n edgeWidth?: number;\n /** Dismiss threshold ratio (0-1). @default 0.3 */\n dismissThreshold?: number;\n};\n\n/**\n * Result from useDrawerSwipeInput hook.\n */\nexport type UseDrawerSwipeInputResult = {\n /** Current operation state */\n state: ContinuousOperationState;\n /** Whether currently opening via edge swipe */\n isOpening: boolean;\n /** Whether currently closing via drag */\n isClosing: boolean;\n /** Progress (0-1) towards open/close threshold */\n progress: number;\n /** Displacement in pixels (primary axis) */\n displacement: number;\n /** Props for edge container (open gesture zone) */\n edgeContainerProps: React.HTMLAttributes<HTMLElement> & {\n style: React.CSSProperties;\n };\n /** Props for drawer content (close gesture zone) */\n drawerContentProps: React.HTMLAttributes<HTMLElement> & {\n style: React.CSSProperties;\n };\n};\n\n/**\n * Get animation axis from direction.\n */\nexport function getDrawerAnimationAxis(direction: DrawerSwipeDirection): \"x\" | \"y\" {\n switch (direction) {\n case \"left\":\n case \"right\":\n return \"x\";\n case \"top\":\n case \"bottom\":\n return \"y\";\n }\n}\n\n/**\n * Get the sign for the close swipe direction.\n * Left drawer closes by swiping left (-1).\n * Right drawer closes by swiping right (+1).\n * Top drawer closes by swiping up (-1).\n * Bottom drawer closes by swiping down (+1).\n */\nexport function getDrawerCloseSwipeSign(direction: DrawerSwipeDirection): 1 | -1 {\n switch (direction) {\n case \"left\":\n return -1;\n case \"right\":\n return 1;\n case \"top\":\n return -1;\n case \"bottom\":\n return 1;\n }\n}\n\n/**\n * Get the sign for the open swipe direction.\n * This is the opposite of the close direction.\n */\nexport function getDrawerOpenSwipeSign(direction: DrawerSwipeDirection): 1 | -1 {\n return (getDrawerCloseSwipeSign(direction) * -1) as 1 | -1;\n}\n","/**\n * @file Hook for detecting swipe gestures to open/close a drawer.\n *\n * Combines:\n * - Edge swipe detection for opening (Stack pattern)\n * - Drag-to-close within drawer (Dialog pattern)\n * - Native gesture guard for browser back prevention\n */\nimport * as React from \"react\";\nimport { useEdgeSwipeInput } from \"../../hooks/gesture/useEdgeSwipeInput.js\";\nimport { useNativeGestureGuard } from \"../../hooks/gesture/useNativeGestureGuard.js\";\nimport { usePointerTracking } from \"../../hooks/gesture/usePointerTracking.js\";\nimport {\n mergeGestureContainerProps,\n isScrollableInDirection,\n} from \"../../hooks/gesture/utils.js\";\nimport { isInSwipeSafeZone } from \"../../components/gesture/SwipeSafeZone.js\";\nimport {\n type ContinuousOperationState,\n IDLE_CONTINUOUS_OPERATION_STATE,\n} from \"../../hooks/gesture/types.js\";\nimport type { UseDrawerSwipeInputOptions, UseDrawerSwipeInputResult } from \"./types.js\";\nimport { getDrawerAnimationAxis, getDrawerCloseSwipeSign, getDrawerOpenSwipeSign } from \"./types.js\";\n\n/**\n * Default dismiss threshold (30% of container size).\n */\nconst DEFAULT_DISMISS_THRESHOLD = 0.3;\n\n/**\n * Velocity threshold for quick flick dismissal (px/ms).\n */\nconst VELOCITY_THRESHOLD = 0.5;\n\n// ============================================================================\n// Helper functions (extracted to avoid ternary violations)\n// ============================================================================\n\nfunction getContainerSize(container: HTMLElement, axis: \"x\" | \"y\"): number {\n if (axis === \"x\") {\n return container.clientWidth;\n }\n return container.clientHeight;\n}\n\nfunction getAxisDelta(\n start: { x: number; y: number },\n current: { x: number; y: number },\n axis: \"x\" | \"y\",\n): number {\n if (axis === \"x\") {\n return current.x - start.x;\n }\n return current.y - start.y;\n}\n\nconst PHASE_MAP: Record<string, \"idle\" | \"operating\" | \"ended\"> = {\n idle: \"idle\",\n ended: \"ended\",\n};\n\nfunction normalizePhase(phase: string): \"idle\" | \"operating\" | \"ended\" {\n return PHASE_MAP[phase] ?? \"operating\";\n}\n\nfunction computeDisplacementValue(\n closeSwipeSign: 1 | -1,\n axis: \"x\" | \"y\",\n closeDisplacement: number,\n): { x: number; y: number } {\n const signedDisplacement = closeSwipeSign * closeDisplacement;\n if (axis === \"x\") {\n return { x: signedDisplacement, y: 0 };\n }\n return { x: 0, y: signedDisplacement };\n}\n\nfunction computeAxisDisplacement(\n displacement: { x: number; y: number },\n axis: \"x\" | \"y\",\n sign: 1 | -1,\n): number {\n // Multiply by sign so displacement is positive when moving in open direction\n // Use Math.max(0, ...) to prevent reverse movement from counting as forward\n if (axis === \"x\") {\n return Math.max(0, sign * displacement.x);\n }\n return Math.max(0, sign * displacement.y);\n}\n\nfunction isEdgeSwipeEnabled(enableEdgeSwipeOpen: boolean, isOpen: boolean): boolean {\n if (!enableEdgeSwipeOpen) {\n return false;\n }\n return !isOpen;\n}\n\nfunction isCloseSwipeEnabled(enableSwipeClose: boolean, isOpen: boolean): boolean {\n if (!enableSwipeClose) {\n return false;\n }\n return isOpen;\n}\n\nfunction isDrawerOpening(isEdgeGesture: boolean, isOpen: boolean): boolean {\n if (!isEdgeGesture) {\n return false;\n }\n return !isOpen;\n}\n\nfunction isDrawerClosing(closePhase: \"idle\" | \"operating\" | \"ended\", isOpen: boolean): boolean {\n if (closePhase === \"idle\") {\n return false;\n }\n return isOpen;\n}\n\nfunction computeVelocity(\n start: { x: number; y: number; timestamp: number } | null,\n current: { x: number; y: number; timestamp: number } | null,\n displacement: number,\n): number {\n if (!start || !current) {\n return 0;\n }\n const timeDelta = Math.max(1, current.timestamp - start.timestamp);\n return displacement / timeDelta;\n}\n\n/**\n * Hook for detecting swipe gestures to open/close a drawer.\n *\n * When drawer is closed:\n * - Detects edge swipe from the anchor edge to trigger open\n *\n * When drawer is open:\n * - Detects drag gesture within drawer to trigger close\n * - Respects scrollable content boundaries\n *\n * @example\n * ```tsx\n * const { state, edgeContainerProps, drawerContentProps } = useDrawerSwipeInput({\n * edgeContainerRef: gridLayoutRef,\n * drawerContentRef: drawerRef,\n * direction: \"left\",\n * isOpen,\n * onSwipeOpen: () => setOpen(true),\n * onSwipeClose: () => setOpen(false),\n * });\n * ```\n */\nexport function useDrawerSwipeInput(\n options: UseDrawerSwipeInputOptions,\n): UseDrawerSwipeInputResult {\n const {\n edgeContainerRef,\n drawerContentRef,\n direction,\n isOpen,\n onSwipeOpen,\n onSwipeClose,\n enableEdgeSwipeOpen = true,\n enableSwipeClose = true,\n edgeWidth = 20,\n dismissThreshold = DEFAULT_DISMISS_THRESHOLD,\n } = options;\n\n const axis = getDrawerAnimationAxis(direction);\n const closeSwipeSign = getDrawerCloseSwipeSign(direction);\n const openSwipeSign = getDrawerOpenSwipeSign(direction);\n\n // Track container size for progress calculation\n const containerSizeRef = React.useRef(0);\n\n // Measure drawer content size\n React.useLayoutEffect(() => {\n const container = drawerContentRef.current;\n if (!container) {\n return;\n }\n\n const updateSize = () => {\n containerSizeRef.current = getContainerSize(container, axis);\n };\n\n updateSize();\n\n const observer = new ResizeObserver(updateSize);\n observer.observe(container);\n\n return () => observer.disconnect();\n }, [drawerContentRef, axis]);\n\n // =========== Edge swipe to OPEN ===========\n const handleOpenSwipeEnd = React.useCallback(\n (state: { direction: 1 | -1 | 0 }) => {\n // Open when swiping in the correct direction (away from edge)\n if (state.direction === openSwipeSign) {\n onSwipeOpen();\n }\n },\n [openSwipeSign, onSwipeOpen],\n );\n\n const {\n isEdgeGesture,\n state: edgeSwipeState,\n containerProps: edgeSwipeProps,\n } = useEdgeSwipeInput({\n containerRef: edgeContainerRef,\n edge: direction,\n edgeWidth,\n enabled: isEdgeSwipeEnabled(enableEdgeSwipeOpen, isOpen),\n onSwipeEnd: handleOpenSwipeEnd,\n });\n\n // Native gesture guard for edge swipe\n const { containerProps: guardProps } = useNativeGestureGuard({\n containerRef: edgeContainerRef,\n active: isEdgeGesture,\n preventEdgeBack: true,\n preventOverscroll: true,\n edgeWidth,\n });\n\n // =========== Drag to CLOSE (Dialog pattern) ===========\n const { state: closeTracking, onPointerDown: baseClosePointerDown } = usePointerTracking({\n enabled: isCloseSwipeEnabled(enableSwipeClose, isOpen),\n });\n\n const [closePhase, setClosePhase] = React.useState<\"idle\" | \"operating\" | \"ended\">(\"idle\");\n const lastCloseDisplacementRef = React.useRef(0);\n\n // Wrap pointer down with scroll check and safe zone check\n const onClosePointerDown = React.useCallback(\n (event: React.PointerEvent) => {\n if (!enableSwipeClose || !isOpen) {\n return;\n }\n\n const container = drawerContentRef.current;\n if (!container) {\n return;\n }\n\n const target = event.target as HTMLElement;\n\n // Check if target is in a SwipeSafeZone\n if (isInSwipeSafeZone(target, container)) {\n return; // Don't start close swipe if inside safe zone\n }\n\n // Check if target is in a scrollable area that would block swipe\n if (isScrollableInDirection(target, container, axis, closeSwipeSign)) {\n return; // Don't start close swipe if inside scrollable content\n }\n\n baseClosePointerDown(event);\n },\n [enableSwipeClose, isOpen, drawerContentRef, axis, closeSwipeSign, baseClosePointerDown],\n );\n\n // Calculate close displacement\n const closeDisplacement = React.useMemo(() => {\n if (!closeTracking.isDown || !closeTracking.start || !closeTracking.current) {\n return lastCloseDisplacementRef.current;\n }\n\n const delta = getAxisDelta(closeTracking.start, closeTracking.current, axis);\n\n // Only count movement in close direction\n const signedDelta = delta * closeSwipeSign;\n return Math.max(0, signedDelta);\n }, [closeTracking.isDown, closeTracking.start, closeTracking.current, axis, closeSwipeSign]);\n\n // Track displacement while dragging\n React.useEffect(() => {\n if (closeTracking.isDown && closeTracking.current) {\n lastCloseDisplacementRef.current = closeDisplacement;\n }\n }, [closeTracking.isDown, closeTracking.current, closeDisplacement]);\n\n // Handle close drag start\n React.useEffect(() => {\n if (closeTracking.isDown && closePhase === \"idle\") {\n setClosePhase(\"operating\");\n }\n }, [closeTracking.isDown, closePhase]);\n\n // Handle close drag end\n React.useEffect(() => {\n if (!closeTracking.isDown && closePhase === \"operating\") {\n const displacement = lastCloseDisplacementRef.current;\n const hasMovement = displacement > 1;\n\n if (hasMovement) {\n setClosePhase(\"ended\");\n\n // Check if should close\n const containerSize = containerSizeRef.current;\n if (containerSize > 0) {\n const ratio = displacement / containerSize;\n const velocity = computeVelocity(closeTracking.start, closeTracking.current, displacement);\n\n if (ratio >= dismissThreshold || velocity >= VELOCITY_THRESHOLD) {\n onSwipeClose();\n }\n }\n } else {\n setClosePhase(\"idle\");\n lastCloseDisplacementRef.current = 0;\n }\n }\n }, [closeTracking.isDown, closePhase, dismissThreshold, onSwipeClose, closeTracking.start, closeTracking.current]);\n\n // Transition from ended to idle\n React.useEffect(() => {\n if (closePhase === \"ended\") {\n queueMicrotask(() => {\n setClosePhase(\"idle\");\n lastCloseDisplacementRef.current = 0;\n });\n }\n }, [closePhase]);\n\n // Reset close state when drawer closes\n React.useEffect(() => {\n if (!isOpen) {\n setClosePhase(\"idle\");\n lastCloseDisplacementRef.current = 0;\n }\n }, [isOpen]);\n\n // =========== Combined state ===========\n const isOpening = isDrawerOpening(isEdgeGesture, isOpen);\n const isClosing = isDrawerClosing(closePhase, isOpen);\n\n // Determine primary displacement based on current operation\n const displacement = React.useMemo(() => {\n if (isOpening) {\n return computeAxisDisplacement(edgeSwipeState.displacement, axis, openSwipeSign);\n }\n if (isClosing) {\n return closeDisplacement;\n }\n return 0;\n }, [isOpening, isClosing, axis, edgeSwipeState.displacement, closeDisplacement, openSwipeSign]);\n\n // Progress calculation\n const progress = React.useMemo(() => {\n const containerSize = containerSizeRef.current;\n if (containerSize <= 0) {\n return 0;\n }\n return Math.min(displacement / containerSize, 1);\n }, [displacement]);\n\n // Combined operation state\n const state = React.useMemo<ContinuousOperationState>(() => {\n if (isOpening) {\n return {\n phase: normalizePhase(edgeSwipeState.phase),\n displacement: edgeSwipeState.displacement,\n velocity: edgeSwipeState.velocity,\n };\n }\n if (isClosing) {\n return {\n phase: closePhase,\n displacement: computeDisplacementValue(closeSwipeSign, axis, closeDisplacement),\n velocity: { x: 0, y: 0 },\n };\n }\n return IDLE_CONTINUOUS_OPERATION_STATE;\n }, [isOpening, isClosing, edgeSwipeState, closePhase, closeDisplacement, axis, closeSwipeSign]);\n\n // Container props\n const edgeContainerProps = React.useMemo(\n () => mergeGestureContainerProps(edgeSwipeProps, guardProps),\n [edgeSwipeProps, guardProps],\n );\n\n const drawerContentProps = React.useMemo(() => ({\n onPointerDown: onClosePointerDown,\n style: {\n touchAction: \"none\" as const,\n userSelect: \"none\" as const,\n WebkitUserSelect: \"none\" as const,\n },\n }), [onClosePointerDown]);\n\n return {\n state,\n isOpening,\n isClosing,\n progress,\n displacement,\n edgeContainerProps,\n drawerContentProps,\n };\n}\n","/**\n * @file Drawer style computation utilities.\n *\n * Provides pure functions for computing drawer styles based on configuration.\n */\nimport type * as React from \"react\";\nimport type { DrawerBehavior } from \"../../types.js\";\nimport {\n COLOR_DRAWER_BACKDROP,\n DRAWER_TRANSITION_DURATION,\n DRAWER_TRANSITION_EASING,\n} from \"../../constants/styles.js\";\n\n/**\n * Base backdrop style shared by backdrop and edge zone.\n */\nexport const DRAWER_BACKDROP_BASE_STYLE: React.CSSProperties = {\n position: \"fixed\",\n inset: 0,\n background: COLOR_DRAWER_BACKDROP,\n};\n\n/**\n * Base drawer panel style.\n */\nexport const DRAWER_PANEL_BASE_STYLE: React.CSSProperties = {\n willChange: \"transform\",\n};\n\n/**\n * Placement-specific styles for drawer positioning.\n */\nexport type DrawerPlacement = \"left\" | \"right\" | \"top\" | \"bottom\";\n\nconst PLACEMENT_STYLES: Record<DrawerPlacement, React.CSSProperties> = {\n left: {\n top: 0,\n bottom: 0,\n left: 0,\n transform: \"translateX(-100%)\",\n },\n right: {\n top: 0,\n bottom: 0,\n right: 0,\n transform: \"translateX(100%)\",\n },\n top: {\n top: 0,\n left: 0,\n right: 0,\n transform: \"translateY(-100%)\",\n },\n bottom: {\n bottom: 0,\n left: 0,\n right: 0,\n transform: \"translateY(100%)\",\n },\n};\n\nconst OPEN_TRANSFORMS: Record<DrawerPlacement, string> = {\n left: \"translateX(0)\",\n right: \"translateX(0)\",\n top: \"translateY(0)\",\n bottom: \"translateY(0)\",\n};\n\n/**\n * Reveal mode: drawer starts partially hidden and slides in with content.\n * This creates a \"pull out\" effect rather than just content sliding away.\n */\nconst REVEAL_CLOSED_OFFSET_PERCENT = 30;\n\nconst REVEAL_CLOSED_TRANSFORMS: Record<DrawerPlacement, string> = {\n left: `translateX(-${REVEAL_CLOSED_OFFSET_PERCENT}%)`,\n right: `translateX(${REVEAL_CLOSED_OFFSET_PERCENT}%)`,\n top: `translateY(-${REVEAL_CLOSED_OFFSET_PERCENT}%)`,\n bottom: `translateY(${REVEAL_CLOSED_OFFSET_PERCENT}%)`,\n};\n\n/**\n * Get placement-specific style.\n */\nexport function getPlacementStyle(placement: DrawerPlacement): React.CSSProperties {\n return PLACEMENT_STYLES[placement];\n}\n\n/**\n * Get transform value for open state.\n */\nexport function getOpenTransform(placement: DrawerPlacement): string {\n return OPEN_TRANSFORMS[placement];\n}\n\n/**\n * Get closed transform value.\n */\nexport function getClosedTransform(placement: DrawerPlacement): string {\n return PLACEMENT_STYLES[placement].transform as string;\n}\n\n/**\n * Get reveal mode transform based on open state.\n * When closed, drawer is partially hidden. When open, fully visible.\n */\nexport function getRevealTransform(placement: DrawerPlacement, isOpen: boolean): string {\n if (isOpen) {\n return OPEN_TRANSFORMS[placement];\n }\n return REVEAL_CLOSED_TRANSFORMS[placement];\n}\n\n/**\n * Compute CSS transition value.\n */\nexport function computeTransitionValue(\n mode: DrawerBehavior[\"transitionMode\"] | undefined,\n duration: DrawerBehavior[\"transitionDuration\"],\n easing: DrawerBehavior[\"transitionEasing\"],\n): string | undefined {\n if (mode === \"none\") {\n return undefined;\n }\n\n const durationValue = duration ?? DRAWER_TRANSITION_DURATION;\n const easingValue = easing ?? DRAWER_TRANSITION_EASING;\n\n return `transform ${durationValue} ${easingValue}`;\n}\n\n/**\n * Compute backdrop transition value.\n */\nexport function computeBackdropTransition(\n mode: DrawerBehavior[\"transitionMode\"] | undefined,\n duration: DrawerBehavior[\"transitionDuration\"],\n): string | undefined {\n if (mode === \"none\") {\n return undefined;\n }\n return `opacity ${duration ?? \"220ms\"} ease`;\n}\n\n/**\n * Check if placement is horizontal (left/right).\n */\nexport function isHorizontalPlacement(placement: DrawerPlacement): boolean {\n return placement === \"left\" || placement === \"right\";\n}\n\n/**\n * Format dimension value to CSS string.\n */\nexport function formatDimension(value: string | number | undefined): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (typeof value === \"number\") {\n return `${value}px`;\n }\n return value;\n}\n\n// ============================================================================\n// Edge Zone Styles\n// ============================================================================\n\n/**\n * Options for computing edge zone style.\n */\nexport type EdgeZoneStyleOptions = {\n placement: DrawerPlacement;\n inline: boolean;\n edgeWidth: number;\n zIndex: number | undefined;\n};\n\n/**\n * Compute edge zone style based on placement and positioning context.\n *\n * The edge zone is positioned at the edge where the drawer appears from:\n * - left drawer: left edge of the container\n * - right drawer: right edge of the container\n * - top drawer: top edge of the container\n * - bottom drawer: bottom edge of the container\n *\n * When inline=true, uses absolute positioning (relative to parent container).\n * When inline=false, uses fixed positioning (relative to viewport).\n */\nexport function computeEdgeZoneStyle(options: EdgeZoneStyleOptions): React.CSSProperties {\n const { placement, inline, edgeWidth, zIndex } = options;\n const position = inline ? \"absolute\" : \"fixed\";\n const computedZIndex = zIndex !== undefined ? zIndex - 2 : 1000;\n\n return getEdgeZoneStyleByPlacement(placement, position, edgeWidth, computedZIndex);\n}\n\nfunction getEdgeZoneStyleByPlacement(\n placement: DrawerPlacement,\n position: \"absolute\" | \"fixed\",\n edgeWidth: number,\n zIndex: number,\n): React.CSSProperties {\n // Common base style\n const base: React.CSSProperties = {\n position,\n zIndex,\n background: \"transparent\",\n pointerEvents: \"auto\",\n };\n\n // Placement-specific positioning\n if (placement === \"left\") {\n return {\n ...base,\n top: 0,\n bottom: 0,\n left: 0,\n width: edgeWidth,\n };\n }\n\n if (placement === \"right\") {\n return {\n ...base,\n top: 0,\n bottom: 0,\n right: 0,\n width: edgeWidth,\n };\n }\n\n if (placement === \"top\") {\n return {\n ...base,\n top: 0,\n left: 0,\n right: 0,\n height: edgeWidth,\n };\n }\n\n // bottom\n return {\n ...base,\n bottom: 0,\n left: 0,\n right: 0,\n height: edgeWidth,\n };\n}\n","/**\n * @file Drawer swipe gesture configuration parsing.\n *\n * Normalizes swipeGestures config from DrawerBehavior into a consistent shape.\n */\nimport type { DrawerBehavior, WindowPosition } from \"../../types.js\";\nimport type { DrawerPlacement } from \"./drawerStyles.js\";\n\n/**\n * Normalized swipe gesture configuration.\n */\nexport type NormalizedSwipeConfig = {\n enabled: boolean;\n edgeSwipeOpen: boolean;\n swipeClose: boolean;\n edgeWidth: number;\n dismissThreshold: number;\n};\n\nconst DEFAULT_EDGE_WIDTH = 20;\nconst DEFAULT_DISMISS_THRESHOLD = 0.3;\n\nconst DISABLED_CONFIG: NormalizedSwipeConfig = {\n enabled: false,\n edgeSwipeOpen: false,\n swipeClose: false,\n edgeWidth: DEFAULT_EDGE_WIDTH,\n dismissThreshold: DEFAULT_DISMISS_THRESHOLD,\n};\n\nconst ENABLED_DEFAULT_CONFIG: NormalizedSwipeConfig = {\n enabled: true,\n edgeSwipeOpen: true,\n swipeClose: true,\n edgeWidth: DEFAULT_EDGE_WIDTH,\n dismissThreshold: DEFAULT_DISMISS_THRESHOLD,\n};\n\n/**\n * Parse swipeGestures config into normalized options.\n */\nexport function parseSwipeGesturesConfig(\n swipeGestures: DrawerBehavior[\"swipeGestures\"],\n): NormalizedSwipeConfig {\n if (swipeGestures === true) {\n return ENABLED_DEFAULT_CONFIG;\n }\n\n if (swipeGestures === false || swipeGestures === undefined) {\n return DISABLED_CONFIG;\n }\n\n return {\n enabled: true,\n edgeSwipeOpen: swipeGestures.edgeSwipeOpen ?? true,\n swipeClose: swipeGestures.swipeClose ?? true,\n edgeWidth: swipeGestures.edgeWidth ?? DEFAULT_EDGE_WIDTH,\n dismissThreshold: swipeGestures.dismissThreshold ?? DEFAULT_DISMISS_THRESHOLD,\n };\n}\n\n/**\n * Resolve drawer placement from anchor and position.\n */\nexport function resolvePlacement(\n anchor: DrawerBehavior[\"anchor\"],\n position: WindowPosition | undefined,\n): DrawerPlacement {\n if (anchor) {\n return anchor;\n }\n\n if (!position) {\n return \"right\";\n }\n\n if (position.left !== undefined) {\n return \"left\";\n }\n if (position.right !== undefined) {\n return \"right\";\n }\n if (position.top !== undefined) {\n return \"top\";\n }\n if (position.bottom !== undefined) {\n return \"bottom\";\n }\n\n return \"right\";\n}\n\n/**\n * Determine if edge zone should be visible.\n */\nexport function shouldShowEdgeZone(\n config: NormalizedSwipeConfig,\n isOpen: boolean,\n isOpening: boolean,\n): boolean {\n if (!config.enabled) {\n return false;\n }\n if (!config.edgeSwipeOpen) {\n return false;\n }\n // Show when closed or actively opening\n if (!isOpen) {\n return true;\n }\n return isOpening;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any -- Generic action helpers rely on 'any' to avoid over-constraining payload creators */\n/**\n * @file Utilities for defining typed action creators and reducer handler maps without external dependencies.\n */\n\nexport type AnyAction = { type: string };\n\nexport type AnyActionCreator = {\n (...args: any[]): AnyAction;\n readonly type: string;\n};\n\ntype PayloadCreator = (...args: any[]) => any;\n\ntype ActionFromPayload<Type extends string, Creator extends PayloadCreator> =\n ReturnType<Creator> extends undefined | void\n ? { type: Type }\n : { type: Type; payload: Exclude<ReturnType<Creator>, undefined> };\n\n/**\n * Creates a typed action creator with an attached literal `type` property.\n */\nexport function createAction<Type extends string>(type: Type): (() => { type: Type }) & { readonly type: Type };\nexport function createAction<Type extends string, Creator extends PayloadCreator>(\n type: Type,\n payloadCreator: Creator,\n): ((...args: Parameters<Creator>) => ActionFromPayload<Type, Creator>) & { readonly type: Type };\nexport function createAction<Type extends string, Creator extends PayloadCreator>(\n type: Type,\n payloadCreator?: Creator,\n) {\n if (!payloadCreator) {\n const actionCreator = (() => ({ type }) as const) as (() => { type: Type }) & { readonly type: Type };\n Object.defineProperty(actionCreator, \"type\", {\n value: type,\n writable: false,\n enumerable: true,\n });\n return actionCreator;\n }\n const actionCreator = ((...args: Parameters<Creator>) => {\n const payload = payloadCreator(...args);\n if (typeof payload === \"undefined\") {\n return { type } as const;\n }\n return { type, payload } as const;\n }) as ((...args: Parameters<Creator>) => ActionFromPayload<Type, Creator>) & { readonly type: Type };\n Object.defineProperty(actionCreator, \"type\", {\n value: type,\n writable: false,\n enumerable: true,\n });\n return actionCreator;\n}\n\nexport type ActionCreatorsMap = Record<string, AnyActionCreator>;\n\nexport type ActionUnion<Creators extends ActionCreatorsMap> = ReturnType<Creators[keyof Creators]>;\n\nexport type CaseReducer<State, Action extends AnyAction, Extra> = (state: State, action: Action, extra: Extra) => State;\n\nexport type BoundActionCreators<Creators extends ActionCreatorsMap> = {\n [Key in keyof Creators]: (...args: Parameters<Creators[Key]>) => ReturnType<Creators[Key]>;\n};\n\nexport const bindActionCreators = <Creators extends ActionCreatorsMap>(\n creators: Creators,\n dispatch: (action: ActionUnion<Creators>) => unknown,\n): BoundActionCreators<Creators> => {\n const bound = {} as BoundActionCreators<Creators>;\n (Object.keys(creators) as Array<keyof Creators>).forEach((key) => {\n const creator = creators[key];\n bound[key] = ((...args: Parameters<typeof creator>) => {\n const action = creator(...args);\n dispatch(action as ActionUnion<Creators>);\n return action;\n }) as BoundActionCreators<Creators>[keyof Creators];\n });\n return bound;\n};\n\nexport const createActionHandlerMap = <State, Creators extends ActionCreatorsMap, Extra = undefined>(\n creators: Creators,\n handlers: {\n [Key in keyof Creators]?: CaseReducer<State, ReturnType<Creators[Key]>, Extra>;\n },\n): Record<string, CaseReducer<State, ReturnType<Creators[keyof Creators]>, Extra>> => {\n const map: Record<string, CaseReducer<State, ReturnType<Creators[keyof Creators]>, Extra>> = {};\n\n (Object.keys(handlers) as Array<keyof Creators>).forEach((key) => {\n const handler = handlers[key];\n if (!handler) {\n return;\n }\n const creator = creators[key];\n if (!creator) {\n throw new Error(`Missing action creator for key \"${String(key)}\"`);\n }\n map[creator.type] = handler as CaseReducer<State, ReturnType<Creators[keyof Creators]>, Extra>;\n });\n\n return map;\n};\n","/**\n * @file Constants for reveal drawer state machine.\n *\n * Centralizes all threshold values used in reveal drawer behavior.\n * These values control swipe gestures, animations, and state transitions.\n */\n\n/**\n * Minimum swipe distance in pixels to trigger drawer open.\n * Used when opening via edge swipe gesture.\n * ~27% of a 375px mobile screen width.\n */\nexport const REVEAL_DRAWER_OPEN_DISTANCE_THRESHOLD = 100;\n\n/**\n * Ratio of drawer size that must be swiped to dismiss (close) the drawer.\n * Value between 0 and 1. When swiping to close, if displacement exceeds\n * this ratio of the drawer size, the drawer will close.\n */\nexport const REVEAL_DRAWER_DISMISS_RATIO = 0.3;\n\n/**\n * Percentage offset for drawer when closed.\n * The drawer is positioned at -30% (or +30% for right/bottom) when closed,\n * creating a \"pull out\" parallax effect during the reveal animation.\n */\nexport const REVEAL_DRAWER_CLOSED_OFFSET_PERCENT = 30;\n\n/**\n * Animation duration in milliseconds for reveal transitions.\n */\nexport const REVEAL_DRAWER_ANIMATION_DURATION = 300;\n\n/**\n * Threshold in pixels below which positions are considered equal.\n * Used to determine if animation is needed between two positions.\n */\nexport const REVEAL_DRAWER_SNAP_THRESHOLD = 1;\n","/**\n * @file Generic state machine for drawer animations.\n *\n * This module provides a React-independent state machine for managing drawer\n * transitions. It handles swipe gestures, button operations, and animations through\n * a reducer pattern with typed actions.\n *\n * The position type is generic, allowing different drawer modes (reveal, overlay)\n * to use the same state machine logic with mode-specific position calculations.\n *\n * Key design principles:\n * - Pure functions: same input → same output\n * - No React/DOM dependencies\n * - Testable in isolation\n * - Deterministic state transitions\n */\n\nimport { createAction, createActionHandlerMap } from \"../../utils/typedActions.js\";\nimport type { DrawerTransformStrategy, DrawerStrategyConfig } from \"./strategies/types.js\";\nimport {\n REVEAL_DRAWER_OPEN_DISTANCE_THRESHOLD,\n REVEAL_DRAWER_DISMISS_RATIO,\n} from \"./revealDrawerConstants.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Phase of drawer animation lifecycle.\n * - closed: Drawer is hidden\n * - opening: Drawer is animating open\n * - open: Drawer is fully visible\n * - closing: Drawer is animating closed\n */\nexport type DrawerPhase = \"closed\" | \"opening\" | \"open\" | \"closing\";\n\n/**\n * Direction of swipe gesture.\n */\nexport type SwipeDirection = \"opening\" | \"closing\" | null;\n\n/**\n * Animation state tracking from/to positions.\n */\nexport type AnimationState<TPosition> = {\n /** Animation type */\n type: \"opening\" | \"closing\";\n /** Starting position */\n from: TPosition;\n /** Target position */\n to: TPosition;\n};\n\n/**\n * Complete state for drawer.\n */\nexport type DrawerState<TPosition> = {\n /** Current animation phase */\n phase: DrawerPhase;\n /** Target open state (what the drawer should be after current operation) */\n targetOpen: boolean;\n /** Current position */\n position: TPosition;\n /** Whether a swipe operation is active */\n isOperating: boolean;\n /** Direction of current swipe */\n swipeDirection: SwipeDirection;\n /** Current swipe displacement in pixels */\n displacement: number;\n /** Animation state if animating */\n animation: AnimationState<TPosition> | null;\n};\n\n// ============================================================================\n// Pure Computation Functions\n// ============================================================================\n\n/**\n * Compute progress (0-1) from displacement.\n *\n * @param displacement - Current swipe displacement in pixels\n * @param drawerSize - Size of the drawer in pixels\n * @param direction - Swipe direction (\"opening\" or \"closing\")\n * @returns Progress value between 0 and 1\n */\nexport function computeProgressFromDisplacement(\n displacement: number,\n drawerSize: number,\n direction: SwipeDirection,\n): number {\n if (drawerSize <= 0 || direction === null) {\n return 0;\n }\n\n const ratio = Math.min(1, Math.max(0, displacement / drawerSize));\n\n if (direction === \"opening\") {\n return ratio;\n }\n return 1 - ratio;\n}\n\n/**\n * Determine if drawer should open or close after swipe ends.\n *\n * @param displacement - Final swipe displacement in pixels\n * @param drawerSize - Size of the drawer in pixels\n * @param direction - Swipe direction\n * @returns true if drawer should be open, false if closed\n */\nexport function computeSwipeEndTarget(\n displacement: number,\n drawerSize: number,\n direction: SwipeDirection,\n): boolean {\n if (direction === \"opening\") {\n return displacement >= REVEAL_DRAWER_OPEN_DISTANCE_THRESHOLD;\n }\n if (direction === \"closing\") {\n const ratio = drawerSize > 0 ? displacement / drawerSize : 0;\n return ratio < REVEAL_DRAWER_DISMISS_RATIO;\n }\n return false;\n}\n\n// ============================================================================\n// Actions\n// ============================================================================\n\n/**\n * Action creators for drawer state machine.\n */\nexport const drawerActions = {\n /** Start swipe operation */\n swipeStart: createAction(\n \"SWIPE_START\",\n (direction: \"opening\" | \"closing\") => ({ direction }),\n ),\n\n /** Update swipe displacement */\n swipeUpdate: createAction(\n \"SWIPE_UPDATE\",\n (displacement: number) => ({ displacement }),\n ),\n\n /** End swipe operation */\n swipeEnd: createAction(\"SWIPE_END\"),\n\n /** Animation frame update */\n animationFrame: createAction(\n \"ANIMATION_FRAME\",\n (easedProgress: number) => ({ easedProgress }),\n ),\n\n /** Animation complete */\n animationComplete: createAction(\"ANIMATION_COMPLETE\"),\n\n /** Button open */\n buttonOpen: createAction(\"BUTTON_OPEN\"),\n\n /** Button close */\n buttonClose: createAction(\"BUTTON_CLOSE\"),\n\n /** Sync open state from external prop */\n syncOpenState: createAction(\n \"SYNC_OPEN_STATE\",\n (isOpen: boolean) => ({ isOpen }),\n ),\n\n /** Initialize state */\n initialize: createAction(\n \"INITIALIZE\",\n (isOpen: boolean) => ({ isOpen }),\n ),\n} as const;\n\nexport type DrawerAction = ReturnType<\n (typeof drawerActions)[keyof typeof drawerActions]\n>;\n\n// ============================================================================\n// Initial State Factory\n// ============================================================================\n\n/**\n * Get target position based on open state.\n */\nfunction getTargetPositionFromOpenState<TPosition>(\n isOpen: boolean,\n strategy: DrawerTransformStrategy<TPosition>,\n config: DrawerStrategyConfig,\n): TPosition {\n if (isOpen) {\n return strategy.getOpenPosition(config);\n }\n return strategy.getClosedPosition(config);\n}\n\n/**\n * Create initial state for drawer.\n *\n * @param isOpen - Initial open state\n * @param strategy - Transform strategy\n * @param config - Drawer configuration\n * @returns Initial state\n */\nexport function createDrawerInitialState<TPosition>(\n isOpen: boolean,\n strategy: DrawerTransformStrategy<TPosition>,\n config: DrawerStrategyConfig,\n): DrawerState<TPosition> {\n const position = getTargetPositionFromOpenState(isOpen, strategy, config);\n\n return {\n phase: isOpen ? \"open\" : \"closed\",\n targetOpen: isOpen,\n position,\n isOperating: false,\n swipeDirection: null,\n displacement: 0,\n animation: null,\n };\n}\n\n// ============================================================================\n// Reducer Factory\n// ============================================================================\n\n/**\n * Create a drawer reducer for a specific strategy.\n *\n * @param strategy - Transform strategy to use for position calculations\n * @returns Reducer function for the drawer state machine\n */\nexport function createDrawerReducer<TPosition>(\n strategy: DrawerTransformStrategy<TPosition>,\n) {\n type State = DrawerState<TPosition>;\n type ReducerHandler = (\n state: State,\n action: DrawerAction,\n config: DrawerStrategyConfig,\n ) => State;\n\n const handlers = createActionHandlerMap<State, typeof drawerActions, DrawerStrategyConfig>(\n drawerActions,\n {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- callback signature requires config\n swipeStart: (state, action, _config) => {\n if (!(\"payload\" in action)) {return state;}\n return {\n ...state,\n isOperating: true,\n swipeDirection: action.payload.direction,\n displacement: 0,\n animation: null,\n };\n },\n\n swipeUpdate: (state, action, config) => {\n if (!(\"payload\" in action)) {return state;}\n if (!state.isOperating) {return state;}\n\n const progress = computeProgressFromDisplacement(\n action.payload.displacement,\n config.drawerSize,\n state.swipeDirection,\n );\n const position = strategy.computePositionFromProgress(progress, config);\n\n return {\n ...state,\n displacement: action.payload.displacement,\n position,\n };\n },\n\n swipeEnd: (state, _action, config) => {\n if (!state.isOperating) {return state;}\n\n const targetOpen = computeSwipeEndTarget(\n state.displacement,\n config.drawerSize,\n state.swipeDirection,\n );\n const targetPosition = getTargetPositionFromOpenState(\n targetOpen,\n strategy,\n config\n );\n\n if (strategy.shouldAnimate(state.position, targetPosition)) {\n const animType = targetOpen ? \"opening\" : \"closing\";\n return {\n ...state,\n isOperating: false,\n swipeDirection: null,\n displacement: 0,\n targetOpen,\n phase: animType,\n animation: {\n type: animType,\n from: state.position,\n to: targetPosition,\n },\n };\n }\n\n return {\n ...state,\n isOperating: false,\n swipeDirection: null,\n displacement: 0,\n targetOpen,\n phase: targetOpen ? \"open\" : \"closed\",\n position: targetPosition,\n animation: null,\n };\n },\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- callback signature requires config\n animationFrame: (state, action, _config) => {\n if (!(\"payload\" in action)) {return state;}\n if (!state.animation) {return state;}\n\n const position = strategy.interpolatePosition(\n state.animation.from,\n state.animation.to,\n action.payload.easedProgress,\n );\n\n return {\n ...state,\n position,\n };\n },\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- callback signature requires action and config\n animationComplete: (state, _action, _config) => {\n if (!state.animation) {return state;}\n\n const isOpen = state.animation.type === \"opening\";\n return {\n ...state,\n phase: isOpen ? \"open\" : \"closed\",\n position: state.animation.to,\n animation: null,\n };\n },\n\n buttonOpen: (state, _action, config) => {\n if (state.phase === \"open\" || state.phase === \"opening\") {\n return state;\n }\n if (state.isOperating) {\n return state;\n }\n\n const targetPosition = strategy.getOpenPosition(config);\n const fromPosition = state.position;\n\n if (strategy.shouldAnimate(fromPosition, targetPosition)) {\n return {\n ...state,\n targetOpen: true,\n phase: \"opening\",\n animation: {\n type: \"opening\",\n from: fromPosition,\n to: targetPosition,\n },\n };\n }\n\n return {\n ...state,\n targetOpen: true,\n phase: \"open\",\n position: targetPosition,\n animation: null,\n };\n },\n\n buttonClose: (state, _action, config) => {\n if (state.phase === \"closed\" || state.phase === \"closing\") {\n return state;\n }\n if (state.isOperating) {\n return state;\n }\n\n const targetPosition = strategy.getClosedPosition(config);\n const fromPosition = state.position;\n\n if (strategy.shouldAnimate(fromPosition, targetPosition)) {\n return {\n ...state,\n targetOpen: false,\n phase: \"closing\",\n animation: {\n type: \"closing\",\n from: fromPosition,\n to: targetPosition,\n },\n };\n }\n\n return {\n ...state,\n targetOpen: false,\n phase: \"closed\",\n position: targetPosition,\n animation: null,\n };\n },\n\n syncOpenState: (state, action, config) => {\n if (!(\"payload\" in action)) {return state;}\n\n const { isOpen } = action.payload;\n\n if (state.targetOpen === isOpen && !state.isOperating && !state.animation) {\n return state;\n }\n\n if (state.isOperating) {\n return {\n ...state,\n targetOpen: isOpen,\n };\n }\n\n if (state.animation) {\n const animTarget = state.animation.type === \"opening\";\n if (animTarget === isOpen) {\n return {\n ...state,\n targetOpen: isOpen,\n };\n }\n }\n\n const currentlyOpen = state.phase === \"open\" || state.phase === \"opening\";\n if (currentlyOpen === isOpen) {\n return {\n ...state,\n targetOpen: isOpen,\n };\n }\n\n const targetPosition = getTargetPositionFromOpenState(\n isOpen,\n strategy,\n config\n );\n const fromPosition = state.position;\n\n if (strategy.shouldAnimate(fromPosition, targetPosition)) {\n const animType = isOpen ? \"opening\" : \"closing\";\n return {\n ...state,\n targetOpen: isOpen,\n phase: animType,\n animation: {\n type: animType,\n from: fromPosition,\n to: targetPosition,\n },\n };\n }\n\n return {\n ...state,\n targetOpen: isOpen,\n phase: isOpen ? \"open\" : \"closed\",\n position: targetPosition,\n animation: null,\n };\n },\n\n initialize: (_state, action, config) => {\n if (!(\"payload\" in action)) {return _state;}\n return createDrawerInitialState(action.payload.isOpen, strategy, config);\n },\n },\n );\n\n return function drawerReducer(\n state: State,\n action: DrawerAction,\n config: DrawerStrategyConfig,\n ): State {\n const handler = handlers[action.type] as ReducerHandler | undefined;\n if (handler) {\n return handler(state, action, config);\n }\n return state;\n };\n}\n","/**\n * @file Drawer transform strategy types.\n *\n * Defines the strategy pattern interface for different drawer animation modes.\n * Each mode (reveal, overlay) implements this interface with mode-specific\n * position calculations and DOM operations.\n */\n\nimport type { DrawerPlacement } from \"../../../components/window/drawerStyles.js\";\n\n// ============================================================================\n// Position Types\n// ============================================================================\n\n/**\n * Position values for reveal mode.\n * - Drawer moves from -30% to 0%\n * - Content moves from 0 to +drawerSize\n */\nexport type RevealPosition = {\n /** Drawer offset in pixels */\n drawerPx: number;\n /** Content offset in pixels */\n contentPx: number;\n};\n\n/**\n * Position values for overlay mode.\n * - Drawer moves from ±100% to 0%\n * - Backdrop opacity changes from 0 to 1\n */\nexport type OverlayPosition = {\n /** Drawer offset in pixels */\n drawerPx: number;\n /** Backdrop opacity (0-1) */\n backdropOpacity: number;\n};\n\n// ============================================================================\n// Configuration Types\n// ============================================================================\n\n/**\n * Configuration for drawer strategy calculations.\n */\nexport type DrawerStrategyConfig = {\n /** Drawer placement (left, right, top, bottom) */\n placement: DrawerPlacement;\n /** Drawer size in pixels */\n drawerSize: number;\n /** Content background color (reveal mode) */\n contentBackground?: string;\n};\n\n/**\n * DOM elements used by drawer strategies.\n */\nexport type DrawerElements = {\n /** Drawer element */\n drawer: HTMLElement | null;\n /** Content element (reveal mode) */\n content: HTMLElement | null;\n /** Backdrop element (overlay mode) */\n backdrop: HTMLElement | null;\n};\n\n// ============================================================================\n// Placement Configuration\n// ============================================================================\n\n/**\n * Placement configuration for transform calculations.\n */\nexport type PlacementConfig = {\n /** Transform axis (X or Y) */\n axis: \"X\" | \"Y\";\n /** Sign for transform direction (1 or -1) */\n sign: 1 | -1;\n};\n\n/**\n * Lookup table for placement configuration.\n */\nexport const PLACEMENT_CONFIG: Record<DrawerPlacement, PlacementConfig> = {\n left: { axis: \"X\", sign: 1 },\n right: { axis: \"X\", sign: -1 },\n top: { axis: \"Y\", sign: 1 },\n bottom: { axis: \"Y\", sign: -1 },\n};\n\n/**\n * Get placement configuration for a drawer placement.\n */\nexport function getPlacementConfig(placement: DrawerPlacement): PlacementConfig {\n return PLACEMENT_CONFIG[placement];\n}\n\n// ============================================================================\n// Strategy Interface\n// ============================================================================\n\n/**\n * Strategy interface for drawer transform calculations.\n *\n * Each drawer mode (reveal, overlay) implements this interface to provide\n * mode-specific position calculations and DOM operations while sharing\n * the common state machine logic.\n *\n * @typeParam TPosition - The position type used by this strategy\n */\nexport type DrawerTransformStrategy<TPosition> = {\n /**\n * Get the closed position (progress = 0).\n */\n getClosedPosition: (config: DrawerStrategyConfig) => TPosition;\n\n /**\n * Get the open position (progress = 1).\n */\n getOpenPosition: (config: DrawerStrategyConfig) => TPosition;\n\n /**\n * Compute position from progress (0 = closed, 1 = open).\n */\n computePositionFromProgress: (progress: number, config: DrawerStrategyConfig) => TPosition;\n\n /**\n * Interpolate between two positions.\n */\n interpolatePosition: (from: TPosition, to: TPosition, progress: number) => TPosition;\n\n /**\n * Determine if animation is needed between two positions.\n */\n shouldAnimate: (from: TPosition, to: TPosition) => boolean;\n\n /**\n * Apply position to DOM elements.\n */\n applyToDOM: (\n position: TPosition,\n elements: DrawerElements,\n config: DrawerStrategyConfig,\n ) => void;\n\n /**\n * Clear transforms from DOM elements.\n */\n clearFromDOM: (elements: DrawerElements, config: DrawerStrategyConfig) => void;\n\n /**\n * Called when opening animation starts (optional).\n */\n onOpeningStart?: (elements: DrawerElements, config: DrawerStrategyConfig) => void;\n\n /**\n * Called when closing animation completes (optional).\n */\n onClosingComplete?: (elements: DrawerElements, config: DrawerStrategyConfig) => void;\n};\n","/**\n * @file Drawer reveal animation utilities\n *\n * Provides transform calculations for reveal-mode drawer animations.\n * The reveal mode creates a \"pull out\" effect where:\n * - Drawer slides from partially hidden (-30%) to fully visible (0%)\n * - Content slides away to reveal the drawer behind it\n */\n\nimport type * as React from \"react\";\nimport type { DrawerPlacement } from \"./drawerStyles.js\";\n\n/**\n * Percentage offset for drawer when closed (creates \"pull out\" effect).\n */\nexport const DRAWER_CLOSED_OFFSET_PERCENT = 30;\n\n/**\n * Default animation duration in milliseconds.\n */\nexport const DEFAULT_ANIMATION_DURATION = 300;\n\n/**\n * Placement configuration for transforms.\n */\nexport type PlacementConfig = {\n axis: \"X\" | \"Y\";\n sign: 1 | -1;\n};\n\n/**\n * Lookup table for placement configuration.\n */\nconst PLACEMENT_CONFIG: Record<DrawerPlacement, PlacementConfig> = {\n left: { axis: \"X\", sign: 1 },\n right: { axis: \"X\", sign: -1 },\n top: { axis: \"Y\", sign: 1 },\n bottom: { axis: \"Y\", sign: -1 },\n};\n\n/**\n * Get placement configuration for a drawer placement.\n */\nexport function getPlacementConfig(placement: DrawerPlacement): PlacementConfig {\n return PLACEMENT_CONFIG[placement];\n}\n\n/**\n * Transform values for reveal drawer animation.\n */\nexport type RevealDrawerTransform = {\n /** Drawer offset in percentage */\n drawerOffsetPercent: number;\n /** Content offset in pixels */\n contentOffsetPx: number;\n};\n\n/**\n * Compute progress from swipe displacement.\n * Returns 0 (closed) to 1 (open).\n *\n * @param displacement - Current swipe displacement in pixels\n * @param drawerSize - Size of the drawer in pixels\n * @param isOpening - Whether the gesture is opening the drawer\n * @param isClosing - Whether the gesture is closing the drawer\n * @returns Progress value between 0 and 1\n */\nexport function computeSwipeProgress(\n displacement: number,\n drawerSize: number,\n isOpening: boolean,\n isClosing: boolean,\n): number {\n if (drawerSize <= 0) {\n return 0;\n }\n\n if (isOpening) {\n return Math.min(1, Math.max(0, displacement / drawerSize));\n }\n if (isClosing) {\n return Math.min(1, Math.max(0, 1 - displacement / drawerSize));\n }\n return 0;\n}\n\n/**\n * Compute reveal drawer transforms from progress.\n *\n * @param progress - Animation progress (0 = closed, 1 = open)\n * @param drawerSize - Size of the drawer in pixels\n * @param placement - Drawer placement\n * @returns Transform values for drawer and content\n */\nexport function computeRevealTransform(\n progress: number,\n drawerSize: number,\n placement: DrawerPlacement,\n): RevealDrawerTransform {\n const { sign } = PLACEMENT_CONFIG[placement];\n\n // Drawer moves from -30% (closed) to 0% (open)\n // For left: -30% to 0%\n // For right: +30% to 0%\n const offsetPercent = DRAWER_CLOSED_OFFSET_PERCENT * (1 - progress);\n const drawerOffsetPercent = sign > 0 ? -offsetPercent : offsetPercent;\n\n // Content moves from 0px (closed) to drawerSize (open)\n const contentOffsetPx = sign * drawerSize * progress;\n\n return {\n drawerOffsetPercent,\n contentOffsetPx,\n };\n}\n\n/**\n * Build drawer transform string from progress.\n *\n * @param progress - Animation progress (0 = closed, 1 = open)\n * @param placement - Drawer placement\n * @returns CSS transform string\n */\nexport function buildDrawerTransformString(\n progress: number,\n placement: DrawerPlacement,\n): string {\n const { axis } = PLACEMENT_CONFIG[placement];\n const transform = computeRevealTransform(progress, 0, placement);\n return `translate${axis}(${transform.drawerOffsetPercent}%)`;\n}\n\n/**\n * Build content transform string from progress.\n *\n * @param progress - Animation progress (0 = closed, 1 = open)\n * @param drawerSize - Size of the drawer in pixels\n * @param placement - Drawer placement\n * @returns CSS transform string\n */\nexport function buildContentTransformString(\n progress: number,\n drawerSize: number,\n placement: DrawerPlacement,\n): string {\n const { axis } = PLACEMENT_CONFIG[placement];\n const transform = computeRevealTransform(progress, drawerSize, placement);\n return `translate${axis}(${transform.contentOffsetPx}px)`;\n}\n\n/**\n * Stacking context styles for content element.\n * Applied during reveal animation to ensure proper z-index layering.\n */\nexport type StackingContextStyles = {\n position: string;\n zIndex: string;\n background: string;\n};\n\n/**\n * Default stacking context styles.\n */\nexport const STACKING_CONTEXT_STYLES: StackingContextStyles = {\n position: \"relative\",\n zIndex: \"1\",\n background: \"#fff\",\n};\n\n/**\n * Apply stacking context styles to an element.\n */\nexport function applyStackingContext(element: HTMLElement): void {\n element.style.position = STACKING_CONTEXT_STYLES.position;\n element.style.zIndex = STACKING_CONTEXT_STYLES.zIndex;\n element.style.background = STACKING_CONTEXT_STYLES.background;\n}\n\n/**\n * Clear stacking context styles from an element.\n */\nexport function clearStackingContext(element: HTMLElement): void {\n element.style.position = \"\";\n element.style.zIndex = \"\";\n element.style.background = \"\";\n}\n\n/**\n * Apply overflow hidden to body to prevent scrolling during drawer open.\n * This prevents both horizontal and vertical scrolling of the body\n * while the drawer is open or animating.\n */\nexport function applyOverflowHidden(): void {\n document.body.style.overflow = \"hidden\";\n}\n\n/**\n * Clear overflow hidden from body.\n */\nexport function clearOverflowHidden(): void {\n document.body.style.overflow = \"\";\n}\n\n/**\n * Get the content element to transform.\n *\n * @param inline - Whether drawer is inline mode\n * @param gridRef - Grid container ref for inline mode\n * @returns The content element or null\n */\nexport function getContentElement(\n inline: boolean,\n gridRef?: React.RefObject<HTMLElement | null>,\n): HTMLElement | null {\n if (inline) {\n return gridRef?.current ?? null;\n }\n return document.getElementById(\"root\") ?? (document.body.firstElementChild as HTMLElement | null);\n}\n\n// ============================================================================\n// Pixel-based transform computation (for animation continuity)\n// ============================================================================\n\n/**\n * Tracked position for drawer and content elements in pixels.\n */\nexport type RevealPositionPx = {\n /** Drawer offset in pixels */\n drawerPx: number;\n /** Content offset in pixels */\n contentPx: number;\n};\n\n/**\n * Compute drawer offset in pixels from progress.\n *\n * For reveal mode, the drawer animates from an offset position to 0.\n * The offset is DRAWER_CLOSED_OFFSET_PERCENT of the drawer's own size.\n *\n * @param progress - Animation progress (0 = closed, 1 = open)\n * @param drawerSize - Drawer size in pixels\n * @param placement - Drawer placement\n * @returns Drawer offset in pixels\n */\nexport function computeDrawerOffsetPx(\n progress: number,\n drawerSize: number,\n placement: DrawerPlacement,\n): number {\n const { sign } = PLACEMENT_CONFIG[placement];\n // Drawer offset at closed state: -30% of drawer size (or +30% for right/bottom)\n const maxOffsetPx = drawerSize * (DRAWER_CLOSED_OFFSET_PERCENT / 100);\n const offsetPx = maxOffsetPx * (1 - progress);\n return sign > 0 ? -offsetPx : offsetPx;\n}\n\n/**\n * Compute content offset in pixels from progress.\n *\n * Content moves from 0 (closed) to ±drawerSize (open).\n *\n * @param progress - Animation progress (0 = closed, 1 = open)\n * @param drawerSize - Drawer size in pixels\n * @param placement - Drawer placement\n * @returns Content offset in pixels\n */\nexport function computeContentOffsetPx(\n progress: number,\n drawerSize: number,\n placement: DrawerPlacement,\n): number {\n const { sign } = PLACEMENT_CONFIG[placement];\n return sign * drawerSize * progress;\n}\n\n/**\n * Compute both drawer and content offsets from progress.\n *\n * @param progress - Animation progress (0 = closed, 1 = open)\n * @param drawerSize - Drawer size in pixels\n * @param placement - Drawer placement\n * @returns Position in pixels for both elements\n */\nexport function computePositionFromProgress(\n progress: number,\n drawerSize: number,\n placement: DrawerPlacement,\n): RevealPositionPx {\n return {\n drawerPx: computeDrawerOffsetPx(progress, drawerSize, placement),\n contentPx: computeContentOffsetPx(progress, drawerSize, placement),\n };\n}\n\n/**\n * Compute target positions for open or closed state.\n *\n * @param isOpen - Whether target is the open state\n * @param drawerSize - Drawer size in pixels\n * @param placement - Drawer placement\n * @returns Target positions in pixels\n */\nexport function computeTargetPosition(\n isOpen: boolean,\n drawerSize: number,\n placement: DrawerPlacement,\n): RevealPositionPx {\n const targetProgress = isOpen ? 1 : 0;\n return computePositionFromProgress(targetProgress, drawerSize, placement);\n}\n\n/**\n * Compute position from swipe displacement.\n *\n * This is the main function for tracking position during swipe.\n *\n * @param displacement - Current swipe displacement in pixels\n * @param drawerSize - Drawer size in pixels\n * @param placement - Drawer placement\n * @param isOpening - Whether opening via swipe\n * @param isClosing - Whether closing via swipe\n * @returns Current position in pixels\n */\nexport function computePositionFromDisplacement(\n displacement: number,\n drawerSize: number,\n placement: DrawerPlacement,\n isOpening: boolean,\n isClosing: boolean,\n): RevealPositionPx {\n const progress = computeSwipeProgress(displacement, drawerSize, isOpening, isClosing);\n return computePositionFromProgress(progress, drawerSize, placement);\n}\n\n// ============================================================================\n// Pixel-based transform string builders\n// ============================================================================\n\n/**\n * Build drawer transform string from pixel offset.\n *\n * @param drawerPx - Drawer offset in pixels\n * @param placement - Drawer placement\n * @returns CSS transform string\n */\nexport function buildDrawerTransformPx(\n drawerPx: number,\n placement: DrawerPlacement,\n): string {\n const { axis } = PLACEMENT_CONFIG[placement];\n return `translate${axis}(${drawerPx}px)`;\n}\n\n/**\n * Build content transform string from pixel offset.\n *\n * @param contentPx - Content offset in pixels\n * @param placement - Drawer placement\n * @returns CSS transform string\n */\nexport function buildContentTransformPx(\n contentPx: number,\n placement: DrawerPlacement,\n): string {\n const { axis } = PLACEMENT_CONFIG[placement];\n return `translate${axis}(${contentPx}px)`;\n}\n\n// ============================================================================\n// Visibility management\n// ============================================================================\n\n/**\n * Show the drawer element.\n */\nexport function showDrawer(element: HTMLElement): void {\n element.style.visibility = \"visible\";\n element.style.pointerEvents = \"auto\";\n}\n\n/**\n * Hide the drawer element.\n */\nexport function hideDrawer(element: HTMLElement): void {\n element.style.visibility = \"hidden\";\n element.style.pointerEvents = \"none\";\n}\n\n/**\n * Clear drawer visibility styles.\n */\nexport function clearDrawerVisibility(element: HTMLElement): void {\n element.style.visibility = \"\";\n element.style.pointerEvents = \"\";\n}\n\n// ============================================================================\n// Stacking context with configurable background\n// ============================================================================\n\n/**\n * Apply stacking context styles with configurable background.\n *\n * @param element - Content element\n * @param background - Background color (defaults to #fff)\n */\nexport function applyStackingContextWithBackground(\n element: HTMLElement,\n background: string = STACKING_CONTEXT_STYLES.background,\n): void {\n element.style.position = STACKING_CONTEXT_STYLES.position;\n element.style.zIndex = STACKING_CONTEXT_STYLES.zIndex;\n element.style.background = background;\n}\n","/**\n * @file Reveal mode drawer transform strategy.\n *\n * Implements the reveal animation where:\n * - Drawer slides from -30% to 0% (parallax effect)\n * - Content slides from 0 to +drawerSize (reveals drawer behind)\n */\n\nimport type {\n DrawerTransformStrategy,\n RevealPosition,\n} from \"./types.js\";\nimport { getPlacementConfig } from \"./types.js\";\nimport {\n REVEAL_DRAWER_CLOSED_OFFSET_PERCENT,\n REVEAL_DRAWER_SNAP_THRESHOLD,\n} from \"../revealDrawerConstants.js\";\nimport {\n showDrawer,\n hideDrawer,\n clearStackingContext,\n applyStackingContextWithBackground,\n} from \"../../../components/window/drawerRevealAnimationUtils.js\";\n\n// ============================================================================\n// Reveal Strategy Implementation\n// ============================================================================\n\n/**\n * Reveal mode drawer transform strategy.\n */\nexport const revealStrategy: DrawerTransformStrategy<RevealPosition> = {\n getClosedPosition(config) {\n return this.computePositionFromProgress(0, config);\n },\n\n getOpenPosition(config) {\n return this.computePositionFromProgress(1, config);\n },\n\n computePositionFromProgress(progress, config) {\n const { sign } = getPlacementConfig(config.placement);\n const maxOffsetPx = config.drawerSize * (REVEAL_DRAWER_CLOSED_OFFSET_PERCENT / 100);\n const offsetPx = maxOffsetPx * (1 - progress);\n const drawerPx = sign > 0 ? -offsetPx : offsetPx;\n const contentPx = sign * config.drawerSize * progress;\n\n return { drawerPx, contentPx };\n },\n\n interpolatePosition(from, to, progress) {\n return {\n drawerPx: from.drawerPx + (to.drawerPx - from.drawerPx) * progress,\n contentPx: from.contentPx + (to.contentPx - from.contentPx) * progress,\n };\n },\n\n shouldAnimate(from, to) {\n return Math.abs(from.contentPx - to.contentPx) > REVEAL_DRAWER_SNAP_THRESHOLD;\n },\n\n applyToDOM(position, elements, config) {\n const { drawer, content } = elements;\n const { axis } = getPlacementConfig(config.placement);\n\n if (drawer) {\n drawer.style.transition = \"none\";\n drawer.style.transform = `translate${axis}(${position.drawerPx}px)`;\n }\n if (content) {\n applyStackingContextWithBackground(content, config.contentBackground);\n content.style.transition = \"none\";\n content.style.transform = `translate${axis}(${position.contentPx}px)`;\n }\n },\n\n clearFromDOM(elements) {\n const { drawer, content } = elements;\n\n if (drawer) {\n drawer.style.transform = \"\";\n drawer.style.transition = \"\";\n }\n if (content) {\n content.style.transform = \"\";\n content.style.transition = \"\";\n clearStackingContext(content);\n }\n },\n\n onOpeningStart(elements) {\n if (elements.drawer) {\n showDrawer(elements.drawer);\n }\n },\n\n onClosingComplete(elements) {\n const { drawer, content } = elements;\n\n if (drawer) {\n hideDrawer(drawer);\n drawer.style.transform = \"\";\n drawer.style.transition = \"\";\n }\n if (content) {\n content.style.transform = \"\";\n content.style.transition = \"\";\n clearStackingContext(content);\n }\n },\n};\n","/**\n * @file Overlay mode drawer transform strategy.\n *\n * Implements the overlay animation where:\n * - Drawer slides from ±100% to 0% (slides over content)\n * - Backdrop opacity changes from 0 to 1\n */\n\nimport type {\n DrawerTransformStrategy,\n OverlayPosition,\n DrawerStrategyConfig,\n} from \"./types.js\";\nimport { getPlacementConfig } from \"./types.js\";\n\n/**\n * Snap threshold for overlay mode (in pixels).\n */\nconst OVERLAY_SNAP_THRESHOLD = 1;\n\n// ============================================================================\n// Overlay Strategy Implementation\n// ============================================================================\n\n/**\n * Overlay mode drawer transform strategy.\n */\nexport const overlayStrategy: DrawerTransformStrategy<OverlayPosition> = {\n getClosedPosition(config) {\n const { sign } = getPlacementConfig(config.placement);\n // For overlay mode, drawer starts off-screen on its anchor side:\n // - LEFT drawer: closed at -drawerSize (off-screen left)\n // - RIGHT drawer: closed at +drawerSize (off-screen right)\n // The sign in PLACEMENT_CONFIG is for content movement direction,\n // so we negate it for overlay drawer position.\n return {\n drawerPx: -sign * config.drawerSize,\n backdropOpacity: 0,\n };\n },\n\n getOpenPosition() {\n return {\n drawerPx: 0,\n backdropOpacity: 1,\n };\n },\n\n computePositionFromProgress(progress, config) {\n const { sign } = getPlacementConfig(config.placement);\n // Negate sign for overlay mode (see getClosedPosition comment)\n const closedOffset = -sign * config.drawerSize;\n return {\n drawerPx: closedOffset * (1 - progress),\n backdropOpacity: progress,\n };\n },\n\n interpolatePosition(from, to, progress) {\n return {\n drawerPx: from.drawerPx + (to.drawerPx - from.drawerPx) * progress,\n backdropOpacity: from.backdropOpacity + (to.backdropOpacity - from.backdropOpacity) * progress,\n };\n },\n\n shouldAnimate(from, to) {\n return Math.abs(from.drawerPx - to.drawerPx) > OVERLAY_SNAP_THRESHOLD;\n },\n\n applyToDOM(position, elements, config) {\n const { drawer, backdrop } = elements;\n const { axis } = getPlacementConfig(config.placement);\n\n if (drawer) {\n drawer.style.transition = \"none\";\n drawer.style.transform = `translate${axis}(${position.drawerPx}px)`;\n }\n if (backdrop) {\n backdrop.style.opacity = String(position.backdropOpacity);\n backdrop.style.pointerEvents = position.backdropOpacity > 0 ? \"auto\" : \"none\";\n }\n },\n\n clearFromDOM(elements) {\n const { drawer, backdrop } = elements;\n\n // Clear all inline styles to restore CSS defaults\n if (drawer) {\n drawer.style.transform = \"\";\n drawer.style.transition = \"\";\n }\n if (backdrop) {\n backdrop.style.opacity = \"\";\n backdrop.style.pointerEvents = \"\";\n }\n },\n\n onOpeningStart() {\n // Overlay mode doesn't need special handling on opening start\n // The drawer is already positioned via CSS\n },\n\n onClosingComplete(elements, config) {\n const { drawer, backdrop } = elements;\n const closedTransform = getClosedTransformForPlacement(config);\n\n // Set to closed state (not clearing - that's clearFromDOM's job)\n if (drawer) {\n drawer.style.transform = closedTransform;\n drawer.style.transition = \"\";\n }\n if (backdrop) {\n backdrop.style.opacity = \"0\";\n backdrop.style.pointerEvents = \"none\";\n }\n },\n};\n\n/**\n * Get the closed transform string for a placement.\n */\nfunction getClosedTransformForPlacement(config: DrawerStrategyConfig): string {\n switch (config.placement) {\n case \"left\":\n return \"translateX(-100%)\";\n case \"right\":\n return \"translateX(100%)\";\n case \"top\":\n return \"translateY(-100%)\";\n case \"bottom\":\n return \"translateY(100%)\";\n }\n}\n","/**\n * @file Unified hook for drawer transform animations.\n *\n * This hook provides a single interface for both reveal and overlay drawer modes.\n * It uses a strategy pattern internally to handle mode-specific position calculations\n * and DOM operations while sharing the common state machine logic.\n */\nimport * as React from \"react\";\nimport { useAnimationFrame, easings } from \"../../hooks/useAnimationFrame.js\";\nimport type { ContinuousOperationState } from \"../../hooks/gesture/types.js\";\nimport type { DrawerPlacement } from \"./drawerStyles.js\";\nimport {\n createDrawerReducer,\n createDrawerInitialState,\n drawerActions,\n type DrawerPhase,\n type DrawerAction,\n} from \"../../modules/drawer/drawerStateMachine.js\";\nimport {\n revealStrategy,\n overlayStrategy,\n type DrawerStrategyConfig,\n type DrawerElements,\n type DrawerTransformStrategy,\n type RevealPosition,\n type OverlayPosition,\n} from \"../../modules/drawer/strategies/index.js\";\n\n/**\n * Union type for drawer positions (reveal or overlay mode).\n */\ntype DrawerPosition = RevealPosition | OverlayPosition;\n\n/**\n * Strategy type that works with either position type.\n */\ntype AnyDrawerStrategy = DrawerTransformStrategy<DrawerPosition>;\nimport { REVEAL_DRAWER_ANIMATION_DURATION } from \"../../modules/drawer/revealDrawerConstants.js\";\nimport {\n applyOverflowHidden,\n clearOverflowHidden,\n getContentElement,\n clearDrawerVisibility,\n} from \"./drawerRevealAnimationUtils.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Drawer animation mode.\n */\nexport type DrawerMode = \"reveal\" | \"overlay\";\n\n/**\n * Phase of drawer animation lifecycle.\n */\nexport type DrawerAnimationPhase = \"idle\" | \"opening\" | \"open\" | \"closing\" | \"closed\";\n\n/**\n * Options for useDrawerTransform hook.\n */\nexport type UseDrawerTransformOptions = {\n /** Animation mode */\n mode: DrawerMode;\n /** Ref to the drawer element */\n drawerRef: React.RefObject<HTMLElement | null>;\n /** Ref to the content element (reveal mode) */\n contentRef?: React.RefObject<HTMLElement | null>;\n /** Ref to the backdrop element (overlay mode) */\n backdropRef?: React.RefObject<HTMLElement | null>;\n /** Drawer placement */\n placement: DrawerPlacement;\n /** Drawer size in pixels */\n drawerSize: number;\n /** Whether the drawer is open */\n isOpen: boolean;\n /** Current swipe state */\n swipeState: ContinuousOperationState;\n /** Current swipe displacement */\n displacement: number;\n /** Whether opening via swipe */\n isOpening: boolean;\n /** Whether closing via swipe */\n isClosing: boolean;\n /** Whether this hook is enabled */\n enabled: boolean;\n /** Whether drawer is inline (affects content element for reveal mode) */\n inline?: boolean;\n /** Grid container ref for inline mode (reveal mode) */\n gridRef?: React.RefObject<HTMLElement | null>;\n /** Content background color (reveal mode) */\n contentBackground?: string;\n};\n\n/**\n * Result from useDrawerTransform hook.\n */\nexport type UseDrawerTransformResult = {\n /** Current animation phase */\n phase: DrawerAnimationPhase;\n /** Whether any animation is running */\n isAnimating: boolean;\n};\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * Select strategy based on drawer mode.\n */\nfunction selectStrategy(mode: DrawerMode): AnyDrawerStrategy {\n if (mode === \"reveal\") {\n return revealStrategy as AnyDrawerStrategy;\n }\n return overlayStrategy as AnyDrawerStrategy;\n}\n\n/**\n * Convert state machine phase to animation phase.\n */\nfunction toAnimationPhase(phase: DrawerPhase): DrawerAnimationPhase {\n return phase;\n}\n\n/**\n * Unified hook for drawer transform animations.\n *\n * Supports both reveal and overlay modes through a strategy pattern.\n */\nexport function useDrawerTransform(\n options: UseDrawerTransformOptions,\n): UseDrawerTransformResult {\n const {\n mode,\n drawerRef,\n contentRef,\n backdropRef,\n placement,\n drawerSize,\n isOpen,\n swipeState,\n displacement,\n isOpening,\n isClosing,\n enabled,\n inline = false,\n gridRef,\n contentBackground = \"#fff\",\n } = options;\n\n const isOperating = swipeState.phase === \"operating\";\n\n // Select strategy based on mode (cast to AnyDrawerStrategy for generic state machine)\n const strategy: AnyDrawerStrategy = selectStrategy(mode);\n\n // Config for strategy\n const config: DrawerStrategyConfig = React.useMemo(\n () => ({ placement, drawerSize, contentBackground }),\n [placement, drawerSize, contentBackground],\n );\n\n // Create reducer for the selected strategy\n const reducer = React.useMemo(\n () => createDrawerReducer(strategy),\n [strategy],\n );\n\n // State machine state\n const stateRef = React.useRef(\n createDrawerInitialState(isOpen, strategy, config),\n );\n\n // React state for phase (for external API)\n const [phase, setPhase] = React.useState<DrawerAnimationPhase>(\n isOpen ? \"open\" : \"closed\",\n );\n\n // Track previous values for detecting transitions\n // Note: enabled starts as false to ensure initialization runs on first mount.\n // This is critical for React Strict Mode compatibility where effects run twice.\n const prevRef = React.useRef({\n isOperating: false,\n isOpening: false,\n isClosing: false,\n isOpen,\n enabled: false,\n });\n\n // Resolve elements based on mode\n const resolveContentElement = (): HTMLElement | null => {\n if (mode !== \"reveal\") {\n return null;\n }\n return contentRef?.current ?? getContentElement(inline, gridRef);\n };\n\n const resolveBackdropElement = (): HTMLElement | null => {\n if (mode !== \"overlay\") {\n return null;\n }\n return backdropRef?.current ?? null;\n };\n\n const getElements = React.useCallback((): DrawerElements => {\n return {\n drawer: drawerRef.current,\n content: resolveContentElement(),\n backdrop: resolveBackdropElement(),\n };\n }, [mode, drawerRef, contentRef, backdropRef, inline, gridRef]);\n\n // Dispatch helper\n const dispatch = React.useCallback(\n (action: DrawerAction) => {\n const newState = reducer(stateRef.current, action, config);\n stateRef.current = newState;\n setPhase(toAnimationPhase(newState.phase));\n return newState;\n },\n [reducer, config],\n );\n\n // Animation frame handler\n const handleFrame = React.useCallback(\n ({ easedProgress }: { easedProgress: number }) => {\n const state = stateRef.current;\n if (!state.animation) {\n return;\n }\n\n const position = strategy.interpolatePosition(\n state.animation.from,\n state.animation.to,\n easedProgress,\n );\n\n stateRef.current = { ...state, position };\n\n const elements = getElements();\n strategy.applyToDOM(position, elements, config);\n },\n [strategy, getElements, config],\n );\n\n // Animation complete handler\n const handleComplete = React.useCallback(() => {\n const newState = dispatch(drawerActions.animationComplete());\n const elements = getElements();\n\n if (newState.phase === \"closed\") {\n strategy.onClosingComplete?.(elements, config);\n }\n }, [dispatch, strategy, getElements, config]);\n\n const { isAnimating, start, cancel } = useAnimationFrame({\n duration: REVEAL_DRAWER_ANIMATION_DURATION,\n easing: easings.easeOutExpo,\n onFrame: handleFrame,\n onComplete: handleComplete,\n });\n\n // Initialize drawer state on mount/enable\n React.useLayoutEffect(() => {\n if (!enabled) {\n prevRef.current.enabled = false;\n return;\n }\n\n if (prevRef.current.enabled) {\n return;\n }\n prevRef.current.enabled = true;\n\n // Re-initialize state machine\n stateRef.current = createDrawerInitialState(isOpen, strategy, config);\n setPhase(isOpen ? \"open\" : \"closed\");\n\n const elements = getElements();\n\n if (isOpen) {\n strategy.onOpeningStart?.(elements, config);\n strategy.applyToDOM(stateRef.current.position, elements, config);\n } else {\n strategy.onClosingComplete?.(elements, config);\n }\n }, [enabled, isOpen, strategy, config, getElements]);\n\n // Handle swipe start/end\n React.useLayoutEffect(() => {\n if (!enabled) {\n return;\n }\n\n const prev = prevRef.current;\n const wasOperating = prev.isOperating;\n const wasOpening = prev.isOpening;\n const wasClosing = prev.isClosing;\n\n prev.isOperating = isOperating;\n prev.isOpening = isOpening;\n prev.isClosing = isClosing;\n\n // Swipe start\n if (!wasOperating && isOperating) {\n cancel();\n const direction = isOpening ? \"opening\" : isClosing ? \"closing\" : null;\n if (direction) {\n dispatch(drawerActions.swipeStart(direction));\n }\n return;\n }\n\n // Swipe end\n if (wasOperating && !isOperating) {\n const newState = dispatch(drawerActions.swipeEnd());\n const elements = getElements();\n\n if (newState.animation) {\n strategy.onOpeningStart?.(elements, config);\n start();\n } else {\n if (newState.phase === \"open\") {\n strategy.onOpeningStart?.(elements, config);\n strategy.applyToDOM(newState.position, elements, config);\n } else if (newState.phase === \"closed\") {\n strategy.onClosingComplete?.(elements, config);\n }\n }\n return;\n }\n\n // Direction change during operation\n if (isOperating) {\n const currentDirection = isOpening ? \"opening\" : isClosing ? \"closing\" : null;\n const prevDirection = wasOpening ? \"opening\" : wasClosing ? \"closing\" : null;\n\n if (currentDirection !== prevDirection && currentDirection) {\n dispatch(drawerActions.swipeStart(currentDirection));\n }\n }\n }, [\n enabled,\n isOperating,\n isOpening,\n isClosing,\n dispatch,\n cancel,\n start,\n strategy,\n config,\n getElements,\n ]);\n\n // Handle displacement updates during swipe\n React.useLayoutEffect(() => {\n if (!enabled) {\n return;\n }\n if (!isOperating) {\n return;\n }\n if (!isOpening && !isClosing) {\n return;\n }\n\n const newState = dispatch(drawerActions.swipeUpdate(displacement));\n const elements = getElements();\n\n strategy.onOpeningStart?.(elements, config);\n strategy.applyToDOM(newState.position, elements, config);\n }, [\n enabled,\n isOperating,\n isOpening,\n isClosing,\n displacement,\n dispatch,\n strategy,\n config,\n getElements,\n ]);\n\n // Handle external isOpen prop changes\n React.useLayoutEffect(() => {\n if (!enabled) {\n return;\n }\n\n const prev = prevRef.current;\n if (prev.isOpen === isOpen) {\n return;\n }\n prev.isOpen = isOpen;\n\n if (isOperating) {\n dispatch(drawerActions.syncOpenState(isOpen));\n return;\n }\n\n if (isAnimating) {\n const currentTarget = stateRef.current.animation?.type === \"opening\";\n if (currentTarget === isOpen) {\n return;\n }\n }\n\n const newState = dispatch(drawerActions.syncOpenState(isOpen));\n const elements = getElements();\n\n if (newState.animation) {\n strategy.onOpeningStart?.(elements, config);\n strategy.applyToDOM(newState.animation.from, elements, config);\n start();\n } else if (!isAnimating) {\n if (newState.phase === \"open\") {\n strategy.onOpeningStart?.(elements, config);\n strategy.applyToDOM(newState.position, elements, config);\n } else if (newState.phase === \"closed\") {\n strategy.onClosingComplete?.(elements, config);\n }\n }\n }, [\n enabled,\n isOpen,\n isOperating,\n isAnimating,\n dispatch,\n start,\n strategy,\n config,\n getElements,\n ]);\n\n // Cleanup on disable\n React.useLayoutEffect(() => {\n if (enabled) {\n return;\n }\n if (!prevRef.current.enabled) {\n return;\n }\n\n const elements = getElements();\n strategy.clearFromDOM(elements, config);\n\n if (elements.drawer) {\n clearDrawerVisibility(elements.drawer);\n }\n }, [enabled, strategy, config, getElements]);\n\n // Effect A: Manage body overflow based on drawer state (reveal mode only)\n //\n // This effect runs frequently as isOpen/isOperating/isAnimating change.\n // Cleanup only clears overflow - safe to call repeatedly.\n React.useLayoutEffect(() => {\n if (!enabled || mode !== \"reveal\") {\n if (mode === \"reveal\") {\n clearOverflowHidden();\n }\n return;\n }\n\n const isActive = isOpen ? true : isOperating ? true : isAnimating;\n\n if (isActive) {\n applyOverflowHidden();\n } else {\n clearOverflowHidden();\n }\n\n return () => {\n clearOverflowHidden();\n };\n }, [enabled, mode, isOpen, isOperating, isAnimating]);\n\n // Effect B: Clear content element styles on unmount (reveal mode only)\n //\n // This effect has minimal dependencies (enabled, mode) so cleanup only runs:\n // - When enabled changes to false (handled by \"Cleanup on disable\" effect above)\n // - When mode changes (rare)\n // - On unmount (the main case we care about)\n //\n // Content styles are applied by strategy.applyToDOM() during swipe/animation.\n // Content styles are cleared by strategy.onClosingComplete() during NORMAL close.\n // This effect handles UNMOUNT where onClosingComplete never runs.\n React.useLayoutEffect(() => {\n if (!enabled || mode !== \"reveal\") {\n return;\n }\n\n return () => {\n const elements = getElements();\n if (elements.content) {\n strategy.clearFromDOM({ drawer: null, content: elements.content, backdrop: null }, config);\n }\n };\n }, [enabled, mode, strategy, config, getElements]);\n\n return {\n phase,\n isAnimating,\n };\n}\n","/**\n * @file Hook for applying real-time transform during drawer swipe gestures (backward-compatible wrapper).\n *\n * This hook is a thin wrapper around useDrawerTransform with mode=\"overlay\".\n * For new code, prefer using useDrawerTransform directly.\n *\n * @deprecated Use useDrawerTransform with mode=\"overlay\" instead.\n */\nimport * as React from \"react\";\nimport type { ContinuousOperationState } from \"../../hooks/gesture/types.js\";\nimport type { DrawerSwipeDirection } from \"../../modules/drawer/types.js\";\nimport { useDrawerTransform } from \"./useDrawerTransform.js\";\n\ntype UseDrawerSwipeTransformOptions = {\n drawerRef: React.RefObject<HTMLDivElement | null>;\n backdropRef: React.RefObject<HTMLDivElement | null>;\n placement: DrawerSwipeDirection;\n swipeState: ContinuousOperationState;\n displacement: number;\n isOpening: boolean;\n isClosing: boolean;\n isOpen: boolean;\n enabled: boolean;\n};\n\n/**\n * Apply real-time transform to drawer and backdrop during swipe.\n *\n * @deprecated Use useDrawerTransform with mode=\"overlay\" instead.\n */\nexport function useDrawerSwipeTransform(options: UseDrawerSwipeTransformOptions): void {\n const {\n drawerRef,\n backdropRef,\n placement,\n swipeState,\n displacement,\n isOpening,\n isClosing,\n isOpen,\n enabled,\n } = options;\n\n // Get drawer size from element\n const drawerSizeRef = React.useRef(0);\n React.useLayoutEffect(() => {\n const drawer = drawerRef.current;\n if (drawer) {\n const isHorizontal = placement === \"left\" || placement === \"right\";\n drawerSizeRef.current = isHorizontal ? drawer.clientWidth : drawer.clientHeight;\n }\n }, [drawerRef, placement]);\n\n useDrawerTransform({\n mode: \"overlay\",\n drawerRef,\n backdropRef,\n placement,\n drawerSize: drawerSizeRef.current,\n isOpen,\n swipeState,\n displacement,\n isOpening,\n isClosing,\n enabled,\n });\n}\n","/**\n * @file Context for coordinating reveal-mode drawer animations with GridLayout.\n *\n * When a drawer uses animationMode=\"reveal\", the main content needs to slide away\n * to reveal the drawer behind it. This context provides the communication mechanism\n * between DrawerLayers and GridLayout.\n */\nimport * as React from \"react\";\nimport type { DrawerAnimationMode } from \"../../types.js\";\nimport type { DrawerPlacement } from \"./drawerStyles.js\";\n\n/**\n * State for a reveal-mode drawer animation.\n */\nexport type DrawerRevealState = {\n /** ID of the drawer layer */\n layerId: string;\n /** Drawer placement */\n placement: DrawerPlacement;\n /** Whether the drawer is currently open */\n isOpen: boolean;\n /** Drawer size in pixels (width for left/right, height for top/bottom) */\n drawerSize: number;\n /** Whether swipe operation is in progress */\n isSwipeOperating: boolean;\n /** Current swipe displacement during operation */\n swipeDisplacement: number;\n /** Whether currently opening via swipe */\n isOpening: boolean;\n /** Whether currently closing via swipe */\n isClosing: boolean;\n /** Whether the drawer is inline (container-relative) or fixed (viewport-relative) */\n inline: boolean;\n};\n\n/**\n * Context value provided to GridLayout for reveal-mode animations.\n */\nexport type DrawerRevealContextValue = {\n /** Currently active reveal-mode drawer (only one at a time) */\n activeRevealDrawer: DrawerRevealState | null;\n /** Register/update a reveal-mode drawer state */\n setRevealState: (state: DrawerRevealState | null) => void;\n /** Grid container ref for inline mode transforms */\n gridRef: React.RefObject<HTMLElement | null> | null;\n /** Set the grid ref (called by GridLayout) */\n setGridRef: (ref: React.RefObject<HTMLElement | null> | null) => void;\n};\n\nconst defaultContextValue: DrawerRevealContextValue = {\n activeRevealDrawer: null,\n setRevealState: () => {},\n gridRef: null,\n setGridRef: () => {},\n};\n\nexport const DrawerRevealContext = React.createContext<DrawerRevealContextValue>(defaultContextValue);\n\n/**\n * Provider component for DrawerRevealContext.\n */\nexport const DrawerRevealProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const [activeRevealDrawer, setActiveRevealDrawer] = React.useState<DrawerRevealState | null>(null);\n const [gridRef, setGridRefState] = React.useState<React.RefObject<HTMLElement | null> | null>(null);\n\n const setRevealState = React.useCallback((state: DrawerRevealState | null) => {\n setActiveRevealDrawer(state);\n }, []);\n\n const setGridRef = React.useCallback((ref: React.RefObject<HTMLElement | null> | null) => {\n setGridRefState(ref);\n }, []);\n\n const value = React.useMemo(\n (): DrawerRevealContextValue => ({\n activeRevealDrawer,\n setRevealState,\n gridRef,\n setGridRef,\n }),\n [activeRevealDrawer, setRevealState, gridRef, setGridRef],\n );\n\n return <DrawerRevealContext.Provider value={value}>{children}</DrawerRevealContext.Provider>;\n};\n\n/**\n * Hook to consume DrawerRevealContext.\n */\nexport function useDrawerReveal(): DrawerRevealContextValue {\n return React.useContext(DrawerRevealContext);\n}\n\n/**\n * Check if the given animation mode is reveal mode.\n */\nexport function isRevealMode(animationMode: DrawerAnimationMode | undefined): boolean {\n return animationMode === \"reveal\";\n}\n","/**\n * @file Hook for managing reveal-mode drawer transform (backward-compatible wrapper).\n *\n * This hook is a thin wrapper around useDrawerTransform with mode=\"reveal\".\n * For new code, prefer using useDrawerTransform directly.\n *\n * @deprecated Use useDrawerTransform with mode=\"reveal\" instead.\n */\nimport * as React from \"react\";\nimport type { ContinuousOperationState } from \"../../hooks/gesture/types.js\";\nimport type { DrawerPlacement } from \"./drawerStyles.js\";\nimport {\n useDrawerTransform,\n type DrawerAnimationPhase,\n type UseDrawerTransformResult,\n} from \"./useDrawerTransform.js\";\nimport { getContentElement } from \"./drawerRevealAnimationUtils.js\";\n\n/**\n * Phase of reveal drawer animation lifecycle.\n * @deprecated Use DrawerAnimationPhase from useDrawerTransform.ts\n */\nexport type RevealDrawerAnimationPhase = DrawerAnimationPhase;\n\n/**\n * Options for useRevealDrawerTransform hook.\n */\nexport type UseRevealDrawerTransformOptions = {\n /** Ref to the drawer element */\n drawerRef: React.RefObject<HTMLElement | null>;\n /** Drawer placement */\n placement: DrawerPlacement;\n /** Drawer size in pixels */\n drawerSize: number;\n /** Whether the drawer is open */\n isOpen: boolean;\n /** Current swipe state */\n swipeState: ContinuousOperationState;\n /** Current swipe displacement */\n displacement: number;\n /** Whether opening via swipe */\n isOpening: boolean;\n /** Whether closing via swipe */\n isClosing: boolean;\n /** Whether this hook is enabled */\n enabled: boolean;\n /** Whether drawer is inline (affects target element) */\n inline: boolean;\n /** Grid container ref for inline mode */\n gridRef?: React.RefObject<HTMLElement | null>;\n /** Content background color for stacking context */\n contentBackground?: string;\n};\n\n/**\n * Result from useRevealDrawerTransform hook.\n */\nexport type UseRevealDrawerTransformResult = UseDrawerTransformResult;\n\n/**\n * Hook for managing reveal-mode drawer transform.\n *\n * @deprecated Use useDrawerTransform with mode=\"reveal\" instead.\n */\nexport function useRevealDrawerTransform(\n options: UseRevealDrawerTransformOptions,\n): UseRevealDrawerTransformResult {\n const {\n drawerRef,\n placement,\n drawerSize,\n isOpen,\n swipeState,\n displacement,\n isOpening,\n isClosing,\n enabled,\n inline,\n gridRef,\n contentBackground = \"#fff\",\n } = options;\n\n // Create a content ref that resolves the content element\n const contentRef = React.useRef<HTMLElement | null>(null);\n React.useLayoutEffect(() => {\n contentRef.current = getContentElement(inline, gridRef);\n }, [inline, gridRef]);\n\n return useDrawerTransform({\n mode: \"reveal\",\n drawerRef,\n contentRef,\n placement,\n drawerSize,\n isOpen,\n swipeState,\n displacement,\n isOpening,\n isClosing,\n enabled,\n inline,\n gridRef,\n contentBackground,\n });\n}\n","/**\n * @file Drawer component\n *\n * Mobile-friendly slide-in panel with backdrop support.\n * Supports swipe gestures for opening/closing.\n * Supports reveal mode where content slides to show drawer behind.\n */\nimport * as React from \"react\";\nimport type { DrawerBehavior, WindowPosition } from \"../../types.js\";\nimport {\n FloatingPanelCloseButton,\n FloatingPanelContent,\n FloatingPanelFrame,\n FloatingPanelHeader,\n FloatingPanelTitle,\n} from \"../paneling/FloatingPanelFrame.js\";\nimport {\n DRAWER_HEADER_PADDING_Y,\n DRAWER_HEADER_PADDING_X,\n DRAWER_HEADER_GAP,\n DRAWER_CONTENT_PADDING,\n} from \"../../constants/styles.js\";\nimport { useDrawerSwipeInput } from \"../../modules/drawer/useDrawerSwipeInput.js\";\nimport type { DrawerSwipeDirection } from \"../../modules/drawer/types.js\";\nimport {\n DRAWER_BACKDROP_BASE_STYLE,\n DRAWER_PANEL_BASE_STYLE,\n getPlacementStyle,\n getOpenTransform,\n computeTransitionValue,\n computeBackdropTransition,\n formatDimension,\n computeEdgeZoneStyle,\n} from \"./drawerStyles.js\";\nimport type { DrawerPlacement } from \"./drawerStyles.js\";\nimport {\n parseSwipeGesturesConfig,\n resolvePlacement,\n shouldShowEdgeZone,\n} from \"./drawerSwipeConfig.js\";\nimport { useDrawerSwipeTransform } from \"./useDrawerSwipeTransform.js\";\nimport { useDrawerReveal, isRevealMode } from \"./DrawerRevealContext.js\";\nimport { useRevealDrawerTransform } from \"./useRevealDrawerTransform.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type DrawerProps = {\n id: string;\n config: DrawerBehavior;\n isOpen: boolean;\n onClose: () => void;\n onOpen?: () => void;\n children: React.ReactNode;\n zIndex?: number;\n width?: string | number;\n height?: string | number;\n position?: WindowPosition;\n};\n\n// ============================================================================\n// Sub-components\n// ============================================================================\n\ntype DrawerContentProps = {\n chrome: boolean;\n frameStyle: React.CSSProperties;\n header?: DrawerBehavior[\"header\"];\n dismissible: boolean;\n onClose: () => void;\n children: React.ReactNode;\n};\n\nconst DrawerContent: React.FC<DrawerContentProps> = ({\n chrome,\n frameStyle,\n header,\n dismissible,\n onClose,\n children,\n}) => {\n if (!chrome) {\n return <>{children}</>;\n }\n return (\n <FloatingPanelFrame style={frameStyle}>\n <DrawerHeaderView header={header} dismissible={dismissible} onClose={onClose} />\n <FloatingPanelContent\n style={{ padding: DRAWER_CONTENT_PADDING, flex: 1, display: \"flex\", flexDirection: \"column\" }}\n >\n {children}\n </FloatingPanelContent>\n </FloatingPanelFrame>\n );\n};\n\ntype DrawerHeaderViewProps = {\n header?: DrawerBehavior[\"header\"];\n dismissible: boolean;\n onClose: () => void;\n};\n\nfunction shouldShowCloseButton(dismissible: boolean, showCloseButton: boolean): boolean {\n if (!dismissible) {\n return false;\n }\n return showCloseButton;\n}\n\nfunction renderCloseButton(\n shouldShow: boolean,\n onClose: () => void,\n): React.ReactNode {\n if (!shouldShow) {\n return null;\n }\n return (\n <FloatingPanelCloseButton\n onClick={onClose}\n aria-label=\"Close drawer\"\n style={{ marginLeft: \"auto\" }}\n />\n );\n}\n\nfunction renderEdgeZone(\n showEdgeZone: boolean,\n edgeZoneRef: React.RefObject<HTMLDivElement | null>,\n edgeZoneStyle: React.CSSProperties,\n onPointerDown: ((e: React.PointerEvent<HTMLElement>) => void) | undefined,\n placement: string,\n): React.ReactNode {\n if (!showEdgeZone) {\n return null;\n }\n return (\n <div\n ref={edgeZoneRef}\n style={edgeZoneStyle}\n onPointerDown={onPointerDown}\n data-drawer-edge-zone={placement}\n />\n );\n}\n\n/**\n * Compute drawer size from props based on placement direction.\n */\nfunction computeDrawerSize(\n placement: string,\n width: string | number | undefined,\n height: string | number | undefined,\n): number {\n const isHorizontal = placement === \"left\" || placement === \"right\";\n if (isHorizontal) {\n return typeof width === \"number\" ? width : 0;\n }\n return typeof height === \"number\" ? height : 0;\n}\n\nconst DrawerHeaderView: React.FC<DrawerHeaderViewProps> = ({ header, dismissible, onClose }) => {\n if (!header) {\n return null;\n }\n\n const showCloseButton = header.showCloseButton ?? true;\n const shouldShow = shouldShowCloseButton(dismissible, showCloseButton);\n\n return (\n <FloatingPanelHeader\n style={{ padding: `${DRAWER_HEADER_PADDING_Y} ${DRAWER_HEADER_PADDING_X}`, gap: DRAWER_HEADER_GAP }}\n >\n <FloatingPanelTitle>{header.title}</FloatingPanelTitle>\n {renderCloseButton(shouldShow, onClose)}\n </FloatingPanelHeader>\n );\n};\n\n// ============================================================================\n// Style computation hooks\n// ============================================================================\n\nfunction useDrawerPanelStyle(\n placement: DrawerPlacement,\n isOpen: boolean,\n isSwipeOperating: boolean,\n config: DrawerBehavior,\n dimensions: { width?: string | number; height?: string | number; zIndex?: number },\n): React.CSSProperties {\n const revealMode = isRevealMode(config.animationMode);\n\n return React.useMemo((): React.CSSProperties => {\n // Position follows inline setting consistently for all modes:\n // - inline: true → absolute (container-relative)\n // - inline: false → fixed (viewport-relative)\n const position = config.inline ? \"absolute\" : \"fixed\";\n const placementStyle = getPlacementStyle(placement);\n\n // In reveal mode, drawer transform is handled entirely by useRevealDrawerTransform hook.\n // No transform or transition in React styles - the hook manages all DOM manipulation.\n // This is critical to avoid conflicts between React styles and hook's direct DOM updates.\n if (revealMode) {\n return {\n ...DRAWER_PANEL_BASE_STYLE,\n position,\n // Only position properties from placementStyle, NOT transform\n top: placementStyle.top,\n bottom: placementStyle.bottom,\n left: placementStyle.left,\n right: placementStyle.right,\n // No transform here - hook manages it\n // No transition - hook uses requestAnimationFrame\n // z-index: 0 ensures drawer is behind #root (which has z-index: 1)\n zIndex: 0,\n // Hidden by default - hook will show when needed\n visibility: \"hidden\",\n pointerEvents: \"none\",\n width: formatDimension(dimensions.width),\n height: formatDimension(dimensions.height),\n };\n }\n\n // Overlay mode (default): drawer slides over content\n const effectiveMode = isSwipeOperating ? \"none\" : config.transitionMode;\n const transitionValue = computeTransitionValue(\n effectiveMode,\n config.transitionDuration,\n config.transitionEasing,\n );\n\n const transform = isOpen ? getOpenTransform(placement) : placementStyle.transform;\n\n return {\n ...DRAWER_PANEL_BASE_STYLE,\n position,\n ...placementStyle,\n transform,\n transition: transitionValue,\n zIndex: dimensions.zIndex,\n width: formatDimension(dimensions.width),\n height: formatDimension(dimensions.height),\n };\n }, [placement, isOpen, isSwipeOperating, config, dimensions, revealMode]);\n}\n\nfunction useBackdropStyle(\n isOpen: boolean,\n isSwipeOperating: boolean,\n config: DrawerBehavior,\n zIndex: number | undefined,\n hookControlled: boolean,\n): React.CSSProperties {\n const revealMode = isRevealMode(config.animationMode);\n\n return React.useMemo((): React.CSSProperties => {\n // In reveal mode, no backdrop is shown (content slides instead)\n if (revealMode) {\n return {\n display: \"none\",\n };\n }\n\n const position = config.inline ? \"absolute\" as const : \"fixed\" as const;\n\n // When hook controls the backdrop (overlay mode with swipe enabled),\n // don't set opacity or transition - the hook handles all animations via DOM\n if (hookControlled) {\n return {\n ...DRAWER_BACKDROP_BASE_STYLE,\n position,\n // Initial state: hidden. Hook will manage opacity dynamically.\n opacity: 0,\n pointerEvents: \"none\",\n zIndex: zIndex !== undefined ? zIndex - 1 : undefined,\n };\n }\n\n const effectiveMode = isSwipeOperating ? \"none\" : config.transitionMode;\n const transitionValue = computeBackdropTransition(effectiveMode, config.transitionDuration);\n\n return {\n ...DRAWER_BACKDROP_BASE_STYLE,\n position,\n opacity: isOpen ? 1 : 0,\n pointerEvents: isOpen ? \"auto\" : \"none\",\n transition: transitionValue,\n zIndex: zIndex !== undefined ? zIndex - 1 : undefined,\n };\n }, [isOpen, isSwipeOperating, config, zIndex, revealMode, hookControlled]);\n}\n\nfunction useFrameStyle(placement: DrawerPlacement): React.CSSProperties {\n return React.useMemo((): React.CSSProperties => {\n const style: React.CSSProperties = { borderRadius: 0 };\n if (placement === \"left\" || placement === \"right\") {\n style.height = \"100%\";\n }\n return style;\n }, [placement]);\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\nexport const Drawer: React.FC<DrawerProps> = ({\n id,\n config,\n isOpen,\n onClose,\n onOpen,\n children,\n zIndex,\n width,\n height,\n position,\n}) => {\n const {\n dismissible = true,\n header,\n chrome = true,\n inline = false,\n } = config;\n\n const swipeConfig = parseSwipeGesturesConfig(config.swipeGestures);\n const placement = resolvePlacement(config.anchor, position);\n\n // Refs\n const drawerRef = React.useRef<HTMLDivElement>(null);\n const backdropRef = React.useRef<HTMLDivElement>(null);\n const edgeZoneRef = React.useRef<HTMLDivElement>(null);\n\n // Swipe callbacks\n const handleSwipeOpen = React.useCallback(() => {\n onOpen?.();\n config.onStateChange?.(true);\n }, [onOpen, config]);\n\n const handleSwipeClose = React.useCallback(() => {\n onClose();\n }, [onClose]);\n\n // Swipe input handling\n const {\n state: swipeState,\n displacement,\n edgeContainerProps,\n drawerContentProps,\n isOpening,\n isClosing,\n } = useDrawerSwipeInput({\n edgeContainerRef: edgeZoneRef,\n drawerContentRef: drawerRef,\n direction: placement as DrawerSwipeDirection,\n isOpen,\n onSwipeOpen: handleSwipeOpen,\n onSwipeClose: handleSwipeClose,\n enableEdgeSwipeOpen: swipeConfig.edgeSwipeOpen,\n enableSwipeClose: swipeConfig.swipeClose,\n edgeWidth: swipeConfig.edgeWidth,\n dismissThreshold: swipeConfig.dismissThreshold,\n });\n\n // During \"ended\" phase, isOpen hasn't been updated yet, so we still need to\n // disable transitions to avoid the drawer snapping to closed position briefly.\n const isSwipeOperating = swipeState.phase === \"operating\" || swipeState.phase === \"ended\";\n const revealMode = isRevealMode(config.animationMode);\n\n // Apply swipe transform (only for overlay mode)\n // In reveal mode, swipe transform is handled by useRevealDrawerTransform\n const swipeTransformEnabled = swipeConfig.enabled ? !revealMode : false;\n useDrawerSwipeTransform({\n drawerRef,\n backdropRef,\n placement: placement as DrawerSwipeDirection,\n swipeState,\n displacement,\n isOpening,\n isClosing,\n isOpen,\n enabled: swipeTransformEnabled,\n });\n\n // Compute drawer size from props (single source of truth)\n const drawerSize = computeDrawerSize(placement, width, height);\n\n // Get gridRef from context for inline mode\n const { gridRef } = useDrawerReveal();\n\n // Apply reveal mode transform (handles both drawer and content animation)\n // Enabled for both inline and non-inline reveal mode\n useRevealDrawerTransform({\n drawerRef,\n placement: placement as DrawerPlacement,\n drawerSize,\n isOpen,\n swipeState,\n displacement,\n isOpening,\n isClosing,\n enabled: revealMode,\n inline,\n gridRef: gridRef ?? undefined,\n contentBackground: config.revealBackground,\n });\n\n // Computed styles\n const drawerStyle = useDrawerPanelStyle(placement, isOpen, isSwipeOperating, config, { width, height, zIndex });\n const backdropStyle = useBackdropStyle(isOpen, isSwipeOperating, config, zIndex, swipeTransformEnabled);\n const frameStyle = useFrameStyle(placement);\n\n // Edge zone style: merge positioning style with gesture handlers' style\n // Edge zone positioning follows the inline setting for consistency with drawer and backdrop:\n // - inline: true → position: absolute (container-relative)\n // - inline: false → position: fixed (viewport-relative)\n const edgeZoneStyle = React.useMemo((): React.CSSProperties => {\n const positioningStyle = computeEdgeZoneStyle({\n placement,\n inline,\n edgeWidth: swipeConfig.edgeWidth,\n zIndex,\n });\n // Merge with gesture container styles (touchAction, etc.)\n return { ...positioningStyle, ...edgeContainerProps.style };\n }, [placement, inline, swipeConfig.edgeWidth, zIndex, edgeContainerProps.style]);\n\n // Merged drawer style with swipe props\n const mergedDrawerStyle = React.useMemo((): React.CSSProperties => {\n if (!swipeConfig.enabled) {\n return drawerStyle;\n }\n return { ...drawerStyle, ...drawerContentProps.style };\n }, [swipeConfig.enabled, drawerStyle, drawerContentProps.style]);\n\n // Visibility flags\n const showEdgeZone = shouldShowEdgeZone(swipeConfig, isOpen, isOpening);\n const ariaLabel = header?.title ?? config.ariaLabel ?? \"Drawer\";\n\n const edgeZoneElement = renderEdgeZone(showEdgeZone, edgeZoneRef, edgeZoneStyle, edgeContainerProps.onPointerDown, placement);\n\n return (\n <>\n {edgeZoneElement}\n <div\n ref={backdropRef}\n style={backdropStyle}\n onClick={dismissible ? onClose : undefined}\n />\n <div\n ref={drawerRef}\n data-layer-id={id}\n data-placement={placement}\n style={mergedDrawerStyle}\n role=\"dialog\"\n aria-modal={dismissible ? true : undefined}\n aria-hidden={isOpen ? undefined : true}\n aria-label={ariaLabel}\n onPointerDown={swipeConfig.enabled ? drawerContentProps.onPointerDown : undefined}\n >\n <DrawerContent\n chrome={chrome}\n frameStyle={frameStyle}\n header={header}\n dismissible={dismissible}\n onClose={onClose}\n >\n {children}\n </DrawerContent>\n </div>\n </>\n );\n};\n","/**\n * @file Generic transition state management with animation support.\n */\nimport * as React from \"react\";\n\nexport type TransitionMode = \"none\" | \"css\";\n\nexport type TransitionOptions = {\n mode?: TransitionMode;\n element?: React.RefObject<HTMLElement>;\n duration?: number;\n};\n\nexport type UseTransitionStateOptions = {\n onOpen?: (id: string) => void;\n onClose?: (id: string) => void;\n onTransitionEnd?: (id: string, isOpen: boolean) => void;\n};\n\nconst waitForTransitionEnd = (el: HTMLElement, timeout: number): Promise<void> =>\n new Promise((resolve) => {\n // eslint-disable-next-line no-restricted-syntax -- mutable flag needed for deduplication\n let resolved = false;\n const done = () => {\n if (resolved) {return;}\n resolved = true;\n el.removeEventListener(\"transitionend\", handler);\n resolve();\n };\n const handler = (e: TransitionEvent) => {\n if (e.target === el) {done();}\n };\n el.addEventListener(\"transitionend\", handler);\n setTimeout(done, timeout + 50);\n });\n\nexport const runTransition = async (\n update: () => void,\n mode: TransitionMode,\n el: HTMLElement | null | undefined,\n duration: number,\n): Promise<void> => {\n switch (mode) {\n case \"none\":\n update();\n return;\n\n case \"css\":\n update();\n if (el) {await waitForTransitionEnd(el, duration);}\n return;\n }\n};\n\nexport const useTransitionState = (options?: UseTransitionStateOptions) => {\n const [states, setStates] = React.useState<Record<string, boolean>>({});\n const optionsRef = React.useRef(options);\n optionsRef.current = options;\n\n const update = React.useCallback(\n async (id: string, isOpen: boolean, transitionOptions?: TransitionOptions) => {\n const { mode = \"none\", element, duration = 300 } = transitionOptions ?? {};\n\n const applyState = () => {\n setStates((prev) => {\n if (prev[id] === isOpen) {return prev;}\n return { ...prev, [id]: isOpen };\n });\n };\n\n await runTransition(applyState, mode, element?.current, duration);\n\n const opts = optionsRef.current;\n if (isOpen) {\n opts?.onOpen?.(id);\n } else {\n opts?.onClose?.(id);\n }\n opts?.onTransitionEnd?.(id, isOpen);\n },\n [],\n );\n\n const state = React.useCallback((id: string): boolean => states[id] ?? false, [states]);\n const open = React.useCallback(\n (id: string, opts?: TransitionOptions) => update(id, true, opts),\n [update],\n );\n const close = React.useCallback(\n (id: string, opts?: TransitionOptions) => update(id, false, opts),\n [update],\n );\n\n return { state, open, close };\n};\n","/**\n * @file Hook for managing drawer state (controlled/uncontrolled)\n */\nimport * as React from \"react\";\nimport {\n type TransitionMode,\n type TransitionOptions,\n runTransition,\n} from \"../../hooks/useTransitionState\";\nimport type { LayerDefinition } from \"../../types\";\n\nconst parseDuration = (value: string | undefined): number => {\n if (!value) {return 300;}\n const match = value.match(/(\\d+)/);\n return match ? parseInt(match[1], 10) : 300;\n};\n\nexport const useDrawerState = (layers: LayerDefinition[]) => {\n const [drawerStates, setDrawerStates] = React.useState<Record<string, boolean>>(() => {\n const initial: Record<string, boolean> = {};\n layers.forEach((layer) => {\n if (layer.drawer) {\n initial[layer.id] = layer.drawer.defaultOpen ?? false;\n }\n });\n return initial;\n });\n\n const layerMap = React.useMemo(() => {\n const map = new Map<string, LayerDefinition>();\n layers.forEach((layer) => map.set(layer.id, layer));\n return map;\n }, [layers]);\n\n const updateState = React.useCallback(\n async (layerId: string, isOpen: boolean, options?: TransitionOptions) => {\n const layer = layerMap.get(layerId);\n if (!layer?.drawer) {return;}\n\n const mode: TransitionMode = options?.mode ?? layer.drawer.transitionMode ?? \"css\";\n const duration = options?.duration ?? parseDuration(layer.drawer.transitionDuration);\n const element = options?.element?.current;\n\n const applyState = () => {\n if (layer.drawer?.open === undefined) {\n setDrawerStates((prev) => {\n if (prev[layerId] === isOpen) {return prev;}\n return { ...prev, [layerId]: isOpen };\n });\n }\n layer.drawer?.onStateChange?.(isOpen);\n };\n\n await runTransition(applyState, mode, element, duration);\n },\n [layerMap],\n );\n\n const state = React.useCallback(\n (layerId: string): boolean => {\n const layer = layerMap.get(layerId);\n if (layer?.drawer?.open !== undefined) {\n return layer.drawer.open;\n }\n return drawerStates[layerId] ?? false;\n },\n [layerMap, drawerStates],\n );\n\n const open = React.useCallback(\n (id: string, options?: TransitionOptions) => updateState(id, true, options),\n [updateState],\n );\n\n const close = React.useCallback(\n (id: string, options?: TransitionOptions) => updateState(id, false, options),\n [updateState],\n );\n\n return { state, open, close };\n};\n","/**\n * @file DrawerLayers component\n */\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport type { LayerDefinition } from \"../../types.js\";\nimport { Drawer } from \"./Drawer.js\";\nimport { useDrawerState } from \"../../modules/window/useDrawerState.js\";\nimport { isRevealMode } from \"./DrawerRevealContext.js\";\n\nexport type DrawerLayersProps = {\n layers: LayerDefinition[];\n};\n\n/**\n * Check if a drawer should be rendered in a portal (outside #root).\n * Reveal mode + non-inline drawers need to be outside #root so they\n * don't move when #root is transformed.\n */\nfunction shouldUsePortal(layer: LayerDefinition): boolean {\n if (!layer.drawer) {\n return false;\n }\n const { animationMode, inline = false } = layer.drawer;\n if (!isRevealMode(animationMode)) {\n return false;\n }\n return !inline;\n}\n\n/**\n * Create a map of layer ID to handler function.\n */\nfunction createHandlerMap(\n layers: LayerDefinition[],\n createHandler: (layerId: string) => () => void,\n): Map<string, () => void> {\n const handlers = new Map<string, () => void>();\n layers.forEach((layer) => {\n handlers.set(layer.id, createHandler(layer.id));\n });\n return handlers;\n}\n\nexport const DrawerLayers: React.FC<DrawerLayersProps> = ({ layers }) => {\n const drawer = useDrawerState(layers);\n\n const drawerLayers = React.useMemo(() => layers.filter((layer) => layer.drawer), [layers]);\n\n const closeHandlers = React.useMemo(\n () => createHandlerMap(drawerLayers, (id) => () => drawer.close(id)),\n [drawerLayers, drawer.close],\n );\n\n const openHandlers = React.useMemo(\n () => createHandlerMap(drawerLayers, (id) => () => drawer.open(id)),\n [drawerLayers, drawer.open],\n );\n\n return (\n <>\n {drawerLayers.map((layer) => {\n if (!layer.drawer) {\n return null;\n }\n\n const isOpen = drawer.state(layer.id);\n const onClose = closeHandlers.get(layer.id);\n const onOpen = openHandlers.get(layer.id);\n\n if (!onClose) {\n return null;\n }\n\n const drawerElement = (\n <Drawer\n key={layer.id}\n id={layer.id}\n config={layer.drawer}\n isOpen={isOpen}\n onClose={onClose}\n onOpen={onOpen}\n zIndex={layer.zIndex}\n width={layer.width}\n height={layer.height}\n position={layer.position}\n >\n {layer.component}\n </Drawer>\n );\n\n // Render reveal-mode (non-inline) drawers in a portal to document.body\n if (shouldUsePortal(layer)) {\n return ReactDOM.createPortal(drawerElement, document.body);\n }\n\n return drawerElement;\n })}\n </>\n );\n};\n","/**\n * @file Context provider for grid layer rendering helpers.\n */\nimport * as React from \"react\";\nimport type { LayerDefinition } from \"../../types\";\n\nexport type GridLayerHandleProps = React.HTMLAttributes<HTMLElement> & {\n \"data-drag-handle\": \"true\";\n};\n\nexport type ResizeHandleConfig =\n | {\n key: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\";\n variant: \"corner\";\n horizontal: \"left\" | \"right\";\n vertical: \"top\" | \"bottom\";\n }\n | {\n key: \"left\" | \"right\" | \"top\" | \"bottom\";\n variant: \"edge\";\n horizontal?: \"left\" | \"right\";\n vertical?: \"top\" | \"bottom\";\n };\n\nexport type GridLayerRenderState = {\n style: React.CSSProperties;\n isResizable: boolean;\n isResizing: boolean;\n onResizeHandlePointerDown: (config: ResizeHandleConfig, event: React.PointerEvent<HTMLDivElement>) => void;\n};\n\nexport type GridLayoutContextValue = {\n handleLayerPointerDown: (event: React.PointerEvent<HTMLDivElement>) => void;\n getLayerRenderState: (layer: LayerDefinition) => GridLayerRenderState;\n getLayerHandleProps: (layerId: string) => GridLayerHandleProps;\n /**\n * Whether the GridLayout is mounted at root level.\n * When true, scrollable layers should delegate to browser's native scroll.\n */\n isRootLevel: boolean;\n};\n\nconst GridLayoutContext = React.createContext<GridLayoutContextValue | null>(null);\n\nexport const GridLayoutProvider: React.FC<\n React.PropsWithChildren<{ value: GridLayoutContextValue }>\n> = ({ value, children }) => {\n return <GridLayoutContext.Provider value={value}>{children}</GridLayoutContext.Provider>;\n};\n\nexport const useGridLayoutContext = (): GridLayoutContextValue => {\n const context = React.useContext(GridLayoutContext);\n if (!context) {\n throw new Error(\"useGridLayoutContext must be used within a GridLayoutProvider.\");\n }\n return context;\n};\n","/**\n * @file PanelSystemContext\n *\n * Core provider for panel definitions and registry. Grid-specific layout and\n * interactions are composed by UI layers (e.g., GridLayout) on top of this.\n *\n * Includes content caching to preserve React component state across re-renders.\n * This is essential for maintaining internal state when parent components\n * re-create the layers array.\n */\nimport * as React from \"react\";\nimport type { PanelLayoutConfig, LayerDefinition } from \"./types\";\nimport { useContentCache } from \"./hooks/useContentCache\";\n\nexport type PanelSystemContextValue = {\n config: PanelLayoutConfig;\n style?: React.CSSProperties;\n layers: {\n /** Raw panel definitions (no grid normalization). */\n defs: LayerDefinition[];\n /** Fast lookup map by id for consumers. */\n layerById: Map<string, LayerDefinition>;\n };\n /**\n * Get cached content for a layer. Returns the same ReactNode reference\n * for the same layer ID to prevent remounting on parent re-renders.\n */\n getCachedContent: (layerId: string) => React.ReactNode | null;\n};\n\nconst PanelSystemContext = React.createContext<PanelSystemContextValue | null>(null);\n\nexport const usePanelSystem = (): PanelSystemContextValue => {\n const ctx = React.useContext(PanelSystemContext);\n if (!ctx) {\n throw new Error(\"usePanelSystem must be used within a PanelSystemProvider.\");\n }\n return ctx;\n};\n\nexport type PanelSystemProviderProps = React.PropsWithChildren<{\n config: PanelLayoutConfig;\n layers: LayerDefinition[];\n style?: React.CSSProperties;\n}>;\n\nexport const PanelSystemProvider: React.FC<PanelSystemProviderProps> = ({ config, layers, style, children }) => {\n const layerById = React.useMemo(() => {\n const map = new Map<string, LayerDefinition>();\n layers.forEach((layer) => {\n map.set(layer.id, layer);\n });\n return map;\n }, [layers]);\n\n // Content resolver for useContentCache\n const resolveContent = React.useCallback(\n (layerId: string): React.ReactNode | null => {\n const layer = layerById.get(layerId);\n return layer?.component ?? null;\n },\n [layerById],\n );\n\n // Valid IDs for cache cleanup\n const validIds = React.useMemo(() => layers.map((l) => l.id), [layers]);\n\n // Use shared content cache hook\n const { getCachedContent } = useContentCache({\n resolveContent,\n validIds,\n });\n\n const value = React.useMemo<PanelSystemContextValue>(\n () => ({\n config,\n style,\n layers: {\n defs: layers,\n layerById,\n },\n getCachedContent,\n }),\n [config, style, layers, layerById, getCachedContent],\n );\n\n return <PanelSystemContext.Provider value={value}>{children}</PanelSystemContext.Provider>;\n};\n","/**\n * @file Context exposing the current grid layer id and helpers to child components.\n */\nimport * as React from \"react\";\nimport type { LayerDefinition } from \"../../types\";\nimport { usePanelSystem } from \"../../PanelSystemContext\";\nimport { useGridLayoutContext, type GridLayerHandleProps } from \"./GridLayoutContext\";\n\ntype LayerInstanceContextValue = {\n layerId: string;\n};\n\nconst LayerInstanceContext = React.createContext<LayerInstanceContextValue | null>(null);\n\nexport type LayerInstanceProviderProps = React.PropsWithChildren<LayerInstanceContextValue>;\n\nexport const LayerInstanceProvider: React.FC<LayerInstanceProviderProps> = ({ layerId, children }) => {\n const value = React.useMemo(() => ({ layerId }), [layerId]);\n return <LayerInstanceContext.Provider value={value}>{children}</LayerInstanceContext.Provider>;\n};\n\nexport const useLayerInstance = (): LayerInstanceContextValue => {\n const value = React.useContext(LayerInstanceContext);\n if (!value) {\n throw new Error(\"useLayerInstance must be used within a LayerInstanceProvider.\");\n }\n return value;\n};\n\n/**\n * Convenience: read the current layer definition from the core registry.\n */\nexport const useCurrentLayerDefinition = (): LayerDefinition => {\n const { layerId } = useLayerInstance();\n const { layers } = usePanelSystem();\n const def = layers.layerById.get(layerId);\n if (!def) {\n throw new Error(`Layer definition not found for id: ${layerId}`);\n }\n return def;\n};\n\n/**\n * Convenience: get drag handle props, pre-bound to the current layer.\n */\nexport const useCurrentLayerHandleProps = (): GridLayerHandleProps => {\n const { layerId } = useLayerInstance();\n const { getLayerHandleProps } = useGridLayoutContext();\n return React.useMemo(() => getLayerHandleProps(layerId), [getLayerHandleProps, layerId]);\n};\n\n/**\n * Compatibility helper for existing code using useLayerDragHandle.\n * Prefer useCurrentLayerHandleProps for direct access.\n */\nexport const useLayerDragHandleProps = useCurrentLayerHandleProps;\n","/**\n * @file Renders floating layers inside a dedicated browser popup window.\n */\nimport * as React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { LayerDefinition, PopupWindowOptions, WindowPosition, WindowBounds } from \"../../types\";\nimport { LayerInstanceProvider } from \"../../modules/grid/LayerInstanceContext\";\n\nconst ensureNumericOffset = (value: number | string | undefined, key: keyof WindowPosition, layerId: string): number => {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n throw new Error(`Popup layer \"${layerId}\" requires a numeric \"${key}\" value.`);\n};\n\nconst resolvePopupAnchor = (position: WindowPosition | undefined, layerId: string): { left: number; top: number } => {\n if (!position) {\n throw new Error(`Popup layer \"${layerId}\" must define position (left/top).`);\n }\n return {\n left: ensureNumericOffset(position.left, \"left\", layerId),\n top: ensureNumericOffset(position.top, \"top\", layerId),\n };\n};\n\nconst numericFeature = (value: number): string => {\n return `${Math.round(value)}`;\n};\n\nconst booleanFeature = (value: boolean | undefined): string | undefined => {\n if (value === undefined) {\n return undefined;\n }\n return value ? \"yes\" : \"no\";\n};\n\nconst buildWindowFeatures = (\n layerId: string,\n position: WindowPosition | undefined,\n width: number | string | undefined,\n height: number | string | undefined,\n options: PopupWindowOptions | undefined,\n): string => {\n const features: Record<string, string> = {};\n const anchor = resolvePopupAnchor(position, layerId);\n\n if (typeof width !== \"number\" || typeof height !== \"number\") {\n throw new Error(`Popup layer \"${layerId}\" requires numeric width/height.`);\n }\n features.width = numericFeature(width);\n features.height = numericFeature(height);\n features.left = numericFeature(anchor.left);\n features.top = numericFeature(anchor.top);\n\n const overrides = options?.features;\n if (overrides) {\n const toolbar = booleanFeature(overrides.toolbar);\n const menubar = booleanFeature(overrides.menubar);\n const location = booleanFeature(overrides.location);\n const status = booleanFeature(overrides.status);\n const resizable = booleanFeature(overrides.resizable);\n const scrollbars = booleanFeature(overrides.scrollbars);\n\n if (toolbar !== undefined) {\n features.toolbar = toolbar;\n }\n if (menubar !== undefined) {\n features.menubar = menubar;\n }\n if (location !== undefined) {\n features.location = location;\n }\n if (status !== undefined) {\n features.status = status;\n }\n if (resizable !== undefined) {\n features.resizable = resizable;\n }\n if (scrollbars !== undefined) {\n features.scrollbars = scrollbars;\n }\n }\n\n return Object.entries(features)\n .map(([key, value]) => `${key}=${value}`)\n .join(\",\");\n};\n\nconst applyBoundsToWindow = (\n popupWindow: Window,\n layerId: string,\n position: WindowPosition | undefined,\n width: number | string | undefined,\n height: number | string | undefined,\n) => {\n const anchor = resolvePopupAnchor(position, layerId);\n if (typeof width !== \"number\" || typeof height !== \"number\") {\n throw new Error(`Popup layer \"${layerId}\" requires numeric width/height.`);\n }\n popupWindow.moveTo(Math.round(anchor.left), Math.round(anchor.top));\n popupWindow.resizeTo(Math.round(width), Math.round(height));\n};\n\ntype PopupLayerPortalProps = {\n layer: LayerDefinition;\n};\n\nexport const PopupLayerPortal: React.FC<PopupLayerPortalProps> = ({ layer }) => {\n const floating = layer.floating;\n if (!floating) {\n throw new Error(`Layer \"${layer.id}\" is missing floating configuration required for popup mode.`);\n }\n const mode = floating.mode ?? \"embedded\";\n if (mode !== \"popup\") {\n throw new Error(`PopupLayerPortal received layer \"${layer.id}\" that is not configured for popup mode.`);\n }\n\n const containerRef = React.useRef<HTMLDivElement | null>(null);\n const popupWindowRef = React.useRef<Window | null>(null);\n const [isMounted, setIsMounted] = React.useState(false);\n\n React.useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n const features = buildWindowFeatures(layer.id, layer.position, layer.width, layer.height, floating.popup);\n const windowName = floating.popup?.name ?? layer.id;\n const createdWindow = resolvePopupWindow(\n windowName,\n features,\n {\n position: layer.position,\n size: { width: layer.width as number, height: layer.height as number },\n },\n floating.popup,\n );\n\n if (!createdWindow) {\n throw new Error(`Failed to open popup window for layer \"${layer.id}\".`);\n }\n\n const openedWindow = createdWindow;\n\n popupWindowRef.current = openedWindow;\n\n if (floating.popup?.focus !== false) {\n openedWindow.focus();\n }\n\n if (!openedWindow.document.title) {\n openedWindow.document.title = layer.id;\n }\n openedWindow.document.body.innerHTML = \"\";\n const mountNode = openedWindow.document.createElement(\"div\");\n mountNode.dataset.layerId = layer.id;\n openedWindow.document.body.appendChild(mountNode);\n containerRef.current = mountNode;\n setIsMounted(true);\n\n applyBoundsToWindow(openedWindow, layer.id, layer.position, layer.width, layer.height);\n\n const handleBeforeUnload = () => {\n popupWindowRef.current = null;\n containerRef.current = null;\n setIsMounted(false);\n };\n openedWindow.addEventListener(\"beforeunload\", handleBeforeUnload);\n\n return () => {\n openedWindow.removeEventListener(\"beforeunload\", handleBeforeUnload);\n if (floating.popup?.closeOnUnmount !== false) {\n openedWindow.close();\n }\n popupWindowRef.current = null;\n containerRef.current = null;\n setIsMounted(false);\n };\n }, [\n floating.popup?.closeOnUnmount,\n floating.popup?.features?.location,\n floating.popup?.features?.menubar,\n floating.popup?.features?.resizable,\n floating.popup?.features?.scrollbars,\n floating.popup?.features?.status,\n floating.popup?.features?.toolbar,\n floating.popup?.focus,\n floating.popup?.name,\n layer.id,\n ]);\n\n React.useEffect(() => {\n const popupWindow = popupWindowRef.current;\n if (!popupWindow) {\n return;\n }\n applyBoundsToWindow(popupWindow, layer.id, layer.position, layer.width, layer.height);\n }, [layer.position?.left, layer.position?.top, layer.height, layer.width, layer.id]);\n\n if (!isMounted || !containerRef.current) {\n return null;\n }\n\n return createPortal(<LayerInstanceProvider layerId={layer.id}>{layer.component}</LayerInstanceProvider>, containerRef.current);\n};\n\nconst resolvePopupWindow = (\n windowName: string,\n features: string,\n bounds: WindowBounds,\n options: PopupWindowOptions | undefined,\n): Window | null => {\n const customFactory = options?.createWindow;\n if (customFactory) {\n return customFactory({ name: windowName, features, bounds });\n }\n return window.open(\"\", windowName, features);\n};\n","/**\n * @file FloatingWindow component with chrome support\n *\n * Renders floating panel content with optional built-in chrome (FloatingPanelFrame).\n * When chrome is enabled and header is provided, header becomes the drag handle.\n */\nimport * as React from \"react\";\nimport type { FloatingBehavior } from \"../../types\";\nimport {\n FloatingPanelCloseButton,\n FloatingPanelFrame,\n FloatingPanelHeader,\n FloatingPanelTitle,\n FloatingPanelControls,\n FloatingPanelContent,\n} from \"../paneling/FloatingPanelFrame\";\n\nexport type FloatingWindowProps = {\n id: string;\n config: FloatingBehavior;\n onClose: () => void;\n children: React.ReactNode;\n};\n\ntype CloseButtonProps = {\n onClick: () => void;\n};\n\nconst CloseButton: React.FC<CloseButtonProps> = ({ onClick }) => (\n <FloatingPanelControls>\n <FloatingPanelCloseButton onClick={onClick} aria-label=\"Close window\" data-drag-ignore=\"true\" />\n </FloatingPanelControls>\n);\n\ntype FloatingWindowHeaderProps = {\n header?: FloatingBehavior[\"header\"];\n draggable?: boolean;\n onClose: () => void;\n};\n\nconst FloatingWindowHeader: React.FC<FloatingWindowHeaderProps> = ({ header, draggable, onClose }) => {\n if (!header) {\n return null;\n }\n\n const showCloseButton = header.showCloseButton ?? false;\n const dragHandleProps = draggable ? { \"data-drag-handle\": \"true\" } : {};\n const cursorStyle = draggable ? \"grab\" : undefined;\n\n return (\n <FloatingPanelHeader {...dragHandleProps} style={{ cursor: cursorStyle }}>\n {header.title ? <FloatingPanelTitle>{header.title}</FloatingPanelTitle> : null}\n {showCloseButton ? <CloseButton onClick={onClose} /> : null}\n </FloatingPanelHeader>\n );\n};\n\ntype FloatingWindowViewProps = {\n header?: FloatingBehavior[\"header\"];\n draggable?: boolean;\n chrome: boolean;\n onClose: () => void;\n children: React.ReactNode;\n};\n\nconst FloatingWindowView: React.FC<FloatingWindowViewProps> = ({ header, draggable, chrome, onClose, children }) => {\n if (!chrome) {\n return <>{children}</>;\n }\n\n return (\n <FloatingPanelFrame style={{ height: \"100%\", width: \"100%\" }}>\n <FloatingWindowHeader header={header} draggable={draggable} onClose={onClose} />\n <FloatingPanelContent style={{ flex: 1, display: \"flex\", flexDirection: \"column\" }}>\n {children}\n </FloatingPanelContent>\n </FloatingPanelFrame>\n );\n};\n\nexport const FloatingWindow: React.FC<FloatingWindowProps> = ({ id, config, onClose, children }) => {\n const chrome = config.chrome ?? false;\n const draggable = config.draggable ?? false;\n const ariaLabel = config.header?.title ?? config.ariaLabel ?? \"Floating window\";\n\n return (\n <div data-floating-window={id} role=\"dialog\" aria-label={ariaLabel} style={{ height: \"100%\", width: \"100%\" }}>\n <FloatingWindowView header={config.header} draggable={draggable} chrome={chrome} onClose={onClose}>\n {children}\n </FloatingWindowView>\n </div>\n );\n};\n\nFloatingWindow.displayName = \"FloatingWindow\";\n"],"names":["SWIPE_SAFE_ZONE_ATTR","SwipeSafeZone","children","className","style","jsx","isInSwipeSafeZone","element","container","current","getDrawerAnimationAxis","direction","getDrawerCloseSwipeSign","getDrawerOpenSwipeSign","DEFAULT_DISMISS_THRESHOLD","VELOCITY_THRESHOLD","getContainerSize","axis","getAxisDelta","start","PHASE_MAP","normalizePhase","phase","computeDisplacementValue","closeSwipeSign","closeDisplacement","signedDisplacement","computeAxisDisplacement","displacement","sign","isEdgeSwipeEnabled","enableEdgeSwipeOpen","isOpen","isCloseSwipeEnabled","enableSwipeClose","isDrawerOpening","isEdgeGesture","isDrawerClosing","closePhase","computeVelocity","timeDelta","useDrawerSwipeInput","options","edgeContainerRef","drawerContentRef","onSwipeOpen","onSwipeClose","edgeWidth","dismissThreshold","openSwipeSign","containerSizeRef","React","updateSize","observer","handleOpenSwipeEnd","state","edgeSwipeState","edgeSwipeProps","useEdgeSwipeInput","guardProps","useNativeGestureGuard","closeTracking","baseClosePointerDown","usePointerTracking","setClosePhase","lastCloseDisplacementRef","onClosePointerDown","event","target","isScrollableInDirection","signedDelta","containerSize","ratio","velocity","isOpening","isClosing","progress","IDLE_CONTINUOUS_OPERATION_STATE","edgeContainerProps","mergeGestureContainerProps","drawerContentProps","DRAWER_BACKDROP_BASE_STYLE","COLOR_DRAWER_BACKDROP","DRAWER_PANEL_BASE_STYLE","PLACEMENT_STYLES","OPEN_TRANSFORMS","getPlacementStyle","placement","getOpenTransform","computeTransitionValue","mode","duration","easing","DRAWER_TRANSITION_DURATION","DRAWER_TRANSITION_EASING","computeBackdropTransition","formatDimension","value","computeEdgeZoneStyle","inline","zIndex","position","computedZIndex","getEdgeZoneStyleByPlacement","base","DEFAULT_EDGE_WIDTH","DISABLED_CONFIG","ENABLED_DEFAULT_CONFIG","parseSwipeGesturesConfig","swipeGestures","resolvePlacement","anchor","shouldShowEdgeZone","config","createAction","type","payloadCreator","actionCreator","args","payload","bindActionCreators","creators","dispatch","bound","key","creator","action","createActionHandlerMap","handlers","map","handler","REVEAL_DRAWER_OPEN_DISTANCE_THRESHOLD","REVEAL_DRAWER_DISMISS_RATIO","REVEAL_DRAWER_CLOSED_OFFSET_PERCENT","REVEAL_DRAWER_ANIMATION_DURATION","REVEAL_DRAWER_SNAP_THRESHOLD","computeProgressFromDisplacement","drawerSize","computeSwipeEndTarget","drawerActions","easedProgress","getTargetPositionFromOpenState","strategy","createDrawerInitialState","createDrawerReducer","_config","_action","targetOpen","targetPosition","animType","fromPosition","_state","PLACEMENT_CONFIG","getPlacementConfig","STACKING_CONTEXT_STYLES","clearStackingContext","applyOverflowHidden","clearOverflowHidden","getContentElement","gridRef","showDrawer","hideDrawer","clearDrawerVisibility","applyStackingContextWithBackground","background","revealStrategy","offsetPx","drawerPx","contentPx","from","to","elements","drawer","content","OVERLAY_SNAP_THRESHOLD","overlayStrategy","backdrop","closedTransform","getClosedTransformForPlacement","selectStrategy","useDrawerTransform","drawerRef","contentRef","backdropRef","swipeState","enabled","contentBackground","isOperating","reducer","stateRef","setPhase","prevRef","resolveContentElement","resolveBackdropElement","getElements","newState","handleFrame","handleComplete","isAnimating","cancel","useAnimationFrame","easings","prev","wasOperating","wasOpening","wasClosing","currentDirection","useDrawerSwipeTransform","drawerSizeRef","isHorizontal","defaultContextValue","DrawerRevealContext","DrawerRevealProvider","activeRevealDrawer","setActiveRevealDrawer","setGridRefState","setRevealState","setGridRef","ref","useDrawerReveal","isRevealMode","animationMode","useRevealDrawerTransform","DrawerContent","chrome","frameStyle","header","dismissible","onClose","jsxs","FloatingPanelFrame","DrawerHeaderView","FloatingPanelContent","DRAWER_CONTENT_PADDING","shouldShowCloseButton","showCloseButton","renderCloseButton","shouldShow","FloatingPanelCloseButton","renderEdgeZone","showEdgeZone","edgeZoneRef","edgeZoneStyle","onPointerDown","computeDrawerSize","width","height","FloatingPanelHeader","DRAWER_HEADER_PADDING_Y","DRAWER_HEADER_PADDING_X","DRAWER_HEADER_GAP","FloatingPanelTitle","useDrawerPanelStyle","isSwipeOperating","dimensions","revealMode","placementStyle","effectiveMode","transitionValue","transform","useBackdropStyle","hookControlled","useFrameStyle","Drawer","id","onOpen","swipeConfig","handleSwipeOpen","handleSwipeClose","swipeTransformEnabled","drawerStyle","backdropStyle","mergedDrawerStyle","ariaLabel","edgeZoneElement","Fragment","waitForTransitionEnd","el","timeout","resolve","resolved","done","e","runTransition","update","useTransitionState","states","setStates","optionsRef","transitionOptions","opts","open","close","parseDuration","match","useDrawerState","layers","drawerStates","setDrawerStates","initial","layer","layerMap","updateState","layerId","shouldUsePortal","createHandlerMap","createHandler","DrawerLayers","drawerLayers","closeHandlers","openHandlers","drawerElement","ReactDOM","GridLayoutContext","GridLayoutProvider","useGridLayoutContext","context","PanelSystemContext","usePanelSystem","ctx","PanelSystemProvider","layerById","resolveContent","validIds","getCachedContent","useContentCache","LayerInstanceContext","LayerInstanceProvider","useLayerInstance","ensureNumericOffset","resolvePopupAnchor","numericFeature","booleanFeature","buildWindowFeatures","features","overrides","toolbar","menubar","location","status","resizable","scrollbars","applyBoundsToWindow","popupWindow","PopupLayerPortal","floating","containerRef","popupWindowRef","isMounted","setIsMounted","windowName","createdWindow","resolvePopupWindow","openedWindow","mountNode","handleBeforeUnload","createPortal","bounds","customFactory","CloseButton","onClick","FloatingPanelControls","FloatingWindowHeader","draggable","FloatingWindowView","FloatingWindow"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";const h=require("react/jsx-runtime"),xe=require("react"),le=require("react-dom"),_=require("./FloatingPanelFrame-CEmXDvUA.cjs"),U=require("./styles-qf6ptVLD.cjs"),$=require("./useAnimationFrame-BZ6D2lMq.cjs"),Re=require("./useContentCache-DqXtLrLs.cjs");function de(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}}return t.default=e,Object.freeze(t)}const s=de(xe),Te=de(le),Ae="data-swipe-safe-zone",Me=({children:e,className:t,style:n})=>h.jsx("div",{className:t,style:n,"data-swipe-safe-zone":"true",children:e});function _e(e,t){let n=e;for(;n&&n!==t;){if(n.hasAttribute(Ae))return!0;n=n.parentElement}return!1}function Le(e){switch(e){case"left":case"right":return"x";case"top":case"bottom":return"y"}}function pe(e){switch(e){case"left":return-1;case"right":return 1;case"top":return-1;case"bottom":return 1}}function Fe(e){return pe(e)*-1}const ke=.3,Ie=.5;function Ne(e,t){return t==="x"?e.clientWidth:e.clientHeight}function We(e,t,n){return n==="x"?t.x-e.x:t.y-e.y}const je={idle:"idle",ended:"ended"};function ze(e){return je[e]??"operating"}function He(e,t,n){const r=e*n;return t==="x"?{x:r,y:0}:{x:0,y:r}}function Be(e,t,n){return t==="x"?Math.max(0,n*e.x):Math.max(0,n*e.y)}function $e(e,t){return e?!t:!1}function Ge(e,t){return e?t:!1}function Ue(e,t){return e?!t:!1}function Ve(e,t){return e==="idle"?!1:t}function Ye(e,t,n){if(!e||!t)return 0;const r=Math.max(1,t.timestamp-e.timestamp);return n/r}function Ze(e){const{edgeContainerRef:t,drawerContentRef:n,direction:r,isOpen:o,onSwipeOpen:i,onSwipeClose:a,enableEdgeSwipeOpen:c=!0,enableSwipeClose:u=!0,edgeWidth:l=20,dismissThreshold:d=ke}=e,p=Le(r),w=pe(r),O=Fe(r),C=s.useRef(0);s.useLayoutEffect(()=>{const m=n.current;if(!m)return;const y=()=>{C.current=Ne(m,p)};y();const T=new ResizeObserver(y);return T.observe(m),()=>T.disconnect()},[n,p]);const D=s.useCallback(m=>{m.direction===O&&i()},[O,i]),{isEdgeGesture:E,state:f,containerProps:g}=$.useEdgeSwipeInput({containerRef:t,edge:r,edgeWidth:l,enabled:$e(c,o),onSwipeEnd:D}),{containerProps:G}=$.useNativeGestureGuard({containerRef:t,active:E,preventEdgeBack:!0,preventOverscroll:!0,edgeWidth:l}),{state:b,onPointerDown:I}=$.usePointerTracking({enabled:Ge(u,o)}),[R,x]=s.useState("idle"),M=s.useRef(0),W=s.useCallback(m=>{if(!u||!o)return;const y=n.current;if(!y)return;const T=m.target;_e(T,y)||$.isScrollableInDirection(T,y,p,w)||I(m)},[u,o,n,p,w,I]),P=s.useMemo(()=>{if(!b.isDown||!b.start||!b.current)return M.current;const y=We(b.start,b.current,p)*w;return Math.max(0,y)},[b.isDown,b.start,b.current,p,w]);s.useEffect(()=>{b.isDown&&b.current&&(M.current=P)},[b.isDown,b.current,P]),s.useEffect(()=>{b.isDown&&R==="idle"&&x("operating")},[b.isDown,R]),s.useEffect(()=>{if(!b.isDown&&R==="operating"){const m=M.current;if(m>1){x("ended");const T=C.current;if(T>0){const A=m/T,N=Ye(b.start,b.current,m);(A>=d||N>=Ie)&&a()}}else x("idle"),M.current=0}},[b.isDown,R,d,a,b.start,b.current]),s.useEffect(()=>{R==="ended"&&queueMicrotask(()=>{x("idle"),M.current=0})},[R]),s.useEffect(()=>{o||(x("idle"),M.current=0)},[o]);const v=Ue(E,o),L=Ve(R,o),j=s.useMemo(()=>v?Be(f.displacement,p,O):L?P:0,[v,L,p,f.displacement,P,O]),F=s.useMemo(()=>{const m=C.current;return m<=0?0:Math.min(j/m,1)},[j]),z=s.useMemo(()=>v?{phase:ze(f.phase),displacement:f.displacement,velocity:f.velocity}:L?{phase:R,displacement:He(w,p,P),velocity:{x:0,y:0}}:$.IDLE_CONTINUOUS_OPERATION_STATE,[v,L,f,R,P,p,w]),H=s.useMemo(()=>$.mergeGestureContainerProps(g,G),[g,G]),S=s.useMemo(()=>({onPointerDown:W,style:{touchAction:"none",userSelect:"none",WebkitUserSelect:"none"}}),[W]);return{state:z,isOpening:v,isClosing:L,progress:F,displacement:j,edgeContainerProps:H,drawerContentProps:S}}const oe={position:"fixed",inset:0,background:U.COLOR_DRAWER_BACKDROP},ie={willChange:"transform"},qe={left:{top:0,bottom:0,left:0,transform:"translateX(-100%)"},right:{top:0,bottom:0,right:0,transform:"translateX(100%)"},top:{top:0,left:0,right:0,transform:"translateY(-100%)"},bottom:{bottom:0,left:0,right:0,transform:"translateY(100%)"}},Xe={left:"translateX(0)",right:"translateX(0)",top:"translateY(0)",bottom:"translateY(0)"};function Ke(e){return qe[e]}function Je(e){return Xe[e]}function Qe(e,t,n){if(e==="none")return;const r=t??U.DRAWER_TRANSITION_DURATION,o=n??U.DRAWER_TRANSITION_EASING;return`transform ${r} ${o}`}function et(e,t){if(e!=="none")return`opacity ${t??"220ms"} ease`}function q(e){if(e!==void 0)return typeof e=="number"?`${e}px`:e}function tt(e){const{placement:t,inline:n,edgeWidth:r,zIndex:o}=e,i=n?"absolute":"fixed",a=o!==void 0?o-2:1e3;return nt(t,i,r,a)}function nt(e,t,n,r){const o={position:t,zIndex:r,background:"transparent",pointerEvents:"auto"};return e==="left"?{...o,top:0,bottom:0,left:0,width:n}:e==="right"?{...o,top:0,bottom:0,right:0,width:n}:e==="top"?{...o,top:0,left:0,right:0,height:n}:{...o,bottom:0,left:0,right:0,height:n}}const te=20,ne=.3,rt={enabled:!1,edgeSwipeOpen:!1,swipeClose:!1,edgeWidth:te,dismissThreshold:ne},ot={enabled:!0,edgeSwipeOpen:!0,swipeClose:!0,edgeWidth:te,dismissThreshold:ne};function it(e){return e===!0?ot:e===!1||e===void 0?rt:{enabled:!0,edgeSwipeOpen:e.edgeSwipeOpen??!0,swipeClose:e.swipeClose??!0,edgeWidth:e.edgeWidth??te,dismissThreshold:e.dismissThreshold??ne}}function st(e,t){return e||(t?t.left!==void 0?"left":t.right!==void 0?"right":t.top!==void 0?"top":t.bottom!==void 0?"bottom":"right":"right")}function at(e,t,n){return!e.enabled||!e.edgeSwipeOpen?!1:t?n:!0}function k(e,t){if(!t){const r=(()=>({type:e}));return Object.defineProperty(r,"type",{value:e,writable:!1,enumerable:!0}),r}const n=((...r)=>{const o=t(...r);return typeof o>"u"?{type:e}:{type:e,payload:o}});return Object.defineProperty(n,"type",{value:e,writable:!1,enumerable:!0}),n}const ct=(e,t)=>{const n={};return Object.keys(e).forEach(r=>{const o=e[r];n[r]=((...i)=>{const a=o(...i);return t(a),a})}),n},fe=(e,t)=>{const n={};return Object.keys(t).forEach(r=>{const o=t[r];if(!o)return;const i=e[r];if(!i)throw new Error(`Missing action creator for key "${String(r)}"`);n[i.type]=o}),n},ut=100,lt=.3,dt=30,pt=300,ft=1;function mt(e,t,n){if(t<=0||n===null)return 0;const r=Math.min(1,Math.max(0,e/t));return n==="opening"?r:1-r}function wt(e,t,n){return n==="opening"?e>=ut:n==="closing"?(t>0?e/t:0)<lt:!1}const B={swipeStart:k("SWIPE_START",e=>({direction:e})),swipeUpdate:k("SWIPE_UPDATE",e=>({displacement:e})),swipeEnd:k("SWIPE_END"),animationFrame:k("ANIMATION_FRAME",e=>({easedProgress:e})),animationComplete:k("ANIMATION_COMPLETE"),buttonOpen:k("BUTTON_OPEN"),buttonClose:k("BUTTON_CLOSE"),syncOpenState:k("SYNC_OPEN_STATE",e=>({isOpen:e})),initialize:k("INITIALIZE",e=>({isOpen:e}))};function Q(e,t,n){return e?t.getOpenPosition(n):t.getClosedPosition(n)}function ee(e,t,n){const r=Q(e,t,n);return{phase:e?"open":"closed",targetOpen:e,position:r,isOperating:!1,swipeDirection:null,displacement:0,animation:null}}function gt(e){const t=fe(B,{swipeStart:(n,r,o)=>"payload"in r?{...n,isOperating:!0,swipeDirection:r.payload.direction,displacement:0,animation:null}:n,swipeUpdate:(n,r,o)=>{if(!("payload"in r)||!n.isOperating)return n;const i=mt(r.payload.displacement,o.drawerSize,n.swipeDirection),a=e.computePositionFromProgress(i,o);return{...n,displacement:r.payload.displacement,position:a}},swipeEnd:(n,r,o)=>{if(!n.isOperating)return n;const i=wt(n.displacement,o.drawerSize,n.swipeDirection),a=Q(i,e,o);if(e.shouldAnimate(n.position,a)){const c=i?"opening":"closing";return{...n,isOperating:!1,swipeDirection:null,displacement:0,targetOpen:i,phase:c,animation:{type:c,from:n.position,to:a}}}return{...n,isOperating:!1,swipeDirection:null,displacement:0,targetOpen:i,phase:i?"open":"closed",position:a,animation:null}},animationFrame:(n,r,o)=>{if(!("payload"in r)||!n.animation)return n;const i=e.interpolatePosition(n.animation.from,n.animation.to,r.payload.easedProgress);return{...n,position:i}},animationComplete:(n,r,o)=>{if(!n.animation)return n;const i=n.animation.type==="opening";return{...n,phase:i?"open":"closed",position:n.animation.to,animation:null}},buttonOpen:(n,r,o)=>{if(n.phase==="open"||n.phase==="opening"||n.isOperating)return n;const i=e.getOpenPosition(o),a=n.position;return e.shouldAnimate(a,i)?{...n,targetOpen:!0,phase:"opening",animation:{type:"opening",from:a,to:i}}:{...n,targetOpen:!0,phase:"open",position:i,animation:null}},buttonClose:(n,r,o)=>{if(n.phase==="closed"||n.phase==="closing"||n.isOperating)return n;const i=e.getClosedPosition(o),a=n.position;return e.shouldAnimate(a,i)?{...n,targetOpen:!1,phase:"closing",animation:{type:"closing",from:a,to:i}}:{...n,targetOpen:!1,phase:"closed",position:i,animation:null}},syncOpenState:(n,r,o)=>{if(!("payload"in r))return n;const{isOpen:i}=r.payload;if(n.targetOpen===i&&!n.isOperating&&!n.animation)return n;if(n.isOperating)return{...n,targetOpen:i};if(n.animation&&n.animation.type==="opening"===i)return{...n,targetOpen:i};if((n.phase==="open"||n.phase==="opening")===i)return{...n,targetOpen:i};const c=Q(i,e,o),u=n.position;if(e.shouldAnimate(u,c)){const l=i?"opening":"closing";return{...n,targetOpen:i,phase:l,animation:{type:l,from:u,to:c}}}return{...n,targetOpen:i,phase:i?"open":"closed",position:c,animation:null}},initialize:(n,r,o)=>"payload"in r?ee(r.payload.isOpen,e,o):n});return function(r,o,i){const a=t[o.type];return a?a(r,o,i):r}}const ht={left:{axis:"X",sign:1},right:{axis:"X",sign:-1},top:{axis:"Y",sign:1},bottom:{axis:"Y",sign:-1}};function Y(e){return ht[e]}const K={position:"relative",zIndex:"1",background:"#fff"};function se(e){e.style.position="",e.style.zIndex="",e.style.background=""}function St(){document.body.style.overflow="hidden"}function J(){document.body.style.overflow=""}function me(e,t){return e?t?.current??null:document.getElementById("root")??document.body.firstElementChild}function bt(e){e.style.visibility="visible",e.style.pointerEvents="auto"}function Et(e){e.style.visibility="hidden",e.style.pointerEvents="none"}function Pt(e){e.style.visibility="",e.style.pointerEvents=""}function yt(e,t=K.background){e.style.position=K.position,e.style.zIndex=K.zIndex,e.style.background=t}const Ot={getClosedPosition(e){return this.computePositionFromProgress(0,e)},getOpenPosition(e){return this.computePositionFromProgress(1,e)},computePositionFromProgress(e,t){const{sign:n}=Y(t.placement),o=t.drawerSize*(dt/100)*(1-e),i=n>0?-o:o,a=n*t.drawerSize*e;return{drawerPx:i,contentPx:a}},interpolatePosition(e,t,n){return{drawerPx:e.drawerPx+(t.drawerPx-e.drawerPx)*n,contentPx:e.contentPx+(t.contentPx-e.contentPx)*n}},shouldAnimate(e,t){return Math.abs(e.contentPx-t.contentPx)>ft},applyToDOM(e,t,n){const{drawer:r,content:o}=t,{axis:i}=Y(n.placement);r&&(r.style.transition="none",r.style.transform=`translate${i}(${e.drawerPx}px)`),o&&(yt(o,n.contentBackground),o.style.transition="none",o.style.transform=`translate${i}(${e.contentPx}px)`)},clearFromDOM(e){const{drawer:t,content:n}=e;t&&(t.style.transform="",t.style.transition=""),n&&(n.style.transform="",n.style.transition="",se(n))},onOpeningStart(e){e.drawer&&bt(e.drawer)},onClosingComplete(e){const{drawer:t,content:n}=e;t&&(Et(t),t.style.transform="",t.style.transition=""),n&&(n.style.transform="",n.style.transition="",se(n))}},Ct=1,Dt={getClosedPosition(e){const{sign:t}=Y(e.placement);return{drawerPx:-t*e.drawerSize,backdropOpacity:0}},getOpenPosition(){return{drawerPx:0,backdropOpacity:1}},computePositionFromProgress(e,t){const{sign:n}=Y(t.placement);return{drawerPx:-n*t.drawerSize*(1-e),backdropOpacity:e}},interpolatePosition(e,t,n){return{drawerPx:e.drawerPx+(t.drawerPx-e.drawerPx)*n,backdropOpacity:e.backdropOpacity+(t.backdropOpacity-e.backdropOpacity)*n}},shouldAnimate(e,t){return Math.abs(e.drawerPx-t.drawerPx)>Ct},applyToDOM(e,t,n){const{drawer:r,backdrop:o}=t,{axis:i}=Y(n.placement);r&&(r.style.transition="none",r.style.transform=`translate${i}(${e.drawerPx}px)`),o&&(o.style.opacity=String(e.backdropOpacity),o.style.pointerEvents=e.backdropOpacity>0?"auto":"none")},clearFromDOM(e){const{drawer:t,backdrop:n}=e;t&&(t.style.transform="",t.style.transition=""),n&&(n.style.opacity="",n.style.pointerEvents="")},onOpeningStart(){},onClosingComplete(e,t){const{drawer:n,backdrop:r}=e,o=vt(t);n&&(n.style.transform=o,n.style.transition=""),r&&(r.style.opacity="0",r.style.pointerEvents="none")}};function vt(e){switch(e.placement){case"left":return"translateX(-100%)";case"right":return"translateX(100%)";case"top":return"translateY(-100%)";case"bottom":return"translateY(100%)"}}function xt(e){return e==="reveal"?Ot:Dt}function we(e){const{mode:t,drawerRef:n,contentRef:r,backdropRef:o,placement:i,drawerSize:a,isOpen:c,swipeState:u,displacement:l,isOpening:d,isClosing:p,enabled:w,inline:O=!1,gridRef:C,contentBackground:D="#fff"}=e,E=u.phase==="operating",f=xt(t),g=s.useMemo(()=>({placement:i,drawerSize:a,contentBackground:D}),[i,a,D]),G=s.useMemo(()=>gt(f),[f]),b=s.useRef(ee(c,f,g)),[I,R]=s.useState(c?"open":"closed"),x=s.useRef({isOperating:!1,isOpening:!1,isClosing:!1,isOpen:c,enabled:!1}),M=()=>t!=="reveal"?null:r?.current??me(O,C),W=()=>t!=="overlay"?null:o?.current??null,P=s.useCallback(()=>({drawer:n.current,content:M(),backdrop:W()}),[t,n,r,o,O,C]),v=s.useCallback(S=>{const m=G(b.current,S,g);return b.current=m,R(m.phase),m},[G,g]),L=s.useCallback(({easedProgress:S})=>{const m=b.current;if(!m.animation)return;const y=f.interpolatePosition(m.animation.from,m.animation.to,S);b.current={...m,position:y};const T=P();f.applyToDOM(y,T,g)},[f,P,g]),j=s.useCallback(()=>{const S=v(B.animationComplete()),m=P();S.phase==="closed"&&f.onClosingComplete?.(m,g)},[v,f,P,g]),{isAnimating:F,start:z,cancel:H}=$.useAnimationFrame({duration:pt,easing:$.easings.easeOutExpo,onFrame:L,onComplete:j});return s.useLayoutEffect(()=>{if(!w){x.current.enabled=!1;return}if(x.current.enabled)return;x.current.enabled=!0,b.current=ee(c,f,g),R(c?"open":"closed");const S=P();c?(f.onOpeningStart?.(S,g),f.applyToDOM(b.current.position,S,g)):f.onClosingComplete?.(S,g)},[w,c,f,g,P]),s.useLayoutEffect(()=>{if(!w)return;const S=x.current,m=S.isOperating,y=S.isOpening,T=S.isClosing;if(S.isOperating=E,S.isOpening=d,S.isClosing=p,!m&&E){H();const A=d?"opening":p?"closing":null;A&&v(B.swipeStart(A));return}if(m&&!E){const A=v(B.swipeEnd()),N=P();A.animation?(f.onOpeningStart?.(N,g),z()):A.phase==="open"?(f.onOpeningStart?.(N,g),f.applyToDOM(A.position,N,g)):A.phase==="closed"&&f.onClosingComplete?.(N,g);return}if(E){const A=d?"opening":p?"closing":null;A!==(y?"opening":T?"closing":null)&&A&&v(B.swipeStart(A))}},[w,E,d,p,v,H,z,f,g,P]),s.useLayoutEffect(()=>{if(!w||!E||!d&&!p)return;const S=v(B.swipeUpdate(l)),m=P();f.onOpeningStart?.(m,g),f.applyToDOM(S.position,m,g)},[w,E,d,p,l,v,f,g,P]),s.useLayoutEffect(()=>{if(!w)return;const S=x.current;if(S.isOpen===c)return;if(S.isOpen=c,E){v(B.syncOpenState(c));return}if(F&&b.current.animation?.type==="opening"===c)return;const m=v(B.syncOpenState(c)),y=P();m.animation?(f.onOpeningStart?.(y,g),f.applyToDOM(m.animation.from,y,g),z()):F||(m.phase==="open"?(f.onOpeningStart?.(y,g),f.applyToDOM(m.position,y,g)):m.phase==="closed"&&f.onClosingComplete?.(y,g))},[w,c,E,F,v,z,f,g,P]),s.useLayoutEffect(()=>{if(w||!x.current.enabled)return;const S=P();f.clearFromDOM(S,g),S.drawer&&Pt(S.drawer)},[w,f,g,P]),s.useLayoutEffect(()=>{if(!w||t!=="reveal"){t==="reveal"&&J();return}return(c||E?!0:F)?St():J(),()=>{J()}},[w,t,c,E,F]),s.useLayoutEffect(()=>{if(!(!w||t!=="reveal"))return()=>{const S=P();S.content&&f.clearFromDOM({drawer:null,content:S.content,backdrop:null},g)}},[w,t,f,g,P]),{phase:I,isAnimating:F}}function Rt(e){const{drawerRef:t,backdropRef:n,placement:r,swipeState:o,displacement:i,isOpening:a,isClosing:c,isOpen:u,enabled:l}=e,d=s.useRef(0);s.useLayoutEffect(()=>{const p=t.current;if(p){const w=r==="left"||r==="right";d.current=w?p.clientWidth:p.clientHeight}},[t,r]),we({mode:"overlay",drawerRef:t,backdropRef:n,placement:r,drawerSize:d.current,isOpen:u,swipeState:o,displacement:i,isOpening:a,isClosing:c,enabled:l})}const Tt={activeRevealDrawer:null,setRevealState:()=>{},gridRef:null,setGridRef:()=>{}},ge=s.createContext(Tt),At=({children:e})=>{const[t,n]=s.useState(null),[r,o]=s.useState(null),i=s.useCallback(u=>{n(u)},[]),a=s.useCallback(u=>{o(u)},[]),c=s.useMemo(()=>({activeRevealDrawer:t,setRevealState:i,gridRef:r,setGridRef:a}),[t,i,r,a]);return h.jsx(ge.Provider,{value:c,children:e})};function he(){return s.useContext(ge)}function Z(e){return e==="reveal"}function Mt(e){const{drawerRef:t,placement:n,drawerSize:r,isOpen:o,swipeState:i,displacement:a,isOpening:c,isClosing:u,enabled:l,inline:d,gridRef:p,contentBackground:w="#fff"}=e,O=s.useRef(null);return s.useLayoutEffect(()=>{O.current=me(d,p)},[d,p]),we({mode:"reveal",drawerRef:t,contentRef:O,placement:n,drawerSize:r,isOpen:o,swipeState:i,displacement:a,isOpening:c,isClosing:u,enabled:l,inline:d,gridRef:p,contentBackground:w})}const _t=({chrome:e,frameStyle:t,header:n,dismissible:r,onClose:o,children:i})=>e?h.jsxs(_.FloatingPanelFrame,{style:t,children:[h.jsx(Nt,{header:n,dismissible:r,onClose:o}),h.jsx(_.FloatingPanelContent,{style:{padding:U.DRAWER_CONTENT_PADDING,flex:1,display:"flex",flexDirection:"column"},children:i})]}):h.jsx(h.Fragment,{children:i});function Lt(e,t){return e?t:!1}function Ft(e,t){return e?h.jsx(_.FloatingPanelCloseButton,{onClick:t,"aria-label":"Close drawer",style:{marginLeft:"auto"}}):null}function kt(e,t,n,r,o){return e?h.jsx("div",{ref:t,style:n,onPointerDown:r,"data-drawer-edge-zone":o}):null}function It(e,t,n){return e==="left"||e==="right"?typeof t=="number"?t:0:typeof n=="number"?n:0}const Nt=({header:e,dismissible:t,onClose:n})=>{if(!e)return null;const r=e.showCloseButton??!0,o=Lt(t,r);return h.jsxs(_.FloatingPanelHeader,{style:{padding:`${U.DRAWER_HEADER_PADDING_Y} ${U.DRAWER_HEADER_PADDING_X}`,gap:U.DRAWER_HEADER_GAP},children:[h.jsx(_.FloatingPanelTitle,{children:e.title}),Ft(o,n)]})};function Wt(e,t,n,r,o){const i=Z(r.animationMode);return s.useMemo(()=>{const a=r.inline?"absolute":"fixed",c=Ke(e);if(i)return{...ie,position:a,top:c.top,bottom:c.bottom,left:c.left,right:c.right,zIndex:0,visibility:"hidden",pointerEvents:"none",width:q(o.width),height:q(o.height)};const u=n?"none":r.transitionMode,l=Qe(u,r.transitionDuration,r.transitionEasing),d=t?Je(e):c.transform;return{...ie,position:a,...c,transform:d,transition:l,zIndex:o.zIndex,width:q(o.width),height:q(o.height)}},[e,t,n,r,o,i])}function jt(e,t,n,r,o){const i=Z(n.animationMode);return s.useMemo(()=>{if(i)return{display:"none"};const a=n.inline?"absolute":"fixed";if(o)return{...oe,position:a,opacity:0,pointerEvents:"none",zIndex:r!==void 0?r-1:void 0};const c=t?"none":n.transitionMode,u=et(c,n.transitionDuration);return{...oe,position:a,opacity:e?1:0,pointerEvents:e?"auto":"none",transition:u,zIndex:r!==void 0?r-1:void 0}},[e,t,n,r,i,o])}function zt(e){return s.useMemo(()=>{const t={borderRadius:0};return(e==="left"||e==="right")&&(t.height="100%"),t},[e])}const Se=({id:e,config:t,isOpen:n,onClose:r,onOpen:o,children:i,zIndex:a,width:c,height:u,position:l})=>{const{dismissible:d=!0,header:p,chrome:w=!0,inline:O=!1}=t,C=it(t.swipeGestures),D=st(t.anchor,l),E=s.useRef(null),f=s.useRef(null),g=s.useRef(null),G=s.useCallback(()=>{o?.(),t.onStateChange?.(!0)},[o,t]),b=s.useCallback(()=>{r()},[r]),{state:I,displacement:R,edgeContainerProps:x,drawerContentProps:M,isOpening:W,isClosing:P}=Ze({edgeContainerRef:g,drawerContentRef:E,direction:D,isOpen:n,onSwipeOpen:G,onSwipeClose:b,enableEdgeSwipeOpen:C.edgeSwipeOpen,enableSwipeClose:C.swipeClose,edgeWidth:C.edgeWidth,dismissThreshold:C.dismissThreshold}),v=I.phase==="operating"||I.phase==="ended",L=Z(t.animationMode),j=C.enabled?!L:!1;Rt({drawerRef:E,backdropRef:f,placement:D,swipeState:I,displacement:R,isOpening:W,isClosing:P,isOpen:n,enabled:j});const F=It(D,c,u),{gridRef:z}=he();Mt({drawerRef:E,placement:D,drawerSize:F,isOpen:n,swipeState:I,displacement:R,isOpening:W,isClosing:P,enabled:L,inline:O,gridRef:z??void 0,contentBackground:t.revealBackground});const H=Wt(D,n,v,t,{width:c,height:u,zIndex:a}),S=jt(n,v,t,a,j),m=zt(D),y=s.useMemo(()=>({...tt({placement:D,inline:O,edgeWidth:C.edgeWidth,zIndex:a}),...x.style}),[D,O,C.edgeWidth,a,x.style]),T=s.useMemo(()=>C.enabled?{...H,...M.style}:H,[C.enabled,H,M.style]),A=at(C,n,W),N=p?.title??t.ariaLabel??"Drawer",ve=kt(A,g,y,x.onPointerDown,D);return h.jsxs(h.Fragment,{children:[ve,h.jsx("div",{ref:f,style:S,onClick:d?r:void 0}),h.jsx("div",{ref:E,"data-layer-id":e,"data-placement":D,style:T,role:"dialog","aria-modal":d?!0:void 0,"aria-hidden":n?void 0:!0,"aria-label":N,onPointerDown:C.enabled?M.onPointerDown:void 0,children:h.jsx(_t,{chrome:w,frameStyle:m,header:p,dismissible:d,onClose:r,children:i})})]})},Ht=(e,t)=>new Promise(n=>{let r=!1;const o=()=>{r||(r=!0,e.removeEventListener("transitionend",i),n())},i=a=>{a.target===e&&o()};e.addEventListener("transitionend",i),setTimeout(o,t+50)}),re=async(e,t,n,r)=>{switch(t){case"none":e();return;case"css":e(),n&&await Ht(n,r);return}},Bt=e=>{const[t,n]=s.useState({}),r=s.useRef(e);r.current=e;const o=s.useCallback(async(u,l,d)=>{const{mode:p="none",element:w,duration:O=300}=d??{};await re(()=>{n(E=>E[u]===l?E:{...E,[u]:l})},p,w?.current,O);const D=r.current;l?D?.onOpen?.(u):D?.onClose?.(u),D?.onTransitionEnd?.(u,l)},[]),i=s.useCallback(u=>t[u]??!1,[t]),a=s.useCallback((u,l)=>o(u,!0,l),[o]),c=s.useCallback((u,l)=>o(u,!1,l),[o]);return{state:i,open:a,close:c}},$t=e=>{if(!e)return 300;const t=e.match(/(\d+)/);return t?parseInt(t[1],10):300},be=e=>{const[t,n]=s.useState(()=>{const u={};return e.forEach(l=>{l.drawer&&(u[l.id]=l.drawer.defaultOpen??!1)}),u}),r=s.useMemo(()=>{const u=new Map;return e.forEach(l=>u.set(l.id,l)),u},[e]),o=s.useCallback(async(u,l,d)=>{const p=r.get(u);if(!p?.drawer)return;const w=d?.mode??p.drawer.transitionMode??"css",O=d?.duration??$t(p.drawer.transitionDuration),C=d?.element?.current;await re(()=>{p.drawer?.open===void 0&&n(E=>E[u]===l?E:{...E,[u]:l}),p.drawer?.onStateChange?.(l)},w,C,O)},[r]),i=s.useCallback(u=>{const l=r.get(u);return l?.drawer?.open!==void 0?l.drawer.open:t[u]??!1},[r,t]),a=s.useCallback((u,l)=>o(u,!0,l),[o]),c=s.useCallback((u,l)=>o(u,!1,l),[o]);return{state:i,open:a,close:c}};function Gt(e){if(!e.drawer)return!1;const{animationMode:t,inline:n=!1}=e.drawer;return Z(t)?!n:!1}function ae(e,t){const n=new Map;return e.forEach(r=>{n.set(r.id,t(r.id))}),n}const Ut=({layers:e})=>{const t=be(e),n=s.useMemo(()=>e.filter(i=>i.drawer),[e]),r=s.useMemo(()=>ae(n,i=>()=>t.close(i)),[n,t.close]),o=s.useMemo(()=>ae(n,i=>()=>t.open(i)),[n,t.open]);return h.jsx(h.Fragment,{children:n.map(i=>{if(!i.drawer)return null;const a=t.state(i.id),c=r.get(i.id),u=o.get(i.id);if(!c)return null;const l=h.jsx(Se,{id:i.id,config:i.drawer,isOpen:a,onClose:c,onOpen:u,zIndex:i.zIndex,width:i.width,height:i.height,position:i.position,children:i.component},i.id);return Gt(i)?Te.createPortal(l,document.body):l})})},Ee=s.createContext(null),Vt=({value:e,children:t})=>h.jsx(Ee.Provider,{value:e,children:t}),Yt=()=>{const e=s.useContext(Ee);if(!e)throw new Error("useGridLayoutContext must be used within a GridLayoutProvider.");return e},Pe=s.createContext(null),Zt=()=>{const e=s.useContext(Pe);if(!e)throw new Error("usePanelSystem must be used within a PanelSystemProvider.");return e},qt=({config:e,layers:t,style:n,children:r})=>{const o=s.useMemo(()=>{const l=new Map;return t.forEach(d=>{l.set(d.id,d)}),l},[t]),i=s.useCallback(l=>o.get(l)?.component??null,[o]),a=s.useMemo(()=>t.map(l=>l.id),[t]),{getCachedContent:c}=Re.useContentCache({resolveContent:i,validIds:a}),u=s.useMemo(()=>({config:e,style:n,layers:{defs:t,layerById:o},getCachedContent:c}),[e,n,t,o,c]);return h.jsx(Pe.Provider,{value:u,children:r})},ye=s.createContext(null),Oe=({layerId:e,children:t})=>{const n=s.useMemo(()=>({layerId:e}),[e]);return h.jsx(ye.Provider,{value:n,children:t})},Xt=()=>{const e=s.useContext(ye);if(!e)throw new Error("useLayerInstance must be used within a LayerInstanceProvider.");return e},ce=(e,t,n)=>{if(typeof e=="number"&&Number.isFinite(e))return e;throw new Error(`Popup layer "${n}" requires a numeric "${t}" value.`)},Ce=(e,t)=>{if(!e)throw new Error(`Popup layer "${t}" must define position (left/top).`);return{left:ce(e.left,"left",t),top:ce(e.top,"top",t)}},X=e=>`${Math.round(e)}`,V=e=>{if(e!==void 0)return e?"yes":"no"},Kt=(e,t,n,r,o)=>{const i={},a=Ce(t,e);if(typeof n!="number"||typeof r!="number")throw new Error(`Popup layer "${e}" requires numeric width/height.`);i.width=X(n),i.height=X(r),i.left=X(a.left),i.top=X(a.top);const c=o?.features;if(c){const u=V(c.toolbar),l=V(c.menubar),d=V(c.location),p=V(c.status),w=V(c.resizable),O=V(c.scrollbars);u!==void 0&&(i.toolbar=u),l!==void 0&&(i.menubar=l),d!==void 0&&(i.location=d),p!==void 0&&(i.status=p),w!==void 0&&(i.resizable=w),O!==void 0&&(i.scrollbars=O)}return Object.entries(i).map(([u,l])=>`${u}=${l}`).join(",")},ue=(e,t,n,r,o)=>{const i=Ce(n,t);if(typeof r!="number"||typeof o!="number")throw new Error(`Popup layer "${t}" requires numeric width/height.`);e.moveTo(Math.round(i.left),Math.round(i.top)),e.resizeTo(Math.round(r),Math.round(o))},Jt=({layer:e})=>{const t=e.floating;if(!t)throw new Error(`Layer "${e.id}" is missing floating configuration required for popup mode.`);if((t.mode??"embedded")!=="popup")throw new Error(`PopupLayerPortal received layer "${e.id}" that is not configured for popup mode.`);const r=s.useRef(null),o=s.useRef(null),[i,a]=s.useState(!1);return s.useEffect(()=>{if(typeof window>"u")return;const c=Kt(e.id,e.position,e.width,e.height,t.popup),u=t.popup?.name??e.id,l=Qt(u,c,{position:e.position,size:{width:e.width,height:e.height}},t.popup);if(!l)throw new Error(`Failed to open popup window for layer "${e.id}".`);const d=l;o.current=d,t.popup?.focus!==!1&&d.focus(),d.document.title||(d.document.title=e.id),d.document.body.innerHTML="";const p=d.document.createElement("div");p.dataset.layerId=e.id,d.document.body.appendChild(p),r.current=p,a(!0),ue(d,e.id,e.position,e.width,e.height);const w=()=>{o.current=null,r.current=null,a(!1)};return d.addEventListener("beforeunload",w),()=>{d.removeEventListener("beforeunload",w),t.popup?.closeOnUnmount!==!1&&d.close(),o.current=null,r.current=null,a(!1)}},[t.popup?.closeOnUnmount,t.popup?.features?.location,t.popup?.features?.menubar,t.popup?.features?.resizable,t.popup?.features?.scrollbars,t.popup?.features?.status,t.popup?.features?.toolbar,t.popup?.focus,t.popup?.name,e.id]),s.useEffect(()=>{const c=o.current;c&&ue(c,e.id,e.position,e.width,e.height)},[e.position?.left,e.position?.top,e.height,e.width,e.id]),!i||!r.current?null:le.createPortal(h.jsx(Oe,{layerId:e.id,children:e.component}),r.current)},Qt=(e,t,n,r)=>{const o=r?.createWindow;return o?o({name:e,features:t,bounds:n}):window.open("",e,t)},en=({onClick:e})=>h.jsx(_.FloatingPanelControls,{children:h.jsx(_.FloatingPanelCloseButton,{onClick:e,"aria-label":"Close window","data-drag-ignore":"true"})}),tn=({header:e,draggable:t,onClose:n})=>{if(!e)return null;const r=e.showCloseButton??!1,o=t?{"data-drag-handle":"true"}:{},i=t?"grab":void 0;return h.jsxs(_.FloatingPanelHeader,{...o,style:{cursor:i},children:[e.title?h.jsx(_.FloatingPanelTitle,{children:e.title}):null,r?h.jsx(en,{onClick:n}):null]})},nn=({header:e,draggable:t,chrome:n,onClose:r,children:o})=>n?h.jsxs(_.FloatingPanelFrame,{style:{height:"100%",width:"100%"},children:[h.jsx(tn,{header:e,draggable:t,onClose:r}),h.jsx(_.FloatingPanelContent,{style:{flex:1,display:"flex",flexDirection:"column"},children:o})]}):h.jsx(h.Fragment,{children:o}),De=({id:e,config:t,onClose:n,children:r})=>{const o=t.chrome??!1,i=t.draggable??!1,a=t.header?.title??t.ariaLabel??"Floating window";return h.jsx("div",{"data-floating-window":e,role:"dialog","aria-label":a,style:{height:"100%",width:"100%"},children:h.jsx(nn,{header:t.header,draggable:i,chrome:o,onClose:n,children:r})})};De.displayName="FloatingWindow";exports.Drawer=Se;exports.DrawerLayers=Ut;exports.DrawerRevealProvider=At;exports.FloatingWindow=De;exports.GridLayoutProvider=Vt;exports.LayerInstanceProvider=Oe;exports.PanelSystemProvider=qt;exports.PopupLayerPortal=Jt;exports.SwipeSafeZone=Me;exports.bindActionCreators=ct;exports.createAction=k;exports.createActionHandlerMap=fe;exports.isRevealMode=Z;exports.runTransition=re;exports.useDrawerReveal=he;exports.useDrawerState=be;exports.useGridLayoutContext=Yt;exports.useLayerInstance=Xt;exports.usePanelSystem=Zt;exports.useTransitionState=Bt;
2
+ //# sourceMappingURL=FloatingWindow-Cvyokf0m.cjs.map