diff --git a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.js b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.js index 7e95d407eb21..ef9347c2f20b 100644 --- a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.js +++ b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.js @@ -3,7 +3,7 @@ import React from 'react'; import {Pressable, StyleSheet} from 'react-native'; import lodashGet from 'lodash/get'; import Text from '../../Text'; -import {propTypes, defaultProps} from '../anchorForCommentsOnlyPropTypes'; +import * as anchorForCommentsOnlyPropTypes from '../anchorForCommentsOnlyPropTypes'; import PressableWithSecondaryInteraction from '../../PressableWithSecondaryInteraction'; import * as ReportActionContextMenu from '../../../pages/home/report/ContextMenu/ReportActionContextMenu'; import * as ContextMenuActions from '../../../pages/home/report/ContextMenu/ContextMenuActions'; @@ -15,7 +15,8 @@ import fileDownload from '../../../libs/fileDownload'; */ const BaseAnchorForCommentsOnly = (props) => { let linkRef; - const rest = _.omit(props, _.keys(propTypes)); + // eslint-disable-next-line react/forbid-foreign-prop-types + const rest = _.omit(props, _.keys(anchorForCommentsOnlyPropTypes.propTypes)); return ( props.isAttachment ? ( @@ -32,16 +33,17 @@ const BaseAnchorForCommentsOnly = (props) => { ) : ( { - ReportActionContextMenu.showContextMenu( - ContextMenuActions.CONTEXT_MENU_TYPES.LINK, - event, - props.href, - lodashGet(linkRef, 'current'), - ); - } + (event) => { + ReportActionContextMenu.showContextMenu( + ContextMenuActions.CONTEXT_MENU_TYPES.LINK, + event, + props.href, + lodashGet(linkRef, 'current'), + ); } + } > linkRef = el} @@ -63,8 +65,8 @@ const BaseAnchorForCommentsOnly = (props) => { ); }; -BaseAnchorForCommentsOnly.propTypes = propTypes; -BaseAnchorForCommentsOnly.defaultProps = defaultProps; +BaseAnchorForCommentsOnly.propTypes = anchorForCommentsOnlyPropTypes.propTypes; +BaseAnchorForCommentsOnly.defaultProps = anchorForCommentsOnlyPropTypes.defaultProps; BaseAnchorForCommentsOnly.displayName = 'BaseAnchorForCommentsOnly'; export default BaseAnchorForCommentsOnly; diff --git a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.native.js b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.native.js index 2cac487788bc..a15b74ea93b4 100644 --- a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.native.js +++ b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly/index.native.js @@ -2,7 +2,7 @@ import _ from 'underscore'; import React from 'react'; import lodashGet from 'lodash/get'; import {Linking, StyleSheet, Pressable} from 'react-native'; -import {propTypes, defaultProps} from '../anchorForCommentsOnlyPropTypes'; +import * as anchorForCommentsOnlyPropTypes from '../anchorForCommentsOnlyPropTypes'; import fileDownload from '../../../libs/fileDownload'; import Text from '../../Text'; import PressableWithSecondaryInteraction from '../../PressableWithSecondaryInteraction'; @@ -16,7 +16,8 @@ import styles from '../../../styles/styles'; */ const BaseAnchorForCommentsOnly = (props) => { let linkRef; - const rest = _.omit(props, _.keys(propTypes)); + // eslint-disable-next-line react/forbid-foreign-prop-types + const rest = _.omit(props, _.keys(anchorForCommentsOnlyPropTypes.propTypes)); return ( props.isAttachment ? ( @@ -35,16 +36,17 @@ const BaseAnchorForCommentsOnly = (props) => { ) : ( { - ReportActionContextMenu.showContextMenu( - ContextMenuActions.CONTEXT_MENU_TYPES.LINK, - event, - props.href, - lodashGet(linkRef, 'current'), - ); - } - } + (event) => { + ReportActionContextMenu.showContextMenu( + ContextMenuActions.CONTEXT_MENU_TYPES.LINK, + event, + props.href, + lodashGet(linkRef, 'current'), + ); + } + } onPress={() => Linking.openURL(props.href)} > { ); }; -BaseAnchorForCommentsOnly.propTypes = propTypes; -BaseAnchorForCommentsOnly.defaultProps = defaultProps; +BaseAnchorForCommentsOnly.propTypes = anchorForCommentsOnlyPropTypes.propTypes; +BaseAnchorForCommentsOnly.defaultProps = anchorForCommentsOnlyPropTypes.defaultProps; BaseAnchorForCommentsOnly.displayName = 'BaseAnchorForCommentsOnly'; export default BaseAnchorForCommentsOnly; diff --git a/src/components/AnchorForCommentsOnly/index.js b/src/components/AnchorForCommentsOnly/index.js index 556c2c577d87..55dc0b3154ef 100644 --- a/src/components/AnchorForCommentsOnly/index.js +++ b/src/components/AnchorForCommentsOnly/index.js @@ -1,10 +1,7 @@ import _ from 'underscore'; import React from 'react'; import PropTypes from 'prop-types'; -import { - propTypes as anchorForCommentsOnlyPropTypes, - defaultProps as anchorForCommentsOnlyDefaultProps, -} from './anchorForCommentsOnlyPropTypes'; +import * as anchorForCommentsOnlyPropTypes from './anchorForCommentsOnlyPropTypes'; import BaseAnchorForCommentsOnly from './BaseAnchorForCommentsOnly'; import addEncryptedAuthTokenToURL from '../../libs/addEncryptedAuthTokenToURL'; @@ -12,12 +9,13 @@ const propTypes = { /** Do we need an auth token to view this link or download the remote resource? */ isAuthTokenRequired: PropTypes.bool, - ...anchorForCommentsOnlyPropTypes, + // eslint-disable-next-line react/forbid-foreign-prop-types + ...anchorForCommentsOnlyPropTypes.propTypes, }; const defaultProps = { isAuthTokenRequired: false, - ...anchorForCommentsOnlyDefaultProps, + ...anchorForCommentsOnlyPropTypes.defaultProps, }; /* diff --git a/src/components/PressableWithSecondaryInteraction/index.android.js b/src/components/PressableWithSecondaryInteraction/index.android.js index cb1bb4a96061..b81cf77a7adf 100644 --- a/src/components/PressableWithSecondaryInteraction/index.android.js +++ b/src/components/PressableWithSecondaryInteraction/index.android.js @@ -1,8 +1,8 @@ import _ from 'underscore'; import React, {forwardRef} from 'react'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; -import {Pressable, Platform} from 'react-native'; -import {propTypes, defaultProps} from './pressableWithSecondaryInteractionPropTypes'; +import {Pressable, Platform, Text as RNText} from 'react-native'; +import * as pressableWithSecondaryInteractionPropTypes from './pressableWithSecondaryInteractionPropTypes'; /** * Triggers haptic feedback, and calls onSecondaryInteraction @@ -31,22 +31,26 @@ function handleLongPress(event, props) { * @param {Object} props * @returns {React.Component} */ -const PressableWithSecondaryInteraction = props => ( - handleLongPress(event, props)} - onPressOut={props.onPressOut} - // eslint-disable-next-line react/jsx-props-no-spreading - {...(_.omit(props, 'onLongPress'))} - > - {props.children} - -); +const PressableWithSecondaryInteraction = (props) => { + // Use Text node for inline mode to prevent content overflow. + const Node = props.inline ? RNText : Pressable; + return ( + handleLongPress(event, props)} + onPressOut={props.onPressOut} + // eslint-disable-next-line react/jsx-props-no-spreading + {...(_.omit(props, 'onLongPress'))} + > + {props.children} + + ); +}; -PressableWithSecondaryInteraction.propTypes = propTypes; -PressableWithSecondaryInteraction.defaultProps = defaultProps; +PressableWithSecondaryInteraction.propTypes = pressableWithSecondaryInteractionPropTypes.propTypes; +PressableWithSecondaryInteraction.defaultProps = pressableWithSecondaryInteractionPropTypes.defaultProps; PressableWithSecondaryInteraction.displayName = 'PressableWithSecondaryInteraction'; export default forwardRef((props, ref) => ( diff --git a/src/components/PressableWithSecondaryInteraction/index.ios.js b/src/components/PressableWithSecondaryInteraction/index.ios.js index 20c68d523fae..4d11ef538976 100644 --- a/src/components/PressableWithSecondaryInteraction/index.ios.js +++ b/src/components/PressableWithSecondaryInteraction/index.ios.js @@ -1,8 +1,8 @@ import _ from 'underscore'; import React, {forwardRef} from 'react'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; -import {Pressable} from 'react-native'; -import {propTypes, defaultProps} from './pressableWithSecondaryInteractionPropTypes'; +import {Pressable, Text as RNText} from 'react-native'; +import * as pressableWithSecondaryInteractionPropTypes from './pressableWithSecondaryInteractionPropTypes'; /** * This is a special Pressable that calls onSecondaryInteraction when LongPressed. @@ -10,28 +10,32 @@ import {propTypes, defaultProps} from './pressableWithSecondaryInteractionPropTy * @param {Object} props * @returns {React.Component} */ -const PressableWithSecondaryInteraction = props => ( - { - e.preventDefault(); - ReactNativeHapticFeedback.trigger('selection', { - enableVibrateFallback: true, - }); - props.onSecondaryInteraction(e); - }} - onPressOut={props.onPressOut} - // eslint-disable-next-line react/jsx-props-no-spreading - {...(_.omit(props, 'onLongPress'))} - > - {props.children} - -); +const PressableWithSecondaryInteraction = (props) => { + // Use Text node for inline mode to prevent content overflow. + const Node = props.inline ? RNText : Pressable; + return ( + { + e.preventDefault(); + ReactNativeHapticFeedback.trigger('selection', { + enableVibrateFallback: true, + }); + props.onSecondaryInteraction(e); + }} + onPressOut={props.onPressOut} + // eslint-disable-next-line react/jsx-props-no-spreading + {...(_.omit(props, 'onLongPress'))} + > + {props.children} + + ); +}; -PressableWithSecondaryInteraction.propTypes = propTypes; -PressableWithSecondaryInteraction.defaultProps = defaultProps; +PressableWithSecondaryInteraction.propTypes = pressableWithSecondaryInteractionPropTypes.propTypes; +PressableWithSecondaryInteraction.defaultProps = pressableWithSecondaryInteractionPropTypes.defaultProps; PressableWithSecondaryInteraction.displayName = 'PressableWithSecondaryInteraction'; export default forwardRef((props, ref) => ( diff --git a/src/components/PressableWithSecondaryInteraction/index.js b/src/components/PressableWithSecondaryInteraction/index.js index d490ddde0f22..c14d0576a5aa 100644 --- a/src/components/PressableWithSecondaryInteraction/index.js +++ b/src/components/PressableWithSecondaryInteraction/index.js @@ -1,7 +1,8 @@ import _ from 'underscore'; import React, {Component} from 'react'; import {Pressable} from 'react-native'; -import {propTypes, defaultProps} from './pressableWithSecondaryInteractionPropTypes'; +import * as pressableWithSecondaryInteractionPropTypes from './pressableWithSecondaryInteractionPropTypes'; +import styles from '../../styles/styles'; /** * This is a special Pressable that calls onSecondaryInteraction when LongPressed, or right-clicked. @@ -39,10 +40,12 @@ class PressableWithSecondaryInteraction extends Component { render() { const defaultPressableProps = _.omit(this.props, ['onSecondaryInteraction', 'children', 'onLongPress']); + + // On Web, Text does not support LongPress events thus manage inline mode with styling instead of using Text. return ( ( // eslint-disable-next-line react/jsx-props-no-spreading diff --git a/src/components/PressableWithSecondaryInteraction/pressableWithSecondaryInteractionPropTypes.js b/src/components/PressableWithSecondaryInteraction/pressableWithSecondaryInteractionPropTypes.js index b0a2fa1982a3..619c9ec00c76 100644 --- a/src/components/PressableWithSecondaryInteraction/pressableWithSecondaryInteractionPropTypes.js +++ b/src/components/PressableWithSecondaryInteraction/pressableWithSecondaryInteractionPropTypes.js @@ -21,6 +21,16 @@ const propTypes = { /** Prevent the default ContextMenu on web/Desktop */ preventDefaultContentMenu: PropTypes.bool, + + /** Use Text instead of Pressable to create inline layout. + * It has few limitations in comparison to Pressable. + * + * - No support for delayLongPress. + * - No support for pressIn and pressOut events. + * + * Note: Web uses styling instead of Text due to no support of LongPress. Thus above pointers are not valid for web. + */ + inline: PropTypes.bool, }; const defaultProps = { @@ -28,6 +38,7 @@ const defaultProps = { onPressIn: () => {}, onPressOut: () => {}, preventDefaultContentMenu: true, + inline: false, }; export {propTypes, defaultProps};