react-panel-layout 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{FloatingPanelFrame-D9Cp2al1.cjs → FloatingPanelFrame-CEmXDvUA.cjs} +2 -2
- package/dist/FloatingPanelFrame-CEmXDvUA.cjs.map +1 -0
- package/dist/{FloatingPanelFrame-6W5OexYe.js → FloatingPanelFrame-SgYLc6Ud.js} +12 -15
- package/dist/FloatingPanelFrame-SgYLc6Ud.js.map +1 -0
- package/dist/FloatingWindow-BpdOpg_L.js +400 -0
- package/dist/FloatingWindow-BpdOpg_L.js.map +1 -0
- package/dist/FloatingWindow-TCDNY5gE.cjs +2 -0
- package/dist/FloatingWindow-TCDNY5gE.cjs.map +1 -0
- package/dist/GridLayout-B4VRsC0r.cjs +2 -0
- package/dist/GridLayout-B4VRsC0r.cjs.map +1 -0
- package/dist/GridLayout-BltqeCPK.js +927 -0
- package/dist/GridLayout-BltqeCPK.js.map +1 -0
- package/dist/HorizontalDivider-B5Z-KZLk.cjs +2 -0
- package/dist/HorizontalDivider-B5Z-KZLk.cjs.map +1 -0
- package/dist/HorizontalDivider-WF1k_qND.js +30 -0
- package/dist/HorizontalDivider-WF1k_qND.js.map +1 -0
- package/dist/PanelSystem-Bs8bQwQF.cjs +3 -0
- package/dist/PanelSystem-Bs8bQwQF.cjs.map +1 -0
- package/dist/PanelSystem-Dr1TBhxM.js +1946 -0
- package/dist/PanelSystem-Dr1TBhxM.js.map +1 -0
- package/dist/ResizeHandle-CScipO5l.cjs +2 -0
- package/dist/ResizeHandle-CScipO5l.cjs.map +1 -0
- package/dist/ResizeHandle-CdA_JYfN.js +120 -0
- package/dist/ResizeHandle-CdA_JYfN.js.map +1 -0
- package/dist/SwipePivotTabBar-BGO9X94m.js +407 -0
- package/dist/SwipePivotTabBar-BGO9X94m.js.map +1 -0
- package/dist/SwipePivotTabBar-BrQismcZ.cjs +2 -0
- package/dist/SwipePivotTabBar-BrQismcZ.cjs.map +1 -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 +18 -4
- 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 +110 -0
- package/dist/hooks/gesture/thresholdValue.d.ts +44 -0
- package/dist/hooks/gesture/types.d.ts +254 -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 +40 -0
- package/dist/hooks/useAnimatedVisibility.d.ts +58 -0
- package/dist/hooks/useAnimationFrame.d.ts +84 -0
- package/dist/hooks/useSnapAnimation.d.ts +54 -0
- package/dist/hooks/useSwipeContentTransform.d.ts +79 -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/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 +89 -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 +73 -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 +63 -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 +980 -0
- package/dist/stack.js.map +1 -0
- package/dist/sticky-header/StickyArea.d.ts +38 -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 +65 -174
- package/dist/sticky-header.js.map +1 -1
- package/dist/styles-DPPuJ0sf.js +57 -0
- package/dist/styles-DPPuJ0sf.js.map +1 -0
- package/dist/styles-qf6ptVLD.cjs +2 -0
- package/dist/styles-qf6ptVLD.cjs.map +1 -0
- package/dist/types.d.ts +12 -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-CKdhGXd0.js +46 -0
- package/dist/useDocumentPointerEvents-CKdhGXd0.js.map +1 -0
- package/dist/useDocumentPointerEvents-ChqrKXDk.cjs +2 -0
- package/dist/useDocumentPointerEvents-ChqrKXDk.cjs.map +1 -0
- package/dist/useEffectEvent-Dp7HLCf0.js +13 -0
- package/dist/useEffectEvent-Dp7HLCf0.js.map +1 -0
- package/dist/useEffectEvent-huSsGUnl.cjs +2 -0
- package/dist/useEffectEvent-huSsGUnl.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/window/index.d.ts +61 -0
- package/dist/window.cjs +2 -0
- package/dist/window.cjs.map +1 -0
- package/dist/window.js +149 -0
- package/dist/window.js.map +1 -0
- package/docs/design-tokens.md +405 -0
- package/package.json +29 -4
- package/src/PanelSystemContext.tsx +88 -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 +282 -0
- package/src/components/window/DrawerLayers.tsx +58 -0
- package/src/components/window/FloatingWindow.tsx +95 -0
- package/src/components/window/PopupLayerPortal.tsx +218 -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 +261 -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/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/menu/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 +289 -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.tsx +217 -0
- package/src/demo/pages/Stack/components/StackTablet.module.css +299 -0
- package/src/demo/pages/Stack/components/StackTablet.tsx +401 -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 +193 -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/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 +237 -0
- package/src/hooks/gesture/testing/createGestureSimulator.ts +310 -0
- package/src/hooks/gesture/thresholdValue.spec.ts +103 -0
- package/src/hooks/gesture/thresholdValue.ts +77 -0
- package/src/hooks/gesture/types.ts +290 -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 +454 -0
- package/src/hooks/gesture/useEdgeSwipeInput.ts +131 -0
- package/src/hooks/gesture/useNativeGestureGuard.spec.ts +413 -0
- package/src/hooks/gesture/useNativeGestureGuard.ts +133 -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 +87 -0
- package/src/hooks/useAnimatedVisibility.spec.ts +257 -0
- package/src/hooks/useAnimatedVisibility.ts +146 -0
- package/src/hooks/useAnimationFrame.ts +200 -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/useResizeObserver.tsx +81 -0
- package/src/hooks/useScrollContainer.ts +79 -0
- package/src/hooks/useSnapAnimation.ts +128 -0
- package/src/hooks/useSwipeContentTransform.spec.ts +133 -0
- package/src/hooks/useSwipeContentTransform.ts +235 -0
- package/src/hooks/useTransitionState.ts +95 -0
- package/src/index.tsx +88 -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 +304 -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 +167 -0
- package/src/modules/pivot/SwipePivotContent.spec.tsx +464 -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 +865 -0
- package/src/modules/pivot/SwipePivotTabBar.tsx +523 -0
- package/src/modules/pivot/index.ts +8 -0
- package/src/modules/pivot/scaleInputState.spec.ts +210 -0
- package/src/modules/pivot/scaleInputState.ts +66 -0
- package/src/modules/pivot/types.ts +139 -0
- package/src/modules/pivot/usePivot.spec.ts +621 -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 +649 -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 +1277 -0
- package/src/modules/stack/SwipeStackContent.tsx +356 -0
- package/src/modules/stack/SwipeStackOutlet.spec.tsx +252 -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/types.ts +226 -0
- package/src/modules/stack/useStackAnimationState.spec.ts +186 -0
- package/src/modules/stack/useStackAnimationState.ts +138 -0
- package/src/modules/stack/useStackNavigation.spec.ts +477 -0
- package/src/modules/stack/useStackNavigation.tsx +336 -0
- package/src/modules/stack/useStackSwipeInput.spec.ts +276 -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 +221 -0
- package/src/sticky-header/index.ts +18 -0
- package/src/sticky-header/types.ts +68 -0
- package/src/types.ts +323 -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 +67 -0
- package/dist/FloatingPanelFrame-6W5OexYe.js.map +0 -1
- package/dist/FloatingPanelFrame-D9Cp2al1.cjs.map +0 -1
- package/dist/GridLayout-BzrIDrC9.js +0 -1465
- package/dist/GridLayout-BzrIDrC9.js.map +0 -1
- package/dist/GridLayout-ZrOhoLLB.cjs +0 -2
- package/dist/GridLayout-ZrOhoLLB.cjs.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-BS-DGfwd.cjs +0 -2
- package/dist/usePivot-BS-DGfwd.cjs.map +0 -1
- package/dist/usePivot-BvOGxLQQ.js +0 -124
- package/dist/usePivot-BvOGxLQQ.js.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const E=require("react/jsx-runtime"),Y=require("react"),z=require("./styles-qf6ptVLD.cjs"),H=require("./useContentCache-DqXtLrLs.cjs");function J(s){const o=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const n in s)if(n!=="default"){const d=Object.getOwnPropertyDescriptor(s,n);Object.defineProperty(o,n,d.get?d:{enumerable:!0,get:()=>s[n]})}}return o.default=s,Object.freeze(o)}const t=J(Y),K=1e3;function Q({isVisible:s,leaveAnimation:o,skipAnimation:n=!1,animationTimeout:d=K}){const a=t.useRef(s),[r,u]=t.useState(!1),l=t.useRef(null);t.useEffect(()=>()=>{l.current&&clearTimeout(l.current)},[]),t.useEffect(()=>{const i=a.current;a.current=s,l.current&&(clearTimeout(l.current),l.current=null),i&&!s?n||!o||o==="none"?u(!1):(u(!0),l.current=setTimeout(()=>{u(!1)},d)):!i&&s&&u(!1)},[s,o,n,d]);const R=t.useCallback(i=>{i.target===i.currentTarget&&r&&(l.current&&(clearTimeout(l.current),l.current=null),u(!1))},[r]),y=s||r;return{state:{shouldDisplay:y,isAnimatingOut:r},props:{onAnimationEnd:R},style:{display:y?"block":"none"}}}const Z={position:"absolute",inset:0,width:"100%",height:"100%"},W=t.memo(({id:s,isActive:o,transitionMode:n,children:d})=>{const a=Q({isVisible:o,leaveAnimation:n==="css"?z.PIVOT_ANIMATION_LEAVE:void 0,skipAnimation:n!=="css"}),r=t.useMemo(()=>{const l={...Z,...a.style,pointerEvents:o?"auto":"none"};return n==="css"&&(l.animation=o?z.PIVOT_ANIMATION_ENTER:z.PIVOT_ANIMATION_LEAVE),l},[o,n,a.style]),u=E.jsx("div",{"data-pivot-content":s,"data-active":o?"true":"false",style:r,...a.props,children:d});return n==="none"?E.jsx(t.Activity,{mode:o?"visible":"hidden",children:u}):u}),X=t.createContext(null),ee=t.memo(()=>{const s=t.useContext(X);if(!s)throw new Error("PivotOutlet must be used within usePivot");const[,o]=t.useReducer(r=>r+1,0);t.useEffect(()=>s.subscribe(o),[s]);const{items:n,activeId:d,transitionMode:a}=s.getState();return E.jsx(E.Fragment,{children:n.map(r=>E.jsx(W,{id:r.id,isActive:r.id===d,transitionMode:a,children:r.cache?s.getCachedContent(r.id):r.content},r.id))})});function te(s){const{items:o,activeId:n,defaultActiveId:d,onActiveChange:a,transitionMode:r="css",navigationMode:u="linear"}=s,l=n!==void 0,[R,y]=t.useState(()=>{if(d!==void 0)return d;const e=o.find(c=>c.disabled!==!0);if(!e)throw new Error("usePivot: No enabled items provided");return e.id}),i=l?n:R,[v,M]=t.useState(!1),P=t.useCallback((e,c)=>{const g=o.find(x=>x.id===e);if(!g||g.disabled)return;const h=c?.animated??r==="css";M(h),l||y(e),a?.(e)},[o,l,a,r]),w=t.useCallback(()=>{M(!1)},[]),N=t.useCallback(e=>e===i,[i]),I=t.useMemo(()=>o.filter(e=>e.disabled!==!0),[o]),f=t.useMemo(()=>{const e=I.findIndex(c=>c.id===i);return e===-1?0:e},[I,i]),m=I.length,j=t.useCallback(e=>{if(e===0)return!1;if(u==="loop")return m>=2;const c=f+e;return c>=0&&c<m},[f,m,u]),F=t.useCallback(e=>{const c=f+e;return u==="loop"?(c%m+m)%m:c},[f,u,m]),b=t.useCallback((e,c)=>{if(!j(e))return;const g=F(e),h=I[g];h&&P(h.id,c)},[j,F,I,P]),_=t.useCallback(e=>{const c=I.findIndex(h=>h.id===e);if(c===-1)return null;if(u==="linear"){const h=c-f;return Math.abs(h)>1?null:h}const g=((c-f)%m+m)%m;return g===0?0:g===1?1:m-g===1?-1:null},[I,f,u,m]),k=t.useCallback(e=>{const c=I.findIndex(x=>x.id===e);if(c===-1)return null;if(u==="linear")return c-f;const g=((c-f)%m+m)%m,h=m-g;return g<=h?g:-h},[I,f,u,m]),q=t.useCallback(e=>({"data-pivot-item":e,"data-active":e===i?"true":"false","aria-selected":e===i,tabIndex:e===i?0:-1,onClick:()=>{P(e)}}),[i,P]),D=t.useMemo(()=>({position:"relative",width:"100%",height:"100%"}),[]),T=t.useRef({items:o,activeId:i,transitionMode:r});T.current={items:o,activeId:i,transitionMode:r};const S=t.useRef(new Set);t.useEffect(()=>{S.current.forEach(e=>e())},[i,r]);const U=t.useCallback(e=>T.current.items.find(g=>g.id===e)?.content??null,[]),p=t.useMemo(()=>o.map(e=>e.id),[o]),{getCachedContent:A}=H.useContentCache({resolveContent:U,validIds:p}),O=t.useMemo(()=>({getState:()=>T.current,subscribe:e=>(S.current.add(e),()=>S.current.delete(e)),getCachedContent:A}),[A]),C=t.useMemo(()=>{const e=()=>E.jsx(X.Provider,{value:O,children:E.jsx("div",{style:D,"data-pivot-container":!0,children:E.jsx(ee,{})})});return e.displayName="PivotOutlet",e},[O,D]);return{activeId:i,setActiveId:P,isActive:N,getItemProps:q,Outlet:C,go:b,canGo:j,activeIndex:f,itemCount:m,isAnimating:v,endAnimation:w,navigationMode:u,getVirtualPosition:_,getItemPosition:k}}const ne=300,re=(s,o)=>s.phase==="idle"?0:o==="horizontal"?s.displacement.x:s.displacement.y,$=(s,o)=>(s%o+o)%o,se=(s,o,n,d)=>{const a=o+s;return d==="linear"?a<0||a>=n?null:a:$(a,n)},oe=t.memo(({slotPosition:s,item:o,itemIndex:n,isActive:d,centerX:a,tabWidth:r,viewportWidth:u,offsetPx:l,axis:R,renderTab:y})=>{const i=s*r,v=a+i+l,M=v+r>0&&v<u,P=R==="horizontal"?"translateX":"translateY";return E.jsx("div",{"data-pivot-tab":o.id,"data-slot":s,"data-active":d?"true":"false",style:{position:"absolute",left:a,top:0,width:r,height:"100%",visibility:M?"visible":"hidden",willChange:"transform",transform:`${P}(${i+l}px)`},children:y(o,d,n)})}),B=s=>s===1?1:1-Math.pow(2,-10*s);function ce({items:s,activeId:o,activeIndex:n,itemCount:d,inputState:a,tabWidth:r,viewportWidth:u,navigationMode:l="linear",axis:R="horizontal",renderTab:y,animationDuration:i=ne,fixedTabs:v=!1,renderIndicator:M}){const P=re(a,R),w=a.phase==="swiping"||a.phase==="tracking",[N,I]=t.useState(0),f=t.useRef(null),[m,j]=t.useState(n*r),F=t.useRef(n*r),b=t.useRef(null),_=t.useRef(null);t.useEffect(()=>{F.current=m},[m]);const k=t.useRef(n),q=Math.ceil(u/r/2)+1,D=(u-r)/2;t.useEffect(()=>{if(!v||!w)return;const p=n*r-P;_.current=p,j(p)},[v,w,n,r,P]),t.useEffect(()=>{if(!v||w)return;const p=n*r,A=_.current??F.current;if(_.current=null,Math.abs(A-p)<1){j(p);return}b.current&&cancelAnimationFrame(b.current.rafId);const O=performance.now(),C=A,e=c=>{const g=c-O,h=Math.min(g/i,1),x=B(h),V=C+(p-C)*x;j(V),h<1?b.current={rafId:requestAnimationFrame(e)}:(b.current=null,j(p))};b.current={rafId:requestAnimationFrame(e)}},[v,w,n,r,i]),t.useEffect(()=>{if(v||k.current===n)return;const p=k.current;k.current=n;let A;if(l==="loop"){const g=$(n-p,d),h=d-g;A=g<=h?g:-h}else A=n-p;const O=-A*r,C=w?P:N;if(f.current&&cancelAnimationFrame(f.current.rafId),Math.abs(C-O)<1){I(0);return}const e=performance.now(),c=g=>{const h=g-e,x=Math.min(h/i,1),V=B(x),L=C-O,G=L*(1-V);I(G),x<1?f.current={startTime:e,startOffset:L,targetOffset:0,rafId:requestAnimationFrame(c)}:(f.current=null,I(0))};f.current={startTime:e,startOffset:C-O,targetOffset:0,rafId:requestAnimationFrame(c)}},[v,n,d,r,i,l,P,w,N]),t.useEffect(()=>{v&&(k.current=n)},[v,n]),t.useEffect(()=>()=>{f.current&&cancelAnimationFrame(f.current.rafId),b.current&&cancelAnimationFrame(b.current.rafId)},[]);const T=w?P:N,S=f.current!==null||b.current!==null;if(t.useEffect(()=>{w&&f.current&&(cancelAnimationFrame(f.current.rafId),f.current=null,I(0))},[w]),v){const p=s.length*r,A=(u-p)/2;return E.jsxs("div",{style:{position:"relative",width:"100%",height:"100%",overflow:"hidden",display:"flex",justifyContent:"center"},children:[M?.({offsetPx:m,tabWidth:r,centerX:A,isSwiping:w,isAnimating:S}),s.map((O,C)=>E.jsx("div",{"data-pivot-tab":O.id,"data-active":C===n?"true":"false",style:{position:"relative",width:r,height:"100%",flexShrink:0},children:y(O,C===n,C)},O.id))]})}const U=[];for(let p=-q;p<=q;p++){const A=se(p,n,d,l);A!==null&&U.push({slotPosition:p,itemIndex:A,item:s[A]})}return E.jsxs("div",{style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"},children:[M?.({offsetPx:T,tabWidth:r,centerX:D,isSwiping:w,isAnimating:S}),U.map(({slotPosition:p,itemIndex:A,item:O})=>E.jsx(oe,{slotPosition:p,item:O,itemIndex:A,isActive:A===n,centerX:D,tabWidth:r,viewportWidth:u,offsetPx:T,axis:R,renderTab:y},p))]})}exports.SwipePivotTabBar=ce;exports.usePivot=te;
|
|
2
|
+
//# sourceMappingURL=SwipePivotTabBar-BrQismcZ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwipePivotTabBar-BrQismcZ.cjs","sources":["../src/hooks/useAnimatedVisibility.ts","../src/modules/pivot/PivotContent.tsx","../src/modules/pivot/usePivot.tsx","../src/modules/pivot/SwipePivotTabBar.tsx"],"sourcesContent":["/**\n * @file Hook for animation-aware visibility control.\n *\n * Common pattern for showing/hiding elements with CSS animations:\n * - If animation exists: wait for animationend before hiding\n * - If no animation: hide immediately\n * - Uses display:none for performance (removes from layout)\n * - Includes timeout fallback in case animationend doesn't fire\n */\nimport * as React from \"react\";\n\n/** Default timeout for animation fallback (ms) */\nconst DEFAULT_ANIMATION_TIMEOUT = 1000;\n\ntype AnimatedVisibilityState = {\n /** Whether element should be displayed (display: block/none) */\n shouldDisplay: boolean;\n /** Whether element is currently animating out */\n isAnimatingOut: boolean;\n};\n\ntype UseAnimatedVisibilityOptions = {\n /** Whether the element is logically visible */\n isVisible: boolean;\n /** CSS animation value for leave animation (e.g., CSS variable) */\n leaveAnimation?: string;\n /** Skip animation and hide immediately */\n skipAnimation?: boolean;\n /** Timeout for animation fallback in ms (default: 1000ms) */\n animationTimeout?: number;\n};\n\ntype UseAnimatedVisibilityResult = {\n /** Current visibility state */\n state: AnimatedVisibilityState;\n /** Props to spread on the animated element */\n props: {\n onAnimationEnd: (e: React.AnimationEvent) => void;\n };\n /** Style to apply for display control */\n style: {\n display: \"block\" | \"none\";\n };\n};\n\n/**\n * Hook for animation-aware visibility control.\n *\n * @example\n * const { state, props, style } = useAnimatedVisibility({\n * isVisible: isActive,\n * leaveAnimation: PIVOT_ANIMATION_LEAVE,\n * });\n *\n * return (\n * <div\n * style={{ ...baseStyle, ...style, animation: isActive ? enterAnim : leaveAnim }}\n * {...props}\n * >\n * {children}\n * </div>\n * );\n */\nexport function useAnimatedVisibility({\n isVisible,\n leaveAnimation,\n skipAnimation = false,\n animationTimeout = DEFAULT_ANIMATION_TIMEOUT,\n}: UseAnimatedVisibilityOptions): UseAnimatedVisibilityResult {\n const prevVisibleRef = React.useRef(isVisible);\n const [isAnimatingOut, setIsAnimatingOut] = React.useState(false);\n const timeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Clear timeout on unmount\n React.useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n React.useEffect(() => {\n const wasVisible = prevVisibleRef.current;\n prevVisibleRef.current = isVisible;\n\n // Clear any pending timeout\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n\n if (wasVisible && !isVisible) {\n // Transitioning from visible to hidden\n if (skipAnimation || !leaveAnimation || leaveAnimation === \"none\") {\n // No animation, hide immediately\n setIsAnimatingOut(false);\n } else {\n // Has animation, mark as animating out\n setIsAnimatingOut(true);\n\n // Set timeout fallback in case animationend doesn't fire\n // (e.g., CSS variable resolves to \"none\", or animation is very short)\n timeoutRef.current = setTimeout(() => {\n setIsAnimatingOut(false);\n }, animationTimeout);\n }\n } else if (!wasVisible && isVisible) {\n // Transitioning from hidden to visible\n setIsAnimatingOut(false);\n }\n }, [isVisible, leaveAnimation, skipAnimation, animationTimeout]);\n\n const handleAnimationEnd = React.useCallback(\n (e: React.AnimationEvent) => {\n // Only handle animation end for this element (not bubbled from children)\n if (e.target === e.currentTarget && isAnimatingOut) {\n // Clear timeout since animation completed normally\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n setIsAnimatingOut(false);\n }\n },\n [isAnimatingOut],\n );\n\n // Element should be displayed if:\n // - It's visible, OR\n // - It's animating out (leave animation in progress)\n const shouldDisplay = isVisible || isAnimatingOut;\n\n return {\n state: {\n shouldDisplay,\n isAnimatingOut,\n },\n props: {\n onAnimationEnd: handleAnimationEnd,\n },\n style: {\n display: shouldDisplay ? \"block\" : \"none\",\n },\n };\n}\n","/**\n * @file PivotContent component for rendering pivot items with CSS animations.\n *\n * Override via CSS custom properties:\n * - --rpl-pivot-animation-enter: Animation when becoming active\n * - --rpl-pivot-animation-leave: Animation when becoming inactive\n *\n * User defines @keyframes in their CSS and references via these tokens.\n * Example:\n * @keyframes pivotEnter {\n * from { opacity: 0; }\n * to { opacity: 1; }\n * }\n * :root { --rpl-pivot-animation-enter: pivotEnter 150ms ease-out forwards; }\n */\nimport * as React from \"react\";\nimport { PIVOT_ANIMATION_ENTER, PIVOT_ANIMATION_LEAVE } from \"../../constants/styles\";\nimport { useAnimatedVisibility } from \"../../hooks/useAnimatedVisibility\";\n\nexport type PivotContentProps = {\n id: string;\n isActive: boolean;\n transitionMode: \"css\" | \"none\";\n children: React.ReactNode;\n};\n\nconst baseStyle: React.CSSProperties = {\n position: \"absolute\",\n inset: 0,\n width: \"100%\",\n height: \"100%\",\n};\n\n/**\n * Renders pivot content with CSS animation support.\n *\n * When transitionMode=\"css\": Applies enter/leave animations with display:none when hidden.\n * When transitionMode=\"none\": Uses React.Activity for memory optimization.\n */\nexport const PivotContent: React.FC<PivotContentProps> = React.memo(({ id, isActive, transitionMode, children }) => {\n const visibility = useAnimatedVisibility({\n isVisible: isActive,\n leaveAnimation: transitionMode === \"css\" ? PIVOT_ANIMATION_LEAVE : undefined,\n skipAnimation: transitionMode !== \"css\",\n });\n\n const style = React.useMemo<React.CSSProperties>(() => {\n const s: React.CSSProperties = {\n ...baseStyle,\n ...visibility.style,\n pointerEvents: isActive ? \"auto\" : \"none\",\n };\n\n if (transitionMode === \"css\") {\n s.animation = isActive ? PIVOT_ANIMATION_ENTER : PIVOT_ANIMATION_LEAVE;\n }\n\n return s;\n }, [isActive, transitionMode, visibility.style]);\n\n const content = (\n <div\n data-pivot-content={id}\n data-active={isActive ? \"true\" : \"false\"}\n style={style}\n {...visibility.props}\n >\n {children}\n </div>\n );\n\n if (transitionMode === \"none\") {\n return <React.Activity mode={isActive ? \"visible\" : \"hidden\"}>{content}</React.Activity>;\n }\n\n return content;\n});\n","/**\n * @file Headless hook for managing Pivot (content switching) behavior.\n *\n * Includes content caching to preserve React component state across re-renders.\n * This is essential for maintaining internal state when parent components\n * re-create the items array.\n */\nimport * as React from \"react\";\nimport type { UsePivotOptions, UsePivotResult, PivotItemProps, PivotItem, PivotNavigationOptions } from \"./types\";\nimport { PivotContent } from \"./PivotContent\";\nimport { useContentCache } from \"../../hooks/useContentCache\";\n\n/**\n * Context for sharing pivot state with Outlet component.\n * Uses a ref-based approach to avoid re-creating the Outlet component.\n * Includes content cache to preserve component state.\n */\ntype PivotOutletContextValue = {\n getState: () => {\n items: ReadonlyArray<PivotItem>;\n activeId: string;\n transitionMode: \"css\" | \"none\";\n };\n subscribe: (callback: () => void) => () => void;\n /**\n * Get cached content for an item. Returns the same ReactNode reference\n * for the same item ID to prevent remounting on parent re-renders.\n */\n getCachedContent: (itemId: string) => React.ReactNode | null;\n};\n\nconst PivotOutletContext = React.createContext<PivotOutletContextValue | null>(null);\n\n/**\n * Stable Outlet component that subscribes to state changes.\n * This prevents remounting when activeId changes.\n * Uses cached content only when item.cache is true.\n */\nconst PivotOutletInner: React.FC = React.memo(() => {\n const ctx = React.useContext(PivotOutletContext);\n if (!ctx) {\n throw new Error(\"PivotOutlet must be used within usePivot\");\n }\n\n const [, forceUpdate] = React.useReducer((x) => x + 1, 0);\n\n React.useEffect(() => {\n return ctx.subscribe(forceUpdate);\n }, [ctx]);\n\n const { items, activeId, transitionMode } = ctx.getState();\n\n return (\n <>\n {items.map((item) => (\n <PivotContent key={item.id} id={item.id} isActive={item.id === activeId} transitionMode={transitionMode}>\n {item.cache ? ctx.getCachedContent(item.id) : item.content}\n </PivotContent>\n ))}\n </>\n );\n});\n\n/**\n * Headless hook for managing content switching within a scope.\n * Provides behavior only - UI is fully customizable.\n *\n * @example\n * ```tsx\n * const { activeId, getItemProps, Outlet } = usePivot({\n * items: [\n * { id: 'home', label: 'Home', content: <HomePage /> },\n * { id: 'settings', label: 'Settings', content: <SettingsPage /> }\n * ],\n * defaultActiveId: 'home'\n * });\n *\n * return (\n * <div>\n * <nav>\n * {items.map((item) => (\n * <button key={item.id} {...getItemProps(item.id)}>{item.label}</button>\n * ))}\n * </nav>\n * <Outlet />\n * </div>\n * );\n * ```\n */\nexport function usePivot<TId extends string = string>(options: UsePivotOptions<TId>): UsePivotResult<TId> {\n const { items, activeId: controlledActiveId, defaultActiveId, onActiveChange, transitionMode = \"css\", navigationMode = \"linear\" } = options;\n\n const isControlled = controlledActiveId !== undefined;\n\n const [uncontrolledActiveId, setUncontrolledActiveId] = React.useState<TId>(() => {\n if (defaultActiveId !== undefined) {\n return defaultActiveId;\n }\n const firstEnabled = items.find((item) => item.disabled !== true);\n if (!firstEnabled) {\n throw new Error(\"usePivot: No enabled items provided\");\n }\n return firstEnabled.id;\n });\n\n const activeId = isControlled ? controlledActiveId : uncontrolledActiveId;\n\n // Animation state\n const [isAnimating, setIsAnimating] = React.useState(false);\n\n const setActiveId = React.useCallback(\n (id: TId, options?: PivotNavigationOptions) => {\n const target = items.find((item) => item.id === id);\n if (!target) {\n return;\n }\n if (target.disabled) {\n return;\n }\n\n // Determine if we should animate\n const shouldAnimate = options?.animated ?? (transitionMode === \"css\");\n setIsAnimating(shouldAnimate);\n\n if (!isControlled) {\n setUncontrolledActiveId(id);\n }\n onActiveChange?.(id);\n },\n [items, isControlled, onActiveChange, transitionMode],\n );\n\n // End animation callback\n const endAnimation = React.useCallback(() => {\n setIsAnimating(false);\n }, []);\n\n const isActive = React.useCallback((id: TId): boolean => id === activeId, [activeId]);\n\n // Get only enabled items for navigation\n const enabledItems = React.useMemo(\n () => items.filter((item) => item.disabled !== true),\n [items],\n );\n\n // Current index in enabled items\n const activeIndex = React.useMemo(() => {\n const index = enabledItems.findIndex((item) => item.id === activeId);\n return index === -1 ? 0 : index;\n }, [enabledItems, activeId]);\n\n // Total count of enabled items\n const itemCount = enabledItems.length;\n\n // Check if navigation in a direction is possible\n const canGo = React.useCallback(\n (direction: number): boolean => {\n if (direction === 0) {\n return false;\n }\n // In loop mode, navigation is always possible if there are 2+ items\n if (navigationMode === \"loop\") {\n return itemCount >= 2;\n }\n // Linear mode: check bounds\n const targetIndex = activeIndex + direction;\n return targetIndex >= 0 && targetIndex < itemCount;\n },\n [activeIndex, itemCount, navigationMode],\n );\n\n // Compute target index with optional wrap-around\n const computeTargetIndex = React.useCallback(\n (direction: number): number => {\n const rawIndex = activeIndex + direction;\n if (navigationMode === \"loop\") {\n return ((rawIndex % itemCount) + itemCount) % itemCount;\n }\n return rawIndex;\n },\n [activeIndex, navigationMode, itemCount],\n );\n\n // Navigate in a direction\n const go = React.useCallback(\n (direction: number, options?: PivotNavigationOptions): void => {\n if (!canGo(direction)) {\n return;\n }\n const targetIndex = computeTargetIndex(direction);\n const targetItem = enabledItems[targetIndex];\n if (targetItem) {\n setActiveId(targetItem.id, options);\n }\n },\n [canGo, computeTargetIndex, enabledItems, setActiveId],\n );\n\n // Get virtual position for an item relative to active (for loop mode support)\n const getVirtualPosition = React.useCallback(\n (id: TId): -1 | 0 | 1 | null => {\n const itemIndex = enabledItems.findIndex((item) => item.id === id);\n if (itemIndex === -1) {\n return null;\n }\n\n if (navigationMode === \"linear\") {\n const rawOffset = itemIndex - activeIndex;\n if (Math.abs(rawOffset) > 1) {\n return null;\n }\n return rawOffset as -1 | 0 | 1;\n }\n\n // Loop mode: find shortest path\n const forwardDist = ((itemIndex - activeIndex) % itemCount + itemCount) % itemCount;\n if (forwardDist === 0) {\n return 0;\n }\n if (forwardDist === 1) {\n return 1; // Item is next\n }\n if (itemCount - forwardDist === 1) {\n return -1; // Item is previous\n }\n return null;\n },\n [enabledItems, activeIndex, navigationMode, itemCount],\n );\n\n // Get position for any item relative to active (for viewport mode)\n const getItemPosition = React.useCallback(\n (id: TId): number | null => {\n const itemIndex = enabledItems.findIndex((item) => item.id === id);\n if (itemIndex === -1) {\n return null;\n }\n\n if (navigationMode === \"linear\") {\n return itemIndex - activeIndex;\n }\n\n // Loop mode: find shortest path\n const forwardDist = ((itemIndex - activeIndex) % itemCount + itemCount) % itemCount;\n const backwardDist = itemCount - forwardDist;\n\n // Return the shorter path (prefer forward on tie)\n if (forwardDist <= backwardDist) {\n return forwardDist;\n }\n return -backwardDist;\n },\n [enabledItems, activeIndex, navigationMode, itemCount],\n );\n\n const getItemProps = React.useCallback(\n (id: TId): PivotItemProps => ({\n \"data-pivot-item\": id,\n \"data-active\": (id === activeId ? \"true\" : \"false\") as \"true\" | \"false\",\n \"aria-selected\": id === activeId,\n tabIndex: id === activeId ? 0 : -1,\n onClick: () => {\n setActiveId(id);\n },\n }),\n [activeId, setActiveId],\n );\n\n const containerStyle: React.CSSProperties = React.useMemo(\n () => ({\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n }),\n [],\n );\n\n // Store state in a ref for stable getState function\n const stateRef = React.useRef({\n items,\n activeId,\n transitionMode,\n });\n\n // Update ref when state changes\n stateRef.current = {\n items,\n activeId,\n transitionMode,\n };\n\n // Subscribers for state changes\n const subscribersRef = React.useRef(new Set<() => void>());\n\n // Notify subscribers when activeId changes\n React.useEffect(() => {\n subscribersRef.current.forEach((callback) => callback());\n }, [activeId, transitionMode]);\n\n // Content resolver for useContentCache\n const resolveContent = React.useCallback(\n (itemId: string): React.ReactNode | null => {\n const item = stateRef.current.items.find((i) => i.id === itemId);\n return item?.content ?? null;\n },\n [],\n );\n\n // Valid IDs for cache cleanup (cast to string[] for useContentCache compatibility)\n const validIds = React.useMemo((): readonly string[] => items.map((i) => i.id), [items]);\n\n // Use shared content cache hook\n const { getCachedContent } = useContentCache({\n resolveContent,\n validIds,\n });\n\n // Stable context value (never changes)\n const contextValue = React.useMemo<PivotOutletContextValue>(\n () => ({\n getState: () => stateRef.current,\n subscribe: (callback) => {\n subscribersRef.current.add(callback);\n return () => subscribersRef.current.delete(callback);\n },\n getCachedContent,\n }),\n [getCachedContent],\n );\n\n // Stable Outlet component (reference never changes)\n const Outlet = React.useMemo(() => {\n const OutletComponent: React.FC = () => (\n <PivotOutletContext.Provider value={contextValue}>\n <div style={containerStyle} data-pivot-container>\n <PivotOutletInner />\n </div>\n </PivotOutletContext.Provider>\n );\n OutletComponent.displayName = \"PivotOutlet\";\n return OutletComponent;\n }, [contextValue, containerStyle]);\n\n return { activeId, setActiveId, isActive, getItemProps, Outlet, go, canGo, activeIndex, itemCount, isAnimating, endAnimation, navigationMode, getVirtualPosition, getItemPosition };\n}\n","/**\n * @file SwipePivotTabBar - Swipeable tab bar for pivot navigation with proper looping.\n *\n * Infinite loop model:\n * - Uses continuous scroll offset (not discrete positions)\n * - Renders tab slots at fixed positions, content determined by scroll offset\n * - Clones tabs at boundaries for seamless looping\n * - Each slot has stable key (by position), preventing remount jumps\n */\nimport * as React from \"react\";\nimport type { SwipeInputState, GestureAxis } from \"../../hooks/gesture/types.js\";\n\n/**\n * Props passed to the indicator render function.\n * Use these to position a sliding indicator (iOS-style).\n */\nexport type IndicatorRenderProps = {\n /** Current offset in pixels (includes swipe displacement and animation) */\n offsetPx: number;\n /** Width of each tab */\n tabWidth: number;\n /** Center X position where active tab is located */\n centerX: number;\n /** Whether currently swiping */\n isSwiping: boolean;\n /** Whether animation is in progress */\n isAnimating: boolean;\n};\n\nexport type SwipePivotTabBarProps<TId extends string = string> = {\n /** Tab items to render */\n items: ReadonlyArray<{ id: TId; label?: string }>;\n /** Currently active tab ID */\n activeId: TId;\n /** Index of active tab */\n activeIndex: number;\n /** Total number of items */\n itemCount: number;\n /** Current swipe input state */\n inputState: SwipeInputState;\n /** Width of each tab */\n tabWidth: number;\n /** Width of the visible viewport */\n viewportWidth: number;\n /** Navigation mode */\n navigationMode?: \"linear\" | \"loop\";\n /** Axis for swipe (horizontal or vertical) */\n axis?: GestureAxis;\n /** Render function for each tab */\n renderTab: (item: { id: TId; label?: string }, isActive: boolean, index: number) => React.ReactNode;\n /** Animation duration in ms */\n animationDuration?: number;\n /**\n * When true, tabs stay at fixed positions and only the indicator moves.\n * Use this for iOS segmented control style where the \"window\" slides over fixed tabs.\n * @default false\n */\n fixedTabs?: boolean;\n /**\n * Optional render function for a sliding indicator (iOS-style).\n * The indicator follows the active tab position during swipe and animation.\n * Rendered behind the tabs.\n *\n * When used with fixedTabs=true, only the indicator moves while tabs stay fixed.\n *\n * @example\n * ```tsx\n * renderIndicator={({ offsetPx, tabWidth, centerX }) => (\n * <div\n * style={{\n * position: 'absolute',\n * left: centerX,\n * bottom: 0,\n * width: tabWidth,\n * height: 3,\n * backgroundColor: '#007AFF',\n * transform: `translateX(${offsetPx}px)`,\n * }}\n * />\n * )}\n * ```\n */\n renderIndicator?: (props: IndicatorRenderProps) => React.ReactNode;\n};\n\nconst DEFAULT_ANIMATION_DURATION = 300;\n\n/** Get displacement value for the given axis from input state */\nconst getAxisDisplacement = (inputState: SwipeInputState, axis: GestureAxis): number => {\n if (inputState.phase === \"idle\") {\n return 0;\n }\n return axis === \"horizontal\" ? inputState.displacement.x : inputState.displacement.y;\n};\n\n/**\n * Normalize index to valid range [0, count)\n */\nconst normalizeIndex = (index: number, count: number): number => {\n return ((index % count) + count) % count;\n};\n\n/**\n * Calculate which item should appear at a given slot position.\n * For loop mode, wraps around using modulo.\n * For linear mode, returns null if out of range.\n */\nconst getItemAtPosition = (\n slotPosition: number,\n activeIndex: number,\n itemCount: number,\n navigationMode: \"linear\" | \"loop\",\n): number | null => {\n const targetIndex = activeIndex + slotPosition;\n\n if (navigationMode === \"linear\") {\n if (targetIndex < 0 || targetIndex >= itemCount) {\n return null;\n }\n return targetIndex;\n }\n\n // Loop mode: wrap around\n return normalizeIndex(targetIndex, itemCount);\n};\n\ntype TabSlotProps<TId extends string> = {\n slotPosition: number;\n item: { id: TId; label?: string };\n itemIndex: number;\n isActive: boolean;\n centerX: number;\n tabWidth: number;\n viewportWidth: number;\n offsetPx: number;\n axis: GestureAxis;\n renderTab: (item: { id: TId; label?: string }, isActive: boolean, index: number) => React.ReactNode;\n};\n\n/**\n * Tab slot component - renders a tab at a fixed slot position.\n * The slot position is stable; only the content changes based on scroll offset.\n */\nconst TabSlot = React.memo(<TId extends string>({\n slotPosition,\n item,\n itemIndex,\n isActive,\n centerX,\n tabWidth,\n viewportWidth,\n offsetPx,\n axis,\n renderTab,\n}: TabSlotProps<TId>) => {\n // Calculate visual position: centerX + slotPosition * tabWidth + offsetPx\n const basePx = slotPosition * tabWidth;\n const visualPx = centerX + basePx + offsetPx;\n\n // Check if visible in viewport\n const visible = visualPx + tabWidth > 0 && visualPx < viewportWidth;\n\n const transformFn = axis === \"horizontal\" ? \"translateX\" : \"translateY\";\n\n return (\n <div\n data-pivot-tab={item.id}\n data-slot={slotPosition}\n data-active={isActive ? \"true\" : \"false\"}\n style={{\n position: \"absolute\",\n left: centerX,\n top: 0,\n width: tabWidth,\n height: \"100%\",\n visibility: visible ? \"visible\" : \"hidden\",\n willChange: \"transform\",\n transform: `${transformFn}(${basePx + offsetPx}px)`,\n }}\n >\n {renderTab(item, isActive, itemIndex)}\n </div>\n );\n}) as <TId extends string>(props: TabSlotProps<TId>) => React.ReactElement;\n\n/**\n * Easing function for smooth animation\n */\nconst easeOutExpo = (t: number): number => {\n return t === 1 ? 1 : 1 - Math.pow(2, -10 * t);\n};\n\nexport function SwipePivotTabBar<TId extends string = string>({\n items,\n activeId,\n activeIndex,\n itemCount,\n inputState,\n tabWidth,\n viewportWidth,\n navigationMode = \"linear\",\n axis = \"horizontal\",\n renderTab,\n animationDuration = DEFAULT_ANIMATION_DURATION,\n fixedTabs = false,\n renderIndicator,\n}: SwipePivotTabBarProps<TId>): React.ReactElement {\n const displacement = getAxisDisplacement(inputState, axis);\n const isSwiping = inputState.phase === \"swiping\" || inputState.phase === \"tracking\";\n\n // ============================================================\n // Animation state for SLOT-BASED mode (scrolling tabs)\n // ============================================================\n const [animatedOffset, setAnimatedOffset] = React.useState(0);\n const animationRef = React.useRef<{\n startTime: number;\n startOffset: number;\n targetOffset: number;\n rafId: number;\n } | null>(null);\n\n // ============================================================\n // Animation state for FIXED TABS mode (iOS-style indicator)\n // Tracks the actual indicator position in pixels\n // ============================================================\n const [indicatorPosition, setIndicatorPosition] = React.useState(activeIndex * tabWidth);\n const indicatorPositionRef = React.useRef(activeIndex * tabWidth); // Track current position for animation start\n const fixedAnimationRef = React.useRef<{\n rafId: number;\n } | null>(null);\n const lastSwipePositionRef = React.useRef<number | null>(null);\n\n // Keep ref in sync with state\n React.useEffect(() => {\n indicatorPositionRef.current = indicatorPosition;\n }, [indicatorPosition]);\n\n const prevActiveIndexRef = React.useRef(activeIndex);\n\n // Calculate the range of slot positions to render\n const halfRange = Math.ceil(viewportWidth / tabWidth / 2) + 1;\n\n // Center position for active tab (for slot-based mode)\n const centerX = (viewportWidth - tabWidth) / 2;\n\n // ============================================================\n // Fixed tabs mode: track swipe position\n // ============================================================\n React.useEffect(() => {\n if (!fixedTabs || !isSwiping) return;\n\n // During swipe, track the visual position\n // Swipe direction is OPPOSITE to indicator movement\n const visualPosition = activeIndex * tabWidth - displacement;\n lastSwipePositionRef.current = visualPosition;\n setIndicatorPosition(visualPosition);\n }, [fixedTabs, isSwiping, activeIndex, tabWidth, displacement]);\n\n // ============================================================\n // Fixed tabs mode: animate when swipe ends or tab clicked\n // ============================================================\n React.useEffect(() => {\n if (!fixedTabs || isSwiping) return;\n\n // When swipe ends or tab changes via click\n const targetPosition = activeIndex * tabWidth;\n const startPosition = lastSwipePositionRef.current ?? indicatorPositionRef.current;\n lastSwipePositionRef.current = null;\n\n // Already at target\n if (Math.abs(startPosition - targetPosition) < 1) {\n setIndicatorPosition(targetPosition);\n return;\n }\n\n // Cancel existing animation\n if (fixedAnimationRef.current) {\n cancelAnimationFrame(fixedAnimationRef.current.rafId);\n }\n\n // Animate from current position to target\n const startTime = performance.now();\n const animationStartPosition = startPosition; // Capture for closure\n\n const animate = (currentTime: number) => {\n const elapsed = currentTime - startTime;\n const progress = Math.min(elapsed / animationDuration, 1);\n const easedProgress = easeOutExpo(progress);\n\n const currentPosition = animationStartPosition + (targetPosition - animationStartPosition) * easedProgress;\n setIndicatorPosition(currentPosition);\n\n if (progress < 1) {\n fixedAnimationRef.current = {\n rafId: requestAnimationFrame(animate),\n };\n } else {\n fixedAnimationRef.current = null;\n setIndicatorPosition(targetPosition);\n }\n };\n\n fixedAnimationRef.current = {\n rafId: requestAnimationFrame(animate),\n };\n }, [fixedTabs, isSwiping, activeIndex, tabWidth, animationDuration]);\n\n // ============================================================\n // Slot-based mode animation: handle activeIndex changes\n // ============================================================\n React.useEffect(() => {\n if (fixedTabs) return; // Skip for fixed tabs mode\n\n if (prevActiveIndexRef.current === activeIndex) {\n return;\n }\n\n const prevIndex = prevActiveIndexRef.current;\n prevActiveIndexRef.current = activeIndex;\n\n // Calculate direction of movement\n let delta: number;\n if (navigationMode === \"loop\") {\n // Use shortest path in loop mode\n const forwardDist = normalizeIndex(activeIndex - prevIndex, itemCount);\n const backwardDist = itemCount - forwardDist;\n delta = forwardDist <= backwardDist ? forwardDist : -backwardDist;\n } else {\n delta = activeIndex - prevIndex;\n }\n\n // Target offset to animate to (then snap to 0)\n const targetOffsetPx = -delta * tabWidth;\n\n // Start from current visual position\n const startOffset = isSwiping ? displacement : animatedOffset;\n\n // Cancel any existing animation\n if (animationRef.current) {\n cancelAnimationFrame(animationRef.current.rafId);\n }\n\n // If already at target (within threshold), snap immediately\n if (Math.abs(startOffset - targetOffsetPx) < 1) {\n setAnimatedOffset(0);\n return;\n }\n\n // Start animation\n const startTime = performance.now();\n\n const animate = (currentTime: number) => {\n const elapsed = currentTime - startTime;\n const progress = Math.min(elapsed / animationDuration, 1);\n const easedProgress = easeOutExpo(progress);\n\n // Interpolate from startOffset toward targetOffset, but we want to end at 0\n // So we animate: startOffset → targetOffset, but since we're rendering with\n // the NEW activeIndex, we need to compensate\n //\n // When activeIndex changes, slots now show different content.\n // We animate the offset from (startOffset - targetOffset) back to 0.\n const compensatedStart = startOffset - targetOffsetPx;\n const currentOffset = compensatedStart * (1 - easedProgress);\n\n setAnimatedOffset(currentOffset);\n\n if (progress < 1) {\n animationRef.current = {\n startTime,\n startOffset: compensatedStart,\n targetOffset: 0,\n rafId: requestAnimationFrame(animate),\n };\n } else {\n animationRef.current = null;\n setAnimatedOffset(0);\n }\n };\n\n animationRef.current = {\n startTime,\n startOffset: startOffset - targetOffsetPx,\n targetOffset: 0,\n rafId: requestAnimationFrame(animate),\n };\n }, [fixedTabs, activeIndex, itemCount, tabWidth, animationDuration, navigationMode, displacement, isSwiping, animatedOffset]);\n\n // Update prevActiveIndexRef for fixed tabs mode too\n React.useEffect(() => {\n if (fixedTabs) {\n prevActiveIndexRef.current = activeIndex;\n }\n }, [fixedTabs, activeIndex]);\n\n // Cleanup animation on unmount\n React.useEffect(() => {\n return () => {\n if (animationRef.current) {\n cancelAnimationFrame(animationRef.current.rafId);\n }\n if (fixedAnimationRef.current) {\n cancelAnimationFrame(fixedAnimationRef.current.rafId);\n }\n };\n }, []);\n\n // Current offset for slot-based mode\n const currentOffset = isSwiping ? displacement : animatedOffset;\n const isAnimating = animationRef.current !== null || fixedAnimationRef.current !== null;\n\n // Cancel slot animation when swiping starts\n React.useEffect(() => {\n if (isSwiping && animationRef.current) {\n cancelAnimationFrame(animationRef.current.rafId);\n animationRef.current = null;\n setAnimatedOffset(0);\n }\n }, [isSwiping]);\n\n // ============================================================\n // Fixed tabs mode: render fixed tabs with sliding indicator\n // ============================================================\n if (fixedTabs) {\n // Calculate total width and centering offset\n const totalTabsWidth = items.length * tabWidth;\n const centeringOffset = (viewportWidth - totalTabsWidth) / 2;\n\n return (\n <div\n style={{\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n overflow: \"hidden\",\n display: \"flex\",\n justifyContent: \"center\",\n }}\n >\n {/* Sliding indicator (rendered behind tabs) */}\n {renderIndicator?.({\n offsetPx: indicatorPosition,\n tabWidth,\n centerX: centeringOffset,\n isSwiping,\n isAnimating,\n })}\n\n {/* Fixed tabs - each tab at its natural position */}\n {items.map((item, index) => (\n <div\n key={item.id}\n data-pivot-tab={item.id}\n data-active={index === activeIndex ? \"true\" : \"false\"}\n style={{\n position: \"relative\",\n width: tabWidth,\n height: \"100%\",\n flexShrink: 0,\n }}\n >\n {renderTab(item, index === activeIndex, index)}\n </div>\n ))}\n </div>\n );\n }\n\n // Slot-based rendering for scrolling tabs (infinite loop support)\n const slots: Array<{\n slotPosition: number;\n itemIndex: number;\n item: { id: TId; label?: string };\n }> = [];\n\n for (let pos = -halfRange; pos <= halfRange; pos++) {\n const itemIndex = getItemAtPosition(pos, activeIndex, itemCount, navigationMode);\n if (itemIndex !== null) {\n slots.push({\n slotPosition: pos,\n itemIndex,\n item: items[itemIndex],\n });\n }\n }\n\n return (\n <div\n style={{\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n overflow: \"hidden\",\n }}\n >\n {/* Sliding indicator (rendered behind tabs) */}\n {renderIndicator?.({\n offsetPx: currentOffset,\n tabWidth,\n centerX,\n isSwiping,\n isAnimating,\n })}\n\n {/* Tab slots */}\n {slots.map(({ slotPosition, itemIndex, item }) => (\n <TabSlot\n key={slotPosition}\n slotPosition={slotPosition}\n item={item}\n itemIndex={itemIndex}\n isActive={itemIndex === activeIndex}\n centerX={centerX}\n tabWidth={tabWidth}\n viewportWidth={viewportWidth}\n offsetPx={currentOffset}\n axis={axis}\n renderTab={renderTab}\n />\n ))}\n </div>\n );\n}\n"],"names":["DEFAULT_ANIMATION_TIMEOUT","useAnimatedVisibility","isVisible","leaveAnimation","skipAnimation","animationTimeout","prevVisibleRef","React","isAnimatingOut","setIsAnimatingOut","timeoutRef","wasVisible","handleAnimationEnd","e","shouldDisplay","baseStyle","PivotContent","id","isActive","transitionMode","children","visibility","PIVOT_ANIMATION_LEAVE","style","s","PIVOT_ANIMATION_ENTER","content","jsx","PivotOutletContext","PivotOutletInner","ctx","forceUpdate","x","items","activeId","Fragment","item","usePivot","options","controlledActiveId","defaultActiveId","onActiveChange","navigationMode","isControlled","uncontrolledActiveId","setUncontrolledActiveId","firstEnabled","isAnimating","setIsAnimating","setActiveId","target","shouldAnimate","endAnimation","enabledItems","activeIndex","index","itemCount","canGo","direction","targetIndex","computeTargetIndex","rawIndex","go","targetItem","getVirtualPosition","itemIndex","rawOffset","forwardDist","getItemPosition","backwardDist","getItemProps","containerStyle","stateRef","subscribersRef","callback","resolveContent","itemId","i","validIds","getCachedContent","useContentCache","contextValue","Outlet","OutletComponent","DEFAULT_ANIMATION_DURATION","getAxisDisplacement","inputState","axis","normalizeIndex","count","getItemAtPosition","slotPosition","TabSlot","centerX","tabWidth","viewportWidth","offsetPx","renderTab","basePx","visualPx","visible","transformFn","easeOutExpo","t","SwipePivotTabBar","animationDuration","fixedTabs","renderIndicator","displacement","isSwiping","animatedOffset","setAnimatedOffset","animationRef","indicatorPosition","setIndicatorPosition","indicatorPositionRef","fixedAnimationRef","lastSwipePositionRef","prevActiveIndexRef","halfRange","visualPosition","targetPosition","startPosition","startTime","animationStartPosition","animate","currentTime","elapsed","progress","easedProgress","currentPosition","prevIndex","delta","targetOffsetPx","startOffset","compensatedStart","currentOffset","totalTabsWidth","centeringOffset","jsxs","slots","pos"],"mappings":"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"}
|
package/dist/config.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("react/jsx-runtime"),v=require("react"),b=require("./GridLayout-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("react/jsx-runtime"),v=require("react"),b=require("./GridLayout-B4VRsC0r.cjs");require("./FloatingPanelFrame-CEmXDvUA.cjs");require("./FloatingWindow-TCDNY5gE.cjs");function E(r){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const n in r)if(n!=="default"){const i=Object.getOwnPropertyDescriptor(r,n);Object.defineProperty(t,n,i.get?i:{enumerable:!0,get:()=>r[n]})}}return t.default=r,Object.freeze(t)}const s=E(v),C=r=>{const t=z(r);if(t==="grid"&&!r.area)throw new Error(`PanelRoute ${r.id} must specify 'area' for grid placement.`);return{id:r.id,component:r.element,visible:r.visible,gridArea:r.area,positionMode:t,position:r.position,zIndex:r.zIndex,width:r.width,height:r.height,pointerEvents:r.pointerEvents,style:r.style,drawer:r.drawer,floating:r.floating,pivot:r.pivot,backdropStyle:r.backdropStyle}},z=r=>r.positionMode?r.positionMode:r.floating?"absolute":(r.drawer,"grid"),P=r=>{const t=[],n=i=>{t.push(i),i.children&&i.children.forEach(e=>n(e))};return r.forEach(i=>n(i)),t},I=r=>{const t=new Set;r.forEach(n=>{if(t.has(n.id))throw new Error(`Duplicate PanelRoute id detected: ${n.id}`);t.add(n.id)})},A=r=>{const t=P(r);return I(t),t.map(n=>C(n))},p=()=>null,x=()=>null,a=(r,t)=>s.isValidElement(r)?r.type===t:!1,d=r=>{const t=[],n=i=>{if(!(i==null||typeof i=="boolean")){if(Array.isArray(i)){i.forEach(n);return}if(a(i,p)){const e=i.props;if(!e.id)throw new Error("<Panel> requires an 'id' prop.");if(e.type==="grid"){if(!e.area)throw new Error(`<Panel id="${e.id}"> requires an explicit 'area' prop when type="grid".`);t.push({id:e.id,area:e.area,element:e.children??null,visible:e.visible,zIndex:e.zIndex,width:e.width,height:e.height,pointerEvents:e.pointerEvents,style:e.style});return}if(e.type==="floating"){if(!e.position)throw new Error(`<Panel id="${e.id}"> requires a 'position' prop when type="floating".`);if(e.width===void 0||e.height===void 0)throw new Error(`<Panel id="${e.id}"> requires 'width' and 'height' when type="floating".`);t.push({id:e.id,element:e.children??null,visible:e.visible??!0,positionMode:"absolute",position:e.position,zIndex:e.zIndex,width:e.width,height:e.height,pointerEvents:e.pointerEvents,style:e.style,floating:{mode:"embedded",draggable:e.draggable,resizable:e.resizable}});return}if(e.type==="drawer"){t.push({id:e.id,element:e.children??null,visible:e.visible??!0,positionMode:"relative",position:e.position,zIndex:e.zIndex,width:e.width,height:e.height,pointerEvents:e.pointerEvents,style:e.style,drawer:e.drawer,backdropStyle:e.backdropStyle});return}if(e.type==="pivot"){if(!e.area)throw new Error(`<Panel id="${e.id}"> requires an explicit 'area' prop when type="pivot".`);const o=$(e.children);if(o.length===0)throw new Error(`<Panel id="${e.id}"> requires at least one <PivotItem> child when type="pivot".`);t.push({id:e.id,area:e.area,element:null,visible:e.visible,zIndex:e.zIndex,width:e.width,height:e.height,pointerEvents:e.pointerEvents,style:e.style,pivot:{items:o,activeId:e.activeId,defaultActiveId:e.defaultActiveId,onActiveChange:e.onActiveChange}});return}throw new Error("<Panel> has unsupported type.")}if(s.isValidElement(i)){if(i.type===s.Fragment){n(i.props.children);return}return}}};return n(r),t},R=({config:r,style:t,children:n})=>{const i=s.useMemo(()=>d(n),[n]),e=s.useMemo(()=>A(i),[i]),o=s.useMemo(()=>{if(r)return r;const l=m(n);if(!l)throw new Error("Panel requires either 'config' prop or a JSX config (<Config><Rows/><Columns/><Areas/></Config>). ");return l},[n,r]);return y.jsx(b.GridLayout,{config:o,layers:e,style:t})},h=()=>null,q=()=>null,S=()=>null,f=()=>null,w=()=>null,g=()=>null,u=(r,t)=>{const n=[],i=e=>{if(!(e==null||typeof e=="boolean")){if(Array.isArray(e)){e.forEach(i);return}if(a(e,t)){const o=e.props;if(!o.size)throw new Error("Row/Col requires 'size' property.");n.push({size:o.size,resizable:o.resizable,minSize:o.minSize,maxSize:o.maxSize});return}s.isValidElement(e)&&i(e.props.children)}};return i(r),n},M=r=>{const t=c(r,h);if(!t)return null;const n=t.props,i=u(t.props.children,f),e=u(t.props.children,w),o=c(t.props.children,g),l=o?o.props.matrix:void 0;return{gap:n.gap,style:n.style,rows:i,columns:e,areas:l}},c=(r,t)=>{const n=i=>{if(i==null||typeof i=="boolean")return null;if(Array.isArray(i)){for(const e of i){const o=n(e);if(o)return o}return null}return a(i,t)?i:s.isValidElement(i)?n(i.props.children):null};return n(r)},$=r=>{const t=[],n=i=>{if(!(i==null||typeof i=="boolean")){if(Array.isArray(i)){i.forEach(n);return}if(a(i,x)){const e=i.props;if(!e.id)throw new Error("<PivotItem> requires an 'id' prop.");t.push({id:e.id,label:e.label,content:e.children??null,disabled:e.disabled});return}s.isValidElement(i)&&i.type===s.Fragment&&n(i.props.children)}};return n(r),t},m=r=>{const t=M(r);if(!t)return null;if(!t.rows||t.rows.length===0)throw new Error("Config must include at least one <Row size=...> inside <Config>.");if(!t.columns||t.columns.length===0)throw new Error("Config must include at least one <Col size=...> inside <Config>.");if(!t.areas||t.areas.length===0)throw new Error("Config must include <Areas matrix={...}> inside <Config>.");const n=t.areas.length,i=t.areas[0]?.length??0;if(n!==t.rows.length)throw new Error(`Areas row count (${n}) must match Rows count (${t.rows.length}).`);if(i!==t.columns.length)throw new Error(`Areas column count (${i}) must match Columns count (${t.columns.length}).`);return{areas:t.areas,rows:t.rows,columns:t.columns,gap:t.gap,style:t.style}};exports.Areas=g;exports.Col=w;exports.Columns=S;exports.Config=h;exports.Panel=p;exports.PanelLayout=R;exports.Row=f;exports.Rows=q;exports.buildConfigFromChildren=m;exports.buildRoutesFromChildren=d;
|
|
2
2
|
//# sourceMappingURL=config.cjs.map
|
package/dist/config.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.cjs","sources":["../src/config/panelRouter.tsx","../src/config/PanelContentDeclaration.tsx"],"sourcesContent":["/**\n * @file Router-like builder for GridLayout\n *\n * Provides a React Router–style configuration API to declare panel layers.\n * Converts route objects to the existing GridLayout props without magic.\n */\nimport * as React from \"react\";\nimport type {\n DrawerBehavior,\n FloatingBehavior,\n LayerDefinition,\n LayerPositionMode,\n PanelLayoutConfig,\n PanelLayoutProps,\n PivotBehavior,\n WindowPosition,\n} from \"../types\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\n\nexport type PanelRoute = {\n /** Unique id for the layer. Required. */\n id: string;\n /** React node to render for this layer. Required. */\n element: React.ReactNode;\n /** Visibility flag. Defaults to visible. */\n visible?: boolean;\n\n /**\n * Grid placement key. When using `positionMode: 'grid'` (default), this must be provided.\n * Using `area` mirrors React Router's route path intent but for grid cells.\n */\n area?: string;\n\n /** Explicit positioning mode; defaults to 'grid' unless floating/drawer implies otherwise. */\n positionMode?: LayerPositionMode;\n /** Offsets when using non-grid modes. */\n position?: WindowPosition;\n /** Optional stacking order. */\n zIndex?: number;\n /** Optional dimensions; required for resizable/draggable floating layers. */\n width?: number | string;\n height?: number | string;\n /** Pointer events control. */\n pointerEvents?: boolean | \"auto\" | \"none\";\n /** Optional style overrides. */\n style?: React.CSSProperties;\n /** Optional backdrop style (drawer). */\n backdropStyle?: React.CSSProperties;\n\n /** Drawer behavior for mobile-friendly panels. */\n drawer?: DrawerBehavior;\n /** Floating window configuration. */\n floating?: FloatingBehavior;\n /** Pivot behavior for content switching. */\n pivot?: PivotBehavior;\n\n /**\n * Optional child declarations; purely a grouping convenience.\n * Children are flattened; no implicit inheritance.\n */\n children?: PanelRoute[];\n};\n\nconst toLayer = (route: PanelRoute): LayerDefinition => {\n const inferredMode: LayerPositionMode = resolveRoutePositionMode(route);\n\n if (inferredMode === \"grid\") {\n if (!route.area) {\n throw new Error(`PanelRoute ${route.id} must specify 'area' for grid placement.`);\n }\n }\n\n return {\n id: route.id,\n component: route.element,\n visible: route.visible,\n gridArea: route.area,\n positionMode: inferredMode,\n position: route.position,\n zIndex: route.zIndex,\n width: route.width,\n height: route.height,\n pointerEvents: route.pointerEvents,\n style: route.style,\n drawer: route.drawer,\n floating: route.floating,\n pivot: route.pivot,\n backdropStyle: route.backdropStyle,\n } satisfies LayerDefinition;\n};\n\nconst resolveRoutePositionMode = (route: PanelRoute): LayerPositionMode => {\n if (route.positionMode) {\n return route.positionMode;\n }\n if (route.floating) {\n // Embedded => absolute, Popup => relative (handled by renderer); keep explicitness here.\n return \"absolute\";\n }\n if (route.drawer) {\n return \"grid\";\n }\n return \"grid\";\n};\n\nconst flattenRoutes = (routes: PanelRoute[]): PanelRoute[] => {\n const result: PanelRoute[] = [];\n const walk = (node: PanelRoute): void => {\n result.push(node);\n if (node.children) {\n node.children.forEach((child) => walk(child));\n }\n };\n routes.forEach((r) => walk(r));\n return result;\n};\n\nconst validateUniqueIds = (routes: PanelRoute[]): void => {\n const seen = new Set<string>();\n routes.forEach((r) => {\n if (seen.has(r.id)) {\n throw new Error(`Duplicate PanelRoute id detected: ${r.id}`);\n }\n seen.add(r.id);\n });\n};\n\nexport const buildLayersFromRoutes = (routes: PanelRoute[]): LayerDefinition[] => {\n const flat = flattenRoutes(routes);\n validateUniqueIds(flat);\n return flat.map((r) => toLayer(r));\n};\n\nexport const createPanelLayoutFromRoutes = (input: {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n}): PanelLayoutProps => {\n const layers = buildLayersFromRoutes(input.routes);\n return {\n config: input.config,\n layers,\n };\n};\n\nexport type PanelLayoutRouterProps = {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n};\n\nexport const PanelLayoutRouter: React.FC<PanelLayoutRouterProps> = ({ config, routes, style }) => {\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n return <GridLayout config={config} layers={layers} style={style} />;\n};\n","/**\n * @file PanelContentDeclaration (JSX DSL for content configuration ONLY)\n *\n * IMPORTANT: This file declares a JSX DSL to configure panel \"content\" and layout\n * tracks. It does NOT implement grid rendering, resizing, dragging, or drawers.\n * Those behaviors live in the existing layout/rendering modules. Keep this file\n * limited to declaration and conversion into GridLayout props.\n *\n * Usage (content declaration):\n * <PanelLayout>\n * <Config>\n * <Rows>...</Rows>\n * <Columns>...</Columns>\n * <Areas matrix={...}/>\n * </Config>\n * <Panel type=\"grid\" id=\"main\" area=\"main\">...</Panel>\n * <Panel type=\"floating\" id=\"preview\" position={{ left: 0, top: 0 }} width={300} height={200} />\n * <Panel type=\"drawer\" id=\"nav\" drawer={{ defaultOpen: true }} position={{ left: 0 }} />\n * </PanelLayout>\n */\nimport * as React from \"react\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\nimport type { DrawerBehavior, GridTrack, PanelLayoutConfig, WindowPosition } from \"../types\";\nimport type { PanelRoute } from \"./panelRouter\";\nimport { buildLayersFromRoutes } from \"./panelRouter\";\n\nexport type PanelRootProps = {\n config?: PanelLayoutConfig;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\n// Unified child declaration: <Panel type=\"grid\" .../> or <Panel type=\"floating\" .../>...\ntype PanelCommonProps = {\n id: string;\n visible?: boolean;\n zIndex?: number;\n width?: number | string;\n height?: number | string;\n pointerEvents?: boolean | \"auto\" | \"none\";\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport type PanelProps =\n | (PanelCommonProps & { type: \"grid\"; area: string })\n | (PanelCommonProps & {\n type: \"floating\";\n position: WindowPosition;\n width: number | string;\n height: number | string;\n draggable?: boolean;\n resizable?: boolean;\n })\n | (PanelCommonProps & {\n type: \"drawer\";\n drawer: DrawerBehavior;\n position?: WindowPosition;\n backdropStyle?: React.CSSProperties;\n })\n | (Omit<PanelCommonProps, \"children\"> & {\n type: \"pivot\";\n area: string;\n /** Currently active item ID (controlled mode) */\n activeId?: string;\n /** Default active item ID (uncontrolled mode) */\n defaultActiveId?: string;\n /** Callback when active item changes */\n onActiveChange?: (id: string) => void;\n children?: React.ReactNode;\n });\n\nexport const Panel: React.FC<PanelProps> = () => null;\n\n/**\n * PivotItem declaration for use inside <Panel type=\"pivot\">\n */\nexport type PivotItemDeclProps = {\n id: string;\n label?: string;\n disabled?: boolean;\n children?: React.ReactNode;\n};\n\nexport const PivotItem: React.FC<PivotItemDeclProps> = () => null;\n\nconst isElementOf = <P,>(element: unknown, component: React.FC<P>): element is React.ReactElement<P> => {\n if (!React.isValidElement<P>(element)) {\n return false;\n }\n return element.type === component;\n};\n\nexport const buildRoutesFromChildren = (children: React.ReactNode): PanelRoute[] => {\n const routes: PanelRoute[] = [];\n\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n // Unified <Panel type=\"...\" />\n if (isElementOf(node, Panel)) {\n const props = node.props as PanelProps;\n if (!props.id) {\n throw new Error(\"<Panel> requires an 'id' prop.\");\n }\n if (props.type === \"grid\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"grid\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: props.children ?? null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n });\n return;\n }\n if (props.type === \"floating\") {\n if (!props.position) {\n throw new Error(`<Panel id=\"${props.id}\"> requires a 'position' prop when type=\"floating\".`);\n }\n if (props.width === undefined || props.height === undefined) {\n throw new Error(`<Panel id=\"${props.id}\"> requires 'width' and 'height' when type=\"floating\".`);\n }\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"absolute\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n floating: { mode: \"embedded\", draggable: props.draggable, resizable: props.resizable },\n });\n return;\n }\n if (props.type === \"drawer\") {\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"relative\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n drawer: props.drawer,\n backdropStyle: props.backdropStyle,\n });\n return;\n }\n if (props.type === \"pivot\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"pivot\".`);\n }\n const pivotItems = collectPivotItems(props.children);\n if (pivotItems.length === 0) {\n throw new Error(`<Panel id=\"${props.id}\"> requires at least one <PivotItem> child when type=\"pivot\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n pivot: {\n items: pivotItems,\n activeId: props.activeId,\n defaultActiveId: props.defaultActiveId,\n onActiveChange: props.onActiveChange,\n },\n });\n return;\n }\n // unknown type -> error for explicitness\n throw new Error(\"<Panel> has unsupported type.\");\n }\n\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n return;\n }\n // Unknown element: ignore quietly to allow comments/wrappers.\n return;\n }\n // Primitive nodes (string/number) are ignored.\n };\n\n visit(children);\n return routes;\n};\n\n// Root container renamed to PanelLayout to avoid name collision with child <Panel/>\nexport const PanelLayout: React.FC<PanelRootProps> = ({ config, style, children }) => {\n const routes = React.useMemo(() => buildRoutesFromChildren(children), [children]);\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n const derivedConfig = React.useMemo(() => {\n if (config) {\n return config;\n }\n const built = buildConfigFromChildren(children);\n if (!built) {\n throw new Error(\"Panel requires either 'config' prop or a JSX config (<Config><Rows/><Columns/><Areas/></Config>). \");\n }\n return built;\n }, [children, config]);\n return <GridLayout config={derivedConfig} layers={layers} style={style} />;\n};\n\n// =============================\n// JSX Config Declarations\n// =============================\n\nexport type ConfigProps = {\n gap?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport const Config: React.FC<ConfigProps> = () => {\n return null;\n};\n\nexport const Rows: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport const Columns: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport type RowProps = GridTrack;\nexport const Row: React.FC<RowProps> = () => {\n return null;\n};\n\nexport type ColumnProps = GridTrack;\nexport const Col: React.FC<ColumnProps> = () => {\n return null;\n};\n\nexport type AreasProps = {\n matrix: string[][];\n};\nexport const Areas: React.FC<AreasProps> = () => {\n return null;\n};\n\ntype CollectedConfig = {\n gap?: string;\n style?: React.CSSProperties;\n rows?: GridTrack[];\n columns?: GridTrack[];\n areas?: string[][];\n};\n\nconst collectTracks = <P extends GridTrack>(children: React.ReactNode, marker: React.FC<P>): GridTrack[] => {\n const result: GridTrack[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, marker)) {\n const props = node.props as P;\n if (!props.size) {\n throw new Error(\"Row/Col requires 'size' property.\");\n }\n result.push({\n size: props.size,\n resizable: props.resizable,\n minSize: props.minSize,\n maxSize: props.maxSize,\n });\n return;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n };\n visit(children);\n return result;\n};\n\nconst collectConfigBlock = (children: React.ReactNode): CollectedConfig | null => {\n const node = findFirst(children, Config);\n if (!node) {\n return null;\n }\n const props = node.props as ConfigProps;\n const rows = collectTracks(node.props.children, Row);\n const columns = collectTracks(node.props.children, Col);\n const areasNode = findFirst(node.props.children, Areas);\n const areas = areasNode ? (areasNode.props as AreasProps).matrix : undefined;\n return {\n gap: props.gap,\n style: props.style,\n rows,\n columns,\n areas,\n };\n};\n\nconst findFirst = <P,>(children: React.ReactNode, marker: React.FC<P>): React.ReactElement<P> | null => {\n const visit = (node: React.ReactNode): React.ReactElement<P> | null => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return null;\n }\n if (Array.isArray(node)) {\n for (const item of node) {\n const found = visit(item);\n if (found) {\n return found;\n }\n }\n return null;\n }\n if (isElementOf(node, marker)) {\n return node as React.ReactElement<P>;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n return visit(el.props.children);\n }\n return null;\n };\n return visit(children);\n};\n\ntype CollectedPivotItem = {\n id: string;\n label?: string;\n content: React.ReactNode;\n disabled?: boolean;\n};\n\nconst collectPivotItems = (children: React.ReactNode): CollectedPivotItem[] => {\n const items: CollectedPivotItem[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, PivotItem)) {\n const props = node.props as PivotItemDeclProps;\n if (!props.id) {\n throw new Error(\"<PivotItem> requires an 'id' prop.\");\n }\n items.push({\n id: props.id,\n label: props.label,\n content: props.children ?? null,\n disabled: props.disabled,\n });\n return;\n }\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n }\n };\n visit(children);\n return items;\n};\n\nexport const buildConfigFromChildren = (children: React.ReactNode): PanelLayoutConfig | null => {\n const collected = collectConfigBlock(children);\n if (!collected) {\n return null;\n }\n if (!collected.rows || collected.rows.length === 0) {\n throw new Error(\"Config must include at least one <Row size=...> inside <Config>.\");\n }\n if (!collected.columns || collected.columns.length === 0) {\n throw new Error(\"Config must include at least one <Col size=...> inside <Config>.\");\n }\n if (!collected.areas || collected.areas.length === 0) {\n throw new Error(\"Config must include <Areas matrix={...}> inside <Config>.\");\n }\n\n const rowCount = collected.areas.length;\n const colCount = collected.areas[0]?.length ?? 0;\n if (rowCount !== collected.rows.length) {\n throw new Error(`Areas row count (${rowCount}) must match Rows count (${collected.rows.length}).`);\n }\n if (colCount !== collected.columns.length) {\n throw new Error(`Areas column count (${colCount}) must match Columns count (${collected.columns.length}).`);\n }\n\n return {\n areas: collected.areas,\n rows: collected.rows,\n columns: collected.columns,\n gap: collected.gap,\n style: collected.style,\n } satisfies PanelLayoutConfig;\n};\n"],"names":["toLayer","route","inferredMode","resolveRoutePositionMode","flattenRoutes","routes","result","walk","node","child","r","validateUniqueIds","seen","buildLayersFromRoutes","flat","Panel","PivotItem","isElementOf","element","component","React","buildRoutesFromChildren","children","visit","props","pivotItems","collectPivotItems","PanelLayout","config","style","layers","derivedConfig","built","buildConfigFromChildren","jsx","GridLayout","Config","Rows","Columns","Row","Col","Areas","collectTracks","marker","collectConfigBlock","findFirst","rows","columns","areasNode","areas","item","found","items","collected","rowCount","colCount"],"mappings":"ycA+DMA,EAAWC,GAAuC,CACtD,MAAMC,EAAkCC,EAAyBF,CAAK,EAEtE,GAAIC,IAAiB,QACf,CAACD,EAAM,KACT,MAAM,IAAI,MAAM,cAAcA,EAAM,EAAE,0CAA0C,EAIpF,MAAO,CACL,GAAIA,EAAM,GACV,UAAWA,EAAM,QACjB,QAASA,EAAM,QACf,SAAUA,EAAM,KAChB,aAAcC,EACd,SAAUD,EAAM,SAChB,OAAQA,EAAM,OACd,MAAOA,EAAM,MACb,OAAQA,EAAM,OACd,cAAeA,EAAM,cACrB,MAAOA,EAAM,MACb,OAAQA,EAAM,OACd,SAAUA,EAAM,SAChB,MAAOA,EAAM,MACb,cAAeA,EAAM,aAAA,CAEzB,EAEME,EAA4BF,GAC5BA,EAAM,aACDA,EAAM,aAEXA,EAAM,SAED,YAELA,EAAM,OACD,QAKLG,EAAiBC,GAAuC,CAC5D,MAAMC,EAAuB,CAAA,EACvBC,EAAQC,GAA2B,CACvCF,EAAO,KAAKE,CAAI,EACZA,EAAK,UACPA,EAAK,SAAS,QAASC,GAAUF,EAAKE,CAAK,CAAC,CAEhD,EACA,OAAAJ,EAAO,QAASK,GAAMH,EAAKG,CAAC,CAAC,EACtBJ,CACT,EAEMK,EAAqBN,GAA+B,CACxD,MAAMO,MAAW,IACjBP,EAAO,QAASK,GAAM,CACpB,GAAIE,EAAK,IAAIF,EAAE,EAAE,EACf,MAAM,IAAI,MAAM,qCAAqCA,EAAE,EAAE,EAAE,EAE7DE,EAAK,IAAIF,EAAE,EAAE,CACf,CAAC,CACH,EAEaG,EAAyBR,GAA4C,CAChF,MAAMS,EAAOV,EAAcC,CAAM,EACjC,OAAAM,EAAkBG,CAAI,EACfA,EAAK,IAAKJ,GAAMV,EAAQU,CAAC,CAAC,CACnC,EC3DaK,EAA8B,IAAM,KAYpCC,EAA0C,IAAM,KAEvDC,EAAc,CAAKC,EAAkBC,IACpCC,EAAM,eAAkBF,CAAO,EAG7BA,EAAQ,OAASC,EAFf,GAKEE,EAA2BC,GAA4C,CAClF,MAAMjB,EAAuB,CAAA,EAEvBkB,EAASf,GAAgC,CAC7C,GAAI,EAAAA,GAAS,MAA8B,OAAOA,GAAS,WAG3D,IAAI,MAAM,QAAQA,CAAI,EAAG,CACvBA,EAAK,QAAQe,CAAK,EAClB,MACF,CAEA,GAAIN,EAAYT,EAAMO,CAAK,EAAG,CAC5B,MAAMS,EAAQhB,EAAK,MACnB,GAAI,CAACgB,EAAM,GACT,MAAM,IAAI,MAAM,gCAAgC,EAElD,GAAIA,EAAM,OAAS,OAAQ,CACzB,GAAI,CAACA,EAAM,KACT,MAAM,IAAI,MAAM,cAAcA,EAAM,EAAE,uDAAuD,EAE/FnB,EAAO,KAAK,CACV,GAAImB,EAAM,GACV,KAAMA,EAAM,KACZ,QAASA,EAAM,UAAY,KAC3B,QAASA,EAAM,QACf,OAAQA,EAAM,OACd,MAAOA,EAAM,MACb,OAAQA,EAAM,OACd,cAAeA,EAAM,cACrB,MAAOA,EAAM,KAAA,CACd,EACD,MACF,CACA,GAAIA,EAAM,OAAS,WAAY,CAC7B,GAAI,CAACA,EAAM,SACT,MAAM,IAAI,MAAM,cAAcA,EAAM,EAAE,qDAAqD,EAE7F,GAAIA,EAAM,QAAU,QAAaA,EAAM,SAAW,OAChD,MAAM,IAAI,MAAM,cAAcA,EAAM,EAAE,wDAAwD,EAEhGnB,EAAO,KAAK,CACV,GAAImB,EAAM,GACV,QAASA,EAAM,UAAY,KAC3B,QAASA,EAAM,SAAW,GAC1B,aAAc,WACd,SAAUA,EAAM,SAChB,OAAQA,EAAM,OACd,MAAOA,EAAM,MACb,OAAQA,EAAM,OACd,cAAeA,EAAM,cACrB,MAAOA,EAAM,MACb,SAAU,CAAE,KAAM,WAAY,UAAWA,EAAM,UAAW,UAAWA,EAAM,SAAA,CAAU,CACtF,EACD,MACF,CACA,GAAIA,EAAM,OAAS,SAAU,CAC3BnB,EAAO,KAAK,CACV,GAAImB,EAAM,GACV,QAASA,EAAM,UAAY,KAC3B,QAASA,EAAM,SAAW,GAC1B,aAAc,WACd,SAAUA,EAAM,SAChB,OAAQA,EAAM,OACd,MAAOA,EAAM,MACb,OAAQA,EAAM,OACd,cAAeA,EAAM,cACrB,MAAOA,EAAM,MACb,OAAQA,EAAM,OACd,cAAeA,EAAM,aAAA,CACtB,EACD,MACF,CACA,GAAIA,EAAM,OAAS,QAAS,CAC1B,GAAI,CAACA,EAAM,KACT,MAAM,IAAI,MAAM,cAAcA,EAAM,EAAE,wDAAwD,EAEhG,MAAMC,EAAaC,EAAkBF,EAAM,QAAQ,EACnD,GAAIC,EAAW,SAAW,EACxB,MAAM,IAAI,MAAM,cAAcD,EAAM,EAAE,+DAA+D,EAEvGnB,EAAO,KAAK,CACV,GAAImB,EAAM,GACV,KAAMA,EAAM,KACZ,QAAS,KACT,QAASA,EAAM,QACf,OAAQA,EAAM,OACd,MAAOA,EAAM,MACb,OAAQA,EAAM,OACd,cAAeA,EAAM,cACrB,MAAOA,EAAM,MACb,MAAO,CACL,MAAOC,EACP,SAAUD,EAAM,SAChB,gBAAiBA,EAAM,gBACvB,eAAgBA,EAAM,cAAA,CACxB,CACD,EACD,MACF,CAEA,MAAM,IAAI,MAAM,+BAA+B,CACjD,CAEA,GAAIJ,EAAM,eAAeZ,CAAI,EAAG,CAC9B,GAAIA,EAAK,OAASY,EAAM,SAAU,CAEhCG,EADWf,EACF,MAAM,QAAQ,EACvB,MACF,CAEA,MACF,EAEF,EAEA,OAAAe,EAAMD,CAAQ,EACPjB,CACT,EAGasB,EAAwC,CAAC,CAAE,OAAAC,EAAQ,MAAAC,EAAO,SAAAP,KAAe,CACpF,MAAMjB,EAASe,EAAM,QAAQ,IAAMC,EAAwBC,CAAQ,EAAG,CAACA,CAAQ,CAAC,EAC1EQ,EAASV,EAAM,QAAQ,IAAMP,EAAsBR,CAAM,EAAG,CAACA,CAAM,CAAC,EACpE0B,EAAgBX,EAAM,QAAQ,IAAM,CACxC,GAAIQ,EACF,OAAOA,EAET,MAAMI,EAAQC,EAAwBX,CAAQ,EAC9C,GAAI,CAACU,EACH,MAAM,IAAI,MAAM,oGAAoG,EAEtH,OAAOA,CACT,EAAG,CAACV,EAAUM,CAAM,CAAC,EACrB,OAAOM,EAAAA,IAACC,EAAAA,WAAA,CAAW,OAAQJ,EAAe,OAAAD,EAAgB,MAAAD,EAAc,CAC1E,EAYaO,EAAgC,IACpC,KAGIC,EAAiD,IACrD,KAGIC,EAAoD,IACxD,KAIIC,EAA0B,IAC9B,KAIIC,EAA6B,IACjC,KAMIC,EAA8B,IAClC,KAWHC,EAAgB,CAAsBpB,EAA2BqB,IAAqC,CAC1G,MAAMrC,EAAsB,CAAA,EACtBiB,EAASf,GAAgC,CAC7C,GAAI,EAAAA,GAAS,MAA8B,OAAOA,GAAS,WAG3D,IAAI,MAAM,QAAQA,CAAI,EAAG,CACvBA,EAAK,QAAQe,CAAK,EAClB,MACF,CACA,GAAIN,EAAYT,EAAMmC,CAAM,EAAG,CAC7B,MAAMnB,EAAQhB,EAAK,MACnB,GAAI,CAACgB,EAAM,KACT,MAAM,IAAI,MAAM,mCAAmC,EAErDlB,EAAO,KAAK,CACV,KAAMkB,EAAM,KACZ,UAAWA,EAAM,UACjB,QAASA,EAAM,QACf,QAASA,EAAM,OAAA,CAChB,EACD,MACF,CACIJ,EAAM,eAAeZ,CAAI,GAE3Be,EADWf,EACF,MAAM,QAAQ,EAE3B,EACA,OAAAe,EAAMD,CAAQ,EACPhB,CACT,EAEMsC,EAAsBtB,GAAsD,CAChF,MAAMd,EAAOqC,EAAUvB,EAAUc,CAAM,EACvC,GAAI,CAAC5B,EACH,OAAO,KAET,MAAMgB,EAAQhB,EAAK,MACbsC,EAAOJ,EAAclC,EAAK,MAAM,SAAU+B,CAAG,EAC7CQ,EAAUL,EAAclC,EAAK,MAAM,SAAUgC,CAAG,EAChDQ,EAAYH,EAAUrC,EAAK,MAAM,SAAUiC,CAAK,EAChDQ,EAAQD,EAAaA,EAAU,MAAqB,OAAS,OACnE,MAAO,CACL,IAAKxB,EAAM,IACX,MAAOA,EAAM,MACb,KAAAsB,EACA,QAAAC,EACA,MAAAE,CAAA,CAEJ,EAEMJ,EAAY,CAAKvB,EAA2BqB,IAAsD,CACtG,MAAMpB,EAASf,GAAwD,CACrE,GAAIA,GAAS,MAA8B,OAAOA,GAAS,UACzD,OAAO,KAET,GAAI,MAAM,QAAQA,CAAI,EAAG,CACvB,UAAW0C,KAAQ1C,EAAM,CACvB,MAAM2C,EAAQ5B,EAAM2B,CAAI,EACxB,GAAIC,EACF,OAAOA,CAEX,CACA,OAAO,IACT,CACA,OAAIlC,EAAYT,EAAMmC,CAAM,EACnBnC,EAELY,EAAM,eAAeZ,CAAI,EAEpBe,EADIf,EACK,MAAM,QAAQ,EAEzB,IACT,EACA,OAAOe,EAAMD,CAAQ,CACvB,EASMI,EAAqBJ,GAAoD,CAC7E,MAAM8B,EAA8B,CAAA,EAC9B7B,EAASf,GAAgC,CAC7C,GAAI,EAAAA,GAAS,MAA8B,OAAOA,GAAS,WAG3D,IAAI,MAAM,QAAQA,CAAI,EAAG,CACvBA,EAAK,QAAQe,CAAK,EAClB,MACF,CACA,GAAIN,EAAYT,EAAMQ,CAAS,EAAG,CAChC,MAAMQ,EAAQhB,EAAK,MACnB,GAAI,CAACgB,EAAM,GACT,MAAM,IAAI,MAAM,oCAAoC,EAEtD4B,EAAM,KAAK,CACT,GAAI5B,EAAM,GACV,MAAOA,EAAM,MACb,QAASA,EAAM,UAAY,KAC3B,SAAUA,EAAM,QAAA,CACjB,EACD,MACF,CACIJ,EAAM,eAAeZ,CAAI,GACvBA,EAAK,OAASY,EAAM,UAEtBG,EADWf,EACF,MAAM,QAAQ,EAG7B,EACA,OAAAe,EAAMD,CAAQ,EACP8B,CACT,EAEanB,EAA2BX,GAAwD,CAC9F,MAAM+B,EAAYT,EAAmBtB,CAAQ,EAC7C,GAAI,CAAC+B,EACH,OAAO,KAET,GAAI,CAACA,EAAU,MAAQA,EAAU,KAAK,SAAW,EAC/C,MAAM,IAAI,MAAM,kEAAkE,EAEpF,GAAI,CAACA,EAAU,SAAWA,EAAU,QAAQ,SAAW,EACrD,MAAM,IAAI,MAAM,kEAAkE,EAEpF,GAAI,CAACA,EAAU,OAASA,EAAU,MAAM,SAAW,EACjD,MAAM,IAAI,MAAM,2DAA2D,EAG7E,MAAMC,EAAWD,EAAU,MAAM,OAC3BE,EAAWF,EAAU,MAAM,CAAC,GAAG,QAAU,EAC/C,GAAIC,IAAaD,EAAU,KAAK,OAC9B,MAAM,IAAI,MAAM,oBAAoBC,CAAQ,4BAA4BD,EAAU,KAAK,MAAM,IAAI,EAEnG,GAAIE,IAAaF,EAAU,QAAQ,OACjC,MAAM,IAAI,MAAM,uBAAuBE,CAAQ,+BAA+BF,EAAU,QAAQ,MAAM,IAAI,EAG5G,MAAO,CACL,MAAOA,EAAU,MACjB,KAAMA,EAAU,KAChB,QAASA,EAAU,QACnB,IAAKA,EAAU,IACf,MAAOA,EAAU,KAAA,CAErB"}
|
|
1
|
+
{"version":3,"file":"config.cjs","sources":["../src/config/panelRouter.tsx","../src/config/PanelContentDeclaration.tsx"],"sourcesContent":["/**\n * @file Router-like builder for GridLayout\n *\n * Provides a React Router–style configuration API to declare panel layers.\n * Converts route objects to the existing GridLayout props without magic.\n */\nimport * as React from \"react\";\nimport type {\n DrawerBehavior,\n FloatingBehavior,\n LayerDefinition,\n LayerPositionMode,\n PanelLayoutConfig,\n PanelLayoutProps,\n PivotBehavior,\n WindowPosition,\n} from \"../types\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\n\nexport type PanelRoute = {\n /** Unique id for the layer. Required. */\n id: string;\n /** React node to render for this layer. Required. */\n element: React.ReactNode;\n /** Visibility flag. Defaults to visible. */\n visible?: boolean;\n\n /**\n * Grid placement key. When using `positionMode: 'grid'` (default), this must be provided.\n * Using `area` mirrors React Router's route path intent but for grid cells.\n */\n area?: string;\n\n /** Explicit positioning mode; defaults to 'grid' unless floating/drawer implies otherwise. */\n positionMode?: LayerPositionMode;\n /** Offsets when using non-grid modes. */\n position?: WindowPosition;\n /** Optional stacking order. */\n zIndex?: number;\n /** Optional dimensions; required for resizable/draggable floating layers. */\n width?: number | string;\n height?: number | string;\n /** Pointer events control. */\n pointerEvents?: boolean | \"auto\" | \"none\";\n /** Optional style overrides. */\n style?: React.CSSProperties;\n /** Optional backdrop style (drawer). */\n backdropStyle?: React.CSSProperties;\n\n /** Drawer behavior for mobile-friendly panels. */\n drawer?: DrawerBehavior;\n /** Floating window configuration. */\n floating?: FloatingBehavior;\n /** Pivot behavior for content switching. */\n pivot?: PivotBehavior;\n\n /**\n * Optional child declarations; purely a grouping convenience.\n * Children are flattened; no implicit inheritance.\n */\n children?: PanelRoute[];\n};\n\nconst toLayer = (route: PanelRoute): LayerDefinition => {\n const inferredMode: LayerPositionMode = resolveRoutePositionMode(route);\n\n if (inferredMode === \"grid\") {\n if (!route.area) {\n throw new Error(`PanelRoute ${route.id} must specify 'area' for grid placement.`);\n }\n }\n\n return {\n id: route.id,\n component: route.element,\n visible: route.visible,\n gridArea: route.area,\n positionMode: inferredMode,\n position: route.position,\n zIndex: route.zIndex,\n width: route.width,\n height: route.height,\n pointerEvents: route.pointerEvents,\n style: route.style,\n drawer: route.drawer,\n floating: route.floating,\n pivot: route.pivot,\n backdropStyle: route.backdropStyle,\n } satisfies LayerDefinition;\n};\n\nconst resolveRoutePositionMode = (route: PanelRoute): LayerPositionMode => {\n if (route.positionMode) {\n return route.positionMode;\n }\n if (route.floating) {\n // Embedded => absolute, Popup => relative (handled by renderer); keep explicitness here.\n return \"absolute\";\n }\n if (route.drawer) {\n return \"grid\";\n }\n return \"grid\";\n};\n\nconst flattenRoutes = (routes: PanelRoute[]): PanelRoute[] => {\n const result: PanelRoute[] = [];\n const walk = (node: PanelRoute): void => {\n result.push(node);\n if (node.children) {\n node.children.forEach((child) => walk(child));\n }\n };\n routes.forEach((r) => walk(r));\n return result;\n};\n\nconst validateUniqueIds = (routes: PanelRoute[]): void => {\n const seen = new Set<string>();\n routes.forEach((r) => {\n if (seen.has(r.id)) {\n throw new Error(`Duplicate PanelRoute id detected: ${r.id}`);\n }\n seen.add(r.id);\n });\n};\n\nexport const buildLayersFromRoutes = (routes: PanelRoute[]): LayerDefinition[] => {\n const flat = flattenRoutes(routes);\n validateUniqueIds(flat);\n return flat.map((r) => toLayer(r));\n};\n\nexport const createPanelLayoutFromRoutes = (input: {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n}): PanelLayoutProps => {\n const layers = buildLayersFromRoutes(input.routes);\n return {\n config: input.config,\n layers,\n };\n};\n\nexport type PanelLayoutRouterProps = {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n};\n\nexport const PanelLayoutRouter: React.FC<PanelLayoutRouterProps> = ({ config, routes, style }) => {\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n return <GridLayout config={config} layers={layers} style={style} />;\n};\n","/**\n * @file PanelContentDeclaration (JSX DSL for content configuration ONLY)\n *\n * IMPORTANT: This file declares a JSX DSL to configure panel \"content\" and layout\n * tracks. It does NOT implement grid rendering, resizing, dragging, or drawers.\n * Those behaviors live in the existing layout/rendering modules. Keep this file\n * limited to declaration and conversion into GridLayout props.\n *\n * Usage (content declaration):\n * <PanelLayout>\n * <Config>\n * <Rows>...</Rows>\n * <Columns>...</Columns>\n * <Areas matrix={...}/>\n * </Config>\n * <Panel type=\"grid\" id=\"main\" area=\"main\">...</Panel>\n * <Panel type=\"floating\" id=\"preview\" position={{ left: 0, top: 0 }} width={300} height={200} />\n * <Panel type=\"drawer\" id=\"nav\" drawer={{ defaultOpen: true }} position={{ left: 0 }} />\n * </PanelLayout>\n */\nimport * as React from \"react\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\nimport type { DrawerBehavior, GridTrack, PanelLayoutConfig, WindowPosition } from \"../types\";\nimport type { PanelRoute } from \"./panelRouter\";\nimport { buildLayersFromRoutes } from \"./panelRouter\";\n\nexport type PanelRootProps = {\n config?: PanelLayoutConfig;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\n// Unified child declaration: <Panel type=\"grid\" .../> or <Panel type=\"floating\" .../>...\ntype PanelCommonProps = {\n id: string;\n visible?: boolean;\n zIndex?: number;\n width?: number | string;\n height?: number | string;\n pointerEvents?: boolean | \"auto\" | \"none\";\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport type PanelProps =\n | (PanelCommonProps & { type: \"grid\"; area: string })\n | (PanelCommonProps & {\n type: \"floating\";\n position: WindowPosition;\n width: number | string;\n height: number | string;\n draggable?: boolean;\n resizable?: boolean;\n })\n | (PanelCommonProps & {\n type: \"drawer\";\n drawer: DrawerBehavior;\n position?: WindowPosition;\n backdropStyle?: React.CSSProperties;\n })\n | (Omit<PanelCommonProps, \"children\"> & {\n type: \"pivot\";\n area: string;\n /** Currently active item ID (controlled mode) */\n activeId?: string;\n /** Default active item ID (uncontrolled mode) */\n defaultActiveId?: string;\n /** Callback when active item changes */\n onActiveChange?: (id: string) => void;\n children?: React.ReactNode;\n });\n\nexport const Panel: React.FC<PanelProps> = () => null;\n\n/**\n * PivotItem declaration for use inside <Panel type=\"pivot\">\n */\nexport type PivotItemDeclProps = {\n id: string;\n label?: string;\n disabled?: boolean;\n children?: React.ReactNode;\n};\n\nexport const PivotItem: React.FC<PivotItemDeclProps> = () => null;\n\nconst isElementOf = <P,>(element: unknown, component: React.FC<P>): element is React.ReactElement<P> => {\n if (!React.isValidElement<P>(element)) {\n return false;\n }\n return element.type === component;\n};\n\nexport const buildRoutesFromChildren = (children: React.ReactNode): PanelRoute[] => {\n const routes: PanelRoute[] = [];\n\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n // Unified <Panel type=\"...\" />\n if (isElementOf(node, Panel)) {\n const props = node.props as PanelProps;\n if (!props.id) {\n throw new Error(\"<Panel> requires an 'id' prop.\");\n }\n if (props.type === \"grid\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"grid\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: props.children ?? null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n });\n return;\n }\n if (props.type === \"floating\") {\n if (!props.position) {\n throw new Error(`<Panel id=\"${props.id}\"> requires a 'position' prop when type=\"floating\".`);\n }\n if (props.width === undefined || props.height === undefined) {\n throw new Error(`<Panel id=\"${props.id}\"> requires 'width' and 'height' when type=\"floating\".`);\n }\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"absolute\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n floating: { mode: \"embedded\", draggable: props.draggable, resizable: props.resizable },\n });\n return;\n }\n if (props.type === \"drawer\") {\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"relative\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n drawer: props.drawer,\n backdropStyle: props.backdropStyle,\n });\n return;\n }\n if (props.type === \"pivot\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"pivot\".`);\n }\n const pivotItems = collectPivotItems(props.children);\n if (pivotItems.length === 0) {\n throw new Error(`<Panel id=\"${props.id}\"> requires at least one <PivotItem> child when type=\"pivot\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n pivot: {\n items: pivotItems,\n activeId: props.activeId,\n defaultActiveId: props.defaultActiveId,\n onActiveChange: props.onActiveChange,\n },\n });\n return;\n }\n // unknown type -> error for explicitness\n throw new Error(\"<Panel> has unsupported type.\");\n }\n\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n return;\n }\n // Unknown element: ignore quietly to allow comments/wrappers.\n return;\n }\n // Primitive nodes (string/number) are ignored.\n };\n\n visit(children);\n return routes;\n};\n\n// Root container renamed to PanelLayout to avoid name collision with child <Panel/>\nexport const PanelLayout: React.FC<PanelRootProps> = ({ config, style, children }) => {\n const routes = React.useMemo(() => buildRoutesFromChildren(children), [children]);\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n const derivedConfig = React.useMemo(() => {\n if (config) {\n return config;\n }\n const built = buildConfigFromChildren(children);\n if (!built) {\n throw new Error(\"Panel requires either 'config' prop or a JSX config (<Config><Rows/><Columns/><Areas/></Config>). \");\n }\n return built;\n }, [children, config]);\n return <GridLayout config={derivedConfig} layers={layers} style={style} />;\n};\n\n// =============================\n// JSX Config Declarations\n// =============================\n\nexport type ConfigProps = {\n gap?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport const Config: React.FC<ConfigProps> = () => {\n return null;\n};\n\nexport const Rows: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport const Columns: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport type RowProps = GridTrack;\nexport const Row: React.FC<RowProps> = () => {\n return null;\n};\n\nexport type ColumnProps = GridTrack;\nexport const Col: React.FC<ColumnProps> = () => {\n return null;\n};\n\nexport type AreasProps = {\n matrix: string[][];\n};\nexport const Areas: React.FC<AreasProps> = () => {\n return null;\n};\n\ntype CollectedConfig = {\n gap?: string;\n style?: React.CSSProperties;\n rows?: GridTrack[];\n columns?: GridTrack[];\n areas?: string[][];\n};\n\nconst collectTracks = <P extends GridTrack>(children: React.ReactNode, marker: React.FC<P>): GridTrack[] => {\n const result: GridTrack[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, marker)) {\n const props = node.props as P;\n if (!props.size) {\n throw new Error(\"Row/Col requires 'size' property.\");\n }\n result.push({\n size: props.size,\n resizable: props.resizable,\n minSize: props.minSize,\n maxSize: props.maxSize,\n });\n return;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n };\n visit(children);\n return result;\n};\n\nconst collectConfigBlock = (children: React.ReactNode): CollectedConfig | null => {\n const node = findFirst(children, Config);\n if (!node) {\n return null;\n }\n const props = node.props as ConfigProps;\n const rows = collectTracks(node.props.children, Row);\n const columns = collectTracks(node.props.children, Col);\n const areasNode = findFirst(node.props.children, Areas);\n const areas = areasNode ? (areasNode.props as AreasProps).matrix : undefined;\n return {\n gap: props.gap,\n style: props.style,\n rows,\n columns,\n areas,\n };\n};\n\nconst findFirst = <P,>(children: React.ReactNode, marker: React.FC<P>): React.ReactElement<P> | null => {\n const visit = (node: React.ReactNode): React.ReactElement<P> | null => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return null;\n }\n if (Array.isArray(node)) {\n for (const item of node) {\n const found = visit(item);\n if (found) {\n return found;\n }\n }\n return null;\n }\n if (isElementOf(node, marker)) {\n return node as React.ReactElement<P>;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n return visit(el.props.children);\n }\n return null;\n };\n return visit(children);\n};\n\ntype CollectedPivotItem = {\n id: string;\n label?: string;\n content: React.ReactNode;\n disabled?: boolean;\n};\n\nconst collectPivotItems = (children: React.ReactNode): CollectedPivotItem[] => {\n const items: CollectedPivotItem[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, PivotItem)) {\n const props = node.props as PivotItemDeclProps;\n if (!props.id) {\n throw new Error(\"<PivotItem> requires an 'id' prop.\");\n }\n items.push({\n id: props.id,\n label: props.label,\n content: props.children ?? null,\n disabled: props.disabled,\n });\n return;\n }\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n }\n };\n visit(children);\n return items;\n};\n\nexport const buildConfigFromChildren = (children: React.ReactNode): PanelLayoutConfig | null => {\n const collected = collectConfigBlock(children);\n if (!collected) {\n return null;\n }\n if (!collected.rows || collected.rows.length === 0) {\n throw new Error(\"Config must include at least one <Row size=...> inside <Config>.\");\n }\n if (!collected.columns || collected.columns.length === 0) {\n throw new Error(\"Config must include at least one <Col size=...> inside <Config>.\");\n }\n if (!collected.areas || collected.areas.length === 0) {\n throw new Error(\"Config must include <Areas matrix={...}> inside <Config>.\");\n }\n\n const rowCount = collected.areas.length;\n const colCount = collected.areas[0]?.length ?? 0;\n if (rowCount !== collected.rows.length) {\n throw new Error(`Areas row count (${rowCount}) must match Rows count (${collected.rows.length}).`);\n }\n if (colCount !== collected.columns.length) {\n throw new Error(`Areas column count (${colCount}) must match Columns count (${collected.columns.length}).`);\n }\n\n return {\n areas: collected.areas,\n rows: collected.rows,\n columns: collected.columns,\n gap: collected.gap,\n style: collected.style,\n } satisfies PanelLayoutConfig;\n};\n"],"names":["toLayer","route","inferredMode","resolveRoutePositionMode","flattenRoutes","routes","result","walk","node","child","r","validateUniqueIds","seen","buildLayersFromRoutes","flat","Panel","PivotItem","isElementOf","element","component","React","buildRoutesFromChildren","children","visit","props","pivotItems","collectPivotItems","PanelLayout","config","style","layers","derivedConfig","built","buildConfigFromChildren","jsx","GridLayout","Config","Rows","Columns","Row","Col","Areas","collectTracks","marker","collectConfigBlock","findFirst","rows","columns","areasNode","areas","item","found","items","collected","rowCount","colCount"],"mappings":"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"}
|
package/dist/config.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { jsx as u } from "react/jsx-runtime";
|
|
2
2
|
import * as s from "react";
|
|
3
|
-
import { G as d } from "./GridLayout-
|
|
3
|
+
import { G as d } from "./GridLayout-BltqeCPK.js";
|
|
4
|
+
import "./FloatingPanelFrame-SgYLc6Ud.js";
|
|
5
|
+
import "./FloatingWindow-BpdOpg_L.js";
|
|
4
6
|
const h = (i) => {
|
|
5
7
|
const r = f(i);
|
|
6
8
|
if (r === "grid" && !i.area)
|
|
@@ -138,7 +140,7 @@ const h = (i) => {
|
|
|
138
140
|
}
|
|
139
141
|
};
|
|
140
142
|
return n(i), r;
|
|
141
|
-
},
|
|
143
|
+
}, S = ({ config: i, style: r, children: n }) => {
|
|
142
144
|
const t = s.useMemo(() => E(n), [n]), e = s.useMemo(() => g(t), [t]), o = s.useMemo(() => {
|
|
143
145
|
if (i)
|
|
144
146
|
return i;
|
|
@@ -148,7 +150,7 @@ const h = (i) => {
|
|
|
148
150
|
return l;
|
|
149
151
|
}, [n, i]);
|
|
150
152
|
return /* @__PURE__ */ u(d, { config: o, layers: e, style: r });
|
|
151
|
-
}, b = () => null,
|
|
153
|
+
}, b = () => null, k = () => null, F = () => null, z = () => null, C = () => null, I = () => null, p = (i, r) => {
|
|
152
154
|
const n = [], t = (e) => {
|
|
153
155
|
if (!(e == null || typeof e == "boolean")) {
|
|
154
156
|
if (Array.isArray(e)) {
|
|
@@ -172,10 +174,10 @@ const h = (i) => {
|
|
|
172
174
|
};
|
|
173
175
|
return t(i), n;
|
|
174
176
|
}, x = (i) => {
|
|
175
|
-
const r =
|
|
177
|
+
const r = c(i, b);
|
|
176
178
|
if (!r)
|
|
177
179
|
return null;
|
|
178
|
-
const n = r.props, t =
|
|
180
|
+
const n = r.props, t = p(r.props.children, z), e = p(r.props.children, C), o = c(r.props.children, I), l = o ? o.props.matrix : void 0;
|
|
179
181
|
return {
|
|
180
182
|
gap: n.gap,
|
|
181
183
|
style: n.style,
|
|
@@ -183,7 +185,7 @@ const h = (i) => {
|
|
|
183
185
|
columns: e,
|
|
184
186
|
areas: l
|
|
185
187
|
};
|
|
186
|
-
},
|
|
188
|
+
}, c = (i, r) => {
|
|
187
189
|
const n = (t) => {
|
|
188
190
|
if (t == null || typeof t == "boolean")
|
|
189
191
|
return null;
|
|
@@ -247,12 +249,12 @@ const h = (i) => {
|
|
|
247
249
|
export {
|
|
248
250
|
I as Areas,
|
|
249
251
|
C as Col,
|
|
250
|
-
|
|
252
|
+
F as Columns,
|
|
251
253
|
b as Config,
|
|
252
254
|
v as Panel,
|
|
253
|
-
|
|
255
|
+
S as PanelLayout,
|
|
254
256
|
z as Row,
|
|
255
|
-
|
|
257
|
+
k as Rows,
|
|
256
258
|
P as buildConfigFromChildren,
|
|
257
259
|
E as buildRoutesFromChildren
|
|
258
260
|
};
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sources":["../src/config/panelRouter.tsx","../src/config/PanelContentDeclaration.tsx"],"sourcesContent":["/**\n * @file Router-like builder for GridLayout\n *\n * Provides a React Router–style configuration API to declare panel layers.\n * Converts route objects to the existing GridLayout props without magic.\n */\nimport * as React from \"react\";\nimport type {\n DrawerBehavior,\n FloatingBehavior,\n LayerDefinition,\n LayerPositionMode,\n PanelLayoutConfig,\n PanelLayoutProps,\n PivotBehavior,\n WindowPosition,\n} from \"../types\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\n\nexport type PanelRoute = {\n /** Unique id for the layer. Required. */\n id: string;\n /** React node to render for this layer. Required. */\n element: React.ReactNode;\n /** Visibility flag. Defaults to visible. */\n visible?: boolean;\n\n /**\n * Grid placement key. When using `positionMode: 'grid'` (default), this must be provided.\n * Using `area` mirrors React Router's route path intent but for grid cells.\n */\n area?: string;\n\n /** Explicit positioning mode; defaults to 'grid' unless floating/drawer implies otherwise. */\n positionMode?: LayerPositionMode;\n /** Offsets when using non-grid modes. */\n position?: WindowPosition;\n /** Optional stacking order. */\n zIndex?: number;\n /** Optional dimensions; required for resizable/draggable floating layers. */\n width?: number | string;\n height?: number | string;\n /** Pointer events control. */\n pointerEvents?: boolean | \"auto\" | \"none\";\n /** Optional style overrides. */\n style?: React.CSSProperties;\n /** Optional backdrop style (drawer). */\n backdropStyle?: React.CSSProperties;\n\n /** Drawer behavior for mobile-friendly panels. */\n drawer?: DrawerBehavior;\n /** Floating window configuration. */\n floating?: FloatingBehavior;\n /** Pivot behavior for content switching. */\n pivot?: PivotBehavior;\n\n /**\n * Optional child declarations; purely a grouping convenience.\n * Children are flattened; no implicit inheritance.\n */\n children?: PanelRoute[];\n};\n\nconst toLayer = (route: PanelRoute): LayerDefinition => {\n const inferredMode: LayerPositionMode = resolveRoutePositionMode(route);\n\n if (inferredMode === \"grid\") {\n if (!route.area) {\n throw new Error(`PanelRoute ${route.id} must specify 'area' for grid placement.`);\n }\n }\n\n return {\n id: route.id,\n component: route.element,\n visible: route.visible,\n gridArea: route.area,\n positionMode: inferredMode,\n position: route.position,\n zIndex: route.zIndex,\n width: route.width,\n height: route.height,\n pointerEvents: route.pointerEvents,\n style: route.style,\n drawer: route.drawer,\n floating: route.floating,\n pivot: route.pivot,\n backdropStyle: route.backdropStyle,\n } satisfies LayerDefinition;\n};\n\nconst resolveRoutePositionMode = (route: PanelRoute): LayerPositionMode => {\n if (route.positionMode) {\n return route.positionMode;\n }\n if (route.floating) {\n // Embedded => absolute, Popup => relative (handled by renderer); keep explicitness here.\n return \"absolute\";\n }\n if (route.drawer) {\n return \"grid\";\n }\n return \"grid\";\n};\n\nconst flattenRoutes = (routes: PanelRoute[]): PanelRoute[] => {\n const result: PanelRoute[] = [];\n const walk = (node: PanelRoute): void => {\n result.push(node);\n if (node.children) {\n node.children.forEach((child) => walk(child));\n }\n };\n routes.forEach((r) => walk(r));\n return result;\n};\n\nconst validateUniqueIds = (routes: PanelRoute[]): void => {\n const seen = new Set<string>();\n routes.forEach((r) => {\n if (seen.has(r.id)) {\n throw new Error(`Duplicate PanelRoute id detected: ${r.id}`);\n }\n seen.add(r.id);\n });\n};\n\nexport const buildLayersFromRoutes = (routes: PanelRoute[]): LayerDefinition[] => {\n const flat = flattenRoutes(routes);\n validateUniqueIds(flat);\n return flat.map((r) => toLayer(r));\n};\n\nexport const createPanelLayoutFromRoutes = (input: {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n}): PanelLayoutProps => {\n const layers = buildLayersFromRoutes(input.routes);\n return {\n config: input.config,\n layers,\n };\n};\n\nexport type PanelLayoutRouterProps = {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n};\n\nexport const PanelLayoutRouter: React.FC<PanelLayoutRouterProps> = ({ config, routes, style }) => {\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n return <GridLayout config={config} layers={layers} style={style} />;\n};\n","/**\n * @file PanelContentDeclaration (JSX DSL for content configuration ONLY)\n *\n * IMPORTANT: This file declares a JSX DSL to configure panel \"content\" and layout\n * tracks. It does NOT implement grid rendering, resizing, dragging, or drawers.\n * Those behaviors live in the existing layout/rendering modules. Keep this file\n * limited to declaration and conversion into GridLayout props.\n *\n * Usage (content declaration):\n * <PanelLayout>\n * <Config>\n * <Rows>...</Rows>\n * <Columns>...</Columns>\n * <Areas matrix={...}/>\n * </Config>\n * <Panel type=\"grid\" id=\"main\" area=\"main\">...</Panel>\n * <Panel type=\"floating\" id=\"preview\" position={{ left: 0, top: 0 }} width={300} height={200} />\n * <Panel type=\"drawer\" id=\"nav\" drawer={{ defaultOpen: true }} position={{ left: 0 }} />\n * </PanelLayout>\n */\nimport * as React from \"react\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\nimport type { DrawerBehavior, GridTrack, PanelLayoutConfig, WindowPosition } from \"../types\";\nimport type { PanelRoute } from \"./panelRouter\";\nimport { buildLayersFromRoutes } from \"./panelRouter\";\n\nexport type PanelRootProps = {\n config?: PanelLayoutConfig;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\n// Unified child declaration: <Panel type=\"grid\" .../> or <Panel type=\"floating\" .../>...\ntype PanelCommonProps = {\n id: string;\n visible?: boolean;\n zIndex?: number;\n width?: number | string;\n height?: number | string;\n pointerEvents?: boolean | \"auto\" | \"none\";\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport type PanelProps =\n | (PanelCommonProps & { type: \"grid\"; area: string })\n | (PanelCommonProps & {\n type: \"floating\";\n position: WindowPosition;\n width: number | string;\n height: number | string;\n draggable?: boolean;\n resizable?: boolean;\n })\n | (PanelCommonProps & {\n type: \"drawer\";\n drawer: DrawerBehavior;\n position?: WindowPosition;\n backdropStyle?: React.CSSProperties;\n })\n | (Omit<PanelCommonProps, \"children\"> & {\n type: \"pivot\";\n area: string;\n /** Currently active item ID (controlled mode) */\n activeId?: string;\n /** Default active item ID (uncontrolled mode) */\n defaultActiveId?: string;\n /** Callback when active item changes */\n onActiveChange?: (id: string) => void;\n children?: React.ReactNode;\n });\n\nexport const Panel: React.FC<PanelProps> = () => null;\n\n/**\n * PivotItem declaration for use inside <Panel type=\"pivot\">\n */\nexport type PivotItemDeclProps = {\n id: string;\n label?: string;\n disabled?: boolean;\n children?: React.ReactNode;\n};\n\nexport const PivotItem: React.FC<PivotItemDeclProps> = () => null;\n\nconst isElementOf = <P,>(element: unknown, component: React.FC<P>): element is React.ReactElement<P> => {\n if (!React.isValidElement<P>(element)) {\n return false;\n }\n return element.type === component;\n};\n\nexport const buildRoutesFromChildren = (children: React.ReactNode): PanelRoute[] => {\n const routes: PanelRoute[] = [];\n\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n // Unified <Panel type=\"...\" />\n if (isElementOf(node, Panel)) {\n const props = node.props as PanelProps;\n if (!props.id) {\n throw new Error(\"<Panel> requires an 'id' prop.\");\n }\n if (props.type === \"grid\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"grid\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: props.children ?? null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n });\n return;\n }\n if (props.type === \"floating\") {\n if (!props.position) {\n throw new Error(`<Panel id=\"${props.id}\"> requires a 'position' prop when type=\"floating\".`);\n }\n if (props.width === undefined || props.height === undefined) {\n throw new Error(`<Panel id=\"${props.id}\"> requires 'width' and 'height' when type=\"floating\".`);\n }\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"absolute\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n floating: { mode: \"embedded\", draggable: props.draggable, resizable: props.resizable },\n });\n return;\n }\n if (props.type === \"drawer\") {\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"relative\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n drawer: props.drawer,\n backdropStyle: props.backdropStyle,\n });\n return;\n }\n if (props.type === \"pivot\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"pivot\".`);\n }\n const pivotItems = collectPivotItems(props.children);\n if (pivotItems.length === 0) {\n throw new Error(`<Panel id=\"${props.id}\"> requires at least one <PivotItem> child when type=\"pivot\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n pivot: {\n items: pivotItems,\n activeId: props.activeId,\n defaultActiveId: props.defaultActiveId,\n onActiveChange: props.onActiveChange,\n },\n });\n return;\n }\n // unknown type -> error for explicitness\n throw new Error(\"<Panel> has unsupported type.\");\n }\n\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n return;\n }\n // Unknown element: ignore quietly to allow comments/wrappers.\n return;\n }\n // Primitive nodes (string/number) are ignored.\n };\n\n visit(children);\n return routes;\n};\n\n// Root container renamed to PanelLayout to avoid name collision with child <Panel/>\nexport const PanelLayout: React.FC<PanelRootProps> = ({ config, style, children }) => {\n const routes = React.useMemo(() => buildRoutesFromChildren(children), [children]);\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n const derivedConfig = React.useMemo(() => {\n if (config) {\n return config;\n }\n const built = buildConfigFromChildren(children);\n if (!built) {\n throw new Error(\"Panel requires either 'config' prop or a JSX config (<Config><Rows/><Columns/><Areas/></Config>). \");\n }\n return built;\n }, [children, config]);\n return <GridLayout config={derivedConfig} layers={layers} style={style} />;\n};\n\n// =============================\n// JSX Config Declarations\n// =============================\n\nexport type ConfigProps = {\n gap?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport const Config: React.FC<ConfigProps> = () => {\n return null;\n};\n\nexport const Rows: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport const Columns: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport type RowProps = GridTrack;\nexport const Row: React.FC<RowProps> = () => {\n return null;\n};\n\nexport type ColumnProps = GridTrack;\nexport const Col: React.FC<ColumnProps> = () => {\n return null;\n};\n\nexport type AreasProps = {\n matrix: string[][];\n};\nexport const Areas: React.FC<AreasProps> = () => {\n return null;\n};\n\ntype CollectedConfig = {\n gap?: string;\n style?: React.CSSProperties;\n rows?: GridTrack[];\n columns?: GridTrack[];\n areas?: string[][];\n};\n\nconst collectTracks = <P extends GridTrack>(children: React.ReactNode, marker: React.FC<P>): GridTrack[] => {\n const result: GridTrack[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, marker)) {\n const props = node.props as P;\n if (!props.size) {\n throw new Error(\"Row/Col requires 'size' property.\");\n }\n result.push({\n size: props.size,\n resizable: props.resizable,\n minSize: props.minSize,\n maxSize: props.maxSize,\n });\n return;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n };\n visit(children);\n return result;\n};\n\nconst collectConfigBlock = (children: React.ReactNode): CollectedConfig | null => {\n const node = findFirst(children, Config);\n if (!node) {\n return null;\n }\n const props = node.props as ConfigProps;\n const rows = collectTracks(node.props.children, Row);\n const columns = collectTracks(node.props.children, Col);\n const areasNode = findFirst(node.props.children, Areas);\n const areas = areasNode ? (areasNode.props as AreasProps).matrix : undefined;\n return {\n gap: props.gap,\n style: props.style,\n rows,\n columns,\n areas,\n };\n};\n\nconst findFirst = <P,>(children: React.ReactNode, marker: React.FC<P>): React.ReactElement<P> | null => {\n const visit = (node: React.ReactNode): React.ReactElement<P> | null => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return null;\n }\n if (Array.isArray(node)) {\n for (const item of node) {\n const found = visit(item);\n if (found) {\n return found;\n }\n }\n return null;\n }\n if (isElementOf(node, marker)) {\n return node as React.ReactElement<P>;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n return visit(el.props.children);\n }\n return null;\n };\n return visit(children);\n};\n\ntype CollectedPivotItem = {\n id: string;\n label?: string;\n content: React.ReactNode;\n disabled?: boolean;\n};\n\nconst collectPivotItems = (children: React.ReactNode): CollectedPivotItem[] => {\n const items: CollectedPivotItem[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, PivotItem)) {\n const props = node.props as PivotItemDeclProps;\n if (!props.id) {\n throw new Error(\"<PivotItem> requires an 'id' prop.\");\n }\n items.push({\n id: props.id,\n label: props.label,\n content: props.children ?? null,\n disabled: props.disabled,\n });\n return;\n }\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n }\n };\n visit(children);\n return items;\n};\n\nexport const buildConfigFromChildren = (children: React.ReactNode): PanelLayoutConfig | null => {\n const collected = collectConfigBlock(children);\n if (!collected) {\n return null;\n }\n if (!collected.rows || collected.rows.length === 0) {\n throw new Error(\"Config must include at least one <Row size=...> inside <Config>.\");\n }\n if (!collected.columns || collected.columns.length === 0) {\n throw new Error(\"Config must include at least one <Col size=...> inside <Config>.\");\n }\n if (!collected.areas || collected.areas.length === 0) {\n throw new Error(\"Config must include <Areas matrix={...}> inside <Config>.\");\n }\n\n const rowCount = collected.areas.length;\n const colCount = collected.areas[0]?.length ?? 0;\n if (rowCount !== collected.rows.length) {\n throw new Error(`Areas row count (${rowCount}) must match Rows count (${collected.rows.length}).`);\n }\n if (colCount !== collected.columns.length) {\n throw new Error(`Areas column count (${colCount}) must match Columns count (${collected.columns.length}).`);\n }\n\n return {\n areas: collected.areas,\n rows: collected.rows,\n columns: collected.columns,\n gap: collected.gap,\n style: collected.style,\n } satisfies PanelLayoutConfig;\n};\n"],"names":["toLayer","route","inferredMode","resolveRoutePositionMode","flattenRoutes","routes","result","walk","node","child","r","validateUniqueIds","seen","buildLayersFromRoutes","flat","Panel","PivotItem","isElementOf","element","component","React","buildRoutesFromChildren","children","visit","props","pivotItems","collectPivotItems","PanelLayout","config","style","layers","derivedConfig","built","buildConfigFromChildren","jsx","GridLayout","Config","Rows","Columns","Row","Col","Areas","collectTracks","marker","collectConfigBlock","findFirst","rows","columns","areasNode","areas","item","found","items","collected","rowCount","colCount"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.js","sources":["../src/config/panelRouter.tsx","../src/config/PanelContentDeclaration.tsx"],"sourcesContent":["/**\n * @file Router-like builder for GridLayout\n *\n * Provides a React Router–style configuration API to declare panel layers.\n * Converts route objects to the existing GridLayout props without magic.\n */\nimport * as React from \"react\";\nimport type {\n DrawerBehavior,\n FloatingBehavior,\n LayerDefinition,\n LayerPositionMode,\n PanelLayoutConfig,\n PanelLayoutProps,\n PivotBehavior,\n WindowPosition,\n} from \"../types\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\n\nexport type PanelRoute = {\n /** Unique id for the layer. Required. */\n id: string;\n /** React node to render for this layer. Required. */\n element: React.ReactNode;\n /** Visibility flag. Defaults to visible. */\n visible?: boolean;\n\n /**\n * Grid placement key. When using `positionMode: 'grid'` (default), this must be provided.\n * Using `area` mirrors React Router's route path intent but for grid cells.\n */\n area?: string;\n\n /** Explicit positioning mode; defaults to 'grid' unless floating/drawer implies otherwise. */\n positionMode?: LayerPositionMode;\n /** Offsets when using non-grid modes. */\n position?: WindowPosition;\n /** Optional stacking order. */\n zIndex?: number;\n /** Optional dimensions; required for resizable/draggable floating layers. */\n width?: number | string;\n height?: number | string;\n /** Pointer events control. */\n pointerEvents?: boolean | \"auto\" | \"none\";\n /** Optional style overrides. */\n style?: React.CSSProperties;\n /** Optional backdrop style (drawer). */\n backdropStyle?: React.CSSProperties;\n\n /** Drawer behavior for mobile-friendly panels. */\n drawer?: DrawerBehavior;\n /** Floating window configuration. */\n floating?: FloatingBehavior;\n /** Pivot behavior for content switching. */\n pivot?: PivotBehavior;\n\n /**\n * Optional child declarations; purely a grouping convenience.\n * Children are flattened; no implicit inheritance.\n */\n children?: PanelRoute[];\n};\n\nconst toLayer = (route: PanelRoute): LayerDefinition => {\n const inferredMode: LayerPositionMode = resolveRoutePositionMode(route);\n\n if (inferredMode === \"grid\") {\n if (!route.area) {\n throw new Error(`PanelRoute ${route.id} must specify 'area' for grid placement.`);\n }\n }\n\n return {\n id: route.id,\n component: route.element,\n visible: route.visible,\n gridArea: route.area,\n positionMode: inferredMode,\n position: route.position,\n zIndex: route.zIndex,\n width: route.width,\n height: route.height,\n pointerEvents: route.pointerEvents,\n style: route.style,\n drawer: route.drawer,\n floating: route.floating,\n pivot: route.pivot,\n backdropStyle: route.backdropStyle,\n } satisfies LayerDefinition;\n};\n\nconst resolveRoutePositionMode = (route: PanelRoute): LayerPositionMode => {\n if (route.positionMode) {\n return route.positionMode;\n }\n if (route.floating) {\n // Embedded => absolute, Popup => relative (handled by renderer); keep explicitness here.\n return \"absolute\";\n }\n if (route.drawer) {\n return \"grid\";\n }\n return \"grid\";\n};\n\nconst flattenRoutes = (routes: PanelRoute[]): PanelRoute[] => {\n const result: PanelRoute[] = [];\n const walk = (node: PanelRoute): void => {\n result.push(node);\n if (node.children) {\n node.children.forEach((child) => walk(child));\n }\n };\n routes.forEach((r) => walk(r));\n return result;\n};\n\nconst validateUniqueIds = (routes: PanelRoute[]): void => {\n const seen = new Set<string>();\n routes.forEach((r) => {\n if (seen.has(r.id)) {\n throw new Error(`Duplicate PanelRoute id detected: ${r.id}`);\n }\n seen.add(r.id);\n });\n};\n\nexport const buildLayersFromRoutes = (routes: PanelRoute[]): LayerDefinition[] => {\n const flat = flattenRoutes(routes);\n validateUniqueIds(flat);\n return flat.map((r) => toLayer(r));\n};\n\nexport const createPanelLayoutFromRoutes = (input: {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n}): PanelLayoutProps => {\n const layers = buildLayersFromRoutes(input.routes);\n return {\n config: input.config,\n layers,\n };\n};\n\nexport type PanelLayoutRouterProps = {\n config: PanelLayoutConfig;\n routes: PanelRoute[];\n style?: React.CSSProperties;\n};\n\nexport const PanelLayoutRouter: React.FC<PanelLayoutRouterProps> = ({ config, routes, style }) => {\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n return <GridLayout config={config} layers={layers} style={style} />;\n};\n","/**\n * @file PanelContentDeclaration (JSX DSL for content configuration ONLY)\n *\n * IMPORTANT: This file declares a JSX DSL to configure panel \"content\" and layout\n * tracks. It does NOT implement grid rendering, resizing, dragging, or drawers.\n * Those behaviors live in the existing layout/rendering modules. Keep this file\n * limited to declaration and conversion into GridLayout props.\n *\n * Usage (content declaration):\n * <PanelLayout>\n * <Config>\n * <Rows>...</Rows>\n * <Columns>...</Columns>\n * <Areas matrix={...}/>\n * </Config>\n * <Panel type=\"grid\" id=\"main\" area=\"main\">...</Panel>\n * <Panel type=\"floating\" id=\"preview\" position={{ left: 0, top: 0 }} width={300} height={200} />\n * <Panel type=\"drawer\" id=\"nav\" drawer={{ defaultOpen: true }} position={{ left: 0 }} />\n * </PanelLayout>\n */\nimport * as React from \"react\";\nimport { GridLayout } from \"../components/grid/GridLayout\";\nimport type { DrawerBehavior, GridTrack, PanelLayoutConfig, WindowPosition } from \"../types\";\nimport type { PanelRoute } from \"./panelRouter\";\nimport { buildLayersFromRoutes } from \"./panelRouter\";\n\nexport type PanelRootProps = {\n config?: PanelLayoutConfig;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\n// Unified child declaration: <Panel type=\"grid\" .../> or <Panel type=\"floating\" .../>...\ntype PanelCommonProps = {\n id: string;\n visible?: boolean;\n zIndex?: number;\n width?: number | string;\n height?: number | string;\n pointerEvents?: boolean | \"auto\" | \"none\";\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport type PanelProps =\n | (PanelCommonProps & { type: \"grid\"; area: string })\n | (PanelCommonProps & {\n type: \"floating\";\n position: WindowPosition;\n width: number | string;\n height: number | string;\n draggable?: boolean;\n resizable?: boolean;\n })\n | (PanelCommonProps & {\n type: \"drawer\";\n drawer: DrawerBehavior;\n position?: WindowPosition;\n backdropStyle?: React.CSSProperties;\n })\n | (Omit<PanelCommonProps, \"children\"> & {\n type: \"pivot\";\n area: string;\n /** Currently active item ID (controlled mode) */\n activeId?: string;\n /** Default active item ID (uncontrolled mode) */\n defaultActiveId?: string;\n /** Callback when active item changes */\n onActiveChange?: (id: string) => void;\n children?: React.ReactNode;\n });\n\nexport const Panel: React.FC<PanelProps> = () => null;\n\n/**\n * PivotItem declaration for use inside <Panel type=\"pivot\">\n */\nexport type PivotItemDeclProps = {\n id: string;\n label?: string;\n disabled?: boolean;\n children?: React.ReactNode;\n};\n\nexport const PivotItem: React.FC<PivotItemDeclProps> = () => null;\n\nconst isElementOf = <P,>(element: unknown, component: React.FC<P>): element is React.ReactElement<P> => {\n if (!React.isValidElement<P>(element)) {\n return false;\n }\n return element.type === component;\n};\n\nexport const buildRoutesFromChildren = (children: React.ReactNode): PanelRoute[] => {\n const routes: PanelRoute[] = [];\n\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n // Unified <Panel type=\"...\" />\n if (isElementOf(node, Panel)) {\n const props = node.props as PanelProps;\n if (!props.id) {\n throw new Error(\"<Panel> requires an 'id' prop.\");\n }\n if (props.type === \"grid\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"grid\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: props.children ?? null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n });\n return;\n }\n if (props.type === \"floating\") {\n if (!props.position) {\n throw new Error(`<Panel id=\"${props.id}\"> requires a 'position' prop when type=\"floating\".`);\n }\n if (props.width === undefined || props.height === undefined) {\n throw new Error(`<Panel id=\"${props.id}\"> requires 'width' and 'height' when type=\"floating\".`);\n }\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"absolute\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n floating: { mode: \"embedded\", draggable: props.draggable, resizable: props.resizable },\n });\n return;\n }\n if (props.type === \"drawer\") {\n routes.push({\n id: props.id,\n element: props.children ?? null,\n visible: props.visible ?? true,\n positionMode: \"relative\",\n position: props.position,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n drawer: props.drawer,\n backdropStyle: props.backdropStyle,\n });\n return;\n }\n if (props.type === \"pivot\") {\n if (!props.area) {\n throw new Error(`<Panel id=\"${props.id}\"> requires an explicit 'area' prop when type=\"pivot\".`);\n }\n const pivotItems = collectPivotItems(props.children);\n if (pivotItems.length === 0) {\n throw new Error(`<Panel id=\"${props.id}\"> requires at least one <PivotItem> child when type=\"pivot\".`);\n }\n routes.push({\n id: props.id,\n area: props.area,\n element: null,\n visible: props.visible,\n zIndex: props.zIndex,\n width: props.width,\n height: props.height,\n pointerEvents: props.pointerEvents,\n style: props.style,\n pivot: {\n items: pivotItems,\n activeId: props.activeId,\n defaultActiveId: props.defaultActiveId,\n onActiveChange: props.onActiveChange,\n },\n });\n return;\n }\n // unknown type -> error for explicitness\n throw new Error(\"<Panel> has unsupported type.\");\n }\n\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n return;\n }\n // Unknown element: ignore quietly to allow comments/wrappers.\n return;\n }\n // Primitive nodes (string/number) are ignored.\n };\n\n visit(children);\n return routes;\n};\n\n// Root container renamed to PanelLayout to avoid name collision with child <Panel/>\nexport const PanelLayout: React.FC<PanelRootProps> = ({ config, style, children }) => {\n const routes = React.useMemo(() => buildRoutesFromChildren(children), [children]);\n const layers = React.useMemo(() => buildLayersFromRoutes(routes), [routes]);\n const derivedConfig = React.useMemo(() => {\n if (config) {\n return config;\n }\n const built = buildConfigFromChildren(children);\n if (!built) {\n throw new Error(\"Panel requires either 'config' prop or a JSX config (<Config><Rows/><Columns/><Areas/></Config>). \");\n }\n return built;\n }, [children, config]);\n return <GridLayout config={derivedConfig} layers={layers} style={style} />;\n};\n\n// =============================\n// JSX Config Declarations\n// =============================\n\nexport type ConfigProps = {\n gap?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n};\n\nexport const Config: React.FC<ConfigProps> = () => {\n return null;\n};\n\nexport const Rows: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport const Columns: React.FC<{ children?: React.ReactNode }> = () => {\n return null;\n};\n\nexport type RowProps = GridTrack;\nexport const Row: React.FC<RowProps> = () => {\n return null;\n};\n\nexport type ColumnProps = GridTrack;\nexport const Col: React.FC<ColumnProps> = () => {\n return null;\n};\n\nexport type AreasProps = {\n matrix: string[][];\n};\nexport const Areas: React.FC<AreasProps> = () => {\n return null;\n};\n\ntype CollectedConfig = {\n gap?: string;\n style?: React.CSSProperties;\n rows?: GridTrack[];\n columns?: GridTrack[];\n areas?: string[][];\n};\n\nconst collectTracks = <P extends GridTrack>(children: React.ReactNode, marker: React.FC<P>): GridTrack[] => {\n const result: GridTrack[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, marker)) {\n const props = node.props as P;\n if (!props.size) {\n throw new Error(\"Row/Col requires 'size' property.\");\n }\n result.push({\n size: props.size,\n resizable: props.resizable,\n minSize: props.minSize,\n maxSize: props.maxSize,\n });\n return;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n };\n visit(children);\n return result;\n};\n\nconst collectConfigBlock = (children: React.ReactNode): CollectedConfig | null => {\n const node = findFirst(children, Config);\n if (!node) {\n return null;\n }\n const props = node.props as ConfigProps;\n const rows = collectTracks(node.props.children, Row);\n const columns = collectTracks(node.props.children, Col);\n const areasNode = findFirst(node.props.children, Areas);\n const areas = areasNode ? (areasNode.props as AreasProps).matrix : undefined;\n return {\n gap: props.gap,\n style: props.style,\n rows,\n columns,\n areas,\n };\n};\n\nconst findFirst = <P,>(children: React.ReactNode, marker: React.FC<P>): React.ReactElement<P> | null => {\n const visit = (node: React.ReactNode): React.ReactElement<P> | null => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return null;\n }\n if (Array.isArray(node)) {\n for (const item of node) {\n const found = visit(item);\n if (found) {\n return found;\n }\n }\n return null;\n }\n if (isElementOf(node, marker)) {\n return node as React.ReactElement<P>;\n }\n if (React.isValidElement(node)) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n return visit(el.props.children);\n }\n return null;\n };\n return visit(children);\n};\n\ntype CollectedPivotItem = {\n id: string;\n label?: string;\n content: React.ReactNode;\n disabled?: boolean;\n};\n\nconst collectPivotItems = (children: React.ReactNode): CollectedPivotItem[] => {\n const items: CollectedPivotItem[] = [];\n const visit = (node: React.ReactNode): void => {\n if (node === null || node === undefined || typeof node === \"boolean\") {\n return;\n }\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (isElementOf(node, PivotItem)) {\n const props = node.props as PivotItemDeclProps;\n if (!props.id) {\n throw new Error(\"<PivotItem> requires an 'id' prop.\");\n }\n items.push({\n id: props.id,\n label: props.label,\n content: props.children ?? null,\n disabled: props.disabled,\n });\n return;\n }\n if (React.isValidElement(node)) {\n if (node.type === React.Fragment) {\n const el = node as React.ReactElement<{ children?: React.ReactNode }>;\n visit(el.props.children);\n }\n }\n };\n visit(children);\n return items;\n};\n\nexport const buildConfigFromChildren = (children: React.ReactNode): PanelLayoutConfig | null => {\n const collected = collectConfigBlock(children);\n if (!collected) {\n return null;\n }\n if (!collected.rows || collected.rows.length === 0) {\n throw new Error(\"Config must include at least one <Row size=...> inside <Config>.\");\n }\n if (!collected.columns || collected.columns.length === 0) {\n throw new Error(\"Config must include at least one <Col size=...> inside <Config>.\");\n }\n if (!collected.areas || collected.areas.length === 0) {\n throw new Error(\"Config must include <Areas matrix={...}> inside <Config>.\");\n }\n\n const rowCount = collected.areas.length;\n const colCount = collected.areas[0]?.length ?? 0;\n if (rowCount !== collected.rows.length) {\n throw new Error(`Areas row count (${rowCount}) must match Rows count (${collected.rows.length}).`);\n }\n if (colCount !== collected.columns.length) {\n throw new Error(`Areas column count (${colCount}) must match Columns count (${collected.columns.length}).`);\n }\n\n return {\n areas: collected.areas,\n rows: collected.rows,\n columns: collected.columns,\n gap: collected.gap,\n style: collected.style,\n } satisfies PanelLayoutConfig;\n};\n"],"names":["toLayer","route","inferredMode","resolveRoutePositionMode","flattenRoutes","routes","result","walk","node","child","r","validateUniqueIds","seen","buildLayersFromRoutes","flat","Panel","PivotItem","isElementOf","element","component","React","buildRoutesFromChildren","children","visit","props","pivotItems","collectPivotItems","PanelLayout","config","style","layers","derivedConfig","built","buildConfigFromChildren","jsx","GridLayout","Config","Rows","Columns","Row","Col","Areas","collectTracks","marker","collectConfigBlock","findFirst","rows","columns","areasNode","areas","item","found","items","collected","rowCount","colCount"],"mappings":"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"}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file Style constants for library components
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* type-safe constants in TypeScript.
|
|
4
|
+
* All style values are defined here with CSS variable fallbacks.
|
|
5
|
+
* Users can override these via CSS variables (--rpl-*).
|
|
7
6
|
*
|
|
8
7
|
* All CSS variables use the unified prefix: --rpl- (react-panel-layout)
|
|
9
|
-
* Users can override these via CSS variables (--rpl-*)
|
|
10
8
|
*
|
|
11
9
|
* @example
|
|
12
10
|
* // In your CSS:
|
|
@@ -77,6 +75,22 @@ export declare const DRAWER_TRANSITION_EASING = "var(--rpl-drawer-transition-eas
|
|
|
77
75
|
*/
|
|
78
76
|
export declare const PIVOT_ANIMATION_ENTER = "var(--rpl-pivot-animation-enter, none)";
|
|
79
77
|
export declare const PIVOT_ANIMATION_LEAVE = "var(--rpl-pivot-animation-leave, none)";
|
|
78
|
+
/**
|
|
79
|
+
* Pivot swipe animations
|
|
80
|
+
* Used by SwipePivotContent for snap-back animation after swipe ends.
|
|
81
|
+
*/
|
|
82
|
+
export declare const PIVOT_SWIPE_SNAP_DURATION = "var(--rpl-pivot-swipe-snap-duration, 300ms)";
|
|
83
|
+
export declare const PIVOT_SWIPE_SNAP_EASING = "var(--rpl-pivot-swipe-snap-easing, cubic-bezier(0.22, 1, 0.36, 1))";
|
|
84
|
+
/**
|
|
85
|
+
* Stack animations
|
|
86
|
+
* User defines @keyframes in their CSS and references via these tokens.
|
|
87
|
+
* - Push: Applied when a new panel is pushed onto the stack
|
|
88
|
+
* - Pop: Applied when a panel is popped from the stack
|
|
89
|
+
*/
|
|
90
|
+
export declare const STACK_ANIMATION_PUSH = "var(--rpl-stack-animation-push, none)";
|
|
91
|
+
export declare const STACK_ANIMATION_POP = "var(--rpl-stack-animation-pop, none)";
|
|
92
|
+
export declare const STACK_TRANSITION_DURATION = "var(--rpl-stack-transition-duration, 350ms)";
|
|
93
|
+
export declare const STACK_TRANSITION_EASING = "var(--rpl-stack-transition-easing, cubic-bezier(0.32, 0.72, 0, 1))";
|
|
80
94
|
/**
|
|
81
95
|
* Tab sizing
|
|
82
96
|
*/
|
package/dist/floating.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./FloatingPanelFrame-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./FloatingPanelFrame-CEmXDvUA.cjs");exports.FloatingPanelContent=a.FloatingPanelContent;exports.FloatingPanelControls=a.FloatingPanelControls;exports.FloatingPanelFrame=a.FloatingPanelFrame;exports.FloatingPanelHeader=a.FloatingPanelHeader;exports.FloatingPanelMeta=a.FloatingPanelMeta;exports.FloatingPanelTitle=a.FloatingPanelTitle;
|
|
2
2
|
//# sourceMappingURL=floating.cjs.map
|
package/dist/floating.js
CHANGED