chore(trading): notification component redesign (#2845)
This commit is contained in:
parent
06ea3924fa
commit
710e2daa27
@ -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;
|
||||
|
@ -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"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user