react-panel-layout 0.5.2 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. package/dist/{FloatingPanelFrame-lLg-Lpg7.js → FloatingPanelFrame-3eU9AwPo.js} +11 -11
  2. package/dist/{FloatingPanelFrame-lLg-Lpg7.js.map → FloatingPanelFrame-3eU9AwPo.js.map} +1 -1
  3. package/dist/{FloatingPanelFrame-D9Cp2al1.cjs → FloatingPanelFrame-CEmXDvUA.cjs} +2 -2
  4. package/dist/{FloatingPanelFrame-D9Cp2al1.cjs.map → FloatingPanelFrame-CEmXDvUA.cjs.map} +1 -1
  5. package/dist/FloatingWindow-CUXnEtrb.js +827 -0
  6. package/dist/FloatingWindow-CUXnEtrb.js.map +1 -0
  7. package/dist/FloatingWindow-DMwyK0eK.cjs +2 -0
  8. package/dist/FloatingWindow-DMwyK0eK.cjs.map +1 -0
  9. package/dist/GridLayout-DKTg_N61.cjs +2 -0
  10. package/dist/GridLayout-DKTg_N61.cjs.map +1 -0
  11. package/dist/GridLayout-UWNxXw77.js +926 -0
  12. package/dist/GridLayout-UWNxXw77.js.map +1 -0
  13. package/dist/HorizontalDivider-DdxzfV0l.js +30 -0
  14. package/dist/HorizontalDivider-DdxzfV0l.js.map +1 -0
  15. package/dist/HorizontalDivider-_pgV4Mcv.cjs +2 -0
  16. package/dist/HorizontalDivider-_pgV4Mcv.cjs.map +1 -0
  17. package/dist/PanelSystem-BqUzNtf2.js +1946 -0
  18. package/dist/PanelSystem-BqUzNtf2.js.map +1 -0
  19. package/dist/PanelSystem-D603LKKv.cjs +3 -0
  20. package/dist/PanelSystem-D603LKKv.cjs.map +1 -0
  21. package/dist/ResizeHandle-CBcAS918.cjs +2 -0
  22. package/dist/ResizeHandle-CBcAS918.cjs.map +1 -0
  23. package/dist/ResizeHandle-CXjc1meV.js +119 -0
  24. package/dist/ResizeHandle-CXjc1meV.js.map +1 -0
  25. package/dist/SwipePivotTabBar-DWrCuwEI.js +411 -0
  26. package/dist/SwipePivotTabBar-DWrCuwEI.js.map +1 -0
  27. package/dist/SwipePivotTabBar-fjjXkpj7.cjs +2 -0
  28. package/dist/SwipePivotTabBar-fjjXkpj7.cjs.map +1 -0
  29. package/dist/components/gesture/SwipeSafeZone.d.ts +40 -0
  30. package/dist/components/window/Drawer.d.ts +3 -1
  31. package/dist/components/window/DrawerLayers.d.ts +1 -1
  32. package/dist/components/window/drawerStyles.d.ts +69 -0
  33. package/dist/components/window/drawerSwipeConfig.d.ts +29 -0
  34. package/dist/components/window/useDrawerSwipeTransform.d.ts +23 -0
  35. package/dist/config.cjs +1 -1
  36. package/dist/config.cjs.map +1 -1
  37. package/dist/config.js +11 -9
  38. package/dist/config.js.map +1 -1
  39. package/dist/constants/styles.d.ts +35 -4
  40. package/dist/dialog/index.d.ts +69 -0
  41. package/dist/floating.cjs +1 -1
  42. package/dist/floating.js +1 -1
  43. package/dist/grid/index.d.ts +58 -0
  44. package/dist/grid.cjs +2 -0
  45. package/dist/grid.cjs.map +1 -0
  46. package/dist/grid.js +13 -0
  47. package/dist/grid.js.map +1 -0
  48. package/dist/hooks/gesture/presets.d.ts +33 -0
  49. package/dist/hooks/gesture/testing/createGestureSimulator.d.ts +117 -0
  50. package/dist/hooks/gesture/thresholdValue.d.ts +44 -0
  51. package/dist/hooks/gesture/types.d.ts +297 -0
  52. package/dist/hooks/gesture/useDirectionalLock.d.ts +20 -0
  53. package/dist/hooks/gesture/useEdgeSwipeInput.d.ts +23 -0
  54. package/dist/hooks/gesture/useNativeGestureGuard.d.ts +23 -0
  55. package/dist/hooks/gesture/usePointerTracking.d.ts +22 -0
  56. package/dist/hooks/gesture/useScrollBoundary.d.ts +23 -0
  57. package/dist/hooks/gesture/useSwipeInput.d.ts +5 -0
  58. package/dist/hooks/gesture/utils.d.ts +59 -0
  59. package/dist/hooks/useAnimatedVisibility.d.ts +58 -0
  60. package/dist/hooks/useAnimationFrame.d.ts +86 -0
  61. package/dist/hooks/useOperationContinuity.d.ts +64 -0
  62. package/dist/hooks/useResizeObserver.d.ts +33 -1
  63. package/dist/hooks/useSharedElementTransition.d.ts +112 -0
  64. package/dist/hooks/useSnapAnimation.d.ts +54 -0
  65. package/dist/hooks/useSwipeContentTransform.d.ts +86 -0
  66. package/dist/index.cjs +1 -2
  67. package/dist/index.cjs.map +1 -1
  68. package/dist/index.d.ts +0 -1
  69. package/dist/index.js +25 -2006
  70. package/dist/index.js.map +1 -1
  71. package/dist/modules/dialog/AlertDialog.d.ts +9 -0
  72. package/dist/modules/dialog/DialogContainer.d.ts +37 -0
  73. package/dist/modules/dialog/Modal.d.ts +26 -0
  74. package/dist/modules/dialog/SwipeDialogContainer.d.ts +16 -0
  75. package/dist/modules/dialog/dialogAnimationUtils.d.ts +113 -0
  76. package/dist/modules/dialog/types.d.ts +183 -0
  77. package/dist/modules/dialog/useDialog.d.ts +39 -0
  78. package/dist/modules/dialog/useDialogContainer.d.ts +47 -0
  79. package/dist/modules/dialog/useDialogSwipeInput.d.ts +70 -0
  80. package/dist/modules/dialog/useDialogTransform.d.ts +82 -0
  81. package/dist/modules/drawer/types.d.ts +74 -0
  82. package/dist/modules/drawer/useDrawerSwipeInput.d.ts +24 -0
  83. package/dist/modules/pivot/PivotContent.d.ts +1 -1
  84. package/dist/modules/pivot/SwipePivotContent.d.ts +39 -0
  85. package/dist/modules/pivot/SwipePivotContent.debug.tmp.d.ts +25 -0
  86. package/dist/modules/pivot/SwipePivotContent.test.d.ts +1 -0
  87. package/dist/modules/pivot/SwipePivotTabBar.d.ts +92 -0
  88. package/dist/modules/pivot/index.d.ts +3 -0
  89. package/dist/modules/pivot/scaleInputState.d.ts +37 -0
  90. package/dist/modules/pivot/types.d.ts +67 -2
  91. package/dist/modules/pivot/usePivotSwipeInput.d.ts +68 -0
  92. package/dist/modules/stack/StackContent.d.ts +15 -0
  93. package/dist/modules/stack/SwipeStackContent.d.ts +66 -0
  94. package/dist/modules/stack/SwipeStackOutlet.d.ts +80 -0
  95. package/dist/modules/stack/computeStackContentState.d.ts +99 -0
  96. package/dist/modules/stack/computeSwipeStackTransform.d.ts +76 -0
  97. package/dist/modules/stack/types.d.ts +194 -0
  98. package/dist/modules/stack/useStackAnimationState.d.ts +32 -0
  99. package/dist/modules/stack/useStackNavigation.d.ts +23 -0
  100. package/dist/modules/stack/useStackSwipeInput.d.ts +27 -0
  101. package/dist/panels/index.d.ts +67 -0
  102. package/dist/panels.cjs +2 -0
  103. package/dist/panels.cjs.map +1 -0
  104. package/dist/panels.js +28 -0
  105. package/dist/panels.js.map +1 -0
  106. package/dist/pivot/index.d.ts +3 -0
  107. package/dist/pivot.cjs +1 -1
  108. package/dist/pivot.cjs.map +1 -1
  109. package/dist/pivot.js +20 -2
  110. package/dist/pivot.js.map +1 -1
  111. package/dist/resizer/index.d.ts +57 -0
  112. package/dist/resizer.cjs +2 -0
  113. package/dist/resizer.cjs.map +1 -0
  114. package/dist/resizer.js +8 -0
  115. package/dist/resizer.js.map +1 -0
  116. package/dist/stack/index.d.ts +72 -0
  117. package/dist/stack.cjs +2 -0
  118. package/dist/stack.cjs.map +1 -0
  119. package/dist/stack.js +721 -0
  120. package/dist/stack.js.map +1 -0
  121. package/dist/sticky-header/StickyArea.d.ts +38 -0
  122. package/dist/sticky-header/calculateStickyMetrics.d.ts +28 -0
  123. package/dist/sticky-header/index.d.ts +4 -4
  124. package/dist/sticky-header/types.d.ts +35 -22
  125. package/dist/sticky-header.cjs +1 -1
  126. package/dist/sticky-header.cjs.map +1 -1
  127. package/dist/sticky-header.js +73 -174
  128. package/dist/sticky-header.js.map +1 -1
  129. package/dist/styles-NkjuMOVS.js +57 -0
  130. package/dist/styles-NkjuMOVS.js.map +1 -0
  131. package/dist/styles-qf6ptVLD.cjs +2 -0
  132. package/dist/styles-qf6ptVLD.cjs.map +1 -0
  133. package/dist/types.d.ts +16 -0
  134. package/dist/useContentCache-CO3LYNmz.js +24 -0
  135. package/dist/useContentCache-CO3LYNmz.js.map +1 -0
  136. package/dist/useContentCache-DqXtLrLs.cjs +2 -0
  137. package/dist/useContentCache-DqXtLrLs.cjs.map +1 -0
  138. package/dist/useDocumentPointerEvents-DXxw3qWj.js +54 -0
  139. package/dist/useDocumentPointerEvents-DXxw3qWj.js.map +1 -0
  140. package/dist/useDocumentPointerEvents-DxDSOtip.cjs +2 -0
  141. package/dist/useDocumentPointerEvents-DxDSOtip.cjs.map +1 -0
  142. package/dist/useFloatingState-C4kRaW_R.cjs +2 -0
  143. package/dist/useFloatingState-C4kRaW_R.cjs.map +1 -0
  144. package/dist/useFloatingState-tEfA_wbc.js +74 -0
  145. package/dist/useFloatingState-tEfA_wbc.js.map +1 -0
  146. package/dist/useNativeGestureGuard-C7TSqEkr.cjs +2 -0
  147. package/dist/useNativeGestureGuard-C7TSqEkr.cjs.map +1 -0
  148. package/dist/useNativeGestureGuard-CGYo6O0r.js +347 -0
  149. package/dist/useNativeGestureGuard-CGYo6O0r.js.map +1 -0
  150. package/dist/window/index.d.ts +63 -0
  151. package/dist/window.cjs +2 -0
  152. package/dist/window.cjs.map +1 -0
  153. package/dist/window.js +160 -0
  154. package/dist/window.js.map +1 -0
  155. package/docs/design-tokens.md +405 -0
  156. package/package.json +34 -4
  157. package/src/PanelSystemContext.tsx +88 -0
  158. package/src/components/gesture/SwipeSafeZone.tsx +69 -0
  159. package/src/components/grid/GridLayerList.tsx +172 -0
  160. package/src/components/grid/GridLayerResizeHandles.tsx +145 -0
  161. package/src/components/grid/GridLayout.spec.tsx +743 -0
  162. package/src/components/grid/GridLayout.tsx +130 -0
  163. package/src/components/grid/GridTrackResizeHandle.tsx +87 -0
  164. package/src/components/paneling/FloatingPanelFrame.tsx +203 -0
  165. package/src/components/panels/DropSuggestOverlay.tsx +131 -0
  166. package/src/components/panels/PanelGroupView.tsx +112 -0
  167. package/src/components/pivot/PivotLayer.tsx +27 -0
  168. package/src/components/resizer/HorizontalDivider.tsx +52 -0
  169. package/src/components/resizer/ResizeHandle.tsx +118 -0
  170. package/src/components/tabs/TabBar.tsx +223 -0
  171. package/src/components/tabs/TabBarTab.tsx +133 -0
  172. package/src/components/tabs/TabDragOverlay.tsx +92 -0
  173. package/src/components/window/DialogOverlay.tsx +180 -0
  174. package/src/components/window/Drawer.tsx +369 -0
  175. package/src/components/window/DrawerLayers.tsx +68 -0
  176. package/src/components/window/FloatingWindow.tsx +95 -0
  177. package/src/components/window/PopupLayerPortal.tsx +218 -0
  178. package/src/components/window/drawerStyles.spec.ts +263 -0
  179. package/src/components/window/drawerStyles.ts +228 -0
  180. package/src/components/window/drawerSwipeConfig.spec.ts +131 -0
  181. package/src/components/window/drawerSwipeConfig.ts +112 -0
  182. package/src/components/window/useDrawerSwipeTransform.spec.ts +234 -0
  183. package/src/components/window/useDrawerSwipeTransform.ts +129 -0
  184. package/src/config/PanelContentDeclaration.tsx +427 -0
  185. package/src/config/index.tsx +52 -0
  186. package/src/config/panelJsx.spec.tsx +54 -0
  187. package/src/config/panelJsxConfig.spec.tsx +54 -0
  188. package/src/config/panelJsxDrawer.spec.tsx +33 -0
  189. package/src/config/panelRouter.spec.ts +68 -0
  190. package/src/config/panelRouter.tsx +155 -0
  191. package/src/constants/styles.ts +280 -0
  192. package/src/demo/Layout.module.css +258 -0
  193. package/src/demo/Layout.tsx +176 -0
  194. package/src/demo/components/CodeBlock.module.css +54 -0
  195. package/src/demo/components/CodeBlock.tsx +34 -0
  196. package/src/demo/components/CodePreview.module.css +37 -0
  197. package/src/demo/components/CodePreview.tsx +31 -0
  198. package/src/demo/components/DataPreview.module.css +177 -0
  199. package/src/demo/components/DataPreview.tsx +115 -0
  200. package/src/demo/components/Story.module.css +68 -0
  201. package/src/demo/components/Story.tsx +54 -0
  202. package/src/demo/components/layout/CodePanel.module.css +183 -0
  203. package/src/demo/components/layout/CodePanel.tsx +149 -0
  204. package/src/demo/components/layout/DemoPage.module.css +60 -0
  205. package/src/demo/components/layout/DemoPage.tsx +56 -0
  206. package/src/demo/components/layout/SingleSamplePage.module.css +11 -0
  207. package/src/demo/components/layout/SingleSamplePage.tsx +35 -0
  208. package/src/demo/components/layout/SplitDemoLayout.module.css +107 -0
  209. package/src/demo/components/layout/SplitDemoLayout.tsx +218 -0
  210. package/src/demo/components/layout/index.ts +11 -0
  211. package/src/demo/components/tab-styles/ChromeTabBar.module.css +75 -0
  212. package/src/demo/components/tab-styles/ChromeTabBar.tsx +111 -0
  213. package/src/demo/components/tab-styles/GitHubTabBar.module.css +81 -0
  214. package/src/demo/components/tab-styles/GitHubTabBar.tsx +109 -0
  215. package/src/demo/components/tab-styles/VSCodeTabBar.module.css +78 -0
  216. package/src/demo/components/tab-styles/VSCodeTabBar.tsx +109 -0
  217. package/src/demo/components/tab-styles/index.ts +6 -0
  218. package/src/demo/components/ui/DemoButton.module.css +63 -0
  219. package/src/demo/components/ui/DemoButton.tsx +32 -0
  220. package/src/demo/components/ui/DemoCard.module.css +15 -0
  221. package/src/demo/components/ui/DemoCard.tsx +30 -0
  222. package/src/demo/components/ui/DemoContainer.module.css +17 -0
  223. package/src/demo/components/ui/DemoContainer.tsx +30 -0
  224. package/src/demo/components/ui/DemoPanel.module.css +23 -0
  225. package/src/demo/components/ui/DemoPanel.tsx +33 -0
  226. package/src/demo/components/ui/PanelText.module.css +18 -0
  227. package/src/demo/components/ui/PanelText.tsx +29 -0
  228. package/src/demo/components/ui/PanelTitle.module.css +18 -0
  229. package/src/demo/components/ui/PanelTitle.tsx +31 -0
  230. package/src/demo/contexts/TabbarDemoConfig.tsx +218 -0
  231. package/src/demo/demo.css +172 -0
  232. package/src/demo/hooks/useMedia.ts +41 -0
  233. package/src/demo/hooks/useShikiHighlight.ts +55 -0
  234. package/src/demo/index.tsx +293 -0
  235. package/src/demo/pages/Dialog/alerts/index.tsx +22 -0
  236. package/src/demo/pages/Dialog/card/index.tsx +22 -0
  237. package/src/demo/pages/Dialog/components/AlertDialogDemo.tsx +124 -0
  238. package/src/demo/pages/Dialog/components/CardExpandDemo.module.css +243 -0
  239. package/src/demo/pages/Dialog/components/CardExpandDemo.tsx +204 -0
  240. package/src/demo/pages/Dialog/components/CustomAlertDialogDemo.tsx +219 -0
  241. package/src/demo/pages/Dialog/components/DialogDemos.module.css +77 -0
  242. package/src/demo/pages/Dialog/components/ModalBasics.tsx +45 -0
  243. package/src/demo/pages/Dialog/components/SwipeDialogDemo.module.css +77 -0
  244. package/src/demo/pages/Dialog/components/SwipeDialogDemo.tsx +181 -0
  245. package/src/demo/pages/Dialog/custom-alert/index.tsx +22 -0
  246. package/src/demo/pages/Dialog/modal/index.tsx +17 -0
  247. package/src/demo/pages/Dialog/swipe/index.tsx +22 -0
  248. package/src/demo/pages/Drawer/animations/index.tsx +22 -0
  249. package/src/demo/pages/Drawer/basics/index.tsx +17 -0
  250. package/src/demo/pages/Drawer/components/DrawerAnimations.module.css +125 -0
  251. package/src/demo/pages/Drawer/components/DrawerAnimations.tsx +118 -0
  252. package/src/demo/pages/Drawer/components/DrawerBasics.module.css +55 -0
  253. package/src/demo/pages/Drawer/components/DrawerBasics.tsx +76 -0
  254. package/src/demo/pages/Drawer/components/DrawerMenuLayout.module.css +332 -0
  255. package/src/demo/pages/Drawer/components/DrawerMenuLayout.tsx +199 -0
  256. package/src/demo/pages/Drawer/components/DrawerSwipe.module.css +316 -0
  257. package/src/demo/pages/Drawer/components/DrawerSwipe.tsx +178 -0
  258. package/src/demo/pages/Drawer/menu/index.tsx +17 -0
  259. package/src/demo/pages/Drawer/swipe/index.tsx +17 -0
  260. package/src/demo/pages/FloatingPanelFrame/ResizableFloatingPanelsPreview.module.css +163 -0
  261. package/src/demo/pages/FloatingPanelFrame/ResizableFloatingPanelsPreview.tsx +234 -0
  262. package/src/demo/pages/FloatingPanelFrame/basic/index.tsx +17 -0
  263. package/src/demo/pages/FloatingPanelFrame/complex/index.tsx +26 -0
  264. package/src/demo/pages/FloatingPanelFrame/components/BasicPanel.module.css +16 -0
  265. package/src/demo/pages/FloatingPanelFrame/components/BasicPanel.tsx +24 -0
  266. package/src/demo/pages/FloatingPanelFrame/components/ComplexPanel.module.css +54 -0
  267. package/src/demo/pages/FloatingPanelFrame/components/ComplexPanel.tsx +67 -0
  268. package/src/demo/pages/FloatingPanelFrame/components/PanelWithControls.module.css +21 -0
  269. package/src/demo/pages/FloatingPanelFrame/components/PanelWithControls.tsx +41 -0
  270. package/src/demo/pages/FloatingPanelFrame/components/PanelWithMeta.module.css +5 -0
  271. package/src/demo/pages/FloatingPanelFrame/components/PanelWithMeta.tsx +43 -0
  272. package/src/demo/pages/FloatingPanelFrame/components/ScrollablePanel.module.css +11 -0
  273. package/src/demo/pages/FloatingPanelFrame/components/ScrollablePanel.tsx +42 -0
  274. package/src/demo/pages/FloatingPanelFrame/index.tsx +80 -0
  275. package/src/demo/pages/FloatingPanelFrame/scrollable/index.tsx +30 -0
  276. package/src/demo/pages/FloatingPanelFrame/with-controls/index.tsx +30 -0
  277. package/src/demo/pages/FloatingPanelFrame/with-meta/index.tsx +17 -0
  278. package/src/demo/pages/HorizontalDivider/components/PanelsWithRichContent.module.css +112 -0
  279. package/src/demo/pages/HorizontalDivider/components/PanelsWithRichContent.tsx +56 -0
  280. package/src/demo/pages/HorizontalDivider/components/SimpleResizablePanels.module.css +46 -0
  281. package/src/demo/pages/HorizontalDivider/components/SimpleResizablePanels.tsx +29 -0
  282. package/src/demo/pages/HorizontalDivider/components/ThreePanelLayout.module.css +54 -0
  283. package/src/demo/pages/HorizontalDivider/components/ThreePanelLayout.tsx +30 -0
  284. package/src/demo/pages/HorizontalDivider/index.module.css +14 -0
  285. package/src/demo/pages/HorizontalDivider/index.tsx +64 -0
  286. package/src/demo/pages/HorizontalDivider/panels-with-rich-content/index.tsx +21 -0
  287. package/src/demo/pages/HorizontalDivider/simple-resizable-panels/index.tsx +21 -0
  288. package/src/demo/pages/HorizontalDivider/three-panel-layout/index.tsx +21 -0
  289. package/src/demo/pages/PanelLayout/PanelLayoutDemo.module.css +174 -0
  290. package/src/demo/pages/PanelLayout/PanelLayoutDemo.tsx +248 -0
  291. package/src/demo/pages/PanelLayout/components/DashboardLayout.module.css +115 -0
  292. package/src/demo/pages/PanelLayout/components/DashboardLayout.tsx +124 -0
  293. package/src/demo/pages/PanelLayout/components/DraggableOverlays.module.css +101 -0
  294. package/src/demo/pages/PanelLayout/components/DraggableOverlays.tsx +122 -0
  295. package/src/demo/pages/PanelLayout/components/IDELayout.module.css +104 -0
  296. package/src/demo/pages/PanelLayout/components/IDELayout.tsx +143 -0
  297. package/src/demo/pages/PanelLayout/components/SimpleGrid.module.css +19 -0
  298. package/src/demo/pages/PanelLayout/components/SimpleGrid.tsx +62 -0
  299. package/src/demo/pages/PanelLayout/dashboard/index.tsx +22 -0
  300. package/src/demo/pages/PanelLayout/draggable-overlays/index.tsx +22 -0
  301. package/src/demo/pages/PanelLayout/ide-layout/index.tsx +22 -0
  302. package/src/demo/pages/PanelLayout/index.tsx +94 -0
  303. package/src/demo/pages/PanelLayout/simple-grid/index.tsx +22 -0
  304. package/src/demo/pages/PanelSystem/PanelSystemPreview.module.css +20 -0
  305. package/src/demo/pages/PanelSystem/PanelSystemPreview.tsx +101 -0
  306. package/src/demo/pages/PanelSystem/preview/index.tsx +18 -0
  307. package/src/demo/pages/PanelSystem/tabbar/index.tsx +129 -0
  308. package/src/demo/pages/Pivot/basics/index.tsx +17 -0
  309. package/src/demo/pages/Pivot/components/Pivot.module.css +278 -0
  310. package/src/demo/pages/Pivot/components/PivotBasics.tsx +103 -0
  311. package/src/demo/pages/Pivot/components/PivotSidebar.tsx +168 -0
  312. package/src/demo/pages/Pivot/components/PivotTabs.tsx +129 -0
  313. package/src/demo/pages/Pivot/components/PivotTransitions.tsx +120 -0
  314. package/src/demo/pages/Pivot/components/SwipePivot.module.css +114 -0
  315. package/src/demo/pages/Pivot/components/SwipePivot.tsx +193 -0
  316. package/src/demo/pages/Pivot/components/SwipeTabsPivot.module.css +203 -0
  317. package/src/demo/pages/Pivot/components/SwipeTabsPivot.tsx +320 -0
  318. package/src/demo/pages/Pivot/sidebar/index.tsx +17 -0
  319. package/src/demo/pages/Pivot/swipe/index.tsx +16 -0
  320. package/src/demo/pages/Pivot/swipe-debug/index.tsx +287 -0
  321. package/src/demo/pages/Pivot/swipe-tabs/index.tsx +15 -0
  322. package/src/demo/pages/Pivot/tabs/index.tsx +17 -0
  323. package/src/demo/pages/Pivot/transitions/index.tsx +17 -0
  324. package/src/demo/pages/ResizeHandle/both-directions/index.tsx +17 -0
  325. package/src/demo/pages/ResizeHandle/components/BothDirectionsDemo.module.css +72 -0
  326. package/src/demo/pages/ResizeHandle/components/BothDirectionsDemo.tsx +41 -0
  327. package/src/demo/pages/ResizeHandle/components/HorizontalResizeDemo.module.css +61 -0
  328. package/src/demo/pages/ResizeHandle/components/HorizontalResizeDemo.tsx +33 -0
  329. package/src/demo/pages/ResizeHandle/components/NestedPanelsDemo.module.css +83 -0
  330. package/src/demo/pages/ResizeHandle/components/NestedPanelsDemo.tsx +53 -0
  331. package/src/demo/pages/ResizeHandle/components/VerticalResizeDemo.module.css +68 -0
  332. package/src/demo/pages/ResizeHandle/components/VerticalResizeDemo.tsx +33 -0
  333. package/src/demo/pages/ResizeHandle/horizontal/index.tsx +17 -0
  334. package/src/demo/pages/ResizeHandle/index.module.css +11 -0
  335. package/src/demo/pages/ResizeHandle/index.tsx +71 -0
  336. package/src/demo/pages/ResizeHandle/nested-panels/index.tsx +17 -0
  337. package/src/demo/pages/ResizeHandle/vertical/index.tsx +17 -0
  338. package/src/demo/pages/ResponsiveLayout/adaptive-workspace/index.tsx +22 -0
  339. package/src/demo/pages/ResponsiveLayout/components/ResponsiveWorkspace.module.css +423 -0
  340. package/src/demo/pages/ResponsiveLayout/components/ResponsiveWorkspace.tsx +398 -0
  341. package/src/demo/pages/Stack/basics/index.tsx +22 -0
  342. package/src/demo/pages/Stack/components/Stack.module.css +234 -0
  343. package/src/demo/pages/Stack/components/StackBasics.spec.tsx +152 -0
  344. package/src/demo/pages/Stack/components/StackBasics.tsx +301 -0
  345. package/src/demo/pages/Stack/components/StackTablet.module.css +299 -0
  346. package/src/demo/pages/Stack/components/StackTablet.spec.tsx +120 -0
  347. package/src/demo/pages/Stack/components/StackTablet.tsx +422 -0
  348. package/src/demo/pages/Stack/tablet/index.tsx +22 -0
  349. package/src/demo/pages/StickyHeader/basics/index.tsx +17 -0
  350. package/src/demo/pages/StickyHeader/components/StickyHeader.module.css +219 -0
  351. package/src/demo/pages/StickyHeader/components/StickyHeaderBasics.tsx +103 -0
  352. package/src/demo/routes.tsx +214 -0
  353. package/src/demo/styles/animations.css +68 -0
  354. package/src/demo/styles/stack-themes.css +35 -0
  355. package/src/demo/utils/createPanelView.tsx +58 -0
  356. package/src/dialog/index.ts +85 -0
  357. package/src/floating/index.ts +24 -0
  358. package/src/grid/index.ts +75 -0
  359. package/src/hooks/ContentCacheContext.tsx +87 -0
  360. package/src/hooks/gesture/presets.spec.ts +86 -0
  361. package/src/hooks/gesture/presets.ts +95 -0
  362. package/src/hooks/gesture/testing/createGestureSimulator.spec.ts +241 -0
  363. package/src/hooks/gesture/testing/createGestureSimulator.ts +385 -0
  364. package/src/hooks/gesture/thresholdValue.spec.ts +103 -0
  365. package/src/hooks/gesture/thresholdValue.ts +77 -0
  366. package/src/hooks/gesture/types.ts +367 -0
  367. package/src/hooks/gesture/useDirectionalLock.spec.ts +271 -0
  368. package/src/hooks/gesture/useDirectionalLock.ts +115 -0
  369. package/src/hooks/gesture/useEdgeSwipeInput.spec.ts +462 -0
  370. package/src/hooks/gesture/useEdgeSwipeInput.ts +131 -0
  371. package/src/hooks/gesture/useNativeGestureGuard.spec.ts +473 -0
  372. package/src/hooks/gesture/useNativeGestureGuard.ts +135 -0
  373. package/src/hooks/gesture/usePointerTracking.spec.ts +364 -0
  374. package/src/hooks/gesture/usePointerTracking.ts +134 -0
  375. package/src/hooks/gesture/useScrollBoundary.spec.ts +249 -0
  376. package/src/hooks/gesture/useScrollBoundary.ts +113 -0
  377. package/src/hooks/gesture/useSwipeInput.spec.ts +592 -0
  378. package/src/hooks/gesture/useSwipeInput.ts +310 -0
  379. package/src/hooks/gesture/utils.spec.ts +152 -0
  380. package/src/hooks/gesture/utils.ts +178 -0
  381. package/src/hooks/useAnimatedVisibility.spec.ts +277 -0
  382. package/src/hooks/useAnimatedVisibility.ts +172 -0
  383. package/src/hooks/useAnimationFrame.ts +208 -0
  384. package/src/hooks/useCSSMatrix.spec.ts +214 -0
  385. package/src/hooks/useCSSMatrix.ts +262 -0
  386. package/src/hooks/useClonedElementPreview.ts +28 -0
  387. package/src/hooks/useContainerScroll.ts +78 -0
  388. package/src/hooks/useContentCache.spec.tsx +232 -0
  389. package/src/hooks/useContentCache.tsx +127 -0
  390. package/src/hooks/useDocumentPointerEvents.ts +137 -0
  391. package/src/hooks/useDocumentScroll.ts +41 -0
  392. package/src/hooks/useEffectEvent.ts +40 -0
  393. package/src/hooks/useElementComponentWrapper.tsx +63 -0
  394. package/src/hooks/useIntersectionObserver.tsx +125 -0
  395. package/src/hooks/useIsomorphicLayoutEffect.ts +29 -0
  396. package/src/hooks/useOperationContinuity.spec.ts +387 -0
  397. package/src/hooks/useOperationContinuity.ts +135 -0
  398. package/src/hooks/useResizeObserver.spec.tsx +277 -0
  399. package/src/hooks/useResizeObserver.tsx +150 -0
  400. package/src/hooks/useScrollContainer.ts +73 -0
  401. package/src/hooks/useSharedElementTransition.ts +333 -0
  402. package/src/hooks/useSnapAnimation.ts +128 -0
  403. package/src/hooks/useSwipeContentTransform.spec.ts +133 -0
  404. package/src/hooks/useSwipeContentTransform.ts +373 -0
  405. package/src/hooks/useTransitionState.ts +95 -0
  406. package/src/index.tsx +88 -0
  407. package/src/modules/dialog/AlertDialog.spec.tsx +387 -0
  408. package/src/modules/dialog/AlertDialog.tsx +221 -0
  409. package/src/modules/dialog/DialogContainer.spec.tsx +228 -0
  410. package/src/modules/dialog/DialogContainer.tsx +188 -0
  411. package/src/modules/dialog/Modal.spec.tsx +220 -0
  412. package/src/modules/dialog/Modal.tsx +182 -0
  413. package/src/modules/dialog/SwipeDialogContainer.tsx +208 -0
  414. package/src/modules/dialog/dialogAnimationUtils.spec.ts +253 -0
  415. package/src/modules/dialog/dialogAnimationUtils.ts +297 -0
  416. package/src/modules/dialog/types.ts +186 -0
  417. package/src/modules/dialog/useDialog.spec.tsx +447 -0
  418. package/src/modules/dialog/useDialog.ts +214 -0
  419. package/src/modules/dialog/useDialogContainer.spec.ts +331 -0
  420. package/src/modules/dialog/useDialogContainer.ts +150 -0
  421. package/src/modules/dialog/useDialogSwipeInput.spec.ts +157 -0
  422. package/src/modules/dialog/useDialogSwipeInput.ts +319 -0
  423. package/src/modules/dialog/useDialogTransform.spec.ts +370 -0
  424. package/src/modules/dialog/useDialogTransform.ts +407 -0
  425. package/src/modules/drawer/types.ts +102 -0
  426. package/src/modules/drawer/useDrawerSwipeInput.spec.ts +566 -0
  427. package/src/modules/drawer/useDrawerSwipeInput.ts +399 -0
  428. package/src/modules/grid/GridLayoutContext.tsx +57 -0
  429. package/src/modules/grid/LayerInstanceContext.tsx +56 -0
  430. package/src/modules/grid/resizeHandles.ts +157 -0
  431. package/src/modules/grid/trackUtils.ts +146 -0
  432. package/src/modules/grid/useGridPlacements.ts +143 -0
  433. package/src/modules/grid/useGridTracks.ts +156 -0
  434. package/src/modules/grid/useLayerDragHandle.ts +16 -0
  435. package/src/modules/grid/useLayerInteractions.tsx +850 -0
  436. package/src/modules/keybindings/KeybindingsProvider.tsx +111 -0
  437. package/src/modules/panels/dom/DomRegistry.tsx +94 -0
  438. package/src/modules/panels/index.ts +45 -0
  439. package/src/modules/panels/interactions/InteractionsContext.test.tsx +330 -0
  440. package/src/modules/panels/interactions/InteractionsContext.tsx +394 -0
  441. package/src/modules/panels/interactions/dnd.ts +28 -0
  442. package/src/modules/panels/keybindings/KeybindingsInstaller.tsx +15 -0
  443. package/src/modules/panels/layout/adapter.ts +124 -0
  444. package/src/modules/panels/rendering/ContentRegistry.spec.tsx +311 -0
  445. package/src/modules/panels/rendering/ContentRegistry.tsx +205 -0
  446. package/src/modules/panels/rendering/GroupContainer.tsx +65 -0
  447. package/src/modules/panels/rendering/RenderBridge.tsx +115 -0
  448. package/src/modules/panels/rendering/RenderContext.tsx +31 -0
  449. package/src/modules/panels/state/PanelSplitHandles.tsx +147 -0
  450. package/src/modules/panels/state/PanelSystemContext.splitLimits.spec.tsx +50 -0
  451. package/src/modules/panels/state/PanelSystemContext.tsx +289 -0
  452. package/src/modules/panels/state/StateContext.tsx +12 -0
  453. package/src/modules/panels/state/cleanup.ts +37 -0
  454. package/src/modules/panels/state/commands.ts +53 -0
  455. package/src/modules/panels/state/focus/Context.tsx +25 -0
  456. package/src/modules/panels/state/focus/logic.ts +57 -0
  457. package/src/modules/panels/state/groups/Context.tsx +25 -0
  458. package/src/modules/panels/state/groups/logic.ts +105 -0
  459. package/src/modules/panels/state/splitLimits.spec.ts +46 -0
  460. package/src/modules/panels/state/splitLimits.ts +90 -0
  461. package/src/modules/panels/state/state.spec.ts +49 -0
  462. package/src/modules/panels/state/tree/Context.tsx +24 -0
  463. package/src/modules/panels/state/tree/logic.spec.ts +34 -0
  464. package/src/modules/panels/state/tree/logic.ts +138 -0
  465. package/src/modules/panels/state/types.ts +142 -0
  466. package/src/modules/panels/system/PanelSystem.empty-tabbar.spec.tsx +53 -0
  467. package/src/modules/panels/system/PanelSystem.tab-click-activates.spec.tsx +44 -0
  468. package/src/modules/panels/system/PanelSystem.tab-reorder.spec.tsx +64 -0
  469. package/src/modules/panels/system/PanelSystem.tabs-no-dup.spec.tsx +57 -0
  470. package/src/modules/panels/system/PanelSystem.tsx +206 -0
  471. package/src/modules/pivot/PivotContent.spec.tsx +179 -0
  472. package/src/modules/pivot/PivotContent.tsx +77 -0
  473. package/src/modules/pivot/SwipePivotContent.debug.tmp.tsx +237 -0
  474. package/src/modules/pivot/SwipePivotContent.position.spec.tsx +171 -0
  475. package/src/modules/pivot/SwipePivotContent.spec.tsx +494 -0
  476. package/src/modules/pivot/SwipePivotContent.test.tsx +502 -0
  477. package/src/modules/pivot/SwipePivotContent.tsx +197 -0
  478. package/src/modules/pivot/SwipePivotTabBar.spec.tsx +882 -0
  479. package/src/modules/pivot/SwipePivotTabBar.tsx +583 -0
  480. package/src/modules/pivot/index.ts +8 -0
  481. package/src/modules/pivot/scaleInputState.spec.ts +219 -0
  482. package/src/modules/pivot/scaleInputState.ts +66 -0
  483. package/src/modules/pivot/types.ts +139 -0
  484. package/src/modules/pivot/usePivot.spec.ts +635 -0
  485. package/src/modules/pivot/usePivot.spec.tsx +186 -0
  486. package/src/modules/pivot/usePivot.tsx +345 -0
  487. package/src/modules/pivot/usePivotSwipeInput.spec.ts +708 -0
  488. package/src/modules/pivot/usePivotSwipeInput.ts +136 -0
  489. package/src/modules/resizer/useResizeDrag.ts +94 -0
  490. package/src/modules/stack/StackContent.spec.tsx +264 -0
  491. package/src/modules/stack/StackContent.tsx +111 -0
  492. package/src/modules/stack/SwipeStackContent.spec.tsx +1564 -0
  493. package/src/modules/stack/SwipeStackContent.tsx +366 -0
  494. package/src/modules/stack/SwipeStackOutlet.spec.tsx +250 -0
  495. package/src/modules/stack/SwipeStackOutlet.tsx +221 -0
  496. package/src/modules/stack/computeStackContentState.spec.ts +281 -0
  497. package/src/modules/stack/computeStackContentState.ts +304 -0
  498. package/src/modules/stack/computeSwipeStackTransform.spec.ts +186 -0
  499. package/src/modules/stack/computeSwipeStackTransform.ts +145 -0
  500. package/src/modules/stack/swipeTransitionContinuity.spec.tsx +1133 -0
  501. package/src/modules/stack/types.ts +226 -0
  502. package/src/modules/stack/useStackAnimationState.spec.ts +188 -0
  503. package/src/modules/stack/useStackAnimationState.ts +143 -0
  504. package/src/modules/stack/useStackNavigation.spec.ts +672 -0
  505. package/src/modules/stack/useStackNavigation.tsx +393 -0
  506. package/src/modules/stack/useStackSwipeInput.spec.ts +309 -0
  507. package/src/modules/stack/useStackSwipeInput.ts +139 -0
  508. package/src/modules/window/useDrawerState.ts +81 -0
  509. package/src/modules/window/useFloatingState.spec.ts +252 -0
  510. package/src/modules/window/useFloatingState.ts +141 -0
  511. package/src/panels/index.ts +119 -0
  512. package/src/pivot/index.ts +19 -0
  513. package/src/resizer/index.ts +68 -0
  514. package/src/stack/index.ts +91 -0
  515. package/src/sticky-header/StickyArea.tsx +193 -0
  516. package/src/sticky-header/calculateStickyMetrics.spec.ts +105 -0
  517. package/src/sticky-header/calculateStickyMetrics.ts +50 -0
  518. package/src/sticky-header/index.ts +18 -0
  519. package/src/sticky-header/types.ts +68 -0
  520. package/src/types.ts +341 -0
  521. package/src/utils/CSSMatrix.ts +321 -0
  522. package/src/utils/css.ts +65 -0
  523. package/src/utils/dialogUtils.ts +43 -0
  524. package/src/utils/math.ts +18 -0
  525. package/src/utils/polyfills/createDialogPolyfill.ts +18 -0
  526. package/src/utils/typedActions.ts +103 -0
  527. package/src/vite-env.d.ts +6 -0
  528. package/src/window/index.ts +69 -0
  529. package/dist/GridLayout-BQQ63eA1.cjs +0 -2
  530. package/dist/GridLayout-BQQ63eA1.cjs.map +0 -1
  531. package/dist/GridLayout-CJTKq7Mp.js +0 -1465
  532. package/dist/GridLayout-CJTKq7Mp.js.map +0 -1
  533. package/dist/sticky-header/StickyHeader.d.ts +0 -53
  534. package/dist/styles-CA2_zLZt.js +0 -52
  535. package/dist/styles-CA2_zLZt.js.map +0 -1
  536. package/dist/styles-PsqGOEJP.cjs +0 -2
  537. package/dist/styles-PsqGOEJP.cjs.map +0 -1
  538. package/dist/usePivot-7ctin_P_.cjs +0 -2
  539. package/dist/usePivot-7ctin_P_.cjs.map +0 -1
  540. package/dist/usePivot-CgQxB8rc.js +0 -124
  541. package/dist/usePivot-CgQxB8rc.js.map +0 -1
@@ -0,0 +1,399 @@
1
+ /**
2
+ * @file Hook for detecting swipe gestures to open/close a drawer.
3
+ *
4
+ * Combines:
5
+ * - Edge swipe detection for opening (Stack pattern)
6
+ * - Drag-to-close within drawer (Dialog pattern)
7
+ * - Native gesture guard for browser back prevention
8
+ */
9
+ import * as React from "react";
10
+ import { useEdgeSwipeInput } from "../../hooks/gesture/useEdgeSwipeInput.js";
11
+ import { useNativeGestureGuard } from "../../hooks/gesture/useNativeGestureGuard.js";
12
+ import { usePointerTracking } from "../../hooks/gesture/usePointerTracking.js";
13
+ import {
14
+ mergeGestureContainerProps,
15
+ isScrollableInDirection,
16
+ } from "../../hooks/gesture/utils.js";
17
+ import { isInSwipeSafeZone } from "../../components/gesture/SwipeSafeZone.js";
18
+ import {
19
+ type ContinuousOperationState,
20
+ IDLE_CONTINUOUS_OPERATION_STATE,
21
+ } from "../../hooks/gesture/types.js";
22
+ import type { UseDrawerSwipeInputOptions, UseDrawerSwipeInputResult } from "./types.js";
23
+ import { getDrawerAnimationAxis, getDrawerCloseSwipeSign, getDrawerOpenSwipeSign } from "./types.js";
24
+
25
+ /**
26
+ * Default dismiss threshold (30% of container size).
27
+ */
28
+ const DEFAULT_DISMISS_THRESHOLD = 0.3;
29
+
30
+ /**
31
+ * Velocity threshold for quick flick dismissal (px/ms).
32
+ */
33
+ const VELOCITY_THRESHOLD = 0.5;
34
+
35
+ // ============================================================================
36
+ // Helper functions (extracted to avoid ternary violations)
37
+ // ============================================================================
38
+
39
+ function getContainerSize(container: HTMLElement, axis: "x" | "y"): number {
40
+ if (axis === "x") {
41
+ return container.clientWidth;
42
+ }
43
+ return container.clientHeight;
44
+ }
45
+
46
+ function getAxisDelta(
47
+ start: { x: number; y: number },
48
+ current: { x: number; y: number },
49
+ axis: "x" | "y",
50
+ ): number {
51
+ if (axis === "x") {
52
+ return current.x - start.x;
53
+ }
54
+ return current.y - start.y;
55
+ }
56
+
57
+ const PHASE_MAP: Record<string, "idle" | "operating" | "ended"> = {
58
+ idle: "idle",
59
+ ended: "ended",
60
+ };
61
+
62
+ function normalizePhase(phase: string): "idle" | "operating" | "ended" {
63
+ return PHASE_MAP[phase] ?? "operating";
64
+ }
65
+
66
+ function computeDisplacementValue(
67
+ closeSwipeSign: 1 | -1,
68
+ axis: "x" | "y",
69
+ closeDisplacement: number,
70
+ ): { x: number; y: number } {
71
+ const signedDisplacement = closeSwipeSign * closeDisplacement;
72
+ if (axis === "x") {
73
+ return { x: signedDisplacement, y: 0 };
74
+ }
75
+ return { x: 0, y: signedDisplacement };
76
+ }
77
+
78
+ function computeAxisDisplacement(
79
+ displacement: { x: number; y: number },
80
+ axis: "x" | "y",
81
+ ): number {
82
+ if (axis === "x") {
83
+ return Math.abs(displacement.x);
84
+ }
85
+ return Math.abs(displacement.y);
86
+ }
87
+
88
+ function isEdgeSwipeEnabled(enableEdgeSwipeOpen: boolean, isOpen: boolean): boolean {
89
+ if (!enableEdgeSwipeOpen) {
90
+ return false;
91
+ }
92
+ return !isOpen;
93
+ }
94
+
95
+ function isCloseSwipeEnabled(enableSwipeClose: boolean, isOpen: boolean): boolean {
96
+ if (!enableSwipeClose) {
97
+ return false;
98
+ }
99
+ return isOpen;
100
+ }
101
+
102
+ function isDrawerOpening(isEdgeGesture: boolean, isOpen: boolean): boolean {
103
+ if (!isEdgeGesture) {
104
+ return false;
105
+ }
106
+ return !isOpen;
107
+ }
108
+
109
+ function isDrawerClosing(closePhase: "idle" | "operating" | "ended", isOpen: boolean): boolean {
110
+ if (closePhase === "idle") {
111
+ return false;
112
+ }
113
+ return isOpen;
114
+ }
115
+
116
+ function computeVelocity(
117
+ start: { x: number; y: number; timestamp: number } | null,
118
+ current: { x: number; y: number; timestamp: number } | null,
119
+ displacement: number,
120
+ ): number {
121
+ if (!start || !current) {
122
+ return 0;
123
+ }
124
+ const timeDelta = Math.max(1, current.timestamp - start.timestamp);
125
+ return displacement / timeDelta;
126
+ }
127
+
128
+ /**
129
+ * Hook for detecting swipe gestures to open/close a drawer.
130
+ *
131
+ * When drawer is closed:
132
+ * - Detects edge swipe from the anchor edge to trigger open
133
+ *
134
+ * When drawer is open:
135
+ * - Detects drag gesture within drawer to trigger close
136
+ * - Respects scrollable content boundaries
137
+ *
138
+ * @example
139
+ * ```tsx
140
+ * const { state, edgeContainerProps, drawerContentProps } = useDrawerSwipeInput({
141
+ * edgeContainerRef: gridLayoutRef,
142
+ * drawerContentRef: drawerRef,
143
+ * direction: "left",
144
+ * isOpen,
145
+ * onSwipeOpen: () => setOpen(true),
146
+ * onSwipeClose: () => setOpen(false),
147
+ * });
148
+ * ```
149
+ */
150
+ export function useDrawerSwipeInput(
151
+ options: UseDrawerSwipeInputOptions,
152
+ ): UseDrawerSwipeInputResult {
153
+ const {
154
+ edgeContainerRef,
155
+ drawerContentRef,
156
+ direction,
157
+ isOpen,
158
+ onSwipeOpen,
159
+ onSwipeClose,
160
+ enableEdgeSwipeOpen = true,
161
+ enableSwipeClose = true,
162
+ edgeWidth = 20,
163
+ dismissThreshold = DEFAULT_DISMISS_THRESHOLD,
164
+ } = options;
165
+
166
+ const axis = getDrawerAnimationAxis(direction);
167
+ const closeSwipeSign = getDrawerCloseSwipeSign(direction);
168
+ const openSwipeSign = getDrawerOpenSwipeSign(direction);
169
+
170
+ // Track container size for progress calculation
171
+ const containerSizeRef = React.useRef(0);
172
+
173
+ // Measure drawer content size
174
+ React.useLayoutEffect(() => {
175
+ const container = drawerContentRef.current;
176
+ if (!container) {
177
+ return;
178
+ }
179
+
180
+ const updateSize = () => {
181
+ containerSizeRef.current = getContainerSize(container, axis);
182
+ };
183
+
184
+ updateSize();
185
+
186
+ const observer = new ResizeObserver(updateSize);
187
+ observer.observe(container);
188
+
189
+ return () => observer.disconnect();
190
+ }, [drawerContentRef, axis]);
191
+
192
+ // =========== Edge swipe to OPEN ===========
193
+ const handleOpenSwipeEnd = React.useCallback(
194
+ (state: { direction: 1 | -1 | 0 }) => {
195
+ // Open when swiping in the correct direction (away from edge)
196
+ if (state.direction === openSwipeSign) {
197
+ onSwipeOpen();
198
+ }
199
+ },
200
+ [openSwipeSign, onSwipeOpen],
201
+ );
202
+
203
+ const {
204
+ isEdgeGesture,
205
+ state: edgeSwipeState,
206
+ containerProps: edgeSwipeProps,
207
+ } = useEdgeSwipeInput({
208
+ containerRef: edgeContainerRef,
209
+ edge: direction,
210
+ edgeWidth,
211
+ enabled: isEdgeSwipeEnabled(enableEdgeSwipeOpen, isOpen),
212
+ onSwipeEnd: handleOpenSwipeEnd,
213
+ });
214
+
215
+ // Native gesture guard for edge swipe
216
+ const { containerProps: guardProps } = useNativeGestureGuard({
217
+ containerRef: edgeContainerRef,
218
+ active: isEdgeGesture,
219
+ preventEdgeBack: true,
220
+ preventOverscroll: true,
221
+ edgeWidth,
222
+ });
223
+
224
+ // =========== Drag to CLOSE (Dialog pattern) ===========
225
+ const { state: closeTracking, onPointerDown: baseClosePointerDown } = usePointerTracking({
226
+ enabled: isCloseSwipeEnabled(enableSwipeClose, isOpen),
227
+ });
228
+
229
+ const [closePhase, setClosePhase] = React.useState<"idle" | "operating" | "ended">("idle");
230
+ const lastCloseDisplacementRef = React.useRef(0);
231
+
232
+ // Wrap pointer down with scroll check and safe zone check
233
+ const onClosePointerDown = React.useCallback(
234
+ (event: React.PointerEvent) => {
235
+ if (!enableSwipeClose || !isOpen) {
236
+ return;
237
+ }
238
+
239
+ const container = drawerContentRef.current;
240
+ if (!container) {
241
+ return;
242
+ }
243
+
244
+ const target = event.target as HTMLElement;
245
+
246
+ // Check if target is in a SwipeSafeZone
247
+ if (isInSwipeSafeZone(target, container)) {
248
+ return; // Don't start close swipe if inside safe zone
249
+ }
250
+
251
+ // Check if target is in a scrollable area that would block swipe
252
+ if (isScrollableInDirection(target, container, axis, closeSwipeSign)) {
253
+ return; // Don't start close swipe if inside scrollable content
254
+ }
255
+
256
+ baseClosePointerDown(event);
257
+ },
258
+ [enableSwipeClose, isOpen, drawerContentRef, axis, closeSwipeSign, baseClosePointerDown],
259
+ );
260
+
261
+ // Calculate close displacement
262
+ const closeDisplacement = React.useMemo(() => {
263
+ if (!closeTracking.isDown || !closeTracking.start || !closeTracking.current) {
264
+ return lastCloseDisplacementRef.current;
265
+ }
266
+
267
+ const delta = getAxisDelta(closeTracking.start, closeTracking.current, axis);
268
+
269
+ // Only count movement in close direction
270
+ const signedDelta = delta * closeSwipeSign;
271
+ return Math.max(0, signedDelta);
272
+ }, [closeTracking.isDown, closeTracking.start, closeTracking.current, axis, closeSwipeSign]);
273
+
274
+ // Track displacement while dragging
275
+ React.useEffect(() => {
276
+ if (closeTracking.isDown && closeTracking.current) {
277
+ lastCloseDisplacementRef.current = closeDisplacement;
278
+ }
279
+ }, [closeTracking.isDown, closeTracking.current, closeDisplacement]);
280
+
281
+ // Handle close drag start
282
+ React.useEffect(() => {
283
+ if (closeTracking.isDown && closePhase === "idle") {
284
+ setClosePhase("operating");
285
+ }
286
+ }, [closeTracking.isDown, closePhase]);
287
+
288
+ // Handle close drag end
289
+ React.useEffect(() => {
290
+ if (!closeTracking.isDown && closePhase === "operating") {
291
+ const displacement = lastCloseDisplacementRef.current;
292
+ const hasMovement = displacement > 1;
293
+
294
+ if (hasMovement) {
295
+ setClosePhase("ended");
296
+
297
+ // Check if should close
298
+ const containerSize = containerSizeRef.current;
299
+ if (containerSize > 0) {
300
+ const ratio = displacement / containerSize;
301
+ const velocity = computeVelocity(closeTracking.start, closeTracking.current, displacement);
302
+
303
+ if (ratio >= dismissThreshold || velocity >= VELOCITY_THRESHOLD) {
304
+ onSwipeClose();
305
+ }
306
+ }
307
+ } else {
308
+ setClosePhase("idle");
309
+ lastCloseDisplacementRef.current = 0;
310
+ }
311
+ }
312
+ }, [closeTracking.isDown, closePhase, dismissThreshold, onSwipeClose, closeTracking.start, closeTracking.current]);
313
+
314
+ // Transition from ended to idle
315
+ React.useEffect(() => {
316
+ if (closePhase === "ended") {
317
+ queueMicrotask(() => {
318
+ setClosePhase("idle");
319
+ lastCloseDisplacementRef.current = 0;
320
+ });
321
+ }
322
+ }, [closePhase]);
323
+
324
+ // Reset close state when drawer closes
325
+ React.useEffect(() => {
326
+ if (!isOpen) {
327
+ setClosePhase("idle");
328
+ lastCloseDisplacementRef.current = 0;
329
+ }
330
+ }, [isOpen]);
331
+
332
+ // =========== Combined state ===========
333
+ const isOpening = isDrawerOpening(isEdgeGesture, isOpen);
334
+ const isClosing = isDrawerClosing(closePhase, isOpen);
335
+
336
+ // Determine primary displacement based on current operation
337
+ const displacement = React.useMemo(() => {
338
+ if (isOpening) {
339
+ return computeAxisDisplacement(edgeSwipeState.displacement, axis);
340
+ }
341
+ if (isClosing) {
342
+ return closeDisplacement;
343
+ }
344
+ return 0;
345
+ }, [isOpening, isClosing, axis, edgeSwipeState.displacement, closeDisplacement]);
346
+
347
+ // Progress calculation
348
+ const progress = React.useMemo(() => {
349
+ const containerSize = containerSizeRef.current;
350
+ if (containerSize <= 0) {
351
+ return 0;
352
+ }
353
+ return Math.min(displacement / containerSize, 1);
354
+ }, [displacement]);
355
+
356
+ // Combined operation state
357
+ const state = React.useMemo<ContinuousOperationState>(() => {
358
+ if (isOpening) {
359
+ return {
360
+ phase: normalizePhase(edgeSwipeState.phase),
361
+ displacement: edgeSwipeState.displacement,
362
+ velocity: edgeSwipeState.velocity,
363
+ };
364
+ }
365
+ if (isClosing) {
366
+ return {
367
+ phase: closePhase,
368
+ displacement: computeDisplacementValue(closeSwipeSign, axis, closeDisplacement),
369
+ velocity: { x: 0, y: 0 },
370
+ };
371
+ }
372
+ return IDLE_CONTINUOUS_OPERATION_STATE;
373
+ }, [isOpening, isClosing, edgeSwipeState, closePhase, closeDisplacement, axis, closeSwipeSign]);
374
+
375
+ // Container props
376
+ const edgeContainerProps = React.useMemo(
377
+ () => mergeGestureContainerProps(edgeSwipeProps, guardProps),
378
+ [edgeSwipeProps, guardProps],
379
+ );
380
+
381
+ const drawerContentProps = React.useMemo(() => ({
382
+ onPointerDown: onClosePointerDown,
383
+ style: {
384
+ touchAction: "none" as const,
385
+ userSelect: "none" as const,
386
+ WebkitUserSelect: "none" as const,
387
+ },
388
+ }), [onClosePointerDown]);
389
+
390
+ return {
391
+ state,
392
+ isOpening,
393
+ isClosing,
394
+ progress,
395
+ displacement,
396
+ edgeContainerProps,
397
+ drawerContentProps,
398
+ };
399
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @file Context provider for grid layer rendering helpers.
3
+ */
4
+ import * as React from "react";
5
+ import type { LayerDefinition } from "../../types";
6
+
7
+ export type GridLayerHandleProps = React.HTMLAttributes<HTMLElement> & {
8
+ "data-drag-handle": "true";
9
+ };
10
+
11
+ export type ResizeHandleConfig =
12
+ | {
13
+ key: "top-left" | "top-right" | "bottom-left" | "bottom-right";
14
+ variant: "corner";
15
+ horizontal: "left" | "right";
16
+ vertical: "top" | "bottom";
17
+ }
18
+ | {
19
+ key: "left" | "right" | "top" | "bottom";
20
+ variant: "edge";
21
+ horizontal?: "left" | "right";
22
+ vertical?: "top" | "bottom";
23
+ };
24
+
25
+ export type GridLayerRenderState = {
26
+ style: React.CSSProperties;
27
+ isResizable: boolean;
28
+ isResizing: boolean;
29
+ onResizeHandlePointerDown: (config: ResizeHandleConfig, event: React.PointerEvent<HTMLDivElement>) => void;
30
+ };
31
+
32
+ export type GridLayoutContextValue = {
33
+ handleLayerPointerDown: (event: React.PointerEvent<HTMLDivElement>) => void;
34
+ getLayerRenderState: (layer: LayerDefinition) => GridLayerRenderState;
35
+ getLayerHandleProps: (layerId: string) => GridLayerHandleProps;
36
+ /**
37
+ * Whether the GridLayout is mounted at root level.
38
+ * When true, scrollable layers should delegate to browser's native scroll.
39
+ */
40
+ isRootLevel: boolean;
41
+ };
42
+
43
+ const GridLayoutContext = React.createContext<GridLayoutContextValue | null>(null);
44
+
45
+ export const GridLayoutProvider: React.FC<
46
+ React.PropsWithChildren<{ value: GridLayoutContextValue }>
47
+ > = ({ value, children }) => {
48
+ return <GridLayoutContext.Provider value={value}>{children}</GridLayoutContext.Provider>;
49
+ };
50
+
51
+ export const useGridLayoutContext = (): GridLayoutContextValue => {
52
+ const context = React.useContext(GridLayoutContext);
53
+ if (!context) {
54
+ throw new Error("useGridLayoutContext must be used within a GridLayoutProvider.");
55
+ }
56
+ return context;
57
+ };
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @file Context exposing the current grid layer id and helpers to child components.
3
+ */
4
+ import * as React from "react";
5
+ import type { LayerDefinition } from "../../types";
6
+ import { usePanelSystem } from "../../PanelSystemContext";
7
+ import { useGridLayoutContext, type GridLayerHandleProps } from "./GridLayoutContext";
8
+
9
+ type LayerInstanceContextValue = {
10
+ layerId: string;
11
+ };
12
+
13
+ const LayerInstanceContext = React.createContext<LayerInstanceContextValue | null>(null);
14
+
15
+ export type LayerInstanceProviderProps = React.PropsWithChildren<LayerInstanceContextValue>;
16
+
17
+ export const LayerInstanceProvider: React.FC<LayerInstanceProviderProps> = ({ layerId, children }) => {
18
+ const value = React.useMemo(() => ({ layerId }), [layerId]);
19
+ return <LayerInstanceContext.Provider value={value}>{children}</LayerInstanceContext.Provider>;
20
+ };
21
+
22
+ export const useLayerInstance = (): LayerInstanceContextValue => {
23
+ const value = React.useContext(LayerInstanceContext);
24
+ if (!value) {
25
+ throw new Error("useLayerInstance must be used within a LayerInstanceProvider.");
26
+ }
27
+ return value;
28
+ };
29
+
30
+ /**
31
+ * Convenience: read the current layer definition from the core registry.
32
+ */
33
+ export const useCurrentLayerDefinition = (): LayerDefinition => {
34
+ const { layerId } = useLayerInstance();
35
+ const { layers } = usePanelSystem();
36
+ const def = layers.layerById.get(layerId);
37
+ if (!def) {
38
+ throw new Error(`Layer definition not found for id: ${layerId}`);
39
+ }
40
+ return def;
41
+ };
42
+
43
+ /**
44
+ * Convenience: get drag handle props, pre-bound to the current layer.
45
+ */
46
+ export const useCurrentLayerHandleProps = (): GridLayerHandleProps => {
47
+ const { layerId } = useLayerInstance();
48
+ const { getLayerHandleProps } = useGridLayoutContext();
49
+ return React.useMemo(() => getLayerHandleProps(layerId), [getLayerHandleProps, layerId]);
50
+ };
51
+
52
+ /**
53
+ * Compatibility helper for existing code using useLayerDragHandle.
54
+ * Prefer useCurrentLayerHandleProps for direct access.
55
+ */
56
+ export const useLayerDragHandleProps = useCurrentLayerHandleProps;
@@ -0,0 +1,157 @@
1
+ /**
2
+ * @file Resize handle configuration computation for grid tracks.
3
+ */
4
+ import type { GridTrack } from "../../types";
5
+
6
+ export type TrackHandleConfig = {
7
+ trackIndex: number;
8
+ align: "start" | "end";
9
+ span: { start: number; end: number };
10
+ };
11
+
12
+ /**
13
+ * Computes the valid row span for a column boundary.
14
+ * Returns the contiguous range of rows where the adjacent areas differ.
15
+ */
16
+ const computeColumnBoundarySpan = (
17
+ areas: string[][],
18
+ boundaryIndex: number,
19
+ ): { start: number; end: number } => {
20
+ const rowCount = areas.length;
21
+
22
+ // Find rows where left and right areas differ at this boundary
23
+ const validRows: number[] = [];
24
+ for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
25
+ const row = areas[rowIndex];
26
+ const leftArea = row[boundaryIndex];
27
+ const rightArea = row[boundaryIndex + 1];
28
+ if (leftArea !== rightArea) {
29
+ validRows.push(rowIndex);
30
+ }
31
+ }
32
+
33
+ if (validRows.length === 0) {
34
+ // Fallback: full span if no valid rows found (shouldn't happen for resizable columns)
35
+ return { start: 1, end: rowCount + 1 };
36
+ }
37
+
38
+ // Convert to 1-indexed grid lines
39
+ const minRow = Math.min(...validRows);
40
+ const maxRow = Math.max(...validRows);
41
+ return { start: minRow + 1, end: maxRow + 2 };
42
+ };
43
+
44
+ /**
45
+ * Computes the valid column span for a row boundary.
46
+ * Returns the contiguous range of columns where the adjacent areas differ.
47
+ */
48
+ const computeRowBoundarySpan = (
49
+ areas: string[][],
50
+ boundaryIndex: number,
51
+ ): { start: number; end: number } => {
52
+ const topRow = areas[boundaryIndex];
53
+ const bottomRow = areas[boundaryIndex + 1];
54
+ const colCount = topRow?.length ?? 0;
55
+
56
+ // Find columns where top and bottom areas differ at this boundary
57
+ const validCols: number[] = [];
58
+ for (let colIndex = 0; colIndex < colCount; colIndex++) {
59
+ const topArea = topRow?.[colIndex];
60
+ const bottomArea = bottomRow?.[colIndex];
61
+ if (topArea !== bottomArea) {
62
+ validCols.push(colIndex);
63
+ }
64
+ }
65
+
66
+ if (validCols.length === 0) {
67
+ // Fallback: full span if no valid columns found
68
+ return { start: 1, end: colCount + 1 };
69
+ }
70
+
71
+ // Convert to 1-indexed grid lines
72
+ const minCol = Math.min(...validCols);
73
+ const maxCol = Math.max(...validCols);
74
+ return { start: minCol + 1, end: maxCol + 2 };
75
+ };
76
+
77
+ export const computeColumnResizeHandles = (
78
+ tracks: GridTrack[],
79
+ areas: string[][],
80
+ ): TrackHandleConfig[] => {
81
+ if (tracks.length === 0) {
82
+ return [];
83
+ }
84
+
85
+ const rowCount = areas.length;
86
+
87
+ if (tracks.length === 1) {
88
+ const onlyTrack = tracks[0];
89
+ if (onlyTrack?.resizable) {
90
+ const fullSpan = { start: 1, end: rowCount + 1 };
91
+ return [{ trackIndex: 0, align: "end", span: fullSpan }];
92
+ }
93
+ return [];
94
+ }
95
+
96
+ const handles: TrackHandleConfig[] = [];
97
+
98
+ const boundaryIndexes = Array.from({ length: tracks.length - 1 }, (_, index) => index);
99
+ boundaryIndexes.forEach((boundaryIndex) => {
100
+ const leftTrack = tracks[boundaryIndex];
101
+ const rightTrack = tracks[boundaryIndex + 1];
102
+
103
+ if (rightTrack?.resizable) {
104
+ const span = computeColumnBoundarySpan(areas, boundaryIndex);
105
+ handles.push({ trackIndex: boundaryIndex + 1, align: "start", span });
106
+ return;
107
+ }
108
+
109
+ if (leftTrack?.resizable) {
110
+ const span = computeColumnBoundarySpan(areas, boundaryIndex);
111
+ handles.push({ trackIndex: boundaryIndex, align: "end", span });
112
+ }
113
+ });
114
+
115
+ return handles;
116
+ };
117
+
118
+ export const computeRowResizeHandles = (
119
+ tracks: GridTrack[],
120
+ areas: string[][],
121
+ ): TrackHandleConfig[] => {
122
+ if (tracks.length === 0) {
123
+ return [];
124
+ }
125
+
126
+ const colCount = areas[0]?.length ?? 0;
127
+
128
+ if (tracks.length === 1) {
129
+ const onlyTrack = tracks[0];
130
+ if (onlyTrack?.resizable) {
131
+ const fullSpan = { start: 1, end: colCount + 1 };
132
+ return [{ trackIndex: 0, align: "end", span: fullSpan }];
133
+ }
134
+ return [];
135
+ }
136
+
137
+ const handles: TrackHandleConfig[] = [];
138
+
139
+ const boundaryIndexes = Array.from({ length: tracks.length - 1 }, (_, index) => index);
140
+ boundaryIndexes.forEach((boundaryIndex) => {
141
+ const topTrack = tracks[boundaryIndex];
142
+ const bottomTrack = tracks[boundaryIndex + 1];
143
+
144
+ if (bottomTrack?.resizable) {
145
+ const span = computeRowBoundarySpan(areas, boundaryIndex);
146
+ handles.push({ trackIndex: boundaryIndex + 1, align: "start", span });
147
+ return;
148
+ }
149
+
150
+ if (topTrack?.resizable) {
151
+ const span = computeRowBoundarySpan(areas, boundaryIndex);
152
+ handles.push({ trackIndex: boundaryIndex, align: "end", span });
153
+ }
154
+ });
155
+
156
+ return handles;
157
+ };