mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Feat/15088/add button icon (#16277)
* 15088: add button icon * button icon story updates * add primary type * update button icon docs * add test * button icon updates * button icon and test updates * button icon border radius and test update * remove padding prop * button icon updates * Update ui/components/component-library/button-icon/button-icon.stories.js Co-authored-by: George Marshall <george.marshall@consensys.net> * Update ui/components/component-library/button-icon/button-icon.stories.js Co-authored-by: George Marshall <george.marshall@consensys.net> * Update ui/components/component-library/button-icon/button-icon.stories.js Co-authored-by: George Marshall <george.marshall@consensys.net> * add aria label for storybook demo Co-authored-by: George Marshall <george.marshall@consensys.net>
This commit is contained in:
parent
a28d727caf
commit
03af17747b
144
ui/components/component-library/button-icon/README.mdx
Normal file
144
ui/components/component-library/button-icon/README.mdx
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
import { Story, Canvas, ArgsTable } from '@storybook/addon-docs';
|
||||||
|
import { ButtonIcon } from './button-icon';
|
||||||
|
|
||||||
|
# ButtonIcon
|
||||||
|
|
||||||
|
The `ButtonIcon` is used for icons associated with a user action.
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story id="ui-components-component-library-button-icon-button-icon-stories-js--default-story" />
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
## Props
|
||||||
|
|
||||||
|
The `ButtonIcon` accepts all props below as well as all [Box](/docs/ui-components-ui-box-box-stories-js--default-story#props) component props
|
||||||
|
|
||||||
|
<ArgsTable of={ButtonIcon} />
|
||||||
|
|
||||||
|
### Icon<span style={{ color: 'red' }}>\*</span>
|
||||||
|
|
||||||
|
Use the required `icon` prop with `ICON_NAMES` object from `./ui/components/component-library/icon` to select icon.
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story id="ui-components-component-library-button-icon-button-icon-stories-js--icon" />
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { ButtonIcon } from '../ui/component-library';
|
||||||
|
import { ICON_NAMES } from '../icon';
|
||||||
|
|
||||||
|
<ButtonIcon icon={ICON_NAMES.CLOSE_OUTLINE} ariaLabel="Close" />;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Size
|
||||||
|
|
||||||
|
Use the `size` prop and the `SIZES` object from `./ui/helpers/constants/design-system.js`
|
||||||
|
to change the size of `ButtonIcon`. Defaults to `SIZES.SM`
|
||||||
|
|
||||||
|
Optional: `BUTTON_ICON_SIZES` from `./button-icon` object can be used instead of `SIZES`.
|
||||||
|
|
||||||
|
Possible sizes include:
|
||||||
|
|
||||||
|
- `SIZES.SM` 24px
|
||||||
|
- `SIZES.LG` 32px
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story id="ui-components-component-library-button-icon-button-icon-stories-js--size" />
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { SIZES } from '../../../helpers/constants/design-system';
|
||||||
|
import { ButtonIcon } from '../ui/component-library';
|
||||||
|
|
||||||
|
<ButtonIcon size={SIZES.SM} icon={ICON_NAMES.CLOSE_OUTLINE} ariaLabel="Close"/>
|
||||||
|
<ButtonIcon size={SIZES.LG} icon={ICON_NAMES.CLOSE_OUTLINE} ariaLabel="Close"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Aria Label
|
||||||
|
|
||||||
|
Use the `ariaLabel` prop to set the name of the ButtonIcon for proper accessibility
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story id="ui-components-component-library-button-icon-button-icon-stories-js--aria-label" />
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { ButtonIcon } from '../ui/component-library';
|
||||||
|
|
||||||
|
|
||||||
|
<ButtonIcon as="button" icon={ICON_NAMES.CLOSE_OUTLINE} ariaLabel="Close"/>
|
||||||
|
<ButtonIcon as="a" href="https://metamask.io/" target="_blank" icon={ICON_NAMES.EXPORT} color={COLORS.PRIMARY_DEFAULT} ariaLabel="Visit MetaMask.io"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### As
|
||||||
|
|
||||||
|
Use the `as` box prop to change the element of `ButtonIcon`. Defaults to `button`.
|
||||||
|
|
||||||
|
Button `as` options:
|
||||||
|
|
||||||
|
- `button`
|
||||||
|
- `a`
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story id="ui-components-component-library-button-icon-button-icon-stories-js--as" />
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { ButtonIcon } from '../ui/component-library';
|
||||||
|
|
||||||
|
|
||||||
|
<ButtonIcon as="button" icon={ICON_NAMES.CLOSE_OUTLINE} ariaLabel="Close"/>
|
||||||
|
<ButtonIcon as="a" href="https://metamask.io/" target="_blank" icon={ICON_NAMES.EXPORT} color={COLORS.PRIMARY_DEFAULT} ariaLabel="Visit MetaMask.io"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Href
|
||||||
|
|
||||||
|
When an `href` prop is passed it will change the element to an anchor(`a`) tag.
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story id="ui-components-component-library-button-icon-button-icon-stories-js--href" />
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { ButtonIcon } from '../ui/component-library';
|
||||||
|
|
||||||
|
<ButtonIcon
|
||||||
|
href="https://metamask.io/"
|
||||||
|
target="_blank"
|
||||||
|
icon={ICON_NAMES.EXPORT}
|
||||||
|
color={COLORS.PRIMARY_DEFAULT}
|
||||||
|
ariaLabel="Visit MetaMask.io"
|
||||||
|
/>;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Color
|
||||||
|
|
||||||
|
Use the `color` prop and the `COLORS` object to change the color of the `ButtonIcon`. Defaults to `COLORS.ICON_DEFAULT`.
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story id="ui-components-component-library-button-icon-button-icon-stories-js--color" />
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { ButtonIcon } from '../ui/component-library';
|
||||||
|
|
||||||
|
<ButtonIcon
|
||||||
|
icon={ICON_NAMES.EXPORT}
|
||||||
|
color={COLORS.PRIMARY_DEFAULT}
|
||||||
|
ariaLabel="Visit MetaMask.io"
|
||||||
|
/>;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Disabled
|
||||||
|
|
||||||
|
Use the boolean `disabled` prop to disable button
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story id="ui-components-component-library-button-icon-button-icon-stories-js--disabled" />
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { ButtonIcon } from '../ui/component-library';
|
||||||
|
|
||||||
|
<ButtonIcon icon={ICON_NAMES.CLOSE_OUTLINE} disabled ariaLabel="Close" />;
|
||||||
|
```
|
@ -0,0 +1,16 @@
|
|||||||
|
// 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"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="box icon icon--size-lg box--flex-direction-row box--color-inherit"
|
||||||
|
style="mask-image: url('./images/icons/icon-add-square-filled.svg;"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
@ -0,0 +1,6 @@
|
|||||||
|
import { SIZES } from '../../../helpers/constants/design-system';
|
||||||
|
|
||||||
|
export const BUTTON_ICON_SIZES = {
|
||||||
|
SM: SIZES.SM,
|
||||||
|
LG: SIZES.LG,
|
||||||
|
};
|
101
ui/components/component-library/button-icon/button-icon.js
Normal file
101
ui/components/component-library/button-icon/button-icon.js
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ALIGN_ITEMS,
|
||||||
|
BORDER_RADIUS,
|
||||||
|
COLORS,
|
||||||
|
DISPLAY,
|
||||||
|
JUSTIFY_CONTENT,
|
||||||
|
} from '../../../helpers/constants/design-system';
|
||||||
|
|
||||||
|
import Box from '../../ui/box';
|
||||||
|
import { Icon } from '../icon';
|
||||||
|
|
||||||
|
import { BUTTON_ICON_SIZES } from './button-icon.constants';
|
||||||
|
|
||||||
|
export const ButtonIcon = ({
|
||||||
|
ariaLabel,
|
||||||
|
as = 'button',
|
||||||
|
className,
|
||||||
|
color = COLORS.ICON_DEFAULT,
|
||||||
|
href,
|
||||||
|
size = BUTTON_ICON_SIZES.LG,
|
||||||
|
icon,
|
||||||
|
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={JUSTIFY_CONTENT.CENTER}
|
||||||
|
alignItems={ALIGN_ITEMS.CENTER}
|
||||||
|
borderRadius={BORDER_RADIUS.LG}
|
||||||
|
backgroundColor={COLORS.TRANSPARENT}
|
||||||
|
href={href}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<Icon name={icon} 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 COLOR object from
|
||||||
|
* ./ui/helpers/constants/design-system.js
|
||||||
|
*/
|
||||||
|
color: PropTypes.oneOf(Object.values(COLORS)),
|
||||||
|
/**
|
||||||
|
* 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 ICON_NAMES
|
||||||
|
*/
|
||||||
|
icon: PropTypes.string.isRequired, // Can't set PropTypes.oneOf(ICON_NAMES) because ICON_NAMES is an environment variable
|
||||||
|
/**
|
||||||
|
* iconProps accepts all the props from Icon
|
||||||
|
*/
|
||||||
|
iconProps: PropTypes.object,
|
||||||
|
/**
|
||||||
|
* The size of the ButtonIcon.
|
||||||
|
* Possible values could be 'SIZES.SM', 'SIZES.LG',
|
||||||
|
*/
|
||||||
|
size: PropTypes.oneOf(Object.values(BUTTON_ICON_SIZES)),
|
||||||
|
/**
|
||||||
|
* ButtonIcon accepts all the props from Box
|
||||||
|
*/
|
||||||
|
...Box.propTypes,
|
||||||
|
};
|
32
ui/components/component-library/button-icon/button-icon.scss
Normal file
32
ui/components/component-library/button-icon/button-icon.scss
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
.mm-button-icon {
|
||||||
|
--button-icon-size: var(--size, 24px);
|
||||||
|
--button-icon-opacity-hover: 0.5; // TODO: replace with design tokens
|
||||||
|
--button-icon-opacity-disabled: 0.3; // TODO: replace with design tokens
|
||||||
|
|
||||||
|
height: var(--button-icon-size);
|
||||||
|
width: var(--button-icon-size);
|
||||||
|
padding: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
// ButtonIcon default states
|
||||||
|
&:active,
|
||||||
|
&:hover {
|
||||||
|
opacity: var(--button-icon-opacity-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disabled,
|
||||||
|
&:disabled {
|
||||||
|
opacity: var(--button-icon-opacity-disabled);
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ButtonIcon Sizes
|
||||||
|
&--size-sm {
|
||||||
|
--button-icon-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--size-lg {
|
||||||
|
--button-icon-size: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,186 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
ALIGN_ITEMS,
|
||||||
|
COLORS,
|
||||||
|
DISPLAY,
|
||||||
|
FLEX_DIRECTION,
|
||||||
|
SIZES,
|
||||||
|
} from '../../../helpers/constants/design-system';
|
||||||
|
import Box from '../../ui/box/box';
|
||||||
|
import { ICON_NAMES } from '../icon';
|
||||||
|
import { BUTTON_ICON_SIZES } from './button-icon.constants';
|
||||||
|
import { ButtonIcon } from './button-icon';
|
||||||
|
import README from './README.mdx';
|
||||||
|
|
||||||
|
const marginSizeControlOptions = [
|
||||||
|
undefined,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
7,
|
||||||
|
8,
|
||||||
|
9,
|
||||||
|
10,
|
||||||
|
11,
|
||||||
|
12,
|
||||||
|
'auto',
|
||||||
|
];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Components/ComponentLibrary/ButtonIcon',
|
||||||
|
id: __filename,
|
||||||
|
component: ButtonIcon,
|
||||||
|
parameters: {
|
||||||
|
docs: {
|
||||||
|
page: README,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
argTypes: {
|
||||||
|
ariaLabel: {
|
||||||
|
control: 'text',
|
||||||
|
},
|
||||||
|
as: {
|
||||||
|
control: 'select',
|
||||||
|
options: ['button', 'a'],
|
||||||
|
},
|
||||||
|
className: {
|
||||||
|
control: 'text',
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
control: 'select',
|
||||||
|
options: Object.values(COLORS),
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
control: 'boolean',
|
||||||
|
},
|
||||||
|
href: {
|
||||||
|
control: 'string',
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
control: 'select',
|
||||||
|
options: Object.values(ICON_NAMES),
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
control: 'select',
|
||||||
|
options: Object.values(BUTTON_ICON_SIZES),
|
||||||
|
},
|
||||||
|
marginTop: {
|
||||||
|
options: marginSizeControlOptions,
|
||||||
|
control: 'select',
|
||||||
|
table: { category: 'box props' },
|
||||||
|
},
|
||||||
|
marginRight: {
|
||||||
|
options: marginSizeControlOptions,
|
||||||
|
control: 'select',
|
||||||
|
table: { category: 'box props' },
|
||||||
|
},
|
||||||
|
marginBottom: {
|
||||||
|
options: marginSizeControlOptions,
|
||||||
|
control: 'select',
|
||||||
|
table: { category: 'box props' },
|
||||||
|
},
|
||||||
|
marginLeft: {
|
||||||
|
options: marginSizeControlOptions,
|
||||||
|
control: 'select',
|
||||||
|
table: { category: 'box props' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DefaultStory = (args) => <ButtonIcon {...args} />;
|
||||||
|
|
||||||
|
DefaultStory.args = {
|
||||||
|
icon: ICON_NAMES.CLOSE_OUTLINE,
|
||||||
|
ariaLabel: 'Close',
|
||||||
|
};
|
||||||
|
|
||||||
|
DefaultStory.storyName = 'Default';
|
||||||
|
|
||||||
|
export const Icon = (args) => (
|
||||||
|
<ButtonIcon {...args} icon={ICON_NAMES.CLOSE_OUTLINE} ariaLabel="Close" />
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Size = (args) => (
|
||||||
|
<Box
|
||||||
|
display={DISPLAY.FLEX}
|
||||||
|
alignItems={ALIGN_ITEMS.BASELINE}
|
||||||
|
gap={1}
|
||||||
|
marginBottom={2}
|
||||||
|
>
|
||||||
|
<ButtonIcon
|
||||||
|
{...args}
|
||||||
|
size={SIZES.SM}
|
||||||
|
icon={ICON_NAMES.CLOSE_OUTLINE}
|
||||||
|
ariaLabel="Close"
|
||||||
|
/>
|
||||||
|
<ButtonIcon
|
||||||
|
{...args}
|
||||||
|
size={SIZES.LG}
|
||||||
|
color={COLORS.PRIMARY}
|
||||||
|
icon={ICON_NAMES.CLOSE_OUTLINE}
|
||||||
|
ariaLabel="Close"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const AriaLabel = (args) => (
|
||||||
|
<>
|
||||||
|
<ButtonIcon
|
||||||
|
as="button"
|
||||||
|
icon={ICON_NAMES.CLOSE_OUTLINE}
|
||||||
|
ariaLabel="Close"
|
||||||
|
{...args}
|
||||||
|
/>
|
||||||
|
<ButtonIcon
|
||||||
|
as="a"
|
||||||
|
href="https://metamask.io/"
|
||||||
|
target="_blank"
|
||||||
|
color={COLORS.PRIMARY_DEFAULT}
|
||||||
|
icon={ICON_NAMES.EXPORT}
|
||||||
|
ariaLabel="Visit MetaMask.io"
|
||||||
|
{...args}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const As = (args) => (
|
||||||
|
<Box display={DISPLAY.FLEX} flexDirection={FLEX_DIRECTION.ROW} gap={2}>
|
||||||
|
<ButtonIcon {...args} icon={ICON_NAMES.CLOSE_OUTLINE} />
|
||||||
|
<ButtonIcon
|
||||||
|
as="a"
|
||||||
|
href="#"
|
||||||
|
{...args}
|
||||||
|
color={COLORS.PRIMARY_DEFAULT}
|
||||||
|
icon={ICON_NAMES.EXPORT}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Href = (args) => (
|
||||||
|
<ButtonIcon icon={ICON_NAMES.EXPORT} {...args} target="_blank" />
|
||||||
|
);
|
||||||
|
|
||||||
|
Href.args = {
|
||||||
|
href: 'https://metamask.io/',
|
||||||
|
color: COLORS.PRIMARY_DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Color = (args) => (
|
||||||
|
<ButtonIcon {...args} icon={ICON_NAMES.CLOSE_OUTLINE} />
|
||||||
|
);
|
||||||
|
|
||||||
|
Color.args = {
|
||||||
|
color: COLORS.PRIMARY_DEFAULT,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Disabled = (args) => (
|
||||||
|
<ButtonIcon {...args} icon={ICON_NAMES.CLOSE_OUTLINE} />
|
||||||
|
);
|
||||||
|
|
||||||
|
Disabled.args = {
|
||||||
|
disabled: true,
|
||||||
|
};
|
146
ui/components/component-library/button-icon/button-icon.test.js
Normal file
146
ui/components/component-library/button-icon/button-icon.test.js
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/* eslint-disable jest/require-top-level-describe */
|
||||||
|
import { render } from '@testing-library/react';
|
||||||
|
import React from 'react';
|
||||||
|
import { COLORS } from '../../../helpers/constants/design-system';
|
||||||
|
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"
|
||||||
|
icon="add-square-filled"
|
||||||
|
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"
|
||||||
|
icon="add-square-filled"
|
||||||
|
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"
|
||||||
|
icon="add-square-filled"
|
||||||
|
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
|
||||||
|
icon="add-square-filled"
|
||||||
|
ariaLabel="add"
|
||||||
|
size={BUTTON_ICON_SIZES.SM}
|
||||||
|
data-testid={BUTTON_ICON_SIZES.SM}
|
||||||
|
/>
|
||||||
|
<ButtonIcon
|
||||||
|
icon="add-square-filled"
|
||||||
|
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
|
||||||
|
icon="add-square-filled"
|
||||||
|
ariaLabel="add"
|
||||||
|
color={COLORS.ICON_DEFAULT}
|
||||||
|
data-testid={COLORS.ICON_DEFAULT}
|
||||||
|
/>
|
||||||
|
<ButtonIcon
|
||||||
|
icon="add-square-filled"
|
||||||
|
ariaLabel="add"
|
||||||
|
color={COLORS.ERROR_DEFAULT}
|
||||||
|
data-testid={COLORS.ERROR_DEFAULT}
|
||||||
|
/>
|
||||||
|
</>,
|
||||||
|
);
|
||||||
|
expect(getByTestId(COLORS.ICON_DEFAULT)).toHaveClass(
|
||||||
|
`box--color-${COLORS.ICON_DEFAULT}`,
|
||||||
|
);
|
||||||
|
expect(getByTestId(COLORS.ERROR_DEFAULT)).toHaveClass(
|
||||||
|
`box--color-${COLORS.ERROR_DEFAULT}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render with added classname', () => {
|
||||||
|
const { getByTestId } = render(
|
||||||
|
<ButtonIcon
|
||||||
|
data-testid="classname"
|
||||||
|
className="mm-button-icon--test"
|
||||||
|
icon="add-square-filled"
|
||||||
|
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"
|
||||||
|
icon="add-square-filled"
|
||||||
|
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"
|
||||||
|
icon="add-square-filled"
|
||||||
|
ariaLabel="add"
|
||||||
|
iconProps={{ 'data-testid': 'button-icon' }}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(getByTestId('button-icon')).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render with aria-label', () => {
|
||||||
|
const { getByLabelText } = render(
|
||||||
|
<ButtonIcon icon="add-square-filled" ariaLabel="add" />,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(getByLabelText('add')).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
2
ui/components/component-library/button-icon/index.js
Normal file
2
ui/components/component-library/button-icon/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export { ButtonIcon } from './button-icon';
|
||||||
|
export { BUTTON_ICON_SIZES } from './button-icon.constants';
|
@ -6,6 +6,7 @@
|
|||||||
@import 'avatar-with-badge/avatar-with-badge';
|
@import 'avatar-with-badge/avatar-with-badge';
|
||||||
@import 'base-avatar/base-avatar';
|
@import 'base-avatar/base-avatar';
|
||||||
@import 'button-base/button-base';
|
@import 'button-base/button-base';
|
||||||
|
@import 'button-icon/button-icon';
|
||||||
@import 'button-link/button-link';
|
@import 'button-link/button-link';
|
||||||
@import 'button-primary/button-primary';
|
@import 'button-primary/button-primary';
|
||||||
@import 'button-secondary/button-secondary';
|
@import 'button-secondary/button-secondary';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user