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

fix/BannerBase to TS (#20421)

* BannerBase to TS

* snapshot updates

* more snapshot updates

* addressing type definition error

* updating eth-sign-modal snapshot

* Updates to stories, types and adding data-testid

* Updating snapshots

* updating snapshot of blockaid-banner-alert and adding unit test for childrenWrapperProps

* BannerBase updates to stories, adding locale for close button, removing static data-testid in favor of using it at the instance, updating snapshots associated with those changes

* Removing incorrect arg from storybook file

* Updating html element in security provider e2e test to match BannerBase. Also updating snapshot of ConfirmTransaction page

* Fixing e2e tests

---------

Co-authored-by: georgewrmarshall <george.marshall@consensys.net>
This commit is contained in:
Dhruv 2023-08-19 03:22:40 +05:30 committed by GitHub
parent 885a8ce256
commit 07abc53cce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 429 additions and 403 deletions

View File

@ -157,7 +157,7 @@ const checkActivityTransaction = async (driver, options) => {
const checkNotification = async (driver, options) => { const checkNotification = async (driver, options) => {
const boxTitle = await driver.findElement( const boxTitle = await driver.findElement(
'[data-testid="mm-banner-base-title"]', '[data-testid="swaps-banner-title"]',
); );
assert.equal(await boxTitle.getText(), options.title, 'Invalid box title'); assert.equal(await boxTitle.getText(), options.title, 'Invalid box title');
const boxContent = await driver.findElement( const boxContent = await driver.findElement(

View File

@ -106,7 +106,7 @@ describe('Transaction security provider', function () {
); );
const warningHeader = await driver.isElementPresent({ const warningHeader = await driver.isElementPresent({
text: 'This could be a scam', text: 'This could be a scam',
tag: 'h5', tag: 'p',
}); });
assert.equal(warningHeader, true); assert.equal(warningHeader, true);
}, },
@ -146,7 +146,7 @@ describe('Transaction security provider', function () {
); );
const warningHeader = await driver.isElementPresent({ const warningHeader = await driver.isElementPresent({
text: 'Request may not be safe', text: 'Request may not be safe',
tag: 'h5', tag: 'p',
}); });
assert.equal(warningHeader, true); assert.equal(warningHeader, true);
}, },
@ -186,7 +186,7 @@ describe('Transaction security provider', function () {
); );
const warningHeader = await driver.isElementPresent({ const warningHeader = await driver.isElementPresent({
text: 'Request may not be safe', text: 'Request may not be safe',
tag: 'h5', tag: 'p',
}); });
assert.equal(warningHeader, false); assert.equal(warningHeader, false);
}, },
@ -226,7 +226,7 @@ describe('Transaction security provider', function () {
); );
const warningHeader = await driver.isElementPresent({ const warningHeader = await driver.isElementPresent({
text: 'Request not verified', text: 'Request not verified',
tag: 'h5', tag: 'p',
}); });
assert.equal(warningHeader, true); assert.equal(warningHeader, true);
}, },

View File

@ -7,7 +7,7 @@ exports[`LedgerInstructionField Component rendering should render properly with
class="confirm-detail-row" class="confirm-detail-row"
> >
<div <div
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-info box--padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-primary-muted box--rounded-sm" class="mm-box mm-banner-base mm-banner-alert mm-banner-alert--severity-info mm-box--padding-3 mm-box--padding-left-2 mm-box--display-flex mm-box--gap-2 mm-box--background-color-primary-muted mm-box--rounded-sm"
> >
<span <span
class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-primary-default" class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-primary-default"

View File

@ -41,7 +41,7 @@ exports[`Eth Sign Modal should match snapshot 1`] = `
</a> </a>
</p> </p>
<div <div
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-danger box--margin-top-6 box--margin-bottom-6 box--padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-error-muted box--rounded-sm" class="mm-box mm-banner-base mm-banner-alert mm-banner-alert--severity-danger mm-box--margin-top-6 mm-box--margin-bottom-6 mm-box--padding-3 mm-box--padding-left-2 mm-box--display-flex mm-box--gap-2 mm-box--background-color-error-muted mm-box--rounded-sm"
> >
<span <span
class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-error-default" class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-error-default"

View File

@ -102,7 +102,7 @@ exports[`Export PrivateKey Modal should match snapshot 1`] = `
class="mm-box mm-text mm-text--body-sm mm-box--color-error-default" class="mm-box mm-text mm-text--body-sm mm-box--color-error-default"
/> />
<div <div
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-danger box--margin-top-4 box--margin-right-5 box--margin-left-5 box--padding-1 box--sm:padding-3 box--lg:padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-error-muted box--rounded-sm" class="mm-box mm-banner-base mm-banner-alert mm-banner-alert--severity-danger mm-box--margin-top-4 mm-box--margin-right-5 mm-box--margin-left-5 mm-box--padding-1 mm-box--sm:padding-3 mm-box--md:padding-0 mm-box--lg:padding-3 mm-box--padding-left-2 mm-box--display-flex mm-box--gap-2 mm-box--background-color-error-muted mm-box--rounded-sm"
> >
<span <span
class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-error-default" class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-error-default"

View File

@ -3,19 +3,18 @@
exports[`Security Provider Banner Alert should match snapshot 1`] = ` exports[`Security Provider Banner Alert should match snapshot 1`] = `
<div> <div>
<div <div
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-danger box--margin-4 box--padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-error-muted box--rounded-sm" class="mm-box mm-banner-base mm-banner-alert mm-banner-alert--severity-danger mm-box--margin-4 mm-box--padding-3 mm-box--padding-left-2 mm-box--display-flex mm-box--gap-2 mm-box--background-color-error-muted mm-box--rounded-sm"
> >
<span <span
class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-error-default" class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-error-default"
style="mask-image: url('./images/icons/danger.svg');" style="mask-image: url('./images/icons/danger.svg');"
/> />
<div> <div>
<h5 <p
class="mm-box mm-text mm-banner-base__title mm-text--body-lg-medium mm-box--color-text-default" class="mm-box mm-text mm-text--body-lg-medium mm-box--color-text-default"
data-testid="mm-banner-base-title"
> >
Malicious third party detected Malicious third party detected
</h5> </p>
<p <p
class="mm-box mm-text mm-text--body-md mm-box--margin-top-2 mm-box--color-text-default" class="mm-box mm-text mm-text--body-md mm-box--margin-top-2 mm-box--color-text-default"
> >

View File

@ -2,19 +2,18 @@
exports[`Blockaid Banner Alert should render 'danger' UI when securityAlertResponse.result_type is 'Malicious 1`] = ` exports[`Blockaid Banner Alert should render 'danger' UI when securityAlertResponse.result_type is 'Malicious 1`] = `
<div <div
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-danger box--margin-4 box--padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-error-muted box--rounded-sm" class="mm-box mm-banner-base mm-banner-alert mm-banner-alert--severity-danger mm-box--margin-4 mm-box--padding-3 mm-box--padding-left-2 mm-box--display-flex mm-box--gap-2 mm-box--background-color-error-muted mm-box--rounded-sm"
> >
<span <span
class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-error-default" class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-error-default"
style="mask-image: url('./images/icons/danger.svg');" style="mask-image: url('./images/icons/danger.svg');"
/> />
<div> <div>
<h5 <p
class="mm-box mm-text mm-banner-base__title mm-text--body-lg-medium mm-box--color-text-default" class="mm-box mm-text mm-text--body-lg-medium mm-box--color-text-default"
data-testid="mm-banner-base-title"
> >
This is a deceptive request This is a deceptive request
</h5> </p>
<p <p
class="mm-box mm-text mm-text--body-md mm-box--margin-top-2 mm-box--color-text-default" class="mm-box mm-text mm-text--body-md mm-box--margin-top-2 mm-box--color-text-default"
> >
@ -48,19 +47,18 @@ exports[`Blockaid Banner Alert should render 'danger' UI when securityAlertRespo
exports[`Blockaid Banner Alert should render 'warning' UI when securityAlertResponse.result_type is 'Failed 1`] = ` exports[`Blockaid Banner Alert should render 'warning' UI when securityAlertResponse.result_type is 'Failed 1`] = `
<div <div
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-warning box--margin-4 box--padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-warning-muted box--rounded-sm" class="mm-box mm-banner-base mm-banner-alert mm-banner-alert--severity-warning mm-box--margin-4 mm-box--padding-3 mm-box--padding-left-2 mm-box--display-flex mm-box--gap-2 mm-box--background-color-warning-muted mm-box--rounded-sm"
> >
<span <span
class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-warning-default" class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-warning-default"
style="mask-image: url('./images/icons/danger.svg');" style="mask-image: url('./images/icons/danger.svg');"
/> />
<div> <div>
<h5 <p
class="mm-box mm-text mm-banner-base__title mm-text--body-lg-medium mm-box--color-text-default" class="mm-box mm-text mm-text--body-lg-medium mm-box--color-text-default"
data-testid="mm-banner-base-title"
> >
This is a deceptive request This is a deceptive request
</h5> </p>
<p <p
class="mm-box mm-text mm-text--body-md mm-box--margin-top-2 mm-box--color-text-default" class="mm-box mm-text mm-text--body-md mm-box--margin-top-2 mm-box--color-text-default"
> >
@ -72,19 +70,18 @@ exports[`Blockaid Banner Alert should render 'warning' UI when securityAlertResp
exports[`Blockaid Banner Alert should render 'warning' UI when securityAlertResponse.result_type is 'Warning 1`] = ` exports[`Blockaid Banner Alert should render 'warning' UI when securityAlertResponse.result_type is 'Warning 1`] = `
<div <div
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-warning box--margin-4 box--padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-warning-muted box--rounded-sm" class="mm-box mm-banner-base mm-banner-alert mm-banner-alert--severity-warning mm-box--margin-4 mm-box--padding-3 mm-box--padding-left-2 mm-box--display-flex mm-box--gap-2 mm-box--background-color-warning-muted mm-box--rounded-sm"
> >
<span <span
class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-warning-default" class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-warning-default"
style="mask-image: url('./images/icons/danger.svg');" style="mask-image: url('./images/icons/danger.svg');"
/> />
<div> <div>
<h5 <p
class="mm-box mm-text mm-banner-base__title mm-text--body-lg-medium mm-box--color-text-default" class="mm-box mm-text mm-text--body-lg-medium mm-box--color-text-default"
data-testid="mm-banner-base-title"
> >
This is a deceptive request This is a deceptive request
</h5> </p>
<p <p
class="mm-box mm-text mm-text--body-md mm-box--margin-top-2 mm-box--color-text-default" class="mm-box mm-text mm-text--body-md mm-box--margin-top-2 mm-box--color-text-default"
> >
@ -119,19 +116,18 @@ exports[`Blockaid Banner Alert should render 'warning' UI when securityAlertResp
exports[`Blockaid Banner Alert should render details when provided 1`] = ` exports[`Blockaid Banner Alert should render details when provided 1`] = `
<div> <div>
<div <div
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-warning box--margin-4 box--padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-warning-muted box--rounded-sm" class="mm-box mm-banner-base mm-banner-alert mm-banner-alert--severity-warning mm-box--margin-4 mm-box--padding-3 mm-box--padding-left-2 mm-box--display-flex mm-box--gap-2 mm-box--background-color-warning-muted mm-box--rounded-sm"
> >
<span <span
class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-warning-default" class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-warning-default"
style="mask-image: url('./images/icons/danger.svg');" style="mask-image: url('./images/icons/danger.svg');"
/> />
<div> <div>
<h5 <p
class="mm-box mm-text mm-banner-base__title mm-text--body-lg-medium mm-box--color-text-default" class="mm-box mm-text mm-text--body-lg-medium mm-box--color-text-default"
data-testid="mm-banner-base-title"
> >
This is a deceptive request This is a deceptive request
</h5> </p>
<p <p
class="mm-box mm-text mm-text--body-md mm-box--margin-top-2 mm-box--color-text-default" class="mm-box mm-text mm-text--body-md mm-box--margin-top-2 mm-box--color-text-default"
> >

View File

@ -3,7 +3,7 @@
exports[`BannerAlert should render BannerAlert element correctly 1`] = ` exports[`BannerAlert should render BannerAlert element correctly 1`] = `
<div> <div>
<div <div
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-info box--padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-primary-muted box--rounded-sm" class="mm-box mm-banner-base mm-banner-alert mm-banner-alert--severity-info mm-box--padding-3 mm-box--padding-left-2 mm-box--display-flex mm-box--gap-2 mm-box--background-color-primary-muted mm-box--rounded-sm"
data-testid="bannerAlert" data-testid="bannerAlert"
> >
<span <span
@ -11,12 +11,11 @@ exports[`BannerAlert should render BannerAlert element correctly 1`] = `
style="mask-image: url('./images/icons/info.svg');" style="mask-image: url('./images/icons/info.svg');"
/> />
<div> <div>
<h5 <p
class="mm-box mm-text mm-banner-base__title mm-text--body-lg-medium mm-box--color-text-default" class="mm-box mm-text mm-text--body-lg-medium mm-box--color-text-default"
data-testid="mm-banner-base-title"
> >
BannerAlert test BannerAlert test
</h5> </p>
<p <p
class="mm-box mm-text mm-text--body-md mm-box--color-text-default" class="mm-box mm-text mm-text--body-md mm-box--color-text-default"
> >

View File

@ -75,9 +75,7 @@ describe('BannerAlert', () => {
const { getByText } = render( const { getByText } = render(
<BannerAlert title="BannerAlert title test" />, <BannerAlert title="BannerAlert title test" />,
); );
expect(getByText('BannerAlert title test')).toHaveClass( expect(getByText('BannerAlert title test')).toBeDefined();
'mm-banner-base__title',
);
}); });
it('should render BannerAlert description', () => { it('should render BannerAlert description', () => {

View File

@ -7,21 +7,19 @@ import { BannerBase } from './banner-base';
`BannerBase` serves as a base for all banner variants. It contains standard props such as information and related actions. `BannerBase` serves as a base for all banner variants. It contains standard props such as information and related actions.
<Canvas style={{ background: 'var(--color-background-alternative)' }}> <Canvas>
<Story id="components-componentlibrary-bannerbase--default-story" /> <Story id="components-componentlibrary-bannerbase--default-story" />
</Canvas> </Canvas>
## Props ## Props
The `BannerBase` accepts all props below as well as all [Box](/docs/components-ui-box--default-story#props) component props
<ArgsTable of={BannerBase} /> <ArgsTable of={BannerBase} />
### Title ### Title
Use the `title` prop to pass a string that is sentence case no period. Use the `titleProps` prop to pass additional props to the `Text` component. Use the `title` prop to pass a string that is sentence case no period. Use the `titleProps` prop to pass additional props to the `Text` component.
<Canvas style={{ background: 'var(--color-background-alternative)' }}> <Canvas>
<Story id="components-componentlibrary-bannerbase--title" /> <Story id="components-componentlibrary-bannerbase--title" />
</Canvas> </Canvas>
@ -39,7 +37,7 @@ The `description` is the content area of the `BannerBase` that must be a string.
If content requires more than a string, see `children` prop below. If content requires more than a string, see `children` prop below.
<Canvas style={{ background: 'var(--color-background-alternative)' }}> <Canvas>
<Story id="components-componentlibrary-bannerbase--description" /> <Story id="components-componentlibrary-bannerbase--description" />
</Canvas> </Canvas>
@ -56,7 +54,7 @@ import { BannerBase } from '../../component-library';
The `children` prop is an alternative to `description` for `BannerBase` when more than a string is needed. Children content shouldn't repeat title and only 1-3 lines. The `children` prop is an alternative to `description` for `BannerBase` when more than a string is needed. Children content shouldn't repeat title and only 1-3 lines.
<Canvas style={{ background: 'var(--color-background-alternative)' }}> <Canvas>
<Story id="components-componentlibrary-bannerbase--children" /> <Story id="components-componentlibrary-bannerbase--children" />
</Canvas> </Canvas>
@ -76,7 +74,7 @@ import { BannerBase } from '../../component-library';
Use the `actionButtonLabel` prop to pass text, `actionButtonOnClick` prop to pass an onClick handler, and `actionButtonProps` prop to pass an object of [ButtonLink props](/docs/components-componentlibrary-buttonlink--default-story) for the action Use the `actionButtonLabel` prop to pass text, `actionButtonOnClick` prop to pass an onClick handler, and `actionButtonProps` prop to pass an object of [ButtonLink props](/docs/components-componentlibrary-buttonlink--default-story) for the action
<Canvas style={{ background: 'var(--color-background-alternative)' }}> <Canvas>
<Story id="components-componentlibrary-bannerbase--action-button" /> <Story id="components-componentlibrary-bannerbase--action-button" />
</Canvas> </Canvas>
@ -103,7 +101,7 @@ Use the `onClose` prop to pass a function to the close button. The close button
Additional props can be passed to the close button with `closeButtonProps` Additional props can be passed to the close button with `closeButtonProps`
<Canvas style={{ background: 'var(--color-background-alternative)' }}> <Canvas>
<Story id="components-componentlibrary-bannerbase--on-close" /> <Story id="components-componentlibrary-bannerbase--on-close" />
</Canvas> </Canvas>
@ -122,7 +120,7 @@ import { BannerBase } from '../../component-library';
Use the `startAccessory` prop to add components such as icons or fox image to the start (default: left) of the `BannerBase` content Use the `startAccessory` prop to add components such as icons or fox image to the start (default: left) of the `BannerBase` content
<Canvas style={{ background: 'var(--color-background-alternative)' }}> <Canvas>
<Story id="components-componentlibrary-bannerbase--start-accessory" /> <Story id="components-componentlibrary-bannerbase--start-accessory" />
</Canvas> </Canvas>

View File

@ -1,24 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`BannerBase should render bannerbase element correctly 1`] = `
<div>
<div
class="box mm-banner-base box--padding-3 box--display-flex box--gap-2 box--flex-direction-row box--background-color-background-default box--rounded-sm"
data-testid="banner-base"
>
<div>
<h5
class="mm-box mm-text mm-banner-base__title mm-text--body-lg-medium mm-box--color-text-default"
data-testid="mm-banner-base-title"
>
Bannerbase test
</h5>
<p
class="mm-box mm-text mm-text--body-md mm-box--color-text-default"
>
should render bannerbase element correctly
</p>
</div>
</div>
</div>
`;

View File

@ -0,0 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`BannerBase should render BannerBase element correctly 1`] = `
<div>
<div
class="mm-box mm-banner-base mm-box--padding-3 mm-box--display-flex mm-box--gap-2 mm-box--background-color-background-default mm-box--rounded-sm"
data-testid="banner-base"
>
<div>
<p
class="mm-box mm-text mm-text--body-lg-medium mm-box--color-text-default"
>
BannerBase test
</p>
<p
class="mm-box mm-text mm-text--body-md mm-box--color-text-default"
>
should render BannerBase element correctly
</p>
</div>
</div>
</div>
`;

View File

@ -1,141 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import {
BackgroundColor,
BorderRadius,
Display,
Size,
TextVariant,
} from '../../../helpers/constants/design-system';
import Box from '../../ui/box';
import { ButtonLink, IconName, ButtonIcon, Text } from '..';
export const BannerBase = ({
className,
title,
titleProps,
description,
descriptionProps,
children,
actionButtonLabel,
actionButtonOnClick,
actionButtonProps,
startAccessory,
onClose,
closeButtonProps,
...props
}) => {
return (
<Box
className={classnames('mm-banner-base', className)}
display={Display.Flex}
gap={2}
backgroundColor={BackgroundColor.backgroundDefault}
borderRadius={BorderRadius.SM}
padding={3}
{...props}
>
{startAccessory && <>{startAccessory}</>}
<div>
{title && (
<Text
className="mm-banner-base__title"
variant={TextVariant.bodyLgMedium}
data-testid="mm-banner-base-title"
as="h5"
{...titleProps}
>
{title}
</Text>
)}
{description && <Text {...descriptionProps}>{description}</Text>}
{children && typeof children === 'object' ? (
children
) : (
<Text>{children}</Text>
)}
{actionButtonLabel && (
<ButtonLink
size={Size.auto}
onClick={actionButtonOnClick}
{...actionButtonProps}
>
{actionButtonLabel}
</ButtonLink>
)}
</div>
{onClose && (
<ButtonIcon
className="mm-banner-base__close-button"
marginLeft="auto"
iconName={IconName.Close}
size={Size.SM}
ariaLabel="Close" // TODO: i18n
onClick={onClose}
{...closeButtonProps}
/>
)}
</Box>
);
};
BannerBase.propTypes = {
/**
* The title of the BannerBase
*/
title: PropTypes.string,
/**
* Additional props to pass to the `Text` component used for the `title` text
*/
titleProps: PropTypes.object,
/**
* The description is the content area below BannerBase title
*/
description: PropTypes.string,
/**
* Additional props to pass to the `Text` component used for the `description` text
*/
descriptionProps: PropTypes.object,
/**
* The children is an alternative to using the description prop for BannerBase content below the title
*/
children: PropTypes.node,
/**
* Label for action button (ButtonLink) of the BannerBase below the children
*/
actionButtonLabel: PropTypes.string,
/**
* Props for action button (ButtonLink) of the BannerBase below the children
*/
actionButtonProps: PropTypes.object,
/**
* The onClick handler for the action button (ButtonLink)
*/
actionButtonOnClick: PropTypes.func,
/**
* The start(defualt left) content area of BannerBase
*/
startAccessory: PropTypes.node,
/**
* The onClick handler for the close button
* When passed this will allow for the close button to show
*/
onClose: PropTypes.func,
/**
* The props to pass to the close button
*/
closeButtonProps: PropTypes.object,
/**
* An additional className to apply to the BannerBase
*/
className: PropTypes.string,
/**
* BannerBase accepts all the props from Box
*/
...Box.propTypes,
};

View File

@ -1,28 +1,17 @@
import React from 'react'; import React from 'react';
import { Meta, StoryFn } from '@storybook/react';
import { useState } from '@storybook/addons'; import { useState } from '@storybook/addons';
import { Size } from '../../../helpers/constants/design-system'; import {
import { ButtonLink, ButtonPrimary, Icon, IconName, IconSize } from '..'; ButtonLink,
ButtonLinkSize,
ButtonPrimary,
Icon,
IconName,
IconSize,
} from '..';
import { BannerBase } from './banner-base'; import { BannerBase } from './banner-base';
import README from './README.mdx'; import README from './README.mdx';
const marginSizeControlOptions = [
undefined,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
'auto',
];
export default { export default {
title: 'Components/ComponentLibrary/BannerBase', title: 'Components/ComponentLibrary/BannerBase',
component: BannerBase, component: BannerBase,
@ -39,20 +28,26 @@ export default {
title: { title: {
control: 'text', control: 'text',
}, },
titleProps: {
control: 'object',
},
description: { description: {
control: 'text', control: 'text',
}, },
descriptionProps: {
control: 'object',
},
children: { children: {
control: 'text', control: 'text',
}, },
action: { childrenProps: {
control: 'func', control: 'object',
}, },
actionButtonLabel: { actionButtonLabel: {
control: 'text', control: 'text',
}, },
actionButtonOnClick: { actionButtonOnClick: {
control: 'func', action: 'actionButtonOnClick',
}, },
actionButtonProps: { actionButtonProps: {
control: 'object', control: 'object',
@ -63,33 +58,12 @@ export default {
onClose: { onClose: {
action: 'onClose', action: 'onClose',
}, },
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' },
},
}, },
}; } as Meta<typeof BannerBase>;
export const DefaultStory = (args) => { const Template: StoryFn<typeof BannerBase> = (args) => <BannerBase {...args} />;
const onClose = () => console.log('BannerBase onClose trigger');
return <BannerBase {...args} onClose={onClose} />; export const DefaultStory = Template.bind({});
};
DefaultStory.args = { DefaultStory.args = {
title: 'Title is sentence case no period', title: 'Title is sentence case no period',
@ -100,18 +74,14 @@ DefaultStory.args = {
DefaultStory.storyName = 'Default'; DefaultStory.storyName = 'Default';
export const Title = (args) => { export const Title = Template.bind({});
return <BannerBase {...args} />;
};
Title.args = { Title.args = {
title: 'Title is sentence case no period', title: 'Title is sentence case no period',
children: 'Pass only a string through the title prop', children: 'Pass only a string through the title prop',
}; };
export const Description = (args) => { export const Description = Template.bind({});
return <BannerBase {...args} />;
};
Description.args = { Description.args = {
title: 'Description vs children', title: 'Description vs children',
@ -119,29 +89,27 @@ Description.args = {
'Pass only a string through the description prop or you can use children if the contents require more', 'Pass only a string through the description prop or you can use children if the contents require more',
}; };
export const Children = (args) => { export const Children: StoryFn<typeof BannerBase> = (args) => {
return ( return (
<BannerBase {...args}> <BannerBase {...args}>
{`Description shouldn't repeat title. 1-3 lines. Can contain a `} Description shouldn't repeat title. 1-3 lines. Can contain a{' '}
<ButtonLink <ButtonLink
size={Size.inherit} size={ButtonLinkSize.Inherit}
href="https://metamask.io/" href="https://metamask.io/"
target="_blank" externalLink
> >
hyperlink. hyperlink
</ButtonLink> </ButtonLink>
.
</BannerBase> </BannerBase>
); );
}; };
export const ActionButton = (args) => { export const ActionButton = Template.bind({});
return <BannerBase {...args} />;
};
ActionButton.args = { ActionButton.args = {
title: 'Action prop demo', title: 'Action prop demo',
actionButtonLabel: 'Action', actionButtonLabel: 'Action',
actionButtonOnClick: () => console.log('ButtonLink actionButtonOnClick demo'),
actionButtonProps: { actionButtonProps: {
endIconName: IconName.Arrow2Right, endIconName: IconName.Arrow2Right,
}, },
@ -149,14 +117,9 @@ ActionButton.args = {
'Use actionButtonLabel for action text, actionButtonOnClick for the onClick handler, and actionButtonProps to pass any ButtonLink prop types such as iconName', 'Use actionButtonLabel for action text, actionButtonOnClick for the onClick handler, and actionButtonProps to pass any ButtonLink prop types such as iconName',
}; };
export const OnClose = (args) => { export const OnClose: StoryFn<typeof BannerBase> = (args) => {
const [isShown, setShown] = useState(true); const [isShown, setShown] = useState(true);
const bannerToggle = () => { const bannerToggle = () => setShown(!isShown);
if (isShown) {
console.log('close button clicked');
}
setShown(!isShown);
};
return ( return (
<> <>
{isShown ? ( {isShown ? (
@ -173,9 +136,7 @@ OnClose.args = {
children: 'Click the close button icon to hide this notifcation', children: 'Click the close button icon to hide this notifcation',
}; };
export const StartAccessory = (args) => { export const StartAccessory = Template.bind({});
return <BannerBase {...args} />;
};
StartAccessory.args = { StartAccessory.args = {
title: 'Start accessory demo', title: 'Start accessory demo',

View File

@ -1,101 +0,0 @@
/* eslint-disable jest/require-top-level-describe */
import { render } from '@testing-library/react';
import React from 'react';
import { renderWithUserEvent } from '../../../../test/lib/render-helpers';
import { Icon, IconName } from '..';
import { BannerBase } from './banner-base';
describe('BannerBase', () => {
it('should render bannerbase element correctly', () => {
const { getByTestId, container } = render(
<BannerBase data-testid="banner-base" title="Bannerbase test">
should render bannerbase element correctly
</BannerBase>,
);
expect(getByTestId('banner-base')).toHaveClass('mm-banner-base');
expect(container).toMatchSnapshot();
});
it('should render with added classname', () => {
const { getByTestId } = render(
<BannerBase
className="mm-banner-base--test"
data-testid="banner-base"
title="Bannerbase test"
>
should render bannerbase element correctly
</BannerBase>,
);
expect(getByTestId('banner-base')).toHaveClass('mm-banner-base--test');
});
it('should render bannerbase title', () => {
const { getByText } = render(<BannerBase title="Bannerbase title test" />);
expect(getByText('Bannerbase title test')).toHaveClass(
'mm-banner-base__title',
);
});
it('should render bannerbase description', () => {
const { getByText } = render(
<BannerBase description="Bannerbase description test" />,
);
expect(getByText('Bannerbase description test')).toBeDefined();
});
it('should render bannerbase children', () => {
const { getByText } = render(
<BannerBase>Bannerbase children test</BannerBase>,
);
expect(getByText('Bannerbase children test')).toBeDefined();
});
it('should render bannerbase action button', () => {
const { getByTestId } = render(
<BannerBase
title="Action prop demo"
actionButtonLabel="Action"
actionButtonProps={{
endIconName: IconName.Arrow2Right,
'data-testid': 'action',
className: 'mm-banner-base__action',
}}
actionButtonOnClick={() =>
console.log('ButtonLink actionButtonOnClick demo')
}
>
Use actionButtonLabel for action text, actionButtonOnClick for the
onClick handler, and actionButtonProps to pass any ButtonLink prop types
such as iconName
</BannerBase>,
);
expect(getByTestId('action')).toHaveClass('mm-banner-base__action');
});
it('should render bannerbase startAccessory', () => {
const { getByTestId } = render(
<BannerBase
startAccessory={
<Icon data-testid="start-accessory" name={IconName.AddSquare} />
}
/>,
);
expect(getByTestId('start-accessory')).toBeDefined();
});
it('should render and fire onClose event', async () => {
const onClose = jest.fn();
const { user, getByTestId } = renderWithUserEvent(
<BannerBase
title="onClose Test"
closeButtonProps={{ 'data-testid': 'close-button' }}
onClose={onClose}
/>,
);
await user.click(getByTestId('close-button'));
expect(onClose).toHaveBeenCalledTimes(1);
});
});

View File

@ -0,0 +1,129 @@
/* eslint-disable jest/require-top-level-describe */
import { render } from '@testing-library/react';
import React from 'react';
import { renderWithUserEvent } from '../../../../test/lib/render-helpers';
import { Icon, IconName } from '..';
import { BannerBase } from './banner-base';
describe('BannerBase', () => {
it('should render BannerBase element correctly', () => {
const { getByTestId, container } = render(
<BannerBase data-testid="banner-base" title="BannerBase test">
should render BannerBase element correctly
</BannerBase>,
);
expect(getByTestId('banner-base')).toHaveClass('mm-banner-base');
expect(container).toMatchSnapshot();
});
it('should render with added classname', () => {
const { getByTestId } = render(
<BannerBase
className="mm-banner-base--test"
data-testid="banner-base"
title="BannerBase test"
>
should render BannerBase element correctly
</BannerBase>,
);
expect(getByTestId('banner-base')).toHaveClass('mm-banner-base--test');
});
it('should render BannerBase title', () => {
const { getByText, getByTestId } = render(
<BannerBase
title="BannerBase title test"
titleProps={{ 'data-testid': 'title' }}
/>,
);
expect(getByText('BannerBase title test')).toBeDefined();
expect(getByTestId('title')).toBeDefined();
});
it('should render BannerBase description', () => {
const { getByText, getByTestId } = render(
<BannerBase
description="BannerBase description test"
descriptionProps={{ 'data-testid': 'description' }}
/>,
);
expect(getByText('BannerBase description test')).toBeDefined();
expect(getByTestId('description')).toBeDefined();
});
it('should render BannerBase children with props', () => {
const { getByText, getByTestId } = render(
<BannerBase
childrenWrapperProps={{
'data-testid': 'children-wrapper',
}}
>
BannerBase children
</BannerBase>,
);
expect(getByTestId('children-wrapper')).toBeDefined();
expect(getByText('BannerBase children')).toBeDefined();
});
it('should render BannerBase children without wrapper when not a string', () => {
const { getByText, queryByTestId } = render(
<BannerBase
childrenWrapperProps={{
'data-testid': 'children-wrapper',
}}
>
<div>BannerBase children</div>
</BannerBase>,
);
expect(queryByTestId('children-wrapper')).not.toBeInTheDocument();
expect(getByText('BannerBase children')).toBeDefined();
});
it('should render BannerBase action button', () => {
const fn = jest.fn();
const { getByTestId } = render(
<BannerBase
title="Action prop demo"
actionButtonLabel="Action"
actionButtonProps={{
endIconName: IconName.Arrow2Right,
'data-testid': 'action',
className: 'mm-banner-base__action',
}}
actionButtonOnClick={fn}
>
BannerBase children
</BannerBase>,
);
expect(getByTestId('action')).toHaveClass('mm-banner-base__action');
});
it('should render BannerBase startAccessory', () => {
const { getByTestId } = render(
<BannerBase
startAccessory={
<Icon data-testid="start-accessory" name={IconName.AddSquare} />
}
/>,
);
expect(getByTestId('start-accessory')).toBeDefined();
});
it('should render and fire onClose event', async () => {
const onClose = jest.fn();
const { user, getByTestId } = renderWithUserEvent(
<BannerBase
title="onClose Test"
closeButtonProps={{ 'data-testid': 'close-button' }}
onClose={onClose}
/>,
);
await user.click(getByTestId('close-button'));
expect(onClose).toHaveBeenCalledTimes(1);
});
});

View File

@ -0,0 +1,94 @@
import React from 'react';
import classnames from 'classnames';
import { useI18nContext } from '../../../hooks/useI18nContext';
import {
BackgroundColor,
BorderRadius,
Display,
TextVariant,
} from '../../../helpers/constants/design-system';
import {
ButtonLink,
IconName,
ButtonIcon,
Text,
Box,
ButtonLinkSize,
ButtonIconSize,
} from '..';
import { BoxProps, PolymorphicRef } from '../box';
import { BannerBaseComponent, BannerBaseProps } from './banner-base.types';
export const BannerBase: BannerBaseComponent = React.forwardRef(
<C extends React.ElementType = 'div'>(
{
className = '',
title,
titleProps,
description,
descriptionProps,
children,
childrenWrapperProps,
actionButtonLabel,
actionButtonOnClick,
actionButtonProps,
startAccessory,
onClose,
closeButtonProps,
...props
}: BannerBaseProps<C>,
ref?: PolymorphicRef<C>,
) => {
const t = useI18nContext();
return (
<Box
className={classnames('mm-banner-base', className)}
ref={ref}
display={Display.Flex}
gap={2}
backgroundColor={BackgroundColor.backgroundDefault}
borderRadius={BorderRadius.SM}
padding={3}
{...(props as BoxProps<C>)}
>
{startAccessory && <>{startAccessory}</>}
<div>
{title && (
<Text variant={TextVariant.bodyLgMedium} {...titleProps}>
{title}
</Text>
)}
{description && <Text {...descriptionProps}>{description}</Text>}
{children && typeof children === 'object' ? (
children
) : (
<Text {...childrenWrapperProps}>{children}</Text>
)}
{actionButtonLabel && (
<ButtonLink
size={ButtonLinkSize.Auto}
onClick={actionButtonOnClick}
{...actionButtonProps}
>
{actionButtonLabel}
</ButtonLink>
)}
</div>
{onClose && (
<ButtonIcon
className="mm-banner-base__close-button"
marginLeft="auto"
iconName={IconName.Close}
size={ButtonIconSize.Sm}
ariaLabel={t('close')}
onClick={onClose}
{...closeButtonProps}
/>
)}
</Box>
);
},
);

View File

@ -0,0 +1,81 @@
import React from 'react';
import type {
PolymorphicComponentPropWithRef,
StyleUtilityProps,
} from '../box';
import type { TextProps } from '../text';
import type { ButtonLinkProps } from '../button-link';
import type { ButtonIconProps } from '../button-icon';
/**
* Makes all props optional so that if a prop object is used not ALL required props need to be passed
* TODO: Move to appropriate place in app as this will be highly reusable
*/
type MakePropsOptional<T> = {
[K in keyof T]?: T[K];
};
export interface BannerBaseStyleUtilityProps extends StyleUtilityProps {
/**
* The title of the BannerBase
*/
title?: string;
/**
* Additional props to pass to the `Text` component used for the `title` text
*/
titleProps?: MakePropsOptional<TextProps<'p'>>;
/**
* The description is the content area below BannerBase title
*/
description?: string;
/**
* Additional props to pass to the `Text` component used for the `description` text
*/
descriptionProps?: MakePropsOptional<TextProps<'p'>>;
/**
* The children is an alternative to using the description prop for BannerBase content below the title
*/
children?: React.ReactNode;
/**
* Additional props to pass to the `Text` component used to wrap the `children` if `children` is type `string`
*/
childrenWrapperProps?: MakePropsOptional<TextProps<'p'>>;
/**
* Label for action button (ButtonLink) of the BannerBase below the children
*/
actionButtonLabel?: string;
/**
* Props for action button (ButtonLink) of the BannerBase below the children
*/
actionButtonProps?: MakePropsOptional<ButtonLinkProps<'button'>>;
/**
* The onClick handler for the action button (ButtonLink)
*/
actionButtonOnClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
/**
* The start(default left) content area of BannerBase
*/
startAccessory?: React.ReactNode;
/**
* The onClick handler for the close button
* When passed this will allow for the close button to show
*/
onClose?: () => void;
/**
* The props to pass to the close button
*/
closeButtonProps?: MakePropsOptional<ButtonIconProps<'button'>>;
/**
* An additional className to apply to the BannerBase
*/
className?: string;
}
export type BannerBaseProps<C extends React.ElementType> =
PolymorphicComponentPropWithRef<C, BannerBaseStyleUtilityProps>;
export type BannerBaseComponent = <C extends React.ElementType = 'div'>(
props: BannerBaseProps<C>,
) => React.ReactElement | null;

View File

@ -1 +0,0 @@
export { BannerBase } from './banner-base';

View File

@ -0,0 +1,2 @@
export { BannerBase } from './banner-base';
export type { BannerBaseProps } from './banner-base.types';

View File

@ -3,7 +3,7 @@
exports[`BannerTip should render BannerTip element correctly 1`] = ` exports[`BannerTip should render BannerTip element correctly 1`] = `
<div> <div>
<div <div
class="box mm-banner-base mm-banner-tip box--padding-3 box--display-flex box--gap-2 box--flex-direction-row box--background-color-background-default box--rounded-sm box--border-color-border-default box--border-style-solid box--border-width-1" class="mm-box mm-banner-base mm-banner-tip mm-box--padding-3 mm-box--display-flex mm-box--gap-2 mm-box--background-color-background-default mm-box--rounded-sm mm-box--border-color-border-default box--border-style-solid box--border-width-1"
data-testid="bannerTip" data-testid="bannerTip"
> >
<div <div
@ -16,12 +16,11 @@ exports[`BannerTip should render BannerTip element correctly 1`] = `
/> />
</div> </div>
<div> <div>
<h5 <p
class="mm-box mm-text mm-banner-base__title mm-text--body-lg-medium mm-box--color-text-default" class="mm-box mm-text mm-text--body-lg-medium mm-box--color-text-default"
data-testid="mm-banner-base-title"
> >
BannerTip test BannerTip test
</h5> </p>
<p <p
class="mm-box mm-text mm-text--body-md mm-box--color-text-default" class="mm-box mm-text mm-text--body-md mm-box--color-text-default"
> >

View File

@ -57,9 +57,7 @@ describe('BannerTip', () => {
it('should render BannerTip title', () => { it('should render BannerTip title', () => {
const { getByText } = render(<BannerTip title="BannerTip title test" />); const { getByText } = render(<BannerTip title="BannerTip title test" />);
expect(getByText('BannerTip title test')).toHaveClass( expect(getByText('BannerTip title test')).toBeDefined();
'mm-banner-base__title',
);
}); });
it('should render BannerTip description', () => { it('should render BannerTip description', () => {

View File

@ -410,6 +410,12 @@ export interface StyleUtilityProps {
* Accepts responsive props in the form of an array. * Accepts responsive props in the form of an array.
*/ */
color?: TextColor | TextColorArray | IconColor | IconColorArray; color?: TextColor | TextColorArray | IconColor | IconColorArray;
/**
* An optional data-testid to apply to the component.
* TypeScript is complaining about data- attributes which means we need to explicitly define this as a prop.
* TODO: Allow data- attributes.
*/
'data-testid'?: string;
} }
/** /**
* Box component props. * Box component props.

View File

@ -3,7 +3,7 @@
exports[`DetectedTokensBanner should render correctly 1`] = ` exports[`DetectedTokensBanner should render correctly 1`] = `
<div> <div>
<div <div
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-info multichain-detected-token-banner box--padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-primary-muted box--rounded-sm" class="mm-box mm-banner-base mm-banner-alert mm-banner-alert--severity-info multichain-detected-token-banner mm-box--padding-3 mm-box--padding-left-2 mm-box--display-flex mm-box--gap-2 mm-box--background-color-primary-muted mm-box--rounded-sm"
data-testid="detected-token-banner" data-testid="detected-token-banner"
> >
<span <span

View File

@ -315,7 +315,7 @@ exports[`ConfirmSendEther should render correct information for for confirm send
class="transaction-alerts" class="transaction-alerts"
> >
<div <div
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-warning box--padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-warning-muted box--rounded-sm" class="mm-box mm-banner-base mm-banner-alert mm-banner-alert--severity-warning mm-box--padding-3 mm-box--padding-left-2 mm-box--display-flex mm-box--gap-2 mm-box--background-color-warning-muted mm-box--rounded-sm"
> >
<span <span
class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-warning-default" class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-warning-default"

View File

@ -489,7 +489,7 @@ exports[`Confirm Transaction Base should match snapshot 1`] = `
</div> </div>
</div> </div>
<div <div
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-danger box--margin-right-4 box--margin-bottom-4 box--margin-left-4 box--padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-error-muted box--rounded-sm" class="mm-box mm-banner-base mm-banner-alert mm-banner-alert--severity-danger mm-box--margin-right-4 mm-box--margin-bottom-4 mm-box--margin-left-4 mm-box--padding-3 mm-box--padding-left-2 mm-box--display-flex mm-box--gap-2 mm-box--background-color-error-muted mm-box--rounded-sm"
> >
<span <span
class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-error-default" class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-error-default"

View File

@ -54,7 +54,7 @@ exports[`Reveal Seed Page should match snapshot 1`] = `
</span> </span>
</p> </p>
<div <div
class="box mm-banner-base mm-banner-alert mm-banner-alert--severity-danger box--padding-3 box--padding-left-2 box--display-flex box--gap-2 box--flex-direction-row box--background-color-error-muted box--rounded-sm" class="mm-box mm-banner-base mm-banner-alert mm-banner-alert--severity-danger mm-box--padding-3 mm-box--padding-left-2 mm-box--display-flex mm-box--gap-2 mm-box--background-color-error-muted mm-box--rounded-sm"
> >
<span <span
class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-error-default" class="mm-box mm-icon mm-icon--size-lg mm-box--display-inline-block mm-box--color-error-default"

View File

@ -1036,6 +1036,9 @@ export default function PrepareSwapPage({
? t('swapTokenVerifiedOn1SourceTitle') ? t('swapTokenVerifiedOn1SourceTitle')
: t('swapTokenAddedManuallyTitle') : t('swapTokenAddedManuallyTitle')
} }
titleProps={{
'data-testid': 'swaps-banner-title',
}}
width={BLOCK_SIZES.FULL} width={BLOCK_SIZES.FULL}
> >
<Box> <Box>

View File

@ -1073,6 +1073,7 @@ export default function ReviewQuote({ setReceiveToAmount }) {
{(showInsufficientWarning || tokenBalanceUnavailable) && ( {(showInsufficientWarning || tokenBalanceUnavailable) && (
<BannerAlert <BannerAlert
title={t('notEnoughBalance')} title={t('notEnoughBalance')}
titleProps={{ 'data-testid': 'swaps-banner-title' }}
severity={Severity.Info} severity={Severity.Info}
description={actionableBalanceErrorMessage} description={actionableBalanceErrorMessage}
descriptionProps={{ descriptionProps={{

View File

@ -59,6 +59,7 @@ export default function ViewQuotePriceDifference(props) {
<Box display={DISPLAY.FLEX} marginTop={2}> <Box display={DISPLAY.FLEX} marginTop={2}>
<BannerAlert <BannerAlert
title={priceDifferenceTitle} title={priceDifferenceTitle}
titleProps={{ 'data-testid': 'swaps-banner-title' }}
severity={severity} severity={severity}
width={BLOCK_SIZES.FULL} width={BLOCK_SIZES.FULL}
data-testid="mm-banner-alert" data-testid="mm-banner-alert"

View File

@ -163,7 +163,11 @@ export default function SwapsBannerAlert({ swapsErrorKey }) {
} }
return ( return (
<BannerAlert severity={severity} title={title}> <BannerAlert
severity={severity}
title={title}
titleProps={{ 'data-testid': 'swaps-banner-title' }}
>
{description} {description}
</BannerAlert> </BannerAlert>
); );

View File

@ -337,6 +337,7 @@ export default function TransactionSettings({
<BannerAlert <BannerAlert
severity={notificationSeverity} severity={notificationSeverity}
title={notificationTitle} title={notificationTitle}
titleProps={{ 'data-testid': 'swaps-banner-title' }}
> >
<Typography <Typography
variant={TypographyVariant.H6} variant={TypographyVariant.H6}