1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 01:47:00 +01:00

Deprecated Icon and ButtonIcon clean up (#19220)

* Updating all deprecated instances of Icon and ButtonIcon

* Removing unused deprecated components and scripts
This commit is contained in:
George Marshall 2023-05-19 10:33:02 -07:00 committed by GitHub
parent 6267fa37c9
commit 8437d0491f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 106 additions and 683 deletions

View File

@ -1,39 +1,42 @@
const path = require('path'); const path = require('path');
const { const { ProvidePlugin } = require('webpack');
ProvidePlugin
} = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin');
const {
generateIconNames
} = require('../development/generate-icon-names');
module.exports = { module.exports = {
core: { core: {
disableTelemetry: true disableTelemetry: true,
}, },
features: { features: {
buildStoriesJson: true buildStoriesJson: true,
}, },
stories: ['../ui/**/*.stories.js', '../ui/**/*.stories.tsx', '../ui/**/*.stories.mdx', './*.stories.mdx'], stories: [
addons: ['@storybook/addon-essentials', '@storybook/addon-actions', '@storybook/addon-a11y', '@storybook/addon-knobs', './i18n-party-addon/register.js', 'storybook-dark-mode', '@whitespace/storybook-addon-html', '@storybook/addon-mdx-gfm'], '../ui/**/*.stories.js',
'../ui/**/*.stories.tsx',
'../ui/**/*.stories.mdx',
'./*.stories.mdx',
],
addons: [
'@storybook/addon-essentials',
'@storybook/addon-actions',
'@storybook/addon-a11y',
'@storybook/addon-knobs',
'./i18n-party-addon/register.js',
'storybook-dark-mode',
'@whitespace/storybook-addon-html',
'@storybook/addon-mdx-gfm',
],
staticDirs: ['../app', './images'], staticDirs: ['../app', './images'],
// Uses babel.config.js settings and prevents "Missing class properties transform" error // Uses babel.config.js settings and prevents "Missing class properties transform" error
babel: async options => ({ babel: async (options) => ({
overrides: options.overrides overrides: options.overrides,
}), }),
// Sets env variables https://storybook.js.org/docs/react/configure/environment-variables/ webpackFinal: async (config) => {
env: async config => {
return {
...config,
// Creates the icon names environment variable for the component-library/icon/icon.js component
ICON_NAMES: generateIconNames()
};
},
webpackFinal: async config => {
config.context = process.cwd(); config.context = process.cwd();
config.node = { config.node = {
__filename: true __filename: true,
}; };
config.resolve.alias['webextension-polyfill'] = require.resolve('../ui/__mocks__/webextension-polyfill.js'); config.resolve.alias['webextension-polyfill'] = require.resolve(
'../ui/__mocks__/webextension-polyfill.js',
);
config.resolve.fallback = { config.resolve.fallback = {
child_process: false, child_process: false,
constants: false, constants: false,
@ -45,44 +48,61 @@ module.exports = {
path: false, path: false,
stream: require.resolve('stream-browserify'), stream: require.resolve('stream-browserify'),
zlib: false, zlib: false,
_stream_transform: require.resolve('readable-stream/lib/_stream_transform.js'), _stream_transform: require.resolve(
'readable-stream/lib/_stream_transform.js',
),
}; };
config.module.strictExportPresence = true; config.module.strictExportPresence = true;
config.module.rules.push({ config.module.rules.push({
test: /\.scss$/, test: /\.scss$/,
use: ['style-loader', { use: [
loader: 'css-loader', 'style-loader',
options: { {
import: false, loader: 'css-loader',
url: false options: {
} import: false,
}, { url: false,
loader: 'sass-loader', },
options: { },
sourceMap: true, {
implementation: require('sass'), loader: 'sass-loader',
sassOptions: { options: {
includePaths: ['ui/css/'] sourceMap: true,
} implementation: require('sass'),
} sassOptions: {
}] includePaths: ['ui/css/'],
},
},
},
],
}); });
config.plugins.push(new CopyWebpackPlugin({ config.plugins.push(
patterns: [{ new CopyWebpackPlugin({
from: path.join('node_modules', '@fortawesome', 'fontawesome-free', 'webfonts'), patterns: [
to: path.join('fonts', 'fontawesome') {
}] from: path.join(
})); 'node_modules',
config.plugins.push(new ProvidePlugin({ '@fortawesome',
Buffer: ['buffer', 'Buffer'] 'fontawesome-free',
})); 'webfonts',
),
to: path.join('fonts', 'fontawesome'),
},
],
}),
);
config.plugins.push(
new ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
);
return config; return config;
}, },
docs: { docs: {
autodocs: true autodocs: true,
}, },
framework: { framework: {
name: '@storybook/react-webpack5', name: '@storybook/react-webpack5',
options: {} options: {},
} },
}; };

View File

@ -200,8 +200,6 @@ env:
# Also see DEBUG and NODE_DEBUG # Also see DEBUG and NODE_DEBUG
- METAMASK_DEBUG: false - METAMASK_DEBUG: false
# Modified in <root>/development/build/scripts.js:@setEnvironmentVariables # Modified in <root>/development/build/scripts.js:@setEnvironmentVariables
- ICON_NAMES
# Modified in <root>/development/build/scripts.js:@setEnvironmentVariables
- IN_TEST - IN_TEST
# Modified in <root>/development/build/scripts.js:@setEnvironmentVariables # Modified in <root>/development/build/scripts.js:@setEnvironmentVariables
- METAMASK_ENVIRONMENT - METAMASK_ENVIRONMENT

View File

@ -33,7 +33,6 @@ const bifyModuleGroups = require('bify-module-groups');
const phishingWarningManifest = require('@metamask/phishing-warning/package.json'); const phishingWarningManifest = require('@metamask/phishing-warning/package.json');
const { streamFlatMap } = require('../stream-flat-map'); const { streamFlatMap } = require('../stream-flat-map');
const { generateIconNames } = require('../generate-icon-names');
const { BUILD_TARGETS, ENVIRONMENT } = require('./constants'); const { BUILD_TARGETS, ENVIRONMENT } = require('./constants');
const { getConfig } = require('./config'); const { getConfig } = require('./config');
const { const {
@ -1182,10 +1181,8 @@ async function setEnvironmentVariables({
}) { }) {
const devMode = isDevBuild(buildTarget); const devMode = isDevBuild(buildTarget);
const testing = isTestBuild(buildTarget); const testing = isTestBuild(buildTarget);
const iconNames = await generateIconNames();
variables.set({ variables.set({
ICON_NAMES: iconNames,
IN_TEST: testing, IN_TEST: testing,
INFURA_PROJECT_ID: getInfuraProjectId({ INFURA_PROJECT_ID: getInfuraProjectId({
buildType, buildType,

View File

@ -1,42 +0,0 @@
/**
* Generate icon names
*
* Reads all the icon svg files in app/images/icons
* and returns an object of icon name key value pairs
* stored in the environment variable ICON_NAMES
* Used with the Icon component in ./ui/components/component-library/icon/icon.js
*/
const fs = require('fs');
const path = require('path');
const SVG_ICONS_FOLDER = './app/images/icons';
const ASSET_EXT = '.svg';
const getIconNameKebabCase = (fileName) => path.basename(fileName, ASSET_EXT);
const getIconNameInSnakeCase = (fileName) =>
path.basename(fileName, ASSET_EXT).replace(/-/gu, '_').toUpperCase();
const generateIconNames = () => {
const iconNames = {};
const svgIconsFolderPath = path.join(__dirname, `../${SVG_ICONS_FOLDER}`);
const fileList = fs.readdirSync(svgIconsFolderPath);
const svgIconsFileList = fileList.filter(
(fileName) => path.extname(fileName) === ASSET_EXT,
);
svgIconsFileList.forEach(
(fileName) =>
(iconNames[getIconNameInSnakeCase(fileName)] =
getIconNameKebabCase(fileName)),
);
const iconNamesStringified = JSON.stringify(iconNames);
return iconNamesStringified;
};
module.exports = { generateIconNames };

View File

@ -32,11 +32,7 @@ module.exports = {
// TODO: enable resetMocks // TODO: enable resetMocks
// resetMocks: true, // resetMocks: true,
restoreMocks: true, restoreMocks: true,
setupFiles: [ setupFiles: ['<rootDir>/test/setup.js', '<rootDir>/test/env.js'],
'<rootDir>/test/setup.js',
'<rootDir>/test/env.js',
'<rootDir>/test/jest/env.js', // jest specific env vars that break mocha tests
],
setupFilesAfterEnv: ['<rootDir>/test/jest/setup.js'], setupFilesAfterEnv: ['<rootDir>/test/jest/setup.js'],
testMatch: [ testMatch: [
'<rootDir>/app/scripts/constants/error-utils.test.js', '<rootDir>/app/scripts/constants/error-utils.test.js',

View File

@ -1,9 +0,0 @@
// jest specific env vars that break mocha tests
import { generateIconNames } from '../../development/generate-icon-names';
/**
* Used for testing components that use the Icon component
* 'ui/components/component-library/icon/icon.js'
*/
process.env.ICON_NAMES = generateIconNames();

View File

@ -33,8 +33,8 @@ import {
ADD_POPULAR_CUSTOM_NETWORK, ADD_POPULAR_CUSTOM_NETWORK,
ADVANCED_ROUTE, ADVANCED_ROUTE,
} from '../../../helpers/constants/routes'; } from '../../../helpers/constants/routes';
import { ButtonIcon } from '../../component-library/button-icon/deprecated';
import { Icon, IconName, IconSize } from '../../component-library'; import { Icon, IconName, IconSize, ButtonIcon } from '../../component-library';
import { Dropdown, DropdownMenuItem } from './dropdown'; import { Dropdown, DropdownMenuItem } from './dropdown';

View File

@ -37,10 +37,14 @@ import {
import { AssetType } from '../../../../shared/constants/transaction'; import { AssetType } from '../../../../shared/constants/transaction';
import useRamps from '../../../hooks/experiences/useRamps'; import useRamps from '../../../hooks/experiences/useRamps';
import { ButtonIcon, Icon, IconName } from '../../component-library'; import {
ButtonIcon,
ButtonIconSize,
Icon,
IconName,
} from '../../component-library';
import { IconColor } from '../../../helpers/constants/design-system'; import { IconColor } from '../../../helpers/constants/design-system';
import { BUTTON_ICON_SIZES } from '../../component-library/button-icon/deprecated';
import { getPortfolioUrl } from '../../../helpers/utils/portfolio'; import { getPortfolioUrl } from '../../../helpers/utils/portfolio';
import WalletOverview from './wallet-overview'; import WalletOverview from './wallet-overview';
@ -95,7 +99,7 @@ const TokenOverview = ({ className, token }) => {
color={IconColor.primaryDefault} color={IconColor.primaryDefault}
iconName={IconName.Diagram} iconName={IconName.Diagram}
ariaLabel={t('portfolio')} ariaLabel={t('portfolio')}
size={BUTTON_ICON_SIZES.LG} size={ButtonIconSize.Lg}
onClick={() => { onClick={() => {
const portfolioUrl = getPortfolioUrl('', 'ext', metaMetricsId); const portfolioUrl = getPortfolioUrl('', 'ext', metaMetricsId);
global.platform.openTab({ global.platform.openTab({

View File

@ -1,20 +1,19 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import { ButtonIcon } from '../button-icon/deprecated';
import { ButtonLink, Text } from '..';
import { ICON_NAMES } from '../icon/deprecated';
import Box from '../../ui/box';
import { import {
BackgroundColor, BackgroundColor,
BorderRadius, BorderRadius,
DISPLAY, Display,
Size, Size,
TextVariant, TextVariant,
} from '../../../helpers/constants/design-system'; } from '../../../helpers/constants/design-system';
import Box from '../../ui/box';
import { ButtonLink, Text, IconName, ButtonIcon } from '..';
export const BannerBase = ({ export const BannerBase = ({
className, className,
title, title,
@ -33,7 +32,7 @@ export const BannerBase = ({
return ( return (
<Box <Box
className={classnames('mm-banner-base', className)} className={classnames('mm-banner-base', className)}
display={DISPLAY.FLEX} display={Display.Flex}
gap={2} gap={2}
backgroundColor={BackgroundColor.backgroundDefault} backgroundColor={BackgroundColor.backgroundDefault}
borderRadius={BorderRadius.SM} borderRadius={BorderRadius.SM}
@ -73,7 +72,7 @@ export const BannerBase = ({
<ButtonIcon <ButtonIcon
className="mm-banner-base__close-button" className="mm-banner-base__close-button"
marginLeft="auto" marginLeft="auto"
iconName={ICON_NAMES.CLOSE} iconName={IconName.Close}
size={Size.SM} size={Size.SM}
ariaLabel="Close" // TODO: i18n ariaLabel="Close" // TODO: i18n
onClick={onClose} onClick={onClose}

View File

@ -1,16 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ButtonIcon should render button element correctly 1`] = `
<div>
<button
aria-label="add"
class="box mm-button-icon mm-button-icon--size-lg box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-icon-default box--background-color-transparent box--rounded-lg"
data-testid="button-icon"
>
<span
class="box mm-icon mm-icon--size-lg box--display-inline-block box--flex-direction-row box--color-inherit"
style="mask-image: url('./images/icons/add-square.svg');"
/>
</button>
</div>
`;

View File

@ -1,6 +0,0 @@
import { Size } from '../../../../helpers/constants/design-system';
export const BUTTON_ICON_SIZES = {
SM: Size.SM,
LG: Size.LG,
};

View File

@ -1,103 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import {
AlignItems,
BackgroundColor,
BorderRadius,
DISPLAY,
IconColor,
JustifyContent,
Size,
} from '../../../../helpers/constants/design-system';
import Box from '../../../ui/box';
import { Icon, ICON_NAMES } from '../../icon/deprecated';
import { BUTTON_ICON_SIZES } from './button-icon.constants';
export const ButtonIcon = ({
ariaLabel,
as = 'button',
className,
color = IconColor.iconDefault,
href,
size = Size.LG,
iconName,
disabled,
iconProps,
...props
}) => {
const Tag = href ? 'a' : as;
return (
<Box
aria-label={ariaLabel}
as={Tag}
className={classnames(
'mm-button-icon',
`mm-button-icon--size-${size}`,
{
'mm-button-icon--disabled': disabled,
},
className,
)}
color={color}
disabled={disabled}
display={DISPLAY.INLINE_FLEX}
justifyContent={JustifyContent.center}
alignItems={AlignItems.center}
borderRadius={BorderRadius.LG}
backgroundColor={BackgroundColor.transparent}
href={href}
{...props}
>
<Icon name={iconName} size={size} {...iconProps} />
</Box>
);
};
ButtonIcon.propTypes = {
/**
* String that adds an accessible name for ButtonIcon
*/
ariaLabel: PropTypes.string.isRequired,
/**
* The polymorphic `as` prop allows you to change the root HTML element of the Button component between `button` and `a` tag
*/
as: PropTypes.string,
/**
* An additional className to apply to the ButtonIcon.
*/
className: PropTypes.string,
/**
* The color of the ButtonIcon component should use the IconColor object from
* ./ui/helpers/constants/design-system.js
*/
color: PropTypes.oneOf(Object.values(IconColor)),
/**
* Boolean to disable button
*/
disabled: PropTypes.bool,
/**
* When an `href` prop is passed, ButtonIcon will automatically change the root element to be an `a` (anchor) tag
*/
href: PropTypes.string,
/**
* The name of the icon to display. Should be one of IconName
*/
iconName: PropTypes.oneOf(Object.values(ICON_NAMES)).isRequired,
/**
* iconProps accepts all the props from Icon
*/
iconProps: PropTypes.object,
/**
* The size of the ButtonIcon.
* Possible values could be 'Size.SM' 24px, 'Size.LG' 32px,
*/
size: PropTypes.oneOf(Object.values(BUTTON_ICON_SIZES)),
/**
* ButtonIcon accepts all the props from Box
*/
...Box.propTypes,
};

View File

@ -1,147 +0,0 @@
/* eslint-disable jest/require-top-level-describe */
import { render } from '@testing-library/react';
import React from 'react';
import { IconColor } from '../../../../helpers/constants/design-system';
import { ICON_NAMES } from '../../icon/deprecated';
import { BUTTON_ICON_SIZES } from './button-icon.constants';
import { ButtonIcon } from './button-icon';
describe('ButtonIcon', () => {
it('should render button element correctly', () => {
const { getByTestId, container } = render(
<ButtonIcon
data-testid="button-icon"
iconName={ICON_NAMES.ADD_SQUARE}
ariaLabel="add"
/>,
);
expect(container.querySelector('button')).toBeDefined();
expect(getByTestId('button-icon')).toHaveClass('mm-button-icon');
expect(container).toMatchSnapshot();
});
it('should render anchor element correctly', () => {
const { getByTestId, container } = render(
<ButtonIcon
as="a"
data-testid="button-icon"
iconName={ICON_NAMES.ADD_SQUARE}
ariaLabel="add"
/>,
);
expect(getByTestId('button-icon')).toHaveClass('mm-button-icon');
const anchor = container.getElementsByTagName('a').length;
expect(anchor).toBe(1);
});
it('should render anchor element correctly using href', () => {
const { getByTestId, getByRole } = render(
<ButtonIcon
href="/metamask"
data-testid="button-icon"
iconName={ICON_NAMES.ADD_SQUARE}
ariaLabel="add"
/>,
);
expect(getByTestId('button-icon')).toHaveClass('mm-button-icon');
expect(getByRole('link')).toBeDefined();
});
it('should render with different size classes', () => {
const { getByTestId } = render(
<>
<ButtonIcon
iconName={ICON_NAMES.ADD_SQUARE}
ariaLabel="add"
size={BUTTON_ICON_SIZES.SM}
data-testid={BUTTON_ICON_SIZES.SM}
/>
<ButtonIcon
iconName={ICON_NAMES.ADD_SQUARE}
ariaLabel="add"
size={BUTTON_ICON_SIZES.LG}
data-testid={BUTTON_ICON_SIZES.LG}
/>
</>,
);
expect(getByTestId(BUTTON_ICON_SIZES.SM)).toHaveClass(
`mm-button-icon--size-${BUTTON_ICON_SIZES.SM}`,
);
expect(getByTestId(BUTTON_ICON_SIZES.LG)).toHaveClass(
`mm-button-icon--size-${BUTTON_ICON_SIZES.LG}`,
);
});
it('should render with different colors', () => {
const { getByTestId } = render(
<>
<ButtonIcon
iconName={ICON_NAMES.ADD_SQUARE}
ariaLabel="add"
color={IconColor.iconDefault}
data-testid={IconColor.iconDefault}
/>
<ButtonIcon
iconName={ICON_NAMES.ADD_SQUARE}
ariaLabel="add"
color={IconColor.errorDefault}
data-testid={IconColor.errorDefault}
/>
</>,
);
expect(getByTestId(IconColor.iconDefault)).toHaveClass(
`box--color-${IconColor.iconDefault}`,
);
expect(getByTestId(IconColor.errorDefault)).toHaveClass(
`box--color-${IconColor.errorDefault}`,
);
});
it('should render with added classname', () => {
const { getByTestId } = render(
<ButtonIcon
data-testid="classname"
className="mm-button-icon--test"
iconName={ICON_NAMES.ADD_SQUARE}
ariaLabel="add"
/>,
);
expect(getByTestId('classname')).toHaveClass('mm-button-icon--test');
});
it('should render with different button states', () => {
const { getByTestId } = render(
<>
<ButtonIcon
disabled
data-testid="disabled"
iconName={ICON_NAMES.ADD_SQUARE}
ariaLabel="add"
/>
</>,
);
expect(getByTestId('disabled')).toHaveClass(`mm-button-icon--disabled`);
expect(getByTestId('disabled')).toBeDisabled();
});
it('should render with icon', () => {
const { getByTestId } = render(
<ButtonIcon
data-testid="icon"
iconName={ICON_NAMES.ADD_SQUARE}
ariaLabel="add"
iconProps={{ 'data-testid': 'button-icon' }}
/>,
);
expect(getByTestId('button-icon')).toBeDefined();
});
it('should render with aria-label', () => {
const { getByLabelText } = render(
<ButtonIcon iconName={ICON_NAMES.ADD_SQUARE} ariaLabel="add" />,
);
expect(getByLabelText('add')).toBeDefined();
});
});

View File

@ -1,2 +0,0 @@
export { ButtonIcon } from './button-icon';
export { BUTTON_ICON_SIZES } from './button-icon.constants';

View File

@ -1,11 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Icon should render correctly 1`] = `
<div>
<span
class="box mm-icon mm-icon--size-md box--display-inline-block box--flex-direction-row box--color-inherit"
data-testid="icon"
style="mask-image: url('./images/icons/add-square.svg');"
/>
</div>
`;

View File

@ -1,23 +0,0 @@
import { Size } from '../../../../helpers/constants/design-system';
/**
* @deprecated `ICON_NAMES` has been deprecated in favour of the `IconName` enum
*
* import { Icon, IconName } from '../../component-library';
*/
/* eslint-disable prefer-destructuring*/ // process.env is not a standard JavaScript object, so we are not able to use object destructuring
export const ICON_NAMES = JSON.parse(process.env.ICON_NAMES);
/**
* @deprecated `ICON_SIZES` has been deprecated in favour of the `IconSize` enum
*
* import { Icon, IconSize, IconName } from '../../component-library';
*/
export const ICON_SIZES = {
XS: Size.XS,
SM: Size.SM,
MD: Size.MD,
LG: Size.LG,
XL: Size.XL,
AUTO: Size.inherit,
};

View File

@ -1,81 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import Box from '../../../ui/box/box';
import {
Size,
IconColor,
DISPLAY,
} from '../../../../helpers/constants/design-system';
import { ICON_SIZES, ICON_NAMES } from './icon.constants';
/**
* @deprecated This is the javascript version of `Icon` which has been deprecated in favour of the TypeScript version of the same name.
*
* To use the TS version update the imports and enums as follows:
*
* `import { Icon, IconSize, IconName } from '../../component-library'`;
*/
export const Icon = ({
name,
size = Size.MD,
color = IconColor.inherit,
className,
style,
...props
}) => {
return (
<Box
className={classnames(className, 'mm-icon', `mm-icon--size-${size}`)}
as="span"
display={DISPLAY.INLINE_BLOCK}
color={color}
style={{
/**
* To reduce the possibility of injection attacks
* the icon component uses mask-image instead of rendering
* the svg directly.
*/
maskImage: `url('./images/icons/${name}.svg')`,
WebkitMaskImage: `url('./images/icons/${name}.svg')`,
...style,
}}
{...props}
/>
);
};
Icon.propTypes = {
/**
* The name of the icon to display. Should be one of ICON_NAMES
*/
name: PropTypes.oneOf(Object.values(ICON_NAMES)).isRequired,
/**
* The size of the Icon.
* Possible values could be SIZES.XS (12px), SIZES.SM (16px), SIZES.MD (20px), SIZES.LG (24px), SIZES.XL (32px),
* Default value is SIZES.MD (20px).
*/
size: PropTypes.oneOf(Object.values(ICON_SIZES)),
/**
* The color of the icon.
* Defaults to IconColor.inherit.
*/
color: PropTypes.oneOf(Object.values(IconColor)),
/**
* An additional className to apply to the icon.
*/
className: PropTypes.string,
/**
* Addition style properties to apply to the icon.
* The Icon component uses inline styles to apply the icon's mask-image so be wary of overriding
*/
style: PropTypes.object,
/**
* Icon accepts all the props from Box
*/
...Box.propTypes,
};

View File

@ -1,141 +0,0 @@
/* eslint-disable jest/require-top-level-describe */
import { render } from '@testing-library/react';
import React from 'react';
import { Size, IconColor } from '../../../../helpers/constants/design-system';
import { ICON_NAMES } from './icon.constants';
import { Icon } from './icon';
describe('Icon', () => {
it('should render correctly', () => {
const { getByTestId, container } = render(
<Icon name={ICON_NAMES.ADD_SQUARE} data-testid="icon" />,
);
expect(getByTestId('icon')).toBeDefined();
expect(container.querySelector('svg')).toBeDefined();
expect(container).toMatchSnapshot();
});
it('should render with a custom class', () => {
const { getByTestId } = render(
<Icon
name={ICON_NAMES.ADD_SQUARE}
data-testid="icon"
className="test-class"
/>,
);
expect(getByTestId('icon')).toHaveClass('test-class');
});
it('should render with an aria-label attribute', () => {
/**
* We aren't specifically adding an ariaLabel prop because in most cases
* the icon should be decorative or be accompanied by text. Also if the icon
* is to be used as a button in most cases ButtonIcon should be used. However
* we should test if it's possible to pass an aria-label attribute to the
* root html element.
*/
const { getByTestId } = render(
<Icon
name={ICON_NAMES.ADD_SQUARE}
data-testid="icon"
aria-label="test aria label"
/>,
);
expect(getByTestId('icon')).toHaveAttribute(
'aria-label',
'test aria label',
);
});
it('should render with different icons using mask-image and image urls', () => {
const { getByTestId } = render(
<>
<Icon name={ICON_NAMES.ADD_SQUARE} data-testid="add-square" />
<Icon name={ICON_NAMES.BANK} data-testid="bank" />
<Icon name={ICON_NAMES.BOOKMARK} data-testid="bookmark" />
<Icon name={ICON_NAMES.CALCULATOR} data-testid="calculator" />
</>,
);
expect(window.getComputedStyle(getByTestId('add-square')).maskImage).toBe(
`url('./images/icons/add-square.svg')`,
);
expect(window.getComputedStyle(getByTestId('bank')).maskImage).toBe(
`url('./images/icons/bank.svg')`,
);
expect(window.getComputedStyle(getByTestId('bookmark')).maskImage).toBe(
`url('./images/icons/bookmark.svg')`,
);
expect(window.getComputedStyle(getByTestId('calculator')).maskImage).toBe(
`url('./images/icons/calculator.svg')`,
);
});
it('should render with different size classes', () => {
const { getByTestId } = render(
<>
<Icon
name={ICON_NAMES.ADD_SQUARE}
size={Size.XS}
data-testid="icon-xs"
/>
<Icon
name={ICON_NAMES.ADD_SQUARE}
size={Size.SM}
data-testid="icon-sm"
/>
<Icon
name={ICON_NAMES.ADD_SQUARE}
size={Size.MD}
data-testid="icon-md"
/>
<Icon
name={ICON_NAMES.ADD_SQUARE}
size={Size.LG}
data-testid="icon-lg"
/>
<Icon
name={ICON_NAMES.ADD_SQUARE}
size={Size.XL}
data-testid="icon-xl"
/>
<Icon
name={ICON_NAMES.ADD_SQUARE}
size={Size.inherit}
data-testid="icon-auto"
/>
</>,
);
expect(getByTestId('icon-xs')).toHaveClass('mm-icon--size-xs');
expect(getByTestId('icon-sm')).toHaveClass('mm-icon--size-sm');
expect(getByTestId('icon-md')).toHaveClass('mm-icon--size-md');
expect(getByTestId('icon-lg')).toHaveClass('mm-icon--size-lg');
expect(getByTestId('icon-xl')).toHaveClass('mm-icon--size-xl');
expect(getByTestId('icon-auto')).toHaveClass('mm-icon--size-inherit');
});
it('should render with icon colors', () => {
const { getByTestId } = render(
<>
<Icon
name={ICON_NAMES.ADD_SQUARE}
color={IconColor.iconDefault}
data-testid="icon-color-default"
/>
<Icon
name={ICON_NAMES.ADD_SQUARE}
color={IconColor.iconAlternative}
data-testid="icon-color-alternative"
/>
<Icon
name={ICON_NAMES.ADD_SQUARE}
color={IconColor.iconMuted}
data-testid="icon-color-muted"
/>
</>,
);
expect(getByTestId('icon-color-default')).toHaveClass(
'box--color-icon-default',
);
expect(getByTestId('icon-color-alternative')).toHaveClass(
'box--color-icon-alternative',
);
expect(getByTestId('icon-color-muted')).toHaveClass(
'box--color-icon-muted',
);
});
});

View File

@ -1,2 +0,0 @@
export { Icon } from './icon';
export { ICON_NAMES, ICON_SIZES } from './icon.constants';

View File

@ -90,8 +90,7 @@ Use the `startAccessory` and `endAccessory` props to add components such as icon
```jsx ```jsx
import { Color, IconColor, SIZES, DISPLAY } from '../../../helpers/constants/design-system'; import { Color, IconColor, SIZES, DISPLAY } from '../../../helpers/constants/design-system';
import { ButtonIcon } from '../../component-library/button-icon/deprecated'; import { TextField, Icon, IconName, ButtonIcon } from '../../component-library';
import { TextField, Icon, IconName } from '../../component-library';
<TextField <TextField
placeholder="Search" placeholder="Search"

View File

@ -1,9 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import { ButtonBase } from '../../component-library'; import { ButtonBase, IconName } from '../../component-library';
// TODO: Replace ICON_NAMES with IconName when ButtonBase/Buttons have been updated
import { ICON_NAMES } from '../../component-library/icon/deprecated';
import { import {
BackgroundColor, BackgroundColor,
TextVariant, TextVariant,
@ -40,7 +38,7 @@ export const AddressCopyButton = ({
size={Size.SM} size={Size.SM}
variant={TextVariant.bodySm} variant={TextVariant.bodySm}
color={TextColor.primaryDefault} color={TextColor.primaryDefault}
endIconName={copied ? ICON_NAMES.COPY_SUCCESS : ICON_NAMES.COPY} endIconName={copied ? IconName.CopySuccess : IconName.Copy}
className={classnames('multichain-address-copy-button', { className={classnames('multichain-address-copy-button', {
'multichain-address-copy-button__address--wrap': wrap, 'multichain-address-copy-button__address--wrap': wrap,
})} })}

View File

@ -4,12 +4,10 @@ import { useHistory } from 'react-router-dom';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
import Box from '../../ui/box/box'; import Box from '../../ui/box/box';
import { ButtonLink } from '../../component-library'; import { ButtonLink, IconName } from '../../component-library';
// TODO: Replace ICON_NAMES with IconName when ButtonBase/Buttons have been updated
import { ICON_NAMES } from '../../component-library/icon/deprecated';
import { import {
AlignItems, AlignItems,
DISPLAY, Display,
Size, Size,
} from '../../../helpers/constants/design-system'; } from '../../../helpers/constants/design-system';
import { useI18nContext } from '../../../hooks/useI18nContext'; import { useI18nContext } from '../../../hooks/useI18nContext';
@ -44,11 +42,11 @@ export const MultichainImportTokenLink = ({ className, ...props }) => {
className={classnames('multichain-import-token-link', className)} className={classnames('multichain-import-token-link', className)}
{...props} {...props}
> >
<Box display={DISPLAY.FLEX} alignItems={AlignItems.center}> <Box display={Display.Flex} alignItems={AlignItems.center}>
<ButtonLink <ButtonLink
size={Size.MD} size={Size.MD}
data-testid="import-token-button" data-testid="import-token-button"
startIconName={ICON_NAMES.ADD} startIconName={IconName.Add}
onClick={() => { onClick={() => {
history.push(IMPORT_TOKEN_ROUTE); history.push(IMPORT_TOKEN_ROUTE);
trackEvent({ trackEvent({
@ -67,13 +65,13 @@ export const MultichainImportTokenLink = ({ className, ...props }) => {
</ButtonLink> </ButtonLink>
</Box> </Box>
<Box <Box
display={DISPLAY.FLEX} display={Display.Flex}
alignItems={AlignItems.center} alignItems={AlignItems.center}
paddingBottom={4} paddingBottom={4}
paddingTop={4} paddingTop={4}
> >
<ButtonLink <ButtonLink
startIconName={ICON_NAMES.REFRESH} startIconName={IconName.Refresh}
data-testid="refresh-list-button" data-testid="refresh-list-button"
onClick={() => detectNewTokens()} onClick={() => detectNewTokens()}
> >

View File

@ -1,5 +1,4 @@
import { IconName } from '../../components/component-library'; import { IconName } from '../../components/component-library';
import { ICON_NAMES } from '../../components/component-library/icon/deprecated';
import { import {
ALERTS_ROUTE, ALERTS_ROUTE,
ADVANCED_ROUTE, ADVANCED_ROUTE,
@ -20,21 +19,21 @@ export const SETTINGS_CONSTANTS = [
sectionMessage: (t) => t('currencyConversion'), sectionMessage: (t) => t('currencyConversion'),
descriptionMessage: (t) => t('currencyConversion'), descriptionMessage: (t) => t('currencyConversion'),
route: `${GENERAL_ROUTE}#currency-conversion`, route: `${GENERAL_ROUTE}#currency-conversion`,
iconName: ICON_NAMES.SETTING, iconName: IconName.Setting,
}, },
{ {
tabMessage: (t) => t('general'), tabMessage: (t) => t('general'),
sectionMessage: (t) => t('primaryCurrencySetting'), sectionMessage: (t) => t('primaryCurrencySetting'),
descriptionMessage: (t) => t('primaryCurrencySettingDescription'), descriptionMessage: (t) => t('primaryCurrencySettingDescription'),
route: `${GENERAL_ROUTE}#primary-currency`, route: `${GENERAL_ROUTE}#primary-currency`,
iconName: ICON_NAMES.SETTING, iconName: IconName.Setting,
}, },
{ {
tabMessage: (t) => t('general'), tabMessage: (t) => t('general'),
sectionMessage: (t) => t('currentLanguage'), sectionMessage: (t) => t('currentLanguage'),
descriptionMessage: (t) => t('currentLanguage'), descriptionMessage: (t) => t('currentLanguage'),
route: `${GENERAL_ROUTE}#current-language`, route: `${GENERAL_ROUTE}#current-language`,
iconName: ICON_NAMES.SETTING, iconName: IconName.Setting,
}, },
{ {
tabMessage: (t) => t('general'), tabMessage: (t) => t('general'),
@ -48,14 +47,14 @@ export const SETTINGS_CONSTANTS = [
sectionMessage: (t) => t('accountIdenticon'), sectionMessage: (t) => t('accountIdenticon'),
descriptionMessage: (t) => t('accountIdenticon'), descriptionMessage: (t) => t('accountIdenticon'),
route: `${GENERAL_ROUTE}#account-identicon`, route: `${GENERAL_ROUTE}#account-identicon`,
iconName: ICON_NAMES.SETTING, iconName: IconName.Setting,
}, },
{ {
tabMessage: (t) => t('general'), tabMessage: (t) => t('general'),
sectionMessage: (t) => t('hideZeroBalanceTokens'), sectionMessage: (t) => t('hideZeroBalanceTokens'),
descriptionMessage: (t) => t('hideZeroBalanceTokens'), descriptionMessage: (t) => t('hideZeroBalanceTokens'),
route: `${GENERAL_ROUTE}#zero-balancetokens`, route: `${GENERAL_ROUTE}#zero-balancetokens`,
iconName: ICON_NAMES.SETTING, iconName: IconName.Setting,
}, },
{ {
tabMessage: (t) => t('advanced'), tabMessage: (t) => t('advanced'),
@ -132,7 +131,7 @@ export const SETTINGS_CONSTANTS = [
sectionMessage: (t) => t('contacts'), sectionMessage: (t) => t('contacts'),
descriptionMessage: (t) => t('contacts'), descriptionMessage: (t) => t('contacts'),
route: CONTACT_LIST_ROUTE, route: CONTACT_LIST_ROUTE,
iconName: ICON_NAMES.BOOK, iconName: IconName.Book,
}, },
///: BEGIN:ONLY_INCLUDE_IN(snaps) ///: BEGIN:ONLY_INCLUDE_IN(snaps)
{ {
@ -140,7 +139,7 @@ export const SETTINGS_CONSTANTS = [
sectionMessage: (t) => t('snaps'), sectionMessage: (t) => t('snaps'),
descriptionMessage: (t) => t('snaps'), descriptionMessage: (t) => t('snaps'),
route: SNAPS_LIST_ROUTE, route: SNAPS_LIST_ROUTE,
iconName: ICON_NAMES.SNAPS, iconName: IconName.Snaps,
}, },
///: END:ONLY_INCLUDE_IN ///: END:ONLY_INCLUDE_IN
{ {
@ -211,7 +210,7 @@ export const SETTINGS_CONSTANTS = [
sectionMessage: (t) => t('alertSettingsUnconnectedAccount'), sectionMessage: (t) => t('alertSettingsUnconnectedAccount'),
descriptionMessage: (t) => t('alertSettingsUnconnectedAccount'), descriptionMessage: (t) => t('alertSettingsUnconnectedAccount'),
route: `${ALERTS_ROUTE}#unconnected-account`, route: `${ALERTS_ROUTE}#unconnected-account`,
iconName: ICON_NAMES.NOTIFICATION, iconName: IconName.Notification,
}, },
{ {
tabMessage: (t) => t('alerts'), tabMessage: (t) => t('alerts'),

View File

@ -26,7 +26,6 @@ import {
} from '../../../store/actions'; } from '../../../store/actions';
import { ONBOARDING_PIN_EXTENSION_ROUTE } from '../../../helpers/constants/routes'; import { ONBOARDING_PIN_EXTENSION_ROUTE } from '../../../helpers/constants/routes';
import { TextField } from '../../../components/component-library'; import { TextField } from '../../../components/component-library';
import { Icon } from '../../../components/component-library/icon/deprecated';
import NetworkDropdown from '../../../components/app/dropdowns/network-dropdown'; import NetworkDropdown from '../../../components/app/dropdowns/network-dropdown';
import NetworkDisplay from '../../../components/app/network-display/network-display'; import NetworkDisplay from '../../../components/app/network-display/network-display';
import { import {
@ -232,7 +231,6 @@ export default function PrivacySettings() {
e.preventDefault(); e.preventDefault();
dispatch(showModal({ name: 'ONBOARDING_ADD_NETWORK' })); dispatch(showModal({ name: 'ONBOARDING_ADD_NETWORK' }));
}} }}
icon={<Icon name="add" marginRight={2} />}
> >
{t('onboardingAdvancedPrivacyNetworkButton')} {t('onboardingAdvancedPrivacyNetworkButton')}
</Button> </Button>