diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js index efc9e432cba8..782ad82f643c 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js @@ -1,70 +1,69 @@ -import React from 'react'; +import React, {useCallback, useEffect, useRef} from 'react'; import _ from 'underscore'; -import withLocalize from '../../../withLocalize'; + +import ControlSelection from '../../../../libs/ControlSelection'; +import * as DeviceCapabilities from '../../../../libs/DeviceCapabilities'; import htmlRendererPropTypes from '../htmlRendererPropTypes'; import BasePreRenderer from './BasePreRenderer'; -import * as DeviceCapabilities from '../../../../libs/DeviceCapabilities'; -import ControlSelection from '../../../../libs/ControlSelection'; - -class PreRenderer extends React.Component { - constructor(props) { - super(props); - this.scrollNode = this.scrollNode.bind(this); - this.debouncedIsScrollingVertically = _.debounce(this.isScrollingVertically.bind(this), 100, true); - } +const isScrollingVertically = (event) => + // Mark as vertical scrolling only when absolute value of deltaY is more than the double of absolute + // value of deltaX, so user can use trackpad scroll on the code block horizontally at a wide angle. + Math.abs(event.deltaY) > Math.abs(event.deltaX) * 2; - componentDidMount() { - if (!this.ref) { - return; - } - this.ref.getScrollableNode().addEventListener('wheel', this.scrollNode); - } +const debouncedIsScrollingVertically = _.debounce(isScrollingVertically, 100, true); - componentWillUnmount() { - this.ref.getScrollableNode().removeEventListener('wheel', this.scrollNode); - } +function PreRenderer(props) { + const scrollViewRef = useRef(); /** - * Check if user is scrolling vertically based on deltaX and deltaY. We debounce this - * method in the constructor to make sure it's called only for the first event. + * Checks if user is scrolling vertically based on deltaX and deltaY. We debounce this + * method in order to make sure it's called only for the first event. * @param {WheelEvent} event Wheel event * @returns {Boolean} true if user is scrolling vertically */ - isScrollingVertically(event) { - // Mark as vertical scrolling only when absolute value of deltaY is more than the double of absolute - // value of deltaX, so user can use trackpad scroll on the code block horizontally at a wide angle. - return Math.abs(event.deltaY) > Math.abs(event.deltaX) * 2; - } /** * Manually scrolls the code block if code block horizontal scrollable, then prevents the event from being passed up to the parent. * @param {Object} event native event */ - scrollNode(event) { - const node = this.ref.getScrollableNode(); + const scrollNode = useCallback((event) => { + const node = scrollViewRef.current.getScrollableNode(); const horizontalOverflow = node.scrollWidth > node.offsetWidth; - const isScrollingVertically = this.debouncedIsScrollingVertically(event); - if (event.currentTarget === node && horizontalOverflow && !isScrollingVertically) { + if (event.currentTarget === node && horizontalOverflow && !debouncedIsScrollingVertically(event)) { node.scrollLeft += event.deltaX; event.preventDefault(); event.stopPropagation(); } - } + }, []); + + useEffect(() => { + const eventListenerRefValue = scrollViewRef.current; + if (!eventListenerRefValue) { + return; + } + eventListenerRefValue.getScrollableNode().addEventListener('wheel', scrollNode); + + return () => { + if (!eventListenerRefValue.getScrollableNode()) { + return; + } + eventListenerRefValue.getScrollableNode().removeEventListener('wheel', scrollNode); + }; + }, [scrollNode]); - render() { - return ( - (this.ref = el)} - onPressIn={() => DeviceCapabilities.canUseTouchScreen() && ControlSelection.block()} - onPressOut={() => ControlSelection.unblock()} - /> - ); - } + return ( + DeviceCapabilities.canUseTouchScreen() && ControlSelection.block()} + onPressOut={ControlSelection.unblock} + /> + ); } PreRenderer.propTypes = htmlRendererPropTypes; +PreRenderer.displayName = 'PreRenderer'; -export default withLocalize(PreRenderer); +export default PreRenderer;