diff --git a/src/components/ContextMenuItem.js b/src/components/ContextMenuItem.js index 4b0609839a71..2cabd71b11cb 100644 --- a/src/components/ContextMenuItem.js +++ b/src/components/ContextMenuItem.js @@ -97,7 +97,7 @@ function ContextMenuItem({onPress, successIcon, successText, icon, text, isMini, wrapperStyle={styles.pr9} success={!isThrottledButtonActive} description={description} - descriptionTextStyle={styles.breakAll} + descriptionTextStyle={styles.breakWord} style={StyleUtils.getContextMenuItemStyles(windowWidth)} isAnonymousAction={isAnonymousAction} focused={isFocused} diff --git a/src/libs/EmailUtils.ts b/src/libs/EmailUtils.ts new file mode 100644 index 000000000000..886823faae87 --- /dev/null +++ b/src/libs/EmailUtils.ts @@ -0,0 +1,30 @@ +/** + * Trims the `mailto:` part from mail link. + * @param mailLink - The `mailto:` link to be trimmed + * @returns The email address + */ +function trimMailTo(mailLink: string) { + return mailLink.replace('mailto:', ''); +} + +/** + * Prepends a zero-width space (U+200B) character before all `.` and `@` characters + * in the email address to provide explicit line break opportunities for consistent + * breaking across platforms. + * + * Note: as explained [here](https://github.com/Expensify/App/issues/30985#issuecomment-1815379835), + * this only provides opportunities for line breaking (rather than forcing line breaks) that shall + * be used by the platform implementation when there are no other customary rules applicable + * and the text would otherwise overflow. + * @param email - The email address to be sanitized + * @returns The email with inserted line break opportunities + */ +function prefixMailSeparatorsWithBreakOpportunities(email: string) { + return email.replace( + /([.@])/g, + // below: zero-width space (U+200B) character + '​$1', + ); +} + +export default {trimMailTo, prefixMailSeparatorsWithBreakOpportunities}; diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.js b/src/pages/home/report/ContextMenu/ContextMenuActions.js index 4f35926c5957..832b3352b2e5 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.js +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.js @@ -7,6 +7,7 @@ import MiniQuickEmojiReactions from '@components/Reactions/MiniQuickEmojiReactio import QuickEmojiReactions from '@components/Reactions/QuickEmojiReactions'; import addEncryptedAuthTokenToURL from '@libs/addEncryptedAuthTokenToURL'; import Clipboard from '@libs/Clipboard'; +import EmailUtils from '@libs/EmailUtils'; import * as Environment from '@libs/Environment/Environment'; import fileDownload from '@libs/fileDownload'; import getAttachmentDetails from '@libs/fileDownload/getAttachmentDetails'; @@ -243,10 +244,10 @@ export default [ successIcon: Expensicons.Checkmark, shouldShow: (type) => type === CONTEXT_MENU_TYPES.EMAIL, onPress: (closePopover, {selection}) => { - Clipboard.setString(selection.replace('mailto:', '')); + Clipboard.setString(EmailUtils.trimMailTo(selection)); hideContextMenu(true, ReportActionComposeFocusManager.focus); }, - getDescription: (selection) => selection.replace('mailto:', ''), + getDescription: (selection) => EmailUtils.prefixMailSeparatorsWithBreakOpportunities(EmailUtils.trimMailTo(selection)), }, { isAnonymousAction: true,