Skip to content

Commit

Permalink
Refactor Modal component
Browse files Browse the repository at this point in the history
  • Loading branch information
tnajdek committed Jun 12, 2021
1 parent 168c88c commit bedaa73
Showing 1 changed file with 53 additions and 60 deletions.
113 changes: 53 additions & 60 deletions src/js/components/modal.jsx
@@ -1,76 +1,69 @@
/* eslint-disable react/no-deprecated */
// @TODO: migrate to getDerivedStateFromProps()
import React from 'react';
import React, { useCallback, useEffect, useRef, memo } from 'react';
import PropTypes from 'prop-types';
import ReactModal from 'react-modal';

var initialPadding;
import { usePrevious } from '../hooks';

class Modal extends React.PureComponent {
componentWillReceiveProps(props) {
if(props.isOpen != this.props.isOpen && props.isOpen === true) {
this.setScrollbar();
}
if(props.isOpen != this.props.isOpen && props.isOpen === false) {
this.resetScrollbar();
}
}
var initialPadding = parseFloat(document.body.style.paddingRight);
initialPadding = Number.isNaN(initialPadding) ? 0 : initialPadding;

checkScrollbar() {
const rect = document.body.getBoundingClientRect();
return rect.left + rect.right < window.innerWidth;
}
const getScrollbarWidth = () => {
const scrollDiv = document.createElement('div');
scrollDiv.className = 'modal-scrollbar-measure';
document.body.appendChild(scrollDiv);
const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
document.body.removeChild(scrollDiv);
return scrollbarWidth;
}

getScrollbarWidth() {
const scrollDiv = document.createElement('div');
scrollDiv.className = 'modal-scrollbar-measure';
document.body.appendChild(scrollDiv);
const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
document.body.removeChild(scrollDiv);
return scrollbarWidth;
}
const setScrollbar = () => {
const calculatedPadding = initialPadding + getScrollbarWidth();
document.body.style.paddingRight = `${calculatedPadding}px`;
}

setScrollbar() {
const calculatedPadding = this.initialPadding + this.getScrollbarWidth();
document.body.style.paddingRight = `${calculatedPadding}px`;
}
const resetScrollbar = () => {
document.body.style.paddingRight = `${initialPadding}px`;
}

resetScrollbar() {
document.body.style.paddingRight = `${this.initialPadding}px`;
}
const Modal = props => {
const { isOpen } = props;
const contentRef = useRef(null);
const wasOpen = usePrevious(isOpen);

handleModalOpen() {
const handleModalOpen = useCallback(() => {
// remove maxHeight hack that prevents scroll on focus
this.contentRef.style.maxHeight = null;
this.contentRef.style.overflowY = null;
}
contentRef.current.style.maxHeight = null;
contentRef.current.style.overflowY = null;
}, []);

get initialPadding() {
if(typeof initialPadding === 'undefined') {
initialPadding = parseFloat(document.body.style.paddingRight);
initialPadding = Number.isNaN(initialPadding) ? 0 : initialPadding;
useEffect(() => {
if(isOpen && !wasOpen) {
setScrollbar();
} else if(wasOpen && !isOpen) {
resetScrollbar();
}
return initialPadding;
}
}, [isOpen, wasOpen])

useEffect(() => {
return resetScrollbar;
}, []);

render() {
return <ReactModal
role="dialog"
// prevent scroll on focus by setting max height
style={{ content: { maxHeight: 'calc(100% - 32px)', overflowY: 'hidden' } }}
onAfterOpen={ this.handleModalOpen.bind(this) }
contentRef={ contentRef => { this.contentRef = contentRef; } }
parentSelector={ () => document.querySelector('.zotero-bib-container') }
appElement={ document.querySelector('.zotero-bib-inner') }
className="modal"
overlayClassName="modal-backdrop"
{ ...this.props }
/>;
}
return <ReactModal
role="dialog"
// prevent scroll on focus by setting max height
style={{ content: { maxHeight: 'calc(100% - 32px)', overflowY: 'hidden' } }}
onAfterOpen={ handleModalOpen }
contentRef={ ref => { contentRef.current = ref; } }
parentSelector={ () => document.querySelector('.zotero-bib-container') }
appElement={ document.querySelector('.zotero-bib-inner') }
className="modal-body"
overlayClassName="modal-backdrop"
{ ...props }
/>;
}

static propTypes = {
isOpen: PropTypes.bool
}
Modal.propTypes = {
isOpen: PropTypes.bool
}

export default Modal;
export default memo(Modal);

0 comments on commit bedaa73

Please sign in to comment.