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,58 @@
1
+ /**
2
+ * @file Hook for animation-aware visibility control.
3
+ *
4
+ * Common pattern for showing/hiding elements with CSS animations:
5
+ * - If animation exists: wait for animationend before hiding
6
+ * - If no animation: hide immediately
7
+ * - Uses display:none for performance (removes from layout)
8
+ * - Includes timeout fallback in case animationend doesn't fire
9
+ */
10
+ import * as React from "react";
11
+ type AnimatedVisibilityState = {
12
+ /** Whether element should be displayed (display: block/none) */
13
+ shouldDisplay: boolean;
14
+ /** Whether element is currently animating out */
15
+ isAnimatingOut: boolean;
16
+ };
17
+ type UseAnimatedVisibilityOptions = {
18
+ /** Whether the element is logically visible */
19
+ isVisible: boolean;
20
+ /** CSS animation value for leave animation (e.g., CSS variable) */
21
+ leaveAnimation?: string;
22
+ /** Skip animation and hide immediately */
23
+ skipAnimation?: boolean;
24
+ /** Timeout for animation fallback in ms (default: 1000ms) */
25
+ animationTimeout?: number;
26
+ };
27
+ type UseAnimatedVisibilityResult = {
28
+ /** Current visibility state */
29
+ state: AnimatedVisibilityState;
30
+ /** Props to spread on the animated element */
31
+ props: {
32
+ onAnimationEnd: (e: React.AnimationEvent) => void;
33
+ };
34
+ /** Style to apply for display control */
35
+ style: {
36
+ display: "block" | "none";
37
+ };
38
+ };
39
+ /**
40
+ * Hook for animation-aware visibility control.
41
+ *
42
+ * @example
43
+ * const { state, props, style } = useAnimatedVisibility({
44
+ * isVisible: isActive,
45
+ * leaveAnimation: PIVOT_ANIMATION_LEAVE,
46
+ * });
47
+ *
48
+ * return (
49
+ * <div
50
+ * style={{ ...baseStyle, ...style, animation: isActive ? enterAnim : leaveAnim }}
51
+ * {...props}
52
+ * >
53
+ * {children}
54
+ * </div>
55
+ * );
56
+ */
57
+ export declare function useAnimatedVisibility({ isVisible, leaveAnimation, skipAnimation, animationTimeout, }: UseAnimatedVisibilityOptions): UseAnimatedVisibilityResult;
58
+ export {};
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Easing function type.
3
+ * Takes a progress value (0-1) and returns an eased value (0-1).
4
+ */
5
+ export type EasingFunction = (t: number) => number;
6
+ /**
7
+ * Built-in easing functions.
8
+ */
9
+ export declare const easings: {
10
+ /** Linear (no easing) */
11
+ readonly linear: (t: number) => number;
12
+ /** Ease out cubic */
13
+ readonly easeOutCubic: (t: number) => number;
14
+ /** Ease out expo (similar to cubic-bezier(0.22, 1, 0.36, 1)) */
15
+ readonly easeOutExpo: (t: number) => number;
16
+ /** Ease out quart */
17
+ readonly easeOutQuart: (t: number) => number;
18
+ /** Ease in out cubic */
19
+ readonly easeInOutCubic: (t: number) => number;
20
+ /** Ease in expo (accelerating, for "suck in" effect) */
21
+ readonly easeInExpo: (t: number) => number;
22
+ };
23
+ /**
24
+ * Animation state passed to callbacks.
25
+ */
26
+ export type AnimationState = {
27
+ /** Raw progress (0-1) */
28
+ progress: number;
29
+ /** Eased progress (0-1) */
30
+ easedProgress: number;
31
+ /** Elapsed time in ms */
32
+ elapsed: number;
33
+ /** Whether animation is complete */
34
+ isComplete: boolean;
35
+ };
36
+ /**
37
+ * Options for useAnimationFrame hook.
38
+ */
39
+ export type UseAnimationFrameOptions = {
40
+ /** Duration of animation in milliseconds */
41
+ duration?: number;
42
+ /** Easing function for the animation */
43
+ easing?: EasingFunction;
44
+ /** Callback called every frame with animation state */
45
+ onFrame?: (state: AnimationState) => void;
46
+ /** Callback when animation completes */
47
+ onComplete?: () => void;
48
+ };
49
+ /**
50
+ * Result from useAnimationFrame hook.
51
+ */
52
+ export type UseAnimationFrameResult = {
53
+ /** Whether animation is currently running */
54
+ isAnimating: boolean;
55
+ /** Start the animation */
56
+ start: () => void;
57
+ /** Cancel the animation */
58
+ cancel: () => void;
59
+ };
60
+ /**
61
+ * Generic requestAnimationFrame-based animation hook.
62
+ *
63
+ * Provides a reusable animation loop with progress calculation and easing.
64
+ * Use this as a building block for specific animation behaviors.
65
+ *
66
+ * @example
67
+ * ```tsx
68
+ * const { start, isAnimating } = useAnimationFrame({
69
+ * duration: 300,
70
+ * easing: easings.easeOutExpo,
71
+ * onFrame: ({ easedProgress }) => {
72
+ * const value = fromValue + (toValue - fromValue) * easedProgress;
73
+ * element.style.transform = `translateX(${value}px)`;
74
+ * },
75
+ * onComplete: () => console.log('Done!'),
76
+ * });
77
+ *
78
+ * // Start animation
79
+ * start();
80
+ * ```
81
+ */
82
+ export declare function useAnimationFrame(options: UseAnimationFrameOptions): UseAnimationFrameResult;
83
+ /**
84
+ * Interpolate between two values using eased progress.
85
+ */
86
+ export declare function interpolate(from: number, to: number, easedProgress: number): number;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Result from useOperationContinuity hook.
3
+ */
4
+ export type UseOperationContinuityResult<T> = {
5
+ /** The effective value (retained during operation, current after) */
6
+ value: T;
7
+ /**
8
+ * True if the value changed during the operation.
9
+ *
10
+ * This is useful for determining how to handle the transition when the
11
+ * operation ends. For example, if the role changed during a swipe,
12
+ * the target position change at operation end should snap rather than animate.
13
+ *
14
+ * This flag is true on the render where shouldRetainPrevious becomes false
15
+ * (operation end), allowing consumers to handle the transition appropriately.
16
+ * It resets to false on subsequent renders.
17
+ */
18
+ changedDuringOperation: boolean;
19
+ /**
20
+ * True on the render where the operation just ended.
21
+ *
22
+ * This is true when shouldRetainPrevious transitions from true to false,
23
+ * regardless of whether the value changed. Use this to detect the moment
24
+ * when an operation completes and delay any immediate animations.
25
+ *
26
+ * In the over-swipe case, this helps prevent unwanted snap-back animation
27
+ * in the intermediate render before navigation changes.
28
+ */
29
+ operationJustEnded: boolean;
30
+ };
31
+ /**
32
+ * Hook for maintaining value continuity during continuous operations.
33
+ *
34
+ * When an operation is in progress, this hook retains the previous value
35
+ * to prevent sudden visual changes from state updates. Once the operation
36
+ * ends (shouldRetainPrevious becomes false), the new value is accepted.
37
+ *
38
+ * Additionally, this hook tracks whether the value changed during the operation,
39
+ * which is useful for determining animation behavior at operation end.
40
+ *
41
+ * IMPORTANT: This hook is designed to be idempotent during render to work
42
+ * correctly with React StrictMode, which calls the render function twice.
43
+ * All ref mutations happen in useLayoutEffect, not during render.
44
+ *
45
+ * @param value - The current value from external state
46
+ * @param shouldRetainPrevious - Whether to retain the previous value (true during operation)
47
+ * @returns Object with effective value and whether it changed during operation
48
+ *
49
+ * @example
50
+ * ```tsx
51
+ * // Maintain role continuity during swipe
52
+ * const { value: effectiveRole, changedDuringOperation } = useOperationContinuity(
53
+ * role,
54
+ * displacement > 0,
55
+ * );
56
+ *
57
+ * // Use changedDuringOperation to skip animation on operation end
58
+ * useSwipeContentTransform({
59
+ * // ...
60
+ * skipTargetChangeAnimation: changedDuringOperation,
61
+ * });
62
+ * ```
63
+ */
64
+ export declare function useOperationContinuity<T>(value: T, shouldRetainPrevious: boolean): UseOperationContinuityResult<T>;
@@ -1,15 +1,47 @@
1
1
  /**
2
2
  * @file Shared useResizeObserver hook with cached observer instances.
3
+ *
4
+ * Provides element size observation with shared observers for memory efficiency.
5
+ * Size becomes available after the first useLayoutEffect cycle completes.
6
+ *
7
+ * Note: Due to React's effect execution order (children before parents),
8
+ * child components may see containerSize=0 on their first effect run.
9
+ * This is a React constraint, not a bug. Consumers should check for
10
+ * valid size before using it for calculations like animation positions.
3
11
  */
4
12
  import * as React from "react";
13
+ /**
14
+ * Clear observer cache. Exported for testing purposes.
15
+ */
16
+ export declare function clearObserverCache(): void;
5
17
  /**
6
18
  * Observe size changes for a given element reference using shared resize observers.
7
19
  *
8
20
  * @param ref - Ref holding the element whose size to monitor.
9
21
  * @param options - Resize observer configuration.
10
22
  * @returns Latest resize entry and a derived DOMRect snapshot.
23
+ *
24
+ * @remarks
25
+ * The `rect` will be `null` on the first render. After the initial
26
+ * useLayoutEffect runs and triggers a re-render, `rect` will contain
27
+ * the measured size.
28
+ *
29
+ * Due to React's effect execution order, child components' effects run
30
+ * before parent effects. If you pass `rect.width` to a child as a prop,
31
+ * the child's first effect will see `0` (or whatever default you use).
32
+ * This is expected React behavior.
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * const containerRef = useRef<HTMLDivElement>(null);
37
+ * const { rect } = useResizeObserver(containerRef, { box: "border-box" });
38
+ * const width = rect?.width ?? 0;
39
+ *
40
+ * // Check if size is ready before using for calculations
41
+ * const isReady = rect !== null;
42
+ * ```
11
43
  */
12
44
  export declare function useResizeObserver<T extends HTMLElement>(ref: React.RefObject<T | null>, { box }: ResizeObserverOptions): {
13
45
  entry: ResizeObserverEntry | null;
14
- rect: DOMRectReadOnly | null;
46
+ rect: DOMRect | null;
15
47
  };
@@ -0,0 +1,112 @@
1
+ /**
2
+ * @file Hook for View Transitions API shared element animations.
3
+ *
4
+ * Enables smooth morph animations between a source element (e.g., card)
5
+ * and a target element (e.g., expanded view) using CSS view-transition-name.
6
+ * Supports swipe-to-dismiss with the expanded view animating back to source.
7
+ */
8
+ import * as React from "react";
9
+ /**
10
+ * Check if View Transitions API is supported.
11
+ */
12
+ export declare function supportsViewTransitions(): boolean;
13
+ type ViewTransitionHandle = {
14
+ finished: Promise<void>;
15
+ ready: Promise<void>;
16
+ updateCallbackDone: Promise<void>;
17
+ skipTransition: () => void;
18
+ };
19
+ /**
20
+ * Start a view transition with the given callback.
21
+ */
22
+ export declare function startViewTransition(callback: () => void): ViewTransitionHandle | null;
23
+ /**
24
+ * Options for useSharedElementTransition hook.
25
+ */
26
+ export type UseSharedElementTransitionOptions<T> = {
27
+ /**
28
+ * Function to generate a unique transition name for an item.
29
+ * Multiple names can be returned for nested shared elements.
30
+ */
31
+ getTransitionName: (item: T) => string | string[];
32
+ /**
33
+ * Function to get a unique key for comparison.
34
+ * Defaults to using getTransitionName result.
35
+ */
36
+ getKey?: (item: T) => string;
37
+ /** Enable swipe to dismiss. @default true */
38
+ swipeDismissible?: boolean;
39
+ /** Threshold ratio (0-1) to trigger dismiss. @default 0.3 */
40
+ dismissThreshold?: number;
41
+ };
42
+ /** 2D vector */
43
+ type Vector2 = {
44
+ x: number;
45
+ y: number;
46
+ };
47
+ /**
48
+ * Result from useSharedElementTransition hook.
49
+ */
50
+ export type UseSharedElementTransitionResult<T> = {
51
+ /** Currently expanded item, or null if none */
52
+ expandedItem: T | null;
53
+ /** Expand an item with view transition */
54
+ expand: (item: T) => void;
55
+ /** Collapse the expanded item with view transition */
56
+ collapse: () => void;
57
+ /**
58
+ * Get style props for a source element (e.g., card).
59
+ */
60
+ getSourceProps: (item: T, nameIndex?: number) => {
61
+ style: React.CSSProperties;
62
+ };
63
+ /**
64
+ * Get style props for the target element (e.g., expanded view).
65
+ * Includes transform for swipe tracking.
66
+ */
67
+ getTargetProps: (nameIndex?: number) => {
68
+ style: React.CSSProperties;
69
+ };
70
+ /**
71
+ * Get swipe container props (onPointerDown, style).
72
+ * Apply to the swipeable container element.
73
+ */
74
+ getSwipeContainerProps: () => React.HTMLAttributes<HTMLElement> & {
75
+ style: React.CSSProperties;
76
+ };
77
+ /** Whether currently being swiped */
78
+ isSwiping: boolean;
79
+ /** Current displacement during swipe */
80
+ displacement: Vector2;
81
+ /** Whether View Transitions API is supported */
82
+ isSupported: boolean;
83
+ };
84
+ /**
85
+ * Hook for managing shared element transitions using View Transitions API.
86
+ *
87
+ * @example
88
+ * ```tsx
89
+ * const {
90
+ * expandedItem, expand, collapse,
91
+ * getSourceProps, getTargetProps, getSwipeContainerProps
92
+ * } = useSharedElementTransition({
93
+ * getTransitionName: (album) => [`album-${album.id}`, `album-art-${album.id}`],
94
+ * });
95
+ *
96
+ * // Source (card)
97
+ * <div {...getSourceProps(album, 0)}>
98
+ * <img {...getSourceProps(album, 1)} />
99
+ * </div>
100
+ *
101
+ * // Target (expanded view) - apply swipe props to container
102
+ * {expandedItem && (
103
+ * <div {...getSwipeContainerProps()}>
104
+ * <div {...getTargetProps(0)}>
105
+ * <img {...getTargetProps(1)} />
106
+ * </div>
107
+ * </div>
108
+ * )}
109
+ * ```
110
+ */
111
+ export declare function useSharedElementTransition<T>(options: UseSharedElementTransitionOptions<T>): UseSharedElementTransitionResult<T>;
112
+ export {};
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @file Hook for snapping element transform animation.
3
+ *
4
+ * Built on top of useAnimationFrame, provides a convenient API
5
+ * for animating element transforms from one position to another.
6
+ */
7
+ import * as React from "react";
8
+ import type { EasingFunction } from "./useAnimationFrame.js";
9
+ export { easings } from "./useAnimationFrame.js";
10
+ export type { EasingFunction } from "./useAnimationFrame.js";
11
+ /**
12
+ * Options for useSnapAnimation hook.
13
+ */
14
+ export type UseSnapAnimationOptions = {
15
+ /** Reference to the element to animate */
16
+ elementRef: React.RefObject<HTMLElement | null>;
17
+ /** Duration of animation in milliseconds */
18
+ duration?: number;
19
+ /** Easing function for the animation */
20
+ easing?: EasingFunction;
21
+ /** Callback when animation completes */
22
+ onComplete?: () => void;
23
+ };
24
+ /**
25
+ * Result from useSnapAnimation hook.
26
+ */
27
+ export type UseSnapAnimationResult = {
28
+ /** Whether animation is currently running */
29
+ isAnimating: boolean;
30
+ /** Start a new animation from current value to target */
31
+ animate: (from: number, to: number, axis: "x" | "y") => void;
32
+ /** Cancel any running animation */
33
+ cancel: () => void;
34
+ };
35
+ /**
36
+ * Hook for snapping element transform animation.
37
+ *
38
+ * Animates an element's transform from one position to another
39
+ * using requestAnimationFrame for smooth animation.
40
+ *
41
+ * @example
42
+ * ```tsx
43
+ * const elementRef = useRef<HTMLDivElement>(null);
44
+ * const { animate, isAnimating } = useSnapAnimation({
45
+ * elementRef,
46
+ * duration: 300,
47
+ * easing: easings.easeOutExpo,
48
+ * });
49
+ *
50
+ * // Start animation
51
+ * animate(currentX, targetX, "x");
52
+ * ```
53
+ */
54
+ export declare function useSnapAnimation(options: UseSnapAnimationOptions): UseSnapAnimationResult;
@@ -0,0 +1,86 @@
1
+ /**
2
+ * @file Shared hook for DOM-based swipe content transform.
3
+ *
4
+ * This hook provides immediate DOM manipulation for swipe gestures,
5
+ * with smooth snap-back animation when the swipe ends.
6
+ *
7
+ * Used by both Pivot and Stack for consistent swipe behavior.
8
+ */
9
+ import * as React from "react";
10
+ import type { GestureAxis } from "./gesture/types.js";
11
+ /**
12
+ * Options for useSwipeContentTransform hook.
13
+ */
14
+ export type UseSwipeContentTransformOptions = {
15
+ /** Ref to the element to transform */
16
+ elementRef: React.RefObject<HTMLElement | null>;
17
+ /** Target position in pixels (where element should be at rest) */
18
+ targetPx: number;
19
+ /** Current swipe displacement in pixels */
20
+ displacement: number;
21
+ /** Whether swipe gesture is active */
22
+ isOperating: boolean;
23
+ /** Axis of transformation */
24
+ axis?: GestureAxis;
25
+ /** Duration of snap animation in ms */
26
+ animationDuration?: number;
27
+ /** Container size in pixels (used for snap on resize) */
28
+ containerSize?: number;
29
+ /**
30
+ * Whether to animate when targetPx changes (without swipe).
31
+ * Use this for tab bar animations triggered by click/button.
32
+ * @default false
33
+ */
34
+ animateOnTargetChange?: boolean;
35
+ /**
36
+ * Initial position in pixels when first mounted.
37
+ * If different from targetPx, will animate from initialPx to targetPx.
38
+ * Use this for push animations where new panel comes from off-screen.
39
+ */
40
+ initialPx?: number;
41
+ /**
42
+ * Skip animation when targetPx changes.
43
+ * Use this when the target changed during an operation (from useOperationContinuity).
44
+ * When true, target changes will snap instead of animate.
45
+ * @default false
46
+ */
47
+ skipTargetChangeAnimation?: boolean;
48
+ };
49
+ /**
50
+ * Animation direction information.
51
+ */
52
+ export type AnimationDirection = {
53
+ /** Source position in pixels */
54
+ from: number;
55
+ /** Target position in pixels */
56
+ to: number;
57
+ };
58
+ /**
59
+ * Result from useSwipeContentTransform hook.
60
+ */
61
+ export type UseSwipeContentTransformResult = {
62
+ /** Whether snap animation is currently running */
63
+ isAnimating: boolean;
64
+ /** Current position in pixels (for visibility calculations) */
65
+ currentPx: number;
66
+ /** Animation direction info, or null if not animating */
67
+ animationDirection: AnimationDirection | null;
68
+ };
69
+ /**
70
+ * Hook for DOM-based swipe content transform.
71
+ *
72
+ * During swipe: immediately updates element.style.transform to follow finger.
73
+ * After swipe: animates from current position to target position.
74
+ *
75
+ * @example
76
+ * ```tsx
77
+ * const containerRef = useRef<HTMLDivElement>(null);
78
+ * const { isAnimating, currentPx } = useSwipeContentTransform({
79
+ * elementRef: containerRef,
80
+ * targetPx: 0,
81
+ * displacement: inputState.displacement.x,
82
+ * isOperating: inputState.phase === "swiping",
83
+ * });
84
+ * ```
85
+ */
86
+ export declare function useSwipeContentTransform(options: UseSwipeContentTransformOptions): UseSwipeContentTransformResult;
package/dist/index.cjs CHANGED
@@ -1,3 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=require("./GridLayout-BQQ63eA1.cjs"),h=require("react/jsx-runtime"),Rt=require("react"),P=require("./styles-PsqGOEJP.cjs"),tt=require("./useIsomorphicLayoutEffect-DGRNF4Lf.cjs"),Pt=require("react-dom"),Dt=require("./usePivot-7ctin_P_.cjs");function jt(t){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const n in t)if(n!=="default"){const r=Object.getOwnPropertyDescriptor(t,n);Object.defineProperty(e,n,r.get?r:{enumerable:!0,get:()=>t[n]})}}return e.default=t,Object.freeze(e)}const u=jt(Rt),At=t=>{const e=t==="drag"?P.COLOR_RESIZE_HANDLE_ACTIVE:t==="hover"?P.COLOR_RESIZE_HANDLE_HOVER:P.COLOR_RESIZE_HANDLE_IDLE;return{width:P.HORIZONTAL_DIVIDER_WIDTH,cursor:"col-resize",position:"relative",userSelect:"none",backgroundColor:e}},kt=({onResize:t,component:e,element:n})=>{const{ref:r,isDragging:o,onPointerDown:s}=E.useResizeDrag({axis:"x",onResize:t}),[a,i]=u.useState(!1),c={ref:r,style:At(o?"drag":a?"hover":"idle"),role:"separator","aria-orientation":"vertical","data-dragging":o?"true":void 0,onPointerDown:s,onPointerEnter:()=>i(!0),onPointerLeave:()=>i(!1)};return n?u.cloneElement(n,c):e?h.jsx(e,{...c}):h.jsx("div",{...c})},_t=()=>{const{layerId:t}=E.useLayerInstance(),{getLayerHandleProps:e}=E.useGridLayoutContext();return u.useMemo(()=>e(t),[e,t])},nt={left:0,top:0},rt={width:400,height:300},Mt=t=>{const[e,n]=u.useState(()=>{const l={};return t.forEach(p=>{if(p.floating){const g=p.floating;l[p.id]={position:g.defaultPosition??nt,size:g.defaultSize??rt}}}),l}),r=u.useMemo(()=>{const l=new Map;return t.forEach(p=>l.set(p.id,p)),l},[t]),o=u.useCallback(l=>{const p=r.get(l);return p?.floating?.position!==void 0?p.floating.position:e[l]?.position??nt},[r,e]),s=u.useCallback(l=>{const p=r.get(l);return p?.floating?.size!==void 0?p.floating.size:e[l]?.size??rt},[r,e]),a=u.useCallback(l=>r.get(l)?.floating?.zIndex,[r]),i=u.useCallback((l,p)=>{const g=r.get(l);g?.floating&&(g.floating.position===void 0&&n(v=>{const b=v[l];return b?{...v,[l]:{...b,position:p}}:v}),g.floating.onMove?.(p))},[r]),c=u.useCallback((l,p)=>{const g=r.get(l);g?.floating&&(g.floating.size===void 0&&n(v=>{const b=v[l];return b?{...v,[l]:{...b,size:p}}:v}),g.floating.onResize?.(p))},[r]),d=u.useCallback(l=>{r.get(l)?.floating?.onClose?.()},[r]);return{getPosition:o,getSize:s,getZIndex:a,updatePosition:i,updateSize:c,close:d}},ut=u.createContext(null),Ot=()=>{const t=u.useContext(ut);if(!t)throw new Error("useKeybindings must be used within KeybindingsProvider");return t},Nt=t=>{const e=[];t.metaKey&&e.push("Mod"),t.ctrlKey&&e.push("Ctrl"),t.altKey&&e.push("Alt"),t.shiftKey&&e.push("Shift");const n=t.key.length===1?t.key.toUpperCase():t.key;return e.push(n),e.join("-")},Lt=({children:t,configure:e})=>{const n=u.useRef({}),r=u.useCallback((a,i)=>{n.current={...n.current,[a]:i}},[]),o=u.useCallback(a=>{const i={...n.current};delete i[a],n.current=i},[]);u.useEffect(()=>{const a=i=>{const c=Nt(i),d=n.current[c];d&&d(i)};return window.addEventListener("keydown",a),()=>{window.removeEventListener("keydown",a)}},[]);const s=u.useMemo(()=>({register:r,unregister:o}),[r,o]);return u.useEffect(()=>{e&&e(s)},[s,e]),h.jsx(ut.Provider,{value:s,children:t})},Bt=(t,e)=>{t.register("Mod-\\",n=>{n.preventDefault(),e.splitFocused("vertical")}),t.register("Mod-Shift-\\",n=>{n.preventDefault(),e.splitFocused("horizontal")});for(const n of[1,2,3,4,5,6,7,8,9])t.register(`Mod-${String(n)}`,r=>{r.preventDefault(),e.focusGroupIndex(n)});t.register("Alt-ArrowRight",n=>{n.preventDefault(),e.focusNextGroup()}),t.register("Alt-ArrowLeft",n=>{n.preventDefault(),e.focusPrevGroup()})},Ht=t=>t.type==="group",lt=(t,e={x:0,y:0,w:100,h:100})=>{const n=new Map,r=(o,s)=>{if(Ht(o)){n.set(o.groupId,s);return}if(o.direction==="vertical"){const c=s.w*o.ratio,d=s.w-c;r(o.a,{x:s.x,y:s.y,w:c,h:s.h}),r(o.b,{x:s.x+c,y:s.y,w:d,h:s.h});return}const a=s.h*o.ratio,i=s.h-a;r(o.a,{x:s.x,y:s.y,w:s.w,h:a}),r(o.b,{x:s.x,y:s.y+a,w:s.w,h:i})};return r(t,e),n},zt=(t,e)=>{const n=lt(t.tree),r={areas:[["root"]],rows:[{size:"1fr"}],columns:[{size:"1fr"}],gap:"0px",style:{position:"relative"}},o=Array.from(n.entries()).map(([s,a])=>{const i={position:"absolute",left:`${a.x}%`,top:`${a.y}%`,width:`${a.w}%`,height:`${a.h}%`,overflow:"hidden",display:"flex",flexDirection:"column"};return{id:s,positionMode:"absolute",style:i,component:e(s)}});return{config:r,layers:o}},$t=(t,e,n)=>{const r=lt(t.tree),o=Array.from(new Set(Array.from(r.values()).flatMap(b=>[b.x,b.x+b.w]))).sort((b,I)=>b-I),s=Array.from(new Set(Array.from(r.values()).flatMap(b=>[b.y,b.y+b.h]))).sort((b,I)=>b-I),a=o.slice(1).map((b,I)=>`${b-o[I]}fr`),i=s.slice(1).map((b,I)=>`${b-s[I]}fr`),c=a.map(b=>({size:b,resizable:n})),d=i.map(b=>({size:b,resizable:n})),l=(b,I,w,y)=>{for(const[m,x]of r.entries())if(b>=x.x&&I<=x.x+x.w&&w>=x.y&&y<=x.y+x.h)return m;return"."},p=[];for(let b=0;b<s.length-1;b+=1){const I=[];for(let w=0;w<o.length-1;w+=1)I.push(l(o[w],o[w+1],s[b],s[b+1]));p.push(I)}const g={areas:p,rows:d,columns:c,gap:"0px"},v=Array.from(r.keys()).map(b=>({id:b,gridArea:b,component:e(b)}));return{config:g,layers:v}},dt=u.createContext(null),Ft=()=>{const t=u.useContext(dt);if(!t)throw new Error("usePanelRenderContext must be used within PanelRenderProvider");return t},Xt=({value:t,children:e})=>h.jsx(dt.Provider,{value:t,children:e}),pt=u.createContext(null),ft=()=>{const t=u.useContext(pt);if(!t)throw new Error("useDomRegistry must be used within DomRegistryProvider");return t},Yt=({children:t})=>{const e=u.useRef(new Map),n=u.useCallback(c=>{const d=e.current.get(c);if(d)return d;const l={group:null,tabbar:null,content:null};return e.current.set(c,l),l},[]),r=u.useCallback((c,d)=>{const l=n(c);if(l.group=d,d===null){const p=e.current.get(c);(p?p.tabbar===null&&p.content===null:!1)&&e.current.delete(c)}},[n]),o=u.useCallback((c,d)=>{const l=n(c);if(l.tabbar=d,d===null){const p=e.current.get(c);(p?p.group===null&&p.content===null:!1)&&e.current.delete(c)}},[n]),s=u.useCallback((c,d)=>{const l=n(c);if(l.content=d,d===null){const p=e.current.get(c);(p?p.group===null&&p.tabbar===null:!1)&&e.current.delete(c)}},[n]),a=u.useCallback(()=>e.current,[]),i=u.useMemo(()=>({setGroupEl:r,setTabbarEl:o,setContentEl:s,getAll:a}),[r,o,s,a]);return h.jsx(pt.Provider,{value:i,children:t})},qt={display:"flex",flexDirection:"column",width:"100%",height:"100%"},Ut={flex:"1 1 auto",minWidth:0,minHeight:0,position:"relative",overflow:"hidden"};function Vt(t,e,n,r){return t?u.cloneElement(t,n,r):e?h.jsx(e,{...n,children:r}):h.jsx("div",{...n,children:r})}function Kt(t,e,n,r){return t?u.cloneElement(t,n,r):e?h.jsx(e,{...n,children:r}):h.jsx("div",{...n,children:r})}const Wt=({group:t,tabbar:e,content:n,onContentPointerDown:r,groupRef:o,contentRef:s,component:a,element:i,contentComponent:c,contentElement:d})=>{const l={ref:o,style:qt,"data-group-id":t.id},g=Vt(d,c,{ref:s,style:Ut,"data-dnd-zone":"content",onPointerDown:r},n),v=h.jsxs(h.Fragment,{children:[e,g]});return Kt(i,a,l,v)},gt=u.memo(Wt,(t,e)=>t.group.id!==e.group.id||t.group.activeTabId!==e.group.activeTabId||t.group.tabs.length!==e.group.tabs.length?!1:t.group.tabs===e.group.tabs);gt.displayName="PanelGroupView";const q=(t,e,n)=>{const r=t.left,o=t.top,s=t.width,a=t.height,i=e-r,c=n-o,d=s/3,l=a/3;return i>d&&i<s-d&&c>l&&c<a-l?"center":i<c&&i<s-i&&c<a-c?"left":s-i<c&&s-i<i&&c<a-c?"right":c<i&&c<a-c&&i<s-i?"top":"bottom"};function k(t,e){if(!e){const r=(()=>({type:t}));return Object.defineProperty(r,"type",{value:t,writable:!1,enumerable:!0}),r}const n=((...r)=>{const o=e(...r);return typeof o>"u"?{type:t}:{type:t,payload:o}});return Object.defineProperty(n,"type",{value:t,writable:!1,enumerable:!0}),n}const Zt=(t,e)=>{const n={};return Object.keys(t).forEach(r=>{const o=t[r];n[r]=((...s)=>{const a=o(...s);return e(a),a})}),n},bt=(t,e)=>{const n={};return Object.keys(e).forEach(r=>{const o=e[r];if(!o)return;const s=t[r];if(!s)throw new Error(`Missing action creator for key "${String(r)}"`);n[s.type]=o}),n},ht={phase:{kind:"idle"},suggest:null,pointer:null,tabbarHover:null,draggingTabElement:null},A={startContent:k("START_CONTENT",t=>t),startTab:k("START_TAB",t=>t),setSuggest:k("SET_SUGGEST",t=>t),setPointer:k("SET_POINTER",t=>t),setTabbarHover:k("SET_TABBAR_HOVER",t=>t),reset:k("RESET")},Jt=bt(A,{startContent:(t,e)=>({phase:{kind:"content",startX:e.payload.x,startY:e.payload.y,fromGroupId:e.payload.groupId,tabId:e.payload.tabId,cache:e.payload.cache},suggest:null,pointer:null,tabbarHover:null,draggingTabElement:null}),startTab:(t,e)=>({phase:{kind:"tab",startX:e.payload.x,startY:e.payload.y,fromGroupId:e.payload.groupId,tabId:e.payload.tabId,cache:e.payload.cache},suggest:null,pointer:null,tabbarHover:null,draggingTabElement:e.payload.element}),setSuggest:(t,e)=>({...t,suggest:e.payload}),setPointer:(t,e)=>({...t,pointer:e.payload}),setTabbarHover:(t,e)=>({...t,tabbarHover:e.payload}),reset:()=>ht}),Qt=(t,e)=>{const n=Jt[e.type];return n?n(t,e,void 0):t},mt=u.createContext(null),K=()=>{const t=u.useContext(mt);if(!t)throw new Error("usePanelInteractions must be used within InteractionsProvider");return t},te=({containerRef:t,dragThresholdPx:e,onCommitContentDrop:n,onCommitTabDrop:r,isContentZoneAllowed:o,children:s})=>{const[a,i]=u.useReducer(Qt,ht),c=ft(),d=u.useCallback(()=>{const w=Array.from(c.getAll().entries()),y=w.map(([f,S])=>({gid:f,el:S.content??S.group})).filter(f=>!!f.el).map(f=>({...f,rect:f.el.getBoundingClientRect()})),m=w.map(([f,S])=>({gid:f,el:S.tabbar})).filter(f=>!!f.el).map(f=>({...f,rect:f.el.getBoundingClientRect()})),x=w.map(([f,S])=>({gid:f,el:S.content??S.group})).filter(f=>!!f.el).map(f=>({...f,rect:f.el.getBoundingClientRect()}));return{groups:y,tabbars:m,contents:x}},[c]),l=E.useEffectEvent(w=>{if(!t.current)return;const m=w.clientX,x=w.clientY,f=a.phase;if(f.kind==="idle")return;const S=Math.abs(m-f.startX),C=Math.abs(x-f.startY);if(S<e&&C<e){a.phase.kind==="content"&&i(A.setSuggest(null)),i(A.setPointer(null)),i(A.setTabbarHover(null));return}if(i(A.setPointer({x:m,y:x})),f.kind==="content"){const G=f.cache.groups.find(({rect:T})=>m>=T.left&&m<=T.right&&x>=T.top&&x<=T.bottom);if(!G){i(A.setSuggest(null));return}const D=q(G.rect,m,x);if(o&&!o({targetGroupId:G.gid,zone:D})){i(A.setSuggest(null));return}i(A.setSuggest({rect:G.rect,zone:D}));return}if(f.kind==="tab"){const G=f.cache.tabbars.find(({rect:R})=>m>=R.left&&m<=R.right&&x>=R.top&&x<=R.bottom);if(G){const _=Array.from(G.el.querySelectorAll("[role='tab']")).map(H=>H.getBoundingClientRect()),j=_.map(H=>H.left+H.width/2),O=j.findIndex(H=>m<H),N=O===-1?j.length:O,Ct=_.length===0?G.rect.left+8:N===0?_[0].left:N===_.length?_[_.length-1].right:(_[N-1].right+_[N].left)/2;i(A.setTabbarHover({groupId:G.gid,index:N,rect:G.rect,insertX:Ct}))}else i(A.setTabbarHover(null));const D=f.cache.contents.find(({rect:R})=>m>=R.left&&m<=R.right&&x>=R.top&&x<=R.bottom);if(!D){i(A.setSuggest(null));return}const T=q(D.rect,m,x);if(o&&!o({targetGroupId:D.gid,zone:T})){i(A.setSuggest(null));return}i(A.setSuggest({rect:D.rect,zone:T}))}}),p=E.useEffectEvent(w=>{const y=t.current,m=a;if(i(A.reset()),!y)return;const x=w.clientX,f=w.clientY;if(m.phase.kind==="idle")return;const S=Math.abs(x-m.phase.startX),C=Math.abs(f-m.phase.startY);if(!(S<e&&C<e)){if(m.phase.kind==="content"){const G=m.phase.cache.groups.find(({rect:R})=>x>=R.left&&x<=R.right&&f>=R.top&&f<=R.bottom);if(!G)return;const D=G.gid??null;if(!D)return;const T=q(G.rect,x,f);if(o&&!o({targetGroupId:D,zone:T}))return;n({fromGroupId:m.phase.fromGroupId,tabId:m.phase.tabId,targetGroupId:D,zone:T});return}if(m.phase.kind==="tab"){const G=m.phase.cache.tabbars.find(({rect:T})=>x>=T.left&&x<=T.right&&f>=T.top&&f<=T.bottom);if(G){const T=G.gid;if(!T)return;const _=Array.from(G.el.querySelectorAll("[role='tab']")).map(N=>{const Z=N.getBoundingClientRect();return Z.left+Z.width/2}),j=_.findIndex(N=>x<N),O=j===-1?_.length:j;r({fromGroupId:m.phase.fromGroupId,tabId:m.phase.tabId,targetGroupId:T,targetIndex:O});return}const D=m.phase.cache.contents.find(({rect:T})=>x>=T.left&&x<=T.right&&f>=T.top&&f<=T.bottom);if(D){const T=D.gid??null;if(!T)return;const R=q(D.rect,x,f);if(o&&!o({targetGroupId:T,zone:R}))return;n({fromGroupId:m.phase.fromGroupId,tabId:m.phase.tabId,targetGroupId:T,zone:R})}}}}),g=E.useEffectEvent(()=>{i(A.reset())});u.useEffect(()=>{if(a.phase.kind!=="idle")return window.addEventListener("pointermove",l),window.addEventListener("pointerup",p,{once:!0}),window.addEventListener("pointercancel",g,{once:!0}),()=>{window.removeEventListener("pointermove",l),window.removeEventListener("pointerup",p),window.removeEventListener("pointercancel",g)}},[a.phase.kind]);const v=u.useCallback((w,y,m)=>{if(m.button!==0)return;m.currentTarget.setPointerCapture(m.pointerId);const x=d();i(A.startContent({x:m.clientX,y:m.clientY,groupId:w,tabId:y,cache:x}))},[d]),b=u.useCallback((w,y,m)=>{if(m.button!==0)return;const x=m.currentTarget;x&&x.setPointerCapture(m.pointerId);const f=d();i(A.startTab({x:m.clientX,y:m.clientY,groupId:y,tabId:w,cache:f,element:x}))},[d]),I=u.useMemo(()=>({suggest:a.suggest,isTabDragging:a.phase.kind==="tab",draggingTabId:a.phase.kind==="tab"?a.phase.tabId:null,dragPointer:a.pointer,tabbarHover:a.tabbarHover,draggingTabElement:a.draggingTabElement,onStartContentDrag:v,onStartTabDrag:b}),[a.suggest,a.pointer,a.tabbarHover,a.phase,a.draggingTabElement,v,b]);return h.jsx(mt.Provider,{value:I,children:s})},ot={display:"inline-flex",alignItems:"center",userSelect:"none"},ee=({groupId:t,tab:e,active:n,dragging:r,onClickTab:o,onStartDrag:s,onCloseTab:a,tabComponent:i,tabElement:c,onDoubleClick:d})=>{const l=u.useEffectEvent(()=>{o(e.id)}),p=u.useEffectEvent(I=>{s&&I.button===0&&s(e.id,t,I)}),g=()=>{const I=!!a;return h.jsx(u.Activity,{mode:I?"visible":"hidden",children:h.jsx("button",{type:"button","aria-label":`Close tab ${e.title}`,onClick:w=>{a&&(w.stopPropagation(),a(t,e.id))},style:{marginLeft:6},tabIndex:I?void 0:-1,disabled:!I,"aria-hidden":I?void 0:!0,children:"×"})})},v={role:"tab","aria-selected":n,tabIndex:n?0:-1,style:ot,onClick:l,onPointerDown:p,onDoubleClick:d,"data-tab-id":e.id,"data-active":n?"true":"false","data-dragging":r?"true":"false",children:h.jsxs(h.Fragment,{children:[h.jsx("span",{children:e.title}),g()]})},b={type:"button",role:"tab","aria-selected":n,tabIndex:n?0:-1,style:ot,onClick:()=>{o(e.id)},onPointerDown:I=>{s&&I.button===0&&s(e.id,t,I)},onDoubleClick:d,children:h.jsx("span",{children:e.title})};return c?c(b):i?h.jsx(i,{...b}):h.jsx("div",{...v})},ne={display:"flex",alignItems:"center"},re={flex:"1 1 auto",alignSelf:"stretch"},oe=({group:t,onClickTab:e,onStartDrag:n,rootRef:r,component:o,element:s,tabComponent:a,tabElement:i,onAddTab:c,onCloseTab:d,doubleClickToAdd:l})=>{const{isTabDragging:p,draggingTabId:g}=K(),v=u.useRef(null),b=u.useCallback(f=>{if(v.current=f,!!r){if(typeof r=="function"){r(f);return}try{r.current=f}catch{}}},[r]),I=u.useEffectEvent(f=>{const S=v.current??f.currentTarget;if(!S)return;const C=Array.from(S.querySelectorAll('[role="tab"]'));if(C.length===0)return;const G=j=>{const O=Math.max(0,Math.min(j,C.length-1)),N=C[O];N&&N.focus()},D=document.activeElement,T=D?C.indexOf(D):C.findIndex(j=>j.getAttribute("data-tab-id")===t.activeTabId);if(f.key==="ArrowRight"){f.preventDefault();const j=T>=0?T+1:0;G(j>=C.length?0:j);return}if(f.key==="ArrowLeft"){f.preventDefault();const j=T>=0?T-1:C.length-1;G(j<0?C.length-1:j);return}if(f.key==="Home"){f.preventDefault(),G(0);return}if(f.key==="End"){f.preventDefault(),G(C.length-1);return}if(f.key==="Enter"||f.key===" "){f.preventDefault();const O=(T>=0?C[T]:null)?.getAttribute("data-tab-id")??null;O&&e(O);return}if(f.key==="Delete"||f.key==="Backspace"){if(d){f.preventDefault();const O=(T>=0?C[T]:null)?.getAttribute("data-tab-id")??null;O&&d(t.id,O)}return}const R=(f.ctrlKey?1:0)+(f.metaKey?1:0)>0,_=typeof f.key=="string"?f.key.toLowerCase():"";if(R&&_==="t"){c&&(f.preventDefault(),c(t.id));return}});u.useEffect(()=>{const f=v.current;if(!f)return;const S=f.querySelector(`[role="tab"][data-tab-id="${t.activeTabId}"]`);if(S===document.activeElement)return;!f.contains(document.activeElement)&&S&&S.focus()},[t.activeTabId]);const w={style:ne,role:"tablist","data-tabbar":"true","data-group-id":t.id,"data-dragging":p?"true":"false",onKeyDown:I},y=E.useElementComponentWrapper({element:s,component:o}),m=()=>c?h.jsx("button",{type:"button","aria-label":"Add tab",onClick:()=>{c(t.id)},children:"+"}):null,x=u.useCallback(()=>{l&&c&&c(t.id)},[l,c,t.id]);return h.jsxs(y,{...w,ref:b,onDoubleClick:x,children:[t.tabs.map((f,S)=>h.jsx(ee,{groupId:t.id,tab:f,active:t.activeTabId===f.id,dragging:g===f.id,onClickTab:e,onStartDrag:n,onCloseTab:d,tabComponent:a,tabElement:i,onDoubleClick:C=>C.stopPropagation()},`${t.id}:${f.id}:${S}`)),h.jsx("span",{style:re}),m()]})},se=({id:t,TabBarComponent:e,PanelGroupComponent:n})=>{const{getGroup:r,getGroupContent:o,onClickTab:s,onAddTab:a,onCloseTab:i,onStartTabDrag:c,doubleClickToAdd:d,registerContentContainer:l}=Ft(),{setGroupEl:p,setTabbarEl:g,setContentEl:v}=ft(),b=u.useCallback(S=>{p(t,S)},[t,p]),I=u.useCallback(S=>{v(t,S),l(t,S)},[t,v,l]),w=u.useCallback(S=>{g(t,S)},[t,g]),y=r(t);if(!y)return null;const m=o(t),x=e??oe,f=n??(S=>h.jsx(gt,{...S}));return h.jsx(f,{group:y,tabbar:h.jsx(x,{rootRef:w,group:y,onClickTab:S=>s(t,S),onAddTab:a,onCloseTab:i,onStartDrag:(S,C,G)=>c(S,C,G),doubleClickToAdd:d}),content:m,groupRef:b,contentRef:I})},ie=(t,e)=>{const n=new Array(16);for(let r=0;r<4;r++)for(let o=0;o<4;o++)n[r*4+o]=t[0+o]*e[r*4+0]+t[4+o]*e[r*4+1]+t[8+o]*e[r*4+2]+t[12+o]*e[r*4+3];return n},U=t=>{if(t.length!==16)throw new Error("Matrix must have exactly 16 values");const e=Object.freeze([...t]),n=r=>{const o=ie(e,r);return U(o)};return Object.freeze({translate:(r=0,o=0,s=0)=>n([1,0,0,0,0,1,0,0,0,0,1,0,r,o,s,1]),translate3d:(r,o,s)=>n([1,0,0,0,0,1,0,0,0,0,1,0,r,o,s,1]),translateX:r=>n([1,0,0,0,0,1,0,0,0,0,1,0,r,0,0,1]),translateY:r=>n([1,0,0,0,0,1,0,0,0,0,1,0,0,r,0,1]),translateZ:r=>n([1,0,0,0,0,1,0,0,0,0,1,0,0,0,r,1]),scale:(r=1,o=1,s=1)=>n([r,0,0,0,0,o,0,0,0,0,s,0,0,0,0,1]),scale3d:(r,o,s)=>n([r,0,0,0,0,o,0,0,0,0,s,0,0,0,0,1]),scaleX:r=>n([r,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),scaleY:r=>n([1,0,0,0,0,r,0,0,0,0,1,0,0,0,0,1]),scaleZ:r=>n([1,0,0,0,0,1,0,0,0,0,r,0,0,0,0,1]),rotateX:r=>{const o=Math.cos(r),s=Math.sin(r);return n([1,0,0,0,0,o,s,0,0,-s,o,0,0,0,0,1])},rotateY:r=>{const o=Math.cos(r),s=Math.sin(r);return n([o,0,-s,0,0,1,0,0,s,0,o,0,0,0,0,1])},rotateZ:r=>{const o=Math.cos(r),s=Math.sin(r);return n([o,s,0,0,-s,o,0,0,0,0,1,0,0,0,0,1])},rotate:(r,o,s,a)=>{const i=Math.sqrt(o*o+s*s+a*a);if(i===0)return U(e);o/=i,s/=i,a/=i;const c=Math.cos(r),d=Math.sin(r),l=1-c;return n([l*o*o+c,l*o*s+d*a,l*o*a-d*s,0,l*o*s-d*a,l*s*s+c,l*s*a+d*o,0,l*o*a+d*s,l*s*a-d*o,l*a*a+c,0,0,0,0,1])},rotate3d:(r,o,s,a)=>{const i=Math.sqrt(r*r+o*o+s*s);if(i===0)return U(e);r/=i,o/=i,s/=i;const c=Math.cos(a),d=Math.sin(a),l=1-c;return n([l*r*r+c,l*r*o+d*s,l*r*s-d*o,0,l*r*o-d*s,l*o*o+c,l*o*s+d*r,0,l*r*s+d*o,l*o*s-d*r,l*s*s+c,0,0,0,0,1])},skew:(r=0,o=0)=>{const s=Math.tan(r),a=Math.tan(o);return n([1,a,0,0,s,1,0,0,0,0,1,0,0,0,0,1])},skewX:r=>{const o=Math.tan(r);return n([1,0,0,0,o,1,0,0,0,0,1,0,0,0,0,1])},skewY:r=>{const o=Math.tan(r);return n([1,o,0,0,0,1,0,0,0,0,1,0,0,0,0,1])},perspective:r=>{if(r===0)throw new Error("Perspective distance cannot be zero");return n([1,0,0,0,0,1,0,0,0,0,1,-1/r,0,0,0,1])},toCSS:()=>`matrix3d(${e.join(", ")})`,toArray:()=>e,toString:()=>[`[${e[0]}, ${e[4]}, ${e[8]}, ${e[12]}]`,`[${e[1]}, ${e[5]}, ${e[9]}, ${e[13]}]`,`[${e[2]}, ${e[6]}, ${e[10]}, ${e[14]}]`,`[${e[3]}, ${e[7]}, ${e[11]}, ${e[15]}]`].join(`
2
- `)})},ae=()=>U([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),ce={position:"fixed",inset:0,pointerEvents:"none",zIndex:P.DROP_SUGGEST_Z_INDEX},ue={position:"absolute",border:`${P.DROP_SUGGEST_BORDER_WIDTH} dashed ${P.DROP_SUGGEST_BORDER_COLOR}`,background:P.DROP_SUGGEST_BG_COLOR,borderRadius:P.DROP_SUGGEST_BORDER_RADIUS,transformOrigin:"top left"},L=(t,e)=>e<=0?0:E.clampNumber(t/e,0),le=(t,e,n)=>{const{width:r,height:o}=t,s=n/2,a=r>0?r:1,i=o>0?o:1,c={translateX:n,translateY:n,scaleX:L(E.clampNumber(r-n*2,0),a),scaleY:L(E.clampNumber(o-n*2,0),i)},d={translateX:n,translateY:n,scaleX:L(E.clampNumber(r/2-n*1.5,0),a),scaleY:L(E.clampNumber(o-n*2,0),i)},l={translateX:r/2+s,translateY:n,scaleX:L(E.clampNumber(r/2-n*1.5,0),a),scaleY:L(E.clampNumber(o-n*2,0),i)},p={translateX:n,translateY:n,scaleX:L(E.clampNumber(r-n*2,0),a),scaleY:L(E.clampNumber(o/2-n*1.5,0),i)},g={translateX:n,translateY:o/2+s,scaleX:L(E.clampNumber(r-n*2,0),a),scaleY:L(E.clampNumber(o/2-n*1.5,0),i)},v={center:c,left:d,right:l,top:p,bottom:g},{translateX:b,translateY:I,scaleX:w,scaleY:y}=v[e];return ae().translate(b,I,0).scale(w,y,1).toCSS()},de=(t,e)=>{const n=P.DROP_SUGGEST_PADDING_PX;return{...ue,left:t.left,top:t.top,width:t.width,height:t.height,transform:le(t,e,n)}},pe=({suggest:t})=>{if(!t)return null;const{rect:e,zone:n}=t,r=de(e,n);return h.jsx("div",{style:ce,children:h.jsx("div",{style:r})})},fe=typeof window<"u"&&typeof document<"u",ge=t=>{const[e,n]=u.useState(null),[r,o]=u.useState(null);return tt.useIsomorphicLayoutEffect(()=>{if(!fe||!t){n(null),o(null);return}const s=t.getBoundingClientRect();n({width:s.width,height:s.height}),o(t.outerHTML)},[t]),{html:r,size:e}},be={position:"fixed",inset:0,pointerEvents:"none",zIndex:P.TAB_DRAG_OVERLAY_Z_INDEX},he={position:"absolute",width:P.TAB_DRAG_INSERT_GUIDE_WIDTH,borderRadius:P.TAB_DRAG_INSERT_GUIDE_BORDER_RADIUS,background:P.TAB_DRAG_INSERT_GUIDE_COLOR,boxShadow:P.TAB_DRAG_INSERT_GUIDE_SHADOW},me=()=>{const{isTabDragging:t,draggingTabId:e,dragPointer:n,tabbarHover:r,draggingTabElement:o}=K(),{html:s,size:a}=ge(o),i=n!==null&&e!==null,c=u.useMemo(()=>{if(!(!i||!n))return{position:"absolute",left:n.x,top:n.y,transform:`translate(${P.TAB_DRAG_PREVIEW_OFFSET_X}, ${P.TAB_DRAG_PREVIEW_OFFSET_Y})`,pointerEvents:"none"}},[i,n]),d=u.useMemo(()=>{if(!(!c||!o))return a?{...c,width:a.width,height:a.height}:c},[c,o,a]),l=u.useMemo(()=>{if(r)return{...he,left:r.insertX,top:r.rect.top+4,height:Math.max(0,r.rect.height-8)}},[r]);return t?h.jsxs("div",{style:be,children:[h.jsx(u.Activity,{mode:d?"visible":"hidden",children:h.jsx("div",{style:d,children:h.jsx("div",{style:{width:"100%",height:"100%",pointerEvents:"none"},dangerouslySetInnerHTML:{__html:s??""}})})}),h.jsx(u.Activity,{mode:l?"visible":"hidden",children:h.jsx("div",{style:l})})]}):null},M=t=>t.type==="group",X=(t,e=[])=>{if(M(t))return[...e,t.groupId];const n=X(t.a,e);return X(t.b,n)},W=(t,e)=>e.reduce((n,r)=>M(n)?n:n[r],t),Y=(t,e,n)=>{if(e.length===0)return n;const[r,...o]=e;return M(t)?t:r==="a"?{...t,a:Y(t.a,o,n)}:{...t,b:Y(t.b,o,n)}},V=(t,e,n=[])=>{if(M(t))return t.groupId===e?{splitPath:null,side:null}:null;if(M(t.a)&&t.a.groupId===e)return{splitPath:n,side:"a"};if(M(t.b)&&t.b.groupId===e)return{splitPath:n,side:"b"};const r=V(t.a,e,[...n,"a"]);return r||V(t.b,e,[...n,"b"])},vt=(t,e,n,r)=>{const o=r(),s=V(t,e),a={type:"split",direction:n,ratio:.5,a:{type:"group",groupId:e},b:{type:"group",groupId:o}};if(!s||s.splitPath===null)return{tree:a,newGroupId:o};const i=s.splitPath,c=W(t,i);if(M(c))return{tree:a,newGroupId:o};const d=s.side==="a"?{...c,a}:{...c,b:a};return{tree:Y(t,i,d),newGroupId:o}},ve=(t,e)=>{const n=V(t,e);if(!n||n.splitPath===null)return{tree:t,survivorGroupId:e};const r=n.splitPath,o=W(t,r);if(M(o))return{tree:t,survivorGroupId:e};const s=n.side==="a"?o.b:o.a,a=Y(t,r,s),i=M(s)?s.groupId:X(s)[0]??null;return{tree:a,survivorGroupId:i}},Ie=(t,e,n)=>{const r=W(t,e);if(M(r))return t;const o={...r,ratio:E.clampNumber(n,.05,.95)};return Y(t,e,o)},J=t=>{if(Object.keys(t.groups).filter(o=>t.groups[o].tabIds.length===0).length===0)return t;const r=(o,s)=>{const a=o.groups[s];if(!a||a.tabs.length>0||Object.keys(o.groups).length<=1)return o;const{tree:c,survivorGroupId:d}=ve(o.tree,s),{[s]:l,...p}=o.groups,g=X(c),v=o.focusedGroupId===s?d??g[0]??null:o.focusedGroupId;return{...o,tree:c,groups:p,groupOrder:g,focusedGroupId:v}};return t.groupOrder.reduce((o,s)=>r(o,s),t)},we=t=>({id:t,tabIds:[],tabs:[],activeTabId:null}),st=(t,e,n,r)=>{const o={...t.groups},s=o[e];if(!s)throw new Error(`Group ${e} does not exist.`);const a={...t.panels,[n.id]:n},i=[...s.tabIds,n.id],c=r?n.id:s.activeTabId??n.id,d=i.map(p=>a[p]),l={...s,tabIds:i,tabs:d,activeTabId:c};return o[e]=l,{...t,panels:a,groups:o}},xe=(t,e,n)=>{const r={...t.groups},o=r[e];if(!o)throw new Error(`Group ${e} does not exist.`);const s=o.tabIds.filter(c=>c!==n),a=s.map(c=>t.panels[c]),i=o.activeTabId===n?s[0]??null:o.activeTabId;return r[e]={...o,tabIds:s,tabs:a,activeTabId:i},{...t,groups:r}},it=(t,e,n,r,o)=>{const s=t.groups[e],a=t.groups[n];if(!s||!a)throw new Error("moveTab: source or target group is missing.");const i={...t.groups},c=s.tabIds.filter(p=>p!==r),d=[...a.tabIds.filter(p=>p!==r),r],l=s.activeTabId===r?c[0]??null:s.activeTabId;return i[e]={...s,tabIds:c,tabs:c.map(p=>t.panels[p]),activeTabId:l},i[n]={...a,tabIds:d,tabs:d.map(p=>t.panels[p]),activeTabId:r},{...t,groups:i}},It=(t,e,n)=>{const r=t.groups[e];if(!r)throw new Error(`setActiveTab: group ${e} not found.`);if(!r.tabIds.some(s=>s===n))throw new Error(`setActiveTab: tab ${n} not found in group ${e}.`);const o={...t.groups,[e]:{...r,activeTabId:n}};return{...t,groups:o,focusedGroupId:e}},at=(t,e,n,r,o)=>{const s=t.groups[e];if(!s)throw new Error(`addTabToGroupAtIndex: group ${e} not found.`);const a={...t.panels,[n.id]:n},i=s.tabIds.slice(),c=Math.max(0,Math.min(r,i.length));i.splice(c,0,n.id);const d=i.map(g=>a[g]),l=o?n.id:s.activeTabId??n.id,p={...t.groups,[e]:{...s,tabIds:i,tabs:d,activeTabId:l}};return{...t,panels:a,groups:p}},B=(t,e)=>{if(!t.groups[e])throw new Error(`setFocusedGroup: group ${e} not found.`);return{...t,focusedGroupId:e}},ye=(t,e)=>{const n=e-1,r=t.groupOrder[n];return r?B(t,r):t},Se=t=>{const e=t.groupOrder,n=t.focusedGroupId;if(!n){const s=e[0];return s?B(t,s):t}const r=e.indexOf(n),o=e[(r+1)%e.length];return B(t,o)},Te=t=>{const e=t.groupOrder,n=t.focusedGroupId;if(!n){const s=e[e.length-1];return s?B(t,s):t}const r=e.indexOf(n),o=e[(r-1+e.length)%e.length];return B(t,o)},wt=(t,e,n,r)=>{const{tree:o,newGroupId:s}=vt(t.tree,e,n,r),a={...t.groups,[s]:we(s)},i=X(o);return{...t,tree:o,groups:a,groupOrder:i,focusedGroupId:s}},Ee=t=>{const n={type:"group",groupId:"g_1"},r=Object.fromEntries(t.map(i=>[i.id,i])),s={g_1:{id:"g_1",tabIds:t.map(i=>i.id),tabs:t,activeTabId:t[0]?.id??null}};return{tree:n,panels:r,groups:s,groupOrder:["g_1"],focusedGroupId:"g_1"}},Ge=u.createContext(null),Ce=({value:t,children:e})=>h.jsx(Ge.Provider,{value:t,children:e}),xt=u.createContext(null),Re=()=>{const t=u.useContext(xt);if(!t)throw new Error("useTree must be used within TreeProvider");return t},Pe=({value:t,children:e})=>h.jsx(xt.Provider,{value:t,children:e}),De=u.createContext(null),je=({value:t,children:e})=>h.jsx(De.Provider,{value:t,children:e}),$=t=>{const e=E.toFiniteNumberOr(t,Number.POSITIVE_INFINITY);return E.clampNumber(e,1)},Ae=t=>typeof t=="object"&&t!==null,ke=t=>Ae(t)?"rows"in t?!0:"cols"in t:!1,yt=t=>{if(!t)return{rows:Number.POSITIVE_INFINITY,cols:Number.POSITIVE_INFINITY};if(typeof t=="number"){const n=$(t);return{rows:n,cols:n}}if(ke(t))return{rows:$(t.rows),cols:$(t.cols)};const e=t;return{rows:$(e.maxHorizontal),cols:$(e.maxVertical)}},Q=t=>{if(M(t))return{horizontal:1,vertical:1};const e=Q(t.a),n=Q(t.b);return t.direction==="horizontal"?{horizontal:e.horizontal+n.horizontal,vertical:Math.max(e.vertical,n.vertical)}:{horizontal:Math.max(e.horizontal,n.horizontal),vertical:e.vertical+n.vertical}},_e=(t,e,n)=>{const{tree:r}=vt(t,e,n,()=>"__preview__");return r},et=(t,e,n,r)=>{if(!Number.isFinite(r.rows)&&!Number.isFinite(r.cols))return!0;const o=_e(t,e,n),s=Q(o);return!(s.horizontal>r.rows||s.vertical>r.cols)},St={splitFocused:k("panelState/splitFocused",t=>({direction:t})),focusGroupIndex:k("panelState/focusGroupIndex",t=>({index1Based:t})),focusNextGroup:k("panelState/focusNextGroup"),focusPrevGroup:k("panelState/focusPrevGroup"),setActiveTab:k("panelState/setActiveTab",(t,e)=>({groupId:t,tabId:e})),addTab:k("panelState/addTab",t=>t),addNewTab:k("panelState/addNewTab",t=>t),removeTab:k("panelState/removeTab",(t,e)=>({groupId:t,tabId:e})),contentDrop:k("panelState/contentDrop",t=>t),tabDrop:k("panelState/tabDrop",t=>t),adjustSplitRatio:k("panelState/adjustSplitRatio",t=>t)},Me=(t,e,n)=>{const r=t.groups[e.fromGroupId],o=t.groups[e.targetGroupId];if(!r||!o||!r.tabs.find(p=>p.id===e.tabId))return t;if(e.zone==="center"&&e.fromGroupId===e.targetGroupId)return It(t,e.fromGroupId,e.tabId);if(e.zone==="center"){const p=it(t,e.fromGroupId,e.targetGroupId,e.tabId);return B(p,e.targetGroupId)}const a=e.zone==="left"||e.zone==="right"?"vertical":"horizontal";if(!et(t.tree,e.targetGroupId,a,n.splitLimits))return t;const i=n.createGroupId(),c=wt(t,e.targetGroupId,a,()=>i),d=e.zone==="left"||e.zone==="top"?e.targetGroupId:i,l=it(c,e.fromGroupId,d,e.tabId);return B(l,d)},Oe=(t,e)=>{const n=t.groups[e.fromGroupId],r=t.groups[e.targetGroupId];if(!n||!r||!t.panels[e.tabId])return t;if(e.fromGroupId===e.targetGroupId){const g=n.tabIds.filter(y=>y!==e.tabId),v=Math.max(0,Math.min(e.targetIndex,g.length)),b=g.slice(0,v).concat([e.tabId],g.slice(v)),I=b.map(y=>t.panels[y]).filter(Boolean),w={...t.groups,[e.fromGroupId]:{...n,tabIds:b,tabs:I}};return{...t,groups:w}}const s={...t.groups},a=n.tabIds.filter(g=>g!==e.tabId),i=a.map(g=>t.panels[g]);s[e.fromGroupId]={...n,tabIds:a,tabs:i,activeTabId:n.activeTabId===e.tabId?i[0]?.id??null:n.activeTabId};const c=r.tabIds.filter(g=>g!==e.tabId),d=Math.max(0,Math.min(e.targetIndex,c.length)),l=c.slice(0,d).concat([e.tabId],c.slice(d)),p=l.map(g=>t.panels[g]).filter(Boolean);return s[e.targetGroupId]={...r,tabIds:l,tabs:p,activeTabId:e.tabId},{...t,groups:s,focusedGroupId:e.targetGroupId}},Ne=bt(St,{splitFocused:(t,e,n)=>{const r=t.focusedGroupId??t.groupOrder[0]??null;return!r||!et(t.tree,r,e.payload.direction,n.splitLimits)?t:wt(t,r,e.payload.direction,n.createGroupId)},focusGroupIndex:(t,e)=>ye(t,e.payload.index1Based),focusNextGroup:t=>Se(t),focusPrevGroup:t=>Te(t),setActiveTab:(t,e)=>It(t,e.payload.groupId,e.payload.tabId),addTab:(t,e)=>{const{groupId:n,tab:r,index:o,makeActive:s}=e.payload;return typeof o=="number"?at(t,n,r,o,s??!0):st(t,n,r,s??!0)},addNewTab:(t,e,n)=>{if(!n.createPanelId)throw new Error("addNewTab requires PanelSystemProvider.createPanelId");const o={id:n.createPanelId(),title:e.payload.title,render:()=>e.payload.title},{groupId:s,index:a,makeActive:i}=e.payload;return typeof a=="number"?at(t,s,o,a,i??!0):st(t,s,o,i??!0)},removeTab:(t,e)=>xe(t,e.payload.groupId,e.payload.tabId),contentDrop:(t,e,n)=>Me(t,e.payload,n),tabDrop:(t,e)=>Oe(t,e.payload),adjustSplitRatio:(t,e)=>{const n=W(t.tree,e.payload.path);if(M(n))return t;const r=Ie(t.tree,e.payload.path,n.ratio+e.payload.deltaRatio);return{...t,tree:r}}}),ct=(t,e,n)=>{const r=Ne[e.type];if(!r)return t;const o=r(t,e,n);return J(o)},Tt=u.createContext(null),z=()=>{const t=u.useContext(Tt);if(!t)throw new Error("usePanelSystem must be used within PanelSystemProvider");return t},Le=({initialState:t,createGroupId:e,createPanelId:n,state:r,onStateChange:o,splitLimits:s,children:a})=>{const i=u.useMemo(()=>J(t),[t]),c=u.useMemo(()=>yt(s),[s]),d=u.useRef({createGroupId:e,splitLimits:c,createPanelId:n});d.current.createGroupId=e,d.current.splitLimits=c,d.current.createPanelId=n;const[l,p]=u.useReducer((S,C)=>ct(S,C,d.current),i),g=u.useMemo(()=>r?J(r):l,[r,l]),v=u.useRef(g);v.current=g;const b=r!==void 0,I=u.useCallback(S=>{if(b){const C=ct(v.current,S,d.current);o?.(C);return}p(S)},[b,o,p]),w=u.useMemo(()=>Zt(St,I),[I]),y=u.useMemo(()=>({setActiveTab:w.setActiveTab,tabDrop:w.tabDrop}),[w]),m=u.useMemo(()=>({adjustSplitRatio:w.adjustSplitRatio}),[w]),x=u.useMemo(()=>({focusGroupIndex:w.focusGroupIndex,focusNextGroup:w.focusNextGroup,focusPrevGroup:w.focusPrevGroup}),[w]),f=u.useMemo(()=>({state:g,dispatch:I,actions:w}),[g,I,w]);return h.jsx(Tt.Provider,{value:f,children:h.jsx(Ce,{value:y,children:h.jsx(Pe,{value:m,children:h.jsx(je,{value:x,children:a})})})})},Be=()=>{const{actions:t}=z();return u.useMemo(()=>({splitFocused:e=>{t.splitFocused(e)},focusGroupIndex:e=>{t.focusGroupIndex(e)},focusNextGroup:()=>{t.focusNextGroup()},focusPrevGroup:()=>{t.focusPrevGroup()},closeFocusedGroup:()=>{}}),[t])},He=()=>{const{actions:t}=z(),e=u.useCallback(({fromGroupId:r,tabId:o,targetGroupId:s,zone:a})=>{t.contentDrop({fromGroupId:r,tabId:o,targetGroupId:s,zone:a})},[t]),n=u.useCallback(({fromGroupId:r,tabId:o,targetGroupId:s,targetIndex:a})=>{t.tabDrop({fromGroupId:r,tabId:o,targetGroupId:s,targetIndex:a})},[t]);return{onCommitContentDrop:e,onCommitTabDrop:n}},ze=()=>{const t=Ot(),e=Be();return u.useEffect(()=>{Bt(t,e)},[t,e]),null},Et=u.createContext(null),$e=()=>{const t=u.useContext(Et);if(!t)throw new Error("useContentRegistry must be used within ContentRegistryProvider");return t},Fe=t=>{const e=document.createElement("div");return e.setAttribute("data-panel-wrapper",t),e.style.display="contents",e},Xe=(t,e,n)=>{const[r]=u.useState(()=>Fe(t));return tt.useIsomorphicLayoutEffect(()=>(r.style.display=n?"contents":"none",e&&r.parentElement!==e&&e.appendChild(r),()=>{r.parentElement?.removeChild(r)}),[r,e,n]),r},Gt=u.memo(({panelId:t,content:e,placement:n,containerElement:r})=>{const o=n?.isActive??!1,s=Xe(t,r,o);return Pt.createPortal(h.jsx(u.Activity,{mode:o?"visible":"hidden",children:e}),s)});Gt.displayName="PanelContentHost";const Ye=({children:t,panels:e,placements:n})=>{const[r,o]=u.useState(new Map),s=u.useCallback((g,v)=>{o(b=>{const I=new Map(b);return v?I.set(g,v):I.delete(g),I})},[]),a=u.useMemo(()=>({registerContentContainer:s}),[s]),i=u.useRef(e);i.current=e;const c=u.useCallback(g=>{const v=i.current[g];return v?v.render(v.id):null},[]),d=u.useMemo(()=>Object.keys(e),[e]),{getCachedContent:l}=Dt.useContentCache({resolveContent:c,validIds:d}),p=Object.keys(e);return h.jsxs(Et.Provider,{value:a,children:[t,p.map(g=>{if(!e[g])return null;const b=n[g]??null,I=b?r.get(b.groupId)??null:null,w=l(g);return h.jsx(Gt,{panelId:g,content:w,placement:b,containerElement:I},g)})]})},qe=({children:t,emptyContentComponent:e,doubleClickToAdd:n})=>{const r=K(),{state:o,actions:s}=z(),{registerContentContainer:a}=$e(),i=u.useCallback(()=>u.createElement("div",{style:{color:"#888",fontSize:12,padding:12}},"No tabs"),[]),c=e??i,d=u.useCallback(y=>{const m=o.groups[y];if(!m)return null;const x=m.tabIds.map(f=>o.panels[f]).filter(Boolean);return{...m,tabs:x}},[o.groups,o.panels]),l=u.useCallback(y=>{const m=o.groups[y];return!m||m.tabIds.length===0?h.jsx(c,{}):null},[o.groups,c]),p=u.useCallback((y,m)=>{s.setActiveTab(y,m)},[s]),g=u.useCallback(y=>{s.addNewTab({groupId:y,title:"New Tab",makeActive:!0})},[s]),v=u.useCallback((y,m)=>{s.removeTab(y,m)},[s]),b=u.useCallback((y,m,x)=>{s.setActiveTab(m,y),r.onStartTabDrag(y,m,x)},[s,r]),I=u.useCallback((y,m)=>{const x=o.groups[y];!x||!x.activeTabId||r.onStartContentDrag(y,x.activeTabId,m)},[o.groups,r]),w=u.useMemo(()=>({getGroup:d,getGroupContent:l,onClickTab:p,onAddTab:g,onCloseTab:v,onStartTabDrag:b,onStartContentDrag:I,doubleClickToAdd:n,registerContentContainer:a}),[d,l,p,g,v,b,I,n,a]);return h.jsx(Xt,{value:w,children:t})},Ue=({children:t,emptyContentComponent:e,doubleClickToAdd:n})=>{const{state:r}=z(),o=u.useMemo(()=>{const s={};for(const[a,i]of Object.entries(r.groups))for(const c of i.tabIds)s[c]={groupId:a,isActive:c===i.activeTabId};return s},[r.groups]);return h.jsx(Ye,{panels:r.panels,placements:o,children:h.jsx(qe,{emptyContentComponent:e,doubleClickToAdd:n,children:t})})},F=(t,e,n,r)=>{if(M(t))return r;const o=t.direction,s=o==="vertical"?n.x+n.w*t.ratio:n.y+n.h*t.ratio;if(r.push({path:e,direction:o,parentRect:n,linePos:s}),o==="vertical"){const c=n.w*t.ratio,d=n.w-c;return F(t.a,[...e,"a"],{x:n.x,y:n.y,w:c,h:n.h},r),F(t.b,[...e,"b"],{x:n.x+c,y:n.y,w:d,h:n.h},r),r}const a=n.h*t.ratio,i=n.h-a;return F(t.a,[...e,"a"],{x:n.x,y:n.y,w:n.w,h:a},r),F(t.b,[...e,"b"],{x:n.x,y:n.y+a,w:n.w,h:i},r),r},Ve=({containerRef:t})=>{const{state:e}=z(),{adjustSplitRatio:n}=Re(),r=u.useMemo(()=>F(e.tree,[],{x:0,y:0,w:100,h:100},[]),[e.tree]),[o,s]=u.useState(null);if(tt.useIsomorphicLayoutEffect(()=>{const i=t.current;if(!i)return;const c=()=>{const v=i.getBoundingClientRect();s({left:v.left,top:v.top,width:v.width,height:v.height})};c();function d(){try{const v=window.ResizeObserver;return typeof v=="function"?v:null}catch{return null}}const l=d(),p=l?new l(()=>c()):null;p&&p.observe(i);const g=()=>c();return window.addEventListener("scroll",g,!0),()=>{window.removeEventListener("scroll",g,!0),p&&p.disconnect()}},[t,e.tree]),!o)return null;const a=(i,c)=>{const d={left:o.left+o.width*i.parentRect.x/100,top:o.top+o.height*i.parentRect.y/100,width:o.width*i.parentRect.w/100,height:o.height*i.parentRect.h/100},l=P.SPLIT_HANDLE_THICKNESS;if(i.direction==="vertical"){const b=d.left+d.width*(i.linePos-i.parentRect.x)/i.parentRect.w,I={position:"fixed",left:`calc(${Math.round(b)}px - ${l} / 2)`,top:Math.round(d.top),width:l,height:Math.round(d.height),cursor:"col-resize",pointerEvents:"auto"},w=y=>{const m=o.width*i.parentRect.w/100,x=m===0?0:y/m;n({path:i.path,deltaRatio:x})};return h.jsx("div",{style:I,children:h.jsx(E.ResizeHandle,{direction:"vertical",onResize:w})},`split-${c}`)}const p=d.top+d.height*(i.linePos-i.parentRect.y)/i.parentRect.h,g={position:"fixed",left:Math.round(d.left),top:`calc(${Math.round(p)}px - ${l} / 2)`,width:Math.round(d.width),height:l,cursor:"row-resize",pointerEvents:"auto"},v=b=>{const I=o.height*i.parentRect.h/100,w=I===0?0:b/I;n({path:i.path,deltaRatio:w})};return h.jsx("div",{style:g,children:h.jsx(E.ResizeHandle,{direction:"horizontal",onResize:v})},`split-${c}`)};return h.jsx("div",{style:{position:"fixed",inset:0,pointerEvents:"none"},children:r.map((i,c)=>a(i,c))})},Ke={position:"relative",display:"flex",width:"100%",height:"100%"},We=({state:t,layoutMode:e,gridTracksInteractive:n,view:r,tabBarComponent:o,panelGroupComponent:s})=>{const a=c=>{if(r){const d=r;return h.jsx(d,{groupId:c})}return h.jsx(se,{id:c,TabBarComponent:o,PanelGroupComponent:s})};if(e==="grid"){const c=$t(t,a,!!n);return h.jsx(E.GridLayout,{config:c.config,layers:c.layers})}const i=zt(t,a);return h.jsx(E.GridLayout,{config:i.config,layers:i.layers})},Ze=({containerRef:t,layoutMode:e,gridTracksInteractive:n,dragThresholdPx:r,view:o,style:s,className:a,tabBarComponent:i,panelGroupComponent:c,splitLimits:d,emptyContentComponent:l,doubleClickToAdd:p})=>{const{state:g}=z(),{onCommitContentDrop:v,onCommitTabDrop:b}=He(),I=u.useMemo(()=>({...Ke,...s}),[s]),w=u.useCallback(({targetGroupId:y,zone:m})=>{if(m==="center")return!0;const x=m==="left"||m==="right"?"vertical":"horizontal";return et(g.tree,y,x,d)},[g.tree,d]);return h.jsx(Yt,{children:h.jsxs(te,{containerRef:t,dragThresholdPx:r,onCommitContentDrop:v,onCommitTabDrop:b,isContentZoneAllowed:w,children:[h.jsx(Ue,{emptyContentComponent:l,doubleClickToAdd:p,children:h.jsx("div",{ref:t,className:a,style:I,children:h.jsx(We,{state:g,layoutMode:e,gridTracksInteractive:n,view:o,tabBarComponent:i,panelGroupComponent:c})})}),h.jsx(Ve,{containerRef:t}),h.jsx(Je,{})]})})},Je=()=>{const t=K();return h.jsxs(h.Fragment,{children:[h.jsx(pe,{suggest:t.suggest}),h.jsx(me,{})]})},Qe=({initialState:t,createGroupId:e,createPanelId:n,layoutMode:r,gridTracksInteractive:o,dragThresholdPx:s,view:a,emptyContentComponent:i,state:c,onStateChange:d,className:l,style:p,tabBarComponent:g,panelGroupComponent:v,splitLimits:b,doubleClickToAdd:I})=>{if(!t)throw new Error("PanelSystem requires initialState.");if(!e)throw new Error("PanelSystem requires explicit createGroupId function.");if(!r)throw new Error("PanelSystem requires explicit layoutMode ('absolute' | 'grid').");if(r==="grid"&&o===void 0)throw new Error("PanelSystem(layoutMode='grid') requires explicit 'gridTracksInteractive' flag.");if(s===void 0)throw new Error("PanelSystem requires explicit 'dragThresholdPx' value.");const w=u.useRef(null),y=u.useMemo(()=>yt(b),[b]);return h.jsx(Le,{initialState:t,createGroupId:e,createPanelId:n,state:c,onStateChange:d,splitLimits:b,children:h.jsxs(Lt,{children:[h.jsx(ze,{}),h.jsx(Ze,{containerRef:w,layoutMode:r,gridTracksInteractive:o,dragThresholdPx:s,view:a,style:p,className:l,tabBarComponent:g,panelGroupComponent:v,splitLimits:y,emptyContentComponent:i,doubleClickToAdd:I})]})})};exports.Drawer=E.Drawer;exports.DrawerLayers=E.DrawerLayers;exports.FloatingWindow=E.FloatingWindow;exports.GridLayout=E.GridLayout;exports.ResizeHandle=E.ResizeHandle;exports.runTransition=E.runTransition;exports.useTransitionState=E.useTransitionState;exports.CSS_VAR_PREFIX=P.CSS_VAR_PREFIX;exports.HorizontalDivider=kt;exports.PanelSystem=Qe;exports.buildInitialState=Ee;exports.useFloatingState=Mt;exports.useLayerDragHandle=_t;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./GridLayout-DKTg_N61.cjs"),t=require("./FloatingWindow-DMwyK0eK.cjs"),s=require("./HorizontalDivider-_pgV4Mcv.cjs"),u=require("./ResizeHandle-CBcAS918.cjs"),l=require("react"),c=require("./useFloatingState-C4kRaW_R.cjs"),d=require("./styles-qf6ptVLD.cjs"),i=require("./PanelSystem-D603LKKv.cjs");function y(e){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const a=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(r,n,a.get?a:{enumerable:!0,get:()=>e[n]})}}return r.default=e,Object.freeze(r)}const S=y(l),g=()=>{const{layerId:e}=t.useLayerInstance(),{getLayerHandleProps:r}=t.useGridLayoutContext();return S.useMemo(()=>r(e),[r,e])};exports.GridLayout=o.GridLayout;exports.Drawer=t.Drawer;exports.DrawerLayers=t.DrawerLayers;exports.FloatingWindow=t.FloatingWindow;exports.runTransition=t.runTransition;exports.useTransitionState=t.useTransitionState;exports.HorizontalDivider=s.HorizontalDivider;exports.ResizeHandle=u.ResizeHandle;exports.useFloatingState=c.useFloatingState;exports.CSS_VAR_PREFIX=d.CSS_VAR_PREFIX;exports.PanelSystem=i.PanelSystem;exports.buildInitialState=i.buildInitialState;exports.useLayerDragHandle=g;
3
2
  //# sourceMappingURL=index.cjs.map