chore(trading): notification component redesign (#2845)

This commit is contained in:
macqbat 2023-02-06 13:31:35 +01:00 committed by GitHub
parent 06ea3924fa
commit 710e2daa27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 100 additions and 38 deletions

View File

@ -15,7 +15,7 @@ export const Header = ({ title, children }: TradeMarketHeaderProps) => {
<div className="px-4 xl:px-0 pb-2 xl:pb-3">{title}</div>
<div
data-testid="header-summary"
className="flex flex-nowrap items-start xl:flex-1 w-full overflow-x-auto text-xs"
className="flex flex-nowrap items-end xl:flex-1 w-full overflow-x-auto text-xs"
>
{Children.map(children, (child, index) => {
if (!child) return null;

View File

@ -20,14 +20,19 @@ export const AssetProposalNotification = ({
const proposalLink = tokenLink(
TOKEN_PROPOSAL.replace(':id', proposal.id || '')
);
const message = (
<>
{t('Changes have been proposed for this asset.')}{' '}
<ExternalLink href={proposalLink}>{t('View proposal')}</ExternalLink>
</>
);
return (
<Notification
intent={Intent.Warning}
message={t('Changes have been proposed for this asset')}
message={message}
testId="asset-proposal-notification"
>
<ExternalLink href={proposalLink}>{t('View proposal')}</ExternalLink>
</Notification>
className="mb-2"
/>
);
}

View File

@ -20,14 +20,23 @@ export const MarketProposalNotification = ({
const proposalLink = tokenLink(
TOKEN_PROPOSAL.replace(':id', proposal.id || '')
);
const message = (
<div className="flex flex-col text-sm">
{t('Changes have been proposed for this market.')}{' '}
<ExternalLink href={proposalLink} className="w-fit">
{t('View proposal')}
</ExternalLink>
</div>
);
return (
<div className="border-l border-default pl-1 pr-1 pb-1 min-w-min whitespace-nowrap">
<Notification
intent={Intent.Warning}
message={t('Changes have been proposed for this market')}
message={message}
testId="market-proposal-notification"
>
<ExternalLink href={proposalLink}>{t('View proposal')}</ExternalLink>
</Notification>
className="px-2 py-1"
/>
</div>
);
}

View File

@ -1,29 +1,33 @@
import type { Meta, Story } from '@storybook/react';
import type { Meta } from '@storybook/react';
import { Intent } from '../../utils/intent';
import { ExternalLink, Link } from '../link';
import { Link } from '../link';
import { Notification } from './notification';
import type { ComponentStory } from '@storybook/react';
export default {
component: Notification,
title: 'Notification',
} as Meta;
const Template: Story = ({ intent, message, children }) => (
<div className="flex">
<Notification intent={intent} message={message}>
{children}
</Notification>
const Template: ComponentStory<typeof Notification> = (props) => (
<div className="max-w-[410px]">
<Notification {...props} />
</div>
);
const props = {
message: 'Exercitationem doloremque neque laborum incidunt consectetur amet',
children: (
<div className="flex space-x-1">
<Link>Action</Link>
<ExternalLink>External action</ExternalLink>
</div>
message: (
<>
This is a default message with an{' '}
<Link href="/?path=/story/notification--default">optional link</Link> that
returns onto multiple lines.
</>
),
title: 'Optional title',
buttonProps: {
text: 'Optional button',
action: () => alert('Optional button action'),
},
};
export const Default = Template.bind({});
@ -36,22 +40,50 @@ export const Primary = Template.bind({});
Primary.args = {
...props,
intent: Intent.Primary,
message: (
<>
This is a info message with an{' '}
<Link href="/?path=/story/notification--primary">optional link</Link> that
returns onto multiple lines.
</>
),
};
export const Success = Template.bind({});
Success.args = {
...props,
intent: Intent.Success,
message: (
<>
This is a success message with an{' '}
<Link href="/?path=/story/notification--success">optional link</Link> that
returns onto multiple lines.
</>
),
};
export const Warning = Template.bind({});
Warning.args = {
...props,
intent: Intent.Warning,
message: (
<>
This is a warning message with an{' '}
<Link href="/?path=/story/notification--warning">optional link</Link> that
returns onto multiple lines.
</>
),
};
export const Danger = Template.bind({});
Danger.args = {
...props,
intent: Intent.Danger,
message: (
<>
This is an error message with an{' '}
<Link href="/?path=/story/notification--danger">optional link</Link> that
returns onto multiple lines.
</>
),
};

View File

@ -4,12 +4,15 @@ import classNames from 'classnames';
import type { ReactNode } from 'react';
import { Intent } from '../../utils/intent';
import { Icon } from '../icon';
import { Button } from '../button';
type NotificationProps = {
intent: Intent;
message: string;
message: ReactNode | string;
title?: string;
buttonProps?: { text: string; action: () => void; className?: string };
testId?: string;
children?: ReactNode;
className?: string;
};
const getIcon = (intent: Intent): IconName => {
@ -26,8 +29,10 @@ const getIcon = (intent: Intent): IconName => {
export const Notification = ({
intent,
message,
title,
testId,
children,
buttonProps,
className,
}: NotificationProps) => {
return (
<div
@ -40,7 +45,8 @@ export const Notification = ({
'border-yellow-500': intent === Intent.Warning,
'border-vega-pink': intent === Intent.Danger,
},
'border rounded px-3 py-1 text-xs mb-1 mr-1'
'border rounded text-xs p-4 flex items-start gap-2.5 bg-neutral-100 dark:bg-neutral-900',
className
)}
>
<div
@ -52,18 +58,28 @@ export const Notification = ({
'text-yellow-600 dark:text-yellow-500': intent === Intent.Warning,
'text-vega-pink': intent === Intent.Danger,
},
'flex items-start'
'flex items-start mt-1'
)}
>
<Icon size={3} className="mr-1 mt-[2px]" name={getIcon(intent)} />
<span
title={message}
className="whitespace-nowrap overflow-hidden text-ellipsis"
>
{message}
</span>
<Icon size={4} name={getIcon(intent)} />
</div>
<div className="flex flex-col flex-grow items-start gap-1.5 text-base">
{title && (
<div className="whitespace-nowrap overflow-hidden text-ellipsis uppercase text-sm leading-6">
{title}
</div>
)}
<div>{message}</div>
{buttonProps && (
<Button
size="sm"
onClick={buttonProps.action}
className={classNames('mt-2 px-6 py-3', buttonProps.className)}
>
{buttonProps.text}
</Button>
)}
</div>
{children}
</div>
);
};