diff --git a/src/components/Modal/types.ts b/src/components/Modal/types.ts index 3fa60e6ac765..ebe55d9b7469 100644 --- a/src/components/Modal/types.ts +++ b/src/components/Modal/types.ts @@ -64,3 +64,4 @@ type BaseModalProps = WindowDimensionsProps & }; export default BaseModalProps; +export type {PopoverAnchorPosition}; diff --git a/src/components/Popover/index.native.js b/src/components/Popover/index.native.js deleted file mode 100644 index c8d37c2ad61c..000000000000 --- a/src/components/Popover/index.native.js +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react'; -import _ from 'underscore'; -import Modal from '@components/Modal'; -import {windowDimensionsPropTypes} from '@components/withWindowDimensions'; -import CONST from '@src/CONST'; -import {defaultProps, propTypes as popoverPropTypes} from './popoverPropTypes'; - -const propTypes = { - ..._.omit(popoverPropTypes, _.keys(windowDimensionsPropTypes)), -}; - -/* - * This is a convenience wrapper around the Modal component for a responsive Popover. - * On small screen widths, it uses BottomDocked modal type, and a Popover type on wide screen widths. - */ -function Popover(props) { - const propsWithoutAnimation = _.omit(props, ['animationIn', 'animationOut', 'popoverAnchorPosition', 'disableAnimation']); - return ( - - ); -} - -Popover.propTypes = propTypes; -Popover.defaultProps = defaultProps; -Popover.displayName = 'Popover'; - -export default Popover; diff --git a/src/components/Popover/index.native.tsx b/src/components/Popover/index.native.tsx new file mode 100644 index 000000000000..3fff04d00d2f --- /dev/null +++ b/src/components/Popover/index.native.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import Modal from '@components/Modal'; +import CONST from '@src/CONST'; +import {PopoverProps} from './types'; + +/* + * This is a convenience wrapper around the Modal component for a responsive Popover. + * On small screen widths, it uses BottomDocked modal type, and a Popover type on wide screen widths. + */ +function Popover({animationIn, animationOut, popoverAnchorPosition, disableAnimation, anchorPosition = {}, fromSidebarMediumScreen, ...propsWithoutAnimation}: PopoverProps) { + return ( + + ); +} + +Popover.displayName = 'Popover'; + +export default Popover; diff --git a/src/components/Popover/index.js b/src/components/Popover/index.tsx similarity index 78% rename from src/components/Popover/index.js rename to src/components/Popover/index.tsx index b8889e806629..bf79415d4794 100644 --- a/src/components/Popover/index.js +++ b/src/components/Popover/index.tsx @@ -5,14 +5,30 @@ import {PopoverContext} from '@components/PopoverProvider'; import PopoverWithoutOverlay from '@components/PopoverWithoutOverlay'; import withWindowDimensions from '@components/withWindowDimensions'; import CONST from '@src/CONST'; -import {defaultProps, propTypes} from './popoverPropTypes'; +import {PopoverWithWindowDimensionsProps} from './types'; /* * This is a convenience wrapper around the Modal component for a responsive Popover. * On small screen widths, it uses BottomDocked modal type, and a Popover type on wide screen widths. */ -function Popover(props) { - const {isVisible, onClose, isSmallScreenWidth, fullscreen, animationInTiming, onLayout, animationOutTiming, disableAnimation, withoutOverlay, anchorPosition, anchorRef} = props; + +function Popover(props: PopoverWithWindowDimensionsProps) { + const { + isVisible, + onClose, + isSmallScreenWidth, + fullscreen, + animationInTiming = CONST.ANIMATED_TRANSITION, + onLayout, + animationOutTiming, + disableAnimation = true, + withoutOverlay, + anchorPosition = {}, + anchorRef = () => {}, + animationIn = 'fadeIn', + animationOut = 'fadeOut', + } = props; + const withoutOverlayRef = useRef(null); const {close, popover} = React.useContext(PopoverContext); @@ -33,7 +49,7 @@ function Popover(props) { }, [onClose, isVisible]); const onCloseWithPopoverContext = () => { - if (popover) { + if (popover && 'current' in anchorRef) { close(anchorRef); } onClose(); @@ -51,6 +67,8 @@ function Popover(props) { animationOutTiming={disableAnimation ? 1 : animationOutTiming} shouldCloseOnOutsideClick onLayout={onLayout} + animationIn={animationIn} + animationOut={animationOut} />, document.body, ); @@ -62,6 +80,8 @@ function Popover(props) { // eslint-disable-next-line react/jsx-props-no-spreading {...props} withoutOverlayRef={withoutOverlayRef} + animationIn={animationIn} + animationOut={animationOut} />, document.body, ); @@ -78,12 +98,12 @@ function Popover(props) { animationInTiming={disableAnimation && !isSmallScreenWidth ? 1 : animationInTiming} animationOutTiming={disableAnimation && !isSmallScreenWidth ? 1 : animationOutTiming} onLayout={onLayout} + animationIn={animationIn} + animationOut={animationOut} /> ); } -Popover.propTypes = propTypes; -Popover.defaultProps = defaultProps; Popover.displayName = 'Popover'; export default withWindowDimensions(Popover); diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts new file mode 100644 index 000000000000..7f7e2829770c --- /dev/null +++ b/src/components/Popover/types.ts @@ -0,0 +1,42 @@ +import BaseModalProps, {PopoverAnchorPosition} from '@components/Modal/types'; +import {WindowDimensionsProps} from '@components/withWindowDimensions/types'; + +type AnchorAlignment = {horizontal: string; vertical: string}; + +type PopoverDimensions = { + width: number; + height: number; +}; + +type PopoverProps = BaseModalProps & { + /** The anchor position of the popover */ + anchorPosition?: PopoverAnchorPosition; + + /** The anchor alignment of the popover */ + anchorAlignment: AnchorAlignment; + + /** The anchor ref of the popover */ + anchorRef: React.RefObject; + + /** Whether disable the animations */ + disableAnimation: boolean; + + /** Whether we don't want to show overlay */ + withoutOverlay: boolean; + + /** The dimensions of the popover */ + popoverDimensions?: PopoverDimensions; + + /** The ref of the popover */ + withoutOverlayRef?: React.RefObject; + + /** Whether we want to show the popover on the right side of the screen */ + fromSidebarMediumScreen?: boolean; + + /** The popover children */ + children: React.ReactNode; +}; + +type PopoverWithWindowDimensionsProps = PopoverProps & WindowDimensionsProps; + +export type {PopoverProps, PopoverWithWindowDimensionsProps};