Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a default position x,y of "center" #437

Open
tnrich opened this issue Sep 1, 2018 · 13 comments
Open

Add a default position x,y of "center" #437

tnrich opened this issue Sep 1, 2018 · 13 comments
Assignees

Comments

@tnrich
Copy link

tnrich commented Sep 1, 2018

Hey there,

I want to make a dialog that sizes to the elements within it but am having trouble doing that AND getting the dialog to be centered on the page.

It would be awesome if we could pass something like:

default={{x:"center", y:"center"}}

That way the dialog could be centered and that expands to fit the elements inside (up to its specified bounds).

Thanks @bokuweb !

@tnrich
Copy link
Author

tnrich commented Feb 28, 2019

@bokuweb can you please update to react-draggable 3.2.0 or higher ? That will fix this issue!

Thanks!

@tnrich tnrich mentioned this issue Feb 28, 2019
@tnrich
Copy link
Author

tnrich commented Feb 28, 2019

@bokuweb it looks like there are some failing tests with the latest react-rnd:

#510

https://circleci.com/gh/bokuweb/react-rnd/1340?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link

I'm not sure why that is. I'll ask @STRML if he knows..?

@STRML
Copy link

STRML commented Mar 1, 2019

It appears there was an inadvertent breaking change in 3.2.0.

Prior to 3.2.0, if a defaultPosition were present, it became the x and y present in the callback on the initial drag and subsequent to that.

In 3.2.0, the x and y received in the callback is relative to the defaultPosition already passed. So if you pass a defaultPosition of x: 100, y:100and initiateonDragStart, the callback will contain {x: 0, y: 0}in the data. This makes sense if you considerdefaultPositionto be something more likeinitialOffset, and is required if your offset is something like, for example, {x: '10%', y: '10%'}`.

I'm going to pull the release for now and work out how to fix this. I may end up renaming defaultPosition and issue a 4.0.

@tnrich
Copy link
Author

tnrich commented Mar 1, 2019

I've added my comments here: react-grid-layout/react-draggable#391

@tnrich
Copy link
Author

tnrich commented May 17, 2019

@bokuweb I believe this is now possible thanks to this PR: react-grid-layout/react-draggable#393

We can now set a positionOffset using percentages

<Draggable positionOffset={{x: '-10%', y: '-10%'}} {...dragHandlers}>
          <div className="box">
            {'I have a default position based on percents {x: \'-10%\', y: \'-10%\'}, so I\'m slightly offset.'}
          </div>
        </Draggable>

@wavesbig
Copy link

Hello, Do you know where I come from

@wavesbig
Copy link

板凳宽板凳长

@bokuweb
Copy link
Owner

bokuweb commented May 20, 2019

@tnrich Thanks :) Is it enough to update to react-draggable3.3?
If you are ok could you please create PR with new storybook story??(Please add your story here https://github.com/bokuweb/react-rnd/tree/master/stories)

@tnrich
Copy link
Author

tnrich commented May 20, 2019

Hi @bokuweb
So I tried updating react-rnd to version 3.3 of react-draggable but it wasn't enough to just do that. I think because react-rnd calculates a position offset from the parent, the initial % translation from the positionOffset prop gets canceled out. You'll need to take a look at the code I think and tinker with it a bit. I tried editing the react-rnd position offset code but was a little stumped as to how to get it to work perfectly.

@bokuweb
Copy link
Owner

bokuweb commented May 20, 2019

@tnrich Thanks for your investigation :) I'll try it later. Unfortunately I can not have enough time to fix it(I have a lot of tasks 😭 ) Please wait ...

@bokuweb bokuweb self-assigned this Jun 11, 2019
@tnrich
Copy link
Author

tnrich commented May 20, 2020

@bokuweb any chance you could find some time to tackle this one? Thank you!

@nvdarekar
Copy link

Hi @bokuweb
Any updates on this?
Thank you!

@eek eek mentioned this issue Feb 2, 2021
@tnrich
Copy link
Author

tnrich commented Feb 3, 2021

Here's a link to the hand rolled solution I came up with (in dialog form) to get around this: https://teselagen.github.io/teselagen-react-components/#/ResizableDraggableDialog

And here's a link to the source code:
https://github.com/TeselaGen/teselagen-react-components/blob/master/src/ResizableDraggableDialog/index.js

Basically I ended up controlling all the state and do manual checks of the window size and the contents of the dialog:

import React from "react";
import { Dialog, Classes } from "@blueprintjs/core";
import { Rnd } from "react-rnd";
import "./style.css";

const defaultDialogWidth = 400;
const defaultDialogHeight = 450;
export default class ResizableDraggableDialog extends React.Component {
  componentDidMount() {
    window.addEventListener("resize", this.onWindowResize);
    this.setDefaults();
    setTimeout(() => {
      this.setDefaults();
    }, 0);
  }
  state = {
    x: 0,
    y: 0,
    width: defaultDialogWidth,
    height: defaultDialogHeight
  };

  setDefaults = () => {
    const { width, height } = this.props;
    const { windowWidth, windowHeight } = this.getWindowWidthAndHeight();

    let heightToUse;
    if (height) {
      heightToUse = height;
    } else {
      heightToUse = (document.querySelector(".bp3-dialog-body") || {})
        .scrollHeight;
      if (heightToUse) {
        heightToUse = heightToUse + 60;
      } else {
        heightToUse = defaultDialogHeight;
      }
    }
    let widthToUse;
    if (width) {
      widthToUse = width;
    } else {
      widthToUse = defaultDialogWidth;
    }

    this.setState({
      x: Math.round(Math.max((windowWidth - widthToUse) / 2, 0)),
      y: Math.round(Math.max((windowHeight - heightToUse) / 2, 0)),
      width: Math.min(widthToUse, windowWidth),
      height: Math.min(Math.max(defaultDialogHeight, heightToUse), windowHeight)
    });
  };
  onWindowResize = () => {
    this.setDefaults();
  };
  componentWillUnmount() {
    window.removeEventListener("resize", this.onWindowResize);
  }

  getWindowWidthAndHeight = () => {
    const w = window,
      d = document,
      e = d.documentElement,
      g = d.getElementsByTagName("body")[0],
      windowWidth = w.innerWidth || e.clientWidth || g.clientWidth,
      windowHeight = w.innerHeight || e.clientHeight || g.clientHeight;
    return {
      windowWidth,
      windowHeight: windowHeight - 20 //add a small correction here
    };
  };

  render() {
    const { width, height, RndProps, ...rest } = this.props;
    const { windowWidth, windowHeight } = this.getWindowWidthAndHeight();
    return (
      <div
        className="tg-bp3-dialog-resizable-draggable"
        style={{ top: 0, left: 0, position: "fixed" }}
      >
        <Rnd
          enableResizing={{
            bottomLeft: true,
            bottomRight: true,
            topLeft: true,
            topRight: true
          }}
          maxHeight={windowHeight}
          maxWidth={windowWidth}
          bounds="window"
          size={{ width: this.state.width, height: this.state.height }}
          position={{ x: this.state.x, y: this.state.y }}
          onDragStop={(e, d) => {
            this.setState({ x: d.x, y: d.y });
          }}
          onResizeStop={(e, direction, ref, delta, position) => {
            this.setState({
              width: ref.style.width,
              height: ref.style.height,
              ...position
            });
          }}
          dragHandleClassName={Classes.DIALOG_HEADER}
          {...RndProps}
        >
          <Dialog
            enforceFocus={false}
            hasBackdrop={false}
            usePortal={false}
            canEscapeKeyClose={true}
            {...rest}
          />
        </Rnd>
      </div>
    );
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants