Reactstrap: Add ability to specify Modal parent

Created on 23 Feb 2018  路  16Comments  路  Source: reactstrap/reactstrap

Issue description

  • components: Modal
  • reactstrap version 5.0.0-beta
  • react version 16.3.0
  • bootstrap version 4.0.0

What is happening?

There is currently no way to specify a Modal container. All Modals appear as children of the body.

What should be happening?

Modal should provide a parentSelector prop, similar to the one in the react-modal library.

See: http://reactcommunity.org/react-modal/#usage

/*
  Function that will be called to get the parent element that the modal will be attached to.
*/
parentSelector={() => document.body}

This should be a relatively minor feature. I'd be happy to implement and create a pull request myself (although that's not necessary.)

I'm creating this issue mostly to test the water and get feedback from the reactstrap devs.

Most helpful comment

@leebradley That is a cool use case but can it be done with bootstrap CSS? The goal of reactstrap is to make bootstrap easy to use with react by creating components that apply the correct class names and replacing the jquery library with react. Since bootstrap only supports full page modals, this is out of scope for reactstrap.

@tannerhallman Hopefully soon! @TheSharpieOne manages the releases.

All 16 comments

Pull request https://github.com/reactstrap/reactstrap/pull/796 was merged in recently to support portals for modal. It'll be available in the next release.

Actually it sounds like you want to attach modals elements other than the body? Generally modals don't matter where they are since they are fixed positioned but I think they are preferred at the body level. That is what the parentSelector would help with so your component can receive props as needed and be rendered correctly. What is your use case for somewhere else?

The most common use of a modal is with document.body, where the modal backdrop covers the entire application and is centered in the middle of the body.

But this is generally a poor user experience. I'd argue it's done for two reasons: Design simplicity or pushing the user down a sales corridor. Ideally, modals should only disable interaction with the relevant part of an application. As an example: When an "alert" modal shows up in Chrome, you can still change to another tab.

In my application, I would like to disable interaction with a user form and present the user with a list of options. Either "Add Another User" or "Continue". But this modal should not affect other parts of the application, such as the navigation menu.

@supergibbs any timeline on the next release?

@leebradley That is a cool use case but can it be done with bootstrap CSS? The goal of reactstrap is to make bootstrap easy to use with react by creating components that apply the correct class names and replacing the jquery library with react. Since bootstrap only supports full page modals, this is out of scope for reactstrap.

@tannerhallman Hopefully soon! @TheSharpieOne manages the releases.

I tried generating the release assets but ran into https://github.com/reactstrap/reactstrap/issues/820#issuecomment-367156748

Ya react-popper is broken. We can downgrade to v0.8.1 for now until v0.8.3 is released

@supergibbs That's a good point. It's not supported in vanilla Bootstrap 4. I didn't realize that Bootstrap fixed-positioned the modal element by default, but I guess that makes sense.

@supergibbs Will it be possible to set an parent element? Our issue is the following:

We're using react-strap in an application together with react-full-screen, what this library does is making the Main component full screen. However when you open up a modal when in fullscreen mode, the modal is show, but outside the main component so for example input elements are not reachable (tested on OSX/Chrome).

When it is possible to set the container, it will be possible to add the modal to the Main component so it becomes part of the full-screen component.

Is the PR about React Portal sufficient to get the above working?

Thanks.

@rvmourik I am not sure I understand the issue (can you make a demo?) but setting the parent of the modal doesn't really do anything since the position is fixed. You may need to override the bootstrap css to make it work with your app.

@supergibbs Hi, I'm experiencing the same issue as @rvmourik. The Modal component does not work when any DOM element is in full screen mode. Only the children of the element for which full screen has been granted are visible in this scenario.

Angular UI/bootstrap Modal has the parameter appendTo for this purpose.

I think you can use a portal right? I don't think there is any other way, PRs welcome!

Yeah, but... Would a portal to a portal work? The Modal component already uses a portal to body. Maybe the component could have a property to specify the target container of the portal (with body as default).

Ya, sorry, I'll admit I haven't been using ReactStrap myself much lately in my current role and my team hasn't had this issue. Looks like it's hardcoded to append to <body>. Need a PR if that is something you need to override.

From Bootstrap docs, it sounds like only body is truly supported:

Modals use position: fixed, which can sometimes be a bit particular about its rendering. Whenever possible, place your modal HTML in a top-level position to avoid potential interference from other elements. You鈥檒l likely run into issues when nesting a .modal within another fixed element.

I understand that placing the modal in the body element would be the right thing to do in most cases. But when using the Fullscreen API, the top-level element changes and body is not available and then it makes more sense to use an appendTo property. I think I could work in a PR for that.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

thecodejack picture thecodejack  路  22Comments

ruszki picture ruszki  路  15Comments

changLiuUNSW picture changLiuUNSW  路  18Comments

Rootmafia picture Rootmafia  路  17Comments

madisvain picture madisvain  路  17Comments