diff --git a/src/components/EmojiPicker/EmojiPicker.js b/src/components/EmojiPicker/EmojiPicker.js index a12b089ddf97..8b32234fdbdf 100644 --- a/src/components/EmojiPicker/EmojiPicker.js +++ b/src/components/EmojiPicker/EmojiPicker.js @@ -1,12 +1,13 @@ import React, {useState, useEffect, useRef, forwardRef, useImperativeHandle} from 'react'; import {Dimensions} from 'react-native'; import _ from 'underscore'; +import PropTypes from 'prop-types'; import EmojiPickerMenu from './EmojiPickerMenu'; import CONST from '../../CONST'; import styles from '../../styles/styles'; import PopoverWithMeasuredContent from '../PopoverWithMeasuredContent'; import withWindowDimensions, {windowDimensionsPropTypes} from '../withWindowDimensions'; -import withViewportOffsetTop, {viewportOffsetTopPropTypes} from '../withViewportOffsetTop'; +import withViewportOffsetTop from '../withViewportOffsetTop'; import compose from '../../libs/compose'; import * as StyleUtils from '../../styles/StyleUtils'; import calculateAnchorPosition from '../../libs/calculateAnchorPosition'; @@ -18,7 +19,7 @@ const DEFAULT_ANCHOR_ORIGIN = { const propTypes = { ...windowDimensionsPropTypes, - ...viewportOffsetTopPropTypes, + viewportOffsetTop: PropTypes.number.isRequired, }; const EmojiPicker = forwardRef((props, ref) => { diff --git a/src/components/withViewportOffsetTop.js b/src/components/withViewportOffsetTop.js deleted file mode 100644 index ccf928b3bd13..000000000000 --- a/src/components/withViewportOffsetTop.js +++ /dev/null @@ -1,61 +0,0 @@ -import React, {useEffect, forwardRef, useState} from 'react'; -import PropTypes from 'prop-types'; -import lodashGet from 'lodash/get'; -import getComponentDisplayName from '../libs/getComponentDisplayName'; -import addViewportResizeListener from '../libs/VisualViewport'; -import refPropTypes from './refPropTypes'; - -const viewportOffsetTopPropTypes = { - // viewportOffsetTop returns the offset of the top edge of the visual viewport from the - // top edge of the layout viewport in CSS pixels, when the visual viewport is resized. - - viewportOffsetTop: PropTypes.number.isRequired, -}; - -export default function (WrappedComponent) { - function WithViewportOffsetTop(props) { - const [viewportOffsetTop, setViewportOffsetTop] = useState(0); - - useEffect(() => { - /** - * @param {SyntheticEvent} e - */ - const updateDimensions = (e) => { - const targetOffsetTop = lodashGet(e, 'target.offsetTop', 0); - setViewportOffsetTop(targetOffsetTop); - }; - - const removeViewportResizeListener = addViewportResizeListener(updateDimensions); - - return () => { - removeViewportResizeListener(); - }; - }, []); - - return ( - - ); - } - - WithViewportOffsetTop.displayName = `WithViewportOffsetTop(${getComponentDisplayName(WrappedComponent)})`; - WithViewportOffsetTop.propTypes = { - forwardedRef: refPropTypes, - }; - WithViewportOffsetTop.defaultProps = { - forwardedRef: undefined, - }; - return forwardRef((props, ref) => ( - - )); -} - -export {viewportOffsetTopPropTypes}; diff --git a/src/components/withViewportOffsetTop.tsx b/src/components/withViewportOffsetTop.tsx new file mode 100644 index 000000000000..e2e1dc2d3484 --- /dev/null +++ b/src/components/withViewportOffsetTop.tsx @@ -0,0 +1,41 @@ +import React, {useEffect, forwardRef, useState, ComponentType, RefAttributes, ForwardedRef} from 'react'; +import getComponentDisplayName from '../libs/getComponentDisplayName'; +import addViewportResizeListener from '../libs/VisualViewport'; + +type ViewportOffsetTopProps = { + // viewportOffsetTop returns the offset of the top edge of the visual viewport from the + // top edge of the layout viewport in CSS pixels, when the visual viewport is resized. + viewportOffsetTop: number; +}; + +export default function withViewportOffsetTop(WrappedComponent: ComponentType>) { + function WithViewportOffsetTop(props: Omit, ref: ForwardedRef) { + const [viewportOffsetTop, setViewportOffsetTop] = useState(0); + + useEffect(() => { + const updateDimensions = (event: Event) => { + const targetOffsetTop = (event.target instanceof VisualViewport && event.target.offsetTop) || 0; + setViewportOffsetTop(targetOffsetTop); + }; + + const removeViewportResizeListener = addViewportResizeListener(updateDimensions); + + return () => { + removeViewportResizeListener(); + }; + }, []); + + return ( + + ); + } + + WithViewportOffsetTop.displayName = `WithViewportOffsetTop(${getComponentDisplayName(WrappedComponent)})`; + + return forwardRef(WithViewportOffsetTop); +} diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 6ec7cdf81821..81000c2dab92 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -26,7 +26,7 @@ import Banner from '../../components/Banner'; import reportPropTypes from '../reportPropTypes'; import reportMetadataPropTypes from '../reportMetadataPropTypes'; import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView'; -import withViewportOffsetTop, {viewportOffsetTopPropTypes} from '../../components/withViewportOffsetTop'; +import withViewportOffsetTop from '../../components/withViewportOffsetTop'; import * as ReportActionsUtils from '../../libs/ReportActionsUtils'; import personalDetailsPropType from '../personalDetailsPropType'; import getIsReportFullyVisible from '../../libs/getIsReportFullyVisible'; @@ -94,7 +94,7 @@ const propTypes = { /** Whether user is leaving the current report */ userLeavingStatus: PropTypes.bool, - ...viewportOffsetTopPropTypes, + viewportOffsetTop: PropTypes.number.isRequired, ...withCurrentReportIDPropTypes, };