diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 03f2c2de29d2..10fd6d792df8 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -2537,6 +2537,19 @@ "message": "Swapping on mobile is here!", "description": "Title for a notification in the 'See What's New' popup. Tells users that they can now use MetaMask Swaps on Mobile." }, + "notifications20ActionText": { + "message": "Learn more", + "description": "The 'call to action' on the button, or link, of the 'Stay secure' notification. Upon clicking, users will be taken to a ledger page to resolve the U2F connection issue." + }, + + "notifications20Description": { + "message": "If you're on the latest version of Firefox, you might be experiencing an issue related to Firefox dropping U2F support.", + "description": "Description of a notification in the 'See What's New' popup. Describes the U2F support being dropped by firefox and that it affects ledger users." + }, + "notifications20Title": { + "message": "Ledger and Firefox Users Experiencing Connection Issues", + "description": "Title for a notification in the 'See What's New' popup. Tells users that latest firefox users using U2F may experience connection issues." + }, "notifications3ActionText": { "message": "Read more", "description": "The 'call to action' on the button, or link, of the 'Stay secure' notification. Upon clicking, users will be taken to a page about security on the metamask support website." @@ -4541,6 +4554,22 @@ "transferFrom": { "message": "Transfer from" }, + "troubleConnectingToLedgerU2FOnFirefox": { + "message": "We're having trouble connecting your Ledger. $1", + "description": "$1 is a link to the wallet connection guide;" + }, + "troubleConnectingToLedgerU2FOnFirefox2": { + "message": "Review our hardware wallet connection guide and try again.", + "description": "$1 of the ledger wallet connection guide" + }, + "troubleConnectingToLedgerU2FOnFirefoxLedgerSolution": { + "message": "If you're on the latest version of Firefox, you might be experiencing an issue related to Firefox dropping U2F support. Learn how to fix this issue $1.", + "description": "It is a link to the ledger website for the workaround." + }, + "troubleConnectingToLedgerU2FOnFirefoxLedgerSolution2": { + "message": "here", + "description": "Second part of the error message; It is a link to the ledger website for the workaround." + }, "troubleConnectingToWallet": { "message": "We had trouble connecting to your $1, try reviewing $2 and try again.", "description": "$1 is the wallet device name; $2 is a link to wallet connection guide" diff --git a/app/scripts/controllers/network/network-controller.test.ts b/app/scripts/controllers/network/network-controller.test.ts index 8368decd0e92..2e2c1b0b9052 100644 --- a/app/scripts/controllers/network/network-controller.test.ts +++ b/app/scripts/controllers/network/network-controller.test.ts @@ -6740,7 +6740,7 @@ describe('NetworkController', () => { it('throws if the given chain ID is not a 0x-prefixed hex number', async () => { const invalidChainId = '1'; await withController(async ({ controller }) => { - expect(() => + await expect(() => controller.upsertNetworkConfiguration( { /* @ts-expect-error We are intentionally passing bad input. */ @@ -6755,7 +6755,7 @@ describe('NetworkController', () => { source: MetaMetricsNetworkEventSource.Dapp, }, ), - ).toThrow( + ).rejects.toThrow( new Error( `Invalid chain ID "${invalidChainId}": invalid hex string.`, ), @@ -6765,7 +6765,7 @@ describe('NetworkController', () => { it('throws if the given chain ID is greater than the maximum allowed ID', async () => { await withController(async ({ controller }) => { - expect(() => + await expect(() => controller.upsertNetworkConfiguration( { chainId: '0xFFFFFFFFFFFFFFFF', @@ -6779,7 +6779,7 @@ describe('NetworkController', () => { source: MetaMetricsNetworkEventSource.Dapp, }, ), - ).toThrow( + ).rejects.toThrow( new Error( 'Invalid chain ID "0xFFFFFFFFFFFFFFFF": numerical value greater than max safe value.', ), @@ -6789,7 +6789,7 @@ describe('NetworkController', () => { it('throws if the no (or a falsy) rpcUrl is passed', async () => { await withController(async ({ controller }) => { - expect(() => + await expect(() => controller.upsertNetworkConfiguration( /* @ts-expect-error We are intentionally passing bad input. */ { @@ -6803,7 +6803,7 @@ describe('NetworkController', () => { source: MetaMetricsNetworkEventSource.Dapp, }, ), - ).toThrow( + ).rejects.toThrow( new Error( 'An rpcUrl is required to add or update network configuration', ), @@ -6813,7 +6813,7 @@ describe('NetworkController', () => { it('throws if rpcUrl passed is not a valid Url', async () => { await withController(async ({ controller }) => { - expect(() => + await expect(() => controller.upsertNetworkConfiguration( { chainId: '0x9999', @@ -6827,13 +6827,13 @@ describe('NetworkController', () => { source: MetaMetricsNetworkEventSource.Dapp, }, ), - ).toThrow(new Error('rpcUrl must be a valid URL')); + ).rejects.toThrow(new Error('rpcUrl must be a valid URL')); }); }); it('throws if the no (or a falsy) ticker is passed', async () => { await withController(async ({ controller }) => { - expect(() => + await expect(() => controller.upsertNetworkConfiguration( /* @ts-expect-error We are intentionally passing bad input. */ { @@ -6847,7 +6847,7 @@ describe('NetworkController', () => { source: MetaMetricsNetworkEventSource.Dapp, }, ), - ).toThrow( + ).rejects.toThrow( new Error( 'A ticker is required to add or update networkConfiguration', ), @@ -6857,7 +6857,7 @@ describe('NetworkController', () => { it('throws if an options object is not passed as a second argument', async () => { await withController(async ({ controller }) => { - expect(() => + await expect(() => /* @ts-expect-error We are intentionally passing bad input. */ controller.upsertNetworkConfiguration({ chainId: '0x5', @@ -6865,7 +6865,7 @@ describe('NetworkController', () => { rpcPrefs: { blockExplorerUrl: 'test-block-explorer.com' }, rpcUrl: 'https://mock-rpc-url', }), - ).toThrow( + ).rejects.toThrow( new Error( "Cannot read properties of undefined (reading 'setActive')", ), @@ -6888,7 +6888,7 @@ describe('NetworkController', () => { ticker: 'test_ticker', }; - controller.upsertNetworkConfiguration(rpcUrlNetwork, { + await controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', source: MetaMetricsNetworkEventSource.Dapp, }); @@ -6926,7 +6926,7 @@ describe('NetworkController', () => { invalidKey2: {}, }; - controller.upsertNetworkConfiguration(rpcUrlNetwork, { + await controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', source: MetaMetricsNetworkEventSource.Dapp, }); @@ -6975,7 +6975,7 @@ describe('NetworkController', () => { ticker: 'RPC', }; - controller.upsertNetworkConfiguration(rpcUrlNetwork, { + await controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', source: MetaMetricsNetworkEventSource.Dapp, }); @@ -7024,7 +7024,7 @@ describe('NetworkController', () => { rpcPrefs: { blockExplorerUrl: 'alternativetestchainscan.io' }, chainId: '0x1' as const, }; - controller.upsertNetworkConfiguration(updatedConfiguration, { + await controller.upsertNetworkConfiguration(updatedConfiguration, { referrer: 'https://test-dapp.com', source: MetaMetricsNetworkEventSource.Dapp, }); @@ -7069,7 +7069,7 @@ describe('NetworkController', () => { }, }, async ({ controller }) => { - controller.upsertNetworkConfiguration( + await controller.upsertNetworkConfiguration( { rpcUrl: 'https://test-rpc-url', ticker: 'new-ticker', @@ -7136,7 +7136,7 @@ describe('NetworkController', () => { ticker: 'test_ticker', }; - controller.upsertNetworkConfiguration(rpcUrlNetwork, { + await controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', source: MetaMetricsNetworkEventSource.Dapp, }); @@ -7180,7 +7180,7 @@ describe('NetworkController', () => { ticker: 'test_ticker', }; - controller.upsertNetworkConfiguration(rpcUrlNetwork, { + await controller.upsertNetworkConfiguration(rpcUrlNetwork, { setActive: true, referrer: 'https://test-dapp.com', source: MetaMetricsNetworkEventSource.Dapp, @@ -7229,7 +7229,7 @@ describe('NetworkController', () => { rpcPrefs: { blockExplorerUrl: 'https://block-explorer' }, }; - controller.upsertNetworkConfiguration(newNetworkConfiguration, { + await controller.upsertNetworkConfiguration(newNetworkConfiguration, { referrer: 'https://test-dapp.com', source: MetaMetricsNetworkEventSource.Dapp, }); @@ -7296,10 +7296,10 @@ describe('NetworkController', () => { rpcPrefs: { blockExplorerUrl: 'https://block-explorer' }, }; - expect(() => { + await expect(() => /* @ts-expect-error We are intentionally passing bad input. */ - controller.upsertNetworkConfiguration(newNetworkConfiguration, {}); - }).toThrow( + controller.upsertNetworkConfiguration(newNetworkConfiguration, {}), + ).rejects.toThrow( 'referrer and source are required arguments for adding or updating a network configuration', ); }, diff --git a/app/scripts/controllers/network/network-controller.ts b/app/scripts/controllers/network/network-controller.ts index 9b95a8c7cb43..eaf3f6931933 100644 --- a/app/scripts/controllers/network/network-controller.ts +++ b/app/scripts/controllers/network/network-controller.ts @@ -1034,7 +1034,7 @@ export class NetworkController extends EventEmitter { * @throws if `rpcUrl` is not a valid URL. * @returns The ID for the added or updated network configuration. */ - upsertNetworkConfiguration( + async upsertNetworkConfiguration( { rpcUrl, chainId, @@ -1051,7 +1051,7 @@ export class NetworkController extends EventEmitter { referrer: string; source: string; }, - ): NetworkConfigurationId { + ): Promise { assert.ok( isPrefixedFormattedHexString(chainId), `Invalid chain ID "${chainId}": invalid hex string.`, @@ -1129,7 +1129,7 @@ export class NetworkController extends EventEmitter { } if (setActive) { - this.setActiveNetwork(newNetworkConfigurationId); + await this.setActiveNetwork(newNetworkConfigurationId); } return newNetworkConfigurationId; diff --git a/app/scripts/controllers/swaps.js b/app/scripts/controllers/swaps.js index 5030f1cd391f..b44e66a21922 100644 --- a/app/scripts/controllers/swaps.js +++ b/app/scripts/controllers/swaps.js @@ -113,7 +113,7 @@ export default class SwapsController { fetchTradesInfo = defaultFetchTradesInfo, getCurrentChainId, getEIP1559GasFeeEstimates, - onNetworkDidChange, + onNetworkStateChange, }) { this.store = new ObservableStore({ swapsState: { ...initialState.swapsState }, @@ -137,7 +137,7 @@ export default class SwapsController { this.ethersProvider = new Web3Provider(provider); this._currentNetworkId = networkController.store.getState().networkId; - onNetworkDidChange(() => { + onNetworkStateChange(() => { const { networkId, networkStatus } = networkController.store.getState(); if ( networkStatus === NetworkStatus.Available && diff --git a/app/scripts/controllers/swaps.test.js b/app/scripts/controllers/swaps.test.js index f5a43e0dcab4..e3dbaafda48d 100644 --- a/app/scripts/controllers/swaps.test.js +++ b/app/scripts/controllers/swaps.test.js @@ -160,7 +160,7 @@ describe('SwapsController', function () { return new SwapsController({ getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, networkController: getMockNetworkController(), - onNetworkDidChange: sinon.stub(), + onNetworkStateChange: sinon.stub(), provider: _provider, getProviderConfig: MOCK_GET_PROVIDER_CONFIG, getTokenRatesState: MOCK_TOKEN_RATES_STORE, @@ -208,11 +208,11 @@ describe('SwapsController', function () { it('should replace ethers instance when network changes', function () { const networkController = getMockNetworkController(); - const onNetworkDidChange = sinon.stub(); + const onNetworkStateChange = sinon.stub(); const swapsController = new SwapsController({ getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, networkController, - onNetworkDidChange, + onNetworkStateChange, provider, getProviderConfig: MOCK_GET_PROVIDER_CONFIG, getTokenRatesState: MOCK_TOKEN_RATES_STORE, @@ -220,7 +220,7 @@ describe('SwapsController', function () { getCurrentChainId: getCurrentChainIdStub, }); const currentEthersInstance = swapsController.ethersProvider; - const changeNetwork = onNetworkDidChange.getCall(0).args[0]; + const changeNetwork = onNetworkStateChange.getCall(0).args[0]; networkController.store.getState.returns({ networkId: NETWORK_IDS.MAINNET, @@ -238,11 +238,11 @@ describe('SwapsController', function () { it('should not replace ethers instance when network changes to loading', function () { const networkController = getMockNetworkController(); - const onNetworkDidChange = sinon.stub(); + const onNetworkStateChange = sinon.stub(); const swapsController = new SwapsController({ getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, networkController, - onNetworkDidChange, + onNetworkStateChange, provider, getProviderConfig: MOCK_GET_PROVIDER_CONFIG, getTokenRatesState: MOCK_TOKEN_RATES_STORE, @@ -250,7 +250,7 @@ describe('SwapsController', function () { getCurrentChainId: getCurrentChainIdStub, }); const currentEthersInstance = swapsController.ethersProvider; - const changeNetwork = onNetworkDidChange.getCall(0).args[0]; + const changeNetwork = onNetworkStateChange.getCall(0).args[0]; networkController.store.getState.returns({ networkId: null, @@ -268,11 +268,11 @@ describe('SwapsController', function () { it('should not replace ethers instance when network changes to the same network', function () { const networkController = getMockNetworkController(); - const onNetworkDidChange = sinon.stub(); + const onNetworkStateChange = sinon.stub(); const swapsController = new SwapsController({ getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, networkController, - onNetworkDidChange, + onNetworkStateChange, provider, getProviderConfig: MOCK_GET_PROVIDER_CONFIG, getTokenRatesState: MOCK_TOKEN_RATES_STORE, @@ -280,7 +280,7 @@ describe('SwapsController', function () { getCurrentChainId: getCurrentChainIdStub, }); const currentEthersInstance = swapsController.ethersProvider; - const changeNetwork = onNetworkDidChange.getCall(0).args[0]; + const changeNetwork = onNetworkStateChange.getCall(0).args[0]; networkController.store.getState.returns({ networkId: NETWORK_IDS.GOERLI, diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index fa619c62f133..f24e1777abca 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1195,10 +1195,8 @@ export default class MetamaskController extends EventEmitter { this.txController.txGasUtil, ), networkController: this.networkController, - onNetworkDidChange: networkControllerMessenger.subscribe.bind( - networkControllerMessenger, - NetworkControllerEventType.NetworkDidChange, - ), + onNetworkStateChange: (listener) => + this.networkController.store.subscribe(listener), provider: this.provider, getProviderConfig: () => this.networkController.store.getState().provider, getTokenRatesState: () => this.tokenRatesController.state, diff --git a/coverage-targets.js b/coverage-targets.js index 1ed939c2fc45..f9c2577b06e3 100644 --- a/coverage-targets.js +++ b/coverage-targets.js @@ -6,10 +6,10 @@ // subset of files to check against these targets. module.exports = { global: { - lines: 67.8, - branches: 55.84, - statements: 67.13, - functions: 59.66, + lines: 68.5, + branches: 56.34, + statements: 67.86, + functions: 60.69, }, transforms: { branches: 100, diff --git a/shared/notifications/index.js b/shared/notifications/index.js index 10c24bbfeb19..9bf2859572f1 100644 --- a/shared/notifications/index.js +++ b/shared/notifications/index.js @@ -102,6 +102,10 @@ export const UI_NOTIFICATIONS = { width: '100%', }, }, + 20: { + id: 20, + date: null, + }, }; export const getTranslatedUINotifications = (t, locale) => { @@ -279,5 +283,16 @@ export const getTranslatedUINotifications = (t, locale) => { ) : '', }, + 20: { + ...UI_NOTIFICATIONS[20], + title: t('notifications20Title'), + description: [t('notifications20Description')], + actionText: t('notifications20ActionText'), + date: UI_NOTIFICATIONS[20].date + ? new Intl.DateTimeFormat(formattedLocale).format( + new Date(UI_NOTIFICATIONS[20].date), + ) + : '', + }, }; }; diff --git a/ui/components/app/account-menu/account-menu.component.js b/ui/components/app/account-menu/account-menu.component.js index e1198048950c..7c0b98bc3243 100644 --- a/ui/components/app/account-menu/account-menu.component.js +++ b/ui/components/app/account-menu/account-menu.component.js @@ -37,11 +37,7 @@ import Button from '../../ui/button'; import SearchIcon from '../../ui/icon/search-icon'; import { SUPPORT_LINK } from '../../../../shared/lib/ui-utils'; import { IconColor } from '../../../helpers/constants/design-system'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; import KeyRingLabel from './keyring-label'; export function AccountMenuItem(props) { @@ -229,8 +225,8 @@ export default class AccountMenu extends Component { {isSelected ? ( ) : null} @@ -374,9 +370,7 @@ export default class AccountMenu extends Component { }); history.push(NEW_ACCOUNT_ROUTE); }} - icon={ - - } + icon={} text={t('createAccount')} /> + } text={t('importAccount')} /> @@ -415,10 +409,7 @@ export default class AccountMenu extends Component { } }} icon={ - + } text={t('connectHardwareWallet')} /> @@ -433,7 +424,7 @@ export default class AccountMenu extends Component { }} icon={
- + {unreadNotificationsCount > 0 && (
{unreadNotificationsCount} @@ -466,10 +457,7 @@ export default class AccountMenu extends Component { global.platform.openTab({ url: supportLink }); }} icon={ - + } text={supportText} /> @@ -488,7 +476,7 @@ export default class AccountMenu extends Component { }} icon={ diff --git a/ui/components/app/add-network/add-network.js b/ui/components/app/add-network/add-network.js index 83ec791b97b3..d8eae27ee20a 100644 --- a/ui/components/app/add-network/add-network.js +++ b/ui/components/app/add-network/add-network.js @@ -36,12 +36,7 @@ import { FEATURED_RPCS } from '../../../../shared/constants/network'; import { ADD_NETWORK_ROUTE } from '../../../helpers/constants/routes'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import ZENDESK_URLS from '../../../helpers/constants/zendesk-url'; -import { Text } from '../../component-library'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Text, Icon, IconName, IconSize } from '../../component-library'; import { MetaMetricsNetworkEventSource } from '../../../../shared/constants/metametrics'; const AddNetwork = () => { @@ -249,9 +244,9 @@ const AddNetwork = () => { > ) diff --git a/ui/components/app/approve-content-card/approve-content-card.stories.js b/ui/components/app/approve-content-card/approve-content-card.stories.js index 6ae43c22ce62..17216ba18c10 100644 --- a/ui/components/app/approve-content-card/approve-content-card.stories.js +++ b/ui/components/app/approve-content-card/approve-content-card.stories.js @@ -1,5 +1,5 @@ import React from 'react'; -import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../component-library'; import ApproveContentCard from './approve-content-card'; export default { @@ -72,7 +72,7 @@ export default { }, args: { showHeader: true, - symbol: , + symbol: , title: 'Transaction fee', showEdit: true, showAdvanceGasFeeOptions: true, diff --git a/ui/components/app/asset-list-item/asset-list-item.js b/ui/components/app/asset-list-item/asset-list-item.js index 2be1b78b6721..d5b2b3f63dc8 100644 --- a/ui/components/app/asset-list-item/asset-list-item.js +++ b/ui/components/app/asset-list-item/asset-list-item.js @@ -16,11 +16,7 @@ import { INVALID_ASSET_TYPE } from '../../../helpers/constants/error-keys'; import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; import { AssetType } from '../../../../shared/constants/transaction'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; import Box from '../../ui/box/box'; const AssetListItem = ({ @@ -143,9 +139,9 @@ const AssetListItem = ({ !isERC721 && ( {sendTokenButton} diff --git a/ui/components/app/beta-header/index.js b/ui/components/app/beta-header/index.js index f030d53f6502..1eb7bfbe0a0e 100644 --- a/ui/components/app/beta-header/index.js +++ b/ui/components/app/beta-header/index.js @@ -14,11 +14,7 @@ import { import { BETA_BUGS_URL } from '../../../helpers/constants/beta'; import { hideBetaHeader } from '../../../store/actions'; -import { ButtonIcon } from '../../component-library/button-icon/deprecated'; -import { - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { ButtonIcon, ButtonIconSize, IconName } from '../../component-library'; const BetaHeader = () => { const t = useI18nContext(); @@ -51,8 +47,8 @@ const BetaHeader = () => { ])} - + { const t = useI18nContext(); @@ -60,10 +55,10 @@ const ConfirmationWarningModal = ({ onSubmit, onCancel }) => { className="confirmation-warning-modal__content__header" > - + {t('disconnectThisAccount')} diff --git a/ui/components/app/custom-spending-cap/__snapshots__/custom-spending-cap.test.js.snap b/ui/components/app/custom-spending-cap/__snapshots__/custom-spending-cap.test.js.snap index ba7f51b8939e..d72f4736dd9d 100644 --- a/ui/components/app/custom-spending-cap/__snapshots__/custom-spending-cap.test.js.snap +++ b/ui/components/app/custom-spending-cap/__snapshots__/custom-spending-cap.test.js.snap @@ -42,7 +42,7 @@ exports[`CustomSpendingCap should match snapshot 1`] = ` tabindex="0" >
diff --git a/ui/components/app/custom-spending-cap/custom-spending-cap-tooltip.js b/ui/components/app/custom-spending-cap/custom-spending-cap-tooltip.js index b9113b2c19b0..49aebd8e46e8 100644 --- a/ui/components/app/custom-spending-cap/custom-spending-cap-tooltip.js +++ b/ui/components/app/custom-spending-cap/custom-spending-cap-tooltip.js @@ -8,11 +8,7 @@ import { DISPLAY, TypographyVariant, } from '../../../helpers/constants/design-system'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; export const CustomSpendingCapTooltip = ({ tooltipContentText, @@ -35,13 +31,15 @@ export const CustomSpendingCapTooltip = ({ > {tooltipIcon ? ( ) : ( - tooltipIcon !== '' && + tooltipIcon !== '' && ( + + ) )} diff --git a/ui/components/app/custom-spending-cap/custom-spending-cap.js b/ui/components/app/custom-spending-cap/custom-spending-cap.js index 23e8d16eed84..0614b0f36d7d 100644 --- a/ui/components/app/custom-spending-cap/custom-spending-cap.js +++ b/ui/components/app/custom-spending-cap/custom-spending-cap.js @@ -8,8 +8,7 @@ import { addHexPrefix } from 'ethereumjs-util'; import { I18nContext } from '../../../contexts/i18n'; import Box from '../../ui/box'; import FormField from '../../ui/form-field'; -import { Text, ButtonLink } from '../../component-library'; -import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; +import { Text, ButtonLink, Icon, IconName } from '../../component-library'; import { AlignItems, DISPLAY, @@ -196,7 +195,7 @@ export default function CustomSpendingCap({ as="h6" color={TextColor.errorDefault} > - {t('beCareful')} + {t('beCareful')} , ]) : t('inputLogicEmptyState'); diff --git a/ui/components/app/dropdowns/network-dropdown.js b/ui/components/app/dropdowns/network-dropdown.js index 131b700f63be..8b44fed0ed62 100644 --- a/ui/components/app/dropdowns/network-dropdown.js +++ b/ui/components/app/dropdowns/network-dropdown.js @@ -33,11 +33,7 @@ import { ADVANCED_ROUTE, } from '../../../helpers/constants/routes'; import { ButtonIcon } from '../../component-library/button-icon/deprecated'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; import { Dropdown, DropdownMenuItem } from './dropdown'; @@ -191,7 +187,7 @@ class NetworkDropdown extends Component { }} > {isCurrentRpcTarget ? ( - + ) : (
)} @@ -214,8 +210,8 @@ class NetworkDropdown extends Component { {isCurrentRpcTarget ? null : ( { e.stopPropagation(); @@ -265,7 +261,7 @@ class NetworkDropdown extends Component { style={DROP_DOWN_MENU_ITEM_STYLE} > {providerType === network ? ( - + ) : (
)} @@ -334,7 +330,7 @@ class NetworkDropdown extends Component { style={DROP_DOWN_MENU_ITEM_STYLE} > {isCurrentRpcTarget ? ( - + ) : (
)} diff --git a/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.js b/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.js index 378be5480ab9..e3ee7fa00c5f 100644 --- a/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.js +++ b/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.js @@ -14,11 +14,7 @@ import { useTransactionEventFragment } from '../../../hooks/useTransactionEventF import { useTransactionModalContext } from '../../../contexts/transaction-modal'; import InfoTooltip from '../../ui/info-tooltip/info-tooltip'; import Typography from '../../ui/typography/typography'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; export default function EditGasFeeButton({ userAcknowledgedGasMissing }) { const t = useI18nContext(); @@ -78,9 +74,9 @@ export default function EditGasFeeButton({ userAcknowledgedGasMissing }) { )} {t(title)} {estimateUsed === 'custom' && ( diff --git a/ui/components/app/flask/copyable/copyable.js b/ui/components/app/flask/copyable/copyable.js index 2741fd6c4406..59cb51e6bfd4 100644 --- a/ui/components/app/flask/copyable/copyable.js +++ b/ui/components/app/flask/copyable/copyable.js @@ -14,11 +14,7 @@ import { Color, } from '../../../../helpers/constants/design-system'; import { useCopyToClipboard } from '../../../../hooks/useCopyToClipboard'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../../component-library'; export const Copyable = ({ text }) => { const [copied, handleCopy] = useCopyToClipboard(); @@ -51,14 +47,14 @@ export const Copyable = ({ text }) => { > {copied ? ( ) : ( handleCopy(text)} /> diff --git a/ui/components/app/flask/snap-authorship/snap-authorship.js b/ui/components/app/flask/snap-authorship/snap-authorship.js index 4c44d20ebdea..66f3fa59bb18 100644 --- a/ui/components/app/flask/snap-authorship/snap-authorship.js +++ b/ui/components/app/flask/snap-authorship/snap-authorship.js @@ -20,12 +20,8 @@ import { getSnapName, removeSnapIdPrefix, } from '../../../../helpers/utils/util'; -import { ButtonIcon } from '../../../component-library/button-icon/deprecated'; -import { Text } from '../../../component-library'; -import { - ICON_NAMES, - ICON_SIZES, -} from '../../../component-library/icon/deprecated'; +import { ButtonIcon, IconName, Text } from '../../../component-library'; + import { getTargetSubjectMetadata } from '../../../../selectors'; import SnapAvatar from '../snap-avatar'; @@ -85,9 +81,8 @@ const SnapAuthorship = ({ snapId, className }) => { rel="noopener noreferrer" target="_blank" href={url} - iconName={ICON_NAMES.EXPORT} + iconName={IconName.Export} color={IconColor.infoDefault} - size={ICON_SIZES.MD} style={{ marginLeft: 'auto' }} /> diff --git a/ui/components/app/flask/snap-avatar/snap-avatar.js b/ui/components/app/flask/snap-avatar/snap-avatar.js index 81e101b814ae..4e16b8a2adf8 100644 --- a/ui/components/app/flask/snap-avatar/snap-avatar.js +++ b/ui/components/app/flask/snap-avatar/snap-avatar.js @@ -17,11 +17,9 @@ import { BadgeWrapperPosition, AvatarIcon, AvatarBase, + IconName, + IconSize, } from '../../../component-library'; -import { - ICON_NAMES, - ICON_SIZES, -} from '../../../component-library/icon/deprecated'; import { getTargetSubjectMetadata } from '../../../../selectors'; const SnapAvatar = ({ snapId, className }) => { @@ -40,11 +38,11 @@ const SnapAvatar = ({ snapId, className }) => { className={classnames('snap-avatar', className)} badge={ diff --git a/ui/components/app/flask/snap-content-footer/snap-content-footer.js b/ui/components/app/flask/snap-content-footer/snap-content-footer.js index aa5f385d1ddf..f8b31826aebc 100644 --- a/ui/components/app/flask/snap-content-footer/snap-content-footer.js +++ b/ui/components/app/flask/snap-content-footer/snap-content-footer.js @@ -16,7 +16,7 @@ import { } from '../../../../helpers/constants/design-system'; import Button from '../../../ui/button'; import Box from '../../../ui/box/box'; -import { Icon, ICON_NAMES } from '../../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../../component-library'; export default function SnapContentFooter({ snapName, snapId }) { const t = useI18nContext(); @@ -36,7 +36,7 @@ export default function SnapContentFooter({ snapName, snapId }) { className="snap-content-footer" > diff --git a/ui/components/app/flask/snap-install-warning/snap-install-warning.js b/ui/components/app/flask/snap-install-warning/snap-install-warning.js index 31365909f042..94e8c091c662 100644 --- a/ui/components/app/flask/snap-install-warning/snap-install-warning.js +++ b/ui/components/app/flask/snap-install-warning/snap-install-warning.js @@ -15,8 +15,7 @@ import { } from '../../../../helpers/constants/design-system'; import Popover from '../../../ui/popover'; import Button from '../../../ui/button'; -import { AvatarIcon, Text } from '../../../component-library'; -import { ICON_NAMES } from '../../../component-library/icon/deprecated'; +import { AvatarIcon, Text, IconName } from '../../../component-library'; import Box from '../../../ui/box/box'; /** @@ -79,7 +78,7 @@ export default function SnapInstallWarning({ onCancel, onSubmit, warnings }) { > ) : null } - iconName={ICON_NAMES.EXPORT} + iconName={IconName.Export} > {t( blockExplorerLinkText.firstPart, @@ -109,7 +109,7 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { global.platform.openExtensionInBrowser(); onClose(); }} - iconName={ICON_NAMES.EXPAND} + iconName={IconName.Expand} > {t('expandView')} @@ -127,7 +127,7 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { }); onClose(); }} - iconName={ICON_NAMES.SCAN_BARCODE} + iconName={IconName.ScanBarcode} > {t('accountDetails')} @@ -144,7 +144,7 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { history.push(CONNECTED_ROUTE); onClose(); }} - iconName={ICON_NAMES.CONNECT} + iconName={IconName.Connect} > {t('connectedSites')} @@ -160,7 +160,7 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { ); onClose(); }} - iconName={ICON_NAMES.TRASH} + iconName={IconName.Trash} > {t('removeAccount')} diff --git a/ui/components/app/menu-bar/menu-bar.js b/ui/components/app/menu-bar/menu-bar.js index 08da8208f5ac..7732a3c587ce 100644 --- a/ui/components/app/menu-bar/menu-bar.js +++ b/ui/components/app/menu-bar/menu-bar.js @@ -14,8 +14,7 @@ import { CONNECTED_ACCOUNTS_ROUTE } from '../../../helpers/constants/routes'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { getOriginOfCurrentTab } from '../../../selectors'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { ButtonIcon } from '../../component-library/button-icon/deprecated'; -import { ICON_NAMES } from '../../component-library/icon/deprecated'; +import { ButtonIcon, IconName } from '../../component-library'; import AccountOptionsMenu from './account-options-menu'; export default function MenuBar() { @@ -41,7 +40,7 @@ export default function MenuBar() { handleCopyTokenAddress(tokenAddress)} color={Color.iconMuted} @@ -163,7 +160,7 @@ export default function ContractDetailsModal({ { const blockExplorerTokenLink = getAccountLink( @@ -244,7 +241,7 @@ export default function ContractDetailsModal({ handleCopyToAddress(toAddress)} color={Color.iconMuted} @@ -258,7 +255,7 @@ export default function ContractDetailsModal({ { const blockExplorerTokenLink = getAccountLink( diff --git a/ui/components/app/modals/customize-nonce/customize-nonce.component.js b/ui/components/app/modals/customize-nonce/customize-nonce.component.js index e1e0a944b274..58d3ab79a2b3 100644 --- a/ui/components/app/modals/customize-nonce/customize-nonce.component.js +++ b/ui/components/app/modals/customize-nonce/customize-nonce.component.js @@ -15,11 +15,11 @@ import Box from '../../../ui/box'; import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; import { useI18nContext } from '../../../../hooks/useI18nContext'; import ZENDESK_URLS from '../../../../helpers/constants/zendesk-url'; -import { ButtonIcon } from '../../../component-library/button-icon/deprecated'; import { - ICON_NAMES, - ICON_SIZES, -} from '../../../component-library/icon/deprecated'; + ButtonIcon, + ButtonIconSize, + IconName, +} from '../../../component-library'; const CustomizeNonce = ({ hideModal, @@ -58,9 +58,9 @@ const CustomizeNonce = ({ {t('editNonceField')} diff --git a/ui/components/app/modals/edit-approval-permission/edit-approval-permission.component.js b/ui/components/app/modals/edit-approval-permission/edit-approval-permission.component.js index 3c3b85cf029d..caccc2ad6874 100644 --- a/ui/components/app/modals/edit-approval-permission/edit-approval-permission.component.js +++ b/ui/components/app/modals/edit-approval-permission/edit-approval-permission.component.js @@ -10,11 +10,11 @@ import { calcTokenAmount, toPrecisionWithoutTrailingZeros, } from '../../../../../shared/lib/transactions-controller-utils'; -import { ButtonIcon } from '../../../component-library/button-icon/deprecated'; import { - ICON_SIZES, - ICON_NAMES, -} from '../../../component-library/icon/deprecated'; + ButtonIcon, + ButtonIconSize, + IconName, +} from '../../../component-library'; const MAX_UNSIGNED_256_INT = new BigNumber(2).pow(256).minus(1).toString(10); @@ -63,8 +63,8 @@ export default class EditApprovalPermission extends PureComponent { {t('editPermission')}
diff --git a/ui/components/app/modals/hold-to-reveal-modal/hold-to-reveal-modal.js b/ui/components/app/modals/hold-to-reveal-modal/hold-to-reveal-modal.js index de5a6a962a63..bf4b42ccf050 100644 --- a/ui/components/app/modals/hold-to-reveal-modal/hold-to-reveal-modal.js +++ b/ui/components/app/modals/hold-to-reveal-modal/hold-to-reveal-modal.js @@ -2,9 +2,13 @@ import PropTypes from 'prop-types'; import React from 'react'; import withModalProps from '../../../../helpers/higher-order-components/with-modal-props'; import Box from '../../../ui/box'; -import { Text, Button, BUTTON_TYPES } from '../../../component-library'; -import { ButtonIcon } from '../../../component-library/button-icon/deprecated'; -import { ICON_NAMES } from '../../../component-library/icon/deprecated'; +import { + Text, + Button, + BUTTON_TYPES, + ButtonIcon, + IconName, +} from '../../../component-library'; import { AlignItems, DISPLAY, @@ -47,7 +51,7 @@ const HoldToRevealModal = ({ onLongPressed, hideModal }) => { {t('holdToRevealTitle')}
diff --git a/ui/components/app/modals/transaction-confirmed/transaction-confirmed.component.js b/ui/components/app/modals/transaction-confirmed/transaction-confirmed.component.js index 5899562d48a5..c5f112eefd91 100644 --- a/ui/components/app/modals/transaction-confirmed/transaction-confirmed.component.js +++ b/ui/components/app/modals/transaction-confirmed/transaction-confirmed.component.js @@ -1,11 +1,7 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import Modal from '../../modal'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../../component-library'; import { IconColor } from '../../../../helpers/constants/design-system'; export default class TransactionConfirmed extends PureComponent { @@ -35,9 +31,9 @@ export default class TransactionConfirmed extends PureComponent {
{`${t('confirmed')}!`} diff --git a/ui/components/app/network-display/network-display.js b/ui/components/app/network-display/network-display.js index 24519801bc90..57670908a62f 100644 --- a/ui/components/app/network-display/network-display.js +++ b/ui/components/app/network-display/network-display.js @@ -18,11 +18,7 @@ import { import Chip from '../../ui/chip/chip'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { isNetworkLoading } from '../../../selectors'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; export default function NetworkDisplay({ indicatorSize, @@ -70,9 +66,7 @@ export default function NetworkDisplay({ } rightIcon={ - onClick ? ( - - ) : null + onClick ? : null } label={ networkType === NETWORK_TYPES.RPC diff --git a/ui/components/app/nft-details/nft-details.js b/ui/components/app/nft-details/nft-details.js index 1888f32f1acb..336d5a96c5be 100644 --- a/ui/components/app/nft-details/nft-details.js +++ b/ui/components/app/nft-details/nft-details.js @@ -53,8 +53,7 @@ import { TokenStandard, } from '../../../../shared/constants/transaction'; import NftDefaultImage from '../nft-default-image'; -import { ButtonIcon } from '../../component-library/button-icon/deprecated'; -import { ICON_NAMES } from '../../component-library/icon/deprecated'; +import { ButtonIcon, IconName } from '../../component-library'; import Tooltip from '../../ui/tooltip'; import { decWEIToDecETH } from '../../../../shared/modules/conversion.utils'; @@ -427,7 +426,7 @@ export default function NftDetails({ nft }) { handleAddressCopy(address); }} iconName={ - addressCopied ? ICON_NAMES.COPY_SUCCESS : ICON_NAMES.COPY + addressCopied ? IconName.CopySuccess : IconName.Copy } /> diff --git a/ui/components/app/nft-options/nft-options.js b/ui/components/app/nft-options/nft-options.js index e67525f7c4fd..1ff1c55f1581 100644 --- a/ui/components/app/nft-options/nft-options.js +++ b/ui/components/app/nft-options/nft-options.js @@ -3,8 +3,7 @@ import PropTypes from 'prop-types'; import { I18nContext } from '../../../contexts/i18n'; import { Menu, MenuItem } from '../../ui/menu'; -import { ButtonIcon } from '../../component-library/button-icon/deprecated'; -import { ICON_NAMES } from '../../component-library/icon/deprecated'; +import { ButtonIcon, IconName } from '../../component-library'; import { Color } from '../../../helpers/constants/design-system'; const NftOptions = ({ onRemove, onViewOnOpensea }) => { @@ -15,7 +14,7 @@ const NftOptions = ({ onRemove, onViewOnOpensea }) => { return (
setNftOptionsOpen(true)} @@ -31,7 +30,7 @@ const NftOptions = ({ onRemove, onViewOnOpensea }) => { > {onViewOnOpensea ? ( { setNftOptionsOpen(false); @@ -42,7 +41,7 @@ const NftOptions = ({ onRemove, onViewOnOpensea }) => { ) : null} { setNftOptionsOpen(false); diff --git a/ui/components/app/nfts-items/nfts-items.js b/ui/components/app/nfts-items/nfts-items.js index 0e865b1b8d27..03d4d8f7d81e 100644 --- a/ui/components/app/nfts-items/nfts-items.js +++ b/ui/components/app/nfts-items/nfts-items.js @@ -30,7 +30,7 @@ import { updateNftDropDownState } from '../../../store/actions'; import { usePrevious } from '../../../hooks/usePrevious'; import { getNftsDropdownState } from '../../../ducks/metamask/metamask'; import { useI18nContext } from '../../../hooks/useI18nContext'; -import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../component-library'; import NftDefaultImage from '../nft-default-image'; const width = @@ -158,9 +158,7 @@ export default function NftsItems({ diff --git a/ui/components/app/permission-cell/permission-cell.js b/ui/components/app/permission-cell/permission-cell.js index fbbafea434d8..cb9a10d8d3db 100644 --- a/ui/components/app/permission-cell/permission-cell.js +++ b/ui/components/app/permission-cell/permission-cell.js @@ -11,12 +11,13 @@ import { TextColor, TextVariant, } from '../../../helpers/constants/design-system'; -import { AvatarIcon, Text } from '../../component-library'; import { + AvatarIcon, + Text, Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; + IconName, + IconSize, +} from '../../component-library'; import { formatDate } from '../../../helpers/utils/util'; import { useI18nContext } from '../../../hooks/useI18nContext'; import Tooltip from '../../ui/tooltip'; @@ -32,24 +33,24 @@ const PermissionCell = ({ const t = useI18nContext(); let infoIconColor = IconColor.iconMuted; - let infoIcon = ICON_NAMES.INFO; - let iconColor = Color.primaryDefault; + let infoIcon = IconName.Info; + let iconColor = IconColor.primaryDefault; let iconBackgroundColor = Color.primaryMuted; if (!revoked && weight === 1) { - iconColor = Color.warningDefault; + iconColor = IconColor.warningDefault; iconBackgroundColor = Color.warningMuted; infoIconColor = IconColor.warningDefault; - infoIcon = ICON_NAMES.DANGER; + infoIcon = IconName.Danger; } if (dateApproved) { - iconColor = Color.iconMuted; + iconColor = IconColor.iconMuted; iconBackgroundColor = Color.backgroundAlternative; } if (revoked) { - iconColor = Color.iconMuted; + iconColor = IconColor.iconMuted; iconBackgroundColor = Color.backgroundAlternative; } @@ -72,9 +73,9 @@ const PermissionCell = ({ {typeof permissionIcon === 'string' ? ( {description}
} position="bottom"> - + diff --git a/ui/components/app/selected-account/selected-account.component.js b/ui/components/app/selected-account/selected-account.component.js index 08746392ef8e..3dab4e12a581 100644 --- a/ui/components/app/selected-account/selected-account.component.js +++ b/ui/components/app/selected-account/selected-account.component.js @@ -6,11 +6,7 @@ import { shortenAddress } from '../../../helpers/utils/util'; import Tooltip from '../../ui/tooltip'; import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils'; import { SECOND } from '../../../../shared/constants/time'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; import { IconColor } from '../../../helpers/constants/design-system'; class SelectedAccount extends Component { @@ -71,11 +67,9 @@ class SelectedAccount extends Component {
diff --git a/ui/components/app/set-approval-for-all-warning/set-approval-for-all-warning.js b/ui/components/app/set-approval-for-all-warning/set-approval-for-all-warning.js index f6f0794f6a02..f5dfe26ee97d 100644 --- a/ui/components/app/set-approval-for-all-warning/set-approval-for-all-warning.js +++ b/ui/components/app/set-approval-for-all-warning/set-approval-for-all-warning.js @@ -16,7 +16,7 @@ import { } from '../../../helpers/constants/design-system'; import Identicon from '../../ui/identicon'; import { shortenAddress } from '../../../helpers/utils/util'; -import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../component-library'; const SetApproveForAllWarning = ({ collectionName, @@ -62,7 +62,7 @@ const SetApproveForAllWarning = ({ className="set-approval-for-all-warning__content__header" > diff --git a/ui/components/app/signature-request-siwe/signature-request-siwe-icon/index.js b/ui/components/app/signature-request-siwe/signature-request-siwe-icon/index.js index 7ef015ab57ca..ef85b2e6b958 100644 --- a/ui/components/app/signature-request-siwe/signature-request-siwe-icon/index.js +++ b/ui/components/app/signature-request-siwe/signature-request-siwe-icon/index.js @@ -6,7 +6,7 @@ import { JustifyContent, } from '../../../../helpers/constants/design-system'; import Box from '../../../ui/box'; -import { Icon, ICON_NAMES } from '../../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../../component-library'; const SignatureRequestSIWEIcon = () => { return ( @@ -17,7 +17,7 @@ const SignatureRequestSIWEIcon = () => { backgroundColor={Color.errorDefault} justifyContent={JustifyContent.center} > - + ); }; diff --git a/ui/components/app/tab-bar/tab-bar.js b/ui/components/app/tab-bar/tab-bar.js index bcb97b80bd05..9c3c42a90c13 100644 --- a/ui/components/app/tab-bar/tab-bar.js +++ b/ui/components/app/tab-bar/tab-bar.js @@ -2,11 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../component-library'; const TabBar = (props) => { const { tabs = [], onSelect, isActive } = props; @@ -26,8 +22,8 @@ const TabBar = (props) => {
{content}
diff --git a/ui/components/app/tab-bar/tab-bar.stories.js b/ui/components/app/tab-bar/tab-bar.stories.js index d7e08ed7cf6a..a9677eb19a6b 100644 --- a/ui/components/app/tab-bar/tab-bar.stories.js +++ b/ui/components/app/tab-bar/tab-bar.stories.js @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../component-library'; import TabBar from '.'; export default { @@ -19,12 +19,12 @@ export default { args: { tabs: [ { - icon: , + icon: , content: 'General', key: 'general', }, { - icon: , + icon: , content: 'Contacts', key: 'contacts', }, @@ -39,7 +39,7 @@ export default { key: 'securityAndPrivacy', }, { - icon: , + icon: , content: 'Alerts', key: 'alerts', }, diff --git a/ui/components/app/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js b/ui/components/app/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js index 3e253e62127a..7e119ebe677b 100644 --- a/ui/components/app/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js +++ b/ui/components/app/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js @@ -12,22 +12,18 @@ import { TRANSACTION_CANCEL_ATTEMPTED_EVENT, TRANSACTION_CANCEL_SUCCESS_EVENT, } from '../transaction-activity-log.constants'; -import { - Icon, - ICON_NAMES, - ICON_SIZES, -} from '../../../component-library/icon/deprecated'; +import { Icon, IconName, IconSize } from '../../../component-library'; import { Color } from '../../../../helpers/constants/design-system'; export const ACTIVITY_ICONS = { - [TRANSACTION_CREATED_EVENT]: ICON_NAMES.ADD, - [TRANSACTION_SUBMITTED_EVENT]: ICON_NAMES.ARROW_UP, - [TRANSACTION_RESUBMITTED_EVENT]: ICON_NAMES.PROGRAMMING_ARROWS, - [TRANSACTION_CONFIRMED_EVENT]: ICON_NAMES.CHECK, - [TRANSACTION_DROPPED_EVENT]: ICON_NAMES.CLOSE, - [TRANSACTION_ERRORED_EVENT]: ICON_NAMES.DANGER, - [TRANSACTION_CANCEL_ATTEMPTED_EVENT]: ICON_NAMES.CLOSE, - [TRANSACTION_CANCEL_SUCCESS_EVENT]: ICON_NAMES.CLOSE, + [TRANSACTION_CREATED_EVENT]: IconName.Add, + [TRANSACTION_SUBMITTED_EVENT]: IconName.ArrowUp, + [TRANSACTION_RESUBMITTED_EVENT]: IconName.ProgrammingArrows, + [TRANSACTION_CONFIRMED_EVENT]: IconName.Check, + [TRANSACTION_DROPPED_EVENT]: IconName.Close, + [TRANSACTION_ERRORED_EVENT]: IconName.Danger, + [TRANSACTION_CANCEL_ATTEMPTED_EVENT]: IconName.Close, + [TRANSACTION_CANCEL_SUCCESS_EVENT]: IconName.Close, }; export default class TransactionActivityLogIcon extends PureComponent { @@ -47,7 +43,7 @@ export default class TransactionActivityLogIcon extends PureComponent { return (
{icon ? ( - + ) : null}
); diff --git a/ui/components/app/transaction-decoding/components/ui/copy-raw-data/copy-raw-data.component.js b/ui/components/app/transaction-decoding/components/ui/copy-raw-data/copy-raw-data.component.js index 8e1f62d9341d..57e43e6697f9 100644 --- a/ui/components/app/transaction-decoding/components/ui/copy-raw-data/copy-raw-data.component.js +++ b/ui/components/app/transaction-decoding/components/ui/copy-raw-data/copy-raw-data.component.js @@ -4,10 +4,7 @@ import Tooltip from '../../../../../ui/tooltip/tooltip'; import { I18nContext } from '../../../../../../contexts/i18n'; import { useCopyToClipboard } from '../../../../../../hooks/useCopyToClipboard'; -import { - Icon, - ICON_NAMES, -} from '../../../../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../../../../component-library'; import { IconColor } from '../../../../../../helpers/constants/design-system'; const CopyRawData = ({ data }) => { @@ -25,7 +22,7 @@ const CopyRawData = ({ data }) => { >
diff --git a/ui/components/app/wallet-overview/eth-overview.js b/ui/components/app/wallet-overview/eth-overview.js index 315ce61af358..6d0dbdeaf512 100644 --- a/ui/components/app/wallet-overview/eth-overview.js +++ b/ui/components/app/wallet-overview/eth-overview.js @@ -39,9 +39,10 @@ import { startNewDraftTransaction } from '../../../ducks/send'; import { AssetType } from '../../../../shared/constants/transaction'; import { ButtonIcon, - BUTTON_ICON_SIZES, -} from '../../component-library/button-icon/deprecated'; -import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; + ButtonIconSize, + Icon, + IconName, +} from '../../component-library'; import { IconColor } from '../../../helpers/constants/design-system'; import useRamps from '../../../hooks/experiences/useRamps'; import WalletOverview from './wallet-overview'; @@ -101,9 +102,9 @@ const EthOverview = ({ className }) => { className="eth-overview__portfolio-button" data-testid="home__portfolio-site" color={IconColor.primaryDefault} - iconName={ICON_NAMES.DIAGRAM} + iconName={IconName.Diagram} ariaLabel={t('portfolio')} - size={BUTTON_ICON_SIZES.LG} + size={ButtonIconSize.Lg} onClick={() => { const portfolioUrl = process.env.PORTFOLIO_URL; global.platform.openTab({ @@ -147,9 +148,7 @@ const EthOverview = ({ className }) => { <> - } + Icon={} disabled={!isBuyableChain} data-testid="eth-overview-buy" label={t('buy')} @@ -170,7 +169,7 @@ const EthOverview = ({ className }) => { data-testid="eth-overview-send" Icon={ } @@ -197,7 +196,7 @@ const EthOverview = ({ className }) => { disabled={!isSwapsChain} Icon={ } @@ -239,7 +238,7 @@ const EthOverview = ({ className }) => { disabled={!isBridgeChain} data-testid="eth-overview-bridge" Icon={ - + } label={t('bridge')} onClick={() => { diff --git a/ui/components/app/wallet-overview/token-overview.js b/ui/components/app/wallet-overview/token-overview.js index a2d7728b1e5f..7f9ade4b621b 100644 --- a/ui/components/app/wallet-overview/token-overview.js +++ b/ui/components/app/wallet-overview/token-overview.js @@ -35,7 +35,7 @@ import { import { AssetType } from '../../../../shared/constants/transaction'; import useRamps from '../../../hooks/experiences/useRamps'; -import { Icon, ICON_NAMES } from '../../component-library/icon/deprecated'; +import { Icon, IconName } from '../../component-library'; import { IconColor } from '../../../helpers/constants/design-system'; import WalletOverview from './wallet-overview'; @@ -93,9 +93,7 @@ const TokenOverview = ({ className, token }) => { <> - } + Icon={} label={t('buy')} data-testid="token-overview-buy" onClick={() => { @@ -139,7 +137,7 @@ const TokenOverview = ({ className, token }) => { }} Icon={ } @@ -152,7 +150,7 @@ const TokenOverview = ({ className, token }) => { disabled={!isSwapsChain} Icon={ } @@ -201,10 +199,7 @@ const TokenOverview = ({ className, token }) => { + } label={t('portfolio')} data-testid="home__portfolio-site" diff --git a/ui/components/app/whats-new-popup/whats-new-popup.js b/ui/components/app/whats-new-popup/whats-new-popup.js index 98c636e50541..fd0bf14a7ea7 100644 --- a/ui/components/app/whats-new-popup/whats-new-popup.js +++ b/ui/components/app/whats-new-popup/whats-new-popup.js @@ -73,6 +73,12 @@ function getActionFunctionById(id, history) { updateViewedNotifications({ 19: true }); history.push(`${EXPERIMENTAL_ROUTE}#autodetect-nfts`); }, + 20: () => { + updateViewedNotifications({ 20: true }); + global.platform.openTab({ + url: ZENDESK_URLS.LEDGER_FIREFOX_U2F_GUIDE, + }); + }, }; return actionFunctions[id]; diff --git a/ui/components/component-library/README.md b/ui/components/component-library/README.md index b108e9256def..8c3c27f74bdb 100644 --- a/ui/components/component-library/README.md +++ b/ui/components/component-library/README.md @@ -1,8 +1,38 @@ # Component Library -**⚠️ THESE COMPONENTS HAVE BREAKING CHANGES ⚠️** +This folder contains design system components that are built 1:1 with the Figma [DS Components](https://www.figma.com/file/HKpPKij9V3TpsyMV1TpV7C/DS-Components?node-id=16-6) UI kit and should be used where possible in all UI feature work. -This folder contains new design system(`DS 2.0`) components that will be used for the IA/Nav redesign work. They are currently a WIP and should not be used for feature work. That should change in the near future but for the time being please use existing UI components in `ui/components/ui` +## Architecture + +All components are built on top of the `Box` component and accept all `Box` [component props](https://metamask.github.io/metamask-storybook/?path=/docs/components-ui-box--default-story#props) + +#### Layout + +`component-library` components accept all utility props for layout + +``` +import { Text } from '../../component-library' + +This text has a margin-bottom of 16px +``` + +#### Polymorphic `as` prop + +`component-library` components accept a polymorphic as prop to change the root html element of a component + +``` +import { Text } from '../../component-library' + +
    +This renders as list item html element +
+``` + +## TypeScript + +We are currently in the process of migrating all component-library components to TypeScript. Feel free to contribute by creating a PR against one of [these issues](https://github.com/MetaMask/metamask-extension/issues?q=is%3Aissue+is%3Aopen+DS%2FExtension%2F2023%2FQ2%2FO1%2FKR3) + +## Support If internal folks have any questions please reach out the design system team via the internal slack channel [#metamask-design-system](https://consensys.slack.com/archives/C0354T27M5M) 💁 diff --git a/ui/components/component-library/avatar-base/avatar-base.js b/ui/components/component-library/avatar-base/avatar-base.js index 22a1e9553647..7b981e04a8d8 100644 --- a/ui/components/component-library/avatar-base/avatar-base.js +++ b/ui/components/component-library/avatar-base/avatar-base.js @@ -6,6 +6,7 @@ import { BackgroundColor, BorderColor, TextColor, + IconColor, DISPLAY, JustifyContent, AlignItems, @@ -81,7 +82,10 @@ AvatarBase.propTypes = { * The color of the text inside the AvatarBase * Defaults to TextColor.textDefault */ - color: PropTypes.oneOf(Object.values(TextColor)), + color: PropTypes.oneOf([ + ...Object.values(TextColor), + ...Object.values(IconColor), + ]), /** * Additional classNames to be added to the AvatarToken */ diff --git a/ui/components/component-library/avatar-icon/avatar-icon.js b/ui/components/component-library/avatar-icon/avatar-icon.js index a8f36e063406..53271ef5b131 100644 --- a/ui/components/component-library/avatar-icon/avatar-icon.js +++ b/ui/components/component-library/avatar-icon/avatar-icon.js @@ -73,7 +73,10 @@ AvatarIcon.propTypes = { * The color of the text inside the AvatarIcon * Defaults to TextColor.primaryDefault */ - color: PropTypes.oneOf(Object.values(TextColor)), + color: PropTypes.oneOf([ + ...Object.values(TextColor), + ...Object.values(IconColor), + ]), /** * Additional classNames to be added to the AvatarIcon */ diff --git a/ui/helpers/constants/zendesk-url.js b/ui/helpers/constants/zendesk-url.js index 1e3f4aec9346..79ea52ffb03e 100644 --- a/ui/helpers/constants/zendesk-url.js +++ b/ui/helpers/constants/zendesk-url.js @@ -15,6 +15,8 @@ const ZENDESK_URLS = { 'https://metamask.zendesk.com/hc/en-us/articles/360015289932', INFURA_BLOCKAGE: 'https://metamask.zendesk.com/hc/en-us/articles/360059386712', + LEDGER_FIREFOX_U2F_GUIDE: + 'https://support.ledger.com/hc/en-us/articles/10371387758493-MetaMask-Firefox-Ledger-Integration-Issue?support=true', LEGACY_WEB3: 'https://metamask.zendesk.com/hc/en-us/articles/360053147012', NFT_TOKENS: 'https://metamask.zendesk.com/hc/en-us/articles/360058238591-NFT-tokens-in-MetaMask-wallet', diff --git a/ui/pages/create-account/connect-hardware/__snapshots__/index.test.tsx.snap b/ui/pages/create-account/connect-hardware/__snapshots__/index.test.tsx.snap new file mode 100644 index 000000000000..5284b9760b08 --- /dev/null +++ b/ui/pages/create-account/connect-hardware/__snapshots__/index.test.tsx.snap @@ -0,0 +1,110 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ConnectHardwareForm should match snapshot 1`] = ` +
+ +
+`; diff --git a/ui/pages/create-account/connect-hardware/index.js b/ui/pages/create-account/connect-hardware/index.js index c46800f858f0..3105ceb29da2 100644 --- a/ui/pages/create-account/connect-hardware/index.js +++ b/ui/pages/create-account/connect-hardware/index.js @@ -20,7 +20,14 @@ import { HardwareDeviceNames, LedgerTransportTypes, } from '../../../../shared/constants/hardware-wallets'; +import { + BUTTON_TYPES, + BUTTON_SIZES, + Button, + Text, +} from '../../../components/component-library'; import ZENDESK_URLS from '../../../helpers/constants/zendesk-url'; +import { TextColor } from '../../../helpers/constants/design-system'; import SelectHardware from './select-hardware'; import AccountList from './account-list'; @@ -74,6 +81,7 @@ class ConnectHardwareForm extends Component { browserSupported: true, unlocked: false, device: null, + isFirefox: false, }; UNSAFE_componentWillReceiveProps(nextProps) { @@ -89,6 +97,10 @@ class ConnectHardwareForm extends Component { componentDidMount() { this.checkIfUnlocked(); + const useAgent = window.navigator.userAgent; + if (/Firefox/u.test(useAgent)) { + this.setState({ isFirefox: true }); + } } async checkIfUnlocked() { @@ -287,23 +299,64 @@ class ConnectHardwareForm extends Component { renderError() { if (this.state.error === U2F_ERROR) { + if (this.state.device === 'ledger' && this.state.isFirefox) { + return ( + <> + + {this.context.t('troubleConnectingToLedgerU2FOnFirefox', [ + // eslint-disable-next-line react/jsx-key + , + ])} + + + {this.context.t( + 'troubleConnectingToLedgerU2FOnFirefoxLedgerSolution', + [ + // eslint-disable-next-line react/jsx-key + , + ], + )} + + + ); + } return ( -

+ {this.context.t('troubleConnectingToWallet', [ this.state.device, // eslint-disable-next-line react/jsx-key - {this.context.t('walletConnectionGuide')} - , + , ])} -

+ ); } return this.state.error ? ( diff --git a/ui/pages/create-account/connect-hardware/index.test.tsx b/ui/pages/create-account/connect-hardware/index.test.tsx new file mode 100644 index 000000000000..7707824628c2 --- /dev/null +++ b/ui/pages/create-account/connect-hardware/index.test.tsx @@ -0,0 +1,151 @@ +import configureMockStore from 'redux-mock-store'; +import { fireEvent, waitFor } from '@testing-library/react'; +import thunk from 'redux-thunk'; +import React from 'react'; +import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { + LedgerTransportTypes, + HardwareDeviceNames, +} from '../../../../shared/constants/hardware-wallets'; +import ConnectHardwareForm from '.'; + +const mockConnectHardware = jest.fn(); +const mockCheckHardwareStatus = jest.fn().mockResolvedValue(false); + +jest.mock('../../../store/actions', () => ({ + connectHardware: () => mockConnectHardware, + checkHardwareStatus: () => mockCheckHardwareStatus, +})); + +jest.mock('../../../selectors', () => ({ + getCurrentChainId: () => jest.fn().mockResolvedValue('0x1'), + getRpcPrefsForCurrentProvider: () => jest.fn().mockResolvedValue({}), + getMetaMaskAccountsConnected: () => jest.fn().mockResolvedValue([]), + getMetaMaskAccounts: () => jest.fn().mockResolvedValue([]), +})); + +jest.mock('../../../ducks/history/history', () => ({ + getMostRecentOverviewPage: () => jest.fn().mockResolvedValue('/'), +})); + +const mockProps = { + forgetDevice: jest.fn(), + showAlert: jest.fn(), + hideAlert: jest.fn(), + unlockHardwareWalletAccount: jest.fn(), + setHardwareWalletDefaultHdPath: jest.fn(), + history: {}, + defaultHdPath: "m/44'/60'/0'/0", + mostRecentOverviewPage: '', +}; + +const mockState = { + metamask: { + provider: { + chainId: '0x1', + }, + }, + appState: { + networkDropdownOpen: false, + gasIsLoading: false, + isLoading: false, + modal: { + open: false, + modalState: { + name: null, + props: {}, + }, + previousModalState: { + name: null, + }, + }, + warning: null, + chainId: '0x1', + rpcPrefs: null, + accounts: [], + connectedAccounts: [], + defaultHdPaths: { + [HardwareDeviceNames.lattice]: "m/44'/60'/0'/0", + [HardwareDeviceNames.ledger]: "m/44'/60'/0'/0", + [HardwareDeviceNames.trezor]: "m/44'/60'/0'/0", + }, + mostRecentOverviewPage: '', + ledgerTransportType: LedgerTransportTypes.webhid, + }, +}; + +describe('ConnectHardwareForm', () => { + const mockStore = configureMockStore([thunk])(mockState); + it('should match snapshot', () => { + const { container } = renderWithProvider( + , + mockStore, + ); + + expect(container).toMatchSnapshot(); + }); + + describe('U2F Error', () => { + it('should render a U2F error', async () => { + mockConnectHardware.mockRejectedValue(new Error('U2F Error')); + const mockStateWithU2F = Object.assign(mockState, {}); + mockStateWithU2F.appState.ledgerTransportType = LedgerTransportTypes.u2f; + const mockStoreWithU2F = configureMockStore([thunk])(mockStateWithU2F); + const { getByText, getByLabelText, queryByText } = renderWithProvider( + , + mockStoreWithU2F, + ); + + const ledgerButton = getByLabelText('Ledger'); + const continueButton = getByText('Continue'); + + fireEvent.click(ledgerButton); + fireEvent.click(continueButton); + + await waitFor(() => { + expect( + getByText('We had trouble connecting to your ledger, try reviewing', { + exact: false, + }), + ).toBeInTheDocument(); + const firefoxError = queryByText( + "If you're on the latest version of Firefox, you might be experiencing an issue related to Firefox dropping U2F support. Learn how to fix this issue", + { exact: false }, + ); + expect(firefoxError).not.toBeInTheDocument(); + }); + }); + + it('should render a different U2F error for firefox', async () => { + jest + .spyOn(window.navigator, 'userAgent', 'get') + .mockReturnValue( + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:95.0) Gecko/20100101 Firefox/95.0', + ); + + mockConnectHardware.mockRejectedValue(new Error('U2F Error')); + const mockStateWithU2F = Object.assign(mockState, {}); + mockStateWithU2F.appState.ledgerTransportType = LedgerTransportTypes.u2f; + const mockStoreWithU2F = configureMockStore([thunk])(mockStateWithU2F); + const { getByText, getByLabelText } = renderWithProvider( + , + mockStoreWithU2F, + ); + + const ledgerButton = getByLabelText('Ledger'); + const continueButton = getByText('Continue'); + + fireEvent.click(ledgerButton); + fireEvent.click(continueButton); + + await waitFor(() => { + expect( + getByText( + "If you're on the latest version of Firefox, you might be experiencing an issue related to Firefox dropping U2F support. Learn how to fix this issue", + { exact: false }, + ), + ).toBeInTheDocument(); + }); + }); + }); +}); diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index 4b4c3aba89dd..ec606c02e5cf 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -935,6 +935,7 @@ function getAllowedAnnouncementIds(state) { const supportsWebHid = window.navigator.hid !== undefined; const currentlyUsingLedgerLive = getLedgerTransportType(state) === LedgerTransportTypes.live; + const isFirefox = window.navigator.userAgent.includes('Firefox'); return { 1: false, @@ -956,6 +957,7 @@ function getAllowedAnnouncementIds(state) { 17: false, 18: true, 19: true, + 20: currentKeyringIsLedger && isFirefox, }; }