Giter VIP home page Giter VIP logo

react-popout's Introduction

react-popout

React popout is a React component wrapping window.open allowing you to host content in a browser popup window.

npm install react-popout --save

Demo

To see it in action just go to http://jake.ginnivan.net/react-popout

Usage

Import with es6

import Popout from 'react-popout'

The usage is really simple. When the component is mounted the popup is open, and when it is unmounted the popup is closed.

<Popout url='popout.html' title='Window title' onClosing={this.popupClosed}>
  <div>Popped out content!</div>
</Popout>

To close the window programatically give the window a ref and use the closeWindow function.

props

title [required]

Title for popup window.

url [optional]

URL of the page to load intially. Often needed for css. about:blank will be used if not specified.

onClosing [optional]

Called when popout window is closed, either by user or by calling close.

options [optional]

Object representing window options. See the docs for reference.

Example: <Popout options={{left: '100px', top: '200px'}} />

By default 500px wide, 400px high and centered over the window hosting the react component.

You can also specify a function with signature (options, window) => { } to perform calculations. For example top is calculated with (o, w) => ((w.innerHeight - o.height) / 2) + w.screenY

window [optional]

Instead of using the window global, a window object can be passed in. It needs the following functions on it:

window.open(<url>, <title>, <strWindowFeatures>); and return an object which looks like this:

{
  onbeforeunload: () => { },
  onload: () => { },
  close: () => { },
  document: {
    title: string,
    body: {
      appendChild: (ele) => { }
    }
  }
}

This can be used if you need to intercept the calls and do something else.

containerId [optional]

Assigns an Id to the container that will be injected in the popup window document.body, defaults to popout-content-container, useful for cascading styles.

Example:

// input
<Popout containerId='tearoff'>
  <SomeComponent />
</Popout>

// output in new window:
<div id="tearoff">
  <SomeComponent />
</div>

onError [optional]

Provides a callback incase the window wasn't opened, usually due to a popout blocker within the browser.

Example:

// input
<Popout onError={() => {}}>
    ...
</Popout>

Example hosting component

class HostingComponent {
  constructor(props) {
    super(props);
    this.popout = this.popout.bind(this);
    this.popoutClosed = this.popoutClosed.bind(this);
    this.state = { isPoppedOut: false };
  }

  popout() {
    this.setState({isPoppedOut: true});
  }

  popoutClosed() {
    this.setState({isPoppedOut: false});
  }

  render() {
    if (this.state.isPoppedOut) {
      return (
        <Popout url='popout.html' title='Window title' onClosing={this.popoutClosed}>
          <div>Popped out content!</div>
        </Popout>
      );
    } else {
      var popout = <span onClick={this.popout} className="buttonGlyphicon glyphicon glyphicon-export"></span>
      return (
        <div>
          <strong>Section {popout}</strong>
          <div>Inline content</div>
        </div>
      );
    }
  }
}

The popped out content can have props set and will render just as you would expect a normal React component to render.

react-popout's People

Contributors

ajmeese7 avatar ansmonjol avatar dimitarchristoff avatar domhaas avatar iamdustan avatar jakeginnivan avatar marchaos avatar mikemorton avatar miracle2k avatar smwhit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-popout's Issues

IE 11 broke when popout is already open and content is updated

After first render of popout, while popout window is still open if there is a new trigger of update, getting below error
SCRIPT87: Invalid argument.

If the popout is closed and perform an action that again triggers popout render, starts getting below error for each such render.
SCRIPT5007: Unable to get property 'firstChild' of undefined or null reference

If I close the browser itself and start the session in new browser, same behavior repeats.

This is occurring only in IE 11,but in Chrome it works absolutely fine.

Code for demo

Can you give the code for the demo?
Im trying to place a cancel button on my popout window but i dont know how to implement it just like the close text on your demo?
please help

Multiple Components

How to use nested multiply component.
renderList() {
return this
.data
.map((pane, index) => {
return (
NestedPopout
);
});
}

Thanks

URL?

Could you please explain what the URL field is doing? I tried moving some components from the main page into a popout, but I keep getting these errors:

Uncaught TypeError: Cannot read property 'style' of undefined

It's not clear to me what needs to be defined in the page of the popoout such that the new component will receive updated props.

dom ready issues in the popout

First up nice work on the popout Jake, thanks for the effort.

I was having this odd issues with a popout that hosted a d3 chart, it appears the error was due to code before the dom was ready in the popout. I then noticed this line.

Was there any reason it's called rather than waiting for the window to call it?

Removing this line fixes my problem (in chrome latest).

How to Close window programmatically

This sentence isn't clear to me -
"To close the window programatically give the window a ref and use the closeWindow function."

can you share a simple example or usage? or refer to an example in the docs?

isClosing not working

Hello,

isClosing was not working in my project, so i did some debugging.

I think this:

popoutWindowUnloading() {
    ReactDOM.unmountComponentAtNode(this.state.container);
    this.props.onClosing && this.props.onClosing();
}

should be changed to this:

popoutWindowUnloading() {
    if(this.props.onClosing) {
        this.props.onClosing()
    }
    ReactDOM.unmountComponentAtNode(this.state.container);
}

After the change everything is working fine.
Thanks for this component, helped me a lot.

Is this project abandoned?

Hi,

I noticed that this project is not getting the love that it needs. We are using this project in a production setting, and therefore we are making numerous changes to it that we would like to share with the community. We would like to take it over if you are no longer interested in maintaining it. See https://github.com/marchaos/react-popout/commits/master.

Would you be interested in transferring this project?

Cheers,
Marc.

Opening Multiple Popout Windows

Disclaimer: I haven't found the time to see if I can reproduce this in the demo's...

I haven't found a way to open multiple pop-outs at once successfully. In my example, the second popout content is always empty. There appear to be some issues around registering event listeners also.

Should this be possible?

Error when there is no internal content

If I only want to open a URL, I shouldn't need a child element in the Popup component.

<Popout url='http://www.google.com' title='Window title' >
 </Popout>

but this creates
invariant.js:39 Uncaught Invariant Violation: ReactDOM.render(): Invalid component element.

IE 11 broke when component will update and render at the popout window

After the first render at popout window, when changes some component value or anything that trigger a component update render the UI broke and throw the error infinitely on the IE console.

SCRIPT87: Invalid argument.
"Error: Cannot parse given Error object"
"Error: Invariant Violation: findComponentRoot(..., .1.1): Unable to find element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a when using tables, nesting tags like

,

, or , or using non-SVG elements in an parent. Try inspecting the child nodes of the element with React ID ``.
at invariant
at ReactMount.findComponentRoot
at ReactMount.findReactNodeByID
at getNode
at ReactDOMComponent.Mixin._updateDOMProperties
at ReactDOMComponent.Mixin.updateComponent
}

closeWindow example

Is there a closeWindow example? If I put a "ref" on the component, it doesn't seem to end up in the this.refs array.

CSS Styling of the component

Hi,

I am trying to popout a component called CryptoMarket. The component is working fine but all my CSS styling is gone. I am using webpack and css loader. So all styles are coming from a scss file. Please help

				<PopoutWindow title="Test" onClosing={this.popoutClosed}>
					<div>
						<div onClick={this.popoutContentClicked}>Close</div>
						<CryptoMarkets {...this.props}/>
					</div>
				</PopoutWindow>

blocking for serverside rendering ?

Not sure if I used correctly, but using react-popout, page is blocked when rendered server side
I had the same problems while using window.location at the wrong place

Move React to peerDependencies

At present when you bundle react-popout with webpack/browserify in my app, i get two copies of React, one coming from react-popout and another from my app dependencies.

Moving React to peerDependencies is a good practice in the comunity, see this

more info

maybe

"peerDependencies": {
    "react": "0.13.x"
  }

is ok :)

window prop not working as specified in the doc

Hi @JakeGinnivan ,
First, thanks for your work on react-popout :)

I'm using it in a project and I need to access the window that was opened in my parent component.

To do that, I tried to use the window prop. In the README, you say it need to be an object with a open method on it. So I just did that, I pass an object like this:

{
  open: (...args) => {
    const popoutWindow = window.open(...args);
    this.setState({ popoutWindow });
    return popoutWindow;
  }
}

However, I get an error that (this.props.window || window).removeEventListener is not a function

So my fake window actually might need a few other methods to work properly. I was wondering if you had a comprehensive list of the methods I should implement, so that I'm sure that it won't break?

Another solution to my problem would be to have a callback prop that would be called once the window is opened, passing the window object in argument, like so:

  onPopoutOpened: function(popoutWindow) {
    this.setState({ popoutWindow });
  },

...

  render: function() {
    return <Popout onPopoutOpened={this.onPopoutOpened} />;
  }

Any intention to do that in the future? Tell me if you'd like a PR for this.

Can't hide location options.location = "no", options.location = "0", options.location = 0

None of the option does not work when using the URL. According to the docs you linked:

NOTE: All features can be set to yes or 1, or just be present to be "on". Set them to no or 0, or in most cases just omit them, to be "off".
Example: "status=yes", "status=1", and "status" have identical results.

So, how can we specify the options? I can set the size property, but the location is not affected...

<PopoutWindow url="http://localhost:8080"
            title="Configuration"
            onClosing={this.githubAuthClosed}
            options={{
              height: "780",
              width: "1000",
              toolbar: "no",
              location: "no"
            }}>
          <div />
        </PopoutWindow>

Add typings

Could not find a declaration file for module 'react-popout'. '/node_modules/react-popout/dist/react-popout.min.js' implicitly has an 'any' type.
Try npm install @types/react-popout if it exists or add a new declaration (.d.ts) file containing declare module 'react-popout';

Auto-Close the popout window?

Quick question regarding your online demo. If I open the Popout window, and then close the main window, the Popout window doesn't automatically close. Is there a way to make the Popout window close automatically? This is the comment from your blog post:

"The nice thing about having this as a React component is that the Popout window’s lifecycle is tied to the lifecycle of the owning component. So when the History component is unmounted the Popout will close the popup it might have had opened."

but how do I make that work in your online example?

height and width of popout not changing

I passed

options={{height: '640px', width: '600px'}}

in the

<Popout url='popout.html' title='Window title' />

but the height and width of popout doesn't changed

Popout options

Popout options specifically resizable:'no', scrollbars:'no' is not working.

url parameter with Django

I am trying to use the url parameter to open the popout window on a page that will load the css I need.
The problem is that when I give a url to open, the content of the component is ignored, and only the content of the page (nothing for now) is displayed.

I suppose this has to do with the fact that I am using Django which has a particular way of managing urls.

IE11 with URL not working?

Trying to get example3 working on IE11 - but it only seems to work with Chrome. Ran into issues, so just tried to get example3 to work on IE11 without success. I can get IE11 to work without the URL setting, but I need the URL to load CSS and javascript link into new window.

Seems to complain about this: react-popout.jsx:123

TypeError: Object doesn't support property or method 'addEventListener'

Which is strange, because I know IE11 does support addEventListener...

(line number, code...)
120 | const popoutWindow = ownerWindow.open(this.props.url, this.props.name || this.props.title, this.createOptions(ownerWindow));
121 | this.setState({ popoutWindow });
122 |

123 | popoutWindow.addEventListener('load', this.popoutWindowLoaded);
124 | popoutWindow.addEventListener('beforeunload', this.popoutWindowUnloading);
125 |
126 | // If they have no specified a URL, then we need to forcefully call popoutWindowLoaded()

Component inside Popout cannot use findDomNode

I've got a couple components that are wrapping legacy non-react modules. These components rely on findDomNode to work correctly, however if they're rendered inside the Popout they break down. Using refs also breaks down in this context. Does anyone have any ideas to get around this?

IE unable to render elements after state has changed

I found some issues using react-popout on IE. The main issue can be examplified by the following piece of simple code:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import domready from 'domready';
    import Popout from '../lib/react-popout.jsx';

    class AnotherCoolComponent extends React.Component {
      render() {
        return (
         <p>{this.props.sentence}</p>
        );
      }
    }

    class Example extends React.Component {
      constructor(props) {
        super(props);
        this.popout = this.popout.bind(this);
        this.popoutClosed = this.popoutClosed.bind(this);
        this.popoutContentClicked = this.popoutContentClicked.bind(this);
        this.showSomething = this.showSomething.bind(this);
        this.state = {
          isPoppedOut: false,
          showSomething: false,
        };
      }

      popout() {
        this.setState({isPoppedOut: true});
      }

      popoutClosed() {
        this.setState({isPoppedOut: false});
      }

      showSomething() {
        this.setState({
          showSomething: !this.state.showSomething
        });
      }

      popoutContentClicked() {
        this.popoutClosed();
      }

      render() {
        if (this.state.isPoppedOut) {
          return (
            <Popout title='Test' onClosing={this.popoutClosed}>
              <div>
                <button onClick={this.popoutContentClicked}>Close</button>
                <button onClick={this.showSomething}>Click here to show something</button>
                {this.state.showSomething && <AnotherCoolComponent sentence="testing" />}
              </div>
            </Popout>
          );
        } else {
          return (
            <a onClick={this.popout}>(pop window out)</a>
          );
        }
      }
    }

    domready(() => {
      var container = document.createElement('div');
      document.body.appendChild(container);
      ReactDOM.render(<Example />, container);
    });

When a change on the state of the component inside the popout causes a new component to be rendered, React for some reason, is unable to render it and throws errors:

It's not possible to get property "firstChild" of undefined reference or null

onClick() not working in popup

This is my component:

import React, {Component} from 'react'
import PopoutWindow from 'react-popout'

class Help extends Component {
  render() {
    return (
      <PopoutWindow
        onClosing={this.props.closeHelpWindow}
        options={{width: '500px', height: '500px'}}
        ref={el => this._popup = el}
        >
      <div>
        
      // Other HTML content

      <div onClick={console.log('click')}>CLICK</div>

      <button onClick={() => {
        console.log('CLICK')
        this.props.closeHelpWindow
        this._popup.closeWindow
      }}>
        Ok
      </button>
    </div>
    </PopoutWindow>
    )
  }
}

export default Help

When I click the DIV or the button, nothing gets logged to the console (i used inspect on the popup window).

IE 11 Input Text Broken

In IE 11, if the following JSX element: <input type="text" /> is in the popout window, the popout window will fail to render with the console error:

'enumerable' attribute on the property descriptor cannot be set to 'true' on this object

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.