@@ -6,6 +6,7 @@ import cloneElement from './cloneElement';
66import type { Element as ReactElement , Node as ReactNode } from 'react' ;
77
88type Axis = 'both' | 'x' | 'y' | 'none' ;
9+ type ResizeHandle = 's' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne' ;
910type State = {
1011 resizing : boolean ,
1112 width : number , height : number ,
@@ -35,7 +36,8 @@ export type Props = {
3536 onResizeStop ?: ?( e : SyntheticEvent < > , data : ResizeCallbackData ) => any ,
3637 onResizeStart ?: ?( e : SyntheticEvent < > , data : ResizeCallbackData ) => any ,
3738 onResize ?: ?( e : SyntheticEvent < > , data : ResizeCallbackData ) => any ,
38- draggableOpts ?: ?Object
39+ draggableOpts ?: ?Object ,
40+ resizeHandles ?: ?ResizeHandle [ ]
3941} ;
4042
4143export default class Resizable extends React . Component < Props , State > {
@@ -61,6 +63,18 @@ export default class Resizable extends React.Component<Props, State> {
6163 // If you change this, be sure to update your css
6264 handleSize : PropTypes . array ,
6365
66+ // Defines which resize handles should be rendered (default: 'se')
67+ // Allows for any combination of:
68+ // 's' - South handle (bottom-center)
69+ // 'w' - West handle (left-center)
70+ // 'e' - East handle (right-center)
71+ // 'n' - North handle (top-center)
72+ // 'sw' - Southwest handle (bottom-left)
73+ // 'nw' - Northwest handle (top-left)
74+ // 'se' - Southeast handle (bottom-right)
75+ // 'ne' - Northeast handle (top-center)
76+ resizeHandles : PropTypes . arrayOf ( PropTypes . oneOf ( [ 's' , 'w' , 'e' , 'n' , 'sw' , 'nw' , 'se' , 'ne' ] ) ) ,
77+
6478 // If true, will only allow width/height to move in lockstep
6579 lockAspectRatio : PropTypes . bool ,
6680
@@ -89,7 +103,8 @@ export default class Resizable extends React.Component<Props, State> {
89103 lockAspectRatio : false ,
90104 axis : 'both' ,
91105 minConstraints : [ 20 , 20 ] ,
92- maxConstraints : [ Infinity , Infinity ]
106+ maxConstraints : [ Infinity , Infinity ] ,
107+ resizeHandles : [ 'se' ]
93108 } ;
94109
95110 state : State = {
@@ -161,12 +176,19 @@ export default class Resizable extends React.Component<Props, State> {
161176 * @param {String } handlerName Handler name to wrap.
162177 * @return {Function } Handler function.
163178 */
164- resizeHandler ( handlerName : string ) : Function {
179+ resizeHandler ( handlerName : string , axis : ResizeHandle ) : Function {
165180 return ( e : SyntheticEvent < > | MouseEvent , { node , deltaX , deltaY } : DragCallbackData ) => {
166181
167182 // Axis restrictions
168- const canDragX = this . props . axis === 'both' || this . props . axis === 'x' ;
169- const canDragY = this . props . axis === 'both' || this . props . axis === 'y' ;
183+ const canDragX = ( this . props . axis === 'both' || this . props . axis === 'x' ) && [ 'n' , 's' ] . indexOf ( axis ) === - 1 ;
184+ const canDragY = ( this . props . axis === 'both' || this . props . axis === 'y' ) && [ 'e' , 'w' ] . indexOf ( axis ) === - 1 ;
185+
186+ if ( axis [ 0 ] === 'n' ) {
187+ deltaY = - deltaY ;
188+ }
189+ if ( axis [ axis . length - 1 ] === 'w' ) {
190+ deltaX = - deltaX ;
191+ }
170192
171193 // Update w/h
172194 let width = this . state . width + ( canDragX ? deltaX : 0 ) ;
@@ -202,9 +224,27 @@ export default class Resizable extends React.Component<Props, State> {
202224 } ;
203225 }
204226
227+ renderResizeHandles ( ) : ReactNode {
228+ const { draggableOpts, handle, resizeHandles} = this . props ;
229+ if ( handle ) {
230+ return handle ;
231+ }
232+ return resizeHandles . map ( h => (
233+ < DraggableCore
234+ { ...draggableOpts }
235+ key = { `resizableHandle-${ h } ` }
236+ onStop = { this . resizeHandler ( 'onResizeStop' , h ) }
237+ onStart = { this . resizeHandler ( 'onResizeStart' , h ) }
238+ onDrag = { this . resizeHandler ( 'onResize' , h ) }
239+ >
240+ < span key = { h } className = { `react-resizable-handle react-resizable-handle-${ h } ` } />
241+ </ DraggableCore >
242+ ) ) ;
243+ }
244+
205245 render ( ) : ReactNode {
206246 // eslint-disable-next-line no-unused-vars
207- const { children, draggableOpts , width, height, handle, handleSize,
247+ const { children, width, height, handle, handleSize,
208248 lockAspectRatio, axis, minConstraints, maxConstraints, onResize,
209249 onResizeStop, onResizeStart, ...p } = this . props ;
210250
@@ -215,21 +255,13 @@ export default class Resizable extends React.Component<Props, State> {
215255 // What we're doing here is getting the child of this element, and cloning it with this element's props.
216256 // We are then defining its children as:
217257 // Its original children (resizable's child's children), and
218- // A draggable handle .
258+ // One or more draggable handles .
219259 return cloneElement ( children , {
220260 ...p ,
221261 className,
222262 children : [
223263 children . props . children ,
224- < DraggableCore
225- { ...draggableOpts }
226- key = "resizableHandle"
227- onStop = { this . resizeHandler ( 'onResizeStop' ) }
228- onStart = { this . resizeHandler ( 'onResizeStart' ) }
229- onDrag = { this . resizeHandler ( 'onResize' ) }
230- >
231- { handle || < span className = "react-resizable-handle" /> }
232- </ DraggableCore >
264+ this . renderResizeHandles ( )
233265 ]
234266 } ) ;
235267 }
0 commit comments