I have a modal that opens up when selecting a link.
The modal contains an input field that can be clicked to be focused on.
On v.2.4.1 I am able to select the input field just fine. However, on v3 when selecting the input field or anything inside the modal wrapper the onRequestClose prop is triggered.
I have the modal component defined here wrapped around a link tag.
class Modal extends React.Component {
static propTypes = {
contentLabel: PropTypes.string.isRequired,
children: PropTypes.node,
onClick: PropTypes.func,
showModal: PropTypes.bool.isRequired
};
handleClick = (event) => {
if (this.props.onClick) {
this.props.onClick(event);
}
render() {
const { showModal, to, children, contentLabel, ...props } = this.props;
return (
<a href="" {...props} onClick={this.handleClick}>{children}
<ReactModal
isOpen={showModal}
onRequestClose={this.handleClick}
shouldCloseOnOverlayClick={true}
contentLabel={contentLabel}
style={customStyles}
>
{to}
</ReactModal>
</a>
);
}
}
I have a Login component with the input field inside it:
<Login />
and I wrap the Modal inside
toggleLoginModal simply defines the visibility of the modal
toggleLoginModal = () => {
this.setState({ showLoginModal: !this.state.showLoginModal });
};
The input field should be able to be selected and not trigger onRequestClose from the modal unless clicking outside of the component
I feel like I may be doing something silly here. It works fine on v2.4.1 just not on v3.0.x
Hi @quachsimon can you provide an example of the issue?
@diasbruno I have updated my OP
<a href="" {...props} onClick={this.handleClick}> will also be triggered, because the modal is inside the <a/>. So, actually is not the onRequestClose={this.handleClick} that is been triggered.
Better move the modal outside of the link.
Is there a reason why it works on v2.4.1 though?
One way to check is inspecting the event that the handleClick receives. In one version it will be the a. (event.target)
Sorry, I think I marked too soon as 'not a bug'. I'll let this open till we figure this out.
@quachsimon Did you find a solution for this issue?
@diasbruno I played around with it and have not found a solution for this issue. I can not figure out why it closes
I wrote 2 sandbox with those versions of react-modal. I couldn't reproduce your issue. The reason is that the modal is mounted on document.body and my previous answer will be correct if the modal was mounted inside of the <a/>.
https://codesandbox.io/s/r5r58lvxkq - react-modal 2.4.1
https://codesandbox.io/s/k9z5owy3q7 - react-modal 3.1.0
Is there anything missing?
I pass the toggle up to a parent component (which I guess is bad practice?).
I edited one of the sandboxes to show you what I mean:
https://codesandbox.io/s/13v5p7y6pj
I wasn't able to put everything in though...
The parent component toggles the states each time the onClick props is set and is passed to the showModal prop.
I wrap the modal component (the to prop) around a form with two input fields.
When I click on the children prop it toggles the state of the modal which will have open up a form with 2 input fields. When clicking on the input fields it closes the entire modal and does not focus on the text.
It works normally on 2.4.1 but not on 3.1.0
It's not a bad practice.
https://codesandbox.io/s/lx4pwn1437
Now it will show up whom actually is triggering.
On the log inside the modal, it will keep track of the current target of the event.
I've edited it with the to prop going to the node component that I have which is an input.
When clicking on the input it toggles the modal. However, it seems to work fine on the older version.
https://codesandbox.io/s/zxk7nor8x3 - react-modal 2.4.1
https://codesandbox.io/s/40jr09kl49 - react-modal 3.1.0
I suspect that with react 16, the portal is connected properly on the tree, so it will follow the correct path: a -> modal -> input. Therefore, the event will pass through the a node and the handler is fired.
A suggestion for creating your component would be:
const FormWithModalOptions (?) = (props) => {
const { showModal, to, children, onClick, contentLabel, ...props } = props;
return (
<div>
<a onClick={onClick}>{children}</a>
<Modal isOpen={showModal} onRequestClose={onClick} ...>
{to}
</Modal>
</div>
);
};
@quachsimon Please feel free to reopen the issue if necessary. I'll close this for clean up.
Thank you.