diff --git a/ui/helpers/utils/util.js b/ui/helpers/utils/util.js index 1353f2703741..909c7c2c2d8a 100644 --- a/ui/helpers/utils/util.js +++ b/ui/helpers/utils/util.js @@ -208,6 +208,35 @@ export function getRandomFileName() { return fileName; } +/** + * Shortens the given string, preserving the beginning and end. + * Returns the string it is no longer than truncatedCharLimit. + * + * @param {string} stringToShorten - The string to shorten. + * @param {object} options - The options to use when shortening the string. + * @param {number} options.truncatedCharLimit - The maximum length of the string. + * @param {number} options.truncatedStartChars - The number of characters to preserve at the beginning. + * @param {number} options.truncatedEndChars - The number of characters to preserve at the end. + * @returns {string} The shortened string. + */ +export function shortenString( + stringToShorten = '', + { truncatedCharLimit, truncatedStartChars, truncatedEndChars } = { + truncatedCharLimit: TRUNCATED_NAME_CHAR_LIMIT, + truncatedStartChars: TRUNCATED_ADDRESS_START_CHARS, + truncatedEndChars: TRUNCATED_ADDRESS_END_CHARS, + }, +) { + if (stringToShorten.length < truncatedCharLimit) { + return stringToShorten; + } + + return `${stringToShorten.slice( + 0, + truncatedStartChars, + )}...${stringToShorten.slice(-truncatedEndChars)}`; +} + /** * Shortens an Ethereum address for display, preserving the beginning and end. * Returns the given address if it is no longer than 10 characters. @@ -220,13 +249,11 @@ export function getRandomFileName() { * than 10 characters. */ export function shortenAddress(address = '') { - if (address.length < TRUNCATED_NAME_CHAR_LIMIT) { - return address; - } - - return `${address.slice(0, TRUNCATED_ADDRESS_START_CHARS)}...${address.slice( - -TRUNCATED_ADDRESS_END_CHARS, - )}`; + return shortenString(address, { + truncatedCharLimit: TRUNCATED_NAME_CHAR_LIMIT, + truncatedStartChars: TRUNCATED_ADDRESS_START_CHARS, + truncatedEndChars: TRUNCATED_ADDRESS_END_CHARS, + }); } export function getAccountByAddress(accounts = [], targetAddress) { diff --git a/ui/helpers/utils/util.test.js b/ui/helpers/utils/util.test.js index bd9cbee4ebdf..ce60fcdd85f8 100644 --- a/ui/helpers/utils/util.test.js +++ b/ui/helpers/utils/util.test.js @@ -1042,4 +1042,32 @@ describe('util', () => { expect(util.hexToText(hexValue)).toBe(hexValue); }); }); + + describe('shortenAddress', () => { + it('should return the same address if it is shorter than TRUNCATED_NAME_CHAR_LIMIT', () => { + expect(util.shortenAddress('0x123')).toStrictEqual('0x123'); + }); + + it('should return the shortened address if it is a valid address', () => { + expect( + util.shortenAddress('0x1234567890123456789012345678901234567890'), + ).toStrictEqual('0x12345...67890'); + }); + }); + + describe('shortenString', () => { + it('should return the same string if it is shorter than TRUNCATED_NAME_CHAR_LIMIT', () => { + expect(util.shortenString('string')).toStrictEqual('string'); + }); + + it('should return the shortened string according to the specified options', () => { + expect( + util.shortenString('0x1234567890123456789012345678901234567890', { + truncatedCharLimit: 10, + truncatedStartChars: 4, + truncatedEndChars: 4, + }), + ).toStrictEqual('0x12...7890'); + }); + }); }); diff --git a/ui/pages/confirmations/components/index.scss b/ui/pages/confirmations/components/index.scss index 10bf10d15bfd..30b3cdbb105a 100644 --- a/ui/pages/confirmations/components/index.scss +++ b/ui/pages/confirmations/components/index.scss @@ -36,3 +36,4 @@ @import 'transaction-decoding/index'; @import 'transaction-detail/index'; @import 'transaction-detail-item/index'; +@import 'simulation-details/index'; diff --git a/ui/pages/confirmations/components/simulation-details/amount-pill.scss b/ui/pages/confirmations/components/simulation-details/amount-pill.scss new file mode 100644 index 000000000000..fd9a3a13f342 --- /dev/null +++ b/ui/pages/confirmations/components/simulation-details/amount-pill.scss @@ -0,0 +1,3 @@ +.tippy-tooltip.word-break-all-theme .tippy-tooltip-content { + word-break: break-all; +} diff --git a/ui/pages/confirmations/components/simulation-details/amount-pill.test.tsx b/ui/pages/confirmations/components/simulation-details/amount-pill.test.tsx index dce1b74372e2..044eca8d887c 100644 --- a/ui/pages/confirmations/components/simulation-details/amount-pill.test.tsx +++ b/ui/pages/confirmations/components/simulation-details/amount-pill.test.tsx @@ -207,4 +207,20 @@ describe('AmountPill', () => { }, ); }); + + it('renders shortened token id if given id is too long', () => { + const longHexadecimalTokenId = '0x11111111111111111111111111111'; + const longTokenIdInDecimal = '5538449982437149470432529417834769'; + renderAndExpect( + { + ...ERC721_ASSET_MOCK, + tokenId: longHexadecimalTokenId, + }, + new BigNumber(1), + { + text: '+ #5538...4769', + tooltip: `#${longTokenIdInDecimal}`, + }, + ); + }); }); diff --git a/ui/pages/confirmations/components/simulation-details/amount-pill.tsx b/ui/pages/confirmations/components/simulation-details/amount-pill.tsx index 1204eaf16bd4..5e86018f5e58 100644 --- a/ui/pages/confirmations/components/simulation-details/amount-pill.tsx +++ b/ui/pages/confirmations/components/simulation-details/amount-pill.tsx @@ -15,6 +15,7 @@ import { hexToDecimal } from '../../../../../shared/modules/conversion.utils'; import { TokenStandard } from '../../../../../shared/constants/transaction'; import Tooltip from '../../../../components/ui/tooltip'; import { getIntlLocale } from '../../../../ducks/locale/locale'; +import { shortenString as shortenAssetId } from '../../../../helpers/utils/util'; import { AssetIdentifier } from './types'; import { formatAmount, formatAmountMaxPrecision } from './formatAmount'; @@ -53,10 +54,18 @@ export const AmountPill: React.FC<{ } if (asset.tokenId) { - const tokenIdPart = `#${hexToDecimal(asset.tokenId)}`; + const decimalTokenId = hexToDecimal(asset.tokenId); + const shortenedDecimalTokenId = shortenAssetId(decimalTokenId, { + truncatedCharLimit: 11, + truncatedStartChars: 4, + truncatedEndChars: 4, + }); - amountParts.push(tokenIdPart); - tooltipParts.push(tokenIdPart); + const shortenedTokenIdPart = `#${shortenedDecimalTokenId}`; + const tooltipIdPart = `#${decimalTokenId}`; + + amountParts.push(shortenedTokenIdPart); + tooltipParts.push(tooltipIdPart); } return ( @@ -78,6 +87,7 @@ export const AmountPill: React.FC<{ position="bottom" title={tooltipParts.join(' ')} wrapperStyle={{ minWidth: 0 }} + theme="word-break-all" interactive > diff --git a/ui/pages/confirmations/components/simulation-details/index.scss b/ui/pages/confirmations/components/simulation-details/index.scss new file mode 100644 index 000000000000..92073c736d2b --- /dev/null +++ b/ui/pages/confirmations/components/simulation-details/index.scss @@ -0,0 +1 @@ +@import 'amount-pill';