diff --git a/test/e2e/tests/add-account.spec.js b/test/e2e/tests/add-account.spec.js index dc10beb56..226c8bda9 100644 --- a/test/e2e/tests/add-account.spec.js +++ b/test/e2e/tests/add-account.spec.js @@ -242,7 +242,7 @@ describe('Add account', function () { // enter private key', await driver.fill('#private-key-box', testPrivateKey); - await driver.clickElement({ text: 'Import', tag: 'span' }); + await driver.clickElement({ text: 'Import', tag: 'button' }); // should show the correct account name const importedAccountName = await driver.findElement( diff --git a/test/e2e/tests/failing-contract.spec.js b/test/e2e/tests/failing-contract.spec.js index b3f9bb5c0..3391d878e 100644 --- a/test/e2e/tests/failing-contract.spec.js +++ b/test/e2e/tests/failing-contract.spec.js @@ -63,7 +63,7 @@ describe('Failing contract interaction ', function () { // dismiss warning and confirm the transaction await driver.clickElement({ text: 'I want to proceed anyway', - tag: 'span', + tag: 'button', }); await driver.clickElement({ text: 'Confirm', tag: 'button' }); await driver.waitUntilXWindowHandles(2); @@ -149,7 +149,7 @@ describe('Failing contract interaction on non-EIP1559 network', function () { // dismiss warning and confirm the transaction await driver.clickElement({ text: 'I want to proceed anyway', - tag: 'span', + tag: 'button', }); await driver.clickElement({ text: 'Confirm', tag: 'button' }); await driver.waitUntilXWindowHandles(2); diff --git a/test/e2e/tests/from-import-ui.spec.js b/test/e2e/tests/from-import-ui.spec.js index 6a9318351..e56882c05 100644 --- a/test/e2e/tests/from-import-ui.spec.js +++ b/test/e2e/tests/from-import-ui.spec.js @@ -212,7 +212,7 @@ describe('MetaMask Import UI', function () { // enter private key', await driver.fill('#private-key-box', testPrivateKey1); - await driver.clickElement({ text: 'Import', tag: 'span' }); + await driver.clickElement({ text: 'Import', tag: 'button' }); // should show the correct account name const importedAccountName = await driver.findElement( @@ -239,7 +239,7 @@ describe('MetaMask Import UI', function () { await driver.clickElement({ text: 'Import account', tag: 'div' }); // enter private key await driver.fill('#private-key-box', testPrivateKey2); - await driver.clickElement({ text: 'Import', tag: 'span' }); + await driver.clickElement({ text: 'Import', tag: 'button' }); // should see new account in account menu const importedAccount2Name = await driver.findElement( @@ -330,7 +330,7 @@ describe('MetaMask Import UI', function () { await driver.fill('#json-password-box', 'foobarbazqux'); - await driver.clickElement({ text: 'Import', tag: 'span' }); + await driver.clickElement({ text: 'Import', tag: 'button' }); // should show the correct account name const importedAccountName = await driver.findElement( @@ -392,7 +392,7 @@ describe('MetaMask Import UI', function () { // enter private key', await driver.fill('#private-key-box', testPrivateKey); - await driver.clickElement({ text: 'Import', tag: 'span' }); + await driver.clickElement({ text: 'Import', tag: 'button' }); // error should occur await driver.waitForSelector({ diff --git a/ui/components/component-library/button-base/README.mdx b/ui/components/component-library/button-base/README.mdx index 239032379..f18d98636 100644 --- a/ui/components/component-library/button-base/README.mdx +++ b/ui/components/component-library/button-base/README.mdx @@ -102,7 +102,9 @@ import { ButtonBase } from '../../component-library'; When an `externalLink` prop is passed it will change the element to an anchor(`a`) tag and add the `target="_blank"` and `rel="noopener noreferrer"` attributes. + + ```jsx import { ButtonBase } from '../../component-library'; @@ -168,7 +170,7 @@ import { ICON_NAMES } from '../icon'; ### RTL -For RTL language support use the `textProps` prop to pass a `textDirection` prop. +For RTL language support use the `textDirection` prop. @@ -187,11 +189,28 @@ import { ButtonBase, ICON_NAMES } from '../../component-library'; Button Demo >; ``` + +### Ellipsis + +Use the boolean `ellipsis` prop to change the if the `ButtonBase` component to have an ellipsis. + +Note: this should only be used for dynamic/user generated content or addresses. Generally, button text should be succinct and only contain one or two words. + + + + + +```jsx +import { ButtonBase } from '../../component-library'; + + + This is long text example without ellipsis + This is long text example with ellipsis +; +``` diff --git a/ui/components/component-library/button-base/__snapshots__/button-base.test.js.snap b/ui/components/component-library/button-base/__snapshots__/button-base.test.js.snap index 6dc5bfbcf..9e3221f01 100644 --- a/ui/components/component-library/button-base/__snapshots__/button-base.test.js.snap +++ b/ui/components/component-library/button-base/__snapshots__/button-base.test.js.snap @@ -3,17 +3,13 @@ exports[`ButtonBase should render anchor element correctly by href and externalLink, href target and rel exist 1`] = ` - - Button Base - + Button Base `; @@ -21,14 +17,10 @@ exports[`ButtonBase should render anchor element correctly by href and externalL exports[`ButtonBase should render button element correctly and match snapshot 1`] = ` - - Button base - + Button base `; diff --git a/ui/components/component-library/button-base/button-base.js b/ui/components/component-library/button-base/button-base.js index 1a870284a..c79a757e9 100644 --- a/ui/components/component-library/button-base/button-base.js +++ b/ui/components/component-library/button-base/button-base.js @@ -15,6 +15,7 @@ import { Size, BorderRadius, BackgroundColor, + IconColor, } from '../../../helpers/constants/design-system'; import { BUTTON_BASE_SIZES } from './button-base.constants'; @@ -24,6 +25,7 @@ export const ButtonBase = ({ children, className, href, + ellipsis = false, externalLink, size = BUTTON_BASE_SIZES.MD, startIconName, @@ -34,6 +36,7 @@ export const ButtonBase = ({ disabled, iconLoadingProps, textProps, + color = TextColor.textDefault, ...props }) => { const Tag = href ? 'a' : as; @@ -42,13 +45,14 @@ export const ButtonBase = ({ props.rel = 'noopener noreferrer'; } return ( - - - {startIconName && ( - - )} - {children} - {endIconName && ( - - )} - + {startIconName && ( + + )} + {/* + * If children is a string and doesn't need truncation or loading + * prevent html bloat by rendering just the string + * otherwise render with wrapper to allow truncation or loading + */} + {typeof children === 'string' && !ellipsis && !loading ? ( + children + ) : ( + + {children} + + )} + {endIconName && ( + + )} {loading && ( )} - + ); }; @@ -126,6 +150,10 @@ ButtonBase.propTypes = { * When an `href` prop is passed, ButtonBase will automatically change the root element to be an `a` (anchor) tag */ href: PropTypes.string, + /** + * Used for long strings that can be cut off... + */ + ellipsis: PropTypes.bool, /** * Boolean indicating if the link targets external content, it will cause the link to open in a new tab */ diff --git a/ui/components/component-library/button-base/button-base.scss b/ui/components/component-library/button-base/button-base.scss index 42e6d24a9..6b4e249c2 100644 --- a/ui/components/component-library/button-base/button-base.scss +++ b/ui/components/component-library/button-base/button-base.scss @@ -6,18 +6,13 @@ vertical-align: middle; user-select: none; - &:active, - &:hover { - color: var(--color-text-default); - } - &--block { display: block; width: 100%; } - &__content { - height: 100%; + &--ellipsis { + max-width: 100%; } &--size-sm { @@ -36,10 +31,6 @@ cursor: not-allowed; } - &--loading &__content { - color: transparent; - } - &--disabled, &:disabled { opacity: 0.3; diff --git a/ui/components/component-library/button-base/button-base.stories.js b/ui/components/component-library/button-base/button-base.stories.js index ffb512783..0a4afed2c 100644 --- a/ui/components/component-library/button-base/button-base.stories.js +++ b/ui/components/component-library/button-base/button-base.stories.js @@ -1,6 +1,7 @@ import React from 'react'; import { AlignItems, + Color, DISPLAY, FLEX_DIRECTION, Size, @@ -199,11 +200,18 @@ export const Rtl = (args) => ( {...args} startIconName={ICON_NAMES.ADD_SQUARE} endIconName={ICON_NAMES.ARROW_2_RIGHT} - textProps={{ - textDirection: TEXT_DIRECTIONS.RIGHT_TO_LEFT, - }} + textDirection={TEXT_DIRECTIONS.RIGHT_TO_LEFT} > Button Demo ); + +export const Ellipsis = (args) => ( + + Example without ellipsis + + Example with ellipsis + + +); diff --git a/ui/components/component-library/button-link/README.mdx b/ui/components/component-library/button-link/README.mdx index 292190b07..4850161ad 100644 --- a/ui/components/component-library/button-link/README.mdx +++ b/ui/components/component-library/button-link/README.mdx @@ -67,7 +67,7 @@ import { ButtonLink, Text, TextVariant } from '../../component-library'; - Inherits the font-size of the parent element and example with textProps override for a success color. + Inherits the font-size of the parent element and example with override for a success color. Learn more ``` @@ -103,7 +103,7 @@ import { ButtonLink } from '../../component-library'; ### External Link -When an `externalLink` prop is passed it adds the `target="_blank"` and `rel="noopener noreferrer"` attributes. +When an `externalLink` prop is passed it adds the `target="_blank"` and `rel="noopener noreferrer"` attributes. `rel="noreferrer noopener"` is used in links to prevent security vulnerabilities that can be exploited by malicious websites. It disables the window.opener property and prevents the new page from sending the referrer information, providing an additional layer of security. diff --git a/ui/components/component-library/button-link/__snapshots__/button-link.test.js.snap b/ui/components/component-library/button-link/__snapshots__/button-link.test.js.snap index f62717f6c..1a5c0af51 100644 --- a/ui/components/component-library/button-link/__snapshots__/button-link.test.js.snap +++ b/ui/components/component-library/button-link/__snapshots__/button-link.test.js.snap @@ -3,14 +3,10 @@ exports[`ButtonLink should render button element correctly 1`] = ` - - Button Link - + Button Link `; diff --git a/ui/components/component-library/button-link/button-link.js b/ui/components/component-library/button-link/button-link.js index aa77a788a..c7d7dd14f 100644 --- a/ui/components/component-library/button-link/button-link.js +++ b/ui/components/component-library/button-link/button-link.js @@ -3,26 +3,25 @@ import PropTypes from 'prop-types'; import classnames from 'classnames'; import { ButtonBase } from '../button-base'; -import { Text } from '../text'; import { BackgroundColor, Color, Size, - TextVariant, } from '../../../helpers/constants/design-system'; import { BUTTON_LINK_SIZES } from './button-link.constants'; export const ButtonLink = ({ className, danger, + disabled, size = Size.auto, - textProps, ...props }) => { return ( ); }; @@ -62,15 +54,15 @@ ButtonLink.propTypes = { * Boolean to change button type to Danger when true */ danger: PropTypes.bool, + /** + * Boolean to disable button + */ + disabled: PropTypes.bool, /** * Possible size values: 'SIZES.AUTO'(auto), 'SIZES.SM'(32px), 'SIZES.MD'(40px), 'SIZES.LG'(48px), 'SIZES.INHERIT'(inherits parents font-size) * Default value is 'SIZES.AUTO'. */ size: PropTypes.oneOf(Object.values(BUTTON_LINK_SIZES)), - /** - * textProps accepts all the props from Text component - */ - textProps: PropTypes.shape(Text.PropTypes), /** * ButtonLink accepts all the props from ButtonBase */ diff --git a/ui/components/component-library/button-link/button-link.scss b/ui/components/component-library/button-link/button-link.scss index 5c8a4c10b..30e40042c 100644 --- a/ui/components/component-library/button-link/button-link.scss +++ b/ui/components/component-library/button-link/button-link.scss @@ -1,17 +1,14 @@ .mm-button-link { &:hover { - color: var(--color-primary-default); opacity: 0.5; } &:active { - color: var(--color-primary-default); opacity: 0.5; } &--disabled { &:hover { - color: var(--color-primary-default); opacity: 0.3; } diff --git a/ui/components/component-library/button-link/button-link.stories.js b/ui/components/component-library/button-link/button-link.stories.js index b97d8de36..bda5a27f4 100644 --- a/ui/components/component-library/button-link/button-link.stories.js +++ b/ui/components/component-library/button-link/button-link.stories.js @@ -162,12 +162,12 @@ export const SizeStory = (args) => ( - Inherits the font-size of the parent element and example with textProps - override for a success color.{' '} + Inherits the font-size of the parent element and example with override for + a success color.{' '} Learn more diff --git a/ui/components/component-library/button-primary/__snapshots__/button-primary.test.js.snap b/ui/components/component-library/button-primary/__snapshots__/button-primary.test.js.snap index 8b0c03a89..8768e1c7c 100644 --- a/ui/components/component-library/button-primary/__snapshots__/button-primary.test.js.snap +++ b/ui/components/component-library/button-primary/__snapshots__/button-primary.test.js.snap @@ -3,14 +3,10 @@ exports[`ButtonPrimary should render button element correctly 1`] = ` - - Button Primary - + Button Primary `; diff --git a/ui/components/component-library/button-secondary/__snapshots__/button-secondary.test.js.snap b/ui/components/component-library/button-secondary/__snapshots__/button-secondary.test.js.snap index c6f9a3177..fcc63172f 100644 --- a/ui/components/component-library/button-secondary/__snapshots__/button-secondary.test.js.snap +++ b/ui/components/component-library/button-secondary/__snapshots__/button-secondary.test.js.snap @@ -3,14 +3,10 @@ exports[`ButtonSecondary should render button element correctly 1`] = ` - - Button Secondary - + Button Secondary `; diff --git a/ui/components/component-library/button/__snapshots__/button.test.js.snap b/ui/components/component-library/button/__snapshots__/button.test.js.snap index a0685c51a..7d795a179 100644 --- a/ui/components/component-library/button/__snapshots__/button.test.js.snap +++ b/ui/components/component-library/button/__snapshots__/button.test.js.snap @@ -3,14 +3,10 @@ exports[`Button should render button element correctly 1`] = ` - - Button - + Button `; @@ -18,34 +14,22 @@ exports[`Button should render button element correctly 1`] = ` exports[`Button should render with different button types 1`] = ` - - Button - + Button - - Button - + Button - - Button - + Button `; diff --git a/ui/helpers/constants/design-system.ts b/ui/helpers/constants/design-system.ts index c39e95f51..a80999cbf 100644 --- a/ui/helpers/constants/design-system.ts +++ b/ui/helpers/constants/design-system.ts @@ -130,6 +130,7 @@ export enum TextColor { lineaTestnetInverse = 'lineatestnet-inverse', goerliInverse = 'goerli-inverse', sepoliaInverse = 'sepolia-inverse', + transparent = 'transparent', } export enum IconColor { diff --git a/ui/pages/keychains/__snapshots__/reveal-seed.test.js.snap b/ui/pages/keychains/__snapshots__/reveal-seed.test.js.snap index 0d97c028a..5bf39129d 100644 --- a/ui/pages/keychains/__snapshots__/reveal-seed.test.js.snap +++ b/ui/pages/keychains/__snapshots__/reveal-seed.test.js.snap @@ -17,16 +17,12 @@ exports[`Reveal Seed Page should match snapshot 1`] = ` The - - Secret Recovery Phrase (SRP) - + Secret Recovery Phrase (SRP) provides - - non-custodial wallet - + non-custodial wallet . That means you're the owner of your SRP. @@ -112,23 +104,15 @@ exports[`Reveal Seed Page should match snapshot 1`] = ` class="box box--margin-top-auto box--display-flex box--gap-4 box--flex-direction-row" > - - Cancel - + Cancel - - Next - + Next