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,119 @@
1
+ /**
2
+ * @file Panels entry point - VSCode-like panel system
3
+ * @packageDocumentation
4
+ *
5
+ * This is a subpath export entry point for `react-panel-layout/panels`.
6
+ *
7
+ * ## Overview
8
+ * Panels provides a VSCode-like panel system with tabbed groups, drag-and-drop
9
+ * tab reordering, split views, and keyboard navigation. Supports both controlled
10
+ * and uncontrolled state management.
11
+ *
12
+ * ## Installation
13
+ * ```ts
14
+ * import { PanelSystem, buildInitialState, usePanelSystem } from "react-panel-layout/panels";
15
+ * ```
16
+ *
17
+ * ## Basic Usage
18
+ * ```tsx
19
+ * const tabs = [
20
+ * { id: 'file1', title: 'index.ts', render: () => <Editor file="index.ts" /> },
21
+ * { id: 'file2', title: 'app.tsx', render: () => <Editor file="app.tsx" /> },
22
+ * ];
23
+ *
24
+ * function App() {
25
+ * const initialState = buildInitialState(tabs);
26
+ * let groupCounter = 1;
27
+ *
28
+ * return (
29
+ * <PanelSystem
30
+ * initialState={initialState}
31
+ * createGroupId={() => `g_${++groupCounter}`}
32
+ * layoutMode="grid"
33
+ * gridTracksInteractive={true}
34
+ * dragThresholdPx={5}
35
+ * />
36
+ * );
37
+ * }
38
+ * ```
39
+ *
40
+ * ## Controlled State
41
+ * ```tsx
42
+ * const [state, setState] = useState(() => buildInitialState(tabs));
43
+ *
44
+ * <PanelSystem
45
+ * initialState={state}
46
+ * state={state}
47
+ * onStateChange={setState}
48
+ * // ...
49
+ * />
50
+ * ```
51
+ *
52
+ * ## Using Context
53
+ * ```tsx
54
+ * function TabActions() {
55
+ * const { actions } = usePanelSystem();
56
+ * return <button onClick={() => actions.splitFocused('vertical')}>Split</button>;
57
+ * }
58
+ * ```
59
+ */
60
+
61
+ // Components
62
+ export { PanelSystem } from "../modules/panels/system/PanelSystem.js";
63
+ export { PanelGroupView } from "../components/panels/PanelGroupView.js";
64
+ export { DropSuggestOverlay } from "../components/panels/DropSuggestOverlay.js";
65
+
66
+ // Context
67
+ export {
68
+ PanelSystemProvider,
69
+ usePanelSystem,
70
+ } from "../modules/panels/state/PanelSystemContext.js";
71
+
72
+ // State operations
73
+ export {
74
+ collectGroupsInOrder,
75
+ splitLeaf,
76
+ closeLeaf,
77
+ isGroup,
78
+ setSplitRatio,
79
+ createEmptyGroup,
80
+ addTabToGroup,
81
+ removeTabFromGroup,
82
+ moveTab,
83
+ setActiveTab,
84
+ reorderTabWithinGroup,
85
+ addTabToGroupAtIndex,
86
+ setFocusedGroup,
87
+ focusGroupIndex,
88
+ nextGroup,
89
+ prevGroup,
90
+ refreshGroupOrder,
91
+ splitGroup,
92
+ buildInitialState,
93
+ } from "../modules/panels/index.js";
94
+
95
+ // Types
96
+ export type {
97
+ PanelId,
98
+ GroupId,
99
+ SplitDirection,
100
+ TabDefinition,
101
+ GroupModel,
102
+ PanelTree,
103
+ PanelSystemState,
104
+ DropZone,
105
+ DraggingTab,
106
+ PanelCommands,
107
+ PanelSystemProps,
108
+ PanelSplitLimits,
109
+ IdFactory,
110
+ } from "../modules/panels/index.js";
111
+
112
+ export type {
113
+ PanelSystemContextValue,
114
+ PanelSystemProviderProps,
115
+ PanelStateAction,
116
+ PanelStateActions,
117
+ } from "../modules/panels/state/PanelSystemContext.js";
118
+
119
+ export type { PanelGroupViewProps } from "../components/panels/PanelGroupView.js";
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @file Pivot entry point - Headless content switching
3
+ *
4
+ * Import via: import { usePivot } from "react-panel-layout/pivot";
5
+ */
6
+
7
+ // Hook
8
+ export { usePivot } from "../modules/pivot";
9
+
10
+ // Components
11
+ export { SwipePivotTabBar } from "../modules/pivot";
12
+
13
+ // Utilities
14
+ export { scaleInputState } from "../modules/pivot";
15
+
16
+ // Types
17
+ export type { PivotItem, UsePivotOptions, UsePivotResult, PivotItemProps } from "../modules/pivot";
18
+ export type { SwipePivotTabBarProps, IndicatorRenderProps } from "../modules/pivot";
19
+ export type { PivotBehavior, PivotBehaviorItem } from "../types";
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @file Resizer entry point - Resize handle components and hooks
3
+ * @packageDocumentation
4
+ *
5
+ * This is a subpath export entry point for `react-panel-layout/resizer`.
6
+ *
7
+ * ## Overview
8
+ * Resizer provides draggable resize handles for creating resizable layouts.
9
+ * Includes both ready-to-use components and a low-level hook for custom implementations.
10
+ *
11
+ * ## Installation
12
+ * ```ts
13
+ * import { ResizeHandle, useResizeDrag } from "react-panel-layout/resizer";
14
+ * ```
15
+ *
16
+ * ## Basic Usage with ResizeHandle
17
+ * ```tsx
18
+ * function ResizableLayout() {
19
+ * const [width, setWidth] = useState(300);
20
+ *
21
+ * return (
22
+ * <div style={{ display: 'flex' }}>
23
+ * <div style={{ width }}>Left Panel</div>
24
+ * <ResizeHandle
25
+ * direction="vertical"
26
+ * onResize={(delta) => setWidth((w) => w + delta)}
27
+ * />
28
+ * <div style={{ flex: 1 }}>Right Panel</div>
29
+ * </div>
30
+ * );
31
+ * }
32
+ * ```
33
+ *
34
+ * ## Custom Handle with useResizeDrag
35
+ * ```tsx
36
+ * function CustomHandle({ onResize }) {
37
+ * const { ref, isDragging, onPointerDown } = useResizeDrag({
38
+ * axis: 'x',
39
+ * onResize,
40
+ * });
41
+ *
42
+ * return (
43
+ * <div
44
+ * ref={ref}
45
+ * onPointerDown={onPointerDown}
46
+ * style={{ cursor: 'col-resize', background: isDragging ? 'blue' : 'gray' }}
47
+ * />
48
+ * );
49
+ * }
50
+ * ```
51
+ */
52
+
53
+ // Hooks
54
+ export { useResizeDrag } from "../modules/resizer/useResizeDrag.js";
55
+
56
+ // Components
57
+ export { ResizeHandle } from "../components/resizer/ResizeHandle.js";
58
+ export { HorizontalDivider } from "../components/resizer/HorizontalDivider.js";
59
+
60
+ // Types
61
+ export type {
62
+ ResizeDragAxis,
63
+ UseResizeDragOptions,
64
+ UseResizeDragResult,
65
+ } from "../modules/resizer/useResizeDrag.js";
66
+
67
+ export type { ResizeHandleProps } from "../components/resizer/ResizeHandle.js";
68
+ export type { HorizontalDividerProps } from "../components/resizer/HorizontalDivider.js";
@@ -0,0 +1,91 @@
1
+ /**
2
+ * @file Stack entry point - Hierarchical navigation with swipe support
3
+ * @packageDocumentation
4
+ *
5
+ * This is a subpath export entry point for `react-panel-layout/stack`.
6
+ *
7
+ * ## Overview
8
+ * Stack provides iOS/iPadOS-style hierarchical navigation where panels stack
9
+ * as users drill down into content. Supports swipe-to-go-back gestures.
10
+ *
11
+ * ## Installation
12
+ * ```ts
13
+ * import { useStackNavigation, SwipeStackOutlet } from "react-panel-layout/stack";
14
+ * ```
15
+ *
16
+ * ## Basic Usage
17
+ * ```tsx
18
+ * const panels = [
19
+ * { id: 'list', title: 'Items', content: <ListPage /> },
20
+ * { id: 'detail', title: 'Detail', content: <DetailPage /> },
21
+ * ];
22
+ *
23
+ * function App() {
24
+ * const { push, go, Outlet } = useStackNavigation({
25
+ * panels,
26
+ * displayMode: 'overlay',
27
+ * });
28
+ *
29
+ * return (
30
+ * <div>
31
+ * <button onClick={() => push('detail')}>View Detail</button>
32
+ * <button onClick={() => go(-1)}>Back</button>
33
+ * <Outlet />
34
+ * </div>
35
+ * );
36
+ * }
37
+ * ```
38
+ *
39
+ * ## With Swipe Gestures (SwipeStackContent)
40
+ * ```tsx
41
+ * const containerRef = useRef<HTMLDivElement>(null);
42
+ * const navigation = useStackNavigation({ panels, displayMode: 'overlay' });
43
+ * const swipeInput = useStackSwipeInput({ containerRef, navigation });
44
+ * const { rect } = useResizeObserver(containerRef);
45
+ *
46
+ * return (
47
+ * <div ref={containerRef} {...swipeInput.containerProps}>
48
+ * {panels.map((panel, index) => (
49
+ * <SwipeStackContent
50
+ * key={panel.id}
51
+ * id={panel.id}
52
+ * depth={index}
53
+ * navigationDepth={navigation.state.depth}
54
+ * isActive={navigation.currentPanelId === panel.id}
55
+ * inputState={swipeInput.inputState}
56
+ * containerSize={rect?.width ?? 0}
57
+ * >
58
+ * {panel.content}
59
+ * </SwipeStackContent>
60
+ * ))}
61
+ * </div>
62
+ * );
63
+ * ```
64
+ */
65
+
66
+ // Hooks
67
+ export { useStackNavigation } from "../modules/stack/useStackNavigation.js";
68
+ export { useStackSwipeInput } from "../modules/stack/useStackSwipeInput.js";
69
+
70
+ // Components
71
+ export { StackContent } from "../modules/stack/StackContent.js";
72
+ export { SwipeStackContent } from "../modules/stack/SwipeStackContent.js";
73
+ export { SwipeStackOutlet } from "../modules/stack/SwipeStackOutlet.js";
74
+
75
+ // Types
76
+ export type {
77
+ StackDisplayMode,
78
+ StackTransitionMode,
79
+ StackPanel,
80
+ StackNavigationState,
81
+ StackPanelProps,
82
+ StackBackButtonProps,
83
+ UseStackNavigationOptions,
84
+ UseStackNavigationResult,
85
+ UseStackSwipeInputOptions,
86
+ UseStackSwipeInputResult,
87
+ StackContentProps,
88
+ } from "../modules/stack/types.js";
89
+
90
+ export type { SwipeStackContentProps } from "../modules/stack/SwipeStackContent.js";
91
+ export type { SwipeStackOutletProps } from "../modules/stack/SwipeStackOutlet.js";
@@ -0,0 +1,193 @@
1
+ /**
2
+ * @file StickyArea component for native app-like overscroll experience.
3
+ *
4
+ * Displays cover content that expands during overscroll/bounce,
5
+ * providing a native app-like pull effect commonly seen in iOS apps.
6
+ *
7
+ * Supports both top (header) and bottom (footer) positions.
8
+ * Works with document-level scroll only.
9
+ */
10
+ import * as React from "react";
11
+ import { useIsomorphicLayoutEffect } from "../hooks/useIsomorphicLayoutEffect";
12
+ import { calculateStickyMetrics } from "./calculateStickyMetrics";
13
+ import type { StickyAreaProps, StickyAreaState } from "./types";
14
+
15
+ /**
16
+ * Get area styles based on position.
17
+ */
18
+ function getAreaStyle(position: "top" | "bottom"): React.CSSProperties {
19
+ return {
20
+ position: "relative",
21
+ paddingTop: position === "top" ? "env(safe-area-inset-top)" : undefined,
22
+ paddingBottom: position === "bottom" ? "env(safe-area-inset-bottom)" : undefined,
23
+ boxSizing: "border-box",
24
+ };
25
+ }
26
+
27
+ const bodyStyle: React.CSSProperties = {
28
+ zIndex: 1,
29
+ };
30
+
31
+ /**
32
+ * Get cover styles based on position.
33
+ * Explicitly disables transitions to prevent jank from inherited CSS.
34
+ */
35
+ function getCoverStyle(position: "top" | "bottom"): React.CSSProperties {
36
+ return {
37
+ opacity: 0,
38
+ zIndex: 0,
39
+ userSelect: "none",
40
+ pointerEvents: "none",
41
+ // Disable transitions to prevent jank - styles are updated via RAF
42
+ transition: "none",
43
+ // Enable GPU acceleration for smoother animations
44
+ willChange: "height, opacity",
45
+ transform: "translateZ(0)",
46
+ position: "fixed",
47
+ top: position === "top" ? 0 : undefined,
48
+ bottom: position === "bottom" ? 0 : undefined,
49
+ left: 0,
50
+ right: 0,
51
+ };
52
+ }
53
+
54
+ const wrapperStyle: React.CSSProperties = {
55
+ position: "relative",
56
+ };
57
+
58
+ /**
59
+ * StickyArea provides a native app-like overscroll experience.
60
+ *
61
+ * When the user overscrolls (pulls beyond the edge), the cover content
62
+ * expands to fill the visible area, similar to native iOS/Android app behavior.
63
+ *
64
+ * Supports both top (header) and bottom (footer) positions.
65
+ * Works with document-level scroll only.
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * // Header (top) - expands on pull-down
70
+ * <StickyArea position="top" cover={<img src="/hero.jpg" />}>
71
+ * <header><h1>My App</h1></header>
72
+ * </StickyArea>
73
+ *
74
+ * // Footer (bottom) - expands on pull-up
75
+ * <StickyArea position="bottom" cover={<div className="footer-bg" />}>
76
+ * <footer>Footer content</footer>
77
+ * </StickyArea>
78
+ * ```
79
+ */
80
+ export const StickyArea: React.FC<StickyAreaProps> = ({
81
+ position = "top",
82
+ cover,
83
+ children,
84
+ onStateChange,
85
+ }) => {
86
+ const areaRef = React.useRef<HTMLDivElement>(null);
87
+ const coverAreaRef = React.useRef<HTMLDivElement>(null);
88
+
89
+ // State for render function and callback
90
+ const [state, setState] = React.useState<StickyAreaState>({
91
+ isStuck: false,
92
+ scrollOffset: 0,
93
+ });
94
+
95
+ // Update state when values change
96
+ const stateRef = React.useRef(state);
97
+ const updateState = React.useCallback(
98
+ (newState: StickyAreaState) => {
99
+ const prev = stateRef.current;
100
+ if (prev.isStuck !== newState.isStuck || prev.scrollOffset !== newState.scrollOffset) {
101
+ stateRef.current = newState;
102
+ setState(newState);
103
+ onStateChange?.(newState);
104
+ }
105
+ },
106
+ [onStateChange],
107
+ );
108
+
109
+ useIsomorphicLayoutEffect(() => {
110
+ const area = areaRef.current;
111
+ const coverArea = coverAreaRef.current;
112
+ if (!coverArea || !area) {
113
+ return;
114
+ }
115
+
116
+ // eslint-disable-next-line no-restricted-syntax -- Performance: mutable state for RAF loop
117
+ let prevHeight = Number.NaN;
118
+ // eslint-disable-next-line no-restricted-syntax -- Performance: mutable state for RAF loop
119
+ let prevLeft = Number.NaN;
120
+ // eslint-disable-next-line no-restricted-syntax -- Performance: mutable state for RAF loop
121
+ let prevWidth = Number.NaN;
122
+ // eslint-disable-next-line no-restricted-syntax -- Performance: mutable state for RAF loop
123
+ let prevIsStuck = false;
124
+ // eslint-disable-next-line no-restricted-syntax -- Performance: mutable state for RAF loop
125
+ let isFirstRun = true;
126
+
127
+ const loop = () => {
128
+ const liveRect = area.getBoundingClientRect();
129
+ const viewportHeight = window.innerHeight;
130
+
131
+ // Calculate metrics using pure function
132
+ const { coverAreaHeight, isStuck, scrollOffset } = calculateStickyMetrics(
133
+ position,
134
+ liveRect,
135
+ viewportHeight
136
+ );
137
+
138
+ // Update height/opacity
139
+ if (coverAreaHeight !== prevHeight) {
140
+ coverArea.style.opacity = coverAreaHeight > 0 ? "1" : "0";
141
+ coverArea.style.height = `${coverAreaHeight}px`;
142
+ prevHeight = coverAreaHeight;
143
+ }
144
+
145
+ // Update left/width
146
+ if (liveRect.left !== prevLeft || liveRect.width !== prevWidth) {
147
+ coverArea.style.left = `${liveRect.left}px`;
148
+ coverArea.style.width = `${liveRect.width}px`;
149
+ prevLeft = liveRect.left;
150
+ prevWidth = liveRect.width;
151
+ }
152
+
153
+ // Update state
154
+ const shouldUpdateState = isFirstRun ? true : isStuck !== prevIsStuck;
155
+ if (shouldUpdateState) {
156
+ isFirstRun = false;
157
+ prevIsStuck = isStuck;
158
+ updateState({ isStuck, scrollOffset });
159
+ }
160
+ };
161
+
162
+ // eslint-disable-next-line no-restricted-syntax -- Performance: RAF id needs reassignment
163
+ let id = requestAnimationFrame(function animate() {
164
+ loop();
165
+ id = requestAnimationFrame(animate);
166
+ });
167
+
168
+ return () => {
169
+ cancelAnimationFrame(id);
170
+ };
171
+ }, [position, updateState]);
172
+
173
+ // Render children
174
+ const renderedChildren = typeof children === "function" ? children(state) : children;
175
+
176
+ return (
177
+ <div style={wrapperStyle}>
178
+ <div ref={coverAreaRef} style={getCoverStyle(position)}>
179
+ {cover}
180
+ </div>
181
+ <div ref={areaRef} style={getAreaStyle(position)}>
182
+ <div style={bodyStyle}>{renderedChildren}</div>
183
+ </div>
184
+ </div>
185
+ );
186
+ };
187
+
188
+ StickyArea.displayName = "StickyArea";
189
+
190
+ /**
191
+ * @deprecated Use StickyArea with position="top" instead
192
+ */
193
+ export const StickyHeader = StickyArea;
@@ -0,0 +1,105 @@
1
+ /**
2
+ * @file Tests for calculateStickyMetrics pure function.
3
+ *
4
+ * Verifies the calculation of coverAreaHeight, isStuck, and scrollOffset
5
+ * for both top and bottom positions under various scroll scenarios.
6
+ */
7
+ import { calculateStickyMetrics, type ElementRect } from "./calculateStickyMetrics.js";
8
+
9
+ describe("calculateStickyMetrics", () => {
10
+ describe("position: top", () => {
11
+ it("returns expanded coverAreaHeight during overscroll (pull-down)", () => {
12
+ const rect: ElementRect = { top: 50, bottom: 150, height: 100 };
13
+ const result = calculateStickyMetrics("top", rect, 800);
14
+
15
+ expect(result).toEqual({
16
+ coverAreaHeight: 150, // height + top = 100 + 50
17
+ isStuck: false,
18
+ scrollOffset: 0,
19
+ });
20
+ });
21
+
22
+ it("returns reduced coverAreaHeight during normal scroll", () => {
23
+ const rect: ElementRect = { top: -30, bottom: 70, height: 100 };
24
+ const result = calculateStickyMetrics("top", rect, 800);
25
+
26
+ expect(result).toEqual({
27
+ coverAreaHeight: 70, // height + top = 100 + (-30)
28
+ isStuck: true,
29
+ scrollOffset: 30,
30
+ });
31
+ });
32
+
33
+ it("returns exact height at boundary (top === 0)", () => {
34
+ const rect: ElementRect = { top: 0, bottom: 100, height: 100 };
35
+ const result = calculateStickyMetrics("top", rect, 800);
36
+
37
+ expect(result).toEqual({
38
+ coverAreaHeight: 100,
39
+ isStuck: false,
40
+ scrollOffset: 0,
41
+ });
42
+ });
43
+
44
+ it("clamps coverAreaHeight to 0 when fully scrolled past", () => {
45
+ const rect: ElementRect = { top: -150, bottom: -50, height: 100 };
46
+ const result = calculateStickyMetrics("top", rect, 800);
47
+
48
+ expect(result.coverAreaHeight).toBe(0);
49
+ expect(result.isStuck).toBe(true);
50
+ expect(result.scrollOffset).toBe(150);
51
+ });
52
+ });
53
+
54
+ describe("position: bottom", () => {
55
+ it("returns expanded coverAreaHeight during overscroll (pull-up)", () => {
56
+ const rect: ElementRect = { top: 600, bottom: 700, height: 100 };
57
+ const viewportHeight = 800;
58
+ const result = calculateStickyMetrics("bottom", rect, viewportHeight);
59
+
60
+ // distanceFromBottom = 800 - 700 = 100
61
+ // coverAreaHeight = 100 + 100 = 200
62
+ expect(result).toEqual({
63
+ coverAreaHeight: 200,
64
+ isStuck: false,
65
+ scrollOffset: 0,
66
+ });
67
+ });
68
+
69
+ it("returns reduced coverAreaHeight during normal scroll", () => {
70
+ const rect: ElementRect = { top: 750, bottom: 850, height: 100 };
71
+ const viewportHeight = 800;
72
+ const result = calculateStickyMetrics("bottom", rect, viewportHeight);
73
+
74
+ // distanceFromBottom = 800 - 850 = -50
75
+ // coverAreaHeight = 100 + (-50) = 50
76
+ expect(result).toEqual({
77
+ coverAreaHeight: 50,
78
+ isStuck: true,
79
+ scrollOffset: 50,
80
+ });
81
+ });
82
+
83
+ it("returns exact height at boundary (bottom === viewportHeight)", () => {
84
+ const rect: ElementRect = { top: 700, bottom: 800, height: 100 };
85
+ const viewportHeight = 800;
86
+ const result = calculateStickyMetrics("bottom", rect, viewportHeight);
87
+
88
+ expect(result).toEqual({
89
+ coverAreaHeight: 100,
90
+ isStuck: false,
91
+ scrollOffset: 0,
92
+ });
93
+ });
94
+
95
+ it("clamps coverAreaHeight to 0 when fully scrolled past", () => {
96
+ const rect: ElementRect = { top: 900, bottom: 1000, height: 100 };
97
+ const viewportHeight = 800;
98
+ const result = calculateStickyMetrics("bottom", rect, viewportHeight);
99
+
100
+ expect(result.coverAreaHeight).toBe(0);
101
+ expect(result.isStuck).toBe(true);
102
+ expect(result.scrollOffset).toBe(200);
103
+ });
104
+ });
105
+ });
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @file Pure function for calculating sticky area metrics.
3
+ *
4
+ * Extracts the position-dependent calculation logic from StickyArea component
5
+ * to enable unit testing and reduce code duplication.
6
+ */
7
+ import type { StickyAreaPosition } from "./types";
8
+
9
+ /** Output metrics for sticky area layout. */
10
+ export type StickyMetrics = {
11
+ coverAreaHeight: number;
12
+ isStuck: boolean;
13
+ scrollOffset: number;
14
+ };
15
+
16
+ /** Lightweight element bounding rect used for calculations. */
17
+ export type ElementRect = {
18
+ top: number;
19
+ bottom: number;
20
+ height: number;
21
+ };
22
+
23
+ /**
24
+ * Calculate sticky area metrics based on element position and viewport.
25
+ *
26
+ * @param position - Whether the sticky area is at "top" or "bottom"
27
+ * @param rect - Element bounding rect (top, bottom, height)
28
+ * @param viewportHeight - Current viewport height
29
+ * @returns Calculated metrics for cover area height, stuck state, and scroll offset
30
+ */
31
+ export function calculateStickyMetrics(
32
+ position: StickyAreaPosition,
33
+ rect: ElementRect,
34
+ viewportHeight: number
35
+ ): StickyMetrics {
36
+ if (position === "top") {
37
+ return {
38
+ coverAreaHeight: Math.max(0, rect.height + rect.top),
39
+ isStuck: rect.top < 0,
40
+ scrollOffset: Math.max(0, -rect.top),
41
+ };
42
+ }
43
+ // bottom
44
+ const distanceFromBottom = viewportHeight - rect.bottom;
45
+ return {
46
+ coverAreaHeight: Math.max(0, rect.height + distanceFromBottom),
47
+ isStuck: rect.bottom > viewportHeight,
48
+ scrollOffset: Math.max(0, rect.bottom - viewportHeight),
49
+ };
50
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @file StickyArea entry point - Native app-like overscroll experience
3
+ *
4
+ * Import via: import { StickyArea } from "react-panel-layout/sticky-header";
5
+ */
6
+
7
+ // Components
8
+ export { StickyArea, StickyHeader } from "./StickyArea";
9
+
10
+ // Types
11
+ export type {
12
+ StickyAreaPosition,
13
+ StickyAreaProps,
14
+ StickyAreaState,
15
+ // Backwards compatibility
16
+ StickyHeaderProps,
17
+ StickyHeaderState,
18
+ } from "./types";