Skip to content

Instantly share code, notes, and snippets.

@romanlex
Created November 28, 2017 07:24
Show Gist options
  • Save romanlex/7123db9e893a9d21565fb454317322c8 to your computer and use it in GitHub Desktop.
Save romanlex/7123db9e893a9d21565fb454317322c8 to your computer and use it in GitHub Desktop.
import React, {Component, PureComponent} from 'react';
import PropTypes from 'prop-types';
import { spring, Motion, presets } from 'react-motion';
import Modal from 'react-modal';
const portalClassName = "modal-portal";
const bodyOpenClassName = "modal-opened";
export const MODAL_VERTICAL_POSITIONS = {
TOP: 'top',
CENTER: 'center',
BOTTOM: 'bottom'
};
class MotionModal extends Component {
static scrollPositions = {};
static hasVScroll = {};
constructor(props) {
super(props);
}
componentWillUpdate() {
this.scrollPositions = { x: window.pageXOffset, y: window.pageYOffset };
this.hasVScroll = { scroll: document.body.scrollHeight };
}
render() {
const { isOpen, modalVerticalAlign, overlayClassName, offset } = this.props;
const overlayClasses = {
...overlayClassName
};
switch (modalVerticalAlign) {
case MODAL_VERTICAL_POSITIONS.TOP:
overlayClasses.base = `${overlayClasses.base} ${overlayClasses.base}--top`;
break;
case MODAL_VERTICAL_POSITIONS.BOTTOM:
overlayClasses.base = `${overlayClasses.base} ${overlayClasses.base}--bottom`;
break;
}
// if(offset) {
// console.log(this.modalContent);
// }
return (
<Modal {...this.props}
overlayClassName={overlayClasses}>
<Motion defaultStyle={{ translateY: -250, opacity: 0 }}
style={{ translateY: spring(isOpen ? 0 : -250, presets.stiff), opacity: spring(isOpen ? 1 : 0, presets.stiff) }}>
{({translateY, opacity}) => {
console.log(this.modalContent);
return <div ref={modal => this.modalContent = modal}
style={{transform: `translateY(${translateY}px`, opacity: opacity, display: 'block'}}
className={`motion-modal`}>
{this.props.children}
</div>
}}
</Motion>
</Modal>
);
}
}
MotionModal.propTypes = {
children: PropTypes.any.isRequired,
modalVerticalAlign: PropTypes.string,
offset: PropTypes.func,
// React-modal
isOpen: PropTypes.bool.isRequired,
style: PropTypes.shape({
content: PropTypes.object,
overlay: PropTypes.object
}),
portalClassName: PropTypes.string,
bodyOpenClassName: PropTypes.string,
className: PropTypes.oneOfType([
PropTypes.string,
PropTypes.shape({
base: PropTypes.string.isRequired,
afterOpen: PropTypes.string.isRequired,
beforeClose: PropTypes.string.isRequired
})
]),
overlayClassName: PropTypes.oneOfType([
PropTypes.string,
PropTypes.shape({
base: PropTypes.string.isRequired,
afterOpen: PropTypes.string.isRequired,
beforeClose: PropTypes.string.isRequired
})
]),
onAfterOpen: PropTypes.func,
onRequestClose: PropTypes.func,
closeTimeoutMS: PropTypes.number,
ariaHideApp: PropTypes.bool,
shouldFocusAfterRender: PropTypes.bool,
shouldCloseOnOverlayClick: PropTypes.bool,
shouldReturnFocusAfterClose: PropTypes.bool,
parentSelector: PropTypes.func,
aria: PropTypes.object,
role: PropTypes.string,
contentLabel: PropTypes.string,
shouldCloseOnEsc: PropTypes.bool
};
MotionModal.defaultProps = {
modalVerticalAlign: 'center',
isOpen: false,
portalClassName,
bodyOpenClassName,
ariaHideApp: true,
closeTimeoutMS: 0,
className: {
base: 'motion-modal-wrapper',
afterOpen: 'motion-modal-wrapper--after-open',
beforeClose: 'motion-modal-wrapper--before-close'
},
overlayClassName: {
base: 'modal-overlay',
afterOpen: 'modal-overlay--after-open',
beforeClose: 'modal-overlay--before-close',
},
shouldFocusAfterRender: true,
shouldCloseOnEsc: true,
shouldCloseOnOverlayClick: true,
shouldReturnFocusAfterClose: true,
parentSelector() {
return document.body;
}
};
export default MotionModal;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment