mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-28 03:43:28 +10:00
Make modal open state respond to window resize
This commit is contained in:
parent
6b92f44171
commit
a258c65cf7
4 changed files with 46 additions and 32 deletions
|
|
@ -14,9 +14,11 @@
|
|||
import React, { Component, PropTypes } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Modal } from '../../components';
|
||||
import { withViewport } from '../../util/contextHelpers';
|
||||
|
||||
import css from './ModalInMobile.css';
|
||||
|
||||
class ModalInMobile extends Component {
|
||||
class ModalInMobileComponent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
|
@ -27,28 +29,25 @@ class ModalInMobile extends Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { isModalOpenOnMobile, showAsModalMaxWidth } = this.props;
|
||||
const { isModalOpenOnMobile, showAsModalMaxWidth, viewport } = this.props;
|
||||
|
||||
// After Mounting, component can adapt to responsive screen size
|
||||
const shouldShowAsModal = window.matchMedia
|
||||
? window.matchMedia(`(max-width: ${showAsModalMaxWidth}px)`).matches
|
||||
: false;
|
||||
if (shouldShowAsModal && isModalOpenOnMobile) {
|
||||
const isMobileLayout = viewport.width <= showAsModalMaxWidth;
|
||||
|
||||
if (isMobileLayout && isModalOpenOnMobile) {
|
||||
this.changeOpenStatus(isModalOpenOnMobile);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const { isModalOpenOnMobile, showAsModalMaxWidth } = nextProps;
|
||||
const { isModalOpenOnMobile, showAsModalMaxWidth, viewport } = nextProps;
|
||||
|
||||
const isChanging = isModalOpenOnMobile !== this.state.isOpen;
|
||||
const shouldShowAsModal = window.matchMedia
|
||||
? window.matchMedia(`(max-width: ${showAsModalMaxWidth}px)`).matches
|
||||
: false;
|
||||
const shouldBeClosedAsModal = !shouldShowAsModal && !isModalOpenOnMobile;
|
||||
const isMobileLayout = viewport.width <= showAsModalMaxWidth;
|
||||
const shouldBeClosedAsModal = !isMobileLayout && !isModalOpenOnMobile;
|
||||
|
||||
// Handle change if status is changing on mobile layout or it is closing (on desktop layout)
|
||||
if (isChanging && (shouldShowAsModal || shouldBeClosedAsModal)) {
|
||||
if (isChanging && (isMobileLayout || shouldBeClosedAsModal)) {
|
||||
this.changeOpenStatus(isModalOpenOnMobile);
|
||||
}
|
||||
}
|
||||
|
|
@ -72,13 +71,13 @@ class ModalInMobile extends Component {
|
|||
id,
|
||||
showAsModalMaxWidth,
|
||||
onManageDisableScrolling,
|
||||
viewport,
|
||||
} = this.props;
|
||||
|
||||
const isMobileLayout = typeof window !== 'undefined' && window.matchMedia
|
||||
? window.matchMedia(`(max-width: ${showAsModalMaxWidth}px)`).matches
|
||||
: false;
|
||||
const isMobileLayout = viewport.width <= showAsModalMaxWidth;
|
||||
const isOpenInMobile = this.state.isOpen;
|
||||
const isClosedInMobile = isMobileLayout && !isOpenInMobile;
|
||||
const isOpen = isOpenInMobile && isMobileLayout;
|
||||
|
||||
// We have 3 view states:
|
||||
// - default desktop layout (just an extra wrapper)
|
||||
|
|
@ -92,7 +91,7 @@ class ModalInMobile extends Component {
|
|||
className={classes}
|
||||
contentClassName={css.modalContent}
|
||||
id={id}
|
||||
isOpen={isOpenInMobile}
|
||||
isOpen={isOpen}
|
||||
isClosedClassName={closedClassName}
|
||||
onClose={this.handleClose}
|
||||
onManageDisableScrolling={onManageDisableScrolling}
|
||||
|
|
@ -103,16 +102,16 @@ class ModalInMobile extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
ModalInMobile.defaultProps = {
|
||||
ModalInMobileComponent.defaultProps = {
|
||||
children: null,
|
||||
className: '',
|
||||
onClose: null,
|
||||
showAsModalMaxWidth: 0,
|
||||
};
|
||||
|
||||
const { bool, func, node, number, string } = PropTypes;
|
||||
const { bool, func, node, number, string, shape } = PropTypes;
|
||||
|
||||
ModalInMobile.propTypes = {
|
||||
ModalInMobileComponent.propTypes = {
|
||||
children: node,
|
||||
className: string,
|
||||
id: string.isRequired,
|
||||
|
|
@ -121,6 +120,14 @@ ModalInMobile.propTypes = {
|
|||
showAsModalMaxWidth: number,
|
||||
// eslint-disable-next-line react/no-unused-prop-types
|
||||
onManageDisableScrolling: func.isRequired,
|
||||
|
||||
// from withViewport
|
||||
viewport: shape({
|
||||
width: number.isRequired,
|
||||
height: number.isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
const ModalInMobile = withViewport(ModalInMobileComponent);
|
||||
|
||||
export default ModalInMobile;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { pickBy } from 'lodash';
|
|||
import classNames from 'classnames';
|
||||
import { Button, Modal, NamedLink, TopbarDesktop, TopbarMobileMenu } from '../../components';
|
||||
import { TopbarSearchForm } from '../../containers';
|
||||
import { withFlattenedRoutes } from '../../util/contextHelpers';
|
||||
import { withFlattenedRoutes, withViewport } from '../../util/contextHelpers';
|
||||
import { parse, stringify } from '../../util/urlHelpers';
|
||||
import { ensureUser } from '../../util/data';
|
||||
import { createResourceLocatorString, pathByRouteName } from '../../util/routes';
|
||||
|
|
@ -16,6 +16,8 @@ import LogoIcon from './LogoIcon';
|
|||
import SearchIcon from './SearchIcon';
|
||||
import css from './Topbar.css';
|
||||
|
||||
const maxMobileScreenWidth = 768;
|
||||
|
||||
const redirectToURLWithModalState = (props, modalStateParam) => {
|
||||
const { history, location } = props;
|
||||
const { pathname, search, state } = location;
|
||||
|
|
@ -89,6 +91,7 @@ class TopbarComponent extends Component {
|
|||
currentUser,
|
||||
currentUserHasListings,
|
||||
notificationCount,
|
||||
viewport,
|
||||
intl,
|
||||
location,
|
||||
onManageDisableScrolling,
|
||||
|
|
@ -103,8 +106,10 @@ class TopbarComponent extends Component {
|
|||
|
||||
const notificationDot = notificationCount > 0 ? <div className={css.notificationDot} /> : null;
|
||||
|
||||
const isMobileMenuOpen = mobilemenu === 'open';
|
||||
const isMobileSearchOpen = mobilesearch === 'open';
|
||||
const isMobileLayout = viewport.width < maxMobileScreenWidth;
|
||||
const isMobileMenuOpen = isMobileLayout && mobilemenu === 'open';
|
||||
const isMobileSearchOpen = isMobileLayout && mobilesearch === 'open';
|
||||
|
||||
const mobileMenu = (
|
||||
<TopbarMobileMenu
|
||||
isAuthenticated={isAuthenticated}
|
||||
|
|
@ -223,6 +228,12 @@ TopbarComponent.propTypes = {
|
|||
search: string.isRequired,
|
||||
}).isRequired,
|
||||
|
||||
// from withViewport
|
||||
viewport: shape({
|
||||
width: number.isRequired,
|
||||
height: number.isRequired,
|
||||
}).isRequired,
|
||||
|
||||
// from withFlattenedRoutes
|
||||
flattenedRoutes: arrayOf(propTypes.route).isRequired,
|
||||
|
||||
|
|
@ -230,7 +241,7 @@ TopbarComponent.propTypes = {
|
|||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
const Topbar = compose(withFlattenedRoutes, injectIntl)(TopbarComponent);
|
||||
const Topbar = compose(withViewport, withFlattenedRoutes, injectIntl)(TopbarComponent);
|
||||
|
||||
Topbar.displayName = 'Topbar';
|
||||
|
||||
|
|
|
|||
|
|
@ -130,8 +130,7 @@ exports[`ListingPage matches snapshot 1`] = `
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ModalInMobile
|
||||
className=""
|
||||
<withViewport(ModalInMobileComponent)
|
||||
id="BookingDatesFormInModal"
|
||||
isModalOpenOnMobile={false}
|
||||
onClose={[Function]}
|
||||
|
|
@ -177,7 +176,7 @@ exports[`ListingPage matches snapshot 1`] = `
|
|||
"currency": "USD",
|
||||
}
|
||||
} />
|
||||
</ModalInMobile>
|
||||
</withViewport(ModalInMobileComponent)>
|
||||
<div>
|
||||
<div>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -62,18 +62,15 @@ exports[`SearchPageComponent matches snapshot 1`] = `
|
|||
search={Object {}} />
|
||||
</div>
|
||||
</div>
|
||||
<ModalInMobile
|
||||
className=""
|
||||
<withViewport(ModalInMobileComponent)
|
||||
id="SearchPage.map"
|
||||
isModalOpenOnMobile={false}
|
||||
onClose={null}
|
||||
onManageDisableScrolling={[Function]}
|
||||
showAsModalMaxWidth={0}>
|
||||
onManageDisableScrolling={[Function]}>
|
||||
<div>
|
||||
<InjectIntl(SearchMapComponent)
|
||||
listings={Array []} />
|
||||
</div>
|
||||
</ModalInMobile>
|
||||
</withViewport(ModalInMobileComponent)>
|
||||
</div>
|
||||
</withRouter(PageLayout)>
|
||||
`;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue