@rango-dev/widget-embedded 0.24.2-next.5 → 0.24.2-next.7

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.
Files changed (55) hide show
  1. package/dist/components/HeaderButtons/HeaderButtons.d.ts.map +1 -1
  2. package/dist/components/HeaderButtons/HeaderButtons.types.d.ts +1 -0
  3. package/dist/components/HeaderButtons/HeaderButtons.types.d.ts.map +1 -1
  4. package/dist/components/Quote/Quote.d.ts.map +1 -1
  5. package/dist/components/Quote/Quote.types.d.ts +3 -0
  6. package/dist/components/Quote/Quote.types.d.ts.map +1 -1
  7. package/dist/components/Quote/QuoteTrigger.d.ts.map +1 -1
  8. package/dist/components/Quotes/Quotes.d.ts.map +1 -1
  9. package/dist/components/Quotes/Quotes.types.d.ts +1 -0
  10. package/dist/components/Quotes/Quotes.types.d.ts.map +1 -1
  11. package/dist/components/SwapDetails/SwapDetails.d.ts.map +1 -1
  12. package/dist/components/SwapDetails/SwapDetails.helpers.d.ts.map +1 -1
  13. package/dist/components/SwapDetails/SwapDetails.styles.d.ts +325 -0
  14. package/dist/components/SwapDetails/SwapDetails.styles.d.ts.map +1 -1
  15. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.Failed.d.ts.map +1 -1
  16. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.styles.d.ts +328 -0
  17. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.styles.d.ts.map +1 -1
  18. package/dist/components/SwapDetailsModal/SwapDetailsModal.styles.d.ts +162 -0
  19. package/dist/components/SwapDetailsModal/SwapDetailsModal.styles.d.ts.map +1 -1
  20. package/dist/components/SwapDetailsModal/SwapDetailsModal.types.d.ts +2 -1
  21. package/dist/components/SwapDetailsModal/SwapDetailsModal.types.d.ts.map +1 -1
  22. package/dist/containers/ExpandedQuotes/ExpandedQuotes.d.ts.map +1 -1
  23. package/dist/containers/QuoteInfo/QuoteInfo.d.ts.map +1 -1
  24. package/dist/containers/QuoteInfo/QuoteInfo.styles.d.ts +3 -1
  25. package/dist/containers/QuoteInfo/QuoteInfo.styles.d.ts.map +1 -1
  26. package/dist/containers/QuoteInfo/QuoteInfo.types.d.ts +1 -0
  27. package/dist/containers/QuoteInfo/QuoteInfo.types.d.ts.map +1 -1
  28. package/dist/hooks/useWalletList.d.ts.map +1 -1
  29. package/dist/index.js +2 -2
  30. package/dist/index.js.map +4 -4
  31. package/dist/pages/WalletsPage.d.ts.map +1 -1
  32. package/dist/utils/wallets.d.ts.map +1 -1
  33. package/package.json +2 -2
  34. package/src/components/HeaderButtons/HeaderButtons.tsx +2 -1
  35. package/src/components/HeaderButtons/HeaderButtons.types.ts +1 -0
  36. package/src/components/Quote/Quote.tsx +95 -74
  37. package/src/components/Quote/Quote.types.ts +3 -0
  38. package/src/components/Quote/QuoteTrigger.tsx +10 -6
  39. package/src/components/Quotes/Quotes.tsx +4 -1
  40. package/src/components/Quotes/Quotes.types.ts +1 -0
  41. package/src/components/SwapDetails/SwapDetails.helpers.tsx +16 -10
  42. package/src/components/SwapDetails/SwapDetails.styles.ts +10 -1
  43. package/src/components/SwapDetails/SwapDetails.tsx +44 -23
  44. package/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Failed.tsx +19 -11
  45. package/src/components/SwapDetailsAlerts/SwapDetailsAlerts.styles.ts +24 -0
  46. package/src/components/SwapDetailsModal/SwapDetailsModal.styles.ts +8 -0
  47. package/src/components/SwapDetailsModal/SwapDetailsModal.types.ts +1 -1
  48. package/src/containers/ExpandedQuotes/ExpandedQuotes.tsx +4 -2
  49. package/src/containers/QuoteInfo/QuoteInfo.styles.ts +7 -0
  50. package/src/containers/QuoteInfo/QuoteInfo.tsx +2 -0
  51. package/src/containers/QuoteInfo/QuoteInfo.types.ts +1 -0
  52. package/src/containers/Settings/Lists.tsx +12 -12
  53. package/src/hooks/useWalletList.ts +8 -1
  54. package/src/pages/WalletsPage.tsx +1 -2
  55. package/src/utils/wallets.ts +7 -1
@@ -1 +1 @@
1
- {"version":3,"file":"WalletsPage.d.ts","sourceRoot":"","sources":["../../src/pages/WalletsPage.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAuBxC,eAAO,MAAM,mBAAmB,OAAQ,CAAC;AACzC,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,wBAAgB,WAAW,sBA0E1B"}
1
+ {"version":3,"file":"WalletsPage.d.ts","sourceRoot":"","sources":["../../src/pages/WalletsPage.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAsBxC,eAAO,MAAM,mBAAmB,OAAQ,CAAC;AACzC,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,wBAAgB,WAAW,sBA0E1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"wallets.d.ts","sourceRoot":"","sources":["../../src/utils/wallets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wallets.d.ts","sourceRoot":"","sources":["../../src/utils/wallets.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/widget-embedded",
3
- "version": "0.24.2-next.5",
3
+ "version": "0.24.2-next.7",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "source": "./src/index.ts",
@@ -26,7 +26,7 @@
26
26
  "@rango-dev/queue-manager-core": "^0.26.0",
27
27
  "@rango-dev/queue-manager-rango-preset": "^0.29.2-next.1",
28
28
  "@rango-dev/queue-manager-react": "^0.26.0",
29
- "@rango-dev/ui": "^0.30.1-next.1",
29
+ "@rango-dev/ui": "^0.30.1-next.3",
30
30
  "@rango-dev/wallets-react": "^0.15.1-next.0",
31
31
  "@rango-dev/wallets-shared": "^0.29.1-next.0",
32
32
  "bignumber.js": "^9.1.1",
@@ -26,6 +26,7 @@ export function HeaderButtons(props: HeaderButtonsPropTypes) {
26
26
  onClickHistory,
27
27
  onClickSettings,
28
28
  hidden = [],
29
+ container,
29
30
  } = props;
30
31
 
31
32
  const {
@@ -40,7 +41,7 @@ export function HeaderButtons(props: HeaderButtonsPropTypes) {
40
41
  <>
41
42
  {!hidden.includes('refresh') && (
42
43
  <Tooltip
43
- container={getContainer()}
44
+ container={container || getContainer()}
44
45
  side="top"
45
46
  content={i18n.t('Refresh')}>
46
47
  <RefreshButton onClick={onClickRefresh} />
@@ -8,4 +8,5 @@ export interface HeaderButtonsPropTypes {
8
8
  onClickRefresh?: () => void;
9
9
  onClickHistory?: () => void;
10
10
  hidden?: ('settings' | 'refresh' | 'history' | 'notifications')[];
11
+ container?: HTMLElement;
11
12
  }
@@ -50,7 +50,7 @@ import {
50
50
  getPriceImpactLevel,
51
51
  sortTags,
52
52
  } from '../../utils/quote';
53
- import { getTotalFeeInUsd } from '../../utils/swap';
53
+ import { getTotalFeeInUsd, getUsdFeeOfStep } from '../../utils/swap';
54
54
 
55
55
  import {
56
56
  AllRoutesButton,
@@ -85,6 +85,7 @@ export function Quote(props: QuoteProps) {
85
85
  showModalFee = true,
86
86
  onClickAllRoutes,
87
87
  fullExpandedMode = false,
88
+ container: propContainer,
88
89
  } = props;
89
90
  const blockchains = useAppStore().blockchains();
90
91
  const tokens = useAppStore().tokens();
@@ -116,18 +117,27 @@ export function Quote(props: QuoteProps) {
116
117
  );
117
118
  const priceImpactWarningLevel = getPriceImpactLevel(priceImpact ?? 0);
118
119
 
119
- const getQuoteSteps = (swaps: SwapResult[]): Step[] => {
120
+ const getQuoteSteps = (
121
+ swaps: SwapResult[],
122
+ internalSwap?: boolean
123
+ ): Step[] => {
120
124
  return swaps.map((swap, index) => {
121
125
  let stepState: 'error' | 'warning' | undefined = undefined;
122
- const stepHasError =
123
- (error?.type === QuoteErrorType.BRIDGE_LIMIT &&
124
- error.swap.swapperId === swap.swapperId) ||
125
- (error?.type === QuoteErrorType.INSUFFICIENT_SLIPPAGE &&
126
- error.recommendedSlippages?.has(index));
127
- const stepHasWarning =
126
+ const hasBridgeLimitError =
127
+ error?.type === QuoteErrorType.BRIDGE_LIMIT &&
128
+ error.swap.swapperId === swap.swapperId;
129
+
130
+ const hasSlippageError =
131
+ error?.type === QuoteErrorType.INSUFFICIENT_SLIPPAGE &&
132
+ error.recommendedSlippages?.has(index);
133
+
134
+ const hasSlippageWarning =
128
135
  warning?.type === QuoteWarningType.INSUFFICIENT_SLIPPAGE &&
129
136
  warning.recommendedSlippages?.has(index);
130
137
 
138
+ const stepHasError = hasBridgeLimitError || hasSlippageError;
139
+ const stepHasWarning = hasSlippageWarning;
140
+
131
141
  if (stepHasError) {
132
142
  stepState = 'error';
133
143
  } else if (stepHasWarning) {
@@ -138,7 +148,7 @@ export function Quote(props: QuoteProps) {
138
148
  ? i18n.t('Slippage Error')
139
149
  : i18n.t('Slippage Warning');
140
150
 
141
- if (error?.type === QuoteErrorType.BRIDGE_LIMIT) {
151
+ if (hasBridgeLimitError) {
142
152
  alertTitle = error?.recommendation;
143
153
  }
144
154
 
@@ -158,7 +168,7 @@ export function Quote(props: QuoteProps) {
158
168
  },
159
169
  price: {
160
170
  value:
161
- index === 0
171
+ index === 0 && !internalSwap
162
172
  ? numberToString(
163
173
  input.value,
164
174
  TOKEN_AMOUNT_MIN_DECIMALS,
@@ -213,83 +223,93 @@ export function Quote(props: QuoteProps) {
213
223
  state: stepState,
214
224
  alerts:
215
225
  stepHasError || stepHasWarning ? (
216
- <FooterStepAlarm>
226
+ <FooterStepAlarm dense={fullExpandedMode}>
217
227
  <Alert
218
228
  variant="alarm"
219
229
  type={stepHasError ? 'error' : 'warning'}
220
230
  title={alertTitle}
221
231
  footer={
222
- <FooterAlert>
223
- {error?.type === QuoteErrorType.BRIDGE_LIMIT && (
224
- <>
225
- <Typography
226
- size="xsmall"
227
- variant="body"
228
- color="neutral900">
229
- {error.fromAmountRangeError}
230
- </Typography>
231
- <Divider direction="horizontal" size={8} />
232
- <Typography
233
- size="xsmall"
234
- variant="body"
235
- color="neutral900">
236
- |
237
- </Typography>
238
- <Divider direction="horizontal" size={8} />
239
- <Typography
240
- size="xsmall"
241
- variant="body"
242
- color="neutral900">
243
- {i18n.t({
244
- id: 'Yours: {amount} {symbol}',
245
- values: {
246
- amount: numberToString(
247
- swap.fromAmount,
248
- TOKEN_AMOUNT_MIN_DECIMALS,
249
- TOKEN_AMOUNT_MAX_DECIMALS
250
- ),
251
- symbol: swap?.from.symbol,
252
- },
253
- })}
254
- </Typography>
255
- </>
256
- )}
257
- {(error?.type === QuoteErrorType.INSUFFICIENT_SLIPPAGE ||
258
- warning?.type ===
259
- QuoteWarningType.INSUFFICIENT_SLIPPAGE) && (
260
- <Typography
261
- size="xsmall"
262
- variant="body"
263
- color="neutral900">
264
- {i18n.t({
265
- id: 'Minimum required slippage is {minRequiredSlippage}',
266
- values: {
267
- ...(error?.type ===
268
- QuoteErrorType.INSUFFICIENT_SLIPPAGE && {
269
- minRequiredSlippage:
270
- error.recommendedSlippages?.get(index),
271
- }),
272
- ...(warning?.type ===
273
- QuoteWarningType.INSUFFICIENT_SLIPPAGE && {
274
- minRequiredSlippage:
275
- warning.recommendedSlippages?.get(index),
276
- }),
277
- },
278
- })}
279
- </Typography>
280
- )}
281
- </FooterAlert>
232
+ !fullExpandedMode ? (
233
+ <FooterAlert>
234
+ {hasBridgeLimitError && (
235
+ <>
236
+ <Typography
237
+ size="xsmall"
238
+ variant="body"
239
+ color="neutral900">
240
+ {error.fromAmountRangeError}
241
+ </Typography>
242
+ <Divider direction="horizontal" size={8} />
243
+ <Typography
244
+ size="xsmall"
245
+ variant="body"
246
+ color="neutral900">
247
+ |
248
+ </Typography>
249
+ <Divider direction="horizontal" size={8} />
250
+ <Typography
251
+ size="xsmall"
252
+ variant="body"
253
+ color="neutral900">
254
+ {i18n.t({
255
+ id: 'Yours: {amount} {symbol}',
256
+ values: {
257
+ amount: numberToString(
258
+ swap.fromAmount,
259
+ TOKEN_AMOUNT_MIN_DECIMALS,
260
+ TOKEN_AMOUNT_MAX_DECIMALS
261
+ ),
262
+ symbol: swap?.from.symbol,
263
+ },
264
+ })}
265
+ </Typography>
266
+ </>
267
+ )}
268
+ {(hasSlippageError || hasSlippageWarning) &&
269
+ !hasBridgeLimitError && (
270
+ <Typography
271
+ size="xsmall"
272
+ variant="body"
273
+ color="neutral900">
274
+ {i18n.t({
275
+ id: 'Minimum required slippage is {minRequiredSlippage}',
276
+ values: {
277
+ ...(error?.type ===
278
+ QuoteErrorType.INSUFFICIENT_SLIPPAGE && {
279
+ minRequiredSlippage:
280
+ error.recommendedSlippages?.get(index),
281
+ }),
282
+ ...(warning?.type ===
283
+ QuoteWarningType.INSUFFICIENT_SLIPPAGE && {
284
+ minRequiredSlippage:
285
+ warning.recommendedSlippages?.get(index),
286
+ }),
287
+ },
288
+ })}
289
+ </Typography>
290
+ )}
291
+ </FooterAlert>
292
+ ) : null
282
293
  }
283
294
  />
284
295
  </FooterStepAlarm>
285
296
  ) : undefined,
297
+ time: roundedSecondsToString(swap.estimatedTimeInSeconds),
298
+ fee: numberToString(
299
+ getUsdFeeOfStep(swap, tokens),
300
+ GAS_FEE_MIN_DECIMALS,
301
+ GAS_FEE_MAX_DECIMALS
302
+ ),
303
+ internalSwaps: swap.internalSwaps
304
+ ? getQuoteSteps(swap.internalSwaps)
305
+ : undefined,
286
306
  };
287
307
  });
288
308
  };
289
309
  const steps = getQuoteSteps(quote?.swaps ?? []);
290
310
 
291
311
  const numberOfSteps = steps.length;
292
- const container = getContainer();
312
+ const container = propContainer || getContainer();
293
313
  const sortedQuoteTags = sortTags(props.quote.tags || []);
294
314
  const showAllRoutesButton = !!onClickAllRoutes;
295
315
  const totalTime = roundedSecondsToString(totalArrivalTime(quote?.swaps));
@@ -392,8 +412,8 @@ export function Quote(props: QuoteProps) {
392
412
  <Tooltip
393
413
  content={formatTooltipNumbers(output.usdValue)}
394
414
  container={container}
395
- style={{
396
- display: 'flex',
415
+ styles={{
416
+ root: { display: 'flex' },
397
417
  }}>
398
418
  <Typography
399
419
  color="$neutral600"
@@ -448,6 +468,7 @@ export function Quote(props: QuoteProps) {
448
468
  quoteRef={quoteRef}
449
469
  selected={selected}
450
470
  setExpanded={setExpanded}
471
+ container={container}
451
472
  expanded={expanded}
452
473
  steps={steps}
453
474
  />
@@ -15,6 +15,7 @@ export type QuoteProps = {
15
15
  showModalFee?: boolean;
16
16
  onClickAllRoutes?: () => void;
17
17
  fullExpandedMode?: boolean;
18
+ container?: HTMLElement;
18
19
  };
19
20
 
20
21
  export type optionProps = {
@@ -29,6 +30,7 @@ export type QuoteTriggerProps = {
29
30
  setExpanded: React.Dispatch<React.SetStateAction<boolean | undefined>>;
30
31
  steps: Step[];
31
32
  expanded?: boolean;
33
+ container?: HTMLElement;
32
34
  };
33
35
 
34
36
  export type QuoteTriggerImagesProps = {
@@ -37,6 +39,7 @@ export type QuoteTriggerImagesProps = {
37
39
  src: string;
38
40
  open?: boolean;
39
41
  className?: string;
42
+ container?: HTMLElement;
40
43
  };
41
44
 
42
45
  export type QuoteCostDetailsProps = {
@@ -27,8 +27,8 @@ const MAX_STEPS = 4;
27
27
  const MAX_BLOCKCHAINS = 6;
28
28
 
29
29
  const ImageComponent = (props: QuoteTriggerImagesProps) => {
30
- const tooltipContainer = getContainer();
31
- const { content, src, className, open, state } = props;
30
+ const { content, src, className, open, state, container } = props;
31
+ const tooltipContainer = container || getContainer();
32
32
  return (
33
33
  <Tooltip
34
34
  container={tooltipContainer}
@@ -44,8 +44,9 @@ const ImageComponent = (props: QuoteTriggerImagesProps) => {
44
44
  };
45
45
 
46
46
  export function QuoteTrigger(props: QuoteTriggerProps) {
47
- const { quoteRef, selected, setExpanded, steps, expanded, type } = props;
48
- const tooltipContainer = getContainer();
47
+ const { quoteRef, selected, setExpanded, steps, expanded, type, container } =
48
+ props;
49
+ const tooltipContainer = container || getContainer();
49
50
  const numberOfSteps = steps.length;
50
51
  const blockchains = getUniqueBlockchains(steps);
51
52
  const { isTablet, isMobile } = useScreenDetect();
@@ -78,6 +79,7 @@ export function QuoteTrigger(props: QuoteTriggerProps) {
78
79
  content={step.swapper.displayName}
79
80
  src={step.swapper.image}
80
81
  state={step.state}
82
+ container={container}
81
83
  />
82
84
  {index !== numberOfSteps - 1 && <>{arrow}</>}
83
85
  </React.Fragment>
@@ -90,6 +92,7 @@ export function QuoteTrigger(props: QuoteTriggerProps) {
90
92
  content={step.swapper.displayName}
91
93
  src={step.swapper.image}
92
94
  state={step.state}
95
+ container={container}
93
96
  />
94
97
  {index !== numberOfSteps - 1 && <>{arrow}</>}
95
98
  </>
@@ -98,7 +101,7 @@ export function QuoteTrigger(props: QuoteTriggerProps) {
98
101
  <Tooltip
99
102
  container={tooltipContainer}
100
103
  side="bottom"
101
- align="right"
104
+ align="end"
102
105
  sideOffset={4}
103
106
  content={
104
107
  <div className={rowStyles()}>
@@ -169,7 +172,7 @@ export function QuoteTrigger(props: QuoteTriggerProps) {
169
172
  <Tooltip
170
173
  container={tooltipContainer}
171
174
  side="bottom"
172
- align="right"
175
+ align="end"
173
176
  sideOffset={4}
174
177
  content={
175
178
  <div className={rowStyles()}>
@@ -182,6 +185,7 @@ export function QuoteTrigger(props: QuoteTriggerProps) {
182
185
  src={chain.image}
183
186
  open={false}
184
187
  className={i > index ? 'blockchainImage' : ''}
188
+ container={container}
185
189
  />
186
190
  )
187
191
  )}
@@ -27,6 +27,7 @@ export function Quotes(props: PropTypes) {
27
27
  showModalFee,
28
28
  hasSort = true,
29
29
  fullExpandedMode = false,
30
+ container: propContainer,
30
31
  } = props;
31
32
  const {
32
33
  selectedQuote,
@@ -39,6 +40,7 @@ export function Quotes(props: PropTypes) {
39
40
  } = useQuoteStore();
40
41
  const { slippage, customSlippage } = useAppStore();
41
42
  const tokens = useAppStore().tokens();
43
+ const container = propContainer || getContainer();
42
44
  const hasQuotes = !!quotes && quotes.results.length;
43
45
  const userSlippage = customSlippage ?? slippage;
44
46
  const getQuoteWarning = (quote: MultiRouteSimulationResult) => {
@@ -73,7 +75,7 @@ export function Quotes(props: PropTypes) {
73
75
  <Typography size="xmedium" variant="title">
74
76
  {i18n.t('Sort by')}
75
77
  </Typography>
76
- <SelectStrategy container={getContainer()} />
78
+ <SelectStrategy container={container} />
77
79
  </StrategyContent>
78
80
  <Divider size="10" />
79
81
  </>
@@ -107,6 +109,7 @@ export function Quotes(props: PropTypes) {
107
109
  <React.Fragment key={quote.requestId}>
108
110
  <QuoteInfo
109
111
  showModalFee={showModalFee}
112
+ container={container}
110
113
  selected={selectedQuote?.requestId === quote.requestId}
111
114
  tagHidden={false}
112
115
  quote={{ ...quote, requestAmount: quotes.requestAmount }}
@@ -7,4 +7,5 @@ export type PropTypes = {
7
7
  showModalFee?: boolean;
8
8
  hasSort?: boolean;
9
9
  fullExpandedMode?: boolean;
10
+ container?: HTMLElement;
10
11
  };
@@ -75,18 +75,24 @@ export const getSteps = ({
75
75
  ? step.internalSwaps.map((internalSwap) => {
76
76
  return {
77
77
  from: {
78
- blockchain:
79
- getBlockchainShortNameFor(
80
- internalSwap.fromBlockchain,
81
- blockchains
82
- ) ?? '',
78
+ chain: {
79
+ displayName:
80
+ getBlockchainShortNameFor(
81
+ internalSwap.fromBlockchain,
82
+ blockchains
83
+ ) ?? '',
84
+ image: internalSwap.fromBlockchainLogo ?? '',
85
+ },
83
86
  },
84
87
  to: {
85
- blockchain:
86
- getBlockchainShortNameFor(
87
- internalSwap.toBlockchain,
88
- blockchains
89
- ) ?? '',
88
+ chain: {
89
+ displayName:
90
+ getBlockchainShortNameFor(
91
+ internalSwap.toBlockchain,
92
+ blockchains
93
+ ) ?? '',
94
+ image: internalSwap.toBlockchainLogo ?? '',
95
+ },
90
96
  },
91
97
  swapper: {
92
98
  displayName: getSwapperDisplayName(
@@ -1,4 +1,4 @@
1
- import { css, darkTheme, styled } from '@rango-dev/ui';
1
+ import { css, darkTheme, styled, Typography } from '@rango-dev/ui';
2
2
 
3
3
  import { ScrollableArea } from '../Layout';
4
4
 
@@ -85,3 +85,12 @@ export const StyledLink = styled('a', {
85
85
  alignItems: 'center',
86
86
  justifyContent: 'center',
87
87
  });
88
+
89
+ export const ErrorMessages = styled('div', {
90
+ display: 'flex',
91
+ flexDirection: 'column',
92
+ gap: '$5',
93
+ });
94
+ export const MessageText = styled(Typography, {
95
+ wordBreak: 'break-all',
96
+ });
@@ -64,7 +64,9 @@ import {
64
64
 
65
65
  import { getSteps, getStepState, RESET_INTERVAL } from './SwapDetails.helpers';
66
66
  import {
67
+ ErrorMessages,
67
68
  HeaderDetails,
69
+ MessageText,
68
70
  outputStyles,
69
71
  requestIdStyles,
70
72
  rowStyles,
@@ -211,36 +213,55 @@ export function SwapDetails(props: SwapDetailsProps) {
211
213
 
212
214
  const percentageChange = getPriceImpact(inputUsdValue, outputUsdValue);
213
215
 
216
+ const stepDetailMessage =
217
+ stepMessage.detailedMessage.content || stepMessage.shortMessage;
218
+
214
219
  const completeModalDesc =
215
- swap.status === 'success'
216
- ? i18n.t({
217
- id: 'You have received {amount} {token} in {conciseAddress} wallet on {chain} chain.',
218
- values: {
219
- amount: numberToString(
220
- outputAmount,
221
- TOKEN_AMOUNT_MIN_DECIMALS,
222
- TOKEN_AMOUNT_MAX_DECIMALS
223
- ),
224
- token: steps[numberOfSteps - 1].to.token.displayName,
225
- conciseAddress: getConciseAddress(
226
- swap.wallets[steps[numberOfSteps - 1].to.chain.displayName]
227
- ?.address || ''
228
- ),
229
- chain: steps[numberOfSteps - 1].to.chain.displayName,
230
- },
231
- })
232
- : `${i18n.t('Transaction was not sent.')} ${
233
- lastConvertedTokenInFailedSwap
234
- ? i18n.t({
220
+ swap.status === 'success' ? (
221
+ i18n.t({
222
+ id: 'You have received {amount} {token} in {conciseAddress} wallet on {chain} chain.',
223
+ values: {
224
+ amount: numberToString(
225
+ outputAmount,
226
+ TOKEN_AMOUNT_MIN_DECIMALS,
227
+ TOKEN_AMOUNT_MAX_DECIMALS
228
+ ),
229
+ token: steps[numberOfSteps - 1].to.token.displayName,
230
+ conciseAddress: getConciseAddress(
231
+ swap.wallets[steps[numberOfSteps - 1].to.chain.displayName]
232
+ ?.address || ''
233
+ ),
234
+ chain: steps[numberOfSteps - 1].to.chain.displayName,
235
+ },
236
+ })
237
+ ) : (
238
+ <ErrorMessages>
239
+ <Typography
240
+ variant="body"
241
+ size="medium"
242
+ color="neutral700"
243
+ align="center">
244
+ {!stepDetailMessage ? i18n.t('Transaction was not sent.') : ''}
245
+ {lastConvertedTokenInFailedSwap
246
+ ? `${i18n.t({
235
247
  id: '{amount} {symbol} on {blockchain} remain in your wallet',
236
248
  values: {
237
249
  amount: lastConvertedTokenInFailedSwap.outputAmount,
238
250
  symbol: lastConvertedTokenInFailedSwap.symbol,
239
251
  blockchain: lastConvertedTokenInFailedSwap.blockchain,
240
252
  },
241
- })
242
- : ''
243
- }`;
253
+ })}`
254
+ : ''}
255
+ </Typography>
256
+ <MessageText
257
+ align="center"
258
+ variant="body"
259
+ size="medium"
260
+ color="neutral700">
261
+ {stepDetailMessage}
262
+ </MessageText>
263
+ </ErrorMessages>
264
+ );
244
265
 
245
266
  return (
246
267
  <Layout
@@ -1,13 +1,12 @@
1
1
  import type { FailedAlertsProps } from './SwapDetailsAlerts.types';
2
2
 
3
- import {
4
- Alert,
5
- ChevronDownIcon,
6
- ChevronUpIcon,
7
- IconButton,
8
- } from '@rango-dev/ui';
3
+ import { Alert, ChevronDownIcon, IconButton } from '@rango-dev/ui';
9
4
  import React, { useState } from 'react';
10
5
 
6
+ import { MessageText } from '../SwapDetails/SwapDetails.styles';
7
+
8
+ import { ActionIcon, AlertFooter } from './SwapDetailsAlerts.styles';
9
+
11
10
  export function FailedAlert(props: FailedAlertsProps) {
12
11
  const { message } = props;
13
12
  const [showContentError, setShowContentError] = useState(false);
@@ -16,21 +15,30 @@ export function FailedAlert(props: FailedAlertsProps) {
16
15
  <Alert
17
16
  type="error"
18
17
  title={message.shortMessage}
18
+ containerStyles={{
19
+ '& .footer': {
20
+ paddingTop: '$0',
21
+ },
22
+ }}
19
23
  action={
20
24
  message.detailedMessage.content && (
21
25
  <IconButton
22
26
  onClick={() => setShowContentError((prev) => !prev)}
23
27
  variant="ghost"
24
28
  size="xsmall">
25
- {showContentError ? (
26
- <ChevronUpIcon size={12} color="gray" />
27
- ) : (
29
+ <ActionIcon rotated={showContentError}>
28
30
  <ChevronDownIcon size={12} color="gray" />
29
- )}
31
+ </ActionIcon>
30
32
  </IconButton>
31
33
  )
32
34
  }
33
- footer={showContentError ? message.detailedMessage.content : undefined}
35
+ footer={
36
+ <AlertFooter open={showContentError}>
37
+ <MessageText variant="body" size="xsmall" color="neutral700">
38
+ {message.detailedMessage.content}
39
+ </MessageText>
40
+ </AlertFooter>
41
+ }
34
42
  />
35
43
  );
36
44
  }
@@ -5,3 +5,27 @@ export const Alerts = styled('div', {
5
5
  flexDirection: 'column',
6
6
  gap: '$10',
7
7
  });
8
+
9
+ export const ActionIcon = styled('div', {
10
+ transition: 'transform 0.3s ease-in-out',
11
+ variants: {
12
+ rotated: {
13
+ true: {
14
+ transform: 'rotate(180deg)',
15
+ },
16
+ },
17
+ },
18
+ });
19
+
20
+ export const AlertFooter = styled('div', {
21
+ transition: 'max-height 0.3s ease-in-out',
22
+ maxHeight: '0px',
23
+ overflow: 'hidden',
24
+ variants: {
25
+ open: {
26
+ true: {
27
+ maxHeight: '200px',
28
+ },
29
+ },
30
+ },
31
+ });