Skip to content

Commit b68e892

Browse files
authored
feat: migrate Button component (notifications scope) (#27632)
<!-- 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** <!-- 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? --> Replace Button component using DSRN. ## **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: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-445 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** https://github.com/user-attachments/assets/fc1a3116-4c08-42ac-b561-f2c63baaa969 ### **After** https://github.com/user-attachments/assets/4c53334c-68f9-4a97-9a58-d9de66d53260 ## **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] > **Low Risk** > Low risk UI refactor that swaps the notifications-scoped `Button` implementation to `@metamask/design-system-react-native`, with minor prop/behavior differences (disabled/loading/full-width) that could affect interaction/styling. > > **Overview** > Migrates notifications UI screens/modals from the legacy `component-library` `Button` to `@metamask/design-system-react-native` `Button`, updating prop names (e.g., `ButtonVariants`→`ButtonVariant`, `disabled`/`loading`→`isDisabled`/`isLoading`, `width`→`isFullWidth`) and switching from `label` prop to children. > > Adjusts related styling (e.g., loader button width) and updates snapshots to reflect the new button render tree/accessibility output. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 83ad008. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 3a853ff commit b68e892

7 files changed

Lines changed: 208 additions & 103 deletions

File tree

app/components/UI/Identity/ConfirmTurnOnBackupAndSyncModal/__snapshots__/ConfirmTurnOnBackupAndSyncModal.test.tsx.snap

Lines changed: 152 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -189,90 +189,189 @@ exports[`ConfirmTurnOnBackupAndSyncModal renders correctly 1`] = `
189189
}
190190
}
191191
>
192-
<TouchableOpacity
192+
<View
193+
accessibilityLabel="Cancel"
193194
accessibilityRole="button"
194-
accessible={true}
195-
activeOpacity={1}
196-
onPress={[Function]}
197-
onPressIn={[Function]}
198-
onPressOut={[Function]}
199-
style={
195+
accessibilityState={
200196
{
201-
"alignItems": "center",
202-
"alignSelf": "flex-start",
203-
"backgroundColor": "#b4b4b528",
204-
"borderColor": "transparent",
205-
"borderRadius": 12,
206-
"borderWidth": 1,
207-
"flex": 1,
208-
"flexDirection": "row",
209-
"height": 48,
210-
"justifyContent": "center",
211-
"overflow": "hidden",
212-
"paddingHorizontal": 16,
197+
"busy": undefined,
198+
"checked": undefined,
199+
"disabled": false,
200+
"expanded": undefined,
201+
"selected": undefined,
213202
}
214203
}
204+
accessibilityValue={
205+
{
206+
"max": undefined,
207+
"min": undefined,
208+
"now": undefined,
209+
"text": undefined,
210+
}
211+
}
212+
accessible={true}
213+
collapsable={false}
214+
focusable={true}
215+
onBlur={[Function]}
216+
onClick={[Function]}
217+
onFocus={[Function]}
218+
onResponderGrant={[Function]}
219+
onResponderMove={[Function]}
220+
onResponderRelease={[Function]}
221+
onResponderTerminate={[Function]}
222+
onResponderTerminationRequest={[Function]}
223+
onStartShouldSetResponder={[Function]}
224+
style={
225+
[
226+
{
227+
"alignItems": "center",
228+
"alignSelf": "flex-start",
229+
"backgroundColor": "#b4b4b528",
230+
"borderColor": "transparent",
231+
"borderRadius": 12,
232+
"borderWidth": 1,
233+
"columnGap": 8,
234+
"flexDirection": "row",
235+
"height": 48,
236+
"justifyContent": "center",
237+
"minWidth": 80,
238+
"opacity": 1,
239+
"overflow": "hidden",
240+
"paddingLeft": 16,
241+
"paddingRight": 16,
242+
},
243+
{
244+
"flex": 1,
245+
},
246+
{
247+
"transform": [
248+
{
249+
"scale": 1,
250+
},
251+
],
252+
},
253+
]
254+
}
215255
>
216256
<Text
217257
accessibilityRole="text"
258+
ellipsizeMode="clip"
259+
numberOfLines={1}
218260
style={
219-
{
220-
"color": "#131416",
221-
"fontFamily": "Geist-Medium",
222-
"fontSize": 16,
223-
"letterSpacing": 0,
224-
"lineHeight": 24,
225-
}
261+
[
262+
{
263+
"color": "#131416",
264+
"flexGrow": 0,
265+
"flexShrink": 1,
266+
"flexWrap": "wrap",
267+
"fontFamily": "Geist-Medium",
268+
"fontSize": 16,
269+
"fontWeight": 400,
270+
"letterSpacing": 0,
271+
"lineHeight": 24,
272+
"textAlign": "center",
273+
},
274+
undefined,
275+
]
226276
}
227277
>
228278
Cancel
229279
</Text>
230-
</TouchableOpacity>
280+
</View>
231281
<View
232282
style={
233283
{
234284
"width": 20,
235285
}
236286
}
237287
/>
238-
<TouchableOpacity
288+
<View
289+
accessibilityLabel="Turn on"
239290
accessibilityRole="button"
240-
accessible={true}
241-
activeOpacity={1}
242-
disabled={false}
243-
onPress={[Function]}
244-
onPressIn={[Function]}
245-
onPressOut={[Function]}
246-
style={
291+
accessibilityState={
247292
{
248-
"alignItems": "center",
249-
"alignSelf": "flex-start",
250-
"backgroundColor": "#131416",
251-
"borderRadius": 12,
252-
"flex": 1,
253-
"flexDirection": "row",
254-
"height": 48,
255-
"justifyContent": "center",
256-
"overflow": "hidden",
257-
"paddingHorizontal": 16,
293+
"busy": undefined,
294+
"checked": undefined,
295+
"disabled": false,
296+
"expanded": undefined,
297+
"selected": undefined,
258298
}
259299
}
300+
accessibilityValue={
301+
{
302+
"max": undefined,
303+
"min": undefined,
304+
"now": undefined,
305+
"text": undefined,
306+
}
307+
}
308+
accessible={true}
309+
collapsable={false}
310+
focusable={true}
311+
onBlur={[Function]}
312+
onClick={[Function]}
313+
onFocus={[Function]}
314+
onResponderGrant={[Function]}
315+
onResponderMove={[Function]}
316+
onResponderRelease={[Function]}
317+
onResponderTerminate={[Function]}
318+
onResponderTerminationRequest={[Function]}
319+
onStartShouldSetResponder={[Function]}
320+
style={
321+
[
322+
{
323+
"alignItems": "center",
324+
"alignSelf": "flex-start",
325+
"backgroundColor": "#131416",
326+
"borderRadius": 12,
327+
"columnGap": 8,
328+
"flexDirection": "row",
329+
"height": 48,
330+
"justifyContent": "center",
331+
"minWidth": 80,
332+
"opacity": 1,
333+
"overflow": "hidden",
334+
"paddingLeft": 16,
335+
"paddingRight": 16,
336+
},
337+
{
338+
"flex": 1,
339+
},
340+
{
341+
"transform": [
342+
{
343+
"scale": 1,
344+
},
345+
],
346+
},
347+
]
348+
}
260349
>
261350
<Text
262351
accessibilityRole="text"
352+
ellipsizeMode="clip"
353+
numberOfLines={1}
263354
style={
264-
{
265-
"color": "#ffffff",
266-
"fontFamily": "Geist-Medium",
267-
"fontSize": 16,
268-
"letterSpacing": 0,
269-
"lineHeight": 24,
270-
}
355+
[
356+
{
357+
"color": "#ffffff",
358+
"flexGrow": 0,
359+
"flexShrink": 1,
360+
"flexWrap": "wrap",
361+
"fontFamily": "Geist-Medium",
362+
"fontSize": 16,
363+
"fontWeight": 400,
364+
"letterSpacing": 0,
365+
"lineHeight": 24,
366+
"textAlign": "center",
367+
},
368+
undefined,
369+
]
271370
}
272371
>
273372
Turn on
274373
</Text>
275-
</TouchableOpacity>
374+
</View>
276375
</View>
277376
</View>
278377
</View>

app/components/UI/Notification/Modal/index.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ import Icon, {
99
import Text, {
1010
TextVariant,
1111
} from '../../../../component-library/components/Texts/Text';
12-
import Button, {
12+
import {
13+
Button,
14+
ButtonVariant,
1315
ButtonSize,
14-
ButtonVariants,
15-
} from '../../../../component-library/components/Buttons/Button';
16+
} from '@metamask/design-system-react-native';
1617
import createStyles from './styles';
1718
import { useTheme } from '../../../../util/theme';
1819
interface ModalContentProps {
@@ -75,27 +76,29 @@ const ModalContent = ({
7576
)}
7677
<View style={styles.buttonsContainer}>
7778
<Button
78-
variant={ButtonVariants.Secondary}
79+
variant={ButtonVariant.Secondary}
7980
size={ButtonSize.Lg}
8081
style={styles.button}
8182
accessibilityRole={'button'}
8283
accessible
83-
label={btnLabelCancel}
8484
onPress={handleCancel}
85-
/>
85+
>
86+
{btnLabelCancel}
87+
</Button>
8688
<View style={styles.spacer} />
8789
<Button
88-
variant={ButtonVariants.Primary}
90+
variant={ButtonVariant.Primary}
8991
isDisabled={hascheckBox ? !isChecked : false}
9092
isDanger={hascheckBox ?? false}
9193
size={ButtonSize.Lg}
9294
style={styles.button}
9395
accessibilityRole={'button'}
9496
accessible
95-
label={btnLabelCta}
9697
onPress={handleCta}
97-
loading={loading}
98-
/>
98+
isLoading={loading}
99+
>
100+
{btnLabelCta}
101+
</Button>
99102
</View>
100103
</View>
101104
</View>

app/components/UI/Notification/SwitchLoadingModal/Loader.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ import Icon, {
1313
} from '../../../../component-library/components/Icons/Icon';
1414

1515
import Spinner from '../../AnimatedSpinner';
16-
import Button, {
16+
import {
17+
Button,
18+
ButtonVariant,
1719
ButtonSize,
18-
ButtonVariants,
19-
ButtonWidthTypes,
20-
} from '../../../../component-library/components/Buttons/Button';
20+
} from '@metamask/design-system-react-native';
2121
import { strings } from '../../../../../locales/i18n';
2222
import type { ThemeColors } from '@metamask/design-tokens';
2323

@@ -44,6 +44,7 @@ const createStyles = (colors: ThemeColors) =>
4444
},
4545
button: {
4646
alignSelf: 'center',
47+
width: '90%',
4748
},
4849
});
4950

@@ -79,13 +80,13 @@ const Loader = ({
7980
</Text>
8081
{!!errorText && (
8182
<Button
82-
variant={ButtonVariants.Primary}
83-
label={strings('app_settings.notifications_dismiss_modal')}
83+
variant={ButtonVariant.Primary}
8484
size={ButtonSize.Md}
85-
width={'90%' as ButtonWidthTypes}
8685
onPress={onDismiss}
8786
style={styles.button}
88-
/>
87+
>
88+
{strings('app_settings.notifications_dismiss_modal')}
89+
</Button>
8990
)}
9091
</View>
9192
);

app/components/Views/Notifications/Details/Footers/AnnouncementCtaFooter.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import React from 'react';
22
import { Linking } from 'react-native';
3-
import Button, {
4-
ButtonVariants,
5-
ButtonWidthTypes,
6-
} from '../../../../../component-library/components/Buttons/Button';
3+
import { Button, ButtonVariant } from '@metamask/design-system-react-native';
74
import { ModalFooterAnnouncementCta } from '../../../../../util/notifications/notification-states/types/NotificationModalDetails';
85
import useStyles from '../useStyles';
96
import SharedDeeplinkManager from '../../../../../core/DeeplinkManager/DeeplinkManager';
@@ -66,14 +63,15 @@ export default function AnnouncementCtaFooter(
6663

6764
return (
6865
<Button
69-
variant={ButtonVariants.Primary}
70-
width={ButtonWidthTypes.Full}
71-
label={linkConfig.label}
66+
variant={ButtonVariant.Primary}
67+
isFullWidth
7268
style={styles.ctaBtn}
7369
onPress={() => {
7470
callEvent();
7571
linkConfig.onPress();
7672
}}
77-
/>
73+
>
74+
{linkConfig.label}
75+
</Button>
7876
);
7977
}

0 commit comments

Comments
 (0)