diff --git a/src/components/AttachmentPicker/attachmentPickerPropTypes.js b/src/components/AttachmentPicker/attachmentPickerPropTypes.js index 8338ad9bb9f3..7db237d278f3 100644 --- a/src/components/AttachmentPicker/attachmentPickerPropTypes.js +++ b/src/components/AttachmentPicker/attachmentPickerPropTypes.js @@ -24,10 +24,19 @@ const propTypes = { /** The types of files that can be selected with this picker. */ type: PropTypes.oneOf([CONST.ATTACHMENT_PICKER_TYPE.FILE, CONST.ATTACHMENT_PICKER_TYPE.IMAGE]), + + /** The anchor position of the attachment picker */ + anchorPosition: PropTypes.shape({ + top: PropTypes.number, + right: PropTypes.number, + bottom: PropTypes.number, + left: PropTypes.number, + }), }; const defaultProps = { type: CONST.ATTACHMENT_PICKER_TYPE.FILE, + anchorPosition: {}, }; export { diff --git a/src/components/AttachmentPicker/index.native.js b/src/components/AttachmentPicker/index.native.js index d79c9da17f96..723cf6f9d59a 100644 --- a/src/components/AttachmentPicker/index.native.js +++ b/src/components/AttachmentPicker/index.native.js @@ -305,8 +305,8 @@ class AttachmentPicker extends Component { { diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 7ac5303b02b8..b526b96fdd15 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -186,7 +186,10 @@ class AvatarWithImagePicker extends React.Component { : ( )} - + {({openPicker}) => ( <> { diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index 6c5c20eb008e..424d3f1d0edf 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -41,43 +41,63 @@ const defaultProps = { interactive: true, }; -const MenuItem = props => ( - { - if (props.disabled) { - return; - } - - props.onPress(e); - }} - style={({hovered, pressed}) => ([ - styles.popoverMenuItem, - StyleUtils.getButtonBackgroundColorStyle(getButtonState(props.focused || hovered, pressed, props.success, props.disabled, props.interactive)), - ..._.isArray(props.wrapperStyle) ? props.wrapperStyle : [props.wrapperStyle], - ])} - disabled={props.disabled} - > - {({hovered, pressed}) => ( - <> - - {(props.icon && props.iconType === CONST.ICON_TYPE_ICON) && ( - - - - )} - {(props.icon && props.iconType === CONST.ICON_TYPE_AVATAR) && ( +const MenuItem = (props) => { + let position = { + x: 0, + y: 0, + width: 0, + height: 0, + }; + return ( + { + if (el == null) { + return; + } + el.measureInWindow((x, y, width, height) => { + position = { + x, + y, + width, + height, + }; + }); + }} + onPress={(e) => { + if (props.disabled) { + return; + } + e.nativeEvent.absolutePosition = position; + props.onPress(e); + }} + style={({hovered, pressed}) => ([ + styles.popoverMenuItem, + StyleUtils.getButtonBackgroundColorStyle(getButtonState(props.focused || hovered, pressed, props.success, props.disabled, props.interactive)), + ..._.isArray(props.wrapperStyle) ? props.wrapperStyle : [props.wrapperStyle], + ])} + disabled={props.disabled} + > + {({hovered, pressed}) => ( + <> + + {(props.icon && props.iconType === CONST.ICON_TYPE_ICON) && ( + + + + )} + {(props.icon && props.iconType === CONST.ICON_TYPE_AVATAR) && ( ( source={props.icon} /> - )} - - - {props.title} - - {props.description && ( - - {props.description} - )} - - - - {props.badgeText && } - - {/* Since subtitle can be of type number, we should allow 0 to be shown */} - {(props.subtitle || props.subtitle === 0) && ( - + - {props.subtitle} + {props.title} + {props.description && ( + + {props.description} + + )} - )} - {props.shouldShowRightIcon && ( - - - - )} - {props.shouldShowSelectedState && } - - - )} - -); + + + {props.badgeText && } + + {/* Since subtitle can be of type number, we should allow 0 to be shown */} + {(props.subtitle || props.subtitle === 0) && ( + + + {props.subtitle} + + + )} + {props.shouldShowRightIcon && ( + + + + )} + {props.shouldShowSelectedState && } + + + )} + + ); +}; MenuItem.propTypes = propTypes; MenuItem.defaultProps = defaultProps; diff --git a/src/components/Popover/index.native.js b/src/components/Popover/index.native.js index 05c193bbad71..1aed6dfb8eaa 100644 --- a/src/components/Popover/index.native.js +++ b/src/components/Popover/index.native.js @@ -1,13 +1,9 @@ import _ from 'underscore'; import React from 'react'; -import {propTypes as popoverPropTypes, defaultProps} from './popoverPropTypes'; +import {propTypes, defaultProps} from './popoverPropTypes'; import CONST from '../../CONST'; import Modal from '../Modal'; -import {windowDimensionsPropTypes} from '../withWindowDimensions'; - -const propTypes = { - ...(_.omit(popoverPropTypes, _.keys(windowDimensionsPropTypes))), -}; +import withWindowDimensions from '../withWindowDimensions'; /* * This is a convenience wrapper around the Modal component for a responsive Popover. @@ -17,10 +13,12 @@ const Popover = (props) => { const propsWithoutAnimation = _.omit(props, ['animationIn', 'animationOut', 'popoverAnchorPosition', 'disableAnimation']); return ( {!_.isEmpty(this.props.headerText) && ( diff --git a/src/libs/getClickedElementLocation/index.js b/src/libs/getClickedElementLocation/index.js index f29a57ebf5c0..f371a0223db4 100644 --- a/src/libs/getClickedElementLocation/index.js +++ b/src/libs/getClickedElementLocation/index.js @@ -1,5 +1,5 @@ /** - * We don't need to get the position of the element on native platforms because the popover will be bottom mounted + * Returns the position of the clicked element * * @param {Object} nativeEvent * @returns {Object} diff --git a/src/libs/getClickedElementLocation/index.native.js b/src/libs/getClickedElementLocation/index.native.js index e6ed6a720435..daa1298fb7fd 100644 --- a/src/libs/getClickedElementLocation/index.native.js +++ b/src/libs/getClickedElementLocation/index.native.js @@ -1,12 +1,13 @@ /** - * We don't need to get the position of the element on native platforms because the popover will be bottom mounted + * Returns the position of the clicked element * + * @param {Object} nativeEvent * @returns {Object} */ -function getClickedElementLocation() { +function getClickedElementLocation(nativeEvent) { return { - bottom: 0, - left: 0, + bottom: nativeEvent.absolutePosition.y + nativeEvent.absolutePosition.height, + left: nativeEvent.absolutePosition.x, }; } diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 94baafa5bd59..7ce15630824b 100755 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -426,7 +426,9 @@ class ReportActionCompose extends React.Component { > {({displayFileInModal}) => ( <> - + {({openPicker}) => ( <> diff --git a/src/pages/home/sidebar/SidebarScreen.js b/src/pages/home/sidebar/SidebarScreen.js index 158ba45a26ac..d18b81c29922 100755 --- a/src/pages/home/sidebar/SidebarScreen.js +++ b/src/pages/home/sidebar/SidebarScreen.js @@ -125,7 +125,6 @@ class SidebarScreen extends Component { isVisible={this.state.isCreateMenuActive} anchorPosition={styles.createMenuPositionSidebar} onItemSelected={this.hideCreateMenu} - fromSidebarMediumScreen={!this.props.isSmallScreenWidth} menuItems={[ { icon: Expensicons.ChatBubble, diff --git a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js index f04d34ba6caf..62c94708c79d 100644 --- a/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js +++ b/src/pages/settings/Payments/PaymentsPage/BasePaymentsPage.js @@ -110,15 +110,15 @@ class BasePaymentsPage extends React.Component { /** * Display the delete/default menu, or the add payment method menu * - * @param {Object} nativeEvent + * @param {Object} event * @param {String} accountType * @param {String} account * @param {Boolean} isDefault */ - paymentMethodPressed(nativeEvent, accountType, account, isDefault) { - const position = getClickedElementLocation(nativeEvent); + paymentMethodPressed(event, accountType, account, isDefault) { + const position = getClickedElementLocation(event.nativeEvent); this.setState({ - addPaymentMethodButton: nativeEvent, + addPaymentMethodButton: event.nativeEvent, }); if (accountType) { let formattedSelectedPaymentMethod;