Skip to content

Commit 7e3b289

Browse files
salimtbdarkwing
andauthored
feat: edit custom network flow (#25272)
<!-- 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** Edit network flow from the modal added <!-- 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? --> [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/25272?quickstart=1) ## **Related issues** Fixes: ## **Manual testing steps** 1. Run `yarn && ENABLE_NETWORK_UI_REDESIGN=1 yarn start` 2. Go to Settings -> Developer Options 3. Tun on the network new toggle 4. Go to the wallet page 5. Click on the network button ( see the video below ) 6. click on the three points button 7. click on edit 8. you should be able to edit a network ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** https://github.com/MetaMask/metamask-extension/assets/26223211/cc2e7716-cb13-4158-9994-1c7bccf377ad ### **After** https://github.com/MetaMask/metamask-extension/assets/26223211/c6473a45-bdd1-49d7-81bd-cf92f55376f5 ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.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: David Walsh <[email protected]>
1 parent a6ebbc7 commit 7e3b289

File tree

22 files changed

+774
-214
lines changed

22 files changed

+774
-214
lines changed

app/_locales/en/messages.json

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ui/components/multichain/multichain-components.scss

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
@import 'connected-site-menu';
2020
@import 'token-list-item';
2121
@import 'network-list-item';
22+
@import 'network-list-item-menu';
2223
@import 'network-list-menu';
2324
@import 'product-tour-popover';
2425
@import 'nft-item';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { NetworkListItemMenu } from './network-list-item-menu';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@use "design-system";
2+
3+
.multichain-network-list-item-menu__popover {
4+
z-index: design-system.$popover-in-modal-z-index;
5+
overflow: hidden;
6+
min-width: 225px;
7+
max-width: 225px;
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { useI18nContext } from '../../../hooks/useI18nContext';
4+
import {
5+
IconName,
6+
ModalFocus,
7+
Popover,
8+
PopoverPosition,
9+
PopoverRole,
10+
Text,
11+
} from '../../component-library';
12+
import { MenuItem } from '../../ui/menu';
13+
import { IconColor, TextColor } from '../../../helpers/constants/design-system';
14+
15+
export const NetworkListItemMenu = ({
16+
anchorElement,
17+
onClose,
18+
onEditClick,
19+
onDeleteClick,
20+
isOpen,
21+
}) => {
22+
const t = useI18nContext();
23+
24+
return (
25+
<Popover
26+
className="multichain-network-list-item-menu__popover"
27+
onClickOutside={onClose}
28+
referenceElement={anchorElement}
29+
role={PopoverRole.Dialog}
30+
position={PopoverPosition.Bottom}
31+
offset={[0, 0]}
32+
padding={0}
33+
isOpen={isOpen}
34+
isPortal
35+
preventOverflow
36+
flip
37+
>
38+
<ModalFocus restoreFocus initialFocusRef={anchorElement}>
39+
<div>
40+
{onEditClick ? (
41+
<MenuItem
42+
iconName={IconName.Edit}
43+
onClick={(e) => {
44+
e.stopPropagation();
45+
46+
// Pass network info?
47+
onEditClick();
48+
}}
49+
data-testid="network-list-item-options-edit"
50+
>
51+
{t('edit')}
52+
</MenuItem>
53+
) : null}
54+
{onDeleteClick ? (
55+
<MenuItem
56+
iconName={IconName.Trash}
57+
iconColor={IconColor.errorDefault}
58+
onClick={(e) => {
59+
e.stopPropagation();
60+
61+
// Pass network info?
62+
onDeleteClick();
63+
}}
64+
data-testid="network-list-item-options-delete"
65+
>
66+
<Text color={TextColor.errorDefault}>{t('delete')}</Text>
67+
</MenuItem>
68+
) : null}
69+
</div>
70+
</ModalFocus>
71+
</Popover>
72+
);
73+
};
74+
75+
NetworkListItemMenu.propTypes = {
76+
/**
77+
* Element that the menu should display next to
78+
*/
79+
anchorElement: PropTypes.instanceOf(window.Element),
80+
/**
81+
* Function that executes when the menu is closed
82+
*/
83+
onClose: PropTypes.func.isRequired,
84+
/**
85+
* Function that executes when the Edit menu item is clicked
86+
*/
87+
onEditClick: PropTypes.func,
88+
/**
89+
* Function that executes when the Delete menu item is closed
90+
*/
91+
onDeleteClick: PropTypes.func,
92+
/**
93+
* Represents if the menu is open or not
94+
*
95+
* @type {boolean}
96+
*/
97+
isOpen: PropTypes.bool.isRequired,
98+
};

ui/components/multichain/network-list-item/index.scss

-12
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,6 @@
1414
color: inherit;
1515
}
1616

17-
&:hover,
18-
&:focus,
19-
&:focus-within {
20-
.multichain-network-list-item__delete {
21-
visibility: visible;
22-
}
23-
}
24-
2517
&__network-name {
2618
width: 100%;
2719
flex: 1;
@@ -44,8 +36,4 @@
4436
top: 4px;
4537
left: 4px;
4638
}
47-
48-
&__delete {
49-
visibility: hidden;
50-
}
5139
}

ui/components/multichain/network-list-item/network-list-item.js

+61-16
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,32 @@
1-
import React, { useEffect, useRef } from 'react';
1+
import React, { useEffect, useRef, useState } from 'react';
22
import classnames from 'classnames';
33
import PropTypes from 'prop-types';
4+
import { useSelector } from 'react-redux';
45
import {
56
AlignItems,
67
BackgroundColor,
78
BlockSize,
89
BorderRadius,
910
Color,
1011
Display,
11-
IconColor,
1212
JustifyContent,
13-
Size,
1413
TextColor,
14+
Size,
15+
IconColor,
1516
} from '../../../helpers/constants/design-system';
1617
import {
1718
AvatarNetwork,
1819
Box,
1920
ButtonIcon,
21+
ButtonIconSize,
2022
IconName,
2123
Text,
2224
} from '../../component-library';
2325
import { useI18nContext } from '../../../hooks/useI18nContext';
2426
import { getAvatarNetworkColor } from '../../../helpers/utils/accounts';
2527
import Tooltip from '../../ui/tooltip/tooltip';
28+
import { NetworkListItemMenu } from '../network-list-item-menu';
29+
import { getLocalNetworkMenuRedesignFeatureFlag } from '../../../helpers/utils/feature-flags';
2630

2731
const MAXIMUM_CHARACTERS_WITHOUT_TOOLTIP = 20;
2832

@@ -33,10 +37,52 @@ export const NetworkListItem = ({
3337
focus = true,
3438
onClick,
3539
onDeleteClick,
40+
onEditClick,
3641
}) => {
3742
const t = useI18nContext();
3843
const networkRef = useRef();
3944

45+
const [networkListItemMenuElement, setNetworkListItemMenuElement] =
46+
useState();
47+
const setNetworkListItemMenuRef = (ref) => {
48+
setNetworkListItemMenuElement(ref);
49+
};
50+
const [networkOptionsMenuOpen, setNetworkOptionsMenuOpen] = useState(false);
51+
const networkMenuRedesign = useSelector(
52+
getLocalNetworkMenuRedesignFeatureFlag,
53+
);
54+
55+
const renderButton = () => {
56+
if (networkMenuRedesign) {
57+
return onDeleteClick || onEditClick ? (
58+
<ButtonIcon
59+
iconName={IconName.MoreVertical}
60+
ref={setNetworkListItemMenuRef}
61+
data-testid="network-list-item-options-button"
62+
ariaLabel={t('networkOptions')}
63+
onClick={(e) => {
64+
e.stopPropagation();
65+
setNetworkOptionsMenuOpen(true);
66+
}}
67+
size={ButtonIconSize.Sm}
68+
/>
69+
) : null;
70+
}
71+
72+
return onDeleteClick ? (
73+
<ButtonIcon
74+
className="multichain-network-list-item__delete"
75+
color={IconColor.errorDefault}
76+
iconName={IconName.Trash}
77+
ariaLabel={t('deleteNetwork')}
78+
size={Size.SM}
79+
onClick={(e) => {
80+
e.stopPropagation();
81+
onDeleteClick();
82+
}}
83+
/>
84+
) : null;
85+
};
4086
useEffect(() => {
4187
if (networkRef.current && focus) {
4288
networkRef.current.focus();
@@ -103,19 +149,14 @@ export const NetworkListItem = ({
103149
)}
104150
</Text>
105151
</Box>
106-
{onDeleteClick ? (
107-
<ButtonIcon
108-
className="multichain-network-list-item__delete"
109-
color={IconColor.errorDefault}
110-
iconName={IconName.Trash}
111-
ariaLabel={t('deleteNetwork')}
112-
size={Size.SM}
113-
onClick={(e) => {
114-
e.stopPropagation();
115-
onDeleteClick();
116-
}}
117-
/>
118-
) : null}
152+
{renderButton()}
153+
<NetworkListItemMenu
154+
anchorElement={networkListItemMenuElement}
155+
isOpen={networkOptionsMenuOpen}
156+
onDeleteClick={onDeleteClick}
157+
onEditClick={onEditClick}
158+
onClose={() => setNetworkOptionsMenuOpen(false)}
159+
/>
119160
</Box>
120161
);
121162
};
@@ -141,6 +182,10 @@ NetworkListItem.propTypes = {
141182
* Executes when the delete icon is clicked
142183
*/
143184
onDeleteClick: PropTypes.func,
185+
/**
186+
* Executes when the edit icon is clicked
187+
*/
188+
onEditClick: PropTypes.func,
144189
/**
145190
* Represents if the network item should be keyboard selected
146191
*/

0 commit comments

Comments
 (0)