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.
- package/dist/{FloatingPanelFrame-lLg-Lpg7.js → FloatingPanelFrame-3eU9AwPo.js} +11 -11
- package/dist/{FloatingPanelFrame-lLg-Lpg7.js.map → FloatingPanelFrame-3eU9AwPo.js.map} +1 -1
- package/dist/{FloatingPanelFrame-D9Cp2al1.cjs → FloatingPanelFrame-CEmXDvUA.cjs} +2 -2
- package/dist/{FloatingPanelFrame-D9Cp2al1.cjs.map → FloatingPanelFrame-CEmXDvUA.cjs.map} +1 -1
- package/dist/FloatingWindow-CUXnEtrb.js +827 -0
- package/dist/FloatingWindow-CUXnEtrb.js.map +1 -0
- package/dist/FloatingWindow-DMwyK0eK.cjs +2 -0
- package/dist/FloatingWindow-DMwyK0eK.cjs.map +1 -0
- package/dist/GridLayout-DKTg_N61.cjs +2 -0
- package/dist/GridLayout-DKTg_N61.cjs.map +1 -0
- package/dist/GridLayout-UWNxXw77.js +926 -0
- package/dist/GridLayout-UWNxXw77.js.map +1 -0
- package/dist/HorizontalDivider-DdxzfV0l.js +30 -0
- package/dist/HorizontalDivider-DdxzfV0l.js.map +1 -0
- package/dist/HorizontalDivider-_pgV4Mcv.cjs +2 -0
- package/dist/HorizontalDivider-_pgV4Mcv.cjs.map +1 -0
- package/dist/PanelSystem-BqUzNtf2.js +1946 -0
- package/dist/PanelSystem-BqUzNtf2.js.map +1 -0
- package/dist/PanelSystem-D603LKKv.cjs +3 -0
- package/dist/PanelSystem-D603LKKv.cjs.map +1 -0
- package/dist/ResizeHandle-CBcAS918.cjs +2 -0
- package/dist/ResizeHandle-CBcAS918.cjs.map +1 -0
- package/dist/ResizeHandle-CXjc1meV.js +119 -0
- package/dist/ResizeHandle-CXjc1meV.js.map +1 -0
- package/dist/SwipePivotTabBar-DWrCuwEI.js +411 -0
- package/dist/SwipePivotTabBar-DWrCuwEI.js.map +1 -0
- package/dist/SwipePivotTabBar-fjjXkpj7.cjs +2 -0
- package/dist/SwipePivotTabBar-fjjXkpj7.cjs.map +1 -0
- package/dist/components/gesture/SwipeSafeZone.d.ts +40 -0
- package/dist/components/window/Drawer.d.ts +3 -1
- package/dist/components/window/DrawerLayers.d.ts +1 -1
- package/dist/components/window/drawerStyles.d.ts +69 -0
- package/dist/components/window/drawerSwipeConfig.d.ts +29 -0
- package/dist/components/window/useDrawerSwipeTransform.d.ts +23 -0
- package/dist/config.cjs +1 -1
- package/dist/config.cjs.map +1 -1
- package/dist/config.js +11 -9
- package/dist/config.js.map +1 -1
- package/dist/constants/styles.d.ts +35 -4
- package/dist/dialog/index.d.ts +69 -0
- package/dist/floating.cjs +1 -1
- package/dist/floating.js +1 -1
- package/dist/grid/index.d.ts +58 -0
- package/dist/grid.cjs +2 -0
- package/dist/grid.cjs.map +1 -0
- package/dist/grid.js +13 -0
- package/dist/grid.js.map +1 -0
- package/dist/hooks/gesture/presets.d.ts +33 -0
- package/dist/hooks/gesture/testing/createGestureSimulator.d.ts +117 -0
- package/dist/hooks/gesture/thresholdValue.d.ts +44 -0
- package/dist/hooks/gesture/types.d.ts +297 -0
- package/dist/hooks/gesture/useDirectionalLock.d.ts +20 -0
- package/dist/hooks/gesture/useEdgeSwipeInput.d.ts +23 -0
- package/dist/hooks/gesture/useNativeGestureGuard.d.ts +23 -0
- package/dist/hooks/gesture/usePointerTracking.d.ts +22 -0
- package/dist/hooks/gesture/useScrollBoundary.d.ts +23 -0
- package/dist/hooks/gesture/useSwipeInput.d.ts +5 -0
- package/dist/hooks/gesture/utils.d.ts +59 -0
- package/dist/hooks/useAnimatedVisibility.d.ts +58 -0
- package/dist/hooks/useAnimationFrame.d.ts +86 -0
- package/dist/hooks/useOperationContinuity.d.ts +64 -0
- package/dist/hooks/useResizeObserver.d.ts +33 -1
- package/dist/hooks/useSharedElementTransition.d.ts +112 -0
- package/dist/hooks/useSnapAnimation.d.ts +54 -0
- package/dist/hooks/useSwipeContentTransform.d.ts +86 -0
- package/dist/index.cjs +1 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +25 -2006
- package/dist/index.js.map +1 -1
- package/dist/modules/dialog/AlertDialog.d.ts +9 -0
- package/dist/modules/dialog/DialogContainer.d.ts +37 -0
- package/dist/modules/dialog/Modal.d.ts +26 -0
- package/dist/modules/dialog/SwipeDialogContainer.d.ts +16 -0
- package/dist/modules/dialog/dialogAnimationUtils.d.ts +113 -0
- package/dist/modules/dialog/types.d.ts +183 -0
- package/dist/modules/dialog/useDialog.d.ts +39 -0
- package/dist/modules/dialog/useDialogContainer.d.ts +47 -0
- package/dist/modules/dialog/useDialogSwipeInput.d.ts +70 -0
- package/dist/modules/dialog/useDialogTransform.d.ts +82 -0
- package/dist/modules/drawer/types.d.ts +74 -0
- package/dist/modules/drawer/useDrawerSwipeInput.d.ts +24 -0
- package/dist/modules/pivot/PivotContent.d.ts +1 -1
- package/dist/modules/pivot/SwipePivotContent.d.ts +39 -0
- package/dist/modules/pivot/SwipePivotContent.debug.tmp.d.ts +25 -0
- package/dist/modules/pivot/SwipePivotContent.test.d.ts +1 -0
- package/dist/modules/pivot/SwipePivotTabBar.d.ts +92 -0
- package/dist/modules/pivot/index.d.ts +3 -0
- package/dist/modules/pivot/scaleInputState.d.ts +37 -0
- package/dist/modules/pivot/types.d.ts +67 -2
- package/dist/modules/pivot/usePivotSwipeInput.d.ts +68 -0
- package/dist/modules/stack/StackContent.d.ts +15 -0
- package/dist/modules/stack/SwipeStackContent.d.ts +66 -0
- package/dist/modules/stack/SwipeStackOutlet.d.ts +80 -0
- package/dist/modules/stack/computeStackContentState.d.ts +99 -0
- package/dist/modules/stack/computeSwipeStackTransform.d.ts +76 -0
- package/dist/modules/stack/types.d.ts +194 -0
- package/dist/modules/stack/useStackAnimationState.d.ts +32 -0
- package/dist/modules/stack/useStackNavigation.d.ts +23 -0
- package/dist/modules/stack/useStackSwipeInput.d.ts +27 -0
- package/dist/panels/index.d.ts +67 -0
- package/dist/panels.cjs +2 -0
- package/dist/panels.cjs.map +1 -0
- package/dist/panels.js +28 -0
- package/dist/panels.js.map +1 -0
- package/dist/pivot/index.d.ts +3 -0
- package/dist/pivot.cjs +1 -1
- package/dist/pivot.cjs.map +1 -1
- package/dist/pivot.js +20 -2
- package/dist/pivot.js.map +1 -1
- package/dist/resizer/index.d.ts +57 -0
- package/dist/resizer.cjs +2 -0
- package/dist/resizer.cjs.map +1 -0
- package/dist/resizer.js +8 -0
- package/dist/resizer.js.map +1 -0
- package/dist/stack/index.d.ts +72 -0
- package/dist/stack.cjs +2 -0
- package/dist/stack.cjs.map +1 -0
- package/dist/stack.js +721 -0
- package/dist/stack.js.map +1 -0
- package/dist/sticky-header/StickyArea.d.ts +38 -0
- package/dist/sticky-header/calculateStickyMetrics.d.ts +28 -0
- package/dist/sticky-header/index.d.ts +4 -4
- package/dist/sticky-header/types.d.ts +35 -22
- package/dist/sticky-header.cjs +1 -1
- package/dist/sticky-header.cjs.map +1 -1
- package/dist/sticky-header.js +73 -174
- package/dist/sticky-header.js.map +1 -1
- package/dist/styles-NkjuMOVS.js +57 -0
- package/dist/styles-NkjuMOVS.js.map +1 -0
- package/dist/styles-qf6ptVLD.cjs +2 -0
- package/dist/styles-qf6ptVLD.cjs.map +1 -0
- package/dist/types.d.ts +16 -0
- package/dist/useContentCache-CO3LYNmz.js +24 -0
- package/dist/useContentCache-CO3LYNmz.js.map +1 -0
- package/dist/useContentCache-DqXtLrLs.cjs +2 -0
- package/dist/useContentCache-DqXtLrLs.cjs.map +1 -0
- package/dist/useDocumentPointerEvents-DXxw3qWj.js +54 -0
- package/dist/useDocumentPointerEvents-DXxw3qWj.js.map +1 -0
- package/dist/useDocumentPointerEvents-DxDSOtip.cjs +2 -0
- package/dist/useDocumentPointerEvents-DxDSOtip.cjs.map +1 -0
- package/dist/useFloatingState-C4kRaW_R.cjs +2 -0
- package/dist/useFloatingState-C4kRaW_R.cjs.map +1 -0
- package/dist/useFloatingState-tEfA_wbc.js +74 -0
- package/dist/useFloatingState-tEfA_wbc.js.map +1 -0
- package/dist/useNativeGestureGuard-C7TSqEkr.cjs +2 -0
- package/dist/useNativeGestureGuard-C7TSqEkr.cjs.map +1 -0
- package/dist/useNativeGestureGuard-CGYo6O0r.js +347 -0
- package/dist/useNativeGestureGuard-CGYo6O0r.js.map +1 -0
- package/dist/window/index.d.ts +63 -0
- package/dist/window.cjs +2 -0
- package/dist/window.cjs.map +1 -0
- package/dist/window.js +160 -0
- package/dist/window.js.map +1 -0
- package/docs/design-tokens.md +405 -0
- package/package.json +34 -4
- package/src/PanelSystemContext.tsx +88 -0
- package/src/components/gesture/SwipeSafeZone.tsx +69 -0
- package/src/components/grid/GridLayerList.tsx +172 -0
- package/src/components/grid/GridLayerResizeHandles.tsx +145 -0
- package/src/components/grid/GridLayout.spec.tsx +743 -0
- package/src/components/grid/GridLayout.tsx +130 -0
- package/src/components/grid/GridTrackResizeHandle.tsx +87 -0
- package/src/components/paneling/FloatingPanelFrame.tsx +203 -0
- package/src/components/panels/DropSuggestOverlay.tsx +131 -0
- package/src/components/panels/PanelGroupView.tsx +112 -0
- package/src/components/pivot/PivotLayer.tsx +27 -0
- package/src/components/resizer/HorizontalDivider.tsx +52 -0
- package/src/components/resizer/ResizeHandle.tsx +118 -0
- package/src/components/tabs/TabBar.tsx +223 -0
- package/src/components/tabs/TabBarTab.tsx +133 -0
- package/src/components/tabs/TabDragOverlay.tsx +92 -0
- package/src/components/window/DialogOverlay.tsx +180 -0
- package/src/components/window/Drawer.tsx +369 -0
- package/src/components/window/DrawerLayers.tsx +68 -0
- package/src/components/window/FloatingWindow.tsx +95 -0
- package/src/components/window/PopupLayerPortal.tsx +218 -0
- package/src/components/window/drawerStyles.spec.ts +263 -0
- package/src/components/window/drawerStyles.ts +228 -0
- package/src/components/window/drawerSwipeConfig.spec.ts +131 -0
- package/src/components/window/drawerSwipeConfig.ts +112 -0
- package/src/components/window/useDrawerSwipeTransform.spec.ts +234 -0
- package/src/components/window/useDrawerSwipeTransform.ts +129 -0
- package/src/config/PanelContentDeclaration.tsx +427 -0
- package/src/config/index.tsx +52 -0
- package/src/config/panelJsx.spec.tsx +54 -0
- package/src/config/panelJsxConfig.spec.tsx +54 -0
- package/src/config/panelJsxDrawer.spec.tsx +33 -0
- package/src/config/panelRouter.spec.ts +68 -0
- package/src/config/panelRouter.tsx +155 -0
- package/src/constants/styles.ts +280 -0
- package/src/demo/Layout.module.css +258 -0
- package/src/demo/Layout.tsx +176 -0
- package/src/demo/components/CodeBlock.module.css +54 -0
- package/src/demo/components/CodeBlock.tsx +34 -0
- package/src/demo/components/CodePreview.module.css +37 -0
- package/src/demo/components/CodePreview.tsx +31 -0
- package/src/demo/components/DataPreview.module.css +177 -0
- package/src/demo/components/DataPreview.tsx +115 -0
- package/src/demo/components/Story.module.css +68 -0
- package/src/demo/components/Story.tsx +54 -0
- package/src/demo/components/layout/CodePanel.module.css +183 -0
- package/src/demo/components/layout/CodePanel.tsx +149 -0
- package/src/demo/components/layout/DemoPage.module.css +60 -0
- package/src/demo/components/layout/DemoPage.tsx +56 -0
- package/src/demo/components/layout/SingleSamplePage.module.css +11 -0
- package/src/demo/components/layout/SingleSamplePage.tsx +35 -0
- package/src/demo/components/layout/SplitDemoLayout.module.css +107 -0
- package/src/demo/components/layout/SplitDemoLayout.tsx +218 -0
- package/src/demo/components/layout/index.ts +11 -0
- package/src/demo/components/tab-styles/ChromeTabBar.module.css +75 -0
- package/src/demo/components/tab-styles/ChromeTabBar.tsx +111 -0
- package/src/demo/components/tab-styles/GitHubTabBar.module.css +81 -0
- package/src/demo/components/tab-styles/GitHubTabBar.tsx +109 -0
- package/src/demo/components/tab-styles/VSCodeTabBar.module.css +78 -0
- package/src/demo/components/tab-styles/VSCodeTabBar.tsx +109 -0
- package/src/demo/components/tab-styles/index.ts +6 -0
- package/src/demo/components/ui/DemoButton.module.css +63 -0
- package/src/demo/components/ui/DemoButton.tsx +32 -0
- package/src/demo/components/ui/DemoCard.module.css +15 -0
- package/src/demo/components/ui/DemoCard.tsx +30 -0
- package/src/demo/components/ui/DemoContainer.module.css +17 -0
- package/src/demo/components/ui/DemoContainer.tsx +30 -0
- package/src/demo/components/ui/DemoPanel.module.css +23 -0
- package/src/demo/components/ui/DemoPanel.tsx +33 -0
- package/src/demo/components/ui/PanelText.module.css +18 -0
- package/src/demo/components/ui/PanelText.tsx +29 -0
- package/src/demo/components/ui/PanelTitle.module.css +18 -0
- package/src/demo/components/ui/PanelTitle.tsx +31 -0
- package/src/demo/contexts/TabbarDemoConfig.tsx +218 -0
- package/src/demo/demo.css +172 -0
- package/src/demo/hooks/useMedia.ts +41 -0
- package/src/demo/hooks/useShikiHighlight.ts +55 -0
- package/src/demo/index.tsx +293 -0
- package/src/demo/pages/Dialog/alerts/index.tsx +22 -0
- package/src/demo/pages/Dialog/card/index.tsx +22 -0
- package/src/demo/pages/Dialog/components/AlertDialogDemo.tsx +124 -0
- package/src/demo/pages/Dialog/components/CardExpandDemo.module.css +243 -0
- package/src/demo/pages/Dialog/components/CardExpandDemo.tsx +204 -0
- package/src/demo/pages/Dialog/components/CustomAlertDialogDemo.tsx +219 -0
- package/src/demo/pages/Dialog/components/DialogDemos.module.css +77 -0
- package/src/demo/pages/Dialog/components/ModalBasics.tsx +45 -0
- package/src/demo/pages/Dialog/components/SwipeDialogDemo.module.css +77 -0
- package/src/demo/pages/Dialog/components/SwipeDialogDemo.tsx +181 -0
- package/src/demo/pages/Dialog/custom-alert/index.tsx +22 -0
- package/src/demo/pages/Dialog/modal/index.tsx +17 -0
- package/src/demo/pages/Dialog/swipe/index.tsx +22 -0
- package/src/demo/pages/Drawer/animations/index.tsx +22 -0
- package/src/demo/pages/Drawer/basics/index.tsx +17 -0
- package/src/demo/pages/Drawer/components/DrawerAnimations.module.css +125 -0
- package/src/demo/pages/Drawer/components/DrawerAnimations.tsx +118 -0
- package/src/demo/pages/Drawer/components/DrawerBasics.module.css +55 -0
- package/src/demo/pages/Drawer/components/DrawerBasics.tsx +76 -0
- package/src/demo/pages/Drawer/components/DrawerMenuLayout.module.css +332 -0
- package/src/demo/pages/Drawer/components/DrawerMenuLayout.tsx +199 -0
- package/src/demo/pages/Drawer/components/DrawerSwipe.module.css +316 -0
- package/src/demo/pages/Drawer/components/DrawerSwipe.tsx +178 -0
- package/src/demo/pages/Drawer/menu/index.tsx +17 -0
- package/src/demo/pages/Drawer/swipe/index.tsx +17 -0
- package/src/demo/pages/FloatingPanelFrame/ResizableFloatingPanelsPreview.module.css +163 -0
- package/src/demo/pages/FloatingPanelFrame/ResizableFloatingPanelsPreview.tsx +234 -0
- package/src/demo/pages/FloatingPanelFrame/basic/index.tsx +17 -0
- package/src/demo/pages/FloatingPanelFrame/complex/index.tsx +26 -0
- package/src/demo/pages/FloatingPanelFrame/components/BasicPanel.module.css +16 -0
- package/src/demo/pages/FloatingPanelFrame/components/BasicPanel.tsx +24 -0
- package/src/demo/pages/FloatingPanelFrame/components/ComplexPanel.module.css +54 -0
- package/src/demo/pages/FloatingPanelFrame/components/ComplexPanel.tsx +67 -0
- package/src/demo/pages/FloatingPanelFrame/components/PanelWithControls.module.css +21 -0
- package/src/demo/pages/FloatingPanelFrame/components/PanelWithControls.tsx +41 -0
- package/src/demo/pages/FloatingPanelFrame/components/PanelWithMeta.module.css +5 -0
- package/src/demo/pages/FloatingPanelFrame/components/PanelWithMeta.tsx +43 -0
- package/src/demo/pages/FloatingPanelFrame/components/ScrollablePanel.module.css +11 -0
- package/src/demo/pages/FloatingPanelFrame/components/ScrollablePanel.tsx +42 -0
- package/src/demo/pages/FloatingPanelFrame/index.tsx +80 -0
- package/src/demo/pages/FloatingPanelFrame/scrollable/index.tsx +30 -0
- package/src/demo/pages/FloatingPanelFrame/with-controls/index.tsx +30 -0
- package/src/demo/pages/FloatingPanelFrame/with-meta/index.tsx +17 -0
- package/src/demo/pages/HorizontalDivider/components/PanelsWithRichContent.module.css +112 -0
- package/src/demo/pages/HorizontalDivider/components/PanelsWithRichContent.tsx +56 -0
- package/src/demo/pages/HorizontalDivider/components/SimpleResizablePanels.module.css +46 -0
- package/src/demo/pages/HorizontalDivider/components/SimpleResizablePanels.tsx +29 -0
- package/src/demo/pages/HorizontalDivider/components/ThreePanelLayout.module.css +54 -0
- package/src/demo/pages/HorizontalDivider/components/ThreePanelLayout.tsx +30 -0
- package/src/demo/pages/HorizontalDivider/index.module.css +14 -0
- package/src/demo/pages/HorizontalDivider/index.tsx +64 -0
- package/src/demo/pages/HorizontalDivider/panels-with-rich-content/index.tsx +21 -0
- package/src/demo/pages/HorizontalDivider/simple-resizable-panels/index.tsx +21 -0
- package/src/demo/pages/HorizontalDivider/three-panel-layout/index.tsx +21 -0
- package/src/demo/pages/PanelLayout/PanelLayoutDemo.module.css +174 -0
- package/src/demo/pages/PanelLayout/PanelLayoutDemo.tsx +248 -0
- package/src/demo/pages/PanelLayout/components/DashboardLayout.module.css +115 -0
- package/src/demo/pages/PanelLayout/components/DashboardLayout.tsx +124 -0
- package/src/demo/pages/PanelLayout/components/DraggableOverlays.module.css +101 -0
- package/src/demo/pages/PanelLayout/components/DraggableOverlays.tsx +122 -0
- package/src/demo/pages/PanelLayout/components/IDELayout.module.css +104 -0
- package/src/demo/pages/PanelLayout/components/IDELayout.tsx +143 -0
- package/src/demo/pages/PanelLayout/components/SimpleGrid.module.css +19 -0
- package/src/demo/pages/PanelLayout/components/SimpleGrid.tsx +62 -0
- package/src/demo/pages/PanelLayout/dashboard/index.tsx +22 -0
- package/src/demo/pages/PanelLayout/draggable-overlays/index.tsx +22 -0
- package/src/demo/pages/PanelLayout/ide-layout/index.tsx +22 -0
- package/src/demo/pages/PanelLayout/index.tsx +94 -0
- package/src/demo/pages/PanelLayout/simple-grid/index.tsx +22 -0
- package/src/demo/pages/PanelSystem/PanelSystemPreview.module.css +20 -0
- package/src/demo/pages/PanelSystem/PanelSystemPreview.tsx +101 -0
- package/src/demo/pages/PanelSystem/preview/index.tsx +18 -0
- package/src/demo/pages/PanelSystem/tabbar/index.tsx +129 -0
- package/src/demo/pages/Pivot/basics/index.tsx +17 -0
- package/src/demo/pages/Pivot/components/Pivot.module.css +278 -0
- package/src/demo/pages/Pivot/components/PivotBasics.tsx +103 -0
- package/src/demo/pages/Pivot/components/PivotSidebar.tsx +168 -0
- package/src/demo/pages/Pivot/components/PivotTabs.tsx +129 -0
- package/src/demo/pages/Pivot/components/PivotTransitions.tsx +120 -0
- package/src/demo/pages/Pivot/components/SwipePivot.module.css +114 -0
- package/src/demo/pages/Pivot/components/SwipePivot.tsx +193 -0
- package/src/demo/pages/Pivot/components/SwipeTabsPivot.module.css +203 -0
- package/src/demo/pages/Pivot/components/SwipeTabsPivot.tsx +320 -0
- package/src/demo/pages/Pivot/sidebar/index.tsx +17 -0
- package/src/demo/pages/Pivot/swipe/index.tsx +16 -0
- package/src/demo/pages/Pivot/swipe-debug/index.tsx +287 -0
- package/src/demo/pages/Pivot/swipe-tabs/index.tsx +15 -0
- package/src/demo/pages/Pivot/tabs/index.tsx +17 -0
- package/src/demo/pages/Pivot/transitions/index.tsx +17 -0
- package/src/demo/pages/ResizeHandle/both-directions/index.tsx +17 -0
- package/src/demo/pages/ResizeHandle/components/BothDirectionsDemo.module.css +72 -0
- package/src/demo/pages/ResizeHandle/components/BothDirectionsDemo.tsx +41 -0
- package/src/demo/pages/ResizeHandle/components/HorizontalResizeDemo.module.css +61 -0
- package/src/demo/pages/ResizeHandle/components/HorizontalResizeDemo.tsx +33 -0
- package/src/demo/pages/ResizeHandle/components/NestedPanelsDemo.module.css +83 -0
- package/src/demo/pages/ResizeHandle/components/NestedPanelsDemo.tsx +53 -0
- package/src/demo/pages/ResizeHandle/components/VerticalResizeDemo.module.css +68 -0
- package/src/demo/pages/ResizeHandle/components/VerticalResizeDemo.tsx +33 -0
- package/src/demo/pages/ResizeHandle/horizontal/index.tsx +17 -0
- package/src/demo/pages/ResizeHandle/index.module.css +11 -0
- package/src/demo/pages/ResizeHandle/index.tsx +71 -0
- package/src/demo/pages/ResizeHandle/nested-panels/index.tsx +17 -0
- package/src/demo/pages/ResizeHandle/vertical/index.tsx +17 -0
- package/src/demo/pages/ResponsiveLayout/adaptive-workspace/index.tsx +22 -0
- package/src/demo/pages/ResponsiveLayout/components/ResponsiveWorkspace.module.css +423 -0
- package/src/demo/pages/ResponsiveLayout/components/ResponsiveWorkspace.tsx +398 -0
- package/src/demo/pages/Stack/basics/index.tsx +22 -0
- package/src/demo/pages/Stack/components/Stack.module.css +234 -0
- package/src/demo/pages/Stack/components/StackBasics.spec.tsx +152 -0
- package/src/demo/pages/Stack/components/StackBasics.tsx +301 -0
- package/src/demo/pages/Stack/components/StackTablet.module.css +299 -0
- package/src/demo/pages/Stack/components/StackTablet.spec.tsx +120 -0
- package/src/demo/pages/Stack/components/StackTablet.tsx +422 -0
- package/src/demo/pages/Stack/tablet/index.tsx +22 -0
- package/src/demo/pages/StickyHeader/basics/index.tsx +17 -0
- package/src/demo/pages/StickyHeader/components/StickyHeader.module.css +219 -0
- package/src/demo/pages/StickyHeader/components/StickyHeaderBasics.tsx +103 -0
- package/src/demo/routes.tsx +214 -0
- package/src/demo/styles/animations.css +68 -0
- package/src/demo/styles/stack-themes.css +35 -0
- package/src/demo/utils/createPanelView.tsx +58 -0
- package/src/dialog/index.ts +85 -0
- package/src/floating/index.ts +24 -0
- package/src/grid/index.ts +75 -0
- package/src/hooks/ContentCacheContext.tsx +87 -0
- package/src/hooks/gesture/presets.spec.ts +86 -0
- package/src/hooks/gesture/presets.ts +95 -0
- package/src/hooks/gesture/testing/createGestureSimulator.spec.ts +241 -0
- package/src/hooks/gesture/testing/createGestureSimulator.ts +385 -0
- package/src/hooks/gesture/thresholdValue.spec.ts +103 -0
- package/src/hooks/gesture/thresholdValue.ts +77 -0
- package/src/hooks/gesture/types.ts +367 -0
- package/src/hooks/gesture/useDirectionalLock.spec.ts +271 -0
- package/src/hooks/gesture/useDirectionalLock.ts +115 -0
- package/src/hooks/gesture/useEdgeSwipeInput.spec.ts +462 -0
- package/src/hooks/gesture/useEdgeSwipeInput.ts +131 -0
- package/src/hooks/gesture/useNativeGestureGuard.spec.ts +473 -0
- package/src/hooks/gesture/useNativeGestureGuard.ts +135 -0
- package/src/hooks/gesture/usePointerTracking.spec.ts +364 -0
- package/src/hooks/gesture/usePointerTracking.ts +134 -0
- package/src/hooks/gesture/useScrollBoundary.spec.ts +249 -0
- package/src/hooks/gesture/useScrollBoundary.ts +113 -0
- package/src/hooks/gesture/useSwipeInput.spec.ts +592 -0
- package/src/hooks/gesture/useSwipeInput.ts +310 -0
- package/src/hooks/gesture/utils.spec.ts +152 -0
- package/src/hooks/gesture/utils.ts +178 -0
- package/src/hooks/useAnimatedVisibility.spec.ts +277 -0
- package/src/hooks/useAnimatedVisibility.ts +172 -0
- package/src/hooks/useAnimationFrame.ts +208 -0
- package/src/hooks/useCSSMatrix.spec.ts +214 -0
- package/src/hooks/useCSSMatrix.ts +262 -0
- package/src/hooks/useClonedElementPreview.ts +28 -0
- package/src/hooks/useContainerScroll.ts +78 -0
- package/src/hooks/useContentCache.spec.tsx +232 -0
- package/src/hooks/useContentCache.tsx +127 -0
- package/src/hooks/useDocumentPointerEvents.ts +137 -0
- package/src/hooks/useDocumentScroll.ts +41 -0
- package/src/hooks/useEffectEvent.ts +40 -0
- package/src/hooks/useElementComponentWrapper.tsx +63 -0
- package/src/hooks/useIntersectionObserver.tsx +125 -0
- package/src/hooks/useIsomorphicLayoutEffect.ts +29 -0
- package/src/hooks/useOperationContinuity.spec.ts +387 -0
- package/src/hooks/useOperationContinuity.ts +135 -0
- package/src/hooks/useResizeObserver.spec.tsx +277 -0
- package/src/hooks/useResizeObserver.tsx +150 -0
- package/src/hooks/useScrollContainer.ts +73 -0
- package/src/hooks/useSharedElementTransition.ts +333 -0
- package/src/hooks/useSnapAnimation.ts +128 -0
- package/src/hooks/useSwipeContentTransform.spec.ts +133 -0
- package/src/hooks/useSwipeContentTransform.ts +373 -0
- package/src/hooks/useTransitionState.ts +95 -0
- package/src/index.tsx +88 -0
- package/src/modules/dialog/AlertDialog.spec.tsx +387 -0
- package/src/modules/dialog/AlertDialog.tsx +221 -0
- package/src/modules/dialog/DialogContainer.spec.tsx +228 -0
- package/src/modules/dialog/DialogContainer.tsx +188 -0
- package/src/modules/dialog/Modal.spec.tsx +220 -0
- package/src/modules/dialog/Modal.tsx +182 -0
- package/src/modules/dialog/SwipeDialogContainer.tsx +208 -0
- package/src/modules/dialog/dialogAnimationUtils.spec.ts +253 -0
- package/src/modules/dialog/dialogAnimationUtils.ts +297 -0
- package/src/modules/dialog/types.ts +186 -0
- package/src/modules/dialog/useDialog.spec.tsx +447 -0
- package/src/modules/dialog/useDialog.ts +214 -0
- package/src/modules/dialog/useDialogContainer.spec.ts +331 -0
- package/src/modules/dialog/useDialogContainer.ts +150 -0
- package/src/modules/dialog/useDialogSwipeInput.spec.ts +157 -0
- package/src/modules/dialog/useDialogSwipeInput.ts +319 -0
- package/src/modules/dialog/useDialogTransform.spec.ts +370 -0
- package/src/modules/dialog/useDialogTransform.ts +407 -0
- package/src/modules/drawer/types.ts +102 -0
- package/src/modules/drawer/useDrawerSwipeInput.spec.ts +566 -0
- package/src/modules/drawer/useDrawerSwipeInput.ts +399 -0
- package/src/modules/grid/GridLayoutContext.tsx +57 -0
- package/src/modules/grid/LayerInstanceContext.tsx +56 -0
- package/src/modules/grid/resizeHandles.ts +157 -0
- package/src/modules/grid/trackUtils.ts +146 -0
- package/src/modules/grid/useGridPlacements.ts +143 -0
- package/src/modules/grid/useGridTracks.ts +156 -0
- package/src/modules/grid/useLayerDragHandle.ts +16 -0
- package/src/modules/grid/useLayerInteractions.tsx +850 -0
- package/src/modules/keybindings/KeybindingsProvider.tsx +111 -0
- package/src/modules/panels/dom/DomRegistry.tsx +94 -0
- package/src/modules/panels/index.ts +45 -0
- package/src/modules/panels/interactions/InteractionsContext.test.tsx +330 -0
- package/src/modules/panels/interactions/InteractionsContext.tsx +394 -0
- package/src/modules/panels/interactions/dnd.ts +28 -0
- package/src/modules/panels/keybindings/KeybindingsInstaller.tsx +15 -0
- package/src/modules/panels/layout/adapter.ts +124 -0
- package/src/modules/panels/rendering/ContentRegistry.spec.tsx +311 -0
- package/src/modules/panels/rendering/ContentRegistry.tsx +205 -0
- package/src/modules/panels/rendering/GroupContainer.tsx +65 -0
- package/src/modules/panels/rendering/RenderBridge.tsx +115 -0
- package/src/modules/panels/rendering/RenderContext.tsx +31 -0
- package/src/modules/panels/state/PanelSplitHandles.tsx +147 -0
- package/src/modules/panels/state/PanelSystemContext.splitLimits.spec.tsx +50 -0
- package/src/modules/panels/state/PanelSystemContext.tsx +289 -0
- package/src/modules/panels/state/StateContext.tsx +12 -0
- package/src/modules/panels/state/cleanup.ts +37 -0
- package/src/modules/panels/state/commands.ts +53 -0
- package/src/modules/panels/state/focus/Context.tsx +25 -0
- package/src/modules/panels/state/focus/logic.ts +57 -0
- package/src/modules/panels/state/groups/Context.tsx +25 -0
- package/src/modules/panels/state/groups/logic.ts +105 -0
- package/src/modules/panels/state/splitLimits.spec.ts +46 -0
- package/src/modules/panels/state/splitLimits.ts +90 -0
- package/src/modules/panels/state/state.spec.ts +49 -0
- package/src/modules/panels/state/tree/Context.tsx +24 -0
- package/src/modules/panels/state/tree/logic.spec.ts +34 -0
- package/src/modules/panels/state/tree/logic.ts +138 -0
- package/src/modules/panels/state/types.ts +142 -0
- package/src/modules/panels/system/PanelSystem.empty-tabbar.spec.tsx +53 -0
- package/src/modules/panels/system/PanelSystem.tab-click-activates.spec.tsx +44 -0
- package/src/modules/panels/system/PanelSystem.tab-reorder.spec.tsx +64 -0
- package/src/modules/panels/system/PanelSystem.tabs-no-dup.spec.tsx +57 -0
- package/src/modules/panels/system/PanelSystem.tsx +206 -0
- package/src/modules/pivot/PivotContent.spec.tsx +179 -0
- package/src/modules/pivot/PivotContent.tsx +77 -0
- package/src/modules/pivot/SwipePivotContent.debug.tmp.tsx +237 -0
- package/src/modules/pivot/SwipePivotContent.position.spec.tsx +171 -0
- package/src/modules/pivot/SwipePivotContent.spec.tsx +494 -0
- package/src/modules/pivot/SwipePivotContent.test.tsx +502 -0
- package/src/modules/pivot/SwipePivotContent.tsx +197 -0
- package/src/modules/pivot/SwipePivotTabBar.spec.tsx +882 -0
- package/src/modules/pivot/SwipePivotTabBar.tsx +583 -0
- package/src/modules/pivot/index.ts +8 -0
- package/src/modules/pivot/scaleInputState.spec.ts +219 -0
- package/src/modules/pivot/scaleInputState.ts +66 -0
- package/src/modules/pivot/types.ts +139 -0
- package/src/modules/pivot/usePivot.spec.ts +635 -0
- package/src/modules/pivot/usePivot.spec.tsx +186 -0
- package/src/modules/pivot/usePivot.tsx +345 -0
- package/src/modules/pivot/usePivotSwipeInput.spec.ts +708 -0
- package/src/modules/pivot/usePivotSwipeInput.ts +136 -0
- package/src/modules/resizer/useResizeDrag.ts +94 -0
- package/src/modules/stack/StackContent.spec.tsx +264 -0
- package/src/modules/stack/StackContent.tsx +111 -0
- package/src/modules/stack/SwipeStackContent.spec.tsx +1564 -0
- package/src/modules/stack/SwipeStackContent.tsx +366 -0
- package/src/modules/stack/SwipeStackOutlet.spec.tsx +250 -0
- package/src/modules/stack/SwipeStackOutlet.tsx +221 -0
- package/src/modules/stack/computeStackContentState.spec.ts +281 -0
- package/src/modules/stack/computeStackContentState.ts +304 -0
- package/src/modules/stack/computeSwipeStackTransform.spec.ts +186 -0
- package/src/modules/stack/computeSwipeStackTransform.ts +145 -0
- package/src/modules/stack/swipeTransitionContinuity.spec.tsx +1133 -0
- package/src/modules/stack/types.ts +226 -0
- package/src/modules/stack/useStackAnimationState.spec.ts +188 -0
- package/src/modules/stack/useStackAnimationState.ts +143 -0
- package/src/modules/stack/useStackNavigation.spec.ts +672 -0
- package/src/modules/stack/useStackNavigation.tsx +393 -0
- package/src/modules/stack/useStackSwipeInput.spec.ts +309 -0
- package/src/modules/stack/useStackSwipeInput.ts +139 -0
- package/src/modules/window/useDrawerState.ts +81 -0
- package/src/modules/window/useFloatingState.spec.ts +252 -0
- package/src/modules/window/useFloatingState.ts +141 -0
- package/src/panels/index.ts +119 -0
- package/src/pivot/index.ts +19 -0
- package/src/resizer/index.ts +68 -0
- package/src/stack/index.ts +91 -0
- package/src/sticky-header/StickyArea.tsx +193 -0
- package/src/sticky-header/calculateStickyMetrics.spec.ts +105 -0
- package/src/sticky-header/calculateStickyMetrics.ts +50 -0
- package/src/sticky-header/index.ts +18 -0
- package/src/sticky-header/types.ts +68 -0
- package/src/types.ts +341 -0
- package/src/utils/CSSMatrix.ts +321 -0
- package/src/utils/css.ts +65 -0
- package/src/utils/dialogUtils.ts +43 -0
- package/src/utils/math.ts +18 -0
- package/src/utils/polyfills/createDialogPolyfill.ts +18 -0
- package/src/utils/typedActions.ts +103 -0
- package/src/vite-env.d.ts +6 -0
- package/src/window/index.ts +69 -0
- package/dist/GridLayout-BQQ63eA1.cjs +0 -2
- package/dist/GridLayout-BQQ63eA1.cjs.map +0 -1
- package/dist/GridLayout-CJTKq7Mp.js +0 -1465
- package/dist/GridLayout-CJTKq7Mp.js.map +0 -1
- package/dist/sticky-header/StickyHeader.d.ts +0 -53
- package/dist/styles-CA2_zLZt.js +0 -52
- package/dist/styles-CA2_zLZt.js.map +0 -1
- package/dist/styles-PsqGOEJP.cjs +0 -2
- package/dist/styles-PsqGOEJP.cjs.map +0 -1
- package/dist/usePivot-7ctin_P_.cjs +0 -2
- package/dist/usePivot-7ctin_P_.cjs.map +0 -1
- package/dist/usePivot-CgQxB8rc.js +0 -124
- package/dist/usePivot-CgQxB8rc.js.map +0 -1
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Type definitions for gesture input detection hooks.
|
|
3
|
+
*
|
|
4
|
+
* These types support the separation of concerns:
|
|
5
|
+
* - Operation: what to do (navigate, push, pop)
|
|
6
|
+
* - Input: how to command (swipe, click, keyboard)
|
|
7
|
+
* - Presentation: how to show (animation, transition)
|
|
8
|
+
*
|
|
9
|
+
* This file defines types for the Input layer, including the abstract
|
|
10
|
+
* ContinuousOperationState that represents any continuous state transition
|
|
11
|
+
* (whether controlled by human gesture or system animation).
|
|
12
|
+
*/
|
|
13
|
+
import type * as React from "react";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Axis for gesture detection.
|
|
17
|
+
*/
|
|
18
|
+
export type GestureAxis = "horizontal" | "vertical";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 2D vector for displacement and velocity.
|
|
22
|
+
*/
|
|
23
|
+
export type Vector2 = {
|
|
24
|
+
x: number;
|
|
25
|
+
y: number;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// Continuous Operation State
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// A continuous operation is any state transition that occurs over time,
|
|
32
|
+
// where progress can be observed incrementally. The controlling agent
|
|
33
|
+
// may be human (gesture) or system (animation).
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Phase of a continuous operation lifecycle.
|
|
37
|
+
* - "idle": No operation in progress
|
|
38
|
+
* - "operating": Operation is in progress (human or system controlled)
|
|
39
|
+
* - "ended": Operation has completed
|
|
40
|
+
*/
|
|
41
|
+
export type ContinuousOperationPhase = "idle" | "operating" | "ended";
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* State of a continuous operation.
|
|
45
|
+
*
|
|
46
|
+
* This is the abstract representation of any operation that occurs over time,
|
|
47
|
+
* whether controlled by human gesture or system animation. Components that
|
|
48
|
+
* accept this state can respond to both input types uniformly.
|
|
49
|
+
*/
|
|
50
|
+
export type ContinuousOperationState = {
|
|
51
|
+
/** Current phase of the operation */
|
|
52
|
+
phase: ContinuousOperationPhase;
|
|
53
|
+
/** Displacement from start position in pixels */
|
|
54
|
+
displacement: Vector2;
|
|
55
|
+
/** Current velocity in pixels per millisecond */
|
|
56
|
+
velocity: Vector2;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Initial idle state for ContinuousOperationState.
|
|
61
|
+
*/
|
|
62
|
+
export const IDLE_CONTINUOUS_OPERATION_STATE: ContinuousOperationState = {
|
|
63
|
+
phase: "idle",
|
|
64
|
+
displacement: { x: 0, y: 0 },
|
|
65
|
+
velocity: { x: 0, y: 0 },
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Convert SwipeInputPhase to ContinuousOperationPhase.
|
|
70
|
+
* - "idle" → "idle"
|
|
71
|
+
* - "tracking" | "swiping" → "operating"
|
|
72
|
+
* - "ended" → "ended"
|
|
73
|
+
*/
|
|
74
|
+
export function toContinuousPhase(phase: SwipeInputPhase): ContinuousOperationPhase {
|
|
75
|
+
if (phase === "idle") {
|
|
76
|
+
return "idle";
|
|
77
|
+
}
|
|
78
|
+
if (phase === "ended") {
|
|
79
|
+
return "ended";
|
|
80
|
+
}
|
|
81
|
+
return "operating";
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Convert SwipeInputState to ContinuousOperationState.
|
|
86
|
+
*/
|
|
87
|
+
export function toContinuousOperationState(state: SwipeInputState): ContinuousOperationState {
|
|
88
|
+
return {
|
|
89
|
+
phase: toContinuousPhase(state.phase),
|
|
90
|
+
displacement: state.displacement,
|
|
91
|
+
velocity: state.velocity,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ============================================================================
|
|
96
|
+
// Swipe Input (concrete implementation of continuous operation)
|
|
97
|
+
// ============================================================================
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Phase of swipe input lifecycle.
|
|
101
|
+
* - "idle": No swipe in progress
|
|
102
|
+
* - "tracking": Pointer down, tracking movement (direction not yet locked)
|
|
103
|
+
* - "swiping": Direction locked, actively swiping
|
|
104
|
+
* - "ended": Swipe gesture completed
|
|
105
|
+
*/
|
|
106
|
+
export type SwipeInputPhase = "idle" | "tracking" | "swiping" | "ended";
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Point with timestamp for velocity calculation.
|
|
110
|
+
*/
|
|
111
|
+
export type TimestampedPoint = {
|
|
112
|
+
x: number;
|
|
113
|
+
y: number;
|
|
114
|
+
timestamp: number;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Swipe input state during gesture.
|
|
119
|
+
*/
|
|
120
|
+
export type SwipeInputState = {
|
|
121
|
+
/** Current phase of the swipe input */
|
|
122
|
+
phase: SwipeInputPhase;
|
|
123
|
+
/** Displacement from start position in pixels */
|
|
124
|
+
displacement: Vector2;
|
|
125
|
+
/** Current velocity in pixels per millisecond */
|
|
126
|
+
velocity: Vector2;
|
|
127
|
+
/**
|
|
128
|
+
* Direction of movement as a number.
|
|
129
|
+
* -1 = backward (left/up), 0 = no movement, 1 = forward (right/down)
|
|
130
|
+
*/
|
|
131
|
+
direction: -1 | 0 | 1;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Thresholds for swipe input recognition.
|
|
136
|
+
*/
|
|
137
|
+
export type SwipeInputThresholds = {
|
|
138
|
+
/** Minimum distance in pixels to trigger swipe. @default 50 */
|
|
139
|
+
distanceThreshold: number;
|
|
140
|
+
/** Minimum velocity in px/ms to trigger swipe. @default 0.3 */
|
|
141
|
+
velocityThreshold: number;
|
|
142
|
+
/** Distance threshold before direction is locked. @default 10 */
|
|
143
|
+
lockThreshold: number;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Options for usePointerTracking hook.
|
|
148
|
+
*/
|
|
149
|
+
export type UsePointerTrackingOptions = {
|
|
150
|
+
/** Whether tracking is enabled */
|
|
151
|
+
enabled: boolean;
|
|
152
|
+
/** Restrict to primary pointer only (ignore multitouch). @default true */
|
|
153
|
+
primaryOnly?: boolean;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Result from usePointerTracking hook.
|
|
158
|
+
*/
|
|
159
|
+
export type UsePointerTrackingResult = {
|
|
160
|
+
/** Current tracking state */
|
|
161
|
+
state: PointerTrackingState;
|
|
162
|
+
/** Handler to attach to onPointerDown */
|
|
163
|
+
onPointerDown: (event: React.PointerEvent) => void;
|
|
164
|
+
/** Reset tracking state */
|
|
165
|
+
reset: () => void;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Internal pointer tracking state.
|
|
170
|
+
*/
|
|
171
|
+
export type PointerTrackingState = {
|
|
172
|
+
/** Whether pointer is currently down */
|
|
173
|
+
isDown: boolean;
|
|
174
|
+
/** Start position and timestamp */
|
|
175
|
+
start: TimestampedPoint | null;
|
|
176
|
+
/** Current position and timestamp */
|
|
177
|
+
current: TimestampedPoint | null;
|
|
178
|
+
/** Active pointer ID */
|
|
179
|
+
pointerId: number | null;
|
|
180
|
+
/** Whether tracking ended via pointercancel (not pointerup) */
|
|
181
|
+
wasCanceled: boolean;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Options for useDirectionalLock hook.
|
|
186
|
+
*/
|
|
187
|
+
export type UseDirectionalLockOptions = {
|
|
188
|
+
/** Pointer tracking state from usePointerTracking */
|
|
189
|
+
tracking: PointerTrackingState;
|
|
190
|
+
/** Lock threshold in pixels. @default 10 */
|
|
191
|
+
lockThreshold?: number;
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Result from useDirectionalLock hook.
|
|
196
|
+
*/
|
|
197
|
+
export type UseDirectionalLockResult = {
|
|
198
|
+
/** Locked axis, or null if not yet locked */
|
|
199
|
+
lockedAxis: GestureAxis | null;
|
|
200
|
+
/** Whether lock has been determined */
|
|
201
|
+
isLocked: boolean;
|
|
202
|
+
/** Reset the lock state */
|
|
203
|
+
reset: () => void;
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Options for useScrollBoundary hook.
|
|
208
|
+
*/
|
|
209
|
+
export type UseScrollBoundaryOptions = {
|
|
210
|
+
/** Scroll container ref. If null, checks document scroll. */
|
|
211
|
+
containerRef: React.RefObject<HTMLElement | null>;
|
|
212
|
+
/** Axis to monitor */
|
|
213
|
+
axis: GestureAxis;
|
|
214
|
+
/** Tolerance in pixels for "at boundary" detection. @default 1 */
|
|
215
|
+
tolerance?: number;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Result from useScrollBoundary hook.
|
|
220
|
+
*/
|
|
221
|
+
export type UseScrollBoundaryResult = {
|
|
222
|
+
/** Whether at the start boundary (top/left) */
|
|
223
|
+
atStart: boolean;
|
|
224
|
+
/** Whether at the end boundary (bottom/right) */
|
|
225
|
+
atEnd: boolean;
|
|
226
|
+
/** Current scroll position */
|
|
227
|
+
scrollPosition: number;
|
|
228
|
+
/** Maximum scroll position */
|
|
229
|
+
maxScrollPosition: number;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Filter function to determine if a pointer event should start tracking.
|
|
234
|
+
* Receives the pointer event and container element.
|
|
235
|
+
* Return true to allow tracking, false to ignore the event.
|
|
236
|
+
*/
|
|
237
|
+
export type PointerStartFilter = (
|
|
238
|
+
event: React.PointerEvent,
|
|
239
|
+
container: HTMLElement,
|
|
240
|
+
) => boolean;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Options for useSwipeInput hook.
|
|
244
|
+
*/
|
|
245
|
+
export type UseSwipeInputOptions = {
|
|
246
|
+
/** Ref to the container element */
|
|
247
|
+
containerRef: React.RefObject<HTMLElement | null>;
|
|
248
|
+
/** Axis to detect swipes on */
|
|
249
|
+
axis: GestureAxis;
|
|
250
|
+
/** Whether swipe detection is enabled. @default true */
|
|
251
|
+
enabled?: boolean;
|
|
252
|
+
/** Swipe thresholds configuration */
|
|
253
|
+
thresholds?: Partial<SwipeInputThresholds>;
|
|
254
|
+
/** Callback when swipe is completed */
|
|
255
|
+
onSwipeEnd?: (state: SwipeInputState) => void;
|
|
256
|
+
/** Whether to enable trackpad two-finger swipe (wheel events). @default true */
|
|
257
|
+
enableWheel?: boolean;
|
|
258
|
+
/**
|
|
259
|
+
* Optional filter to determine if a pointer event should start tracking.
|
|
260
|
+
* If provided, only events that pass this filter will be tracked.
|
|
261
|
+
* Useful for edge-based swipe detection.
|
|
262
|
+
*/
|
|
263
|
+
pointerStartFilter?: PointerStartFilter;
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Result from useSwipeInput hook.
|
|
268
|
+
*/
|
|
269
|
+
export type UseSwipeInputResult = {
|
|
270
|
+
/** Current swipe input state */
|
|
271
|
+
state: SwipeInputState;
|
|
272
|
+
/** Props to spread on the container element */
|
|
273
|
+
containerProps: React.HTMLAttributes<HTMLElement> & {
|
|
274
|
+
style: React.CSSProperties;
|
|
275
|
+
};
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Edge for edge-originated gestures.
|
|
280
|
+
*/
|
|
281
|
+
export type GestureEdge = "left" | "right" | "top" | "bottom";
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Options for useEdgeSwipeInput hook.
|
|
285
|
+
*/
|
|
286
|
+
export type UseEdgeSwipeInputOptions = {
|
|
287
|
+
/** Ref to the container element */
|
|
288
|
+
containerRef: React.RefObject<HTMLElement | null>;
|
|
289
|
+
/** Which edge to detect swipes from */
|
|
290
|
+
edge: GestureEdge;
|
|
291
|
+
/** Width of the edge detection zone in pixels. @default 20 */
|
|
292
|
+
edgeWidth?: number;
|
|
293
|
+
/** Whether edge swipe detection is enabled. @default true */
|
|
294
|
+
enabled?: boolean;
|
|
295
|
+
/** Swipe thresholds configuration */
|
|
296
|
+
thresholds?: Partial<SwipeInputThresholds>;
|
|
297
|
+
/** Callback when edge swipe is completed */
|
|
298
|
+
onSwipeEnd?: (state: SwipeInputState) => void;
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Result from useEdgeSwipeInput hook.
|
|
303
|
+
*/
|
|
304
|
+
export type UseEdgeSwipeInputResult = {
|
|
305
|
+
/** Whether the current gesture started from the edge */
|
|
306
|
+
isEdgeGesture: boolean;
|
|
307
|
+
/** Current swipe input state */
|
|
308
|
+
state: SwipeInputState;
|
|
309
|
+
/** Props to spread on the container element */
|
|
310
|
+
containerProps: React.HTMLAttributes<HTMLElement> & {
|
|
311
|
+
style: React.CSSProperties;
|
|
312
|
+
};
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Options for useNativeGestureGuard hook.
|
|
317
|
+
*/
|
|
318
|
+
export type UseNativeGestureGuardOptions = {
|
|
319
|
+
/** Ref to the container element */
|
|
320
|
+
containerRef: React.RefObject<HTMLElement | null>;
|
|
321
|
+
/** Whether the guard is active */
|
|
322
|
+
active: boolean;
|
|
323
|
+
/** Prevent iOS/macOS edge back gesture. @default true */
|
|
324
|
+
preventEdgeBack?: boolean;
|
|
325
|
+
/** Prevent overscroll bounce effect. @default true */
|
|
326
|
+
preventOverscroll?: boolean;
|
|
327
|
+
/** Width of edge zone where back gesture is prevented. @default 20 */
|
|
328
|
+
edgeWidth?: number;
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Result from useNativeGestureGuard hook.
|
|
333
|
+
*/
|
|
334
|
+
export type UseNativeGestureGuardResult = {
|
|
335
|
+
/** Props to spread on the container element */
|
|
336
|
+
containerProps: React.HTMLAttributes<HTMLElement> & {
|
|
337
|
+
style: React.CSSProperties;
|
|
338
|
+
};
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Default swipe input thresholds.
|
|
343
|
+
*
|
|
344
|
+
* - distanceThreshold: 100px is ~27% of a 375px mobile screen
|
|
345
|
+
* - velocityThreshold: 0.5px/ms = 500px/s, a moderate flick speed
|
|
346
|
+
* - lockThreshold: 10px before direction is locked
|
|
347
|
+
*/
|
|
348
|
+
export const DEFAULT_SWIPE_THRESHOLDS: SwipeInputThresholds = {
|
|
349
|
+
distanceThreshold: 100,
|
|
350
|
+
velocityThreshold: 0.5,
|
|
351
|
+
lockThreshold: 10,
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Default edge width for edge gesture detection.
|
|
356
|
+
*/
|
|
357
|
+
export const DEFAULT_EDGE_WIDTH = 20;
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Initial idle state for SwipeInputState.
|
|
361
|
+
*/
|
|
362
|
+
export const IDLE_SWIPE_INPUT_STATE: SwipeInputState = {
|
|
363
|
+
phase: "idle",
|
|
364
|
+
displacement: { x: 0, y: 0 },
|
|
365
|
+
velocity: { x: 0, y: 0 },
|
|
366
|
+
direction: 0,
|
|
367
|
+
};
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Tests for useDirectionalLock hook.
|
|
3
|
+
*/
|
|
4
|
+
import { act, renderHook } from "@testing-library/react";
|
|
5
|
+
import { useDirectionalLock } from "./useDirectionalLock.js";
|
|
6
|
+
import type { PointerTrackingState } from "./types.js";
|
|
7
|
+
|
|
8
|
+
const createTrackingState = (
|
|
9
|
+
overrides: Partial<PointerTrackingState> = {},
|
|
10
|
+
): PointerTrackingState => ({
|
|
11
|
+
isDown: false,
|
|
12
|
+
start: null,
|
|
13
|
+
current: null,
|
|
14
|
+
pointerId: null,
|
|
15
|
+
wasCanceled: false,
|
|
16
|
+
...overrides,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
describe("useDirectionalLock", () => {
|
|
20
|
+
describe("initialization", () => {
|
|
21
|
+
it("starts with no locked axis", () => {
|
|
22
|
+
const tracking = createTrackingState();
|
|
23
|
+
const { result } = renderHook(() =>
|
|
24
|
+
useDirectionalLock({ tracking }),
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
expect(result.current.lockedAxis).toBe(null);
|
|
28
|
+
expect(result.current.isLocked).toBe(false);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe("direction detection", () => {
|
|
33
|
+
it("locks to horizontal when X movement dominates", () => {
|
|
34
|
+
const tracking = createTrackingState({
|
|
35
|
+
isDown: true,
|
|
36
|
+
start: { x: 100, y: 100, timestamp: 0 },
|
|
37
|
+
current: { x: 130, y: 105, timestamp: 100 }, // 30px horizontal, 5px vertical
|
|
38
|
+
pointerId: 1,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const { result } = renderHook(() =>
|
|
42
|
+
useDirectionalLock({ tracking, lockThreshold: 10 }),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
expect(result.current.lockedAxis).toBe("horizontal");
|
|
46
|
+
expect(result.current.isLocked).toBe(true);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("locks to vertical when Y movement dominates", () => {
|
|
50
|
+
const tracking = createTrackingState({
|
|
51
|
+
isDown: true,
|
|
52
|
+
start: { x: 100, y: 100, timestamp: 0 },
|
|
53
|
+
current: { x: 105, y: 130, timestamp: 100 }, // 5px horizontal, 30px vertical
|
|
54
|
+
pointerId: 1,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const { result } = renderHook(() =>
|
|
58
|
+
useDirectionalLock({ tracking, lockThreshold: 10 }),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
expect(result.current.lockedAxis).toBe("vertical");
|
|
62
|
+
expect(result.current.isLocked).toBe(true);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("does not lock when movement is below threshold", () => {
|
|
66
|
+
const tracking = createTrackingState({
|
|
67
|
+
isDown: true,
|
|
68
|
+
start: { x: 100, y: 100, timestamp: 0 },
|
|
69
|
+
current: { x: 105, y: 103, timestamp: 100 }, // 5px horizontal, 3px vertical
|
|
70
|
+
pointerId: 1,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const { result } = renderHook(() =>
|
|
74
|
+
useDirectionalLock({ tracking, lockThreshold: 10 }),
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
expect(result.current.lockedAxis).toBe(null);
|
|
78
|
+
expect(result.current.isLocked).toBe(false);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("does not lock when movement is diagonal (ambiguous)", () => {
|
|
82
|
+
const tracking = createTrackingState({
|
|
83
|
+
isDown: true,
|
|
84
|
+
start: { x: 100, y: 100, timestamp: 0 },
|
|
85
|
+
current: { x: 120, y: 118, timestamp: 100 }, // 20px horizontal, 18px vertical - ratio ~1.1
|
|
86
|
+
pointerId: 1,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const { result } = renderHook(() =>
|
|
90
|
+
useDirectionalLock({ tracking, lockThreshold: 10 }),
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
// Movement exceeds threshold but direction is ambiguous
|
|
94
|
+
expect(result.current.lockedAxis).toBe(null);
|
|
95
|
+
expect(result.current.isLocked).toBe(false);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("locks with negative movement values", () => {
|
|
99
|
+
const tracking = createTrackingState({
|
|
100
|
+
isDown: true,
|
|
101
|
+
start: { x: 100, y: 100, timestamp: 0 },
|
|
102
|
+
current: { x: 70, y: 95, timestamp: 100 }, // -30px horizontal, -5px vertical
|
|
103
|
+
pointerId: 1,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const { result } = renderHook(() =>
|
|
107
|
+
useDirectionalLock({ tracking, lockThreshold: 10 }),
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
expect(result.current.lockedAxis).toBe("horizontal");
|
|
111
|
+
expect(result.current.isLocked).toBe(true);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe("lock persistence", () => {
|
|
116
|
+
it("maintains lock once determined", () => {
|
|
117
|
+
const initialTracking = createTrackingState({
|
|
118
|
+
isDown: true,
|
|
119
|
+
start: { x: 100, y: 100, timestamp: 0 },
|
|
120
|
+
current: { x: 130, y: 105, timestamp: 100 }, // Horizontal
|
|
121
|
+
pointerId: 1,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const { result, rerender } = renderHook(
|
|
125
|
+
({ tracking }) => useDirectionalLock({ tracking }),
|
|
126
|
+
{ initialProps: { tracking: initialTracking } },
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
expect(result.current.lockedAxis).toBe("horizontal");
|
|
130
|
+
|
|
131
|
+
// Update to more vertical movement
|
|
132
|
+
const updatedTracking = createTrackingState({
|
|
133
|
+
isDown: true,
|
|
134
|
+
start: { x: 100, y: 100, timestamp: 0 },
|
|
135
|
+
current: { x: 130, y: 200, timestamp: 200 }, // Now more vertical
|
|
136
|
+
pointerId: 1,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
rerender({ tracking: updatedTracking });
|
|
140
|
+
|
|
141
|
+
// Should still be locked to horizontal
|
|
142
|
+
expect(result.current.lockedAxis).toBe("horizontal");
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
describe("reset behavior", () => {
|
|
147
|
+
it("resets lock when pointer is released", () => {
|
|
148
|
+
const downTracking = createTrackingState({
|
|
149
|
+
isDown: true,
|
|
150
|
+
start: { x: 100, y: 100, timestamp: 0 },
|
|
151
|
+
current: { x: 130, y: 105, timestamp: 100 },
|
|
152
|
+
pointerId: 1,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const { result, rerender } = renderHook(
|
|
156
|
+
({ tracking }) => useDirectionalLock({ tracking }),
|
|
157
|
+
{ initialProps: { tracking: downTracking } },
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
expect(result.current.lockedAxis).toBe("horizontal");
|
|
161
|
+
|
|
162
|
+
// Release pointer
|
|
163
|
+
const upTracking = createTrackingState({
|
|
164
|
+
isDown: false,
|
|
165
|
+
start: null,
|
|
166
|
+
current: null,
|
|
167
|
+
pointerId: null,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
rerender({ tracking: upTracking });
|
|
171
|
+
|
|
172
|
+
expect(result.current.lockedAxis).toBe(null);
|
|
173
|
+
expect(result.current.isLocked).toBe(false);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("can manually reset lock and will re-lock based on tracking state", () => {
|
|
177
|
+
const tracking = createTrackingState({
|
|
178
|
+
isDown: true,
|
|
179
|
+
start: { x: 100, y: 100, timestamp: 0 },
|
|
180
|
+
current: { x: 130, y: 105, timestamp: 100 },
|
|
181
|
+
pointerId: 1,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
const { result } = renderHook(() =>
|
|
185
|
+
useDirectionalLock({ tracking }),
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
expect(result.current.lockedAxis).toBe("horizontal");
|
|
189
|
+
|
|
190
|
+
act(() => {
|
|
191
|
+
result.current.reset();
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// Note: reset() sets lockedAxis to null, but the effect will
|
|
195
|
+
// immediately re-evaluate and re-lock based on tracking state.
|
|
196
|
+
// This is expected behavior - manual reset is primarily useful
|
|
197
|
+
// when combined with updated tracking state.
|
|
198
|
+
// The lock will be recalculated on the next effect run.
|
|
199
|
+
expect(result.current.lockedAxis).toBe("horizontal");
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
describe("threshold configuration", () => {
|
|
204
|
+
it("respects custom lock threshold", () => {
|
|
205
|
+
const tracking = createTrackingState({
|
|
206
|
+
isDown: true,
|
|
207
|
+
start: { x: 100, y: 100, timestamp: 0 },
|
|
208
|
+
current: { x: 115, y: 103, timestamp: 100 }, // 15px horizontal
|
|
209
|
+
pointerId: 1,
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
const { result: resultLow } = renderHook(() =>
|
|
213
|
+
useDirectionalLock({ tracking, lockThreshold: 10 }),
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
const { result: resultHigh } = renderHook(() =>
|
|
217
|
+
useDirectionalLock({ tracking, lockThreshold: 20 }),
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
expect(resultLow.current.isLocked).toBe(true);
|
|
221
|
+
expect(resultHigh.current.isLocked).toBe(false);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
describe("edge cases", () => {
|
|
226
|
+
it("handles zero movement", () => {
|
|
227
|
+
const tracking = createTrackingState({
|
|
228
|
+
isDown: true,
|
|
229
|
+
start: { x: 100, y: 100, timestamp: 0 },
|
|
230
|
+
current: { x: 100, y: 100, timestamp: 100 }, // No movement
|
|
231
|
+
pointerId: 1,
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
const { result } = renderHook(() =>
|
|
235
|
+
useDirectionalLock({ tracking }),
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
expect(result.current.lockedAxis).toBe(null);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it("handles missing start position", () => {
|
|
242
|
+
const tracking = createTrackingState({
|
|
243
|
+
isDown: true,
|
|
244
|
+
start: null,
|
|
245
|
+
current: { x: 130, y: 105, timestamp: 100 },
|
|
246
|
+
pointerId: 1,
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const { result } = renderHook(() =>
|
|
250
|
+
useDirectionalLock({ tracking }),
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
expect(result.current.lockedAxis).toBe(null);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it("handles missing current position", () => {
|
|
257
|
+
const tracking = createTrackingState({
|
|
258
|
+
isDown: true,
|
|
259
|
+
start: { x: 100, y: 100, timestamp: 0 },
|
|
260
|
+
current: null,
|
|
261
|
+
pointerId: 1,
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
const { result } = renderHook(() =>
|
|
265
|
+
useDirectionalLock({ tracking }),
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
expect(result.current.lockedAxis).toBe(null);
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
});
|