@rango-dev/widget-embedded 0.23.1-next.0 → 0.23.1-next.2

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 (101) hide show
  1. package/dist/components/Layout/Layout.styles.d.ts +162 -0
  2. package/dist/components/Layout/Layout.styles.d.ts.map +1 -1
  3. package/dist/components/NoResult/NoResult.d.ts.map +1 -1
  4. package/dist/components/NoResult/NoResult.styles.d.ts.map +1 -1
  5. package/dist/components/Quote/Quote.d.ts.map +1 -1
  6. package/dist/components/Quote/Quote.types.d.ts +2 -0
  7. package/dist/components/Quote/Quote.types.d.ts.map +1 -1
  8. package/dist/components/Quote/QuoteCostDetails.d.ts.map +1 -1
  9. package/dist/components/Quote/{QuoteTrigger .d.ts → QuoteTrigger.d.ts} +1 -1
  10. package/dist/components/Quote/QuoteTrigger.d.ts.map +1 -0
  11. package/dist/components/QuoteWarningsAndErrors/HighValueLossWarningModal.d.ts.map +1 -1
  12. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.d.ts +0 -1
  13. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.d.ts.map +1 -1
  14. package/dist/components/QuoteWarningsAndErrors/UnknownPriceWarningModal.d.ts.map +1 -1
  15. package/dist/components/Quotes/Quotes.d.ts +4 -0
  16. package/dist/components/Quotes/Quotes.d.ts.map +1 -0
  17. package/dist/components/Quotes/Quotes.styles.d.ts +487 -0
  18. package/dist/components/Quotes/Quotes.styles.d.ts.map +1 -0
  19. package/dist/components/Quotes/Quotes.types.d.ts +9 -0
  20. package/dist/components/Quotes/Quotes.types.d.ts.map +1 -0
  21. package/dist/components/Quotes/SelectStrategy.d.ts +5 -0
  22. package/dist/components/Quotes/SelectStrategy.d.ts.map +1 -0
  23. package/dist/components/Quotes/index.d.ts +2 -0
  24. package/dist/components/Quotes/index.d.ts.map +1 -0
  25. package/dist/constants/index.d.ts +1 -0
  26. package/dist/constants/index.d.ts.map +1 -1
  27. package/dist/constants/quote.d.ts +4 -3
  28. package/dist/constants/quote.d.ts.map +1 -1
  29. package/dist/containers/ExpandedQuotes/ExpandedQuotes.d.ts +5 -0
  30. package/dist/containers/ExpandedQuotes/ExpandedQuotes.d.ts.map +1 -0
  31. package/dist/containers/ExpandedQuotes/ExpandedQuotes.styles.d.ts +325 -0
  32. package/dist/containers/ExpandedQuotes/ExpandedQuotes.styles.d.ts.map +1 -0
  33. package/dist/containers/ExpandedQuotes/ExpandedQuotes.types.d.ts +9 -0
  34. package/dist/containers/ExpandedQuotes/ExpandedQuotes.types.d.ts.map +1 -0
  35. package/dist/containers/ExpandedQuotes/index.d.ts +2 -0
  36. package/dist/containers/ExpandedQuotes/index.d.ts.map +1 -0
  37. package/dist/containers/Inputs/Inputs.d.ts +4 -0
  38. package/dist/containers/Inputs/Inputs.d.ts.map +1 -0
  39. package/dist/containers/Inputs/Inputs.styles.d.ts +325 -0
  40. package/dist/containers/Inputs/Inputs.styles.d.ts.map +1 -0
  41. package/dist/containers/Inputs/Inputs.types.d.ts +7 -0
  42. package/dist/containers/Inputs/Inputs.types.d.ts.map +1 -0
  43. package/dist/containers/Inputs/index.d.ts +2 -0
  44. package/dist/containers/Inputs/index.d.ts.map +1 -0
  45. package/dist/containers/QuoteInfo/QuoteInfo.d.ts.map +1 -1
  46. package/dist/containers/QuoteInfo/QuoteInfo.types.d.ts +1 -0
  47. package/dist/containers/QuoteInfo/QuoteInfo.types.d.ts.map +1 -1
  48. package/dist/hooks/useMobileDetect.d.ts +3 -0
  49. package/dist/hooks/useMobileDetect.d.ts.map +1 -0
  50. package/dist/hooks/useSwapInput.d.ts.map +1 -1
  51. package/dist/index.d.ts +2 -2
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +2 -2
  54. package/dist/index.js.map +4 -4
  55. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  56. package/dist/pages/Home.d.ts +1 -0
  57. package/dist/pages/Home.d.ts.map +1 -1
  58. package/dist/pages/Routes.d.ts.map +1 -1
  59. package/dist/types/config.d.ts +5 -0
  60. package/dist/types/config.d.ts.map +1 -1
  61. package/dist/utils/common.d.ts +1 -0
  62. package/dist/utils/common.d.ts.map +1 -1
  63. package/package.json +3 -3
  64. package/src/components/Layout/Layout.styles.ts +9 -7
  65. package/src/components/Layout/Layout.tsx +2 -2
  66. package/src/components/NoResult/NoResult.styles.ts +0 -2
  67. package/src/components/NoResult/NoResult.tsx +1 -0
  68. package/src/components/Quote/Quote.styles.ts +1 -1
  69. package/src/components/Quote/Quote.tsx +4 -2
  70. package/src/components/Quote/Quote.types.ts +2 -0
  71. package/src/components/Quote/QuoteCostDetails.tsx +10 -6
  72. package/src/components/Quote/{QuoteTrigger .tsx → QuoteTrigger.tsx} +3 -16
  73. package/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx +15 -12
  74. package/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.ts +0 -1
  75. package/src/components/QuoteWarningsAndErrors/UnknownPriceWarningModal.tsx +16 -13
  76. package/src/components/Quotes/Quotes.styles.ts +18 -0
  77. package/src/components/Quotes/Quotes.tsx +134 -0
  78. package/src/components/Quotes/Quotes.types.ts +9 -0
  79. package/src/components/Quotes/SelectStrategy.tsx +33 -0
  80. package/src/components/Quotes/index.ts +1 -0
  81. package/src/constants/index.ts +1 -0
  82. package/src/constants/quote.ts +22 -7
  83. package/src/containers/ExpandedQuotes/ExpandedQuotes.styles.ts +30 -0
  84. package/src/containers/ExpandedQuotes/ExpandedQuotes.tsx +71 -0
  85. package/src/containers/ExpandedQuotes/ExpandedQuotes.types.ts +9 -0
  86. package/src/containers/ExpandedQuotes/index.ts +1 -0
  87. package/src/containers/Inputs/Inputs.styles.ts +12 -0
  88. package/src/containers/Inputs/Inputs.tsx +165 -0
  89. package/src/containers/Inputs/Inputs.types.ts +7 -0
  90. package/src/containers/Inputs/index.ts +1 -0
  91. package/src/containers/QuoteInfo/QuoteInfo.tsx +2 -0
  92. package/src/containers/QuoteInfo/QuoteInfo.types.ts +1 -0
  93. package/src/hooks/useMobileDetect.ts +21 -0
  94. package/src/hooks/useSwapInput.ts +3 -1
  95. package/src/index.ts +2 -0
  96. package/src/pages/ConfirmSwapPage.tsx +0 -1
  97. package/src/pages/Home.tsx +142 -229
  98. package/src/pages/Routes.tsx +6 -69
  99. package/src/types/config.ts +6 -0
  100. package/src/utils/common.ts +3 -0
  101. package/dist/components/Quote/QuoteTrigger .d.ts.map +0 -1
@@ -0,0 +1,30 @@
1
+ import { darkTheme, styled } from '@rango-dev/ui';
2
+
3
+ export const Container = styled('div', {
4
+ transition: 'width 0.2s, opacity 0.2s, margin-left 0.2s',
5
+ height: '700px',
6
+ width: '390px',
7
+ opacity: 1,
8
+ marginLeft: '$16',
9
+ backgroundColor: '$neutral100',
10
+ [`.${darkTheme} &`]: {
11
+ backgroundColor: '$neutral300',
12
+ },
13
+ '&.is-hidden': {
14
+ width: 0,
15
+ opacity: 0,
16
+ marginLeft: 0,
17
+ },
18
+ });
19
+
20
+ export const Content = styled('div', {
21
+ position: 'relative',
22
+ overflow: 'hidden',
23
+ padding: '$20',
24
+ flexGrow: 1,
25
+ display: 'flex',
26
+ flexDirection: 'column',
27
+ overflowY: 'auto',
28
+ borderRadius: '$primary',
29
+ backgroundColor: '$background',
30
+ });
@@ -0,0 +1,71 @@
1
+ import type { PropTypes } from './ExpandedQuotes.types';
2
+
3
+ import { i18n } from '@lingui/core';
4
+ import { Header } from '@rango-dev/ui';
5
+ import React, { useEffect, useState } from 'react';
6
+
7
+ import { HeaderButtons } from '../../components/HeaderButtons';
8
+ import { LayoutContainer } from '../../components/Layout/Layout.styles';
9
+ import { Quotes } from '../../components/Quotes';
10
+ import { SelectStrategy } from '../../components/Quotes/SelectStrategy';
11
+ import { WIDGET_UI_ID } from '../../constants';
12
+ import { getExpanded } from '../../utils/common';
13
+
14
+ import { Container, Content } from './ExpandedQuotes.styles';
15
+
16
+ export const TIME_TO_CLOSE_OPEN_EXPANDED = 100;
17
+
18
+ export function ExpandedQuotes(props: PropTypes) {
19
+ const { fetch, loading, onClickOnQuote, onClickRefresh, isVisible } = props;
20
+ const [isDelayedVisible, setIsDelayedVisible] = useState(false);
21
+ const containerClass = isDelayedVisible ? '' : 'is-hidden';
22
+
23
+ useEffect(() => {
24
+ let timeout: ReturnType<typeof setTimeout> | null = null;
25
+
26
+ if (isVisible) {
27
+ timeout = setTimeout(() => {
28
+ setIsDelayedVisible(true);
29
+ }, TIME_TO_CLOSE_OPEN_EXPANDED);
30
+ } else {
31
+ setIsDelayedVisible(false);
32
+ if (timeout) {
33
+ clearTimeout(timeout);
34
+ }
35
+ }
36
+
37
+ return () => {
38
+ if (timeout) {
39
+ clearTimeout(timeout);
40
+ }
41
+ };
42
+ }, [isVisible]);
43
+
44
+ return (
45
+ <Container
46
+ className={`${containerClass} ${LayoutContainer()}`}
47
+ id={WIDGET_UI_ID.EXPANDED_BOX_ID}>
48
+ <Header
49
+ title={i18n.t('Routes')}
50
+ suffix={
51
+ <>
52
+ <SelectStrategy container={getExpanded()} />
53
+ <HeaderButtons
54
+ onClickRefresh={onClickRefresh}
55
+ hidden={['history', 'notifications', 'settings']}
56
+ />
57
+ </>
58
+ }
59
+ />
60
+ <Content>
61
+ <Quotes
62
+ showModalFee={false}
63
+ fetch={fetch}
64
+ hasSort={false}
65
+ loading={loading}
66
+ onClickOnQuote={onClickOnQuote}
67
+ />
68
+ </Content>
69
+ </Container>
70
+ );
71
+ }
@@ -0,0 +1,9 @@
1
+ import type { SelectedQuote } from '../../types';
2
+
3
+ export type PropTypes = {
4
+ loading: boolean;
5
+ onClickOnQuote: (quote: SelectedQuote) => void;
6
+ fetch: (shouldChangeSelectedQuote?: boolean) => void;
7
+ onClickRefresh?: () => void;
8
+ isVisible: boolean;
9
+ };
@@ -0,0 +1 @@
1
+ export { ExpandedQuotes } from './ExpandedQuotes';
@@ -0,0 +1,12 @@
1
+ import { styled } from '@rango-dev/ui';
2
+
3
+ export const Container = styled('div', {
4
+ display: 'flex',
5
+ flexDirection: 'column',
6
+ gap: '$5',
7
+ alignSelf: 'stretch',
8
+ });
9
+
10
+ export const FromContainer = styled('div', {
11
+ position: 'relative',
12
+ });
@@ -0,0 +1,165 @@
1
+ import type { PropTypes } from './Inputs.types';
2
+
3
+ import { i18n } from '@lingui/core';
4
+ import { SwapInput } from '@rango-dev/ui';
5
+ import React from 'react';
6
+
7
+ import { SwitchFromAndToButton } from '../../components/SwitchFromAndTo';
8
+ import { errorMessages } from '../../constants/errors';
9
+ import {
10
+ PERCENTAGE_CHANGE_MAX_DECIMALS,
11
+ PERCENTAGE_CHANGE_MIN_DECIMALS,
12
+ TOKEN_AMOUNT_MAX_DECIMALS,
13
+ TOKEN_AMOUNT_MIN_DECIMALS,
14
+ USD_VALUE_MAX_DECIMALS,
15
+ USD_VALUE_MIN_DECIMALS,
16
+ } from '../../constants/routing';
17
+ import { useQuoteStore } from '../../store/quote';
18
+ import { useWalletsStore } from '../../store/wallets';
19
+ import { getContainer } from '../../utils/common';
20
+ import { formatTooltipNumbers, numberToString } from '../../utils/numbers';
21
+ import { getPriceImpact, getPriceImpactLevel } from '../../utils/quote';
22
+ import { canComputePriceImpact } from '../../utils/swap';
23
+ import { formatBalance, isFetchingBalance } from '../../utils/wallets';
24
+
25
+ import { Container, FromContainer } from './Inputs.styles';
26
+
27
+ export function Inputs(props: PropTypes) {
28
+ const { fetchingQuote, fetchMetaStatus, onClickToken } = props;
29
+ const {
30
+ fromToken,
31
+ fromBlockchain,
32
+ toToken,
33
+ toBlockchain,
34
+ setInputAmount,
35
+ inputAmount,
36
+ inputUsdValue,
37
+ outputAmount,
38
+ outputUsdValue,
39
+ selectedQuote,
40
+ } = useQuoteStore();
41
+ const { connectedWallets, getBalanceFor } = useWalletsStore();
42
+
43
+ const fromTokenBalance = fromToken ? getBalanceFor(fromToken) : null;
44
+
45
+ const fromTokenFormattedBalance =
46
+ formatBalance(fromTokenBalance)?.amount ?? '0';
47
+
48
+ const tokenBalanceReal =
49
+ !!fromBlockchain && !!fromToken
50
+ ? numberToString(fromTokenBalance?.amount, fromTokenBalance?.decimals)
51
+ : '0';
52
+
53
+ const fetchingBalance =
54
+ !!fromBlockchain &&
55
+ isFetchingBalance(connectedWallets, fromBlockchain.name);
56
+
57
+ const priceImpactInputCanNotBeComputed = !canComputePriceImpact(
58
+ selectedQuote,
59
+ inputAmount,
60
+ inputUsdValue
61
+ );
62
+
63
+ const priceImpactOutputCanNotBeComputed = !canComputePriceImpact(
64
+ selectedQuote,
65
+ inputAmount,
66
+ outputUsdValue
67
+ );
68
+
69
+ const percentageChange =
70
+ !inputUsdValue || !outputUsdValue || !outputUsdValue.gt(0)
71
+ ? null
72
+ : getPriceImpact(inputUsdValue.toString(), outputUsdValue.toString());
73
+ return (
74
+ <Container>
75
+ <FromContainer>
76
+ <SwapInput
77
+ label={i18n.t('From')}
78
+ mode="From"
79
+ onInputChange={setInputAmount}
80
+ balance={fromTokenFormattedBalance}
81
+ chain={{
82
+ displayName: fromBlockchain?.displayName || '',
83
+ image: fromBlockchain?.logo || '',
84
+ }}
85
+ token={{
86
+ displayName: fromToken?.symbol || '',
87
+ image: fromToken?.image || '',
88
+ }}
89
+ onClickToken={() => onClickToken('from')}
90
+ price={{
91
+ value: inputAmount,
92
+ usdValue: priceImpactInputCanNotBeComputed
93
+ ? undefined
94
+ : numberToString(
95
+ inputUsdValue,
96
+ USD_VALUE_MIN_DECIMALS,
97
+ USD_VALUE_MAX_DECIMALS
98
+ ),
99
+ realUsdValue: priceImpactInputCanNotBeComputed
100
+ ? undefined
101
+ : formatTooltipNumbers(inputUsdValue),
102
+ error: priceImpactInputCanNotBeComputed
103
+ ? errorMessages().unknownPriceError.impactTitle
104
+ : undefined,
105
+ }}
106
+ disabled={fetchMetaStatus === 'failed'}
107
+ loading={fetchMetaStatus === 'loading'}
108
+ loadingBalance={fetchingBalance}
109
+ tooltipContainer={getContainer()}
110
+ onSelectMaxBalance={() => {
111
+ if (fromTokenFormattedBalance !== '0') {
112
+ setInputAmount(tokenBalanceReal.split(',').join(''));
113
+ }
114
+ }}
115
+ />
116
+ <SwitchFromAndToButton />
117
+ </FromContainer>
118
+ <SwapInput
119
+ sharpBottomStyle={!!selectedQuote || fetchingQuote}
120
+ label={i18n.t('To')}
121
+ mode="To"
122
+ fetchingQuote={fetchingQuote}
123
+ chain={{
124
+ displayName: toBlockchain?.displayName || '',
125
+ image: toBlockchain?.logo || '',
126
+ }}
127
+ token={{
128
+ displayName: toToken?.symbol || '',
129
+ image: toToken?.image || '',
130
+ }}
131
+ percentageChange={numberToString(
132
+ getPriceImpact(inputUsdValue, outputUsdValue),
133
+ PERCENTAGE_CHANGE_MIN_DECIMALS,
134
+ PERCENTAGE_CHANGE_MAX_DECIMALS
135
+ )}
136
+ warningLevel={getPriceImpactLevel(percentageChange ?? 0)}
137
+ price={{
138
+ value: numberToString(
139
+ outputAmount,
140
+ TOKEN_AMOUNT_MIN_DECIMALS,
141
+ TOKEN_AMOUNT_MAX_DECIMALS
142
+ ),
143
+ usdValue: priceImpactOutputCanNotBeComputed
144
+ ? undefined
145
+ : numberToString(
146
+ outputUsdValue,
147
+ USD_VALUE_MIN_DECIMALS,
148
+ USD_VALUE_MAX_DECIMALS
149
+ ),
150
+ realValue: formatTooltipNumbers(outputAmount),
151
+ realUsdValue: priceImpactOutputCanNotBeComputed
152
+ ? undefined
153
+ : formatTooltipNumbers(outputUsdValue),
154
+ error: priceImpactOutputCanNotBeComputed
155
+ ? errorMessages().unknownPriceError.impactTitle
156
+ : undefined,
157
+ }}
158
+ onClickToken={() => onClickToken('to')}
159
+ disabled={fetchMetaStatus === 'failed'}
160
+ loading={fetchMetaStatus === 'loading'}
161
+ tooltipContainer={getContainer()}
162
+ />
163
+ </Container>
164
+ );
165
+ }
@@ -0,0 +1,7 @@
1
+ import type { FetchStatus } from '../../store/slices/data';
2
+
3
+ export type PropTypes = {
4
+ fetchingQuote: boolean;
5
+ fetchMetaStatus: FetchStatus;
6
+ onClickToken: (mode: 'from' | 'to') => void;
7
+ };
@@ -0,0 +1 @@
1
+ export { Inputs } from './Inputs';
@@ -22,6 +22,7 @@ export function QuoteInfo(props: PropTypes) {
22
22
  expanded = false,
23
23
  tagHidden,
24
24
  onClick,
25
+ showModalFee,
25
26
  selected,
26
27
  onClickAllRoutes,
27
28
  } = props;
@@ -57,6 +58,7 @@ export function QuoteInfo(props: PropTypes) {
57
58
  <Quote
58
59
  quote={quote}
59
60
  error={error}
61
+ showModalFee={showModalFee}
60
62
  warning={warning}
61
63
  tagHidden={tagHidden}
62
64
  selected={selected}
@@ -13,4 +13,5 @@ export type PropTypes = {
13
13
  expanded?: boolean;
14
14
  onClickAllRoutes?: () => void;
15
15
  selected?: boolean;
16
+ showModalFee?: boolean;
16
17
  };
@@ -0,0 +1,21 @@
1
+ import { useEffect, useState } from 'react';
2
+
3
+ const MIN_WIDTH_WINDOW = 768;
4
+
5
+ const useMobileDetect = () => {
6
+ const [isMobile, setIsMobile] = useState(false);
7
+
8
+ const handleResize = () => {
9
+ setIsMobile(window.innerWidth < MIN_WIDTH_WINDOW);
10
+ };
11
+
12
+ useEffect(() => {
13
+ handleResize(); // Initial check
14
+ window.addEventListener('resize', handleResize);
15
+ return () => window.removeEventListener('resize', handleResize);
16
+ }, []);
17
+
18
+ return isMobile;
19
+ };
20
+
21
+ export default useMobileDetect;
@@ -58,6 +58,8 @@ export function useSwapInput({
58
58
  selectedQuote,
59
59
  sortStrategy,
60
60
  resetQuote,
61
+ error,
62
+ warning,
61
63
  setSelectedQuote,
62
64
  updateQuotePartialState,
63
65
  } = useQuoteStore();
@@ -184,7 +186,7 @@ export function useSwapInput({
184
186
  }
185
187
  if (shouldSkipRequest) {
186
188
  setLoading(false);
187
- if (selectedQuote) {
189
+ if (selectedQuote || error || warning) {
188
190
  resetQuote();
189
191
  }
190
192
  return;
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@ import type {
7
7
  WidgetColorsKeys,
8
8
  WidgetConfig,
9
9
  WidgetTheme,
10
+ WidgetVariant,
10
11
  } from './types';
11
12
  import type {
12
13
  PendingSwapWithQueueID,
@@ -89,6 +90,7 @@ export type {
89
90
  HandleWalletsUpdate,
90
91
  ConnectedWallet,
91
92
  Tokens,
93
+ WidgetVariant,
92
94
  };
93
95
  export {
94
96
  Widget,
@@ -282,7 +282,6 @@ export function ConfirmSwapPage() {
282
282
  <QuoteWarningsAndErrors
283
283
  warning={quoteWarning}
284
284
  error={quoteError}
285
- loading={fetchingConfirmationQuote}
286
285
  refetchQuote={onRefresh}
287
286
  showWarningModal={showQuoteWarningModal}
288
287
  confirmationDisabled={!isActiveTab}