@@ -5,23 +5,12 @@ import {
55 PanelGroup ,
66 PanelResizeHandle ,
77} from 'react-resizable-panels' ;
8- import { createGlobalStyle } from 'styled-components' ;
98
109import { useCunninghamTheme } from '@/cunningham' ;
1110
12- interface PanelStyleProps {
13- $isResizing : boolean ;
14- }
15-
16- const PanelStyle = createGlobalStyle < PanelStyleProps > `
17- ${ ( { $isResizing } ) => $isResizing && `body * { transition: none !important; }` }
18- ` ;
19-
2011// Convert a target pixel width to a percentage of the current viewport width.
21- // react-resizable-panels expects sizes in %, not px.
22- const calculateDefaultSize = ( targetWidth : number ) => {
23- const windowWidth = window . innerWidth ;
24- return ( targetWidth / windowWidth ) * 100 ;
12+ const pxToPercent = ( px : number ) => {
13+ return ( px / window . innerWidth ) * 100 ;
2514} ;
2615
2716type ResizableLeftPanelProps = {
@@ -37,60 +26,49 @@ export const ResizableLeftPanel = ({
3726 minPanelSizePx = 300 ,
3827 maxPanelSizePx = 450 ,
3928} : ResizableLeftPanelProps ) => {
40- const [ isResizing , setIsResizing ] = useState ( false ) ;
4129 const { colorsTokens } = useCunninghamTheme ( ) ;
4230 const ref = useRef < ImperativePanelHandle > ( null ) ;
43- const resizeTimeoutRef = useRef < number | undefined > ( undefined ) ;
31+ const savedWidthPxRef = useRef < number > ( minPanelSizePx ) ;
4432
45- const [ minPanelSize , setMinPanelSize ] = useState ( 0 ) ;
46- const [ maxPanelSize , setMaxPanelSize ] = useState ( 0 ) ;
33+ const [ panelSizePercent , setPanelSizePercent ] = useState ( ( ) =>
34+ pxToPercent ( minPanelSizePx ) ,
35+ ) ;
4736
48- // Single resize listener that handles both panel size updates and transition disabling
37+ const minPanelSizePercent = pxToPercent ( minPanelSizePx ) ;
38+ const maxPanelSizePercent = Math . min ( pxToPercent ( maxPanelSizePx ) , 40 ) ;
39+
40+ // Keep pixel width constant on window resize
4941 useEffect ( ( ) => {
5042 const handleResize = ( ) => {
51- // Update panel sizes (px -> %)
52- const min = Math . round ( calculateDefaultSize ( minPanelSizePx ) ) ;
53- const max = Math . round (
54- Math . min ( calculateDefaultSize ( maxPanelSizePx ) , 40 ) ,
55- ) ;
56- setMinPanelSize ( min ) ;
57- setMaxPanelSize ( max ) ;
58-
59- // Temporarily disable transitions to avoid flicker
60- setIsResizing ( true ) ;
61- if ( resizeTimeoutRef . current ) {
62- clearTimeout ( resizeTimeoutRef . current ) ;
43+ const newPercent = pxToPercent ( savedWidthPxRef . current ) ;
44+ setPanelSizePercent ( newPercent ) ;
45+ if ( ref . current ) {
46+ ref . current . resize ?.( newPercent - ( ref . current . getSize ( ) || 0 ) ) ;
6347 }
64- resizeTimeoutRef . current = window . setTimeout ( ( ) => {
65- setIsResizing ( false ) ;
66- } , 150 ) ;
6748 } ;
6849
69- handleResize ( ) ;
70-
7150 window . addEventListener ( 'resize' , handleResize ) ;
72-
7351 return ( ) => {
7452 window . removeEventListener ( 'resize' , handleResize ) ;
75- if ( resizeTimeoutRef . current ) {
76- clearTimeout ( resizeTimeoutRef . current ) ;
77- }
7853 } ;
79- } , [ minPanelSizePx , maxPanelSizePx ] ) ;
54+ } , [ ] ) ;
55+
56+ const handleResize = ( sizePercent : number ) => {
57+ const widthPx = ( sizePercent / 100 ) * window . innerWidth ;
58+ savedWidthPxRef . current = widthPx ;
59+ setPanelSizePercent ( sizePercent ) ;
60+ } ;
8061
8162 return (
8263 < >
83- < PanelStyle $isResizing = { isResizing } />
84- < PanelGroup
85- autoSaveId = "docs-left-panel-persistence"
86- direction = "horizontal"
87- >
64+ < PanelGroup direction = "horizontal" >
8865 < Panel
8966 ref = { ref }
9067 order = { 0 }
91- defaultSize = { minPanelSize }
92- minSize = { minPanelSize }
93- maxSize = { maxPanelSize }
68+ defaultSize = { panelSizePercent }
69+ minSize = { minPanelSizePercent }
70+ maxSize = { maxPanelSizePercent }
71+ onResize = { handleResize }
9472 >
9573 { leftPanel }
9674 </ Panel >
0 commit comments