Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c93793a93 | ||
|
|
e265a14e69 | ||
|
|
3189fc1b37 | ||
|
|
9715b681ea | ||
|
|
c7c42045a5 | ||
|
|
fbecf0bffd | ||
|
|
0413ef13f3 | ||
|
|
d28d238574 | ||
|
|
937f4beeb0 |
@@ -1,5 +1,4 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { formatLabel } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
OrderRejectionReason,
|
||||
OrderStatus,
|
||||
@@ -7,6 +6,7 @@ import {
|
||||
Side,
|
||||
} from '@vegaprotocol/types';
|
||||
import { VegaTxStatus } from '@vegaprotocol/wallet';
|
||||
import startCase from 'lodash/startCase';
|
||||
import { generateOrder } from '../mocks/generate-orders';
|
||||
import type { OrderFeedbackProps } from './order-feedback';
|
||||
import { OrderFeedback } from './order-feedback';
|
||||
@@ -45,7 +45,7 @@ describe('OrderFeedback', () => {
|
||||
const order = generateOrder(orderFields);
|
||||
render(<OrderFeedback {...props} order={order} />);
|
||||
expect(screen.getByTestId('error-reason')).toHaveTextContent(
|
||||
`Reason: ${formatLabel(orderFields.rejectionReason)}`
|
||||
`Reason: ${startCase(orderFields.rejectionReason)}`
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import type { OrderEvent_busEvents_event_Order } from '../../order-hooks/__generated__';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
formatLabel,
|
||||
t,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
|
||||
import { OrderStatus, OrderType, Side } from '@vegaprotocol/types';
|
||||
import type { VegaTxState } from '@vegaprotocol/wallet';
|
||||
import startCase from 'lodash/startCase';
|
||||
|
||||
export interface OrderFeedbackProps {
|
||||
transaction: VegaTxState;
|
||||
@@ -23,7 +20,7 @@ export const OrderFeedback = ({ transaction, order }: OrderFeedbackProps) => {
|
||||
return (
|
||||
<p data-testid="error-reason">
|
||||
{order.rejectionReason &&
|
||||
t(`Reason: ${formatLabel(order.rejectionReason)}`)}
|
||||
t(`Reason: ${startCase(order.rejectionReason)}`)}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
@@ -44,7 +41,7 @@ export const OrderFeedback = ({ transaction, order }: OrderFeedbackProps) => {
|
||||
<div>
|
||||
<p className={labelClass}>{t('Transaction')}</p>
|
||||
<a
|
||||
className="underline break-words"
|
||||
className="underline break-all"
|
||||
data-testid="tx-block-explorer"
|
||||
href={`${VEGA_EXPLORER_URL}/txs/0x${transaction.txHash}`}
|
||||
target="_blank"
|
||||
@@ -102,7 +99,7 @@ export const OrderFeedback = ({ transaction, order }: OrderFeedbackProps) => {
|
||||
<div>
|
||||
<p className={labelClass}>{t('Transaction')}</p>
|
||||
<a
|
||||
className="underline break-words"
|
||||
className="underline break-all"
|
||||
data-testid="tx-block-explorer"
|
||||
href={`${VEGA_EXPLORER_URL}/txs/0x${transaction.txHash}`}
|
||||
target="_blank"
|
||||
|
||||
@@ -23,13 +23,14 @@ export * from './price-change';
|
||||
export * from './radio-group';
|
||||
export * from './resizable-panel';
|
||||
export * from './select';
|
||||
export * from './slider';
|
||||
export * from './sparkline';
|
||||
export * from './splash';
|
||||
export * from './syntax-highlighter';
|
||||
export * from './tabs';
|
||||
export * from './text-area';
|
||||
export * from './theme-switcher';
|
||||
export * from './toast';
|
||||
export * from './toggle';
|
||||
export * from './tooltip';
|
||||
export * from './vega-logo';
|
||||
export * from './slider';
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './toast';
|
||||
@@ -0,0 +1,62 @@
|
||||
import React, { useState } from 'react';
|
||||
import type { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
|
||||
import { Toast } from './toast';
|
||||
import { Button } from '../button';
|
||||
import { Intent } from '../../utils/intent';
|
||||
|
||||
export default {
|
||||
title: 'Toast',
|
||||
component: Toast,
|
||||
} as ComponentMeta<typeof Toast>;
|
||||
|
||||
const Template: ComponentStory<typeof Toast> = (args) => {
|
||||
const [open, setOpen] = useState(args.open);
|
||||
return (
|
||||
<div>
|
||||
<Button onClick={() => setOpen(true)}>Open Toast</Button>
|
||||
<Toast {...args} open={open} onOpenChange={setOpen}>
|
||||
{args.children}
|
||||
</Toast>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
open: false,
|
||||
title: 'No intent supplied',
|
||||
children: <p>Some content</p>,
|
||||
};
|
||||
|
||||
export const Primary = Template.bind({});
|
||||
Primary.args = {
|
||||
open: false,
|
||||
title: 'Intent: Primary',
|
||||
children: <p>Some content</p>,
|
||||
intent: Intent.Primary,
|
||||
};
|
||||
|
||||
export const Danger = Template.bind({});
|
||||
Danger.args = {
|
||||
open: false,
|
||||
title: 'Intent: Danger',
|
||||
children: <p>Some content</p>,
|
||||
intent: Intent.Danger,
|
||||
};
|
||||
|
||||
export const Warning = Template.bind({});
|
||||
Warning.args = {
|
||||
open: false,
|
||||
title: 'Intent: Warning',
|
||||
children: <p>Some content</p>,
|
||||
intent: Intent.Warning,
|
||||
};
|
||||
|
||||
export const Success = Template.bind({});
|
||||
Success.args = {
|
||||
open: false,
|
||||
title: 'Intent: Success',
|
||||
children: <p>Some content</p>,
|
||||
intent: Intent.Success,
|
||||
};
|
||||
@@ -0,0 +1,74 @@
|
||||
import * as ToastPrimitive from '@radix-ui/react-toast';
|
||||
import type { Intent } from '@vegaprotocol/ui-toolkit';
|
||||
import { getIntentBorder, getIntentShadow } from '@vegaprotocol/ui-toolkit';
|
||||
import classNames from 'classnames';
|
||||
import type { ReactNode } from 'react';
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
export interface ToastProps extends ToastPrimitive.ToastProps {
|
||||
children?: ReactNode;
|
||||
actions?: ReactNode;
|
||||
altText?: string;
|
||||
icon?: ReactNode;
|
||||
intent: Intent;
|
||||
}
|
||||
|
||||
export const Toast = ({
|
||||
title,
|
||||
actions,
|
||||
intent,
|
||||
children,
|
||||
icon,
|
||||
altText = 'toast',
|
||||
...props
|
||||
}: ToastProps) => {
|
||||
const contentClasses = classNames(
|
||||
'relative bg-white dark:bg-black px-28 py-24 max-w-[390px]',
|
||||
// // Need to apply background and text colors again as content is rendered in a portal
|
||||
// 'dark:bg-black dark:text-white-95 bg-white text-black-95',
|
||||
getIntentShadow(intent),
|
||||
getIntentBorder(intent)
|
||||
);
|
||||
const timerRef = useRef(0);
|
||||
|
||||
useEffect(() => {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
return () => clearTimeout(timerRef.current);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ToastPrimitive.ToastProvider swipeDirection="right">
|
||||
<ToastPrimitive.Root duration={100000} className="grid" {...props}>
|
||||
<ToastPrimitive.Description className={contentClasses}>
|
||||
<div className="flex gap-12 max-w-full">
|
||||
{icon && <div className="pt-8 fill-current">{icon}</div>}
|
||||
<div data-testid="toast-content" className="flex-1">
|
||||
{title && (
|
||||
<ToastPrimitive.Title
|
||||
className={`text-ui font-bold text-black-95 dark:text-white-95 mt-0 mb-2`}
|
||||
data-testid="toast-title"
|
||||
>
|
||||
{title}
|
||||
</ToastPrimitive.Title>
|
||||
)}
|
||||
<div className="text-black-60 dark:text-white-60">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
<ToastPrimitive.Close
|
||||
className="p-2 absolute top-8 right-8 leading-[0] focus:outline-none focus-visible:outline-none focus-visible:border focus-visible:border-vega-yellow focus-visible:top-[7px] focus-visible:right-[7px]"
|
||||
data-testid="toast-close"
|
||||
aria-label="Close"
|
||||
>
|
||||
<span aria-hidden>×</span>
|
||||
</ToastPrimitive.Close>
|
||||
</ToastPrimitive.Description>
|
||||
{actions && (
|
||||
<ToastPrimitive.Action asChild altText={altText}>
|
||||
{actions}
|
||||
</ToastPrimitive.Action>
|
||||
)}
|
||||
</ToastPrimitive.Root>
|
||||
<ToastPrimitive.ToastViewport className="z-20 fixed top-[3rem] right-16 flex flex-col p-25 gap-10 m-0" />
|
||||
</ToastPrimitive.ToastProvider>
|
||||
);
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Dialog, Icon, Intent, Loader } from '@vegaprotocol/ui-toolkit';
|
||||
import { formatLabel, t } from '@vegaprotocol/react-helpers';
|
||||
import { Toast, Icon, Intent, Loader } from '@vegaprotocol/ui-toolkit';
|
||||
import type { ReactNode } from 'react';
|
||||
import type { VegaTxState } from '../use-vega-transaction';
|
||||
import { VegaTxStatus } from '../use-vega-transaction';
|
||||
@@ -37,15 +37,15 @@ export const VegaTransactionDialog = ({
|
||||
<VegaDialog transaction={transaction} />
|
||||
);
|
||||
return (
|
||||
<Dialog
|
||||
<Toast
|
||||
open={isOpen}
|
||||
onChange={onChange}
|
||||
onOpenChange={onChange}
|
||||
intent={computedIntent}
|
||||
title={computedTitle}
|
||||
icon={computedIcon}
|
||||
>
|
||||
{content}
|
||||
</Dialog>
|
||||
</Toast>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -72,7 +72,7 @@ export const VegaDialog = ({ transaction }: VegaDialogProps) => {
|
||||
if (transaction.status === VegaTxStatus.Error) {
|
||||
return (
|
||||
<div data-testid={transaction.status}>
|
||||
<p>{transaction.error}</p>
|
||||
<p>{transaction.error && formatLabel(transaction.error)}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
"@radix-ui/react-select": "^0.1.1",
|
||||
"@radix-ui/react-slider": "^1.0.0",
|
||||
"@radix-ui/react-tabs": "^0.1.5",
|
||||
"@radix-ui/react-toast": "^1.0.0",
|
||||
"@radix-ui/react-tooltip": "^0.1.7",
|
||||
"@sentry/nextjs": "^6.19.3",
|
||||
"@sentry/react": "^6.19.2",
|
||||
|
||||
@@ -3791,6 +3791,25 @@
|
||||
"@radix-ui/react-roving-focus" "0.1.5"
|
||||
"@radix-ui/react-use-controllable-state" "0.1.0"
|
||||
|
||||
"@radix-ui/react-toast@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-toast/-/react-toast-1.0.0.tgz#0d808e7f13376ddc74c0dbb7a4ff1c0602778ae2"
|
||||
integrity sha512-mdoF6rahgushdev0OX+9a7JKoH0xZAZBo2Ktf/s779S7EnkZeL3/MFiRIV5LpRP5CtASmfdSD3FLnEvG1RHRtQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/primitive" "1.0.0"
|
||||
"@radix-ui/react-collection" "1.0.0"
|
||||
"@radix-ui/react-compose-refs" "1.0.0"
|
||||
"@radix-ui/react-context" "1.0.0"
|
||||
"@radix-ui/react-dismissable-layer" "1.0.0"
|
||||
"@radix-ui/react-portal" "1.0.0"
|
||||
"@radix-ui/react-presence" "1.0.0"
|
||||
"@radix-ui/react-primitive" "1.0.0"
|
||||
"@radix-ui/react-use-callback-ref" "1.0.0"
|
||||
"@radix-ui/react-use-controllable-state" "1.0.0"
|
||||
"@radix-ui/react-use-layout-effect" "1.0.0"
|
||||
"@radix-ui/react-visually-hidden" "1.0.0"
|
||||
|
||||
"@radix-ui/react-tooltip@^0.1.7":
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-0.1.7.tgz#6f8c00d6e489565d14abf209ce0fb8853c8c8ee3"
|
||||
@@ -3940,6 +3959,14 @@
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/react-primitive" "0.1.4"
|
||||
|
||||
"@radix-ui/react-visually-hidden@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.0.tgz#4d69d7e3b6d21ee4678ed6de5215dcd068394401"
|
||||
integrity sha512-MwAhMdX+n6S4InwRKSnpUsp+lLkYG6izQF56ul6guSX2mBBLOMV9Frx7xJlkEe2GjKLzbNuHhaCS6e5gopmZNA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/react-primitive" "1.0.0"
|
||||
|
||||
"@radix-ui/rect@0.1.1":
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-0.1.1.tgz#95b5ba51f469bea6b1b841e2d427e17e37d38419"
|
||||
|
||||
Reference in New Issue
Block a user