chore(console-lite): add new stepper component and change deal ticket… (#788)
* chore(console-lite): add new stepper component and change deal ticket steps * chore(console-lite): remove @mui/material from project * chore(console-lite): refactor stepper counter styles to make it more legible * fix(console-lite): market selector z-index overlap * fix(console-lite): failing stepper tests * fix(console-lite): fix linting errors * feat(console-lite): add selected value to stepper.tsx * chore(console-lite): change label size stepper
This commit is contained in:
parent
7c2a84805e
commit
cbe3e80e33
@ -43,7 +43,7 @@ export const DealTicketContainer = () => {
|
||||
|
||||
return (
|
||||
<div className="flex">
|
||||
<div className="md:w-1/2 md:min-w-[500px]">
|
||||
<div className="w-full md:w-1/2 md:min-w-[500px]">
|
||||
{marketId ? (
|
||||
<Container marketId={marketId}>
|
||||
{(data) => (
|
||||
|
@ -1,23 +1,15 @@
|
||||
import * as React from 'react';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import Box from '@mui/material/Box';
|
||||
import { Stepper } from '../stepper';
|
||||
import type { DealTicketQuery_market } from '@vegaprotocol/deal-ticket';
|
||||
import { Button, InputError } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
ExpirySelector,
|
||||
SideSelector,
|
||||
TimeInForceSelector,
|
||||
TypeSelector,
|
||||
DealTicketAmount,
|
||||
MarketSelector,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import type { Order } from '@vegaprotocol/orders';
|
||||
import {
|
||||
VegaWalletOrderTimeInForce as OrderTimeInForce,
|
||||
VegaWalletOrderType as OrderType,
|
||||
VegaTxStatus,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import { VegaTxStatus } from '@vegaprotocol/wallet';
|
||||
import { t, addDecimal, toDecimal } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
getDefaultOrder,
|
||||
@ -84,7 +76,6 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
const steps = [
|
||||
{
|
||||
label: t('Select Market'),
|
||||
description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`,
|
||||
component: (
|
||||
<MarketSelector
|
||||
market={market}
|
||||
@ -92,23 +83,10 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
ItemRenderer={MarketNameRenderer}
|
||||
/>
|
||||
),
|
||||
value: market.name,
|
||||
},
|
||||
{
|
||||
label: 'Select Order Type',
|
||||
description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`,
|
||||
component: (
|
||||
<Controller
|
||||
name="type"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<TypeSelector value={field.value} onSelect={field.onChange} />
|
||||
)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Select Market Position',
|
||||
description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`,
|
||||
label: t('Select Direction'),
|
||||
component: (
|
||||
<Controller
|
||||
name="side"
|
||||
@ -120,9 +98,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Select Order Size',
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
|
||||
label: t('Choose Position Size'),
|
||||
component: (
|
||||
<DealTicketAmount
|
||||
orderType={orderType}
|
||||
@ -138,42 +114,9 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Select Time In Force',
|
||||
description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`,
|
||||
label: t('Review Trade'),
|
||||
component: (
|
||||
<>
|
||||
<Controller
|
||||
name="timeInForce"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<TimeInForceSelector
|
||||
value={field.value}
|
||||
orderType={orderType}
|
||||
onSelect={field.onChange}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{orderType === OrderType.Limit &&
|
||||
orderTimeInForce === OrderTimeInForce.GTT && (
|
||||
<Controller
|
||||
name="expiration"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<ExpirySelector
|
||||
value={field.value}
|
||||
onSelect={field.onChange}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Review & Submit Order',
|
||||
description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`,
|
||||
component: (
|
||||
<Box sx={{ mb: 2 }}>
|
||||
<div className="mb-8">
|
||||
{invalidText && (
|
||||
<InputError className="mb-8" data-testid="dealticket-error-message">
|
||||
{invalidText}
|
||||
@ -190,7 +133,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
? t('Pending...')
|
||||
: t('Place order')}
|
||||
</Button>
|
||||
</Box>
|
||||
</div>
|
||||
),
|
||||
disabled: true,
|
||||
},
|
||||
|
@ -10,7 +10,7 @@ export const NavItem = ({ iconName, label }: NavItemProps) => {
|
||||
return (
|
||||
<div className="flex flex-col md:flex-row items-center justify-start cursor-pointer relative">
|
||||
<Icon name={iconName} className="mr-8" />
|
||||
<span>{label}</span>
|
||||
<span className="text-lg">{label}</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -0,0 +1,55 @@
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import Video from '../header/video';
|
||||
|
||||
interface CounterProps {
|
||||
label: string;
|
||||
className?: string;
|
||||
isActive: boolean;
|
||||
}
|
||||
|
||||
type TStyleMap = {
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
const reduceStyles = (styleMap: TStyleMap) =>
|
||||
Object.keys(styleMap).reduce((acc, curr) => acc + `${styleMap[curr]} `, '');
|
||||
|
||||
export const Counter = ({ label, isActive, className }: CounterProps) => {
|
||||
const generalStyles: TStyleMap = {
|
||||
shape: 'rounded-full relative aspect-square clip-path-rounded',
|
||||
border: 'border-black dark:border-white',
|
||||
colours: 'bg-white dark:bg-black text-black dark:text-white',
|
||||
children: 'flex items-center justify-center text-center',
|
||||
};
|
||||
|
||||
const unselected: TStyleMap = {
|
||||
border: 'border',
|
||||
size: 'w-[30px] md:w-40',
|
||||
margin: 'mt-[5px] md:ml-[10px] md:mt-0',
|
||||
};
|
||||
|
||||
const selected: TStyleMap = {
|
||||
colours: 'text-xl text-white',
|
||||
size: 'w-40 md:w-[60px]',
|
||||
};
|
||||
|
||||
const classes = classNames(
|
||||
reduceStyles(generalStyles),
|
||||
isActive ? reduceStyles(selected) : reduceStyles(unselected),
|
||||
className
|
||||
).replace(/ +/g, ' '); // remove double space
|
||||
|
||||
return (
|
||||
<div className={classes} aria-hidden>
|
||||
{isActive && (
|
||||
<div className="w-full h-full">
|
||||
<Video />
|
||||
</div>
|
||||
)}
|
||||
<span className="absolute inset-0 flex items-center justify-center">
|
||||
{label}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1 +1 @@
|
||||
export { default as Stepper } from './stepper';
|
||||
export * from './stepper';
|
||||
|
@ -0,0 +1,124 @@
|
||||
import React from 'react';
|
||||
import { render, waitFor, fireEvent } from '@testing-library/react';
|
||||
import { Stepper } from './index';
|
||||
import type { TStep } from './index';
|
||||
|
||||
jest.mock('@vegaprotocol/react-helpers', () => {
|
||||
return {
|
||||
t: (a: string) => a,
|
||||
useScreenDimensions: jest.fn(() => ({
|
||||
isMobile: true,
|
||||
})),
|
||||
};
|
||||
});
|
||||
|
||||
// Used to disable the error you get from muted video https://github.com/testing-library/react-testing-library/issues/470
|
||||
Object.defineProperty(HTMLMediaElement.prototype, 'muted', {
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
set: () => {},
|
||||
});
|
||||
|
||||
const steps: TStep[] = [
|
||||
{
|
||||
label: 'Alpha',
|
||||
component: <p>Alpha Content</p>,
|
||||
},
|
||||
{
|
||||
label: 'Beta',
|
||||
component: <p>Beta Content</p>,
|
||||
},
|
||||
{
|
||||
label: 'Gamma',
|
||||
component: <p>Gamma Content</p>,
|
||||
},
|
||||
];
|
||||
|
||||
describe('Stepper Component', () => {
|
||||
it('should render it as a list', async () => {
|
||||
const { getByLabelText } = await render(<Stepper steps={steps} />);
|
||||
expect(getByLabelText('Step by step to make a trade')).toBeTruthy();
|
||||
expect(getByLabelText('Step 1')).toBeTruthy();
|
||||
expect(getByLabelText('Step 2')).toBeTruthy();
|
||||
expect(getByLabelText('Step 3')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should go to the correct tab on click', async () => {
|
||||
const { getByRole } = await render(<Stepper steps={steps} />);
|
||||
|
||||
expect(getByRole('tab', { name: 'Alpha' })).toHaveAttribute(
|
||||
'aria-selected',
|
||||
'true'
|
||||
);
|
||||
fireEvent.click(getByRole('tab', { name: 'Beta' }));
|
||||
await waitFor(() => getByRole('tab', { name: 'Gamma' }));
|
||||
expect(getByRole('tab', { name: 'Alpha' })).toHaveAttribute(
|
||||
'aria-selected',
|
||||
'false'
|
||||
);
|
||||
expect(getByRole('tab', { name: 'Beta' })).toHaveAttribute(
|
||||
'aria-selected',
|
||||
'true'
|
||||
);
|
||||
expect(getByRole('tab', { name: 'Gamma' })).toHaveAttribute(
|
||||
'aria-selected',
|
||||
'false'
|
||||
);
|
||||
});
|
||||
|
||||
it('should go to the correct tab on right/left arrow press', async () => {
|
||||
const { getByRole } = await render(<Stepper steps={steps} />);
|
||||
|
||||
expect(getByRole('tab', { name: 'Alpha' })).toHaveAttribute(
|
||||
'aria-selected',
|
||||
'true'
|
||||
);
|
||||
fireEvent.keyDown(getByRole('tab', { name: 'Beta' }), {
|
||||
key: 'ArrowRight',
|
||||
});
|
||||
await waitFor(() => getByRole('tab', { name: 'Beta' }));
|
||||
expect(getByRole('tab', { name: 'Alpha' })).toHaveAttribute(
|
||||
'aria-selected',
|
||||
'false'
|
||||
);
|
||||
expect(getByRole('tab', { name: 'Beta' })).toHaveAttribute(
|
||||
'aria-selected',
|
||||
'true'
|
||||
);
|
||||
fireEvent.keyDown(getByRole('tab', { name: 'Beta' }), { key: 'ArrowLeft' });
|
||||
await waitFor(() => getByRole('tab', { name: 'Alpha' }));
|
||||
expect(getByRole('tab', { name: 'Alpha' })).toHaveAttribute(
|
||||
'aria-selected',
|
||||
'true'
|
||||
);
|
||||
expect(getByRole('tab', { name: 'Beta' })).toHaveAttribute(
|
||||
'aria-selected',
|
||||
'false'
|
||||
);
|
||||
});
|
||||
|
||||
it('should go to next tab on next button click', async () => {
|
||||
const { getByRole } = await render(<Stepper steps={steps} />);
|
||||
expect(getByRole('tab', { name: 'Alpha' })).toHaveAttribute(
|
||||
'aria-selected',
|
||||
'true'
|
||||
);
|
||||
fireEvent.click(getByRole('button', { name: 'Next' }));
|
||||
await waitFor(() => getByRole('tab', { name: 'Gamma' }));
|
||||
expect(getByRole('tab', { name: 'Alpha' })).toHaveAttribute(
|
||||
'aria-selected',
|
||||
'false'
|
||||
);
|
||||
expect(getByRole('tab', { name: 'Beta' })).toHaveAttribute(
|
||||
'aria-selected',
|
||||
'true'
|
||||
);
|
||||
expect(getByRole('tab', { name: 'Gamma' })).toHaveAttribute(
|
||||
'aria-selected',
|
||||
'false'
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
});
|
@ -1,93 +1,157 @@
|
||||
import * as React from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import classNames from 'classnames';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import Stepper from '@mui/material/Stepper';
|
||||
import Step from '@mui/material/Step';
|
||||
import StepLabel from '@mui/material/StepLabel';
|
||||
import StepContent from '@mui/material/StepContent';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import Divider from '@mui/material/Divider';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { t, useScreenDimensions } from '@vegaprotocol/react-helpers';
|
||||
import { Counter } from './counter';
|
||||
|
||||
type Step = {
|
||||
export type TStep = {
|
||||
label: string;
|
||||
description: string;
|
||||
component: ReactNode;
|
||||
disabled?: boolean;
|
||||
value?: string;
|
||||
};
|
||||
|
||||
interface StepperProps {
|
||||
steps: Step[];
|
||||
export interface StepperProps {
|
||||
steps: TStep[];
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export default ({ steps }: StepperProps) => {
|
||||
export const Stepper = ({ steps }: StepperProps) => {
|
||||
const [activeStep, setActiveStep] = React.useState(0);
|
||||
const lastStep = steps.length - 1;
|
||||
const isLastStep = activeStep === lastStep;
|
||||
const { isMobile } = useScreenDimensions();
|
||||
|
||||
const handleClick = (index: typeof activeStep) => {
|
||||
setActiveStep(index);
|
||||
};
|
||||
|
||||
const handleKeyPress = (event: React.KeyboardEvent<HTMLButtonElement>) => {
|
||||
if (event.key === 'ArrowLeft' && activeStep > 0) {
|
||||
return setActiveStep((prevActiveStep) => prevActiveStep - 1);
|
||||
} else if (event.key === 'ArrowRight' && !isLastStep) {
|
||||
return setActiveStep((prevActiveStep) => prevActiveStep + 1);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const handleNext = () => {
|
||||
setActiveStep((prevActiveStep) => prevActiveStep + 1);
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
setActiveStep((prevActiveStep) => prevActiveStep - 1);
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
setActiveStep(0);
|
||||
if (!isLastStep) {
|
||||
setActiveStep((prevActiveStep) => prevActiveStep + 1);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Paper square elevation={1} sx={{ p: 3, mt: 5 }}>
|
||||
<Stepper activeStep={activeStep} orientation="vertical">
|
||||
{steps.map((step, index) => (
|
||||
<Step key={step.label}>
|
||||
<StepLabel
|
||||
optional={
|
||||
index === steps.length - 1 ? (
|
||||
<Typography variant="caption">Last step</Typography>
|
||||
) : null
|
||||
}
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => handleClick(index)}
|
||||
<div>
|
||||
<ol
|
||||
aria-label={t('Step by step to make a trade')}
|
||||
className="relative flex md:flex-col justify-between list-none"
|
||||
>
|
||||
{steps.map((step, index) => {
|
||||
const isActive = activeStep === index;
|
||||
const isFirstStep = !index;
|
||||
const isLastStep = lastStep === index;
|
||||
return (
|
||||
<li
|
||||
className="flex-1"
|
||||
key={`${index}-${step.label}`}
|
||||
aria-label={t(`Step ${index + 1}`)}
|
||||
>
|
||||
{step.label}
|
||||
</StepLabel>
|
||||
<StepContent>
|
||||
<Typography sx={{ mb: 2 }}>{step.description}</Typography>
|
||||
{step.component}
|
||||
<Divider sx={{ mb: 2 }} />
|
||||
<Box>
|
||||
<div>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={handleNext}
|
||||
disabled={step.disabled}
|
||||
<div className="flex relative md:pt-16">
|
||||
{!isFirstStep ? (
|
||||
<div
|
||||
aria-hidden
|
||||
className="flex-auto absolute top-[20px] -left-1/2 right-1/2 md:-top-1/2 md:bottom-1/2 md:left-[29.5px] md:right-auto"
|
||||
>
|
||||
{index === steps.length - 1 ? 'Finish' : 'Continue'}
|
||||
</Button>
|
||||
<Button
|
||||
variant="inline-link"
|
||||
disabled={index === 0}
|
||||
onClick={handleBack}
|
||||
>
|
||||
Back
|
||||
</Button>
|
||||
<span className="h-full block border-t-1 border-black dark:border-white w-full md:border-l-1 md:border-t-0" />
|
||||
</div>
|
||||
) : undefined}
|
||||
<button
|
||||
role="tab"
|
||||
aria-selected={isActive}
|
||||
type="button"
|
||||
id={`step-${index}-control`}
|
||||
aria-controls={`step-${index}-panel`}
|
||||
onKeyDown={(event) => handleKeyPress(event)}
|
||||
onClick={() => handleClick(index)}
|
||||
className="cursor-pointer z-10 flex w-full items-center"
|
||||
>
|
||||
<div className="flex-1 flex flex-col md:flex-row items-center w-full text-center">
|
||||
<Counter
|
||||
className="md:mr-16"
|
||||
isActive={isActive}
|
||||
label={(index + 1).toString()}
|
||||
/>
|
||||
<h3
|
||||
className={classNames(
|
||||
'md:mt-0 font-alpha uppercase text-black dark:text-white',
|
||||
{
|
||||
'mt-8 text-md md:text-2xl': isActive,
|
||||
'mt-16 text-sm md:text-lg ml-8': !isActive,
|
||||
}
|
||||
)}
|
||||
>
|
||||
{step.label}
|
||||
</h3>
|
||||
</div>
|
||||
{step.value && !isActive && (
|
||||
<span
|
||||
aria-label={`Selected value ${step.value}`}
|
||||
className="text-blue hidden md:block"
|
||||
>
|
||||
{step.value}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
{!isMobile && (
|
||||
<div
|
||||
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
|
||||
tabIndex={0}
|
||||
id={`step-${index}-panel`}
|
||||
aria-labelledby={`step-${index}-control`}
|
||||
aria-hidden={!isActive}
|
||||
role="tabpanel"
|
||||
className={classNames(
|
||||
'hidden md:block md:border-black md:dark:border-white md:ml-[29.5px] md:pl-[45px]',
|
||||
{
|
||||
'invisible h-0': !isActive,
|
||||
'visible h-full': isActive,
|
||||
'md:border-l': !isLastStep,
|
||||
}
|
||||
)}
|
||||
>
|
||||
{step.component}
|
||||
</div>
|
||||
</Box>
|
||||
</StepContent>
|
||||
</Step>
|
||||
))}
|
||||
</Stepper>
|
||||
{activeStep === steps.length && (
|
||||
<Paper square elevation={0} sx={{ p: 3 }}>
|
||||
<Typography>All steps completed - you're finished</Typography>
|
||||
<Button onClick={handleReset}>Reset</Button>
|
||||
</Paper>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ol>
|
||||
{isMobile && (
|
||||
<div
|
||||
id={`step-${activeStep}-panel`}
|
||||
aria-labelledby={`step-${activeStep}-control`}
|
||||
role="tabpanel"
|
||||
className="md:hidden mt-32" // md:hidden as fallback
|
||||
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
|
||||
tabIndex={0}
|
||||
>
|
||||
{steps[activeStep].component}
|
||||
{!isLastStep && (
|
||||
<Button
|
||||
className="w-full !py-8 mt-64 md:sr-only"
|
||||
boxShadow={false}
|
||||
variant="secondary"
|
||||
onClick={handleNext}
|
||||
disabled={steps[activeStep].disabled}
|
||||
>
|
||||
{t('Next')}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</Paper>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -7,6 +7,14 @@
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
||||
<link
|
||||
rel="preload"
|
||||
href="https://static.vega.xyz/AlphaLyrae-Medium.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<link rel="stylesheet" href="https://static.vega.xyz/fonts.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root" class="h-full max-h-full"></div>
|
||||
|
@ -206,7 +206,7 @@ export const MarketSelector = ({ market, setMarket, ItemRenderer }: Props) => {
|
||||
<hr className="md:hidden mb-5" />
|
||||
<div
|
||||
className={classNames(
|
||||
'md:absolute flex flex-col top-[30px] z-10 md:drop-shadow-md md:border-1 md:border-black md:dark:border-white bg-white dark:bg-black text-black dark:text-white min-w-full md:max-h-[200px] overflow-y-auto',
|
||||
'md:absolute z-20 flex flex-col top-[30px] z-10 md:drop-shadow-md md:border-1 md:border-black md:dark:border-white bg-white dark:bg-black text-black dark:text-white min-w-full md:max-h-[200px] overflow-y-auto',
|
||||
showPane ? 'block' : 'hidden'
|
||||
)}
|
||||
data-testid="market-pane"
|
||||
@ -221,7 +221,7 @@ export const MarketSelector = ({ market, setMarket, ItemRenderer }: Props) => {
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
key={market.id}
|
||||
className="cursor-pointer focus:bg-white-95 focus:outline-0 dark:focus:bg-black-80 px-20 py-5"
|
||||
className="bg-white dark:bg-black cursor-pointer focus:bg-white-95 focus:outline-0 dark:focus:bg-black-80 px-20 py-5"
|
||||
onClick={() => handleMarketSelect(market)}
|
||||
onKeyDown={(e) => handleItemKeyDown(e, market, i)}
|
||||
>
|
||||
|
@ -1,4 +1,5 @@
|
||||
const theme = require('./theme');
|
||||
const defaultTheme = require('tailwindcss/defaultTheme');
|
||||
|
||||
module.exports = {
|
||||
...theme,
|
||||
@ -25,7 +26,7 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
fontSize: {
|
||||
...theme.fontSize,
|
||||
...defaultTheme.fontSize,
|
||||
capMenu: ['15px', { lineHeight: '24px', letterSpacing: '-0.01em' }],
|
||||
market: ['15px', { lineHeight: '24px' }],
|
||||
'ui-small': ['12px', { lineHeight: '14px' }],
|
||||
@ -42,4 +43,10 @@ module.exports = {
|
||||
'input-focus-error': 'none',
|
||||
'input-focus-error-dark': 'none',
|
||||
},
|
||||
extend: {
|
||||
transitionProperty: {
|
||||
height: 'height',
|
||||
'max-height': 'max-height',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -17,7 +17,6 @@
|
||||
"@blueprintjs/icons": "^3.32.0",
|
||||
"@emotion/react": "^11.9.0",
|
||||
"@emotion/styled": "^11.8.1",
|
||||
"@mui/material": "^5.6.2",
|
||||
"@nrwl/next": "13.10.3",
|
||||
"@radix-ui/react-accordion": "^0.1.6",
|
||||
"@radix-ui/react-dialog": "^0.1.5",
|
||||
|
120
yarn.lock
120
yarn.lock
@ -1217,7 +1217,7 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.14.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.14.8", "@babel/runtime@^7.16.0", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
|
||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.14.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.14.8", "@babel/runtime@^7.16.0", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
|
||||
version "7.17.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72"
|
||||
integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==
|
||||
@ -2518,86 +2518,6 @@
|
||||
call-me-maybe "^1.0.1"
|
||||
glob-to-regexp "^0.3.0"
|
||||
|
||||
"@mui/base@5.0.0-alpha.78":
|
||||
version "5.0.0-alpha.78"
|
||||
resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-alpha.78.tgz#9d0ee8c913969f60cd7072a6082e3c0652be0b74"
|
||||
integrity sha512-5L+GNe2M9/tFjQpjK2r837+kzRg/l6D5R9SQbG1wmSWejw5Ei8P+KXIgS/NLNi9g7dUT8bnCyzz9AZKQX1Jsfg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
"@emotion/is-prop-valid" "^1.1.2"
|
||||
"@mui/types" "^7.1.3"
|
||||
"@mui/utils" "^5.6.1"
|
||||
"@popperjs/core" "^2.11.5"
|
||||
clsx "^1.1.1"
|
||||
prop-types "^15.7.2"
|
||||
react-is "^17.0.2"
|
||||
|
||||
"@mui/material@^5.6.2":
|
||||
version "5.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.6.3.tgz#a5b6cd1b0417fca67a65172530ff5573ab7bc453"
|
||||
integrity sha512-2VovFsbCEhic29NYoBF7zFrpH2sEOlKXXDhGjzxmWiI9OnC3SX63hapWunjaVsiRINVnjuMHuW1MOs4UtV8Gfg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
"@mui/base" "5.0.0-alpha.78"
|
||||
"@mui/system" "^5.6.3"
|
||||
"@mui/types" "^7.1.3"
|
||||
"@mui/utils" "^5.6.1"
|
||||
"@types/react-transition-group" "^4.4.4"
|
||||
clsx "^1.1.1"
|
||||
csstype "^3.0.11"
|
||||
hoist-non-react-statics "^3.3.2"
|
||||
prop-types "^15.7.2"
|
||||
react-is "^17.0.2"
|
||||
react-transition-group "^4.4.2"
|
||||
|
||||
"@mui/private-theming@^5.6.2":
|
||||
version "5.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.6.2.tgz#c42da32f8b9481ba12885176c0168a355727c189"
|
||||
integrity sha512-IbrSfFXfiZdyhRMC2bgGTFtb16RBQ5mccmjeh3MtAERWuepiCK7gkW5D9WhEsfTu6iez+TEjeUKSgmMHlsM2mg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
"@mui/utils" "^5.6.1"
|
||||
prop-types "^15.7.2"
|
||||
|
||||
"@mui/styled-engine@^5.6.1":
|
||||
version "5.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.6.1.tgz#e2c859a4dbdd65af89e77703a0725285aef471fd"
|
||||
integrity sha512-jEhH6TBY8jc9S8yVncXmoTYTbATjEu44RMFXj6sIYfKr5NArVwTwRo3JexLL0t3BOAiYM4xsFLgfKEIvB9SAeQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
"@emotion/cache" "^11.7.1"
|
||||
prop-types "^15.7.2"
|
||||
|
||||
"@mui/system@^5.6.3":
|
||||
version "5.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.6.3.tgz#a03ad6d61b0b7d304a8af60374e27e71e7818ef7"
|
||||
integrity sha512-4SRi52a4ttZ2S4EHEDE8arVNuKqyQLTYUTF80WAZ0tQwnG20qwlBtzcrywCGItmVAMl7RUaYopyWOx3yVPvrmQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
"@mui/private-theming" "^5.6.2"
|
||||
"@mui/styled-engine" "^5.6.1"
|
||||
"@mui/types" "^7.1.3"
|
||||
"@mui/utils" "^5.6.1"
|
||||
clsx "^1.1.1"
|
||||
csstype "^3.0.11"
|
||||
prop-types "^15.7.2"
|
||||
|
||||
"@mui/types@^7.1.3":
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.1.3.tgz#d7636f3046110bcccc63e6acfd100e2ad9ca712a"
|
||||
integrity sha512-DDF0UhMBo4Uezlk+6QxrlDbchF79XG6Zs0zIewlR4c0Dt6GKVFfUtzPtHCH1tTbcSlq/L2bGEdiaoHBJ9Y1gSA==
|
||||
|
||||
"@mui/utils@^5.6.1":
|
||||
version "5.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.6.1.tgz#4ab79a21bd481555d9a588f4b18061b3c28ea5db"
|
||||
integrity sha512-CPrzrkiBusCZBLWu0Sg5MJvR3fKJyK3gKecLVX012LULyqg2U64Oz04BKhfkbtBrPBbSQxM+DWW9B1c9hmV9nQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
"@types/prop-types" "^15.7.4"
|
||||
"@types/react-is" "^16.7.1 || ^17.0.0"
|
||||
prop-types "^15.7.2"
|
||||
react-is "^17.0.2"
|
||||
|
||||
"@napi-rs/triples@1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@napi-rs/triples/-/triples-1.0.3.tgz#76d6d0c3f4d16013c61e45dfca5ff1e6c31ae53c"
|
||||
@ -3344,7 +3264,7 @@
|
||||
schema-utils "^3.0.0"
|
||||
source-map "^0.7.3"
|
||||
|
||||
"@popperjs/core@^2.11.5", "@popperjs/core@^2.5.4", "@popperjs/core@^2.6.0":
|
||||
"@popperjs/core@^2.5.4", "@popperjs/core@^2.6.0":
|
||||
version "2.11.5"
|
||||
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64"
|
||||
integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==
|
||||
@ -6316,7 +6236,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.0.tgz#a1c3809b0ad61c62cac6d4e0c56d610c910b7654"
|
||||
integrity sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==
|
||||
|
||||
"@types/prop-types@*", "@types/prop-types@^15.7.4":
|
||||
"@types/prop-types@*":
|
||||
version "15.7.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
|
||||
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
|
||||
@ -6364,13 +6284,6 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-is@^16.7.1 || ^17.0.0":
|
||||
version "17.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-is/-/react-is-17.0.3.tgz#2d855ba575f2fc8d17ef9861f084acc4b90a137a"
|
||||
integrity sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-router-dom@5.3.1":
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.1.tgz#76700ccce6529413ec723024b71f01fc77a4a980"
|
||||
@ -6402,13 +6315,6 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-transition-group@^4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.4.tgz#acd4cceaa2be6b757db61ed7b432e103242d163e"
|
||||
integrity sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-virtualized-auto-sizer@^1.0.0", "@types/react-virtualized-auto-sizer@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz#b3187dae1dfc4c15880c9cfc5b45f2719ea6ebd4"
|
||||
@ -10542,7 +10448,7 @@ csstype@^2.5.7:
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.20.tgz#9229c65ea0b260cf4d3d997cb06288e36a8d6dda"
|
||||
integrity sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==
|
||||
|
||||
csstype@^3.0.11, csstype@^3.0.2, csstype@^3.0.4:
|
||||
csstype@^3.0.2, csstype@^3.0.4:
|
||||
version "3.0.11"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33"
|
||||
integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==
|
||||
@ -11171,14 +11077,6 @@ dom-helpers@^3.4.0:
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.2"
|
||||
|
||||
dom-helpers@^5.0.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
|
||||
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.8.7"
|
||||
csstype "^3.0.2"
|
||||
|
||||
dom-serializer@0:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
|
||||
@ -18848,16 +18746,6 @@ react-transition-group@2.9.0:
|
||||
prop-types "^15.6.2"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
|
||||
react-transition-group@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470"
|
||||
integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.5"
|
||||
dom-helpers "^5.0.1"
|
||||
loose-envify "^1.4.0"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
react-use-websocket@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-use-websocket/-/react-use-websocket-3.0.0.tgz#754cb8eea76f55d31c5676d4abe3e573bc2cea04"
|
||||
|
Loading…
Reference in New Issue
Block a user