mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
UX: Multichain: Address Copy Button (#18153)
This commit is contained in:
parent
ff20873c65
commit
efc34b9420
@ -0,0 +1,64 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import { ICON_NAMES, ButtonBase } from '../../component-library';
|
||||||
|
import {
|
||||||
|
BackgroundColor,
|
||||||
|
TextVariant,
|
||||||
|
TextColor,
|
||||||
|
Size,
|
||||||
|
BorderRadius,
|
||||||
|
AlignItems,
|
||||||
|
} from '../../../helpers/constants/design-system';
|
||||||
|
import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard';
|
||||||
|
import { shortenAddress } from '../../../helpers/utils/util';
|
||||||
|
import Tooltip from '../../ui/tooltip/tooltip';
|
||||||
|
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||||
|
|
||||||
|
export const AddressCopyButton = ({
|
||||||
|
address,
|
||||||
|
shorten = false,
|
||||||
|
wrap = false,
|
||||||
|
}) => {
|
||||||
|
const displayAddress = shorten ? shortenAddress(address) : address;
|
||||||
|
const [copied, handleCopy] = useCopyToClipboard();
|
||||||
|
const t = useI18nContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip position="bottom" title={copied ? t('copiedExclamation') : null}>
|
||||||
|
<ButtonBase
|
||||||
|
backgroundColor={BackgroundColor.primaryMuted}
|
||||||
|
onClick={() => handleCopy(address)}
|
||||||
|
paddingRight={4}
|
||||||
|
paddingLeft={4}
|
||||||
|
size={Size.SM}
|
||||||
|
variant={TextVariant.bodyXs}
|
||||||
|
color={TextColor.primaryDefault}
|
||||||
|
endIconName={copied ? ICON_NAMES.COPY_SUCCESS : ICON_NAMES.COPY}
|
||||||
|
className={classnames('multichain-address-copy-button', {
|
||||||
|
'multichain-address-copy-button__address--wrap': wrap,
|
||||||
|
})}
|
||||||
|
borderRadius={BorderRadius.pill}
|
||||||
|
alignItems={AlignItems.center}
|
||||||
|
data-testid="address-copy-button-text"
|
||||||
|
>
|
||||||
|
{displayAddress}
|
||||||
|
</ButtonBase>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
AddressCopyButton.propTypes = {
|
||||||
|
/**
|
||||||
|
* Address to be copied
|
||||||
|
*/
|
||||||
|
address: PropTypes.string.isRequired,
|
||||||
|
/**
|
||||||
|
* Represents if the address should be shortened
|
||||||
|
*/
|
||||||
|
shorten: PropTypes.bool,
|
||||||
|
/**
|
||||||
|
* Represents if the element should wrap to multiple lines
|
||||||
|
*/
|
||||||
|
wrap: PropTypes.bool,
|
||||||
|
};
|
@ -0,0 +1,36 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { AddressCopyButton } from '.';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Components/Multichain/AddressCopyButton',
|
||||||
|
component: AddressCopyButton,
|
||||||
|
argTypes: {
|
||||||
|
address: {
|
||||||
|
control: 'text',
|
||||||
|
},
|
||||||
|
shorten: {
|
||||||
|
control: 'boolean',
|
||||||
|
},
|
||||||
|
wrap: {
|
||||||
|
control: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
args: {
|
||||||
|
address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DefaultStory = (args) => <AddressCopyButton {...args} />;
|
||||||
|
DefaultStory.storyName = 'Default';
|
||||||
|
|
||||||
|
export const ShortenedStory = (args) => <AddressCopyButton {...args} />;
|
||||||
|
ShortenedStory.storyName = 'Shortened';
|
||||||
|
ShortenedStory.args = { shorten: true };
|
||||||
|
|
||||||
|
export const WrappedStory = (args) => (
|
||||||
|
<div style={{ width: '200px' }}>
|
||||||
|
<AddressCopyButton {...args} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
WrappedStory.storyName = 'Wrapped';
|
||||||
|
WrappedStory.args = { wrap: true };
|
@ -0,0 +1,31 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { fireEvent, render } from '@testing-library/react';
|
||||||
|
import { AddressCopyButton } from '.';
|
||||||
|
|
||||||
|
const SAMPLE_ADDRESS = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc';
|
||||||
|
|
||||||
|
describe('AccountListItem', () => {
|
||||||
|
it('renders the full address by default', () => {
|
||||||
|
render(<AddressCopyButton address={SAMPLE_ADDRESS} />);
|
||||||
|
expect(
|
||||||
|
document.querySelector('[data-testid="address-copy-button-text"]')
|
||||||
|
.textContent,
|
||||||
|
).toStrictEqual(SAMPLE_ADDRESS);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders a shortened address when it should', () => {
|
||||||
|
render(<AddressCopyButton address={SAMPLE_ADDRESS} shorten />);
|
||||||
|
expect(
|
||||||
|
document.querySelector('[data-testid="address-copy-button-text"]')
|
||||||
|
.textContent,
|
||||||
|
).toStrictEqual('0x0dc...e7bc');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('changes icon when clicked', () => {
|
||||||
|
render(<AddressCopyButton address={SAMPLE_ADDRESS} />);
|
||||||
|
fireEvent.click(document.querySelector('button'));
|
||||||
|
expect(document.querySelector('.mm-icon').style.maskImage).toContain(
|
||||||
|
'copy-success.svg',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
1
ui/components/multichain/address-copy-button/index.js
Normal file
1
ui/components/multichain/address-copy-button/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { AddressCopyButton } from './address-copy-button';
|
7
ui/components/multichain/address-copy-button/index.scss
Normal file
7
ui/components/multichain/address-copy-button/index.scss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.multichain-address-copy-button {
|
||||||
|
&__address--wrap {
|
||||||
|
word-break: break-word;
|
||||||
|
min-height: 32px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
@ -5,3 +5,4 @@ export { DetectedTokensBanner } from './detected-token-banner';
|
|||||||
export { GlobalMenu } from './global-menu';
|
export { GlobalMenu } from './global-menu';
|
||||||
export { MultichainImportTokenLink } from './multichain-import-token-link';
|
export { MultichainImportTokenLink } from './multichain-import-token-link';
|
||||||
export { MultichainTokenListItem } from './multichain-token-list-item';
|
export { MultichainTokenListItem } from './multichain-token-list-item';
|
||||||
|
export { AddressCopyButton } from './address-copy-button';
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
* This will help improve specificity and reduce the chance of
|
* This will help improve specificity and reduce the chance of
|
||||||
* unintended overrides.
|
* unintended overrides.
|
||||||
**/
|
**/
|
||||||
|
@import 'address-copy-button/index';
|
||||||
@import 'account-list-item/index';
|
@import 'account-list-item/index';
|
||||||
@import 'account-list-menu/index';
|
@import 'account-list-menu/index';
|
||||||
@import 'multichain-token-list-item/multichain-token-list-item';
|
@import 'multichain-token-list-item/multichain-token-list-item';
|
||||||
|
@ -8,6 +8,8 @@ import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils
|
|||||||
import Tooltip from '../tooltip';
|
import Tooltip from '../tooltip';
|
||||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||||
import { Icon, ICON_NAMES, ICON_SIZES } from '../../component-library';
|
import { Icon, ICON_NAMES, ICON_SIZES } from '../../component-library';
|
||||||
|
import { AddressCopyButton } from '../../multichain/address-copy-button';
|
||||||
|
import Box from '../box/box';
|
||||||
|
|
||||||
export default connect(mapStateToProps)(QrCodeView);
|
export default connect(mapStateToProps)(QrCodeView);
|
||||||
|
|
||||||
@ -56,6 +58,11 @@ function QrCodeView(props) {
|
|||||||
__html: qrImage.createTableTag(4),
|
__html: qrImage.createTableTag(4),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{process.env.MULTICHAIN ? (
|
||||||
|
<Box marginLeft={2} marginRight={2}>
|
||||||
|
<AddressCopyButton wrap address={toChecksumHexAddress(data)} />
|
||||||
|
</Box>
|
||||||
|
) : (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
wrapperClassName="qr-code__address-container__tooltip-wrapper"
|
wrapperClassName="qr-code__address-container__tooltip-wrapper"
|
||||||
position="bottom"
|
position="bottom"
|
||||||
@ -75,6 +82,7 @@ function QrCodeView(props) {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user