Fix: multiple modals cancelled each others on page load

(when one of the modals was initially open).
This commit is contained in:
Vesa Luusua 2017-06-05 19:32:11 +03:00
parent d7794a7bc8
commit fe28a82831
9 changed files with 37 additions and 24 deletions

View file

@ -48,6 +48,6 @@ export const Empty = {
component: ModalWrapper,
useDefaultWrapperStyles: false,
props: {
title: 'Test Modal',
id: 'ExampleModal',
},
};

View file

@ -3,7 +3,7 @@
*
* Example:
* <Parent>
* <Modal isOpen={this.state.modalIsOpen} onClose={handleClose}>
* <Modal id="UniqueIdForThisModal" isOpen={this.state.modalIsOpen} onClose={handleClose}>
* <FormX />
* </Modal>
* </Parent>
@ -22,20 +22,20 @@ export class ModalComponent extends Component {
}
componentDidMount() {
const { isOpen, togglePageClassNames } = this.props;
togglePageClassNames(css.modalIsOpen, isOpen);
const { id, isOpen, togglePageClassNames } = this.props;
togglePageClassNames(id, css.modalIsOpen, isOpen);
}
componentWillReceiveProps(nextProps) {
const { isOpen, togglePageClassNames } = this.props;
const { id, isOpen, togglePageClassNames } = this.props;
if (nextProps.isOpen !== isOpen) {
togglePageClassNames(css.modalIsOpen, nextProps.isOpen);
togglePageClassNames(id, css.modalIsOpen, nextProps.isOpen);
}
}
handleClose(event) {
const { onClose, togglePageClassNames } = this.props;
togglePageClassNames(css.modalIsOpen, false);
const { id, onClose, togglePageClassNames } = this.props;
togglePageClassNames(id, css.modalIsOpen, false);
onClose(event);
}
@ -86,6 +86,7 @@ const { bool, func, node, string } = PropTypes;
ModalComponent.propTypes = {
children: node,
className: string,
id: string.isRequired,
intl: intlShape.isRequired,
isClosedClassName: string,
isOpen: bool,

View file

@ -5,6 +5,7 @@ import Modal from './Modal';
describe('Modal', () => {
it('no extra classes when window is missing', () => {
const props = {
id: 'TestModal',
className: 'test-class-from-props',
isOpen: false,
onClose: v => v,

View file

@ -51,7 +51,7 @@ export const Empty = {
component: ModalInMobileWrapper,
useDefaultWrapperStyles: false,
props: {
id: 'ExampleModalInMobile',
showAsModalMaxWidth: 400,
title: 'Test ModalInMobile',
},
};

View file

@ -69,8 +69,8 @@ class ModalInMobile extends Component {
const {
children,
className,
id,
showAsModalMaxWidth,
title,
togglePageClassNames,
} = this.props;
@ -90,10 +90,10 @@ class ModalInMobile extends Component {
return (
<Modal
className={classes}
id={id}
isOpen={isOpenInMobile}
isClosedClassName={closedClassName}
onClose={this.handleClose}
title={title}
togglePageClassNames={togglePageClassNames}
>
{children}
@ -107,7 +107,6 @@ ModalInMobile.defaultProps = {
className: '',
onClose: null,
showAsModalMaxWidth: 0,
title: null,
};
const { bool, func, node, number, string } = PropTypes;
@ -115,10 +114,10 @@ const { bool, func, node, number, string } = PropTypes;
ModalInMobile.propTypes = {
children: node,
className: string,
id: string.isRequired,
isModalOpenOnMobile: bool.isRequired,
onClose: func,
showAsModalMaxWidth: number,
title: string,
// eslint-disable-next-line react/no-unused-prop-types
togglePageClassNames: func.isRequired,
};

View file

@ -5,6 +5,7 @@ import ModalInMobile from './ModalInMobile';
describe('ModalInMobile', () => {
it('no extra classes when window is missing', () => {
const props = {
id: 'TestModalInMobile',
className: 'test-class-from-props',
isModalOpenOnMobile: false,
togglePageClassNames: v => v,

View file

@ -3,7 +3,6 @@ import { connect } from 'react-redux';
import Helmet from 'react-helmet';
import { withRouter } from 'react-router-dom';
import { FormattedMessage } from 'react-intl';
import { union, without } from 'lodash';
import classNames from 'classnames';
import { Topbar } from '../../containers';
@ -17,7 +16,7 @@ const scrollToTop = () => {
class PageLayout extends Component {
constructor(props) {
super(props);
this.state = { pageClassNames: '' };
this.state = { pageClassNames: [] };
this.togglePageClassNames = this.togglePageClassNames.bind(this);
}
@ -33,14 +32,24 @@ class PageLayout extends Component {
// This function makes it possible to change page level styles
// E.g. disable scrolling when using Modal
togglePageClassNames(className, addClass = true) {
togglePageClassNames(componentId, classNameFromComponent, addClass = true) {
this.setState(prevState => {
const prevPageClassNames = prevState.pageClassNames.split(' ');
const pageClassNames = addClass
? union(prevPageClassNames, [className]).join(' ')
: without(prevPageClassNames, className).join(' ');
const componentIdExists = prevState.pageClassNames.find(c => c.componentId === componentId);
if (componentIdExists) {
const pageClassNames = prevState.pageClassNames.map(c => {
if (c.componentId === componentId) {
return { ...c, addClass };
}
return c;
});
return { pageClassNames };
return { pageClassNames };
} else {
const pageClassNames = prevState.pageClassNames.concat([
{ componentId, className: classNameFromComponent, addClass },
]);
return { pageClassNames };
}
});
}
@ -67,8 +76,10 @@ class PageLayout extends Component {
}
/* eslint-enable no-console */
const pageClassNames = this.state.pageClassNames.map(c => ({ [c.className]: c.addClass }));
return (
<div className={classNames(css.root, this.state.pageClassNames, className)}>
<div className={classNames(css.root, pageClassNames, className)}>
<Helmet>
<title>{title}</title>
</Helmet>

View file

@ -201,10 +201,10 @@ export class ListingPageComponent extends Component {
{/* eslint-enable react/no-danger */}
{authorInfo}
<ModalInMobile
id="BookingDatesFormInModal"
isModalOpenOnMobile={this.state.isBookingModalOpenOnMobile}
onClose={() => this.setState({ isBookingModalOpenOnMobile: false })}
showAsModalMaxWidth={MODAL_BREAKPOINT}
title={bookBtnMessage}
togglePageClassNames={this.togglePageClassNames}
>
<BookingDatesForm className={css.bookingForm} onSubmit={this.onSubmit} price={price} />

View file

@ -56,10 +56,10 @@ exports[`ListingPage matches snapshot 1`] = `
</div>
<ModalInMobile
className=""
id="BookingDatesFormInModal"
isModalOpenOnMobile={false}
onClose={[Function]}
showAsModalMaxWidth={2500}
title="ListingPage.ctaButtonMessage"
togglePageClassNames={[Function]}>
<BookingDatesForm
onSubmit={[Function]}