react-rnd icon indicating copy to clipboard operation
react-rnd copied to clipboard

getOffsetFromParent has an issue with createPortal component

Open RyanZhu1024 opened this issue 5 years ago • 1 comments

Overview of the problem

I'm using react-rnd version 9.1.2

My browser is: chrome

I am sure this issue is not a duplicate.

I want to render the rnd dialog on the root of the dom so we create a component like this using createPortal:

export default class OnBody extends React.Component {
  constructor(props) {
    super(props);
    this.el = document.createElement('div');
    this.el.style.display = 'contents';
  }

  componentDidMount() {
    const containerRoot = document.body;
    containerRoot.appendChild(this.el);
  }

  componentWillUnmount() {
    const containerRoot = document.body;
    containerRoot.removeChild(this.el);
  }

  render() {
    return ReactDOM.createPortal(this.props.children, this.el);
  }
}

Steps to Reproduce

  1. Rnd is used as a child component under OnBody
      <OnBody>
        <Rnd
          default={this.dialogPosotion}
          minHeight={500}
          minWidth={600}
          style={{
            zIndex: 100,
            background: 'white',
            border: '2px solid #888',
            borderRadius: '4px 4px 4px 4px',
            boxShadow: '0 0 5px #888',
          }}
          dragHandleClassName="filePreviewDragline"
        >
          <div className="filePreviewDragline" style={{ height: '15px', cursor: 'move' }} />
          <Component1 />
        </Rnd>
      </OnBody>
  1. give the right position
  get dialogPosotion() {
    return {
      x: (window.innerWidth - WIDTH) / 2,
      y: (window.innerHeight - HEIGHT) / 2,
      width: WIDTH,
      height: HEIGHT,
    };
  }
  1. open the dialog and the position is doubled somehow.

Expected behavior

position should not get doubled

Actual behavior

Position is doubled in RND because of this function getOffsetFromParent. for example, if the position I give is {x: 300, y: 300}, and getOffsetFromParent is called in the componentDidMount and get forceUpdate, the value in componentDidMount is {x: 600, y: 600} and get passed to draggableComponent, because of this:

        this.draggable.setState({
            x: x - left,
            y: y - top,
        });

where left is -300 and top is -300, which gives 600 and 600

RyanZhu1024 avatar Jun 06 '19 02:06 RyanZhu1024

I've worked around this issue by not using defaultPosition and position and using updatePosition

cdes avatar Feb 24 '20 12:02 cdes