@rango-dev/ui 0.1.10-next.78 → 0.1.10-next.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Alert/Alert.d.ts +2 -2
- package/dist/components/Alert/Alert.stories.d.ts +2 -1
- package/dist/components/BestRoute/BestRoute.d.ts +4 -1
- package/dist/components/SecondaryPage/SecondaryPage.d.ts +3 -5
- package/dist/components/SelectableWalletList/SelectableWalletList.d.ts +1 -1
- package/dist/components/TextField/TextField.stories.d.ts +1 -1
- package/dist/containers/ConfirmSwap/ConfirmSwap.d.ts +8 -4
- package/dist/containers/ConfirmWallets/ConfirmWallets.d.ts +4 -2
- package/dist/containers/History/types.d.ts +1 -0
- package/dist/helper/index.d.ts +0 -5
- package/dist/types/wallet.d.ts +8 -0
- package/dist/ui.cjs.development.js +288 -262
- package/dist/ui.cjs.development.js.map +1 -1
- package/dist/ui.cjs.production.min.js +1 -1
- package/dist/ui.cjs.production.min.js.map +1 -1
- package/dist/ui.esm.js +288 -262
- package/dist/ui.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Alert/Alert.tsx +5 -9
- package/src/components/BestRoute/BestRoute.tsx +55 -21
- package/src/components/BlockchainSelector/BlockchainSelector.tsx +13 -11
- package/src/components/LiquiditySourceList/LiquiditySourceList.tsx +21 -20
- package/src/components/LiquiditySourcesSelector/LiquiditySourcesSelector.tsx +3 -2
- package/src/components/Radio/Radio.tsx +1 -0
- package/src/components/SecondaryPage/SecondaryPage.tsx +5 -6
- package/src/components/SelectableWalletList/SelectableWalletList.tsx +1 -1
- package/src/components/Settings/Settings.tsx +12 -13
- package/src/components/SwapContainer/SwapContainer.tsx +1 -0
- package/src/components/Switch/Switch.tsx +1 -0
- package/src/components/TokenSelector/TokenSelector.tsx +3 -2
- package/src/containers/ConfirmSwap/ConfirmSwap.tsx +92 -54
- package/src/containers/ConfirmWallets/ConfirmWallets.tsx +66 -62
- package/src/containers/History/History.tsx +3 -2
- package/src/containers/History/types.tsx +10 -1
- package/src/containers/SwapHistory/SwapHistory.tsx +87 -95
- package/src/helper/index.ts +1 -22
- package/src/types/wallet.ts +9 -0
- package/dist/containers/ConfirmWallets/types.d.ts +0 -9
- package/src/containers/ConfirmWallets/types.ts +0 -10
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { PropsWithChildren } from 'react';
|
|
2
2
|
import { CheckCircleIcon, InfoCircleIcon, WarningIcon } from '../Icon';
|
|
3
3
|
import { Typography } from '../Typography';
|
|
4
4
|
import { darkTheme, styled } from '../../theme';
|
|
@@ -30,10 +30,7 @@ const MainContainer = styled('div', {
|
|
|
30
30
|
},
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
const ContentContainer = styled('div', {
|
|
34
|
-
display: 'flex',
|
|
35
|
-
flexDirection: 'column',
|
|
36
|
-
});
|
|
33
|
+
const ContentContainer = styled('div', {});
|
|
37
34
|
|
|
38
35
|
const TitleContainer = styled('div', {
|
|
39
36
|
marginBottom: '$8',
|
|
@@ -49,12 +46,11 @@ const StyledTypography = styled(Typography, {
|
|
|
49
46
|
|
|
50
47
|
export interface PropTypes {
|
|
51
48
|
type: 'primary' | 'secondary' | 'success' | 'warning' | 'error';
|
|
52
|
-
description: string;
|
|
53
49
|
title?: string;
|
|
54
50
|
}
|
|
55
51
|
|
|
56
|
-
export function Alert(props: PropTypes) {
|
|
57
|
-
const { type,
|
|
52
|
+
export function Alert(props: PropsWithChildren<PropTypes>) {
|
|
53
|
+
const { type, children, title } = props;
|
|
58
54
|
|
|
59
55
|
const showIcon = (
|
|
60
56
|
['error', 'success', 'warning'] as PropTypes['type'][]
|
|
@@ -75,7 +71,7 @@ export function Alert(props: PropTypes) {
|
|
|
75
71
|
<StyledTypography variant="h6">{title}</StyledTypography>
|
|
76
72
|
</TitleContainer>
|
|
77
73
|
)}
|
|
78
|
-
|
|
74
|
+
{children}
|
|
79
75
|
</ContentContainer>
|
|
80
76
|
</MainContainer>
|
|
81
77
|
);
|
|
@@ -2,8 +2,7 @@ import React, { Fragment, PropsWithChildren } from 'react';
|
|
|
2
2
|
import { GasIcon, TimeIcon } from '../../components/Icon';
|
|
3
3
|
import { StepDetail } from '../../components/StepDetail';
|
|
4
4
|
import { Typography } from '../../components/Typography';
|
|
5
|
-
import {
|
|
6
|
-
import { styled } from '../../theme';
|
|
5
|
+
import { keyframes, styled } from '../../theme';
|
|
7
6
|
import { Skeleton } from '../Skeleton';
|
|
8
7
|
import { Spinner } from '../Spinner';
|
|
9
8
|
import { BestRouteResponse } from 'rango-sdk';
|
|
@@ -77,6 +76,18 @@ const ArrowRight = styled('div', {
|
|
|
77
76
|
borderLeft: '5px solid $foreground',
|
|
78
77
|
});
|
|
79
78
|
|
|
79
|
+
const pulse = keyframes({
|
|
80
|
+
'0%': {
|
|
81
|
+
opacity: 1,
|
|
82
|
+
},
|
|
83
|
+
'50%': {
|
|
84
|
+
opacity: 0.3,
|
|
85
|
+
},
|
|
86
|
+
'100%': {
|
|
87
|
+
opacity: 1,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
80
91
|
const GasContainer = styled('div', {
|
|
81
92
|
backgroundColor: '$neutrals300',
|
|
82
93
|
borderRadius: '5px',
|
|
@@ -91,6 +102,30 @@ const GasContainer = styled('div', {
|
|
|
91
102
|
margin: '$8',
|
|
92
103
|
},
|
|
93
104
|
});
|
|
105
|
+
|
|
106
|
+
const FeeContainer = styled('div', {
|
|
107
|
+
display: 'flex',
|
|
108
|
+
flexDirection: 'column',
|
|
109
|
+
alignItems: 'center',
|
|
110
|
+
variants: {
|
|
111
|
+
warning: {
|
|
112
|
+
true: {
|
|
113
|
+
animation: `${pulse} 2s ease-in-out infinite`,
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const TotalFee = styled(Typography, {
|
|
120
|
+
variants: {
|
|
121
|
+
warning: {
|
|
122
|
+
true: {
|
|
123
|
+
color: '$warning300',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
|
|
94
129
|
const SkeletonContainer = styled('div', {
|
|
95
130
|
padding: '$4',
|
|
96
131
|
'@md': {
|
|
@@ -105,22 +140,14 @@ const SwapperContainer = styled('div', {
|
|
|
105
140
|
|
|
106
141
|
export interface PropTypes {
|
|
107
142
|
data: BestRouteResponse | null;
|
|
143
|
+
totalFee: string;
|
|
144
|
+
feeWarning: boolean;
|
|
145
|
+
totalTime: string;
|
|
108
146
|
loading?: boolean;
|
|
109
147
|
error?: string;
|
|
110
148
|
}
|
|
111
|
-
export function BestRoute({
|
|
112
|
-
data,
|
|
113
|
-
loading,
|
|
114
|
-
error,
|
|
115
|
-
}: PropsWithChildren<PropTypes>) {
|
|
116
|
-
let fee,
|
|
117
|
-
time: string = '';
|
|
118
|
-
|
|
119
|
-
if (!!data) {
|
|
120
|
-
fee = rawFees(data);
|
|
121
|
-
time = secondsToString(totalArrivalTime(data));
|
|
122
|
-
}
|
|
123
|
-
|
|
149
|
+
export function BestRoute(props: PropsWithChildren<PropTypes>) {
|
|
150
|
+
const { data, loading, error, totalFee, feeWarning, totalTime } = props;
|
|
124
151
|
return (
|
|
125
152
|
<Container>
|
|
126
153
|
{loading ? (
|
|
@@ -129,16 +156,23 @@ export function BestRoute({
|
|
|
129
156
|
</SkeletonContainer>
|
|
130
157
|
) : (
|
|
131
158
|
<GasContainer>
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
159
|
+
<FeeContainer warning={feeWarning}>
|
|
160
|
+
<GasIcon size={20} color={feeWarning ? 'warning' : undefined} />
|
|
161
|
+
<TotalFee
|
|
162
|
+
mt={4}
|
|
163
|
+
align="center"
|
|
164
|
+
variant="caption"
|
|
165
|
+
warning={feeWarning}
|
|
166
|
+
>
|
|
167
|
+
{error && '-'}
|
|
168
|
+
{!!data && `$${totalFee}`}
|
|
169
|
+
</TotalFee>
|
|
170
|
+
</FeeContainer>
|
|
137
171
|
<HR />
|
|
138
172
|
<TimeIcon size={20} />
|
|
139
173
|
<Typography mt={4} align="center" variant="caption">
|
|
140
174
|
{error && '-'}
|
|
141
|
-
{!!data && `~${
|
|
175
|
+
{!!data && `~${totalTime}m`}
|
|
142
176
|
</Typography>
|
|
143
177
|
</GasContainer>
|
|
144
178
|
)}
|
|
@@ -7,6 +7,7 @@ import { Spinner } from '../Spinner';
|
|
|
7
7
|
import { styled } from '../../theme';
|
|
8
8
|
import { CSSProperties } from '@stitches/react';
|
|
9
9
|
import { containsText } from '../../helper';
|
|
10
|
+
import { Typography } from '../Typography';
|
|
10
11
|
|
|
11
12
|
const ListContainer = styled('div', {
|
|
12
13
|
height: '450px',
|
|
@@ -58,20 +59,22 @@ export function BlockchainSelector(props: PropTypes) {
|
|
|
58
59
|
textFieldPlaceholder="Search Blockchain By Name"
|
|
59
60
|
title={`Select ${type} Network`}
|
|
60
61
|
onBack={onBack}
|
|
61
|
-
|
|
62
|
+
>
|
|
63
|
+
{(searchedFor) => {
|
|
62
64
|
const filteredBlockchains = filterBlockchains(list, searchedFor);
|
|
63
65
|
return (
|
|
64
|
-
<ListContainer style={listContainerStyle}>
|
|
66
|
+
<ListContainer style={listContainerStyle} key="1">
|
|
65
67
|
{loadingStatus === 'loading' && (
|
|
66
68
|
<div>
|
|
67
69
|
<Spinner size={24} />
|
|
68
70
|
</div>
|
|
69
71
|
)}
|
|
70
72
|
{loadingStatus === 'failed' && (
|
|
71
|
-
<Alert
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
<Alert type="error">
|
|
74
|
+
<Typography variant="body2">
|
|
75
|
+
Error connecting server, please reload the app and try again
|
|
76
|
+
</Typography>
|
|
77
|
+
</Alert>
|
|
75
78
|
)}
|
|
76
79
|
{loadingStatus === 'success' && (
|
|
77
80
|
<>
|
|
@@ -84,16 +87,15 @@ export function BlockchainSelector(props: PropTypes) {
|
|
|
84
87
|
onChange={onChange}
|
|
85
88
|
/>
|
|
86
89
|
) : (
|
|
87
|
-
<Alert
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
/>
|
|
90
|
+
<Alert type="secondary">
|
|
91
|
+
<Typography variant="body2">{`${searchedFor} not found`}</Typography>
|
|
92
|
+
</Alert>
|
|
91
93
|
)}
|
|
92
94
|
</>
|
|
93
95
|
)}
|
|
94
96
|
</ListContainer>
|
|
95
97
|
);
|
|
96
98
|
}}
|
|
97
|
-
|
|
99
|
+
</SecondaryPage>
|
|
98
100
|
);
|
|
99
101
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CSSProperties } from '@stitches/react';
|
|
2
|
-
import React, { useState } from 'react';
|
|
2
|
+
import React, { useEffect, useState } from 'react';
|
|
3
3
|
import { styled } from '../../theme';
|
|
4
4
|
import { LiquiditySource } from '../../types/meta';
|
|
5
5
|
import { Button } from '../Button/Button';
|
|
@@ -21,6 +21,7 @@ const groupLiquiditySources = (
|
|
|
21
21
|
|
|
22
22
|
const LiquiditySourceType = styled(Typography, {
|
|
23
23
|
position: 'sticky',
|
|
24
|
+
display: 'block',
|
|
24
25
|
top: '0',
|
|
25
26
|
marginTop: '$8',
|
|
26
27
|
marginBottom: '$8',
|
|
@@ -55,14 +56,16 @@ export function LiquiditySourceList(props: PropTypes) {
|
|
|
55
56
|
if (clickedItem.selected) return [...prevState, clickedItem];
|
|
56
57
|
return prevState.filter((item) => item.title != clickedItem.title);
|
|
57
58
|
});
|
|
58
|
-
|
|
59
|
-
onChange(clickedItem);
|
|
60
|
-
}, 200);
|
|
59
|
+
onChange(clickedItem);
|
|
61
60
|
};
|
|
62
61
|
|
|
63
62
|
const isSelected = (liquiditySource: LiquiditySource) =>
|
|
64
63
|
!!selected.find((item) => liquiditySource.title === item.title);
|
|
65
64
|
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
setSelected(list.filter((item) => item.selected));
|
|
67
|
+
}, [list]);
|
|
68
|
+
|
|
66
69
|
return (
|
|
67
70
|
<div style={{ height: '450px', ...listContainerStyle }}>
|
|
68
71
|
<div>
|
|
@@ -102,19 +105,17 @@ const LiquiditySourceItem = ({
|
|
|
102
105
|
liquiditySource: LiquiditySource;
|
|
103
106
|
selected: boolean;
|
|
104
107
|
onChange: (clickedItem: LiquiditySource) => void;
|
|
105
|
-
}) =>
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
);
|
|
120
|
-
};
|
|
108
|
+
}) => (
|
|
109
|
+
<Button
|
|
110
|
+
size="large"
|
|
111
|
+
align="start"
|
|
112
|
+
variant="outlined"
|
|
113
|
+
prefix={<LiquidityImage src={liquiditySource.logo} />}
|
|
114
|
+
suffix={<Switch checked={selected} />}
|
|
115
|
+
style={{ marginBottom: '12px' }}
|
|
116
|
+
type={selected ? 'primary' : undefined}
|
|
117
|
+
onClick={onChange.bind(null, liquiditySource)}
|
|
118
|
+
>
|
|
119
|
+
<Typography variant="body1">{liquiditySource.title}</Typography>
|
|
120
|
+
</Button>
|
|
121
|
+
);
|
|
@@ -43,13 +43,14 @@ export function LiquiditySourcesSelector(props: PropTypes) {
|
|
|
43
43
|
}
|
|
44
44
|
hasHeader={hasHeader}
|
|
45
45
|
onBack={onBack}
|
|
46
|
-
|
|
46
|
+
>
|
|
47
|
+
{(searchedFor) => (
|
|
47
48
|
<LiquiditySourceList
|
|
48
49
|
listContainerStyle={listContainerStyle}
|
|
49
50
|
list={filterLiquiditySources(list, searchedFor)}
|
|
50
51
|
onChange={onChange}
|
|
51
52
|
/>
|
|
52
53
|
)}
|
|
53
|
-
|
|
54
|
+
</SecondaryPage>
|
|
54
55
|
);
|
|
55
56
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { ReactNode, useState } from 'react';
|
|
2
2
|
import { styled } from '../../theme';
|
|
3
3
|
import { AngleLeftIcon, SearchIcon } from '../Icon';
|
|
4
4
|
import { TextField } from '../TextField/TextField';
|
|
@@ -7,12 +7,12 @@ import { Typography } from '../Typography';
|
|
|
7
7
|
export type PropTypes = (
|
|
8
8
|
| {
|
|
9
9
|
textField: true;
|
|
10
|
-
|
|
10
|
+
children?: (searchedFor: string) => ReactNode;
|
|
11
11
|
textFieldPlaceholder: string;
|
|
12
12
|
}
|
|
13
13
|
| {
|
|
14
14
|
textField: false;
|
|
15
|
-
|
|
15
|
+
children?: ReactNode;
|
|
16
16
|
}
|
|
17
17
|
) & {
|
|
18
18
|
title?: string;
|
|
@@ -84,10 +84,9 @@ export function SecondaryPage(props: PropTypes) {
|
|
|
84
84
|
</div>
|
|
85
85
|
)}
|
|
86
86
|
<ContentContainer>
|
|
87
|
-
{props.textField &&
|
|
88
|
-
{!props.textField && props.
|
|
87
|
+
{props.textField && props.children?.(searchedFor)}
|
|
88
|
+
{!props.textField && props.children}
|
|
89
89
|
</ContentContainer>
|
|
90
|
-
|
|
91
90
|
{Footer}
|
|
92
91
|
</Container>
|
|
93
92
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { PropsWithChildren, useEffect, useState } from 'react';
|
|
2
|
-
import { SelectableWallet } from '../../containers/ConfirmWallets/types';
|
|
3
2
|
import { styled } from '../../theme';
|
|
3
|
+
import { SelectableWallet } from '../../types';
|
|
4
4
|
import { Typography } from '../Typography';
|
|
5
5
|
|
|
6
6
|
const Row = styled('div', {
|
|
@@ -14,10 +14,12 @@ const BaseContainer = styled('div', {
|
|
|
14
14
|
padding: '$16',
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
+
const Title = styled(Typography, { marginBottom: '$16' });
|
|
18
|
+
|
|
17
19
|
const SlippageChipsContainer = styled('div', {
|
|
18
|
-
display: '
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
display: 'grid',
|
|
21
|
+
rowGap: '$16',
|
|
22
|
+
gridTemplateColumns: 'repeat(auto-fill, 64px)',
|
|
21
23
|
});
|
|
22
24
|
|
|
23
25
|
const LiquiditySourceContainer = styled(BaseContainer, {
|
|
@@ -27,7 +29,7 @@ const LiquiditySourceContainer = styled(BaseContainer, {
|
|
|
27
29
|
cursor: 'pointer',
|
|
28
30
|
});
|
|
29
31
|
|
|
30
|
-
const StyledAngleRight = styled(AngleRightIcon, { marginLeft: '
|
|
32
|
+
const StyledAngleRight = styled(AngleRightIcon, { marginLeft: '$8' });
|
|
31
33
|
|
|
32
34
|
const LiquiditySourceNumber = styled('div', {
|
|
33
35
|
display: 'flex',
|
|
@@ -85,7 +87,7 @@ export function Settings(props: PropTypes) {
|
|
|
85
87
|
const PageContent = (
|
|
86
88
|
<>
|
|
87
89
|
<BaseContainer>
|
|
88
|
-
<
|
|
90
|
+
<Title variant="body1">Slippage tolerance per swap</Title>
|
|
89
91
|
<SlippageChipsContainer>
|
|
90
92
|
{slippages.map((slippage, index) => (
|
|
91
93
|
<Chip
|
|
@@ -126,7 +128,7 @@ export function Settings(props: PropTypes) {
|
|
|
126
128
|
</SlippageChipsContainer>
|
|
127
129
|
</BaseContainer>
|
|
128
130
|
<ThemesContainer>
|
|
129
|
-
<
|
|
131
|
+
<Title variant="body2">Theme</Title>
|
|
130
132
|
<Radio
|
|
131
133
|
defaultValue={selectedTheme}
|
|
132
134
|
options={[
|
|
@@ -141,7 +143,7 @@ export function Settings(props: PropTypes) {
|
|
|
141
143
|
</ThemesContainer>
|
|
142
144
|
<LiquiditySourceContainer onClick={onLiquiditySourcesClick}>
|
|
143
145
|
<Typography variant="body1">Liquidity Sources</Typography>
|
|
144
|
-
<LiquiditySourceNumber
|
|
146
|
+
<LiquiditySourceNumber>
|
|
145
147
|
<Typography variant="body2">{`( ${selectedLiquiditySources.length} / ${liquiditySources.length} )`}</Typography>
|
|
146
148
|
<StyledAngleRight />
|
|
147
149
|
</LiquiditySourceNumber>
|
|
@@ -150,11 +152,8 @@ export function Settings(props: PropTypes) {
|
|
|
150
152
|
);
|
|
151
153
|
|
|
152
154
|
return (
|
|
153
|
-
<SecondaryPage
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
Content={PageContent}
|
|
157
|
-
onBack={onBack}
|
|
158
|
-
/>
|
|
155
|
+
<SecondaryPage title="Settings" textField={false} onBack={onBack}>
|
|
156
|
+
{PageContent}
|
|
157
|
+
</SecondaryPage>
|
|
159
158
|
);
|
|
160
159
|
}
|
|
@@ -33,7 +33,8 @@ export function TokenSelector(props: PropTypes) {
|
|
|
33
33
|
title={`Select ${type} Token`}
|
|
34
34
|
hasHeader={hasHeader}
|
|
35
35
|
onBack={onBack}
|
|
36
|
-
|
|
36
|
+
>
|
|
37
|
+
{(searchedFor) => (
|
|
37
38
|
<TokenList
|
|
38
39
|
searchedText={searchedFor}
|
|
39
40
|
list={list}
|
|
@@ -43,6 +44,6 @@ export function TokenSelector(props: PropTypes) {
|
|
|
43
44
|
onChange={onChange}
|
|
44
45
|
/>
|
|
45
46
|
)}
|
|
46
|
-
|
|
47
|
+
</SecondaryPage>
|
|
47
48
|
);
|
|
48
49
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BestRouteResponse } from 'rango-sdk';
|
|
2
|
-
import React, { Fragment, PropsWithChildren } from 'react';
|
|
2
|
+
import React, { Fragment, PropsWithChildren, ReactNode } from 'react';
|
|
3
3
|
import { Alert } from '../../components/Alert';
|
|
4
4
|
import { Button } from '../../components/Button';
|
|
5
5
|
import { RetryIcon, GasIcon } from '../../components/Icon';
|
|
@@ -8,6 +8,10 @@ import { StepDetail } from '../../components/StepDetail';
|
|
|
8
8
|
import { Typography } from '../../components/Typography';
|
|
9
9
|
import { styled } from '../../theme';
|
|
10
10
|
|
|
11
|
+
const MainContainer = styled('div', {
|
|
12
|
+
overflow: 'hidden',
|
|
13
|
+
});
|
|
14
|
+
|
|
11
15
|
export const Line = styled('div', {
|
|
12
16
|
width: '0',
|
|
13
17
|
marginLeft: '$12',
|
|
@@ -68,24 +72,38 @@ export const StyledUpdateIcon = styled(UpdateIcon, {
|
|
|
68
72
|
cursor: 'pointer',
|
|
69
73
|
});
|
|
70
74
|
|
|
75
|
+
const BestRouteContainer = styled('div', {
|
|
76
|
+
overflow: 'auto',
|
|
77
|
+
});
|
|
78
|
+
|
|
71
79
|
const Alerts = styled('div', { paddingBottom: '$16' });
|
|
72
80
|
|
|
73
81
|
export interface PropTypes {
|
|
74
82
|
bestRoute: BestRouteResponse | null;
|
|
83
|
+
onRefresh?: React.MouseEventHandler<SVGElement>;
|
|
84
|
+
confirmButtonTitle: string;
|
|
85
|
+
confirmButtonDisabled: boolean;
|
|
75
86
|
onBack: () => void;
|
|
76
87
|
onConfirm?: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
|
77
88
|
loading?: boolean;
|
|
78
|
-
|
|
79
|
-
|
|
89
|
+
errors?: ReactNode[];
|
|
90
|
+
warnings?: ReactNode[];
|
|
91
|
+
extraMessages?: ReactNode;
|
|
80
92
|
}
|
|
81
|
-
export function ConfirmSwap({
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
93
|
+
export function ConfirmSwap(props: PropsWithChildren<PropTypes>) {
|
|
94
|
+
const {
|
|
95
|
+
bestRoute,
|
|
96
|
+
onRefresh,
|
|
97
|
+
onBack,
|
|
98
|
+
onConfirm,
|
|
99
|
+
loading,
|
|
100
|
+
errors,
|
|
101
|
+
warnings,
|
|
102
|
+
extraMessages,
|
|
103
|
+
confirmButtonTitle,
|
|
104
|
+
confirmButtonDisabled,
|
|
105
|
+
} = props;
|
|
106
|
+
|
|
89
107
|
return (
|
|
90
108
|
<SecondaryPage
|
|
91
109
|
textField={false}
|
|
@@ -99,56 +117,76 @@ export function ConfirmSwap({
|
|
|
99
117
|
loading={loading}
|
|
100
118
|
variant="contained"
|
|
101
119
|
onClick={onConfirm}
|
|
120
|
+
disabled={confirmButtonDisabled}
|
|
102
121
|
>
|
|
103
|
-
|
|
122
|
+
{confirmButtonTitle}
|
|
104
123
|
</Button>
|
|
105
124
|
</Footer>
|
|
106
125
|
}
|
|
107
|
-
|
|
108
|
-
|
|
126
|
+
TopButton={<StyledUpdateIcon size={24} onClick={onRefresh} />}
|
|
127
|
+
>
|
|
128
|
+
<MainContainer>
|
|
129
|
+
<div>
|
|
130
|
+
{extraMessages || null}
|
|
109
131
|
<Alerts>
|
|
110
|
-
{error
|
|
111
|
-
|
|
132
|
+
{errors?.map((error, index) => (
|
|
133
|
+
<Alert type="error" key={index}>
|
|
134
|
+
{error}
|
|
135
|
+
</Alert>
|
|
136
|
+
))}
|
|
137
|
+
{/* {error && warnings && <Spacer direction="vertical" size={16} />} */}
|
|
138
|
+
{warnings?.map((warning, index) => (
|
|
139
|
+
<Alert type="warning" key={index}>
|
|
140
|
+
{warning}
|
|
141
|
+
</Alert>
|
|
142
|
+
))}
|
|
112
143
|
</Alerts>
|
|
113
|
-
|
|
114
|
-
|
|
144
|
+
</div>
|
|
145
|
+
<BestRouteContainer>
|
|
146
|
+
{bestRoute?.result?.swaps.map((swap, index) => (
|
|
147
|
+
<Fragment key={index}>
|
|
148
|
+
{index === 0 && (
|
|
149
|
+
<RelativeContainer>
|
|
150
|
+
<StepDetail
|
|
151
|
+
logo={swap.from.logo}
|
|
152
|
+
symbol={swap.from.symbol}
|
|
153
|
+
chainLogo={swap.from.blockchainLogo}
|
|
154
|
+
blockchain={swap.from.blockchain}
|
|
155
|
+
amount={swap.fromAmount}
|
|
156
|
+
/>
|
|
157
|
+
<Dot />
|
|
158
|
+
</RelativeContainer>
|
|
159
|
+
)}
|
|
160
|
+
<Line />
|
|
161
|
+
<SwapperContainer>
|
|
162
|
+
<SwapperLogo src={swap.swapperLogo} alt={swap.swapperId} />
|
|
163
|
+
<div>
|
|
164
|
+
<Typography ml={4} variant="caption">
|
|
165
|
+
{swap.swapperType} from {swap.from.symbol} to{' '}
|
|
166
|
+
{swap.to.symbol} via {swap.swapperId}{' '}
|
|
167
|
+
</Typography>
|
|
168
|
+
<Fee>
|
|
169
|
+
<GasIcon />
|
|
170
|
+
<Typography ml={4} variant="caption">
|
|
171
|
+
{parseFloat(swap.fee[0].amount).toFixed(6)} estimated gas
|
|
172
|
+
fee
|
|
173
|
+
</Typography>
|
|
174
|
+
</Fee>
|
|
175
|
+
</div>
|
|
176
|
+
</SwapperContainer>
|
|
177
|
+
<Line />
|
|
178
|
+
{index + 1 === bestRoute.result?.swaps.length && <ArrowDown />}
|
|
115
179
|
<StepDetail
|
|
116
|
-
logo={swap.
|
|
117
|
-
symbol={swap.
|
|
118
|
-
chainLogo={swap.
|
|
119
|
-
blockchain={swap.
|
|
120
|
-
amount={swap.
|
|
180
|
+
logo={swap.to.logo}
|
|
181
|
+
symbol={swap.to.symbol}
|
|
182
|
+
chainLogo={swap.to.blockchainLogo}
|
|
183
|
+
blockchain={swap.to.blockchain}
|
|
184
|
+
amount={swap.toAmount}
|
|
121
185
|
/>
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
<SwapperLogo src={swap.swapperLogo} alt={swap.swapperId} />
|
|
128
|
-
<div>
|
|
129
|
-
<Typography ml={4} variant="caption">
|
|
130
|
-
{swap.swapperType} from {swap.from.symbol} to {swap.to.symbol}{' '}
|
|
131
|
-
via {swap.swapperId}{' '}
|
|
132
|
-
</Typography>
|
|
133
|
-
<Fee>
|
|
134
|
-
<GasIcon />
|
|
135
|
-
<Typography ml={4} variant="caption">
|
|
136
|
-
{parseFloat(swap.fee[0].amount).toFixed(6)} estimated gas fee
|
|
137
|
-
</Typography>
|
|
138
|
-
</Fee>
|
|
139
|
-
</div>
|
|
140
|
-
</SwapperContainer>
|
|
141
|
-
<Line />
|
|
142
|
-
{index + 1 === bestRoute.result?.swaps.length && <ArrowDown />}
|
|
143
|
-
<StepDetail
|
|
144
|
-
logo={swap.to.logo}
|
|
145
|
-
symbol={swap.to.symbol}
|
|
146
|
-
chainLogo={swap.to.blockchainLogo}
|
|
147
|
-
blockchain={swap.to.blockchain}
|
|
148
|
-
amount={swap.toAmount}
|
|
149
|
-
/>
|
|
150
|
-
</Fragment>
|
|
151
|
-
))}
|
|
152
|
-
/>
|
|
186
|
+
</Fragment>
|
|
187
|
+
))}
|
|
188
|
+
</BestRouteContainer>
|
|
189
|
+
</MainContainer>
|
|
190
|
+
</SecondaryPage>
|
|
153
191
|
);
|
|
154
192
|
}
|