@@ -26,6 +26,259 @@ export const SingleRoute: FC<{ trade: TradeOutput }> = ({ trade }) => {
26
26
return (
27
27
< div className = "relative flex items-center justify-between gap-1" >
28
28
< div className = "absolute inset-0 left-1 right-1 text-slate-600 pointer-events-none z-[-1]" >
29
-
29
+ < svg
30
+ width = "100%"
31
+ height = "35"
32
+ viewBox = "850 0 300 200"
33
+ xmlns = "http://www.w3.org/2000/svg"
34
+ className = "sc-o1ook0-5 iESzev"
35
+ >
36
+ < line
37
+ x1 = "0"
38
+ x2 = "3000"
39
+ y1 = "100"
40
+ y2 = "100"
41
+ stroke = "currentColor"
42
+ strokeWidth = "20"
43
+ strokeLinecap = "round"
44
+ strokeDasharray = "1, 45"
45
+ />
46
+ </ svg >
47
+ </ div >
48
+ < Typography
49
+ weight = { 600 }
50
+ variant = "sm"
51
+ className = "py-1 px-1.5 flex items-center gap-1 bg-slate-700 rounded-lg overflow-hidden"
52
+ >
53
+ 100%
54
+ </ Typography >
55
+ { trade . route . legs . map ( ( leg , i ) => (
56
+ < Tooltip
57
+ key = { i }
58
+ mouseEnterDelay = { 0.4 }
59
+ button = {
30
60
< div
61
+ key = { i }
62
+ className = "py-1 px-1.5 flex items-center gap-1.5 bg-slate-700 cursor-pointer hover:bg-slate-600 rounded-lg overflow-hidden"
63
+ >
64
+ < Currency . Icon currency = { tokenFromRToken ( leg . tokenFrom ) } width = { 20 } height = { 20 } />
65
+ { legs < 3 ? (
66
+ < Typography variant = "sm" weight = { 600 } className = "py-0.5" >
67
+ { leg . poolFee * 100 } %
68
+ </ Typography >
69
+ ) : (
70
+ < > </ >
71
+ ) }
72
+ </ div >
73
+ }
74
+ panel = {
75
+ < div className = "flex flex-col gap-2" >
76
+ < div className = "flex items-center" >
77
+ < Currency . IconList iconWidth = { 20 } iconHeight = { 20 } >
78
+ < Currency . Icon currency = { tokenFromRToken ( leg . tokenFrom ) } />
79
+ < Currency . Icon currency = { tokenFromRToken ( leg . tokenTo ) } />
80
+ </ Currency . IconList >
81
+ < Typography variant = "sm" weight = { 600 } className = "flex gap-1 text-slate-50" >
82
+ { leg . tokenFrom . symbol } < span className = "text-slate-500" > /</ span > { leg . tokenTo . symbol }
83
+ </ Typography >
84
+ < Link . External href = { chains [ trade . inputAmount . currency . chainId ] . getTokenUrl ( leg . poolAddress ) } >
85
+ < div className = "pl-1 -mt-0.5" >
86
+ < ExternalLinkIcon className = "text-blue hover:text-blue-400" width = { 18 } height = { 18 } />
87
+ </ div >
88
+ </ Link . External >
89
+ </ div >
90
+ < Typography variant = "xs" weight = { 600 } className = "flex gap-1.5 items-end text-slate-400" >
91
+ < Chip color = "gray" size = "sm" label = { leg . poolType } />
92
+ < Chip color = "gray" size = "sm" label = { `Fee ${ leg . poolFee * 100 } %` } />
93
+ </ Typography >
94
+ </ div >
95
+ }
96
+ />
97
+ ) ) }
98
+ < div className = "w-6 h-6" >
99
+ < Currency . Icon currency = { trade . outputAmount . currency } width = { 24 } height = { 24 } />
100
+ </ div >
101
+ </ div >
102
+ )
103
+ }
104
+
105
+ // Can render a tines multi route
106
+ export const ComplexRoute : FC < { trade : TradeOutput } > = ( { trade } ) => {
107
+ if ( ! trade ) return < > </ >
108
+
109
+ const directPaths = trade . route . legs . filter (
110
+ ( leg ) =>
111
+ leg . tokenFrom . address === trade . inputAmount . currency . wrapped . address &&
112
+ leg . tokenTo . address === trade . outputAmount . currency . wrapped . address
113
+ )
114
+
115
+ const initialPaths = trade . route . legs . filter (
116
+ ( leg ) =>
117
+ leg . tokenFrom . address === trade . inputAmount . currency . wrapped . address &&
118
+ leg . tokenTo . address !== trade . outputAmount . currency . wrapped . address
119
+ )
120
+
121
+ // TODO: Seperate into groups of tokenFrom
122
+ const percentPaths = trade . route . legs . filter (
123
+ ( leg ) =>
124
+ leg . tokenFrom . address !== trade . inputAmount . currency . wrapped . address &&
125
+ leg . tokenTo . address !== trade . outputAmount . currency . wrapped . address
126
+ )
127
+
128
+ const finalPaths = trade . route . legs . filter (
129
+ ( leg ) =>
130
+ leg . tokenFrom . address !== trade . inputAmount . currency . wrapped . address &&
131
+ leg . tokenTo . address === trade . outputAmount . currency . wrapped . address
132
+ )
133
+
134
+ return (
135
+ < div className = "h-full" >
136
+ < div className = "flex flex-col gap-4" >
137
+ { directPaths . map ( ( directPath , i ) => (
138
+ < ComplexRoutePath
139
+ key = { i }
140
+ fromToken = { tokenFromRToken ( directPath . tokenFrom ) }
141
+ toToken = { tokenFromRToken ( directPath . tokenTo ) }
142
+ poolType = { directPath . poolType }
143
+ poolFee = { directPath . poolFee }
144
+ portion = { directPath . absolutePortion }
145
+ />
146
+ ) ) }
147
+ { initialPaths . map ( ( initialPath , i ) => (
148
+ < ComplexRoutePath
149
+ key = { i }
150
+ fromToken = { tokenFromRToken ( initialPath . tokenFrom ) }
151
+ toToken = { tokenFromRToken ( initialPath . tokenTo ) }
152
+ poolType = { initialPath . poolType }
153
+ poolFee = { initialPath . poolFee }
154
+ portion = { initialPath . absolutePortion }
155
+ />
156
+ ) ) }
157
+ { percentPaths . map ( ( percentagePath , i ) => (
158
+ < ComplexRoutePath
159
+ key = { i }
160
+ fromToken = { tokenFromRToken ( percentagePath . tokenFrom ) }
161
+ toToken = { tokenFromRToken ( percentagePath . tokenTo ) }
162
+ poolType = { percentagePath . poolType }
163
+ poolFee = { percentagePath . poolFee }
164
+ portion = { percentagePath . absolutePortion }
165
+ />
166
+ ) ) }
167
+ { finalPaths . map ( ( finalPath , i ) => (
168
+ < ComplexRoutePath
169
+ key = { i }
170
+ fromToken = { tokenFromRToken ( finalPath . tokenFrom ) }
171
+ toToken = { tokenFromRToken ( finalPath . tokenTo ) }
172
+ poolType = { finalPath . poolType }
173
+ poolFee = { finalPath . poolFee }
174
+ portion = { finalPath . absolutePortion }
175
+ />
176
+ ) ) }
177
+ </ div >
178
+ </ div >
179
+ )
180
+ }
31
181
182
+ export const Route : FC = ( ) => {
183
+ const { trade } = useTrade ( )
184
+ if ( ! trade ) return < > </ >
185
+
186
+ return (
187
+ < AppearOnMount >
188
+ { trade . isSingle ( ) && < SingleRoute trade = { trade } /> }
189
+ { trade . isComplex ( ) && < ComplexRoute trade = { trade } /> }
190
+ < div className = "flex flex-col gap-4" >
191
+ { /* {trade.isComplex() && (
192
+ <Tooltip
193
+ panel={<div className="flex flex-col gap-1">{<ComplexRoute trade={trade} /> }</div> }
194
+ button={
195
+ <Typography variant="sm" weight={500} className="text-right cursor-pointer text-blue">
196
+ View Route
197
+ </Typography>
198
+ }
199
+ />
200
+ )} */ }
201
+ { /* <Typography variant="xs" className="mx-auto text-slate-300">
202
+ Tines Optimized Route
203
+ </Typography> */ }
204
+ </ div >
205
+ </ AppearOnMount >
206
+ )
207
+ }
208
+
209
+ interface ComplexRoutePathProps {
210
+ fromToken : Token
211
+ toToken : Token
212
+ poolType : 'Stable' | 'Classic' | 'Unknown'
213
+ poolFee : number
214
+ portion : number
215
+ }
216
+
217
+ const ComplexRoutePath : FC < ComplexRoutePathProps > = ( { fromToken, toToken, poolType, poolFee, portion } ) => {
218
+ const ref = useRef < HTMLDivElement > ( null )
219
+ const [ width , setWidth ] = useState ( 0 )
220
+
221
+ useEffect ( ( ) => {
222
+ if ( ref . current ) {
223
+ setWidth ( ( ref . current . offsetWidth - 28 ) * Number ( portion ) )
224
+ }
225
+ } , [ portion ] )
226
+
227
+ return (
228
+ < div className = "relative grid grid-cols-10" >
229
+ < div className = "absolute inset-0 z-0 flex items-center pointer-events-none" >
230
+ < svg viewBox = "850 0 300 200" width = "100%" height = "35" className = "text-slate-700" >
231
+ < line
232
+ x1 = "0"
233
+ x2 = "3000"
234
+ y1 = "100"
235
+ y2 = "100"
236
+ stroke = "currentColor"
237
+ strokeWidth = "20"
238
+ strokeLinecap = "round"
239
+ strokeDasharray = "1, 45"
240
+ />
241
+ </ svg >
242
+ </ div >
243
+ < div className = "z-[10] col-span-4 flex justify-start items-center" >
244
+ < div
245
+ ref = { ref }
246
+ className = "relative flex items-center justify-between gap-2 p-2 overflow-hidden border-2 rounded-full border-slate-900 bg-slate-900"
247
+ >
248
+ < div
249
+ className = "absolute inset-0 rounded-full pointer-events-none bg-slate-800"
250
+ style = { { width : `calc(28px + ${ width } px)` } }
251
+ />
252
+ < div className = "z-[10] flex items-center gap-1" >
253
+ < Currency . Icon disableLink currency = { fromToken } width = { 16 } height = { 16 } />
254
+ < Typography variant = "xs" weight = { 600 } className = "text-slate-200" >
255
+ { fromToken . symbol }
256
+ </ Typography >
257
+ </ div >
258
+ < Typography variant = "xs" weight = { 600 } className = "z-[10] text-slate-400" >
259
+ { Number ( portion * 100 ) . toFixed ( 2 ) } %
260
+ </ Typography >
261
+ </ div >
262
+ </ div >
263
+ < div className = "z-[10] col-span-3 flex justify-center items-center" >
264
+ < Typography
265
+ variant = "xs"
266
+ weight = { 500 }
267
+ className = "bg-slate-800 text-slate-200 flex items-center border border-slate-200/10 rounded-lg h-[36px] px-2"
268
+ >
269
+ { poolType } { Number ( poolFee * 100 ) . toFixed ( 2 ) } %
270
+ </ Typography >
271
+ </ div >
272
+ < div className = "z-[10] col-span-3 flex justify-end items-center" >
273
+ < div className = "p-0.5 rounded-full bg-slate-900" >
274
+ < div className = "px-2 bg-slate-700 h-[36px] rounded-full flex items-center gap-1" >
275
+ < Currency . Icon disableLink currency = { toToken } width = { 16 } height = { 16 } />
276
+ < Typography variant = "xs" weight = { 600 } className = "text-slate-200" >
277
+ { toToken . symbol }
278
+ </ Typography >
279
+ </ div >
280
+ </ div >
281
+ </ div >
282
+ </ div >
283
+ )
284
+ }
0 commit comments