11import * as React from "react" ;
2- import Draggable from "react-draggable" ;
2+ import { DraggableEventHandler } from "react-draggable" ;
33import Resizable , { ResizableDirection } from "re-resizable" ;
44
5+ // FIXME: https://github.com/mzabriskie/react-draggable/issues/381
6+ // I can not find `scale` too...
7+ type $TODO = any ;
8+ const Draggable = require ( "react-draggable" ) ;
9+
510export type Grid = [ number , number ] ;
611
712export type Position = {
@@ -17,7 +22,13 @@ export type DraggableData = {
1722 lastY : number ;
1823} & Position ;
1924
20- export type RndDragCallback = ( e : Event , data : DraggableData ) => void | false ;
25+ export type RndDragCallback = DraggableEventHandler ;
26+
27+ export type RndDragEvent =
28+ | React . MouseEvent < HTMLElement | SVGElement >
29+ | React . TouchEvent < HTMLElement | SVGElement >
30+ | MouseEvent
31+ | TouchEvent ;
2132
2233export type RndResizeStartCallback = (
2334 e : React . MouseEvent < HTMLDivElement > | React . TouchEvent < HTMLDivElement > ,
@@ -133,6 +144,7 @@ export interface Props {
133144 disableDragging ?: boolean ;
134145 cancel ?: string ;
135146 enableUserSelectHack ?: boolean ;
147+ scale ?: number ;
136148 [ key : string ] : any ;
137149}
138150
@@ -145,10 +157,23 @@ const resizableStyle = {
145157 left : 0 ,
146158} ;
147159
160+ interface DefaultProps {
161+ maxWidth : number ;
162+ maxHeight : number ;
163+ onResizeStart : RndResizeStartCallback ;
164+ onResize : RndResizeCallback ;
165+ onResizeStop : RndResizeCallback ;
166+ onDragStart : RndDragCallback ;
167+ onDrag : RndDragCallback ;
168+ onDragStop : RndDragCallback ;
169+ scale : number ;
170+ }
171+
148172export class Rnd extends React . Component < Props , State > {
149- static defaultProps = {
173+ public static defaultProps : DefaultProps = {
150174 maxWidth : Number . MAX_SAFE_INTEGER ,
151175 maxHeight : Number . MAX_SAFE_INTEGER ,
176+ scale : 1 ,
152177 onResizeStart : ( ) => { } ,
153178 onResize : ( ) => { } ,
154179 onResizeStop : ( ) => { } ,
@@ -157,7 +182,7 @@ export class Rnd extends React.Component<Props, State> {
157182 onDragStop : ( ) => { } ,
158183 } ;
159184 resizable ! : Resizable ;
160- draggable ! : Draggable ;
185+ draggable ! : $TODO ; // Draggable;
161186 isResizing = false ;
162187
163188 constructor ( props : Props ) {
@@ -221,27 +246,60 @@ export class Rnd extends React.Component<Props, State> {
221246 return this . resizable && this . resizable . resizable ;
222247 }
223248
224- onDragStart ( e : Event , data : DraggableData ) {
249+ getOffsetHeight ( boundary : HTMLElement ) {
250+ const scale = this . props . scale as number ;
251+ switch ( this . props . bounds ) {
252+ case "window" :
253+ return window . innerHeight / scale ;
254+ case "body" :
255+ return document . body . offsetHeight / scale ;
256+ default :
257+ return boundary . offsetHeight ;
258+ }
259+ }
260+
261+ getOffsetWidth ( boundary : HTMLElement ) {
262+ const scale = this . props . scale as number ;
263+ switch ( this . props . bounds ) {
264+ case "window" :
265+ return window . innerWidth / scale ;
266+ case "body" :
267+ return document . body . offsetWidth / scale ;
268+ default :
269+ return boundary . offsetWidth ;
270+ }
271+ }
272+
273+ onDragStart ( e : RndDragEvent , data : DraggableData ) {
225274 if ( this . props . onDragStart ) {
226275 this . props . onDragStart ( e , data ) ;
227276 }
228277 if ( ! this . props . bounds ) return ;
229278 const parent = this . getParent ( ) ;
279+ const scale = this . props . scale as number ;
230280 let boundary ;
231281 if ( this . props . bounds === "parent" ) {
232282 boundary = parent ;
233283 } else if ( this . props . bounds === "body" ) {
234- boundary = document . body ;
284+ const parentRect = parent . getBoundingClientRect ( ) ;
285+ const parentLeft = parentRect . left ;
286+ const parentTop = parentRect . top ;
287+ const bodyRect = document . body . getBoundingClientRect ( ) ;
288+ const left = - ( parentLeft - parent . offsetLeft * scale - bodyRect . left ) / scale ;
289+ const top = - ( parentTop - parent . offsetTop * scale - bodyRect . top ) / scale ;
290+ const right = ( document . body . offsetWidth - this . resizable . size . width * scale ) / scale + left ;
291+ const bottom = ( document . body . offsetHeight - this . resizable . size . height * scale ) / scale + top ;
292+ return this . setState ( { bounds : { top, right, bottom, left } } ) ;
235293 } else if ( this . props . bounds === "window" ) {
236294 if ( ! this . resizable ) return ;
237- return this . setState ( {
238- bounds : {
239- top : 0 ,
240- right : window . innerWidth - this . resizable . size . width ,
241- bottom : window . innerHeight - this . resizable . size . height ,
242- left : 0 ,
243- } ,
244- } ) ;
295+ const parentRect = parent . getBoundingClientRect ( ) ;
296+ const parentLeft = parentRect . left ;
297+ const parentTop = parentRect . top ;
298+ const left = - ( parentLeft - parent . offsetLeft * scale ) / scale ;
299+ const top = - ( parentTop - parent . offsetTop * scale ) / scale ;
300+ const right = ( window . innerWidth - this . resizable . size . width * scale ) / scale + left ;
301+ const bottom = ( window . innerHeight - this . resizable . size . height * scale ) / scale + top ;
302+ return this . setState ( { bounds : { top , right , bottom , left } } ) ;
245303 } else {
246304 boundary = document . querySelector ( this . props . bounds ) ;
247305 }
@@ -254,28 +312,28 @@ export class Rnd extends React.Component<Props, State> {
254312 const parentRect = parent . getBoundingClientRect ( ) ;
255313 const parentLeft = parentRect . left ;
256314 const parentTop = parentRect . top ;
257- const left = boundaryLeft - parentLeft ;
315+ const left = ( boundaryLeft - parentLeft ) / scale ;
258316 const top = boundaryTop - parentTop ;
259317 if ( ! this . resizable ) return ;
260318 const offset = this . getOffsetFromParent ( ) ;
261319 this . setState ( {
262320 bounds : {
263321 top : top - offset . top ,
264- right : left + ( boundary . offsetWidth - this . resizable . size . width ) - offset . left ,
322+ right : left + ( boundary . offsetWidth - this . resizable . size . width ) - offset . left / scale ,
265323 bottom : top + ( boundary . offsetHeight - this . resizable . size . height ) - offset . top ,
266- left : left - offset . left ,
324+ left : left - offset . left / scale ,
267325 } ,
268326 } ) ;
269327 }
270328
271- onDrag ( e : Event , data : DraggableData ) {
329+ onDrag ( e : RndDragEvent , data : DraggableData ) {
272330 if ( this . props . onDrag ) {
273331 const offset = this . getOffsetFromParent ( ) ;
274332 this . props . onDrag ( e , { ...data , x : data . x - offset . left , y : data . y - offset . top } ) ;
275333 }
276334 }
277335
278- onDragStop ( e : Event , data : DraggableData ) {
336+ onDragStop ( e : RndDragEvent , data : DraggableData ) {
279337 if ( this . props . onDragStop ) {
280338 const { left, top } = this . getOffsetFromParent ( ) ;
281339 this . props . onDragStop ( e , { ...data , x : data . x + left , y : data . y + top } ) ;
@@ -289,6 +347,7 @@ export class Rnd extends React.Component<Props, State> {
289347 ) {
290348 e . stopPropagation ( ) ;
291349 this . isResizing = true ;
350+ const scale = this . props . scale as number ;
292351 this . setState ( {
293352 original : this . getDraggablePosition ( ) ,
294353 } ) ;
@@ -335,30 +394,30 @@ export class Rnd extends React.Component<Props, State> {
335394 const boundaryRect = this . props . bounds === "window" ? { left : 0 , top : 0 } : boundary . getBoundingClientRect ( ) ;
336395 const boundaryLeft = boundaryRect . left ;
337396 const boundaryTop = boundaryRect . top ;
338- const offsetWidth = this . props . bounds === "window" ? window . innerWidth : boundary . offsetWidth ;
339- const offsetHeight = this . props . bounds === "window" ? window . innerHeight : boundary . offsetHeight ;
397+ const offsetWidth = this . getOffsetWidth ( boundary ) ;
398+ const offsetHeight = this . getOffsetHeight ( boundary ) ;
340399 const hasLeft = dir . toLowerCase ( ) . endsWith ( "left" ) ;
341400 const hasRight = dir . toLowerCase ( ) . endsWith ( "right" ) ;
342401 const hasTop = dir . startsWith ( "top" ) ;
343402 const hasBottom = dir . startsWith ( "bottom" ) ;
344403 if ( hasLeft && this . resizable ) {
345- const max = selfLeft - boundaryLeft + this . resizable . size . width ;
404+ const max = ( selfLeft - boundaryLeft ) / scale + this . resizable . size . width ;
346405 this . setState ( { maxWidth : max > Number ( maxWidth ) ? maxWidth : max } ) ;
347406 }
348407 // INFO: To set bounds in `lock aspect ratio with bounds` case. See also that story.
349408 if ( hasRight || ( this . props . lockAspectRatio && ! hasLeft ) ) {
350- const max = offsetWidth + ( boundaryLeft - selfLeft ) ;
409+ const max = offsetWidth + ( boundaryLeft - selfLeft ) / scale ;
351410 this . setState ( { maxWidth : max > Number ( maxWidth ) ? maxWidth : max } ) ;
352411 }
353412 if ( hasTop && this . resizable ) {
354- const max = selfTop - boundaryTop + this . resizable . size . height ;
413+ const max = ( selfTop - boundaryTop ) / scale + this . resizable . size . height ;
355414 this . setState ( {
356415 maxHeight : max > Number ( maxHeight ) ? maxHeight : max ,
357416 } ) ;
358417 }
359418 // INFO: To set bounds in `lock aspect ratio with bounds` case. See also that story.
360419 if ( hasBottom || ( this . props . lockAspectRatio && ! hasTop ) ) {
361- const max = offsetHeight + ( boundaryTop - selfTop ) ;
420+ const max = offsetHeight + ( boundaryTop - selfTop ) / scale ;
362421 this . setState ( {
363422 maxHeight : max > Number ( maxHeight ) ? maxHeight : max ,
364423 } ) ;
@@ -439,6 +498,7 @@ export class Rnd extends React.Component<Props, State> {
439498 }
440499
441500 getOffsetFromParent ( ) : { top : number ; left : number } {
501+ const scale = this . props . scale as number ;
442502 const parent = this . getParent ( ) ;
443503 if ( ! parent ) {
444504 return {
@@ -452,8 +512,8 @@ export class Rnd extends React.Component<Props, State> {
452512 const selfRect = this . getSelfElement ( ) . getBoundingClientRect ( ) ;
453513 const position = this . getDraggablePosition ( ) ;
454514 return {
455- left : selfRect . left - parentLeft - position . x ,
456- top : selfRect . top - parentTop - position . y ,
515+ left : selfRect . left - parentLeft - position . x * scale ,
516+ top : selfRect . top - parentTop - position . y * scale ,
457517 } ;
458518 }
459519
@@ -482,6 +542,7 @@ export class Rnd extends React.Component<Props, State> {
482542 resizeGrid,
483543 resizeHandleWrapperClass,
484544 resizeHandleWrapperStyle,
545+ scale,
485546 ...resizableProps
486547 } = this . props ;
487548 const defaultValue = this . props . default ? { ...this . props . default } : undefined ;
@@ -504,10 +565,9 @@ export class Rnd extends React.Component<Props, State> {
504565 }
505566 return (
506567 < Draggable
507- ref = { c => {
508- if ( c ) {
509- this . draggable = c ;
510- }
568+ ref = { ( c : $TODO ) => {
569+ if ( ! c ) return ;
570+ this . draggable = c ;
511571 } }
512572 handle = { dragHandleClassName ? `.${ dragHandleClassName } ` : undefined }
513573 defaultPosition = { defaultValue }
@@ -522,6 +582,7 @@ export class Rnd extends React.Component<Props, State> {
522582 position = { draggablePosition }
523583 enableUserSelectHack = { enableUserSelectHack }
524584 cancel = { cancel }
585+ scale = { scale }
525586 >
526587 < Resizable
527588 { ...resizableProps }
@@ -549,6 +610,7 @@ export class Rnd extends React.Component<Props, State> {
549610 lockAspectRatioExtraHeight = { this . props . lockAspectRatioExtraHeight }
550611 handleStyles = { resizeHandleStyles }
551612 handleClasses = { resizeHandleClasses }
613+ scale = { this . props . scale }
552614 >
553615 { children }
554616 </ Resizable >
0 commit comments