Giter Club home page Giter Club logo

react-modal-dialog's Introduction

React Modal Dialog

npm

Check out the demo here

React modal dialog is an idiomatic way to represent modal dialogs in react. It is nested inside the components that require them, and can themselves nest other dialogs. There are no global switches or state, and the contents of the dialog are defined where you need it.

Design Considerations

React modal dialog was built with a few fundamental assumptions and constraints in mind:

  • When you have two dialogs, the ESC key will only close the top level one (there is an event manager implemented like a stack)
  • The package needs to support dialogs that bounce in with a spring animation (not just standard ease-in, ease-out), but still be flexible enough for other designs
  • Dialogs that are too long will scroll in their viewport
  • Dialogs need to be able to show a loading spinner, that means the background and the content need to be separate components

Idiomatic Syntax

From the very beginning, the goal was a syntax very similar to the one below, where the modal component is held within a button or the view with the closest common ancestor of two buttons.

class Button extends React.Component {
  state = {
    isShowingModal: false,
  }
  handleClick = () => this.setState({isShowingModal: true})
  handleClose = () => this.setState({isShowingModal: false})
  render() {
    return <a onClick={this.handleClick}>
      <span>Button Text</span>
      {
        this.state.isShowingModal &&
        <ModalComponentHere onClose={this.handleClose}/>
      }
    </a>;
  }
}

Actual Usage

This is how react-modal-dialog works. You can create a component that wraps ModalContainer and ModalDialog into one CustomDialog, but the reason I have separated is so that I can add a loading spinner above the background but below the dialog.

import React, {PropTypes} from 'react';
import {ModalContainer, ModalDialog} from 'react-modal-dialog';

class View extends React.Component {
  state = {
    isShowingModal: false,
  }
  handleClick = () => this.setState({isShowingModal: true})
  handleClose = () => this.setState({isShowingModal: false})
  render() {
    return <div onClick={this.handleClick}>
      {
        this.state.isShowingModal &&
        <ModalContainer onClose={this.handleClose}>
          <ModalDialog onClose={this.handleClose}>
            <h1>Dialog Content</h1>
            <p>More Content. Anything goes here</p>
          </ModalDialog>
        </ModalContainer>
      }
    </div>;
  }
}

Loading Spinners

import React, {PropTypes} from 'react';
import {ModalContainer, ModalDialog} from 'react-modal-dialog';
import ReactSpinner from 'react-spinjs';

class View extends React.Component {
  static propTypes = {
    // This view takes a isLoading property
    isLoading: PropTypes.bool,
  }
  state = {
    isShowingModal: false,
  }
  handleClick = () => this.setState({isShowingModal: true})
  handleClose = () => this.setState({isShowingModal: false})
  render() {
    const {
      props: {
        isLoading,
      },
    } = this;

    return <div onClick={this.handleClick}>
      {
        this.state.isShowingModal &&
        <ModalContainer onClose={this.handleClose}>
          {
            isLoading ?
            <ReactSpinner/> :
            <ModalDialog onClose={this.handleClose}>
              <h1>Dialog Content</h1>
              <p>More Content. Anything goes here</p>
            </ModalDialog>
          }
        </ModalContainer>
      }
    </div>;
  }
}

Styles (CSS and Images)

In version 4.0+ react-modal-dialog has finally shifted to using narcissus, narcissus makes inline css styles sane, and also works in pure javascript so you don't have to spend time requiring css files awkwardly with NPM and packaging them in webpack with custom loaders yourself.

For a similar reason of not having to deal with external dependencies or awkward loaders/hacked require statements, starting in 4.0+, react-modal-dialog uses hand-written svg for the one "image" that comes with the package, the close button.

For Your Own Implementation

For now, I recommend you check out the source code of this project, as it is quite simple, to really get an understanding of how this dialog works. I've spent a lot of time trying many paradigms (you can read about all that here), and I've settled on this one for good reasons.

The hardest part about dialogs is their architecture, not the UI or specific implementation. Feel free to swap out your own ModalDialog class into my existing ModalContainer, or disassemble ModalContainer into your own portal and background class.

To get the esc key to only close the top dialog when there are two modal dialogs, I employed the use of an event controller. However, you may find this to be peculiar or you may want to attach your dialogs to your own event controller. If that's true, you may want to branch this project to edit the code in componentDidMount and componentWillUnmount of ModalPortal.

Contributing

Feel free to send pull requests, or help document this project more.

A Note on package.json

package.json points to src/index.js, so that it is easy to develop against. However, this folder does not exist in the npm distribution, so the whole thing falls back to the /index.js at the root, which points to the compiled /lib/index.js.

react-modal-dialog's People

Contributors

gildus avatar h34d avatar kelseycohort avatar narendrashetty avatar paulj avatar perrin4869 avatar qimingweng avatar rvanmil 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

react-modal-dialog's Issues

sending event for onClose

sending event object when onClose is triggered will be very helpful when a small computation is needed.

Throw errors when I after building in webpack an run on the browser

Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method ofFirstModal.

Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. Check the render method ofFirstModal.

But I try import the pre-build(es5) files, and it works.

Update to React 0.14

The biggest change is instead of using the portal to render, use renderIntoSubtree (and find out how to access that API too)

Heavy dependencies

Is there any possibility of eliminating immutable and the entire lodash package from the dependencies? ~100kb seems to be a very high price to pay for a modal window.

react 15.2.0 introduces prop warnings

Updating to react 15.2.0 brings along this loud warning in the console.

warning.js?8a56:44 Warning: Unknown props 'componentIsLeaving', 'top', 'left', 'recenter' on <div> tag. Remove these props from the element. For details, see https://fb.me/react-unknown-prop

REF in react 15

Hi Excellent component, however after updating to react 15 there is an issue..

invariant.js?99c6:39 Uncaught Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs.

I think because you give the component ref self it is causing the issue:

  1. The application has multiple react modules in the build.
  2. The ref attribute is not being used w/in the render method.

Multiple modals on one page?

Hi there!
I've html markup which looks like this:

<div className="container">
	<ul>
		<div id="works">
			<li>
				<a href="#" data-modal="modal/.html"> 
				<img src="img/xxx.jpg" alt="" width="320" height="240" /> </a>
				<h3 lang=""></h3> </li>
			<li>
				<a href="#" data-modal="modal/.html"> 
				<img src="img/xxx.jpg" alt="" width="320" height="240" /> </a>
				<h3 lang=""></h3> </li>
			<li>
				<a href="#" data-modal="modal/.html"> 
				<img src="img/xxx.jpg" alt="" width="320" height="240" /> </a>
				<h3 lang=""></h3> </li>
		</div>
	</ul>
</div>

It had multiple modals on one page.
How it could be done with react-modal-dialog? Working example highly appreciated

component blurry until focused

Hi,

first of all thank you for this great component. The only problem I have, is that whenever the component is rendered, it's always blurry until it gains focus. After that it's always fine until it's closed and rendered again. I'm providing some snapshots. Any idea why this might be happening?

Without focus
snapshot15

With focus
snapshot16

Way to add a /route to URL tag when modal is opened.

Is there a way for me to add a parameter string eg. https://github.com/qimingweng/react-modal-dialog/${PARAMETERHERE} when the modal is closed so I can link to the modal.

This would probably need to set the state of the modal to open upon going to the specified link.

I've added an anchor tag but it only adds it to the URL, when I go the URL it doesn't show the modal in the open state.

Thank you.

						{
							<ModalContainer onClose={this.handleCloseRestrictedCountries}>
								<ModalDialog className={_ModalDialog} onClose={this.handleCloseRestrictedCountries}>
								 	<a id="restricted_countries">
										<RestrictedCountries
											excludedCountries={excludedCountries}
										/>
									</a>
								</ModalDialog>
							</ModalContainer>
						}

Broken link for architecture

Hi @qimingweng! The library looks promising, especially when trying to understand how to build one's own modal component possibly - thank you.

It seems like one of the links in Readme is broken ('here' below).

I've spent a lot of time trying many paradigms (you can read about all that here), and I've settled on this one for good reasons.

I was looking forward to reading about your experience with other modals and thoughts on the architectural decisions around this modal. To that end, apart from fixing the link, if you get a chance, could you explain your thought process around the current architecture either in this ticket or the README?

Thank you!

Custom CSS

Hello,
I'm trying to find how to customize CSS, I have located the files and .JS I could get what I wanted. But is there another way directly into the component or the modal is called to customize it?

I could put className and add what I needed to style the modal but I do not put classes for each element type of the background, the overall modal

If you have a solution I'm interested,

Best regards,

screen shot 2016-09-21 at 12 10 19

is this module compatible with react 16 ? got Error: Cannot find module 'inline-style-prefixer/static'

while the npm installation of this module , there are already those warnings:
image
and then also an error
image
and it's the same error i get later on browser:

generate.js:14 Uncaught Error: Cannot find module 'inline-style-prefixer/static'
    at webpackMissingModule (generate.js:14)
    at eval (generate.js:14)
    at Object../node_modules/narcissus/build/generate.js (reactBoilerplateDeps.dll.js:91829)
    at __webpack_require__ (reactBoilerplateDeps.dll.js:21)
    at eval (index.js:15)
    at Object../node_modules/narcissus/build/index.js (reactBoilerplateDeps.dll.js:91842)
    at __webpack_require__ (reactBoilerplateDeps.dll.js:21)
    at eval (FlexDialog.js:31)
    at Object../node_modules/react-modal-dialog/lib/FlexDialog.js (reactBoilerplateDeps.dll.js:102839)
    at __webpack_require__ (reactBoilerplateDeps.dll.js:21)

i'm using "react": "^16.7.0-alpha.2"

warning on react 15.2.0

With react 15.2.0 version we have got the new warning:
Warning: Unknown prop componentIsLeaving on

tag. Remove this prop from the element. For details, see https://fb.me/react-unknown-prop
in div (created by HeadlessModal)
in div (created by ModalBackground)

Modal cannot be closed while loading

Having a ModalContainer without ModalDialog cannot be closed.

Example:

<ModalContainer onClose={onClose}>
    {loading
        ?
        <div style={{...}}>
            <span>Loading ...</span>
        </div>
        :
        <ModalDialog onClose={onClose}>
            {children}
        </ModalDialog>
    }
</ModalContainer>

In this example the modal cannot be closed as long as loading == true. Neither clicking the background nor pressing ESC works.

Set the width and height of the dialog in percentages

Hi,
Is it possible to set the width and height of the dialog to a certain percentage of the screen width? This the output when I try to do it.

screenshot from 2016-05-14 11 04 45

<ModalContainer onClose={this.handleClose}>
{
    this.state.isLoading ?
        <ReactSpinner/> :
        <ModalDialog style={{height: '50%',width: '70%'}} onClose={this.handleClose}>
            <BookItem {...this.state.book}/>
        </ModalDialog>
}
</ModalContainer>

I'd like to make the content fit within the reduced dialog. Is there any way to do it in the current version of react-modal-dialog? Also, this is the output if the content is large and I don't set any width and height for dialog:

screenshot from 2016-05-14 11 29 20

Spinner not working

Hi I can not make the spinner to work. I is throwing this error on runtime:

vendor.js?v=sZBD4ty28krojWTr8aPA_g_AGMpt_Nhz9VS_g69om6M:1 Uncaught Error: Minified React error #130; visit http://facebook.github.io/react/docs/error-decoder.html?invariant=130&args[]=undefined&args[]=%20Check%20the%20render%20method%20of%20%60Login%60. for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
    at r (vendor.js?v=sZBD4ty28krojWTr8aPA_g_AGMpt_Nhz9VS_g69om6M:1)
    at i (vendor.js?v=sZBD4ty28krojWTr8aPA_g_AGMpt_Nhz9VS_g69om6M:49)
    at Object.updateChildren (vendor.js?v=sZBD4ty28krojWTr8aPA_g_AGMpt_Nhz9VS_g69om6M:54)
    at v._reconcilerUpdateChildren (vendor.js?v=sZBD4ty28krojWTr8aPA_g_AGMpt_Nhz9VS_g69om6M:54)
    at v._updateChildren (vendor.js?v=sZBD4ty28krojWTr8aPA_g_AGMpt_Nhz9VS_g69om6M:54)
    at v.updateChildren (vendor.js?v=sZBD4ty28krojWTr8aPA_g_AGMpt_Nhz9VS_g69om6M:54)
    at v._updateDOMChildren (vendor.js?v=sZBD4ty28krojWTr8aPA_g_AGMpt_Nhz9VS_g69om6M:54)
    at v.updateComponent (vendor.js?v=sZBD4ty28krojWTr8aPA_g_AGMpt_Nhz9VS_g69om6M:54)
    at v.receiveComponent (vendor.js?v=sZBD4ty28krojWTr8aPA_g_AGMpt_Nhz9VS_g69om6M:54)
    at Object.receiveComponent (vendor.js?v=sZBD4ty28krojWTr8aPA_g_AGMpt_Nhz9VS_g69om6M:35)

I am using it like this:

{
       this.state.isShowingModal &&
       <ModalContainer onClose={this.handleClose}>
         {
           this.state.isShowingModal ?
           <ReactSpinner color="white"/> :
           <ModalDialog onClose={this.handleClose}>
             <h1>Dialog Content</h1>
             <p>More Content. Anything goes here</p>
           </ModalDialog>
         }
       </ModalContainer>
     }

Undefined number in CloseCircle.js

Hi I am using this to my project,

but getting this error


Uncaught TypeError: Cannot read property 'number' of undefined
    at eval (CloseCircle.js?5cea:48)
    at Object.<anonymous> (bundle.js:1)
    at e (bundle.js:1)
    at eval (UnstyledFlexDialog.js?42b9:33)
    at Object.<anonymous> (bundle.js:1)
    at e (bundle.js:1)
    at eval (FlexDialog.js?69c0:33)
    at Object.<anonymous> (bundle.js:1)
    at e (bundle.js:1)
    at eval (index.js?f624:9)

Uncaught Error: Element type is invalid: expected a string

Not sure why this popular package could not be executed correctly with react 16

	"react": "^16.1.0"

	import * as React from 'react';
	import ReactDOM from 'react-dom';
	import Modal from 'react-modal';

	invariant.js:42 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

	Check the render method of `Index`.

Close icon removed with overflow:scroll

hello -

When updating the CSS for the modal to include

overflow: scroll;

for longer content, the black close X disappears. I have tried everything in CSS to restore it but cant figure out why the overflow whacks it. Any ideas ?

SetState not working

Hello,

I'm currently testing React under basic MDL, I installed your package and I try to make it work.
By default the modal opens and buttons do absolutely nothing,
You have an idea ?
Best regards,

import React, {PropTypes} from 'react';
import ReactDOM from 'react-dom';
import {ModalContainer, ModalDialog} from 'react-modal-dialog';

import {
  Drawer,
  Grid,
  Cell,
  Button,
  isLoading,
  Navigation
} from 'react-mdl';

class DrawerComponent extends React.Component {

      constructor (props) {
        super(props)
        this.state = {
          isShowingModal: false
        };
        this.handleClick = this.handleClick.bind(this);
        this.handleClose = this.handleClose.bind(this);

      }
      handleClick() {
        this.setState({isShowingModal: true});
      }
      handleClose() {
        this.setState({isShowingModal: false});
        console.log('test');
      }

     render() {
        return (
          <Drawer title="Test">
              <Grid>
                  <Cell className="text-center" align="middle" col={12}>
                    <Button colored onClick={this.handleClick} raised ripple>Show Dialog</Button>
                  </Cell>
              </Grid>
              <Navigation>
                  <a href="">Link</a>
                  <a href="">Link</a>
                  <a href="">Link</a>
                  <a href="">Link</a>
              </Navigation>

              <ModalContainer onClose={this.handleClose}>
                  <ModalDialog onClose={this.handleClose}>
                    <h1>Dialog Content</h1>
                    <p>More Content. Anything goes here</p>
                  </ModalDialog>
              </ModalContainer>

          </Drawer>
        );

    }
}
module.exports = DrawerComponent;

React dependency

In package.json react should probably be marked as a peerDependency not a dependency. This makes a big difference as currently react-modal-dialog library pulls its own version of react and react does not like to be double-imported.

Uncaught TypeError: Cannot read property '0' of undefined

After upgrading to version 3, I've got that problem, which seems to be connected with animate.js..

Uncaught TypeError: Cannot read property '0' of undefined
DecomposedMatrix.interpolate @ dynamics.js:848
(anonymous function) @ dynamics.js:4
interpolate @ dynamics.js:1455
animationTick @ dynamics.js:1438
runLoopTick @ dynamics.js:1406

Same thing happens on demo page of react-modal-dialog. To reproduce open dialog, close, error should be visible in console. When trying to open modal again it opens, but won't scale properly.

Modal is positioned at the bottom of the page

I added modal to my component:

return (
      <div>
        <div>
          {
            this.state.isShowingModal &&
            <ModalContainer onClose={this.handleClose.bind(this)}>
              <ModalDialog onClose={this.handleClose.bind(this)}>
                <h1>Dialog Content</h1>
                <p>More Content. Anything goes here</p>
              </ModalDialog>
            </ModalContainer>
          }
        </div>
        <Header />
        <div className="container">
          <SearchBox />
          <LabelForm />
          {this.renderRepos()}
        </div>
      </div>

However, when I open it, ModalDialog gets wrong value of topOffset. In my case it gets 3232.5px which puts it at the bottom of the page.

repos_arranger

I the code I see that this value is injected by centerComponent. Should I pass something to make it work correctly ?

Allow width to be overwritten by user style

Thanks for this, its an awesome component! I would like to suggest that the width of the component be allow to be overwritten by the users style prop or stylesheet, as the 500px might no be ideal for everyone

ios(iphone, ipad) background is not clickable

i made web page for mobile device page using react

all ios(ipad, iphone) modal popup background is not clickable

(desktop safari hasn't this issue)

after clicking modal is not closed

what is problem?

Cannot read property 'number' of undefined

When adding the repository with yarn add react-modal-dialog, just by importing it gives this error, as if the actual _react object is undefined within the library. Any idea of why this happens?

Edit: I believe its in the way proptypes is imported.

screen shot 2017-10-26 at 5 10 19 pm

Calculate top wrongly

I have a problem, On another page, the top is calculated correctly.
screen shot 2018-02-06 at 15 44 50
No have idea how resolve this.

close button fixed

Hi, wonderful library, any chance you can show me how to have a fixed header or close button,
Use case: For long forms its always good that you have the close button visible all the time.

Refs problem in react 15

image
Hello. I try to integrate your react-modal-dialog but i can't understand why in reactDOM after calling modal i don't see ModalBackground and in html it creates but in react DOM not. Can you lokk on it?

Uncaught TypeError: Cannot read property 'refs' of null

Hi,
I am getting Uncaught TypeError: Cannot read property 'refs' of null when I close a dialog that has a form inside of it. If I remove the "ref" property of all input fields, then no error. But still need access to the fields input value via refs.value

It looks that the error is triggered in ModalBackground.js line 46.

Any idea on how to get rid of that error ?

Thanks,
Marius

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.