diff --git a/src/js/components/modal.jsx b/src/js/components/modal.jsx index ab4c03f4..e6a956b0 100644 --- a/src/js/components/modal.jsx +++ b/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 { this.contentRef = contentRef; } } - parentSelector={ () => document.querySelector('.zotero-bib-container') } - appElement={ document.querySelector('.zotero-bib-inner') } - className="modal" - overlayClassName="modal-backdrop" - { ...this.props } - />; - } + return { 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);