diff --git a/app/components/UI/Perps/Perps.testIds.ts b/app/components/UI/Perps/Perps.testIds.ts index 35f8439b724..7d3f7124a4c 100644 --- a/app/components/UI/Perps/Perps.testIds.ts +++ b/app/components/UI/Perps/Perps.testIds.ts @@ -306,6 +306,20 @@ export const PerpsPositionsViewSelectorsIDs = { POSITIONS_SECTION_TITLE: 'perps-positions-section-title', }; +// ======================================== +// PERPS CLOSE ALL POSITIONS VIEW SELECTORS +// ======================================== + +export const PerpsCloseAllPositionsViewSelectorsIDs = { + SHEET: 'perps-close-all-positions-sheet', + TITLE: 'perps-close-all-positions-title', + DESCRIPTION: 'perps-close-all-positions-description', + EMPTY_STATE: 'perps-close-all-positions-empty-state', + CLOSING_STATE: 'perps-close-all-positions-closing-state', + KEEP_BUTTON: 'perps-close-all-positions-keep-button', + CLOSE_ALL_BUTTON: 'perps-close-all-positions-close-all-button', +} as const; + export const PerpsPositionDetailsViewSelectorsIDs = { CANDLESTICK_CHART: 'candlestick-chart', TRADINGVIEW_CHART: 'tradingview-chart', diff --git a/app/components/UI/Perps/Views/PerpsCloseAllPositionsView/PerpsCloseAllPositionsView.styles.ts b/app/components/UI/Perps/Views/PerpsCloseAllPositionsView/PerpsCloseAllPositionsView.styles.ts index 65651903c3b..4d803ed6e60 100644 --- a/app/components/UI/Perps/Views/PerpsCloseAllPositionsView/PerpsCloseAllPositionsView.styles.ts +++ b/app/components/UI/Perps/Views/PerpsCloseAllPositionsView/PerpsCloseAllPositionsView.styles.ts @@ -3,16 +3,9 @@ import type { Theme } from '../../../../../util/theme/models'; export const createStyles = (_theme: Theme) => StyleSheet.create({ - contentContainer: { - paddingHorizontal: 16, - paddingVertical: 8, - }, description: { marginBottom: 16, }, - breakdownContainer: { - gap: 12, - }, loadingContainer: { paddingVertical: 32, alignItems: 'center', @@ -23,22 +16,7 @@ export const createStyles = (_theme: Theme) => }, emptyContainer: { paddingVertical: 32, - paddingHorizontal: 16, alignItems: 'center', justifyContent: 'center', }, - footerContainer: { - paddingHorizontal: 16, - zIndex: 0, // Ensure footer stays behind modal overlays - elevation: 0, // Android equivalent - }, - footerButtonSecondary: { - flex: 1, - borderWidth: 0, - }, - labelWithTooltip: { - flexDirection: 'row', - alignItems: 'center', - gap: 4, - }, }); diff --git a/app/components/UI/Perps/Views/PerpsCloseAllPositionsView/PerpsCloseAllPositionsView.test.tsx b/app/components/UI/Perps/Views/PerpsCloseAllPositionsView/PerpsCloseAllPositionsView.test.tsx index 89807a5f46c..25fa6562239 100644 --- a/app/components/UI/Perps/Views/PerpsCloseAllPositionsView/PerpsCloseAllPositionsView.test.tsx +++ b/app/components/UI/Perps/Views/PerpsCloseAllPositionsView/PerpsCloseAllPositionsView.test.tsx @@ -8,6 +8,7 @@ import { usePerpsRewardAccountOptedIn, } from '../../hooks'; import { InternalAccount } from '@metamask/keyring-internal-api'; +import { PerpsCloseAllPositionsViewSelectorsIDs } from '../../Perps.testIds'; // Mock all dependencies jest.mock('@react-navigation/native', () => ({ @@ -45,57 +46,6 @@ jest.mock('../../hooks/usePerpsEventTracking', () => ({ usePerpsEventTracking: jest.fn(), })); -jest.mock( - '../../../../../component-library/components/BottomSheets/BottomSheet', - () => { - const mockReact = jest.requireActual('react'); - return mockReact.forwardRef( - (props: { children: React.ReactNode }, _ref) => <>{props.children}, - ); - }, -); - -jest.mock( - '../../../../../component-library/components/BottomSheets/BottomSheetHeader', - () => 'BottomSheetHeader', -); - -jest.mock( - '../../../../../component-library/components/BottomSheets/BottomSheetFooter', - () => { - const { View, TouchableOpacity, Text } = jest.requireActual('react-native'); - - return { - __esModule: true, - default: ({ - buttonPropsArray, - }: { - buttonPropsArray?: { - label: string; - onPress: () => void; - disabled?: boolean; - }[]; - }) => ( - - {buttonPropsArray?.map((buttonProps, index) => ( - - {buttonProps.label} - - ))} - - ), - ButtonsAlignment: { - Horizontal: 'Horizontal', - Vertical: 'Vertical', - }, - }; - }, -); - jest.mock('../../components/PerpsCloseSummary', () => 'PerpsCloseSummary'); const mockUsePerpsLivePositions = usePerpsLivePositions as jest.MockedFunction< @@ -138,7 +88,7 @@ describe('PerpsCloseAllPositionsView', () => { takeProfitCount: 0, stopLossCount: 0, marketPrice: '50200', - timestamp: Date.now(), + timestamp: 1700000000000, // fixed epoch ms – 2023-11-14T22:13:20.000Z }, ]; @@ -204,10 +154,12 @@ describe('PerpsCloseAllPositionsView', () => { }); // Act - const { getByText } = render(); + const { getByTestId } = render(); // Assert - expect(getByText('perps.close_all_modal.title')).toBeTruthy(); + expect( + getByTestId(PerpsCloseAllPositionsViewSelectorsIDs.TITLE), + ).toBeOnTheScreen(); }); it('renders empty state when no positions', () => { @@ -218,19 +170,25 @@ describe('PerpsCloseAllPositionsView', () => { }); // Act - const { getByText } = render(); + const { getByTestId } = render(); // Assert - expect(getByText('perps.position.no_positions')).toBeTruthy(); + expect( + getByTestId(PerpsCloseAllPositionsViewSelectorsIDs.EMPTY_STATE), + ).toBeOnTheScreen(); }); it('renders close all positions view with positions', () => { // Arrange & Act - const { getByText } = render(); + const { getByTestId } = render(); // Assert - expect(getByText('perps.close_all_modal.title')).toBeTruthy(); - expect(getByText('perps.close_all_modal.description')).toBeTruthy(); + expect( + getByTestId(PerpsCloseAllPositionsViewSelectorsIDs.TITLE), + ).toBeOnTheScreen(); + expect( + getByTestId(PerpsCloseAllPositionsViewSelectorsIDs.DESCRIPTION), + ).toBeOnTheScreen(); }); it('renders loading state when closing', () => { @@ -241,20 +199,25 @@ describe('PerpsCloseAllPositionsView', () => { }); // Act - const { getAllByText } = render(); + const { getByTestId } = render(); // Assert - const closingElements = getAllByText('perps.close_all_modal.closing'); - expect(closingElements.length).toBeGreaterThan(0); + expect( + getByTestId(PerpsCloseAllPositionsViewSelectorsIDs.CLOSING_STATE), + ).toBeOnTheScreen(); }); it('displays footer buttons with correct labels', () => { // Arrange & Act - const { getByText } = render(); + const { getByTestId } = render(); // Assert - expect(getByText('perps.close_all_modal.keep_positions')).toBeTruthy(); - expect(getByText('perps.close_all_modal.close_all')).toBeTruthy(); + expect( + getByTestId(PerpsCloseAllPositionsViewSelectorsIDs.KEEP_BUTTON), + ).toBeOnTheScreen(); + expect( + getByTestId(PerpsCloseAllPositionsViewSelectorsIDs.CLOSE_ALL_BUTTON), + ).toBeOnTheScreen(); }); it('shows closing label on close button when in progress', () => { @@ -265,11 +228,15 @@ describe('PerpsCloseAllPositionsView', () => { }); // Act - const { getAllByText } = render(); + const { getByTestId } = render(); // Assert - const closingElements = getAllByText('perps.close_all_modal.closing'); - expect(closingElements.length).toBeGreaterThan(0); + expect( + getByTestId(PerpsCloseAllPositionsViewSelectorsIDs.CLOSE_ALL_BUTTON), + ).toBeOnTheScreen(); + expect( + getByTestId(PerpsCloseAllPositionsViewSelectorsIDs.CLOSING_STATE), + ).toBeOnTheScreen(); }); it('renders with empty positions gracefully', () => { @@ -280,18 +247,22 @@ describe('PerpsCloseAllPositionsView', () => { }); // Act - const { getByText } = render(); + const { getByTestId } = render(); // Assert - expect(getByText('perps.position.no_positions')).toBeTruthy(); + expect( + getByTestId(PerpsCloseAllPositionsViewSelectorsIDs.EMPTY_STATE), + ).toBeOnTheScreen(); }); it('renders PerpsCloseSummary when not closing', () => { // Arrange & Act - const { getByText } = render(); + const { getByTestId } = render(); // Assert - expect(getByText('perps.close_all_modal.description')).toBeTruthy(); + expect( + getByTestId(PerpsCloseAllPositionsViewSelectorsIDs.DESCRIPTION), + ).toBeOnTheScreen(); }); it('calls usePerpsRewardAccountOptedIn with totalEstimatedPoints', () => { @@ -337,10 +308,12 @@ describe('PerpsCloseAllPositionsView', () => { }); // Act - const { getByText } = render(); + const { getByTestId } = render(); // Assert - expect(getByText('perps.close_all_modal.description')).toBeTruthy(); + expect( + getByTestId(PerpsCloseAllPositionsViewSelectorsIDs.DESCRIPTION), + ).toBeOnTheScreen(); expect(mockUsePerpsRewardAccountOptedIn).toHaveBeenCalled(); }); @@ -352,10 +325,12 @@ describe('PerpsCloseAllPositionsView', () => { }); // Act - const { getByText } = render(); + const { getByTestId } = render(); // Assert - expect(getByText('perps.close_all_modal.description')).toBeTruthy(); + expect( + getByTestId(PerpsCloseAllPositionsViewSelectorsIDs.DESCRIPTION), + ).toBeOnTheScreen(); expect(mockUsePerpsRewardAccountOptedIn).toHaveBeenCalled(); }); }); diff --git a/app/components/UI/Perps/Views/PerpsCloseAllPositionsView/PerpsCloseAllPositionsView.tsx b/app/components/UI/Perps/Views/PerpsCloseAllPositionsView/PerpsCloseAllPositionsView.tsx index 9a12d50dc68..8754d09fec0 100644 --- a/app/components/UI/Perps/Views/PerpsCloseAllPositionsView/PerpsCloseAllPositionsView.tsx +++ b/app/components/UI/Perps/Views/PerpsCloseAllPositionsView/PerpsCloseAllPositionsView.tsx @@ -1,23 +1,20 @@ import { useNavigation } from '@react-navigation/native'; import React, { useCallback, useMemo, useRef } from 'react'; import { View, ActivityIndicator } from 'react-native'; -import { NotificationMoment } from '../../../../../util/haptics'; -import { strings } from '../../../../../../locales/i18n'; -import BottomSheet, { +import { + BottomSheet, + BottomSheetFooter, + BottomSheetHeader, BottomSheetRef, -} from '../../../../../component-library/components/BottomSheets/BottomSheet'; -import BottomSheetHeader from '../../../../../component-library/components/BottomSheets/BottomSheetHeader'; -import BottomSheetFooter, { + Box, + ButtonSize, ButtonsAlignment, -} from '../../../../../component-library/components/BottomSheets/BottomSheetFooter'; -import Text, { + Text, TextColor, TextVariant, -} from '../../../../../component-library/components/Texts/Text'; -import { - ButtonSize, - ButtonVariants, -} from '../../../../../component-library/components/Buttons/Button'; +} from '@metamask/design-system-react-native'; +import { NotificationMoment } from '../../../../../util/haptics'; +import { strings } from '../../../../../../locales/i18n'; import { IconName } from '../../../../../component-library/components/Icons/Icon'; import { ToastVariants } from '../../../../../component-library/components/Toast/Toast.types'; import { @@ -40,6 +37,7 @@ import { PERPS_EVENT_VALUE, type ClosePositionsResult, } from '@metamask/perps-controller'; +import { PerpsCloseAllPositionsViewSelectorsIDs } from '../../Perps.testIds'; interface PerpsCloseAllPositionsViewProps { sheetRef?: React.RefObject; @@ -222,54 +220,57 @@ const PerpsCloseAllPositionsView: React.FC = ({ } }, [externalSheetRef, handleClose, handleKeepPositions]); - const footerButtons = useMemo( - () => [ - { - label: strings('perps.close_all_modal.keep_positions'), - onPress: handleKeepButtonPress, - variant: ButtonVariants.Secondary, - size: ButtonSize.Lg, - style: styles.footerButtonSecondary, - disabled: isClosing, - }, - { - label: isClosing - ? strings('perps.close_all_modal.closing') - : strings('perps.close_all_modal.close_all'), - onPress: handleCloseAll, - variant: ButtonVariants.Primary, - size: ButtonSize.Lg, - disabled: isClosing, - danger: true, - }, - ], - [ - handleKeepButtonPress, - handleCloseAll, - isClosing, - styles.footerButtonSecondary, - ], + const secondaryButtonProps = useMemo( + () => ({ + children: strings('perps.close_all_modal.keep_positions'), + onPress: handleKeepButtonPress, + size: ButtonSize.Lg, + isDisabled: isClosing, + testID: PerpsCloseAllPositionsViewSelectorsIDs.KEEP_BUTTON, + }), + [handleKeepButtonPress, isClosing], + ); + + const primaryButtonProps = useMemo( + () => ({ + children: isClosing + ? strings('perps.close_all_modal.closing') + : strings('perps.close_all_modal.close_all'), + onPress: handleCloseAll, + size: ButtonSize.Lg, + isDisabled: isClosing, + isDanger: true, + testID: PerpsCloseAllPositionsViewSelectorsIDs.CLOSE_ALL_BUTTON, + }), + [handleCloseAll, isClosing], ); + const goBack = externalSheetRef ? undefined : navigation.goBack; + const onClose = externalSheetRef ? onExternalClose : undefined; + // Show loading state while fetching positions if (isInitialLoading) { return ( - - - {strings('perps.close_all_modal.title')} - + + {strings('perps.close_all_modal.title')} - - - + + + + + ); } @@ -279,19 +280,27 @@ const PerpsCloseAllPositionsView: React.FC = ({ return ( - - - {strings('perps.close_all_modal.title')} - + + {strings('perps.close_all_modal.title')} - - - {strings('perps.position.no_positions')} - - + + + + {strings('perps.position.no_positions')} + + + ); } @@ -299,33 +308,39 @@ const PerpsCloseAllPositionsView: React.FC = ({ return ( - - - {strings('perps.close_all_modal.title')} - + + {strings('perps.close_all_modal.title')} - + {strings('perps.close_all_modal.description')} {isClosing ? ( - + {strings('perps.close_all_modal.closing')} @@ -352,12 +367,12 @@ const PerpsCloseAllPositionsView: React.FC = ({ enableTooltips={false} /> )} - + ); diff --git a/app/components/UI/Perps/Views/PerpsHomeView/PerpsHomeView.tsx b/app/components/UI/Perps/Views/PerpsHomeView/PerpsHomeView.tsx index ceda24a063e..0ab2b8bd554 100644 --- a/app/components/UI/Perps/Views/PerpsHomeView/PerpsHomeView.tsx +++ b/app/components/UI/Perps/Views/PerpsHomeView/PerpsHomeView.tsx @@ -15,6 +15,7 @@ import { type RouteProp, } from '@react-navigation/native'; import { + BottomSheetRef, Button, ButtonVariant, ButtonSize, @@ -112,7 +113,7 @@ import { } from '../../Perps.testIds'; import PerpsCloseAllPositionsView from '../PerpsCloseAllPositionsView/PerpsCloseAllPositionsView'; import PerpsCancelAllOrdersView from '../PerpsCancelAllOrdersView/PerpsCancelAllOrdersView'; -import { BottomSheetRef } from '../../../../../component-library/components/BottomSheets/BottomSheet'; +import { BottomSheetRef as ComponentLibraryBottomSheetRef } from '../../../../../component-library/components/BottomSheets/BottomSheet'; import PerpsNavigationCard, { NavigationItem, } from '../../components/PerpsNavigationCard/PerpsNavigationCard'; @@ -209,7 +210,7 @@ const PerpsHomeView = ({ const [showCloseAllSheet, setShowCloseAllSheet] = useState(false); const [showCancelAllSheet, setShowCancelAllSheet] = useState(false); const closeAllSheetRef = useRef(null); - const cancelAllSheetRef = useRef(null); + const cancelAllSheetRef = useRef(null); // Use hook for eligibility checks and action handlers // Pass button location for tracking deposit entry point diff --git a/app/components/UI/Perps/components/PerpsCloseSummary/PerpsCloseSummary.styles.ts b/app/components/UI/Perps/components/PerpsCloseSummary/PerpsCloseSummary.styles.ts index e339585e69d..b6f91607088 100644 --- a/app/components/UI/Perps/components/PerpsCloseSummary/PerpsCloseSummary.styles.ts +++ b/app/components/UI/Perps/components/PerpsCloseSummary/PerpsCloseSummary.styles.ts @@ -1,10 +1,8 @@ import { StyleSheet } from 'react-native'; import type { Theme } from '../../../../../util/theme/models'; -const styleSheet = (_params: { theme: Theme }) => { - const { colors } = _params.theme; - - return StyleSheet.create({ +const styleSheet = (_params: { theme: Theme }) => + StyleSheet.create({ summaryContainer: { paddingTop: 16, paddingBottom: 16, @@ -26,17 +24,6 @@ const styleSheet = (_params: { theme: Theme }) => { flexShrink: 0, alignItems: 'flex-end', }, - summaryTotalRow: { - marginTop: 4, - paddingTop: 16, - borderTopWidth: 1, - borderTopColor: colors.border.muted, - }, - labelWithTooltip: { - flexDirection: 'row', - alignItems: 'center', - gap: 4, - }, inclusiveFeeRow: { flexDirection: 'row', gap: 4, @@ -47,6 +34,5 @@ const styleSheet = (_params: { theme: Theme }) => { gap: 8, }, }); -}; export default styleSheet; diff --git a/app/components/UI/Perps/components/PerpsCloseSummary/PerpsCloseSummary.test.tsx b/app/components/UI/Perps/components/PerpsCloseSummary/PerpsCloseSummary.test.tsx index 0bab0c54e42..14aabc092f9 100644 --- a/app/components/UI/Perps/components/PerpsCloseSummary/PerpsCloseSummary.test.tsx +++ b/app/components/UI/Perps/components/PerpsCloseSummary/PerpsCloseSummary.test.tsx @@ -26,10 +26,6 @@ jest.mock('../../../../hooks/useStyles', () => ({ summaryLabel: {}, summaryValue: {}, inclusiveFeeRow: {}, - labelWithTooltip: {}, - summaryTotalRow: {}, - rewardsRow: {}, - rewardsContent: {}, loadingContainer: {}, }, theme: mockTheme, @@ -104,7 +100,7 @@ describe('PerpsCloseSummary', () => { // Assert expect(strings).toHaveBeenCalledWith('perps.close_position.margin'); expect(strings).toHaveBeenCalledWith('perps.close_position.includes_pnl'); - expect(getByText('perps.close_position.margin')).toBeTruthy(); + expect(getByText('perps.close_position.margin')).toBeOnTheScreen(); }); it('renders margin with negative P&L', () => { @@ -115,7 +111,7 @@ describe('PerpsCloseSummary', () => { const { getByText } = render(); // Assert - expect(getByText('perps.close_position.margin')).toBeTruthy(); + expect(getByText('perps.close_position.margin')).toBeOnTheScreen(); expect(strings).toHaveBeenCalledWith('perps.close_position.includes_pnl'); }); @@ -128,8 +124,8 @@ describe('PerpsCloseSummary', () => { const { getByTestId, getByText } = render(); // Assert - expect(getByText('perps.close_position.fees')).toBeTruthy(); - expect(getByTestId('fees-tooltip-button')).toBeTruthy(); + expect(getByText('perps.close_position.fees')).toBeOnTheScreen(); + expect(getByTestId('fees-tooltip-button')).toBeOnTheScreen(); }); it('renders receive amount with tooltip', () => { @@ -141,8 +137,8 @@ describe('PerpsCloseSummary', () => { const { getByTestId, getByText } = render(); // Assert - expect(getByText('perps.close_position.you_receive')).toBeTruthy(); - expect(getByTestId('receive-tooltip-button')).toBeTruthy(); + expect(getByText('perps.close_position.you_receive')).toBeOnTheScreen(); + expect(getByTestId('receive-tooltip-button')).toBeOnTheScreen(); }); it('renders rewards section when enabled and account opted in', () => { @@ -159,7 +155,7 @@ describe('PerpsCloseSummary', () => { const { getByText } = render(); // Assert - expect(getByText('perps.estimated_points')).toBeTruthy(); + expect(getByText('perps.estimated_points')).toBeOnTheScreen(); }); it('renders rewards with loading state when account opted in', () => { @@ -176,7 +172,7 @@ describe('PerpsCloseSummary', () => { const { getByText } = render(); // Assert - expect(getByText('perps.estimated_points')).toBeTruthy(); + expect(getByText('perps.estimated_points')).toBeOnTheScreen(); }); it('applies custom style prop', () => { @@ -185,10 +181,10 @@ describe('PerpsCloseSummary', () => { const props = { ...defaultProps, style: customStyle }; // Act - const { getByTestId } = render(); + const { getByText } = render(); // Assert - component renders without crashing with custom style - expect(getByTestId).toBeDefined(); + expect(getByText('perps.close_position.margin')).toBeOnTheScreen(); }); it('applies padding when input focused', () => { @@ -196,10 +192,10 @@ describe('PerpsCloseSummary', () => { const props = { ...defaultProps, isInputFocused: true }; // Act - const { getByTestId } = render(); + const { getByText } = render(); // Assert - component renders without crashing with focused state - expect(getByTestId).toBeDefined(); + expect(getByText('perps.close_position.margin')).toBeOnTheScreen(); }); it('disables tooltip interactions when enableTooltips is false', () => { @@ -238,7 +234,7 @@ describe('PerpsCloseSummary', () => { const { getByText } = render(); // Assert - rewards section still renders with error state - expect(getByText('perps.estimated_points')).toBeTruthy(); + expect(getByText('perps.estimated_points')).toBeOnTheScreen(); }); it('handles tooltip press to open fees tooltip', () => { @@ -252,7 +248,7 @@ describe('PerpsCloseSummary', () => { fireEvent.press(getByTestId('fees-tooltip')); - expect(getByTestId('fees-tooltip')).toBeTruthy(); + expect(getByTestId('fees-tooltip')).toBeOnTheScreen(); }); it('handles tooltip press to open receive amount tooltip', () => { @@ -266,7 +262,7 @@ describe('PerpsCloseSummary', () => { fireEvent.press(getByTestId('receive-tooltip')); - expect(getByTestId('receive-tooltip')).toBeTruthy(); + expect(getByTestId('receive-tooltip')).toBeOnTheScreen(); }); it('handles tooltip press to open points tooltip when rewards enabled and account opted in', () => { @@ -283,7 +279,7 @@ describe('PerpsCloseSummary', () => { fireEvent.press(getByTestId('points-tooltip')); - expect(getByTestId('points-tooltip')).toBeTruthy(); + expect(getByTestId('points-tooltip')).toBeOnTheScreen(); }); it('does not trigger tooltip callback when tooltips are disabled', () => { @@ -312,8 +308,8 @@ describe('PerpsCloseSummary', () => { const { getByTestId, getByText } = render(); // Assert - expect(getByText('perps.estimated_points')).toBeTruthy(); - expect(getByTestId('add-rewards-account')).toBeTruthy(); + expect(getByText('perps.estimated_points')).toBeOnTheScreen(); + expect(getByTestId('add-rewards-account')).toBeOnTheScreen(); }); it('renders RewardsAnimations when account opted in', () => { @@ -332,7 +328,7 @@ describe('PerpsCloseSummary', () => { ); // Assert - expect(getByText('perps.estimated_points')).toBeTruthy(); + expect(getByText('perps.estimated_points')).toBeOnTheScreen(); expect(queryByTestId('add-rewards-account')).toBeNull(); }); diff --git a/app/components/UI/Perps/components/PerpsCloseSummary/PerpsCloseSummary.tsx b/app/components/UI/Perps/components/PerpsCloseSummary/PerpsCloseSummary.tsx index ddd47adb49e..aa8874f29cd 100644 --- a/app/components/UI/Perps/components/PerpsCloseSummary/PerpsCloseSummary.tsx +++ b/app/components/UI/Perps/components/PerpsCloseSummary/PerpsCloseSummary.tsx @@ -1,10 +1,5 @@ import React, { useCallback } from 'react'; -import { - View, - TouchableOpacity, - ActivityIndicator, - type ViewStyle, -} from 'react-native'; +import { View, ActivityIndicator, type ViewStyle } from 'react-native'; import { useNavigation } from '@react-navigation/native'; import { strings } from '../../../../../../locales/i18n'; import { @@ -22,13 +17,14 @@ import createStyles from './PerpsCloseSummary.styles'; import Routes from '../../../../../constants/navigation/Routes'; import { InternalAccount } from '@metamask/keyring-internal-api'; import { + FontWeight, + IconName, + KeyValueRow, + KeyValueRowVariant, + SectionDivider, Text, TextColor, TextVariant, - Icon, - IconName, - IconSize, - IconColor, } from '@metamask/design-system-react-native'; export interface PerpsCloseSummaryProps { @@ -154,6 +150,33 @@ const PerpsCloseSummary: React.FC = ({ const rewardAnimationState = getRewardAnimationState(); + const feesValue = isLoadingFees ? ( + + + + ) : totalFees !== undefined ? ( + + ) : ( + '--' + ); + + const pointsValue = accountOptedIn ? ( + + ) : ( + + ); + return ( = ({ style, ]} > - {/* Margin with P&L breakdown */} + {/* Margin with P&L breakdown — custom row to support nested includes P&L */} - + {strings('perps.close_position.margin')} - + {formatPerpsFiat(totalMargin, { ranges: PRICE_RANGES_MINIMAL_VIEW, })} @@ -194,148 +226,60 @@ const PerpsCloseSummary: React.FC = ({ - {/* Fees with discount */} - - - {enableTooltips ? ( - - handleTooltipPress('closing_fees', { - metamaskFeeRate, - protocolFeeRate, - originalMetamaskFeeRate, - feeDiscountPercentage, - }) - } - style={styles.labelWithTooltip} - testID={testIDs?.feesTooltip} - > - - {strings('perps.close_position.fees')} - - - - ) : ( - - {strings('perps.close_position.fees')} - - )} - - - {isLoadingFees ? ( - - - - ) : totalFees !== undefined ? ( - - ) : ( - -- - )} - - + + handleTooltipPress('closing_fees', { + metamaskFeeRate, + protocolFeeRate, + originalMetamaskFeeRate, + feeDiscountPercentage, + }), + testID: testIDs?.feesTooltip, + }, + })} + value={feesValue} + /> - {/* You'll receive */} - - - {enableTooltips ? ( - handleTooltipPress('close_position_you_receive')} - style={styles.labelWithTooltip} - testID={testIDs?.receiveTooltip} - > - - {strings('perps.close_position.you_receive')} - - - - ) : ( - - {strings('perps.close_position.you_receive')} - - )} - - - - {formatPerpsFiat(receiveAmount, { - ranges: PRICE_RANGES_MINIMAL_VIEW, - })} - - - + + + handleTooltipPress('close_position_you_receive'), + testID: testIDs?.receiveTooltip, + }, + })} + value={formatPerpsFiat(receiveAmount, { + ranges: PRICE_RANGES_MINIMAL_VIEW, + })} + valueTextProps={{ + testID: testIDs?.receiveValue, + }} + /> - {/* Estimated Points */} {shouldShowRewards && (accountOptedIn || (accountOptedIn === false && rewardsAccount !== undefined)) && ( - - - {enableTooltips ? ( - handleTooltipPress('points')} - style={styles.labelWithTooltip} - testID={testIDs?.pointsTooltip} - > - - {strings('perps.estimated_points')} - - - - ) : ( - - {strings('perps.estimated_points')} - - )} - - - {accountOptedIn ? ( - - ) : ( - - )} - - + handleTooltipPress('points'), + testID: testIDs?.pointsTooltip, + }, + })} + value={pointsValue} + /> )} );