From 0825b623c918e7473400442b6411369c51a283c4 Mon Sep 17 00:00:00 2001 From: Antonio Regadas Date: Thu, 25 Jun 2026 10:06:11 +0100 Subject: [PATCH] chore: update visual points --- .../TraderPositionView.test.tsx | 2 +- .../TraderProfileView/TraderProfileView.tsx | 7 +- .../components/PositionRow.test.tsx | 87 +++++++------------ .../components/PositionRow.tsx | 35 ++------ .../components/PerpBadges.test.tsx | 12 +-- .../components/PerpBadges.tsx | 24 +++-- 6 files changed, 70 insertions(+), 97 deletions(-) diff --git a/app/components/Views/SocialLeaderboard/TraderPositionView/TraderPositionView.test.tsx b/app/components/Views/SocialLeaderboard/TraderPositionView/TraderPositionView.test.tsx index 05aa1fcc8ce..6ac97815244 100644 --- a/app/components/Views/SocialLeaderboard/TraderPositionView/TraderPositionView.test.tsx +++ b/app/components/Views/SocialLeaderboard/TraderPositionView/TraderPositionView.test.tsx @@ -466,7 +466,7 @@ describe('TraderPositionView', () => { renderWithProvider(, { state: mockState }); expect(screen.getByText('10x')).toBeOnTheScreen(); - expect(screen.getByText('SHORT')).toBeOnTheScreen(); + expect(screen.getByText('Short')).toBeOnTheScreen(); }); it('does not render the copy token address button for a perp position', () => { diff --git a/app/components/Views/SocialLeaderboard/TraderProfileView/TraderProfileView.tsx b/app/components/Views/SocialLeaderboard/TraderProfileView/TraderProfileView.tsx index 3192d284494..e4fedb1a9a9 100644 --- a/app/components/Views/SocialLeaderboard/TraderProfileView/TraderProfileView.tsx +++ b/app/components/Views/SocialLeaderboard/TraderProfileView/TraderProfileView.tsx @@ -110,7 +110,7 @@ const TabButton: React.FC = ({ testID, }) => ( - + = ({ > {label} + ); diff --git a/app/components/Views/SocialLeaderboard/TraderProfileView/components/PositionRow.test.tsx b/app/components/Views/SocialLeaderboard/TraderProfileView/components/PositionRow.test.tsx index 2c1b8477fbd..0ffda5ba369 100644 --- a/app/components/Views/SocialLeaderboard/TraderProfileView/components/PositionRow.test.tsx +++ b/app/components/Views/SocialLeaderboard/TraderProfileView/components/PositionRow.test.tsx @@ -82,25 +82,20 @@ describe('PositionRow', () => { expect(screen.getByText('$2,259.96')).toBeOnTheScreen(); }); - it('renders an up triangle with the unsigned percent on the bottom-right (no absolute PnL)', () => { + it('renders a signed positive percent on the bottom-right (no absolute PnL)', () => { renderWithProvider(); - // Direction lives in the caret, so the percent is unsigned. - expect(screen.getByText('▲')).toBeOnTheScreen(); - expect(screen.getByText('182%')).toBeOnTheScreen(); - expect(screen.queryByText('+182%')).toBeNull(); + expect(screen.getByText('+182%')).toBeOnTheScreen(); expect(screen.queryByText('+$1,059.96 (+182%)')).toBeNull(); expect(screen.queryByText('+$1,059.96')).toBeNull(); }); - it('colors the percent to match the up triangle for a winning position', () => { + it('colors the percent for a winning position', () => { renderWithProvider(); - const triangleColor = colorOf(screen.getByText('▲')); - const percentColor = colorOf(screen.getByText('182%')); + const percentColor = colorOf(screen.getByText('+182%')); expect(percentColor).toBeDefined(); - expect(percentColor).toBe(triangleColor); }); - it('renders a down triangle with the unsigned percent for a losing open position', () => { + it('renders a signed negative percent for a losing open position', () => { const position = { ...basePosition, pnlValueUsd: -250, @@ -108,20 +103,16 @@ describe('PositionRow', () => { }; renderWithProvider(); - expect(screen.getByText('▼')).toBeOnTheScreen(); - expect(screen.getByText('25%')).toBeOnTheScreen(); - expect(screen.queryByText('-25%')).toBeNull(); + expect(screen.getByText('-25%')).toBeOnTheScreen(); expect(screen.queryByText('-$250.00 (-25%)')).toBeNull(); }); - it('colors the percent to match the down triangle for a losing position', () => { + it('colors the percent for a losing position', () => { const position = { ...basePosition, pnlValueUsd: -250, pnlPercent: -25 }; renderWithProvider(); - const triangleColor = colorOf(screen.getByText('▼')); - const percentColor = colorOf(screen.getByText('25%')); + const percentColor = colorOf(screen.getByText('-25%')); expect(percentColor).toBeDefined(); - expect(percentColor).toBe(triangleColor); }); it('renders the percent even when pnlValueUsd is missing', () => { @@ -131,7 +122,7 @@ describe('PositionRow', () => { } as unknown as Position; renderWithProvider(); - expect(screen.getByText('182%')).toBeOnTheScreen(); + expect(screen.getByText('+182%')).toBeOnTheScreen(); }); it('renders dash when pnlPercent is null', () => { @@ -157,7 +148,7 @@ describe('PositionRow', () => { expect(dashes.length).toBeGreaterThanOrEqual(1); }); - it('renders a neutral minus and unsigned 0% when unrealized PnL is zero', () => { + it('renders +0% with neutral styling when unrealized PnL is zero', () => { const position = { ...basePosition, pnlValueUsd: 0, @@ -165,10 +156,7 @@ describe('PositionRow', () => { }; renderWithProvider(); - // U+2212 minus glyph (not a triangle) for break-even, then unsigned 0%. - expect(screen.getByText('−')).toBeOnTheScreen(); - expect(screen.getByText('0%')).toBeOnTheScreen(); - expect(screen.queryByText('+0%')).toBeNull(); + expect(screen.getByText('+0%')).toBeOnTheScreen(); expect(screen.queryByText('$0.00 (+0%)')).toBeNull(); }); @@ -262,12 +250,11 @@ describe('PositionRow', () => { expect(screen.getByText('Apr 15 at 2:00 pm')).toBeOnTheScreen(); }); - it('renders realized PnL percent as unsigned magnitude (sign comes from caret)', () => { + it('renders realized PnL percent with a signed value', () => { renderWithProvider(); // realizedPnl (300) / boughtUsd (1200) * 100 = 25% - expect(screen.getByText('25%')).toBeOnTheScreen(); - expect(screen.queryByText('+25%')).toBeNull(); + expect(screen.getByText('+25%')).toBeOnTheScreen(); }); it('renders dash for PnL when boughtUsd is zero', () => { @@ -278,14 +265,13 @@ describe('PositionRow', () => { expect(screen.getByText('—')).toBeOnTheScreen(); }); - it('renders negative realized PnL percent as unsigned magnitude', () => { + it('renders negative realized PnL percent with a signed value', () => { const position = { ...closedPosition, realizedPnl: -300 }; renderWithProvider(); // -300 / 1200 * 100 = -25% - expect(screen.getByText('25%')).toBeOnTheScreen(); - expect(screen.queryByText('-25%')).toBeNull(); + expect(screen.getByText('-25%')).toBeOnTheScreen(); }); it('uses realized PnL percent even when pnlPercent is 0', () => { @@ -293,18 +279,16 @@ describe('PositionRow', () => { renderWithProvider(); - expect(screen.getByText('25%')).toBeOnTheScreen(); + expect(screen.getByText('+25%')).toBeOnTheScreen(); }); - it('renders break-even realized PnL with a neutral minus and 0% percent', () => { + it('renders break-even realized PnL with +0% percent', () => { const position = { ...closedPosition, realizedPnl: 0, boughtUsd: 1200 }; renderWithProvider(); expect(screen.getByText('$0.00')).toBeOnTheScreen(); - // U+2212 minus glyph, not a hyphen - expect(screen.getByText('−')).toBeOnTheScreen(); - expect(screen.getByText('0%')).toBeOnTheScreen(); + expect(screen.getByText('+0%')).toBeOnTheScreen(); }); it('renders realized PnL value when boughtUsd is zero (percent null)', () => { @@ -339,19 +323,19 @@ describe('PositionRow', () => { positionAmountWithLeverage: 25, }; - it('renders the leverage and LONG direction badges for a long perp', () => { + it('renders the leverage and Long direction badges for a long perp', () => { renderWithProvider(); expect(screen.getByText('5x')).toBeOnTheScreen(); - expect(screen.getByText('LONG')).toBeOnTheScreen(); + expect(screen.getByText('Long')).toBeOnTheScreen(); }); - it('renders a SHORT badge for a short perp', () => { + it('renders a Short badge for a short perp', () => { const position = { ...perpPosition, perpPositionType: 'short' as const }; renderWithProvider(); - expect(screen.getByText('SHORT')).toBeOnTheScreen(); + expect(screen.getByText('Short')).toBeOnTheScreen(); }); it('omits the leverage badge when perpLeverage is null', () => { @@ -360,14 +344,14 @@ describe('PositionRow', () => { renderWithProvider(); expect(screen.queryByText('5x')).not.toBeOnTheScreen(); - expect(screen.getByText('LONG')).toBeOnTheScreen(); + expect(screen.getByText('Long')).toBeOnTheScreen(); }); it('does not render perp badges for a spot position', () => { renderWithProvider(); - expect(screen.queryByText('LONG')).not.toBeOnTheScreen(); - expect(screen.queryByText('SHORT')).not.toBeOnTheScreen(); + expect(screen.queryByText('Long')).not.toBeOnTheScreen(); + expect(screen.queryByText('Short')).not.toBeOnTheScreen(); }); it('hides the HIP-3 provider prefix in the symbol and amount subtitle', () => { @@ -404,7 +388,7 @@ describe('PositionRow', () => { expect(screen.queryByText('1.50B ETH')).not.toBeOnTheScreen(); }); - it('renders an up triangle with a colored, unsigned percent for a winning closed perp (matching spot)', () => { + it('renders a colored signed percent for a winning closed perp (matching spot)', () => { const closedPerp = { ...perpPosition, currentValueUSD: 0, @@ -415,13 +399,11 @@ describe('PositionRow', () => { renderWithProvider(); - // 300 / 1200 * 100 = 25%, rendered unsigned with the caret carrying direction. - expect(screen.getByText('▲')).toBeOnTheScreen(); - expect(screen.getByText('25%')).toBeOnTheScreen(); - expect(screen.queryByText('+25%')).toBeNull(); + // 300 / 1200 * 100 = 25% + expect(screen.getByText('+25%')).toBeOnTheScreen(); }); - it('renders a down triangle with a colored, unsigned percent for a losing closed perp', () => { + it('renders a colored signed percent for a losing closed perp', () => { const closedPerp = { ...perpPosition, currentValueUSD: 0, @@ -432,18 +414,13 @@ describe('PositionRow', () => { renderWithProvider(); - expect(screen.getByText('▼')).toBeOnTheScreen(); - expect(screen.getByText('25%')).toBeOnTheScreen(); - expect(screen.queryByText('-25%')).toBeNull(); + expect(screen.getByText('-25%')).toBeOnTheScreen(); }); - it('renders the directional triangle with an unsigned percent for an open perp', () => { + it('renders a signed percent for an open perp', () => { renderWithProvider(); - // Open positions now match closed: caret carries direction, percent is unsigned. - expect(screen.getByText('▲')).toBeOnTheScreen(); - expect(screen.getByText('182%')).toBeOnTheScreen(); - expect(screen.queryByText('+182%')).toBeNull(); + expect(screen.getByText('+182%')).toBeOnTheScreen(); }); }); }); diff --git a/app/components/Views/SocialLeaderboard/TraderProfileView/components/PositionRow.tsx b/app/components/Views/SocialLeaderboard/TraderProfileView/components/PositionRow.tsx index e972a689980..8408e216d27 100644 --- a/app/components/Views/SocialLeaderboard/TraderProfileView/components/PositionRow.tsx +++ b/app/components/Views/SocialLeaderboard/TraderProfileView/components/PositionRow.tsx @@ -52,7 +52,6 @@ const PositionRow: React.FC = ({ : null; const displayPnlPercent = isClosed ? closedPnlPercent : position.pnlPercent; - const hasPnlPercent = displayPnlPercent != null; // Perps surface realized/unrealized PnL ($) as the headline figure rather // than spot proceeds / current value. const perpPnlValue = position.pnlValueUsd ?? position.realizedPnl ?? null; @@ -110,33 +109,17 @@ const PositionRow: React.FC = ({ ); - // All positions — open and closed, perp and spot — render a directional - // triangle (▲/▼) alongside an unsigned percentage, both colored by direction - // (green up / red down). A break-even position shows a neutral minus and a - // neutral percentage. The sign lives in the caret, so the percent is unsigned. + // All positions — open and closed, perp and spot — render a signed percentage + // (e.g. +182%, -25%) colored by direction (green up / red down). Break-even + // positions use neutral styling with +0%. const bottomRight = ( - - {!hasPnlPercent ? null : isPnlZero ? ( - - {'−'} - - ) : ( - - {isPnlPositive ? '▲' : '▼'} - - )} - - {formatPercent(displayPnlPercent).replace(/^[+-]/, '')} - - + {formatPercent(displayPnlPercent)} + ); const content = ( diff --git a/app/components/Views/SocialLeaderboard/components/PerpBadges.test.tsx b/app/components/Views/SocialLeaderboard/components/PerpBadges.test.tsx index 6e40c0391ca..eac2a233653 100644 --- a/app/components/Views/SocialLeaderboard/components/PerpBadges.test.tsx +++ b/app/components/Views/SocialLeaderboard/components/PerpBadges.test.tsx @@ -4,31 +4,31 @@ import renderWithProvider from '../../../../util/test/renderWithProvider'; import PerpBadges from './PerpBadges'; describe('PerpBadges', () => { - it('renders an uppercase LONG badge', () => { + it('renders a Long badge', () => { renderWithProvider(); - expect(screen.getByText('LONG')).toBeOnTheScreen(); + expect(screen.getByText('Long')).toBeOnTheScreen(); expect(screen.getByText('10x')).toBeOnTheScreen(); }); - it('renders an uppercase SHORT badge', () => { + it('renders a Short badge', () => { renderWithProvider(); - expect(screen.getByText('SHORT')).toBeOnTheScreen(); + expect(screen.getByText('Short')).toBeOnTheScreen(); expect(screen.getByText('5x')).toBeOnTheScreen(); }); it('omits the leverage pill when leverage is null', () => { renderWithProvider(); - expect(screen.getByText('LONG')).toBeOnTheScreen(); + expect(screen.getByText('Long')).toBeOnTheScreen(); expect(screen.queryByText(/x$/u)).not.toBeOnTheScreen(); }); it('omits the leverage pill when leverage is undefined', () => { renderWithProvider(); - expect(screen.getByText('SHORT')).toBeOnTheScreen(); + expect(screen.getByText('Short')).toBeOnTheScreen(); }); it('forwards the testID', () => { diff --git a/app/components/Views/SocialLeaderboard/components/PerpBadges.tsx b/app/components/Views/SocialLeaderboard/components/PerpBadges.tsx index 32d96462c18..f2111a5a311 100644 --- a/app/components/Views/SocialLeaderboard/components/PerpBadges.tsx +++ b/app/components/Views/SocialLeaderboard/components/PerpBadges.tsx @@ -9,8 +9,8 @@ import { } from '@metamask/design-system-react-native'; import { strings } from '../../../../../locales/i18n'; import type { PerpDirection } from '../utils/perp'; -// eslint-disable-next-line import-x/no-restricted-paths -- TODO(ADR-0020): route-isolation backlog -import PerpsLeverage from '../../../UI/Perps/components/PerpsLeverage/PerpsLeverage'; + +const pillClassName = 'bg-muted rounded px-1.5 py-0.5'; export interface PerpBadgesProps { direction: PerpDirection; @@ -21,7 +21,7 @@ export interface PerpBadgesProps { /** * Renders the perp metadata badges shown next to a token symbol: an optional - * leverage pill (e.g. "10x") and a direction pill (LONG green / SHORT red). + * leverage pill (e.g. "10x") and a direction pill (Long green / Short red). * Used across the trader profile position list, the position detail header, * and individual trade rows so perp positions read consistently. */ @@ -35,7 +35,7 @@ const PerpBadges: React.FC = ({ isLong ? 'social_leaderboard.trader_position.long' : 'social_leaderboard.trader_position.short', - ).toUpperCase(); + ); return ( = ({ testID={testID} > {leverage ? ( - + > + + {`${leverage}x`} + + ) : null} - +