11// @flow
2- import React from 'react' ;
2+ import * as React from 'react' ;
33import type { Node as ReactNode } from 'react' ;
44import { DraggableCore } from 'react-draggable' ;
55import { cloneElement } from './utils' ;
66import { resizableProps } from "./propTypes" ;
7- import type { ResizeHandleAxis , DefaultProps , Props , ReactRef , ResizableState , DragCallbackData } from './propTypes' ;
7+ import type { ResizeHandleAxis , DefaultProps , Props , ReactRef , DragCallbackData } from './propTypes' ;
88
9- export default class Resizable extends React . Component < Props , ResizableState > {
9+ // The base <Resizable> component.
10+ // This component does not have state and relies on the parent to set its props based on callback data.
11+ export default class Resizable extends React . Component < Props , void > {
1012 static propTypes = resizableProps ;
1113
1214 static defaultProps : DefaultProps = {
@@ -19,8 +21,7 @@ export default class Resizable extends React.Component<Props, ResizableState> {
1921 transformScale : 1
2022 } ;
2123
22- state : ResizableState = undefined ;
23-
24+ handleRefs : { [ key : ResizeHandleAxis ] : ReactRef < HTMLElement > } = { } ;
2425 lastHandleRect : ?ClientRect = null ;
2526 slack : ?[ number , number ] = null ;
2627
@@ -151,15 +152,16 @@ export default class Resizable extends React.Component<Props, ResizableState> {
151152 } ;
152153 }
153154
154- renderResizeHandle ( resizeHandleAxis : ResizeHandleAxis ) : ReactNode {
155+ // Render a resize handle given an axis & DOM ref.
156+ renderResizeHandle ( handleAxis : ResizeHandleAxis , ref : ReactRef < HTMLElement > ) : ReactNode {
155157 const { handle} = this . props ;
156158 if ( handle ) {
157159 if ( typeof handle === 'function' ) {
158- return handle ( resizeHandleAxis ) ;
160+ return handle ( handleAxis , ref ) ;
159161 }
160- return handle ;
162+ return React . cloneElement ( handle , { ref } ) ;
161163 }
162- return < span className = { `react-resizable-handle react-resizable-handle-${ resizeHandleAxis } ` } /> ;
164+ return < span className = { `react-resizable-handle react-resizable-handle-${ handleAxis } ` } ref = { ref } / > ;
163165 }
164166
165167 render ( ) : ReactNode {
@@ -178,17 +180,22 @@ export default class Resizable extends React.Component<Props, ResizableState> {
178180 className : `${ className ? `${ className } ` : '' } react-resizable` ,
179181 children : [
180182 ...children . props . children ,
181- ...resizeHandles . map ( ( handleAxis ) => (
182- < DraggableCore
183- { ...draggableOpts }
184- key = { `resizableHandle-${ handleAxis } ` }
185- onStop = { this . resizeHandler ( 'onResizeStop' , handleAxis ) }
186- onStart = { this . resizeHandler ( 'onResizeStart' , handleAxis ) }
187- onDrag = { this . resizeHandler ( 'onResize' , handleAxis ) }
188- >
189- { this . renderResizeHandle ( handleAxis ) }
190- </ DraggableCore >
191- ) )
183+ ...resizeHandles . map ( ( handleAxis ) => {
184+ // Create a ref to the handle so that `<DraggableCore>` doesn't have to use ReactDOM.findDOMNode().
185+ const ref = ( this . handleRefs [ handleAxis ] ) ?? ( this . handleRefs [ handleAxis ] = React . createRef ( ) ) ;
186+ return (
187+ < DraggableCore
188+ { ...draggableOpts }
189+ nodeRef = { ref }
190+ key = { `resizableHandle-${ handleAxis } ` }
191+ onStop = { this . resizeHandler ( 'onResizeStop' , handleAxis ) }
192+ onStart = { this . resizeHandler ( 'onResizeStart' , handleAxis ) }
193+ onDrag = { this . resizeHandler ( 'onResize' , handleAxis ) }
194+ >
195+ { this . renderResizeHandle ( handleAxis , ref ) }
196+ </ DraggableCore >
197+ ) ;
198+ } )
192199 ]
193200 } ) ;
194201 }
0 commit comments