@@ -38,11 +38,9 @@ export default function DraggableWrapper({
3838} : DraggableWrapperProps ) {
3939 const windowSize = useWindowSize ( )
4040 const nodeRef = useRef < HTMLDivElement > ( null )
41-
42- const [ position , setPosition ] = useState < ControlPosition > ( {
43- x : 0 ,
44- y : 0 ,
45- } )
41+
42+ // letting the dom render the element without displaying it so that we know it's dimensions
43+ const [ initialRenderDone , setInitialRenderDone ] = useState ( false )
4644
4745 const getDefaultPosition = ( positionVariant : DraggablePositionVariant ) : ControlPosition => {
4846 // if this return x: 0, y: 0 then it will be top left corner of parentDiv
@@ -60,73 +58,55 @@ export default function DraggableWrapper({
6058
6159 switch ( positionVariant ) {
6260 case DraggablePositionVariant . PARENT_BOTTOM_CENTER : {
63- // currently at parentRect.x and need to start to the center of its width and half of node should lie on left of center and other half on right
64- const x = ( parentRect . width - nodeRefWidth ) / 2
61+ // center div to middle of the parent rect and then add the left offset of the parent rect
62+ const x = ( parentRect . width - nodeRefWidth ) / 2 + parentRect . left
6563 // TODO (v3): Temp fix. Revisit
6664 const parentRectTop = parentRect . top > 0 ? parentRect . top : layoutFixDelta
6765 // currently at parentRect.y now parent height can be greater than windowSize.height so taking min
6866 // subtracting parentRect.top since window height already contains that
69- const baseY =
70- parentRect . height > windowSize . height ? windowSize . height - parentRectTop : parentRect . height
71- const y = baseY - nodeRefHeight - boundaryGap
67+ if ( parentRect . height > windowSize . height ) {
68+ return { x, y : windowSize . height - boundaryGap - nodeRefHeight }
69+ }
70+ const y = parentRect . bottom - nodeRefHeight - boundaryGap
7271 return { x, y }
7372 }
7473 case DraggablePositionVariant . SCREEN_BOTTOM_RIGHT : {
75- const x = windowSize . width - parentRect . left - nodeRefWidth - boundaryGap
76- const y = windowSize . height - parentRect . top - nodeRefHeight - boundaryGap
74+ const x = windowSize . width - nodeRefWidth - boundaryGap
75+ const y = windowSize . height - nodeRefHeight - boundaryGap
7776
7877 return { x, y }
7978 }
8079 // Add more cases for other variants if needed
8180 default : {
8281 // Since need node to be in center of screen so subtracting width/2 by left of parentRect it will start the node from center but want node's midpoint at center so subtracting node's width from it.
83- const x = windowSize . width / 2 - parentRect . left - nodeRefWidth / 2
82+ const x = ( windowSize . width - nodeRefWidth ) / 2
8483 // subtracting top since windowSize already contains that
85- const y = windowSize . height - parentRect . top - nodeRefHeight - boundaryGap
84+ const y = windowSize . height - nodeRefHeight - boundaryGap
8685
8786 return { x, y }
8887 }
8988 }
9089 }
9190
92- // On change of windowSize we will reset the position to default
9391 useEffect ( ( ) => {
94- const defaultPosition = getDefaultPosition ( positionVariant )
95- setPosition ( defaultPosition )
96- } , [ nodeRef , positionVariant , windowSize ] )
97-
98- // Would be called on drag and will not update the state if the new position is out of window screen
99- function handlePositionChange ( e , data : DraggableData ) {
100- const offsetX = parentRef ?. current ?. getBoundingClientRect ( ) . left ?? 0
101- const offsetY = parentRef ?. current ?. getBoundingClientRect ( ) . top ?? 0
102-
103- const nodeRefHeight = nodeRef . current ?. getBoundingClientRect ( ) . height ?? 0
104- const nodeRefWidth = nodeRef . current ?. getBoundingClientRect ( ) . width ?? 0
105-
106- if (
107- offsetX + data . x + nodeRefWidth + boundaryGap > windowSize . width ||
108- offsetY + data . y + nodeRefHeight + boundaryGap > windowSize . height ||
109- offsetX + data . x < 0 ||
110- offsetY + data . y < 0
111- ) {
112- return
113- }
114-
115- setPosition ( {
116- x : data . x ,
117- y : data . y ,
118- } )
119- }
92+ // make the element visible after the initial render
93+ setInitialRenderDone ( true )
94+ } , [ ] )
12095
12196 return (
12297 // Since we are using position fixed so we need to disable click on the div so that it does not interfere with the click of other elements
12398 < div
124- className = " dc__position-fixed dc__disable-click"
99+ className = { ` dc__position-fixed dc__disable-click dc__top-0 dc__left-0 ${ initialRenderDone ? '' : 'dc__visibility-hidden' } ` }
125100 style = { {
126101 zIndex,
127102 } }
128103 >
129- < Draggable handle = { dragSelector } nodeRef = { nodeRef } position = { position } onDrag = { handlePositionChange } >
104+ < Draggable
105+ key = { `${ JSON . stringify ( windowSize ) } ${ initialRenderDone } ` }
106+ handle = { dragSelector }
107+ defaultPosition = { getDefaultPosition ( positionVariant ) }
108+ bounds = "#devtron-base-main-identifier"
109+ nodeRef = { nodeRef } >
130110 < div
131111 ref = { nodeRef }
132112 { ...childDivProps }
0 commit comments