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

fix/BannerTip to TS (#20538)

* BannerTip to TS

* removing actionButtonProps control from storybook file

* fixing console errors in storybook

* BannerTip docs fixes, prop fixes and test updates

---------

Co-authored-by: georgewrmarshall <george.marshall@consensys.net>
This commit is contained in:
Dhruv 2023-08-30 22:37:32 +05:30 committed by GitHub
parent 8b93092e0e
commit 9d59ec5f61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 147 additions and 160 deletions

View File

@ -12,14 +12,8 @@ import { BannerBase } from '..';
## Props ## Props
The `BannerTip` accepts all props below as well as all [Box](/docs/components-ui-box--default-story#props) component props
<ArgsTable of={BannerTip} /> <ArgsTable of={BannerTip} />
The `BannerTip` accepts all `BannerBase` component props below
<ArgsTable of={BannerBase} />
### Logo Type ### Logo Type
Use the `logoType` prop with the `BannerTipLogoType` enum from `../../component-library` to change the context of `BannerTip`. Use the `logoType` prop with the `BannerTipLogoType` enum from `../../component-library` to change the context of `BannerTip`.
@ -87,12 +81,15 @@ The `children` prop is an alternative to `description` for `BannerTip` when more
</Canvas> </Canvas>
```jsx ```jsx
import { Size } from '../../../helpers/constants/design-system'; import { BannerTip, ButtonLinkSize } from '../../component-library';
import { BannerTip } from '../../component-library';
<BannerTip> <BannerTip>
Description shouldn't repeat title. 1-3 lines. Can contain a Description shouldn't repeat title. 1-3 lines. Can contain a
<ButtonLink size={Size.auto} href="https://metamask.io/" target="_blank"> <ButtonLink
size={ButtonLinkSize.Auto}
href="https://metamask.io/"
externalLink
>
hyperlink. hyperlink.
</ButtonLink> </ButtonLink>
</BannerTip>; </BannerTip>;
@ -113,8 +110,7 @@ import { BannerTip, IconName } from '../../component-library';
title="Action prop demo" title="Action prop demo"
actionButtonLabel="Action" actionButtonLabel="Action"
actionButtonProps={{ actionButtonProps={{
icon: IconName.Arrow2Right, // TODO: change to iconName endIconName: IconName.Arrow2Right,
iconPositionRight: true,
}} }}
actionButtonOnClick={() => console.log('ButtonLink actionButtonOnClick demo')} actionButtonOnClick={() => console.log('ButtonLink actionButtonOnClick demo')}
> >

View File

@ -7,11 +7,11 @@ exports[`BannerTip should render BannerTip element correctly 1`] = `
data-testid="bannerTip" data-testid="bannerTip"
> >
<div <div
class="box box--display-flex box--flex-direction-row box--align-items-center" class="mm-box mm-box--display-flex mm-box--align-items-center"
> >
<img <img
alt="greeting" alt="greeting"
class="box mm-banner-tip--logo box--flex-direction-row" class="mm-box mm-banner-tip--logo"
src="images/fox-greeting.png" src="images/fox-greeting.png"
/> />
</div> </div>

View File

@ -1,4 +0,0 @@
export enum BannerTipLogoType {
Greeting = 'greeting',
Chat = 'chat',
}

View File

@ -1,76 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import {
AlignItems,
BorderColor,
DISPLAY,
} from '../../../helpers/constants/design-system';
import Box from '../../ui/box';
import { BannerBase } from '..';
import { BannerTipLogoType } from './banner-tip.constants';
export const BannerTip = ({
children,
className,
logoType = BannerTipLogoType.Greeting,
logoWrapperProps,
logoProps,
startAccessory,
...props
}) => {
return (
<BannerBase
startAccessory={
startAccessory || (
<Box
display={DISPLAY.FLEX}
alignItems={AlignItems.center}
{...logoWrapperProps}
>
<Box
as="img"
className="mm-banner-tip--logo"
src={`images/fox-${logoType}.png`}
alt={logoType}
{...logoProps}
/>
</Box>
)
}
borderColor={BorderColor.borderDefault}
className={classnames('mm-banner-tip', className)}
{...props}
>
{children}
</BannerBase>
);
};
BannerTip.propTypes = {
/**
* An additional className to apply to the Banner
*/
className: PropTypes.string,
/**
* Use the `logoType` prop with the `BannerTipLogoType` enum from `../../component-library` to change the logo image of `BannerTip`.
* Possible options: `BannerTipLogoType.Greeting`(Default), `BannerTipLogoType.Chat`,
*/
logoType: PropTypes.oneOf(Object.values(BannerTipLogoType)),
/**
* logoProps accepts all the props from Box
*/
logoProps: PropTypes.object,
/**
* logoWrapperProps accepts all the props from Box
*/
logoWrapperProps: PropTypes.object,
/**
* The start(defualt left) content area of BannerBase
*/
startAccessory: PropTypes.node,
/**
* BannerTip accepts all the props from BannerBase
*/
...BannerBase.propTypes,
};

View File

@ -1,32 +1,20 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Meta, StoryFn } from '@storybook/react';
import { import {
DISPLAY, Display,
FLEX_DIRECTION, FlexDirection,
Size,
} from '../../../helpers/constants/design-system'; } from '../../../helpers/constants/design-system';
import Box from '../../ui/box/box'; import {
import { ButtonLink, ButtonPrimary, Icon, IconName } from '..'; ButtonLink,
ButtonLinkSize,
ButtonPrimary,
Box,
Icon,
IconName,
} from '..';
import README from './README.mdx'; import README from './README.mdx';
import { BannerTip, BannerTipLogoType } from '.'; import { BannerTip, BannerTipLogoType } from '.';
const marginSizeControlOptions = [
undefined,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
'auto',
];
export default { export default {
title: 'Components/ComponentLibrary/BannerTip', title: 'Components/ComponentLibrary/BannerTip',
component: BannerTip, component: BannerTip,
@ -44,30 +32,12 @@ export default {
className: { className: {
control: 'text', control: 'text',
}, },
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 BannerTip>;
export const DefaultStory = (args) => { const Template: StoryFn<typeof BannerTip> = (args) => <BannerTip {...args} />;
export const DefaultStory: StoryFn<typeof BannerTip> = (args) => {
const onClose = () => console.log('BannerTip onClose trigger'); const onClose = () => console.log('BannerTip onClose trigger');
return <BannerTip {...args} onClose={onClose} />; return <BannerTip {...args} onClose={onClose} />;
}; };
@ -80,9 +50,9 @@ DefaultStory.args = {
DefaultStory.storyName = 'Default'; DefaultStory.storyName = 'Default';
export const LogoType = (args) => { export const LogoType: StoryFn<typeof BannerTip> = (args) => {
return ( return (
<Box display={DISPLAY.FLEX} flexDirection={FLEX_DIRECTION.COLUMN} gap={3}> <Box display={Display.Flex} flexDirection={FlexDirection.Column} gap={3}>
<BannerTip <BannerTip
{...args} {...args}
logoType={BannerTipLogoType.Greeting} logoType={BannerTipLogoType.Greeting}
@ -97,18 +67,14 @@ export const LogoType = (args) => {
); );
}; };
export const Title = (args) => { export const Title = Template.bind({});
return <BannerTip {...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 <BannerTip {...args} />;
};
Description.args = { Description.args = {
title: 'Description vs children', title: 'Description vs children',
@ -116,14 +82,14 @@ 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 BannerTip> = (args) => {
return ( return (
<BannerTip {...args}> <BannerTip {...args}>
Description shouldn&apos;t repeat title. 1-3 lines. Can contain a{' '} Description shouldn&apos;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>
@ -131,23 +97,20 @@ export const Children = (args) => {
); );
}; };
export const ActionButton = (args) => { export const ActionButton = Template.bind({});
return <BannerTip {...args} />;
};
ActionButton.args = { ActionButton.args = {
title: 'Action prop demo', title: 'Action prop demo',
actionButtonLabel: 'Action', actionButtonLabel: 'Action',
actionButtonOnClick: () => console.log('ButtonLink actionButtonOnClick demo'), actionButtonOnClick: () => console.log('ButtonLink actionButtonOnClick demo'),
actionButtonProps: { actionButtonProps: {
iconName: IconName.Arrow2Right, endIconName: IconName.Arrow2Right,
iconPositionRight: true,
}, },
children: children:
'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 BannerTip> = (args) => {
const [isShown, setShown] = useState(true); const [isShown, setShown] = useState(true);
const bannerTipToggle = () => { const bannerTipToggle = () => {
if (isShown) { if (isShown) {
@ -171,7 +134,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: StoryFn<typeof BannerTip> = (args) => {
return ( return (
<BannerTip <BannerTip
{...args} {...args}

View File

@ -22,13 +22,19 @@ describe('BannerTip', () => {
<> <>
<BannerTip <BannerTip
logoType={BannerTipLogoType.Greeting} logoType={BannerTipLogoType.Greeting}
logoProps={{ 'data-testid': 'banner-tip-greeting' }} logoProps={{
'data-testid': 'banner-tip-greeting',
className: 'custom-logo-class',
}}
> >
should render BannerTip element correctly should render BannerTip element correctly
</BannerTip> </BannerTip>
<BannerTip <BannerTip
logoType={BannerTipLogoType.Chat} logoType={BannerTipLogoType.Chat}
logoProps={{ 'data-testid': 'banner-tip-chat' }} logoProps={{
'data-testid': 'banner-tip-chat',
className: 'custom-logo-class',
}}
> >
should render BannerTip element correctly should render BannerTip element correctly
</BannerTip> </BannerTip>
@ -39,7 +45,9 @@ describe('BannerTip', () => {
expect(getByTestId('banner-tip-greeting')).toHaveClass( expect(getByTestId('banner-tip-greeting')).toHaveClass(
'mm-banner-tip--logo', 'mm-banner-tip--logo',
); );
expect(getByTestId('banner-tip-greeting')).toHaveClass('custom-logo-class');
expect(getByTestId('banner-tip-chat')).toHaveClass('mm-banner-tip--logo'); expect(getByTestId('banner-tip-chat')).toHaveClass('mm-banner-tip--logo');
expect(getByTestId('banner-tip-chat')).toHaveClass('custom-logo-class');
}); });
it('should render with added classname', () => { it('should render with added classname', () => {

View File

@ -0,0 +1,59 @@
import React from 'react';
import classnames from 'classnames';
import {
AlignItems,
BorderColor,
Display,
} from '../../../helpers/constants/design-system';
import { BannerBase, Box } from '..';
import { BoxProps, PolymorphicRef } from '../box';
import { BannerBaseProps } from '../banner-base';
import {
BannerTipComponent,
BannerTipLogoType,
BannerTipProps,
} from './banner-tip.types';
export const BannerTip: BannerTipComponent = React.forwardRef(
<C extends React.ElementType = 'div'>(
{
children,
className = '',
logoType = BannerTipLogoType.Greeting,
logoWrapperProps,
logoProps,
startAccessory,
...props
}: BannerTipProps<C>,
ref?: PolymorphicRef<C>,
) => (
<BannerBase
ref={ref}
startAccessory={
startAccessory || (
<Box
display={Display.Flex}
alignItems={AlignItems.center}
{...logoWrapperProps}
>
<Box
as="img"
src={`images/fox-${logoType}.png`}
alt={logoType}
{...(logoProps as BoxProps<C>)}
className={classnames(
'mm-banner-tip--logo',
logoProps?.className ?? '',
)}
/>
</Box>
)
}
borderColor={BorderColor.borderDefault}
className={classnames('mm-banner-tip', className)}
{...(props as BannerBaseProps<C>)}
>
{children}
</BannerBase>
),
);

View File

@ -0,0 +1,40 @@
import React from 'react';
import type { BannerBaseStyleUtilityProps } from '../banner-base/banner-base.types';
import type { PolymorphicComponentPropWithRef, BoxProps } from '../box';
export enum BannerTipLogoType {
Greeting = 'greeting',
Chat = 'chat',
}
export interface BannerTipStyleUtilityProps
extends BannerBaseStyleUtilityProps {
/**
* An additional className to apply to the Banner
*/
className?: string;
/**
* Use the `logoType` prop with the `BannerTipLogoType` enum from `../../component-library` to change the logo image of `BannerTip`.
* Possible options: `BannerTipLogoType.Greeting`(Default), `BannerTipLogoType.Chat`,
*/
logoType?: BannerTipLogoType;
/**
* logoProps accepts all the props from Box
*/
logoProps?: BoxProps<'span'>;
/**
* logoWrapperProps accepts all the props from Box
*/
logoWrapperProps?: BoxProps<'span'>;
/**
* The start(default left) content area of BannerBase
*/
startAccessory?: React.ReactNode;
}
export type BannerTipProps<C extends React.ElementType> =
PolymorphicComponentPropWithRef<C, BannerTipStyleUtilityProps>;
export type BannerTipComponent = <C extends React.ElementType = 'div'>(
props: BannerTipProps<C>,
) => React.ReactElement | null;

View File

@ -1,2 +0,0 @@
export { BannerTip } from './banner-tip';
export { BannerTipLogoType } from './banner-tip.constants';

View File

@ -0,0 +1,3 @@
export { BannerTip } from './banner-tip';
export { BannerTipLogoType } from './banner-tip.types';
export type { BannerTipProps } from './banner-tip.types';