From 07abc53cce5d69466017fa01795f67f94d479fc2 Mon Sep 17 00:00:00 2001 From: Dhruv <79097544+dhruvv173@users.noreply.github.com> Date: Sat, 19 Aug 2023 03:22:40 +0530 Subject: [PATCH] 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 --- test/e2e/swaps/shared.js | 2 +- test/e2e/tests/security-provider.spec.js | 8 +- .../ledger-instruction-field.test.js.snap | 2 +- .../__snapshots__/eth-sign-modal.test.js.snap | 2 +- .../export-private-key-modal.test.js.snap | 2 +- ...ecurity-provider-banner-alert.test.js.snap | 9 +- .../blockaid-banner-alert.test.js.snap | 36 ++--- .../__snapshots__/banner-alert.test.js.snap | 9 +- .../banner-alert/banner-alert.test.js | 4 +- .../component-library/banner-base/README.mdx | 16 +- .../__snapshots__/banner-base.test.js.snap | 24 --- .../__snapshots__/banner-base.test.tsx.snap | 23 +++ .../banner-base/banner-base.js | 141 ------------------ ...ase.stories.js => banner-base.stories.tsx} | 107 +++++-------- .../banner-base/banner-base.test.js | 101 ------------- .../banner-base/banner-base.test.tsx | 129 ++++++++++++++++ .../banner-base/banner-base.tsx | 94 ++++++++++++ .../banner-base/banner-base.types.ts | 81 ++++++++++ .../component-library/banner-base/index.js | 1 - .../component-library/banner-base/index.ts | 2 + .../__snapshots__/banner-tip.test.js.snap | 9 +- .../banner-tip/banner-tip.test.js | 4 +- .../component-library/box/box.types.ts | 6 + .../detected-token-banner.test.js.snap | 2 +- .../confirm-send-ether.test.js.snap | 2 +- .../confirm-transaction-base.test.js.snap | 2 +- .../__snapshots__/reveal-seed.test.js.snap | 2 +- .../prepare-swap-page/prepare-swap-page.js | 3 + .../swaps/prepare-swap-page/review-quote.js | 1 + .../view-quote-price-difference.js | 1 + .../swaps-banner-alert/swaps-banner-alert.js | 6 +- .../transaction-settings.js | 1 + 32 files changed, 429 insertions(+), 403 deletions(-) delete mode 100644 ui/components/component-library/banner-base/__snapshots__/banner-base.test.js.snap create mode 100644 ui/components/component-library/banner-base/__snapshots__/banner-base.test.tsx.snap delete mode 100644 ui/components/component-library/banner-base/banner-base.js rename ui/components/component-library/banner-base/{banner-base.stories.js => banner-base.stories.tsx} (58%) delete mode 100644 ui/components/component-library/banner-base/banner-base.test.js create mode 100644 ui/components/component-library/banner-base/banner-base.test.tsx create mode 100644 ui/components/component-library/banner-base/banner-base.tsx create mode 100644 ui/components/component-library/banner-base/banner-base.types.ts delete mode 100644 ui/components/component-library/banner-base/index.js create mode 100644 ui/components/component-library/banner-base/index.ts diff --git a/test/e2e/swaps/shared.js b/test/e2e/swaps/shared.js index f8f149385be5..0d961a65443a 100644 --- a/test/e2e/swaps/shared.js +++ b/test/e2e/swaps/shared.js @@ -157,7 +157,7 @@ const checkActivityTransaction = async (driver, options) => { const checkNotification = async (driver, options) => { 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'); const boxContent = await driver.findElement( diff --git a/test/e2e/tests/security-provider.spec.js b/test/e2e/tests/security-provider.spec.js index bfbfc443fa13..9ffb5a3529b1 100644 --- a/test/e2e/tests/security-provider.spec.js +++ b/test/e2e/tests/security-provider.spec.js @@ -106,7 +106,7 @@ describe('Transaction security provider', function () { ); const warningHeader = await driver.isElementPresent({ text: 'This could be a scam', - tag: 'h5', + tag: 'p', }); assert.equal(warningHeader, true); }, @@ -146,7 +146,7 @@ describe('Transaction security provider', function () { ); const warningHeader = await driver.isElementPresent({ text: 'Request may not be safe', - tag: 'h5', + tag: 'p', }); assert.equal(warningHeader, true); }, @@ -186,7 +186,7 @@ describe('Transaction security provider', function () { ); const warningHeader = await driver.isElementPresent({ text: 'Request may not be safe', - tag: 'h5', + tag: 'p', }); assert.equal(warningHeader, false); }, @@ -226,7 +226,7 @@ describe('Transaction security provider', function () { ); const warningHeader = await driver.isElementPresent({ text: 'Request not verified', - tag: 'h5', + tag: 'p', }); assert.equal(warningHeader, true); }, diff --git a/ui/components/app/ledger-instruction-field/__snapshots__/ledger-instruction-field.test.js.snap b/ui/components/app/ledger-instruction-field/__snapshots__/ledger-instruction-field.test.js.snap index b1dad7808a88..046b5f148a47 100644 --- a/ui/components/app/ledger-instruction-field/__snapshots__/ledger-instruction-field.test.js.snap +++ b/ui/components/app/ledger-instruction-field/__snapshots__/ledger-instruction-field.test.js.snap @@ -7,7 +7,7 @@ exports[`LedgerInstructionField Component rendering should render properly with class="confirm-detail-row" >

-
Malicious third party detected -
+

diff --git a/ui/components/app/security-provider-banner-alert/blockaid-banner-alert/__snapshots__/blockaid-banner-alert.test.js.snap b/ui/components/app/security-provider-banner-alert/blockaid-banner-alert/__snapshots__/blockaid-banner-alert.test.js.snap index fb17c6870df8..d6c4f3e5d7e2 100644 --- a/ui/components/app/security-provider-banner-alert/blockaid-banner-alert/__snapshots__/blockaid-banner-alert.test.js.snap +++ b/ui/components/app/security-provider-banner-alert/blockaid-banner-alert/__snapshots__/blockaid-banner-alert.test.js.snap @@ -2,19 +2,18 @@ exports[`Blockaid Banner Alert should render 'danger' UI when securityAlertResponse.result_type is 'Malicious 1`] = `

-
This is a deceptive request -
+

@@ -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`] = `

-
This is a deceptive request -
+

@@ -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`] = `

-
This is a deceptive request -
+

@@ -119,19 +116,18 @@ exports[`Blockaid Banner Alert should render 'warning' UI when securityAlertResp exports[`Blockaid Banner Alert should render details when provided 1`] = `

-
This is a deceptive request -
+

diff --git a/ui/components/component-library/banner-alert/__snapshots__/banner-alert.test.js.snap b/ui/components/component-library/banner-alert/__snapshots__/banner-alert.test.js.snap index 28da219ef795..2224365dfb01 100644 --- a/ui/components/component-library/banner-alert/__snapshots__/banner-alert.test.js.snap +++ b/ui/components/component-library/banner-alert/__snapshots__/banner-alert.test.js.snap @@ -3,7 +3,7 @@ exports[`BannerAlert should render BannerAlert element correctly 1`] = `

-
BannerAlert test -
+

diff --git a/ui/components/component-library/banner-alert/banner-alert.test.js b/ui/components/component-library/banner-alert/banner-alert.test.js index 5c612a0c3b5b..f131e9872a1a 100644 --- a/ui/components/component-library/banner-alert/banner-alert.test.js +++ b/ui/components/component-library/banner-alert/banner-alert.test.js @@ -75,9 +75,7 @@ describe('BannerAlert', () => { const { getByText } = render( , ); - expect(getByText('BannerAlert title test')).toHaveClass( - 'mm-banner-base__title', - ); + expect(getByText('BannerAlert title test')).toBeDefined(); }); it('should render BannerAlert description', () => { diff --git a/ui/components/component-library/banner-base/README.mdx b/ui/components/component-library/banner-base/README.mdx index a6711ee9737f..ca427b96275c 100644 --- a/ui/components/component-library/banner-base/README.mdx +++ b/ui/components/component-library/banner-base/README.mdx @@ -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. - + ## Props -The `BannerBase` accepts all props below as well as all [Box](/docs/components-ui-box--default-story#props) component props - ### 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. - + @@ -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. - + @@ -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. - + @@ -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 - + @@ -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` - + @@ -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 - + diff --git a/ui/components/component-library/banner-base/__snapshots__/banner-base.test.js.snap b/ui/components/component-library/banner-base/__snapshots__/banner-base.test.js.snap deleted file mode 100644 index d155bd2c9fad..000000000000 --- a/ui/components/component-library/banner-base/__snapshots__/banner-base.test.js.snap +++ /dev/null @@ -1,24 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`BannerBase should render bannerbase element correctly 1`] = ` -

-
-
-
- Bannerbase test -
-

- should render bannerbase element correctly -

-
-
-
-`; diff --git a/ui/components/component-library/banner-base/__snapshots__/banner-base.test.tsx.snap b/ui/components/component-library/banner-base/__snapshots__/banner-base.test.tsx.snap new file mode 100644 index 000000000000..b7186d2acafa --- /dev/null +++ b/ui/components/component-library/banner-base/__snapshots__/banner-base.test.tsx.snap @@ -0,0 +1,23 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`BannerBase should render BannerBase element correctly 1`] = ` +
+
+
+

+ BannerBase test +

+

+ should render BannerBase element correctly +

+
+
+
+`; diff --git a/ui/components/component-library/banner-base/banner-base.js b/ui/components/component-library/banner-base/banner-base.js deleted file mode 100644 index fc861c1e5f9f..000000000000 --- a/ui/components/component-library/banner-base/banner-base.js +++ /dev/null @@ -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 ( - - {startAccessory && <>{startAccessory}} - -
- {title && ( - - {title} - - )} - {description && {description}} - {children && typeof children === 'object' ? ( - children - ) : ( - {children} - )} - {actionButtonLabel && ( - - {actionButtonLabel} - - )} -
- {onClose && ( - - )} -
- ); -}; - -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, -}; diff --git a/ui/components/component-library/banner-base/banner-base.stories.js b/ui/components/component-library/banner-base/banner-base.stories.tsx similarity index 58% rename from ui/components/component-library/banner-base/banner-base.stories.js rename to ui/components/component-library/banner-base/banner-base.stories.tsx index a964c80e802d..f5df17ca395d 100644 --- a/ui/components/component-library/banner-base/banner-base.stories.js +++ b/ui/components/component-library/banner-base/banner-base.stories.tsx @@ -1,28 +1,17 @@ import React from 'react'; +import { Meta, StoryFn } from '@storybook/react'; import { useState } from '@storybook/addons'; -import { Size } from '../../../helpers/constants/design-system'; -import { ButtonLink, ButtonPrimary, Icon, IconName, IconSize } from '..'; +import { + ButtonLink, + ButtonLinkSize, + ButtonPrimary, + Icon, + IconName, + IconSize, +} from '..'; import { BannerBase } from './banner-base'; 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/BannerBase', component: BannerBase, @@ -39,20 +28,26 @@ export default { title: { control: 'text', }, + titleProps: { + control: 'object', + }, description: { control: 'text', }, + descriptionProps: { + control: 'object', + }, children: { control: 'text', }, - action: { - control: 'func', + childrenProps: { + control: 'object', }, actionButtonLabel: { control: 'text', }, actionButtonOnClick: { - control: 'func', + action: 'actionButtonOnClick', }, actionButtonProps: { control: 'object', @@ -63,33 +58,12 @@ export default { 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; -export const DefaultStory = (args) => { - const onClose = () => console.log('BannerBase onClose trigger'); - return ; -}; +const Template: StoryFn = (args) => ; + +export const DefaultStory = Template.bind({}); DefaultStory.args = { title: 'Title is sentence case no period', @@ -100,18 +74,14 @@ DefaultStory.args = { DefaultStory.storyName = 'Default'; -export const Title = (args) => { - return ; -}; +export const Title = Template.bind({}); Title.args = { title: 'Title is sentence case no period', children: 'Pass only a string through the title prop', }; -export const Description = (args) => { - return ; -}; +export const Description = Template.bind({}); Description.args = { 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', }; -export const Children = (args) => { +export const Children: StoryFn = (args) => { return ( - {`Description shouldn't repeat title. 1-3 lines. Can contain a `} + Description shouldn't repeat title. 1-3 lines. Can contain a{' '} - hyperlink. + hyperlink + . ); }; -export const ActionButton = (args) => { - return ; -}; +export const ActionButton = Template.bind({}); ActionButton.args = { title: 'Action prop demo', actionButtonLabel: 'Action', - actionButtonOnClick: () => console.log('ButtonLink actionButtonOnClick demo'), actionButtonProps: { 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', }; -export const OnClose = (args) => { +export const OnClose: StoryFn = (args) => { const [isShown, setShown] = useState(true); - const bannerToggle = () => { - if (isShown) { - console.log('close button clicked'); - } - setShown(!isShown); - }; + const bannerToggle = () => setShown(!isShown); return ( <> {isShown ? ( @@ -173,9 +136,7 @@ OnClose.args = { children: 'Click the close button icon to hide this notifcation', }; -export const StartAccessory = (args) => { - return ; -}; +export const StartAccessory = Template.bind({}); StartAccessory.args = { title: 'Start accessory demo', diff --git a/ui/components/component-library/banner-base/banner-base.test.js b/ui/components/component-library/banner-base/banner-base.test.js deleted file mode 100644 index 17f4643b31fd..000000000000 --- a/ui/components/component-library/banner-base/banner-base.test.js +++ /dev/null @@ -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( - - should render bannerbase element correctly - , - ); - expect(getByTestId('banner-base')).toHaveClass('mm-banner-base'); - expect(container).toMatchSnapshot(); - }); - - it('should render with added classname', () => { - const { getByTestId } = render( - - should render bannerbase element correctly - , - ); - expect(getByTestId('banner-base')).toHaveClass('mm-banner-base--test'); - }); - - it('should render bannerbase title', () => { - const { getByText } = render(); - expect(getByText('Bannerbase title test')).toHaveClass( - 'mm-banner-base__title', - ); - }); - - it('should render bannerbase description', () => { - const { getByText } = render( - , - ); - expect(getByText('Bannerbase description test')).toBeDefined(); - }); - - it('should render bannerbase children', () => { - const { getByText } = render( - Bannerbase children test, - ); - expect(getByText('Bannerbase children test')).toBeDefined(); - }); - - it('should render bannerbase action button', () => { - const { getByTestId } = render( - - 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 - , - ); - expect(getByTestId('action')).toHaveClass('mm-banner-base__action'); - }); - - it('should render bannerbase startAccessory', () => { - const { getByTestId } = render( - - } - />, - ); - - expect(getByTestId('start-accessory')).toBeDefined(); - }); - - it('should render and fire onClose event', async () => { - const onClose = jest.fn(); - const { user, getByTestId } = renderWithUserEvent( - , - ); - await user.click(getByTestId('close-button')); - expect(onClose).toHaveBeenCalledTimes(1); - }); -}); diff --git a/ui/components/component-library/banner-base/banner-base.test.tsx b/ui/components/component-library/banner-base/banner-base.test.tsx new file mode 100644 index 000000000000..09eaf3943c30 --- /dev/null +++ b/ui/components/component-library/banner-base/banner-base.test.tsx @@ -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( + + should render BannerBase element correctly + , + ); + expect(getByTestId('banner-base')).toHaveClass('mm-banner-base'); + expect(container).toMatchSnapshot(); + }); + + it('should render with added classname', () => { + const { getByTestId } = render( + + should render BannerBase element correctly + , + ); + expect(getByTestId('banner-base')).toHaveClass('mm-banner-base--test'); + }); + + it('should render BannerBase title', () => { + const { getByText, getByTestId } = render( + , + ); + + expect(getByText('BannerBase title test')).toBeDefined(); + expect(getByTestId('title')).toBeDefined(); + }); + + it('should render BannerBase description', () => { + const { getByText, getByTestId } = render( + , + ); + expect(getByText('BannerBase description test')).toBeDefined(); + expect(getByTestId('description')).toBeDefined(); + }); + + it('should render BannerBase children with props', () => { + const { getByText, getByTestId } = render( + + BannerBase children + , + ); + 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 children
+
, + ); + + 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 children + , + ); + expect(getByTestId('action')).toHaveClass('mm-banner-base__action'); + }); + + it('should render BannerBase startAccessory', () => { + const { getByTestId } = render( + + } + />, + ); + + expect(getByTestId('start-accessory')).toBeDefined(); + }); + + it('should render and fire onClose event', async () => { + const onClose = jest.fn(); + const { user, getByTestId } = renderWithUserEvent( + , + ); + await user.click(getByTestId('close-button')); + expect(onClose).toHaveBeenCalledTimes(1); + }); +}); diff --git a/ui/components/component-library/banner-base/banner-base.tsx b/ui/components/component-library/banner-base/banner-base.tsx new file mode 100644 index 000000000000..9947d7a6e001 --- /dev/null +++ b/ui/components/component-library/banner-base/banner-base.tsx @@ -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( + ( + { + className = '', + title, + titleProps, + description, + descriptionProps, + children, + childrenWrapperProps, + actionButtonLabel, + actionButtonOnClick, + actionButtonProps, + startAccessory, + onClose, + closeButtonProps, + ...props + }: BannerBaseProps, + ref?: PolymorphicRef, + ) => { + const t = useI18nContext(); + return ( + )} + > + {startAccessory && <>{startAccessory}} + +
+ {title && ( + + {title} + + )} + {description && {description}} + {children && typeof children === 'object' ? ( + children + ) : ( + {children} + )} + {actionButtonLabel && ( + + {actionButtonLabel} + + )} +
+ {onClose && ( + + )} +
+ ); + }, +); diff --git a/ui/components/component-library/banner-base/banner-base.types.ts b/ui/components/component-library/banner-base/banner-base.types.ts new file mode 100644 index 000000000000..8ed90d71f77c --- /dev/null +++ b/ui/components/component-library/banner-base/banner-base.types.ts @@ -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 = { + [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>; + /** + * 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>; + /** + * 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>; + /** + * 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>; + /** + * The onClick handler for the action button (ButtonLink) + */ + actionButtonOnClick?: (event: React.MouseEvent) => 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>; + /** + * An additional className to apply to the BannerBase + */ + className?: string; +} + +export type BannerBaseProps = + PolymorphicComponentPropWithRef; + +export type BannerBaseComponent = ( + props: BannerBaseProps, +) => React.ReactElement | null; diff --git a/ui/components/component-library/banner-base/index.js b/ui/components/component-library/banner-base/index.js deleted file mode 100644 index e286559ae82b..000000000000 --- a/ui/components/component-library/banner-base/index.js +++ /dev/null @@ -1 +0,0 @@ -export { BannerBase } from './banner-base'; diff --git a/ui/components/component-library/banner-base/index.ts b/ui/components/component-library/banner-base/index.ts new file mode 100644 index 000000000000..4989b34ea6cc --- /dev/null +++ b/ui/components/component-library/banner-base/index.ts @@ -0,0 +1,2 @@ +export { BannerBase } from './banner-base'; +export type { BannerBaseProps } from './banner-base.types'; diff --git a/ui/components/component-library/banner-tip/__snapshots__/banner-tip.test.js.snap b/ui/components/component-library/banner-tip/__snapshots__/banner-tip.test.js.snap index 8658c76c7a12..b44382369021 100644 --- a/ui/components/component-library/banner-tip/__snapshots__/banner-tip.test.js.snap +++ b/ui/components/component-library/banner-tip/__snapshots__/banner-tip.test.js.snap @@ -3,7 +3,7 @@ exports[`BannerTip should render BannerTip element correctly 1`] = `
-
BannerTip test -
+

diff --git a/ui/components/component-library/banner-tip/banner-tip.test.js b/ui/components/component-library/banner-tip/banner-tip.test.js index 772acf722b5a..edfad87a11e7 100644 --- a/ui/components/component-library/banner-tip/banner-tip.test.js +++ b/ui/components/component-library/banner-tip/banner-tip.test.js @@ -57,9 +57,7 @@ describe('BannerTip', () => { it('should render BannerTip title', () => { const { getByText } = render(); - expect(getByText('BannerTip title test')).toHaveClass( - 'mm-banner-base__title', - ); + expect(getByText('BannerTip title test')).toBeDefined(); }); it('should render BannerTip description', () => { diff --git a/ui/components/component-library/box/box.types.ts b/ui/components/component-library/box/box.types.ts index badb3f5ce127..49a2c894e761 100644 --- a/ui/components/component-library/box/box.types.ts +++ b/ui/components/component-library/box/box.types.ts @@ -410,6 +410,12 @@ export interface StyleUtilityProps { * Accepts responsive props in the form of an array. */ 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. diff --git a/ui/components/multichain/detected-token-banner/__snapshots__/detected-token-banner.test.js.snap b/ui/components/multichain/detected-token-banner/__snapshots__/detected-token-banner.test.js.snap index d07c02c5e2bb..014cd0d77b3c 100644 --- a/ui/components/multichain/detected-token-banner/__snapshots__/detected-token-banner.test.js.snap +++ b/ui/components/multichain/detected-token-banner/__snapshots__/detected-token-banner.test.js.snap @@ -3,7 +3,7 @@ exports[`DetectedTokensBanner should render correctly 1`] = `

diff --git a/ui/pages/swaps/prepare-swap-page/review-quote.js b/ui/pages/swaps/prepare-swap-page/review-quote.js index 5c815f2a51d6..9bca5d8c63ca 100644 --- a/ui/pages/swaps/prepare-swap-page/review-quote.js +++ b/ui/pages/swaps/prepare-swap-page/review-quote.js @@ -1073,6 +1073,7 @@ export default function ReviewQuote({ setReceiveToAmount }) { {(showInsufficientWarning || tokenBalanceUnavailable) && ( + {description} ); diff --git a/ui/pages/swaps/transaction-settings/transaction-settings.js b/ui/pages/swaps/transaction-settings/transaction-settings.js index a0d213eaceac..51291ec454a1 100644 --- a/ui/pages/swaps/transaction-settings/transaction-settings.js +++ b/ui/pages/swaps/transaction-settings/transaction-settings.js @@ -337,6 +337,7 @@ export default function TransactionSettings({