From 92726b4ffdcb014ae74a3377e35a1c9e5fcbb70e Mon Sep 17 00:00:00 2001 From: Jakub Butkiewicz Date: Wed, 18 Oct 2023 19:40:59 +0200 Subject: [PATCH 1/9] ref: removed ConfirmPopover since its not used anywhere --- src/components/ConfirmPopover.js | 85 -------------------------------- 1 file changed, 85 deletions(-) delete mode 100644 src/components/ConfirmPopover.js diff --git a/src/components/ConfirmPopover.js b/src/components/ConfirmPopover.js deleted file mode 100644 index 88df6347f850..000000000000 --- a/src/components/ConfirmPopover.js +++ /dev/null @@ -1,85 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import Popover from './Popover'; -import withWindowDimensions, {windowDimensionsPropTypes} from './withWindowDimensions'; -import ConfirmContent from './ConfirmContent'; - -const propTypes = { - /** Title of the modal */ - title: PropTypes.string.isRequired, - - /** A callback to call when the form has been submitted */ - onConfirm: PropTypes.func.isRequired, - - /** A callback to call when the form has been closed */ - onCancel: PropTypes.func, - - /** Modal visibility */ - isVisible: PropTypes.bool.isRequired, - - /** Confirm button text */ - confirmText: PropTypes.string, - - /** Cancel button text */ - cancelText: PropTypes.string, - - /** Is the action destructive */ - danger: PropTypes.bool, - - /** Whether we should show the cancel button */ - shouldShowCancelButton: PropTypes.bool, - - /** Modal content text/element */ - prompt: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), - - /** Where the popover should be positioned */ - anchorPosition: PropTypes.shape({ - top: PropTypes.number, - left: PropTypes.number, - }).isRequired, - - /** Styles for view */ - // eslint-disable-next-line react/forbid-prop-types - contentStyles: PropTypes.arrayOf(PropTypes.object), - - ...windowDimensionsPropTypes, -}; - -const defaultProps = { - confirmText: '', - cancelText: '', - danger: false, - onCancel: () => {}, - shouldShowCancelButton: true, - prompt: '', - contentStyles: [], -}; - -function ConfirmPopover(props) { - return ( - - - - ); -} - -ConfirmPopover.propTypes = propTypes; -ConfirmPopover.defaultProps = defaultProps; -ConfirmPopover.displayName = 'ConfirmPopover'; -export default withWindowDimensions(ConfirmPopover); From 1c11c8f0ea9629a69f4f1916d81f46d263fce71c Mon Sep 17 00:00:00 2001 From: Jakub Butkiewicz Date: Tue, 31 Oct 2023 10:31:32 +0100 Subject: [PATCH 2/9] ref: started migrating Popover and ConfirmPopover to TS --- src/components/ConfirmPopover.js | 85 ------------------- src/components/ConfirmPopover.tsx | 63 ++++++++++++++ .../{index.native.js => index.native.tsx} | 0 .../Popover/{index.js => index.tsx} | 31 ++++++- src/components/Popover/types.ts | 0 5 files changed, 93 insertions(+), 86 deletions(-) delete mode 100644 src/components/ConfirmPopover.js create mode 100644 src/components/ConfirmPopover.tsx rename src/components/Popover/{index.native.js => index.native.tsx} (100%) rename src/components/Popover/{index.js => index.tsx} (79%) create mode 100644 src/components/Popover/types.ts diff --git a/src/components/ConfirmPopover.js b/src/components/ConfirmPopover.js deleted file mode 100644 index 83001736b471..000000000000 --- a/src/components/ConfirmPopover.js +++ /dev/null @@ -1,85 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import ConfirmContent from './ConfirmContent'; -import Popover from './Popover'; -import withWindowDimensions, {windowDimensionsPropTypes} from './withWindowDimensions'; - -const propTypes = { - /** Title of the modal */ - title: PropTypes.string.isRequired, - - /** A callback to call when the form has been submitted */ - onConfirm: PropTypes.func.isRequired, - - /** A callback to call when the form has been closed */ - onCancel: PropTypes.func, - - /** Modal visibility */ - isVisible: PropTypes.bool.isRequired, - - /** Confirm button text */ - confirmText: PropTypes.string, - - /** Cancel button text */ - cancelText: PropTypes.string, - - /** Is the action destructive */ - danger: PropTypes.bool, - - /** Whether we should show the cancel button */ - shouldShowCancelButton: PropTypes.bool, - - /** Modal content text/element */ - prompt: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), - - /** Where the popover should be positioned */ - anchorPosition: PropTypes.shape({ - top: PropTypes.number, - left: PropTypes.number, - }).isRequired, - - /** Styles for view */ - // eslint-disable-next-line react/forbid-prop-types - contentStyles: PropTypes.arrayOf(PropTypes.object), - - ...windowDimensionsPropTypes, -}; - -const defaultProps = { - confirmText: '', - cancelText: '', - danger: false, - onCancel: () => {}, - shouldShowCancelButton: true, - prompt: '', - contentStyles: [], -}; - -function ConfirmPopover(props) { - return ( - - - - ); -} - -ConfirmPopover.propTypes = propTypes; -ConfirmPopover.defaultProps = defaultProps; -ConfirmPopover.displayName = 'ConfirmPopover'; -export default withWindowDimensions(ConfirmPopover); diff --git a/src/components/ConfirmPopover.tsx b/src/components/ConfirmPopover.tsx new file mode 100644 index 000000000000..aed459b11922 --- /dev/null +++ b/src/components/ConfirmPopover.tsx @@ -0,0 +1,63 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import ConfirmContent from './ConfirmContent'; +import Popover from './Popover'; +import withWindowDimensions from './withWindowDimensions'; + +type ConfirmPopoverProps = { + title: string; + onConfirm: () => void; + onCancel?: () => void; + isVisible: boolean; + confirmText?: string; + cancelText?: string; + danger?: boolean; + shouldShowCancelButton?: boolean; + prompt?: string | React.ReactNode; + anchorPosition: { + top: number; + left: number; + }; + contentStyles?: any[]; + // TODO: add props from withWindowDimensions +}; +function ConfirmPopover({ + title, + onConfirm, + onCancel = () => {}, + isVisible, + confirmText = '', + cancelText = '', + danger = false, + anchorPosition, + prompt = '', + shouldShowCancelButton = true, + contentStyles = [], +}: ConfirmPopoverProps) { + return ( + + + + ); +} + +ConfirmPopover.propTypes = propTypes; +ConfirmPopover.defaultProps = defaultProps; +ConfirmPopover.displayName = 'ConfirmPopover'; +export default withWindowDimensions(ConfirmPopover); diff --git a/src/components/Popover/index.native.js b/src/components/Popover/index.native.tsx similarity index 100% rename from src/components/Popover/index.native.js rename to src/components/Popover/index.native.tsx diff --git a/src/components/Popover/index.js b/src/components/Popover/index.tsx similarity index 79% rename from src/components/Popover/index.js rename to src/components/Popover/index.tsx index b8889e806629..07dbe4c7c98e 100644 --- a/src/components/Popover/index.js +++ b/src/components/Popover/index.tsx @@ -11,7 +11,36 @@ import {defaultProps, propTypes} from './popoverPropTypes'; * 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) { + +type PopoverProps = { + isVisible: boolean; + anchorPosition: { + top: number; + left: number; + bottom: number; + right: number; + }; + anchorRef: React.RefObject; + animationInTiming: number; + disableAnimation: boolean; + withoutOverlay: boolean; + fullscreen?: boolean; + shouldCloseOnOutsideClick?: boolean; + shouldSetModalVisibility?: boolean; + onClose: () => void; + children: React.ReactNode; + onSubmit?: () => void; + onModalHide?: () => void; + onModalShow?: () => void; + animationIn?: string | object; + animationOut?: string | object; + innerContainerStyle?: any[]; + statusBarTranslucent?: boolean; + avoidKeyboard?: boolean; + hideModalContentWhileAnimating?: boolean; +}; +function Popover(props: PopoverProps) { + console.log('Popover', props); const {isVisible, onClose, isSmallScreenWidth, fullscreen, animationInTiming, onLayout, animationOutTiming, disableAnimation, withoutOverlay, anchorPosition, anchorRef} = props; const withoutOverlayRef = useRef(null); const {close, popover} = React.useContext(PopoverContext); diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts new file mode 100644 index 000000000000..e69de29bb2d1 From f709815f0bb03368e213e4f344ea3a9bb457bc07 Mon Sep 17 00:00:00 2001 From: Jakub Butkiewicz Date: Tue, 31 Oct 2023 14:47:22 +0100 Subject: [PATCH 3/9] fix: added new props to type --- src/components/ConfirmPopover.tsx | 1 - src/components/Popover/index.tsx | 26 +++++++++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/components/ConfirmPopover.tsx b/src/components/ConfirmPopover.tsx index aed459b11922..c036ee988be9 100644 --- a/src/components/ConfirmPopover.tsx +++ b/src/components/ConfirmPopover.tsx @@ -1,4 +1,3 @@ -import PropTypes from 'prop-types'; import React from 'react'; import ConfirmContent from './ConfirmContent'; import Popover from './Popover'; diff --git a/src/components/Popover/index.tsx b/src/components/Popover/index.tsx index 07dbe4c7c98e..2fddfd01a1d6 100644 --- a/src/components/Popover/index.tsx +++ b/src/components/Popover/index.tsx @@ -1,5 +1,7 @@ import React, {useRef} from 'react'; import {createPortal} from 'react-dom'; +import {ViewStyle} from 'react-native'; +import {ModalProps} from 'react-native-modal'; import Modal from '@components/Modal'; import {PopoverContext} from '@components/PopoverProvider'; import PopoverWithoutOverlay from '@components/PopoverWithoutOverlay'; @@ -20,8 +22,8 @@ type PopoverProps = { bottom: number; right: number; }; + anchorAlignment: {horizontal: string; vertical: string}; anchorRef: React.RefObject; - animationInTiming: number; disableAnimation: boolean; withoutOverlay: boolean; fullscreen?: boolean; @@ -32,15 +34,29 @@ type PopoverProps = { onSubmit?: () => void; onModalHide?: () => void; onModalShow?: () => void; - animationIn?: string | object; - animationOut?: string | object; - innerContainerStyle?: any[]; + animationIn?: ModalProps['animationIn']; + animationInTiming?: number; + animationOut?: ModalProps['animationOut']; + animationOutTiming?: number; + innerContainerStyle?: ViewStyle; statusBarTranslucent?: boolean; avoidKeyboard?: boolean; hideModalContentWhileAnimating?: boolean; + isExtraSmallScreenWidth?: boolean; + isSmallScreenWidth?: boolean; + isMediumScreenWidth?: boolean; + isLargeScreenWidth?: boolean; + popoverDimensions?: { + width: number; + height: number; + }; + windowHeight?: number; + windowWidth?: number; + withoutOverlayRef?: React.RefObject; + outerStyle?: ViewStyle | Record; + onLayout?: () => void; }; function Popover(props: PopoverProps) { - console.log('Popover', props); const {isVisible, onClose, isSmallScreenWidth, fullscreen, animationInTiming, onLayout, animationOutTiming, disableAnimation, withoutOverlay, anchorPosition, anchorRef} = props; const withoutOverlayRef = useRef(null); const {close, popover} = React.useContext(PopoverContext); From 9543c0c230de207f1e3e0060b82ea44e36107ef8 Mon Sep 17 00:00:00 2001 From: Jakub Butkiewicz Date: Mon, 20 Nov 2023 14:43:06 +0100 Subject: [PATCH 4/9] fix: fix types problem in Popover --- src/components/ConfirmPopover.js | 85 ++++++++++++++++++++++ src/components/ConfirmPopover.tsx | 62 ---------------- src/components/Popover/index.native.tsx | 19 ++--- src/components/Popover/index.tsx | 82 +++++++-------------- src/components/Popover/popoverPropTypes.js | 45 ------------ src/components/Popover/types.ts | 28 +++++++ 6 files changed, 147 insertions(+), 174 deletions(-) create mode 100644 src/components/ConfirmPopover.js delete mode 100644 src/components/ConfirmPopover.tsx delete mode 100644 src/components/Popover/popoverPropTypes.js diff --git a/src/components/ConfirmPopover.js b/src/components/ConfirmPopover.js new file mode 100644 index 000000000000..83001736b471 --- /dev/null +++ b/src/components/ConfirmPopover.js @@ -0,0 +1,85 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import ConfirmContent from './ConfirmContent'; +import Popover from './Popover'; +import withWindowDimensions, {windowDimensionsPropTypes} from './withWindowDimensions'; + +const propTypes = { + /** Title of the modal */ + title: PropTypes.string.isRequired, + + /** A callback to call when the form has been submitted */ + onConfirm: PropTypes.func.isRequired, + + /** A callback to call when the form has been closed */ + onCancel: PropTypes.func, + + /** Modal visibility */ + isVisible: PropTypes.bool.isRequired, + + /** Confirm button text */ + confirmText: PropTypes.string, + + /** Cancel button text */ + cancelText: PropTypes.string, + + /** Is the action destructive */ + danger: PropTypes.bool, + + /** Whether we should show the cancel button */ + shouldShowCancelButton: PropTypes.bool, + + /** Modal content text/element */ + prompt: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), + + /** Where the popover should be positioned */ + anchorPosition: PropTypes.shape({ + top: PropTypes.number, + left: PropTypes.number, + }).isRequired, + + /** Styles for view */ + // eslint-disable-next-line react/forbid-prop-types + contentStyles: PropTypes.arrayOf(PropTypes.object), + + ...windowDimensionsPropTypes, +}; + +const defaultProps = { + confirmText: '', + cancelText: '', + danger: false, + onCancel: () => {}, + shouldShowCancelButton: true, + prompt: '', + contentStyles: [], +}; + +function ConfirmPopover(props) { + return ( + + + + ); +} + +ConfirmPopover.propTypes = propTypes; +ConfirmPopover.defaultProps = defaultProps; +ConfirmPopover.displayName = 'ConfirmPopover'; +export default withWindowDimensions(ConfirmPopover); diff --git a/src/components/ConfirmPopover.tsx b/src/components/ConfirmPopover.tsx deleted file mode 100644 index c036ee988be9..000000000000 --- a/src/components/ConfirmPopover.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React from 'react'; -import ConfirmContent from './ConfirmContent'; -import Popover from './Popover'; -import withWindowDimensions from './withWindowDimensions'; - -type ConfirmPopoverProps = { - title: string; - onConfirm: () => void; - onCancel?: () => void; - isVisible: boolean; - confirmText?: string; - cancelText?: string; - danger?: boolean; - shouldShowCancelButton?: boolean; - prompt?: string | React.ReactNode; - anchorPosition: { - top: number; - left: number; - }; - contentStyles?: any[]; - // TODO: add props from withWindowDimensions -}; -function ConfirmPopover({ - title, - onConfirm, - onCancel = () => {}, - isVisible, - confirmText = '', - cancelText = '', - danger = false, - anchorPosition, - prompt = '', - shouldShowCancelButton = true, - contentStyles = [], -}: ConfirmPopoverProps) { - return ( - - - - ); -} - -ConfirmPopover.propTypes = propTypes; -ConfirmPopover.defaultProps = defaultProps; -ConfirmPopover.displayName = 'ConfirmPopover'; -export default withWindowDimensions(ConfirmPopover); diff --git a/src/components/Popover/index.native.tsx b/src/components/Popover/index.native.tsx index c8d37c2ad61c..1b5321bce0df 100644 --- a/src/components/Popover/index.native.tsx +++ b/src/components/Popover/index.native.tsx @@ -1,24 +1,19 @@ 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)), -}; +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(props) { - const propsWithoutAnimation = _.omit(props, ['animationIn', 'animationOut', 'popoverAnchorPosition', 'disableAnimation']); +function Popover(props: PopoverProps) { + const {animationIn, animationOut, popoverAnchorPosition, disableAnimation, ...propsWithoutAnimation} = props; + const {anchorPosition = {}, fromSidebarMediumScreen} = propsWithoutAnimation; return ( ; - disableAnimation: boolean; - withoutOverlay: boolean; - fullscreen?: boolean; - shouldCloseOnOutsideClick?: boolean; - shouldSetModalVisibility?: boolean; - onClose: () => void; - children: React.ReactNode; - onSubmit?: () => void; - onModalHide?: () => void; - onModalShow?: () => void; - animationIn?: ModalProps['animationIn']; - animationInTiming?: number; - animationOut?: ModalProps['animationOut']; - animationOutTiming?: number; - innerContainerStyle?: ViewStyle; - statusBarTranslucent?: boolean; - avoidKeyboard?: boolean; - hideModalContentWhileAnimating?: boolean; - isExtraSmallScreenWidth?: boolean; - isSmallScreenWidth?: boolean; - isMediumScreenWidth?: boolean; - isLargeScreenWidth?: boolean; - popoverDimensions?: { - width: number; - height: number; - }; - windowHeight?: number; - windowWidth?: number; - withoutOverlayRef?: React.RefObject; - outerStyle?: ViewStyle | Record; - onLayout?: () => void; -}; -function Popover(props: PopoverProps) { - const {isVisible, onClose, isSmallScreenWidth, fullscreen, animationInTiming, onLayout, animationOutTiming, disableAnimation, withoutOverlay, anchorPosition, anchorRef} = props; +function Popover(props: PopoverPropsWithWindowDimensions) { + 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); @@ -78,7 +48,7 @@ function Popover(props: PopoverProps) { }, [onClose, isVisible]); const onCloseWithPopoverContext = () => { - if (popover) { + if (popover && 'current' in anchorRef) { close(anchorRef); } onClose(); @@ -92,10 +62,12 @@ function Popover(props: PopoverProps) { onClose={onCloseWithPopoverContext} type={CONST.MODAL.MODAL_TYPE.POPOVER} popoverAnchorPosition={anchorPosition} - animationInTiming={disableAnimation ? 1 : animationInTiming} - animationOutTiming={disableAnimation ? 1 : animationOutTiming} + animationInTiming={disableAnimation ? 1 : animationInTiming ?? 1} + animationOutTiming={disableAnimation ? 1 : animationOutTiming ?? 1} shouldCloseOnOutsideClick onLayout={onLayout} + animationIn={animationIn} + animationOut={animationOut} />, document.body, ); @@ -107,6 +79,8 @@ function Popover(props: PopoverProps) { // eslint-disable-next-line react/jsx-props-no-spreading {...props} withoutOverlayRef={withoutOverlayRef} + animationIn={animationIn} + animationOut={animationOut} />, document.body, ); @@ -120,15 +94,15 @@ function Popover(props: PopoverProps) { type={isSmallScreenWidth ? CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED : CONST.MODAL.MODAL_TYPE.POPOVER} popoverAnchorPosition={isSmallScreenWidth ? undefined : anchorPosition} fullscreen={isSmallScreenWidth ? true : fullscreen} - animationInTiming={disableAnimation && !isSmallScreenWidth ? 1 : animationInTiming} - animationOutTiming={disableAnimation && !isSmallScreenWidth ? 1 : animationOutTiming} + animationInTiming={disableAnimation && !isSmallScreenWidth ? 1 : animationInTiming ?? 1} + animationOutTiming={disableAnimation && !isSmallScreenWidth ? 1 : animationOutTiming ?? 1} 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/popoverPropTypes.js b/src/components/Popover/popoverPropTypes.js deleted file mode 100644 index c13fd8fa0b85..000000000000 --- a/src/components/Popover/popoverPropTypes.js +++ /dev/null @@ -1,45 +0,0 @@ -import PropTypes from 'prop-types'; -import _ from 'underscore'; -import {defaultProps as defaultModalProps, propTypes as modalPropTypes} from '@components/Modal/modalPropTypes'; -import refPropTypes from '@components/refPropTypes'; -import CONST from '@src/CONST'; - -const propTypes = { - ..._.omit(modalPropTypes, ['type', 'popoverAnchorPosition']), - - /** The anchor position of the popover */ - anchorPosition: PropTypes.shape({ - top: PropTypes.number, - right: PropTypes.number, - bottom: PropTypes.number, - left: PropTypes.number, - }), - - /** The anchor ref of the popover */ - anchorRef: refPropTypes, - - /** A react-native-animatable animation timing for the modal display animation. */ - animationInTiming: PropTypes.number, - - /** Whether disable the animations */ - disableAnimation: PropTypes.bool, - - /** The ref of the popover */ - withoutOverlayRef: refPropTypes, -}; - -const defaultProps = { - ..._.omit(defaultModalProps, ['type', 'popoverAnchorPosition']), - - animationIn: 'fadeIn', - animationOut: 'fadeOut', - animationInTiming: CONST.ANIMATED_TRANSITION, - - // Anchor position is optional only because it is not relevant on mobile - anchorPosition: {}, - anchorRef: () => {}, - disableAnimation: true, - withoutOverlayRef: () => {}, -}; - -export {propTypes, defaultProps}; diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts index e69de29bb2d1..085a1000e4bc 100644 --- a/src/components/Popover/types.ts +++ b/src/components/Popover/types.ts @@ -0,0 +1,28 @@ +import BaseModalProps from '@components/Modal/types'; +import {WindowDimensionsProps} from '@components/withWindowDimensions/types'; + +type AnchorPosition = { + top?: number; + left?: number; + bottom?: number; + right?: number; +}; + +type PopoverProps = { + anchorPosition: AnchorPosition; + anchorAlignment: {horizontal: string; vertical: string}; + anchorRef: React.RefObject; + disableAnimation: boolean; + withoutOverlay: boolean; + popoverDimensions?: { + width: number; + height: number; + }; + withoutOverlayRef?: React.RefObject; + fromSidebarMediumScreen?: boolean; + children: React.ReactNode; +} & BaseModalProps; + +type PopoverPropsWithWindowDimensions = PopoverProps & WindowDimensionsProps; + +export type {PopoverProps, PopoverPropsWithWindowDimensions, AnchorPosition}; From 188fffa056ad1b0ba814af106c9593a1fd3ec26d Mon Sep 17 00:00:00 2001 From: Jakub Butkiewicz Date: Mon, 20 Nov 2023 14:54:55 +0100 Subject: [PATCH 5/9] fix: revert remove popoverPropTypes --- src/components/Popover/popoverPropTypes.js | 45 ++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/components/Popover/popoverPropTypes.js diff --git a/src/components/Popover/popoverPropTypes.js b/src/components/Popover/popoverPropTypes.js new file mode 100644 index 000000000000..c13fd8fa0b85 --- /dev/null +++ b/src/components/Popover/popoverPropTypes.js @@ -0,0 +1,45 @@ +import PropTypes from 'prop-types'; +import _ from 'underscore'; +import {defaultProps as defaultModalProps, propTypes as modalPropTypes} from '@components/Modal/modalPropTypes'; +import refPropTypes from '@components/refPropTypes'; +import CONST from '@src/CONST'; + +const propTypes = { + ..._.omit(modalPropTypes, ['type', 'popoverAnchorPosition']), + + /** The anchor position of the popover */ + anchorPosition: PropTypes.shape({ + top: PropTypes.number, + right: PropTypes.number, + bottom: PropTypes.number, + left: PropTypes.number, + }), + + /** The anchor ref of the popover */ + anchorRef: refPropTypes, + + /** A react-native-animatable animation timing for the modal display animation. */ + animationInTiming: PropTypes.number, + + /** Whether disable the animations */ + disableAnimation: PropTypes.bool, + + /** The ref of the popover */ + withoutOverlayRef: refPropTypes, +}; + +const defaultProps = { + ..._.omit(defaultModalProps, ['type', 'popoverAnchorPosition']), + + animationIn: 'fadeIn', + animationOut: 'fadeOut', + animationInTiming: CONST.ANIMATED_TRANSITION, + + // Anchor position is optional only because it is not relevant on mobile + anchorPosition: {}, + anchorRef: () => {}, + disableAnimation: true, + withoutOverlayRef: () => {}, +}; + +export {propTypes, defaultProps}; From 4566b4b69052e87795ddc7cfa4a218137d5c810e Mon Sep 17 00:00:00 2001 From: Jakub Butkiewicz Date: Mon, 20 Nov 2023 15:38:39 +0100 Subject: [PATCH 6/9] fix: types --- src/components/Modal/types.ts | 1 + src/components/Popover/index.native.tsx | 3 +++ src/components/Popover/types.ts | 13 +++---------- 3 files changed, 7 insertions(+), 10 deletions(-) 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.tsx b/src/components/Popover/index.native.tsx index 1b5321bce0df..d7c5076f9639 100644 --- a/src/components/Popover/index.native.tsx +++ b/src/components/Popover/index.native.tsx @@ -19,6 +19,9 @@ function Popover(props: PopoverProps) { // Mobile will always has fullscreen menu // eslint-disable-next-line react/jsx-props-no-multi-spaces fullscreen + // Added those props because TS is complaining about them and those values are default based on documentation https://github.com/react-native-modal/react-native-modal#available-props + animationIn="slideInUp" + animationOut="slideOutDown" /> ); } diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts index 085a1000e4bc..90936076af61 100644 --- a/src/components/Popover/types.ts +++ b/src/components/Popover/types.ts @@ -1,15 +1,8 @@ -import BaseModalProps from '@components/Modal/types'; +import BaseModalProps, {PopoverAnchorPosition} from '@components/Modal/types'; import {WindowDimensionsProps} from '@components/withWindowDimensions/types'; -type AnchorPosition = { - top?: number; - left?: number; - bottom?: number; - right?: number; -}; - type PopoverProps = { - anchorPosition: AnchorPosition; + anchorPosition: PopoverAnchorPosition; anchorAlignment: {horizontal: string; vertical: string}; anchorRef: React.RefObject; disableAnimation: boolean; @@ -25,4 +18,4 @@ type PopoverProps = { type PopoverPropsWithWindowDimensions = PopoverProps & WindowDimensionsProps; -export type {PopoverProps, PopoverPropsWithWindowDimensions, AnchorPosition}; +export type {PopoverProps, PopoverPropsWithWindowDimensions}; From 1dd6bc765cb596d7ecbfb921137f667f432d6fa4 Mon Sep 17 00:00:00 2001 From: Jakub Butkiewicz Date: Tue, 21 Nov 2023 10:09:23 +0100 Subject: [PATCH 7/9] fix: resolve comments --- src/components/Popover/index.native.tsx | 5 +---- src/components/Popover/index.tsx | 9 +++++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/components/Popover/index.native.tsx b/src/components/Popover/index.native.tsx index d7c5076f9639..69312e1c6d39 100644 --- a/src/components/Popover/index.native.tsx +++ b/src/components/Popover/index.native.tsx @@ -7,9 +7,7 @@ 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(props: PopoverProps) { - const {animationIn, animationOut, popoverAnchorPosition, disableAnimation, ...propsWithoutAnimation} = props; - const {anchorPosition = {}, fromSidebarMediumScreen} = propsWithoutAnimation; +function Popover({animationIn, animationOut, popoverAnchorPosition, disableAnimation, anchorPosition = {}, fromSidebarMediumScreen, ...propsWithoutAnimation}: PopoverProps) { return ( Date: Tue, 21 Nov 2023 10:31:39 +0100 Subject: [PATCH 8/9] fix: resolve comments --- src/components/Popover/index.tsx | 4 ++-- src/components/Popover/types.ts | 37 +++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/components/Popover/index.tsx b/src/components/Popover/index.tsx index 2d74ecc7360b..bf79415d4794 100644 --- a/src/components/Popover/index.tsx +++ b/src/components/Popover/index.tsx @@ -5,14 +5,14 @@ import {PopoverContext} from '@components/PopoverProvider'; import PopoverWithoutOverlay from '@components/PopoverWithoutOverlay'; import withWindowDimensions from '@components/withWindowDimensions'; import CONST from '@src/CONST'; -import {PopoverPropsWithWindowDimensions} from './types'; +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: PopoverPropsWithWindowDimensions) { +function Popover(props: PopoverWithWindowDimensionsProps) { const { isVisible, onClose, diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts index 90936076af61..9155c4d401f5 100644 --- a/src/components/Popover/types.ts +++ b/src/components/Popover/types.ts @@ -1,21 +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 = { - anchorPosition: PopoverAnchorPosition; - anchorAlignment: {horizontal: string; vertical: string}; + /** 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; - popoverDimensions?: { - width: number; - height: number; - }; + + /** 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; } & BaseModalProps; -type PopoverPropsWithWindowDimensions = PopoverProps & WindowDimensionsProps; +type PopoverWithWindowDimensionsProps = PopoverProps & WindowDimensionsProps; -export type {PopoverProps, PopoverPropsWithWindowDimensions}; +export type {PopoverProps, PopoverWithWindowDimensionsProps}; From 627ac09fabbd799eb2c9467d2240b3f3d318494c Mon Sep 17 00:00:00 2001 From: Jakub Butkiewicz Date: Mon, 27 Nov 2023 09:36:44 +0100 Subject: [PATCH 9/9] fix: resolve comments --- src/components/Popover/index.native.tsx | 1 - src/components/Popover/types.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/Popover/index.native.tsx b/src/components/Popover/index.native.tsx index 69312e1c6d39..3fff04d00d2f 100644 --- a/src/components/Popover/index.native.tsx +++ b/src/components/Popover/index.native.tsx @@ -16,7 +16,6 @@ function Popover({animationIn, animationOut, popoverAnchorPosition, disableAnima {...propsWithoutAnimation} // Mobile will always has fullscreen menu fullscreen - // Added those props because TS is complaining about them and those values are default based on documentation https://github.com/react-native-modal/react-native-modal#available-props animationIn="slideInUp" animationOut="slideOutDown" /> diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts index 9155c4d401f5..7f7e2829770c 100644 --- a/src/components/Popover/types.ts +++ b/src/components/Popover/types.ts @@ -8,7 +8,7 @@ type PopoverDimensions = { height: number; }; -type PopoverProps = { +type PopoverProps = BaseModalProps & { /** The anchor position of the popover */ anchorPosition?: PopoverAnchorPosition; @@ -35,7 +35,7 @@ type PopoverProps = { /** The popover children */ children: React.ReactNode; -} & BaseModalProps; +}; type PopoverWithWindowDimensionsProps = PopoverProps & WindowDimensionsProps;