Skip to content

Commit 140fd80

Browse files
Matt561abretonc7sclaudegambinish
authored
feat: TAT-1479: replaced max fiat amount with token amount (MetaMask#19474)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** Replaced the fiat "max" amount in the `PerpsOrderView` component to display the token amount instead. <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: changed the fiat "max" amount in the PerpsOrderView component to display the token amount instead. ## **Related issues** Fixes: [TAT-1479: Replace "Max" by Order size in #tokens in the Trade screen](https://consensyssoftware.atlassian.net/browse/TAT-1479) ## **Manual testing steps** 1. Visit the PerpsOrderView (trade screen) 2. You should see the token amount underneath the input instead of the previous fiat "max" ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <img width="506" height="1074" alt="Screenshot 2025-09-09 at 5 09 52 PM" src="https://github.com/user-attachments/assets/fc98ee8b-28ee-408c-9886-dfc9e6fc8340" /> <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --------- Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Nicholas Gambino <nicholas.gambino@consensys.net>
1 parent 3245030 commit 140fd80

4 files changed

Lines changed: 85 additions & 61 deletions

File tree

app/components/UI/Perps/Views/PerpsClosePositionView/PerpsClosePositionView.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,6 @@ const PerpsClosePositionView: React.FC = () => {
476476
<PerpsAmountDisplay
477477
label={strings('perps.close_position.select_amount')}
478478
amount={displayMode === 'usd' ? closeAmountUSDString : closeAmount}
479-
maxAmount={positionValue}
480479
showWarning={false}
481480
onPress={handleAmountPress}
482481
isActive={isInputFocused}

app/components/UI/Perps/Views/PerpsOrderView/PerpsOrderView.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,10 +743,11 @@ const PerpsOrderViewContentBase: React.FC = () => {
743743
{/* Amount Display */}
744744
<PerpsAmountDisplay
745745
amount={orderForm.amount}
746-
maxAmount={availableBalance * orderForm.leverage}
747746
showWarning={availableBalance === 0}
748747
onPress={handleAmountPress}
749748
isActive={isInputFocused}
749+
tokenAmount={positionSize}
750+
tokenSymbol={orderForm.asset}
750751
/>
751752

752753
{/* Amount Slider - Hide when keypad is active */}

app/components/UI/Perps/components/PerpsAmountDisplay/PerpsAmountDisplay.test.tsx

Lines changed: 80 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
2-
import { render, fireEvent } from '@testing-library/react-native';
2+
import { render, fireEvent, screen } from '@testing-library/react-native';
3+
import { PerpsAmountDisplaySelectorsIDs } from '../../../../../../e2e/selectors/Perps/Perps.selectors';
34
import PerpsAmountDisplay from './PerpsAmountDisplay';
45
import { formatPrice, formatPositionSize } from '../../utils/formatUtils';
56

@@ -38,30 +39,23 @@ describe('PerpsAmountDisplay', () => {
3839
});
3940

4041
describe('Rendering', () => {
41-
it('displays amount and max amount with proper formatting', () => {
42+
it('displays amount with proper formatting', () => {
4243
// Arrange
4344
const amount = '1000';
44-
const maxAmount = 5000;
4545

4646
// Act
47-
const { getByText } = render(
48-
<PerpsAmountDisplay amount={amount} maxAmount={maxAmount} />,
49-
);
47+
const { getByText } = render(<PerpsAmountDisplay amount={amount} />);
5048

5149
// Assert
5250
expect(getByText('$1000')).toBeTruthy();
53-
expect(getByText('$5000 max')).toBeTruthy();
5451
});
5552

5653
it('displays $0 when amount is empty', () => {
5754
// Arrange
5855
const emptyAmount = '';
59-
const maxAmount = 5000;
6056

6157
// Act
62-
const { getByText } = render(
63-
<PerpsAmountDisplay amount={emptyAmount} maxAmount={maxAmount} />,
64-
);
58+
const { getByText } = render(<PerpsAmountDisplay amount={emptyAmount} />);
6559

6660
// Assert
6761
expect(getByText('$0')).toBeTruthy();
@@ -71,15 +65,10 @@ describe('PerpsAmountDisplay', () => {
7165
// Arrange - Testing branch coverage for line 72
7266
const label = 'Enter Amount';
7367
const amount = '1000';
74-
const maxAmount = 10000;
7568

7669
// Act
7770
const { getByText } = render(
78-
<PerpsAmountDisplay
79-
amount={amount}
80-
label={label}
81-
maxAmount={maxAmount}
82-
/>,
71+
<PerpsAmountDisplay amount={amount} label={label} />,
8372
);
8473

8574
// Assert
@@ -91,21 +80,23 @@ describe('PerpsAmountDisplay', () => {
9180
const tokenAmount = '0.5';
9281
const tokenSymbol = 'ETH';
9382
const amount = '1000';
94-
const maxAmount = 10000;
9583

9684
// Act
97-
const { getByText } = render(
85+
render(
9886
<PerpsAmountDisplay
9987
amount={amount}
100-
maxAmount={maxAmount}
10188
showTokenAmount
10289
tokenAmount={tokenAmount}
10390
tokenSymbol={tokenSymbol}
10491
/>,
10592
);
10693

10794
// Assert
108-
expect(getByText(`${tokenAmount} ${tokenSymbol}`)).toBeTruthy();
95+
// There will be 2 elements: one in the main display and one in the token amount section
96+
const tokenElements = screen.getAllByText(
97+
`${tokenAmount} ${tokenSymbol}`,
98+
);
99+
expect(tokenElements.length).toBe(2);
109100
expect(formatPositionSize).toHaveBeenCalledWith(tokenAmount);
110101
});
111102
});
@@ -114,15 +105,10 @@ describe('PerpsAmountDisplay', () => {
114105
it('shows default warning when showWarning is true and maxAmount is 0', () => {
115106
// Arrange
116107
const amount = '1000';
117-
const maxAmount = 0;
118108

119109
// Act
120110
const { getByText } = render(
121-
<PerpsAmountDisplay
122-
amount={amount}
123-
maxAmount={maxAmount}
124-
showWarning
125-
/>,
111+
<PerpsAmountDisplay amount={amount} showWarning />,
126112
);
127113

128114
// Assert
@@ -135,13 +121,11 @@ describe('PerpsAmountDisplay', () => {
135121
// Arrange
136122
const customMessage = 'Insufficient balance';
137123
const amount = '1000';
138-
const maxAmount = 5000;
139124

140125
// Act
141126
const { getByText } = render(
142127
<PerpsAmountDisplay
143128
amount={amount}
144-
maxAmount={maxAmount}
145129
showWarning
146130
warningMessage={customMessage}
147131
/>,
@@ -157,15 +141,10 @@ describe('PerpsAmountDisplay', () => {
157141
// Arrange
158142
const onPressMock = jest.fn();
159143
const amount = '1000';
160-
const maxAmount = 5000;
161144

162145
// Act
163146
const { getByText } = render(
164-
<PerpsAmountDisplay
165-
amount={amount}
166-
maxAmount={maxAmount}
167-
onPress={onPressMock}
168-
/>,
147+
<PerpsAmountDisplay amount={amount} onPress={onPressMock} />,
169148
);
170149
fireEvent.press(getByText('$1000'));
171150

@@ -176,12 +155,9 @@ describe('PerpsAmountDisplay', () => {
176155
it('handles press gracefully when onPress is not provided', () => {
177156
// Arrange
178157
const amount = '1000';
179-
const maxAmount = 5000;
180158

181159
// Act
182-
const { getByText } = render(
183-
<PerpsAmountDisplay amount={amount} maxAmount={maxAmount} />,
184-
);
160+
const { getByText } = render(<PerpsAmountDisplay amount={amount} />);
185161

186162
// Assert - This should not throw an error
187163
expect(() => fireEvent.press(getByText('$1000'))).not.toThrow();
@@ -192,11 +168,10 @@ describe('PerpsAmountDisplay', () => {
192168
it('shows cursor when isActive is true', () => {
193169
// Arrange
194170
const amount = '1000';
195-
const maxAmount = 5000;
196171

197172
// Act
198173
const { getByTestId } = render(
199-
<PerpsAmountDisplay amount={amount} maxAmount={maxAmount} isActive />,
174+
<PerpsAmountDisplay amount={amount} isActive />,
200175
);
201176

202177
// Assert
@@ -206,49 +181,101 @@ describe('PerpsAmountDisplay', () => {
206181
it('hides cursor when isActive is false', () => {
207182
// Arrange
208183
const amount = '1000';
209-
const maxAmount = 5000;
210184

211185
// Act
212186
const { queryByTestId } = render(
187+
<PerpsAmountDisplay amount={amount} isActive={false} />,
188+
);
189+
190+
// Assert
191+
expect(queryByTestId('cursor')).toBeNull();
192+
});
193+
});
194+
195+
describe('Token Amount Display', () => {
196+
it('displays token amount when showMaxAmount is true with token data', () => {
197+
// Arrange
198+
const amount = '1000';
199+
const tokenAmount = '0.025';
200+
const tokenSymbol = 'BTC';
201+
202+
// Act
203+
const { getByText } = render(
213204
<PerpsAmountDisplay
214205
amount={amount}
215-
maxAmount={maxAmount}
216-
isActive={false}
206+
showMaxAmount
207+
tokenAmount={tokenAmount}
208+
tokenSymbol={tokenSymbol}
217209
/>,
218210
);
219211

220212
// Assert
221-
expect(queryByTestId('cursor')).toBeNull();
213+
expect(getByText('0.025 BTC')).toBeTruthy();
214+
expect(formatPositionSize).toHaveBeenCalledWith(tokenAmount);
215+
});
216+
217+
it('does not display token amount when showMaxAmount is false', () => {
218+
// Arrange
219+
const amount = '1000';
220+
const tokenAmount = '0.025';
221+
const tokenSymbol = 'BTC';
222+
223+
// Act
224+
const { queryByText } = render(
225+
<PerpsAmountDisplay
226+
amount={amount}
227+
showMaxAmount={false}
228+
tokenAmount={tokenAmount}
229+
tokenSymbol={tokenSymbol}
230+
/>,
231+
);
232+
233+
// Assert
234+
expect(queryByText('0.025 BTC')).toBeNull();
235+
});
236+
237+
it('does not display anything when showMaxAmount is true but no token data', () => {
238+
// Arrange
239+
const amount = '1000';
240+
241+
// Act
242+
const { queryByTestId } = render(
243+
<PerpsAmountDisplay amount={amount} showMaxAmount />,
244+
);
245+
246+
// Assert - The component should not show the token amount section
247+
// When no token data is provided, the token amount section won't be rendered
248+
// We verify by checking if the amount display is there but no token text
249+
expect(
250+
queryByTestId(PerpsAmountDisplaySelectorsIDs.CONTAINER),
251+
).toBeTruthy();
252+
// No token amount should be displayed
253+
expect(screen.queryByText(/BTC|ETH|SOL/)).toBeNull();
222254
});
223255
});
224256

225257
describe('Formatting', () => {
226258
it('formats prices with correct decimal places', () => {
227259
// Arrange
228260
const amount = '1234.56';
229-
const maxAmount = 9876.54;
230261

231262
// Act
232-
render(<PerpsAmountDisplay amount={amount} maxAmount={maxAmount} />);
263+
render(<PerpsAmountDisplay amount={amount} />);
233264

234265
// Assert
235266
expect(formatPrice).toHaveBeenCalledWith('1234.56', {
236267
minimumDecimals: 0,
237268
maximumDecimals: 2,
238269
});
239-
expect(formatPrice).toHaveBeenCalledWith(9876.54, {
240-
minimumDecimals: 2,
241-
maximumDecimals: 2,
242-
});
270+
// Note: formatPrice is no longer called with maxAmount for display
243271
});
244272

245273
it('formats USD amounts with maximum 2 decimal places', () => {
246274
// Arrange
247275
const amount = '1234.5678';
248-
const maxAmount = 5000;
249276

250277
// Act
251-
render(<PerpsAmountDisplay amount={amount} maxAmount={maxAmount} />);
278+
render(<PerpsAmountDisplay amount={amount} />);
252279

253280
// Assert - Verify USD amounts are limited to 2 decimal places
254281
expect(formatPrice).toHaveBeenCalledWith('1234.5678', {

app/components/UI/Perps/components/PerpsAmountDisplay/PerpsAmountDisplay.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@ import Text, {
88
import { useTheme } from '../../../../../util/theme';
99
import { formatPrice, formatPositionSize } from '../../utils/formatUtils';
1010
import createStyles from './PerpsAmountDisplay.styles';
11-
import { strings } from '../../../../../../locales/i18n';
1211

1312
interface PerpsAmountDisplayProps {
1413
amount: string;
15-
maxAmount: number;
1614
showWarning?: boolean;
1715
warningMessage?: string;
1816
onPress?: () => void;
@@ -26,7 +24,6 @@ interface PerpsAmountDisplayProps {
2624

2725
const PerpsAmountDisplay: React.FC<PerpsAmountDisplayProps> = ({
2826
amount,
29-
maxAmount,
3027
showWarning = false,
3128
warningMessage = 'No funds available. Please deposit first.',
3229
onPress,
@@ -106,15 +103,15 @@ const PerpsAmountDisplay: React.FC<PerpsAmountDisplayProps> = ({
106103
/>
107104
)}
108105
</View>
109-
{showMaxAmount && (
106+
{/* Display token amount equivalent for current input */}
107+
{showMaxAmount && tokenAmount && tokenSymbol && (
110108
<Text
111109
variant={TextVariant.BodyMD}
112110
color={TextColor.Alternative}
113111
style={styles.maxAmount}
114112
testID={PerpsAmountDisplaySelectorsIDs.MAX_LABEL}
115113
>
116-
{formatPrice(maxAmount, { minimumDecimals: 2, maximumDecimals: 2 })}{' '}
117-
{strings('perps.order.max')}
114+
{formatPositionSize(tokenAmount)} {tokenSymbol}
118115
</Text>
119116
)}
120117
{showWarning && (

0 commit comments

Comments
 (0)