1- import { ForwardedRef , forwardRef , useContext , useState } from 'react' ;
1+ import {
2+ ForwardedRef ,
3+ forwardRef ,
4+ useContext ,
5+ useEffect ,
6+ useState ,
7+ } from 'react' ;
28import { useHover , useMove } from 'react-aria' ;
39
410import { useWarn } from '../../_internal/index' ;
@@ -12,8 +18,11 @@ type Direction = 'top' | 'right' | 'bottom' | 'left';
1218export interface ResizablePanelProps extends CubePanelProps {
1319 handlerStyles ?: Styles ;
1420 direction : Direction ;
21+ size ?: number ;
22+ onSizeChange ?: ( size : number ) => void ;
1523 minSize ?: string | number ;
1624 maxSize ?: string | number ;
25+ isDisabled ?: boolean ;
1726}
1827
1928const HandlerElement = tasty ( {
@@ -49,7 +58,10 @@ const HandlerElement = tasty({
4958 } ,
5059 position : 'absolute' ,
5160 zIndex : 1 ,
52- cursor : 'col-resize' ,
61+ cursor : {
62+ '' : 'col-resize' ,
63+ disabled : 'not-allowed' ,
64+ } ,
5365 fill : {
5466 '' : '#clear' ,
5567 drag : '#purple-02' ,
@@ -74,7 +86,7 @@ const HandlerElement = tasty({
7486 } ,
7587 fill : {
7688 '' : '#border-opaque' ,
77- 'hovered | drag' : '#purple-03' ,
89+ '( hovered | drag) & !disabled ' : '#purple-03' ,
7890 } ,
7991 transition : 'theme' ,
8092 } ,
@@ -92,6 +104,7 @@ const HandlerElement = tasty({
92104 fill : {
93105 '' : '#dark-03' ,
94106 'hovered | drag' : '#dark-02' ,
107+ disabled : '#dark-04' ,
95108 } ,
96109 inset : {
97110 '' : '3px 50% auto auto' ,
@@ -108,7 +121,7 @@ interface HandlerProps extends BasePropsWithoutChildren {
108121}
109122
110123const Handler = ( props : HandlerProps ) => {
111- const { direction = 'right' } = props ;
124+ const { direction = 'right' , isDisabled } = props ;
112125 const { hoverProps, isHovered } = useHover ( { } ) ;
113126 const isHorizontal = direction === 'left' || direction === 'right' ;
114127
@@ -120,6 +133,7 @@ const Handler = (props: HandlerProps) => {
120133 mods : {
121134 hovered : isHovered ,
122135 horizontal : isHorizontal ,
136+ disabled : isDisabled ,
123137 } ,
124138 'data-direction' : direction ,
125139 } ,
@@ -162,16 +176,43 @@ function ResizablePanel(
162176 ] ,
163177 } ) ;
164178
165- const { direction = 'right' , minSize = '15%' , maxSize = '35%' } = props ;
179+ const isControllable = typeof props . size === 'number' ;
180+ const {
181+ isDisabled,
182+ direction = 'right' ,
183+ size : providedSize ,
184+ onSizeChange,
185+ minSize = 200 ,
186+ maxSize = isControllable ? undefined : 400 ,
187+ } = props ;
188+
166189 const [ isDragging , setIsDragging ] = useState ( false ) ;
167190 const isHorizontal = direction === 'left' || direction === 'right' ;
168191
169192 ref = useCombinedRefs ( ref ) ;
170193
171- let [ size , setSize ] = useState < number > ( 200 ) ;
194+ function clamp ( size : number ) {
195+ if ( typeof maxSize === 'number' ) {
196+ size = Math . min ( maxSize , size ) ;
197+ }
198+
199+ if ( typeof minSize === 'number' || ! minSize ) {
200+ size = Math . max ( ( minSize as number ) || 0 , size ) ;
201+ }
202+
203+ return Math . max ( size , 0 ) ;
204+ }
205+
206+ let [ size , setSize ] = useState < number > (
207+ providedSize != null ? clamp ( providedSize ) : 200 ,
208+ ) ;
172209
173210 let { moveProps } = useMove ( {
174211 onMoveStart ( e ) {
212+ if ( isDisabled ) {
213+ return ;
214+ }
215+
175216 setIsDragging ( true ) ;
176217
177218 const offsetProp = isHorizontal ? 'offsetWidth' : 'offsetHeight' ;
@@ -182,6 +223,10 @@ function ResizablePanel(
182223 } ,
183224 onMove ( e ) {
184225 setSize ( ( size ) => {
226+ if ( isDisabled ) {
227+ return ;
228+ }
229+
185230 if ( e . pointerType === 'keyboard' ) {
186231 return size ;
187232 }
@@ -190,23 +235,38 @@ function ResizablePanel(
190235 ? e . deltaX * ( direction === 'right' ? 1 : - 1 )
191236 : e . deltaY * ( direction === 'bottom' ? 1 : - 1 ) ;
192237
193- return size ;
238+ return clamp ( size ) ;
194239 } ) ;
195240 } ,
196241 onMoveEnd ( e ) {
197242 setIsDragging ( false ) ;
198243 } ,
199244 } ) ;
200245
246+ useEffect ( ( ) => {
247+ onSizeChange ?.( size ) ;
248+ } , [ size ] ) ;
249+
250+ useEffect ( ( ) => {
251+ if ( providedSize ) {
252+ setSize ( providedSize ) ;
253+ }
254+ } , [ providedSize ] ) ;
255+
201256 return (
202257 < PanelElement
203258 ref = { ref }
204259 data-direction = { direction }
205260 extra = {
206261 < Handler
262+ isDisabled = { isDisabled }
207263 direction = { direction }
208264 { ...moveProps }
209- mods = { { drag : isDragging , horizontal : isHorizontal } }
265+ mods = { {
266+ drag : isDragging ,
267+ horizontal : isHorizontal ,
268+ disabled : isDisabled ,
269+ } }
210270 />
211271 }
212272 { ...mergeProps ( props , {
0 commit comments