Skip to content

Commit

Permalink
feat: shared components library
Browse files Browse the repository at this point in the history
  • Loading branch information
dcodes05 committed Aug 23, 2023
1 parent 1ad4e2f commit a0e14d9
Show file tree
Hide file tree
Showing 88 changed files with 5,238 additions and 61 deletions.
33 changes: 33 additions & 0 deletions libs/defi/oeth/src/components/Swap/BestRoutes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Box } from '@mui/material';

import { SwapRouteCard } from './SwapRouteCard';

import type { Route } from './SwapRoute';

interface Props {
routes: Route[];
selected: number;
onSelect: (index: number) => void;
}

export function BestRoutes({ routes, selected, onSelect }: Props) {
return (
<Box
sx={{
gridTemplateColumns: 'repeat(2, 1fr)',
gap: 1,
display: 'grid',
}}
>
{routes.slice(0, 2).map((route, index) => (
<SwapRouteCard
index={index}
key={index}
selected={selected}
onSelect={(index) => onSelect(index)}
route={route}
/>
))}
</Box>
);
}
36 changes: 36 additions & 0 deletions libs/defi/oeth/src/components/Swap/GasPopover.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { screen, userEvent, within } from '@storybook/testing-library';

import { GasPopover } from './GasPopover';

import type { Meta, StoryObj } from '@storybook/react';

const meta: Meta<typeof GasPopover> = {
component: GasPopover,
title: 'Swap/GasPopover',
args: {
gasPrice: 21,
onPriceToleranceChange: (val) => null,
},
};

export default meta;

export const Default: StoryObj<typeof GasPopover> = {};

export const Expanded: StoryObj<typeof GasPopover> = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await canvas.getByTestId('gas-popover-button').click();
},
};

export const HighTolerance: StoryObj<typeof GasPopover> = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);

await canvas.getByTestId('gas-popover-button').click();
const input = await screen.findByLabelText('Price tolerance');
await userEvent.clear(input);
await userEvent.type(input, '1.2');
},
};
199 changes: 199 additions & 0 deletions libs/defi/oeth/src/components/Swap/GasPopover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import { useEffect, useState } from 'react';

import {
alpha,
Box,
Button,
debounce,
FormControl,
FormHelperText,
IconButton,
InputAdornment,
InputBase,
InputLabel,
Popover,
Stack,
useTheme,
} from '@mui/material';
import { isNumber } from 'lodash';
import { useIntl } from 'react-intl';

import type { Theme } from '@mui/material';

const defaultPriceTolerance = 0.01;

const gridStyles = {
display: 'grid',
gridTemplateColumns: (theme: Theme) => `1.5fr 1fr`,
gap: 1,
justifyContent: 'space-between',
alignItems: 'center',
};

interface Props {
gasPrice: number;
onPriceToleranceChange: (value: number) => void;
}

export function GasPopover({ gasPrice, onPriceToleranceChange }: Props) {
const theme = useTheme();
const intl = useIntl();
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
const [priceTolerance, setPriceTolerance] = useState(defaultPriceTolerance);

useEffect(() => {
onPriceToleranceChange(priceTolerance);
}, [priceTolerance, onPriceToleranceChange]);
return (
<>
<IconButton
onClick={(e) => setAnchorEl(e.currentTarget)}
data-testid="gas-popover-button"
>
<img src="https://app.oeth.com/images/settings-icon.svg" />
</IconButton>
<Popover
open={!!anchorEl}
anchorEl={anchorEl}
onClose={() => setAnchorEl(null)}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
sx={{
'& .MuiPaper-root.MuiPopover-paper': {
padding: 3,
boxSizing: 'border-box',
maxWidth: {
xs: '90vw',
md: '16.5rem',
},
width: '100%',
border: '1px solid',
borderColor: 'grey.700',
[theme.breakpoints.down('md')]: {
left: '0 !important',
right: 0,
marginInline: 'auto',
},
},
}}
>
<Stack gap={2} sx={{ '--origin-blue': '#0074F0' }}>
<FormControl variant="standard">
<InputLabel htmlFor="tolerance" shrink>
{intl.formatMessage({ defaultMessage: 'Price tolerance' })}
</InputLabel>
<Box sx={gridStyles}>
<InputBase
id="tolerance"
defaultValue={priceTolerance}
fullWidth
sx={{
borderColor: 'var(--origin-blue)',
backgroundColor: alpha('#0074F0', 0.05),
paddingInlineEnd: 2,
'& .MuiInputBase-input': {
textAlign: 'right',
color: 'primary.contrastText',

'&::placeholder': {
color: 'text.primary',
opacity: 1,
},
},
}}
onChange={debounce((e) => {
if (isNumber(parseFloat(e.target.value))) {
setPriceTolerance(e.target.value);
}
}, 300)}
endAdornment={
<InputAdornment
position="end"
sx={{ color: 'primary.contrastText', ml: 0 }}
>
{intl.formatMessage({ defaultMessage: '%' })}
</InputAdornment>
}
/>

<Button
variant="contained"
sx={{
borderRadius: 20,
height: '38px',
color: 'primary.contrastText',
bgColor:
'linear-gradient(90deg, var(--mui-palette-primary-main) 0%, var(--mui-palette-primary-dark) 100%)',
'&:disabled': {
opacity: 0.3,
},
}}
fullWidth
disabled={priceTolerance === defaultPriceTolerance}
onClick={() => setPriceTolerance(defaultPriceTolerance)}
>
{intl.formatMessage({ defaultMessage: 'Auto' })}
</Button>
</Box>
{priceTolerance > 1 ? (
<FormHelperText
sx={{
gridColumn: 'span 2',
mt: 1.25,
fontSize: (theme) => theme.typography.pxToRem(12),
color: (theme) => theme.palette.warning.main,
fontWeight: 400,
fontStyle: 'normal',
}}
>
{intl.formatMessage({
defaultMessage: 'Your transaction may be frontrun',
})}
</FormHelperText>
) : null}
</FormControl>
<FormControl>
<InputLabel htmlFor="gas" shrink>
{intl.formatMessage({ defaultMessage: 'Gas Price' })}
</InputLabel>
<Box sx={gridStyles}>
<InputBase
id="gas"
defaultValue={gasPrice}
fullWidth
sx={{
borderColor: 'var(--origin-blue)',
backgroundColor: alpha('#0074F0', 0.05),
paddingInlineEnd: 2,
'& .MuiInputBase-input': {
textAlign: 'right',
borderColor: 'var(--origin-blue)',
color: 'primary.contrastText',
'&::placeholder': {
color: 'text.primary',
opacity: 1,
},
},
}}
endAdornment={
<InputAdornment
position="end"
sx={{ color: 'primary.contrastText', ml: 0 }}
>
{intl.formatMessage({ defaultMessage: 'GWEI' })}
</InputAdornment>
}
/>
</Box>
</FormControl>
</Stack>
</Popover>
</>
);
}
94 changes: 94 additions & 0 deletions libs/defi/oeth/src/components/Swap/RedeemMix.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { Box } from '@mui/material';

import { RedeemMix } from './RedeemMix';

import type { Meta, StoryObj } from '@storybook/react';

const meta: Meta<typeof RedeemMix> = {
component: RedeemMix,
title: 'Swap/Redeem Mix',
args: {
selected: 4,
index: 2,
route: {
value: 282967.55,
quantity: 149.55,
name: 'Redeem for mix via OETH vault',
waitTime: '1 min',
transactionCost: 135.83,
rate: 0.995,
type: 'redeem',
tokenAbbreviation: '',
icon: [
'https://app.oeth.com/images/currency/weth-icon-small.png',
'https://app.oeth.com/images/currency/reth-icon-small.png',
'https://app.oeth.com/images/currency/steth-icon-small.svg',
'https://app.oeth.com/images/currency/frxeth-icon-small.svg',
],
},
composition: [
{
name: 'wETH',
quantity: 117.0437,
value: 238378.36,
icon: 'https://app.oeth.com/images/currency/weth-icon-small.png',
},
{
name: 'frxETH',
quantity: 13.1245,
value: 17643.75,
icon: 'https://app.oeth.com/images/currency/frxeth-icon-small.svg',
},
{
name: 'rETH',
quantity: 13.1144,
value: 13138.96,
icon: 'https://app.oeth.com/images/currency/reth-icon-small.png',
},
{
name: 'sETH',
quantity: 4.8354,
value: 13138.96,
icon: 'https://app.oeth.com/images/currency/steth-icon-small.svg',
},
],
},
render: (args) => (
<Box sx={{ maxWidth: { xs: 317, md: 471 } }}>
<RedeemMix {...args} />
</Box>
),
};

export default meta;

export const Default: StoryObj<typeof RedeemMix> = {};

export const Hover: StoryObj<typeof RedeemMix> = {
parameters: {
pseudo: {
hover: true,
},
},
};
export const Selected: StoryObj<typeof RedeemMix> = {
args: {
index: 4,
},
};

export const SmallMobile: StoryObj<typeof RedeemMix> = {
parameters: {
viewport: {
defaultViewport: 'mobile1',
},
},
};

export const LargeMobile: StoryObj<typeof RedeemMix> = {
parameters: {
viewport: {
defaultViewport: 'mobile2',
},
},
};
Loading

0 comments on commit a0e14d9

Please sign in to comment.