Skip to content

Commit 68b310f

Browse files
refactor: replace remove token ActionSheet with MMDS BottomSheet (MetaMask#24112)
## **Description** The ActionSheet is buggy on Android (a new layout shift has caused Android to freeze when the ActionSheet is trying to be visible). Instead we have replaced it with a more reliable MMDS BottomSheet, which allows us to control the buttons and other fields with our Design System components. ## **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: refactor: replace remove token ActionSheet with MMDS BottomSheet ## **Related issues** Fixes: MetaMask#23605, https://consensyssoftware.atlassian.net/browse/ASSETS-1961 ## **Manual testing steps** See issue: 1. Long press non-native tokens 2. See bottom sheet ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** https://www.loom.com/share/8163f10e116646e0b2097aae3a085f0f ## **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 - [x] 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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Replaces the token removal ActionSheet with a new MMDS BottomSheet, updates related state/UX, adds targeted tests, and tweaks test IDs and i18n copy. > > - **UI (Tokens)**: > - **BottomSheet replacement**: Introduces `TokenList/RemoveTokenBottomSheet` and refactors `Tokens` to use it instead of `ActionSheet` (adds `removeTokenState`, `showRemoveMenu`, and close handlers). > - **Skeleton**: Adds `testID="token-list-skeleton"` in `TokenListSkeleton`. > - **Empty State**: `TokensEmptyState` now sets `testID="tokens-empty-state"` and passes through props. > - **Tests**: > - Overhauls `app/components/UI/Tokens/index.test.tsx` to mock subcomponents and cover: container render, loading skeleton, empty state, token list, refresh action, add-token navigation, and EVM/non‑EVM removal via BottomSheet. > - Updates `TokensEmptyState.test.tsx` to assert new `testID`. > - **i18n**: > - Changes `wallet.remove_token_title` to "Hide token?". > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit d30881c. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
1 parent e19ee34 commit 68b310f

7 files changed

Lines changed: 335 additions & 1022 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import {
2+
Box,
3+
Button,
4+
ButtonVariant,
5+
Text,
6+
TextVariant,
7+
} from '@metamask/design-system-react-native';
8+
import React, { useCallback, useRef } from 'react';
9+
import { Modal, View } from 'react-native';
10+
import { strings } from '../../../../../locales/i18n';
11+
import BottomSheet, {
12+
BottomSheetRef,
13+
} from '../../../../component-library/components/BottomSheets/BottomSheet';
14+
import BottomSheetHeader from '../../../../component-library/components/BottomSheets/BottomSheetHeader';
15+
16+
interface RemoveTokenBottomSheetProps {
17+
isVisible: boolean;
18+
onClose: () => void;
19+
onRemove: () => void;
20+
}
21+
22+
const RemoveTokenBottomSheet: React.FC<RemoveTokenBottomSheetProps> = ({
23+
isVisible,
24+
onClose,
25+
onRemove,
26+
}) => {
27+
const sheetRef = useRef<BottomSheetRef>(null);
28+
29+
const handleSheetClose = useCallback(() => {
30+
sheetRef.current?.onCloseBottomSheet();
31+
}, []);
32+
33+
const handleRemove = useCallback(() => {
34+
sheetRef.current?.onCloseBottomSheet();
35+
onRemove();
36+
}, [onRemove]);
37+
38+
if (!isVisible) return null;
39+
40+
// Either we use a BottomSheet but need to figure out how to lift this up,
41+
// Or we use the Modal approach, but requires some heavy styling
42+
return (
43+
// Render View - Modal to place bottom sheet on top of stack
44+
<View testID="remove-token-bottom-sheet">
45+
<Modal visible transparent animationType="none" statusBarTranslucent>
46+
{/* Bottom Sheet */}
47+
<BottomSheet
48+
shouldNavigateBack={false}
49+
ref={sheetRef}
50+
onClose={onClose}
51+
>
52+
<BottomSheetHeader onClose={handleSheetClose}>
53+
<Text variant={TextVariant.HeadingMd}>
54+
{strings('wallet.remove_token_title')}
55+
</Text>
56+
</BottomSheetHeader>
57+
58+
<Box twClassName="pt-4 mx-4 flex gap-4">
59+
<Button
60+
onPress={handleRemove}
61+
isFullWidth
62+
isDanger
63+
testID="remove-token-bottom-sheet-remove-button"
64+
>
65+
{strings('wallet.remove')}
66+
</Button>
67+
<Button
68+
onPress={handleSheetClose}
69+
variant={ButtonVariant.Primary}
70+
isFullWidth
71+
>
72+
{strings('wallet.cancel')}
73+
</Button>
74+
</Box>
75+
</BottomSheet>
76+
</Modal>
77+
</View>
78+
);
79+
};
80+
81+
export default RemoveTokenBottomSheet;

app/components/UI/Tokens/TokenList/TokenListSkeleton/TokenListSkeleton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const TokenListSkeleton = () => {
2828
const styles = createStyles(colors);
2929

3030
return (
31-
<View style={styles.wrapperSkeleton}>
31+
<View style={styles.wrapperSkeleton} testID="token-list-skeleton">
3232
<SkeletonPlaceholder
3333
backgroundColor={colors.background.section}
3434
highlightColor={colors.background.subsection}

0 commit comments

Comments
 (0)