@rango-dev/widget-embedded 0.14.1-next.9 → 0.16.0

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 (147) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/Widget.d.ts.map +1 -1
  3. package/dist/components/BlockchainList/BlockchainList.styles.d.ts +2 -0
  4. package/dist/components/BlockchainList/BlockchainList.styles.d.ts.map +1 -1
  5. package/dist/components/BlockchainsSection/BlockchainsSection.d.ts.map +1 -1
  6. package/dist/components/BlockchainsSection/BlockchainsSection.styles.d.ts +1 -0
  7. package/dist/components/BlockchainsSection/BlockchainsSection.styles.d.ts.map +1 -1
  8. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts +15 -0
  9. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts.map +1 -1
  10. package/dist/components/ConfirmWalletsModal/ConfirmWalletsModal.d.ts.map +1 -1
  11. package/dist/components/ConfirmWalletsModal/WalletList.d.ts.map +1 -1
  12. package/dist/components/ConfirmWalletsModal/WalletList.styles.d.ts +3 -0
  13. package/dist/components/ConfirmWalletsModal/WalletList.styles.d.ts.map +1 -1
  14. package/dist/components/HeaderButtons/HeaderButtons.styles.d.ts +4 -0
  15. package/dist/components/HeaderButtons/HeaderButtons.styles.d.ts.map +1 -1
  16. package/dist/components/Layout/Layout.styles.d.ts +3 -0
  17. package/dist/components/Layout/Layout.styles.d.ts.map +1 -1
  18. package/dist/components/LoadingLiquiditySourceList/LoadingLiquiditySourceList.styles.d.ts +1 -0
  19. package/dist/components/LoadingLiquiditySourceList/LoadingLiquiditySourceList.styles.d.ts.map +1 -1
  20. package/dist/components/LoadingSwapDetails/LoadingSwapDetails.styles.d.ts +3 -0
  21. package/dist/components/LoadingSwapDetails/LoadingSwapDetails.styles.d.ts.map +1 -1
  22. package/dist/components/NoRoutes/NoRoutes.styles.d.ts +3 -0
  23. package/dist/components/NoRoutes/NoRoutes.styles.d.ts.map +1 -1
  24. package/dist/components/NotificationContent/NotificationContent.styles.d.ts +4 -0
  25. package/dist/components/NotificationContent/NotificationContent.styles.d.ts.map +1 -1
  26. package/dist/components/RouteErrors/RouteErrors.styles.d.ts +4 -0
  27. package/dist/components/RouteErrors/RouteErrors.styles.d.ts.map +1 -1
  28. package/dist/components/SearchInput/SearchInput.styles.d.ts +1 -0
  29. package/dist/components/SearchInput/SearchInput.styles.d.ts.map +1 -1
  30. package/dist/components/SettingsContainer/SettingsContainer.style.d.ts +4 -0
  31. package/dist/components/SettingsContainer/SettingsContainer.style.d.ts.map +1 -1
  32. package/dist/components/Slippage/Slippage.styles.d.ts +4 -0
  33. package/dist/components/Slippage/Slippage.styles.d.ts.map +1 -1
  34. package/dist/components/SwapDetails/SwapDetails.Placeholder.d.ts.map +1 -1
  35. package/dist/components/SwapDetails/SwapDetails.d.ts.map +1 -1
  36. package/dist/components/SwapDetails/SwapDetails.styles.d.ts +6 -0
  37. package/dist/components/SwapDetails/SwapDetails.styles.d.ts.map +1 -1
  38. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.styles.d.ts +1 -0
  39. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.styles.d.ts.map +1 -1
  40. package/dist/components/SwapDetailsModal/SwapDetailsModal.styles.d.ts +1 -0
  41. package/dist/components/SwapDetailsModal/SwapDetailsModal.styles.d.ts.map +1 -1
  42. package/dist/components/SwapsGroup/SwapsGroup.styles.d.ts +4 -0
  43. package/dist/components/SwapsGroup/SwapsGroup.styles.d.ts.map +1 -1
  44. package/dist/components/TokenList/TokenList.styles.d.ts +10 -0
  45. package/dist/components/TokenList/TokenList.styles.d.ts.map +1 -1
  46. package/dist/components/WalletModal/WalletModalContent.styles.d.ts +4 -0
  47. package/dist/components/WalletModal/WalletModalContent.styles.d.ts.map +1 -1
  48. package/dist/constants/configs.d.ts +2 -0
  49. package/dist/constants/configs.d.ts.map +1 -0
  50. package/dist/constants/errors.d.ts +1 -1
  51. package/dist/constants/errors.d.ts.map +1 -1
  52. package/dist/constants/languages.d.ts +11 -0
  53. package/dist/constants/languages.d.ts.map +1 -0
  54. package/dist/constants/messages.d.ts +1 -1
  55. package/dist/constants/messages.d.ts.map +1 -1
  56. package/dist/hooks/useLanguage.d.ts +11 -0
  57. package/dist/hooks/useLanguage.d.ts.map +1 -0
  58. package/dist/hooks/usePrepareBlockchainList/index.d.ts +2 -0
  59. package/dist/hooks/usePrepareBlockchainList/index.d.ts.map +1 -0
  60. package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.constants.d.ts +2 -0
  61. package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.constants.d.ts.map +1 -0
  62. package/dist/hooks/{usePrepareBlockchainList.d.ts → usePrepareBlockchainList/usePrepareBlockchainList.d.ts} +1 -9
  63. package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.d.ts.map +1 -0
  64. package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.helpers.d.ts +10 -0
  65. package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.helpers.d.ts.map +1 -0
  66. package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.mock.d.ts +3 -0
  67. package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.mock.d.ts.map +1 -0
  68. package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.test.d.ts +2 -0
  69. package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.test.d.ts.map +1 -0
  70. package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.types.d.ts +11 -0
  71. package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.types.d.ts.map +1 -0
  72. package/dist/hooks/useSyncStoresWithConfig.d.ts.map +1 -1
  73. package/dist/hooks/useTheme.d.ts +1 -1
  74. package/dist/hooks/useTheme.d.ts.map +1 -1
  75. package/dist/index.js +1 -1
  76. package/dist/index.js.map +4 -4
  77. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  78. package/dist/pages/Home.d.ts.map +1 -1
  79. package/dist/pages/LanguagePage.d.ts.map +1 -1
  80. package/dist/store/settings.d.ts +15 -6
  81. package/dist/store/settings.d.ts.map +1 -1
  82. package/dist/types/config.d.ts +7 -3
  83. package/dist/types/config.d.ts.map +1 -1
  84. package/dist/utils/colors.d.ts +1 -1
  85. package/dist/utils/colors.d.ts.map +1 -1
  86. package/dist/utils/configs.d.ts +2 -0
  87. package/dist/utils/configs.d.ts.map +1 -1
  88. package/dist/utils/hash.d.ts +2 -0
  89. package/dist/utils/hash.d.ts.map +1 -0
  90. package/dist/utils/swap.d.ts.map +1 -1
  91. package/dist/utils/time.d.ts.map +1 -1
  92. package/dist/utils/ui.d.ts +13 -0
  93. package/dist/utils/ui.d.ts.map +1 -0
  94. package/dist/utils/wallets.d.ts +0 -1
  95. package/dist/utils/wallets.d.ts.map +1 -1
  96. package/package.json +8 -8
  97. package/src/Widget.tsx +14 -2
  98. package/src/components/BlockchainsSection/BlockchainsSection.tsx +21 -6
  99. package/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx +5 -11
  100. package/src/components/ConfirmWalletsModal/WalletList.tsx +35 -24
  101. package/src/components/Layout/Layout.styles.ts +7 -2
  102. package/src/components/LoadingSwapDetails/LoadingSwapDetails.styles.ts +1 -1
  103. package/src/components/NoRoutes/NoRoutes.helper.ts +4 -4
  104. package/src/components/NoRoutes/NoRoutes.tsx +2 -2
  105. package/src/components/NotificationContent/NotificationContent.tsx +1 -1
  106. package/src/components/NotificationContent/NotificationNotFound.tsx +1 -1
  107. package/src/components/RouteErrors/RouteErrors.tsx +2 -2
  108. package/src/components/RouteErrors/RouteErrorsModal.tsx +6 -6
  109. package/src/components/RouteErrors/RouteErrorsModalItem.tsx +1 -1
  110. package/src/components/Slippage/SlippageTooltipContent.tsx +1 -1
  111. package/src/components/SwapDetails/SwapDetails.Placeholder.tsx +5 -6
  112. package/src/components/SwapDetails/SwapDetails.tsx +6 -10
  113. package/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx +1 -1
  114. package/src/components/SwapsGroup/SwapsGroup.tsx +2 -2
  115. package/src/components/TokenList/TokenList.styles.ts +1 -1
  116. package/src/components/TokenList/TokenList.tsx +1 -1
  117. package/src/constants/configs.ts +1 -0
  118. package/src/constants/errors.ts +44 -41
  119. package/src/constants/languages.ts +19 -0
  120. package/src/constants/messages.ts +7 -5
  121. package/src/hooks/useConfirmSwap.ts +1 -1
  122. package/src/hooks/useLanguage.ts +27 -0
  123. package/src/hooks/usePrepareBlockchainList/index.ts +1 -0
  124. package/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.constants.ts +1 -0
  125. package/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.helpers.ts +108 -0
  126. package/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.mock.ts +3101 -0
  127. package/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.test.ts +273 -0
  128. package/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.ts +38 -0
  129. package/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.types.ts +12 -0
  130. package/src/hooks/useSyncStoresWithConfig.ts +49 -1
  131. package/src/hooks/useTheme.ts +34 -56
  132. package/src/pages/ConfirmSwapPage.tsx +9 -18
  133. package/src/pages/Home.tsx +6 -7
  134. package/src/pages/LanguagePage.tsx +16 -39
  135. package/src/pages/SettingsPage.tsx +1 -1
  136. package/src/store/settings.ts +46 -4
  137. package/src/types/config.ts +6 -2
  138. package/src/utils/colors.ts +16 -0
  139. package/src/utils/configs.ts +3 -0
  140. package/src/utils/hash.ts +27 -0
  141. package/src/utils/settings.ts +1 -1
  142. package/src/utils/swap.ts +15 -20
  143. package/src/utils/time.ts +2 -4
  144. package/src/utils/ui.ts +72 -0
  145. package/src/utils/wallets.ts +4 -25
  146. package/dist/hooks/usePrepareBlockchainList.d.ts.map +0 -1
  147. package/src/hooks/usePrepareBlockchainList.ts +0 -125
@@ -0,0 +1,273 @@
1
+ import type { BlockchainMeta } from 'rango-sdk';
2
+
3
+ import { beforeEach, describe, expect, it } from 'vitest';
4
+
5
+ import { MOST_USED_BLOCKChAINS } from './usePrepareBlockchainList.constants';
6
+ import {
7
+ generateSortByPreferredBlockchainsFor,
8
+ prepare,
9
+ sortByMostUsedBlockchains,
10
+ } from './usePrepareBlockchainList.helpers';
11
+ import { sampleBlockchains } from './usePrepareBlockchainList.mock';
12
+
13
+ describe('usePrepareBlockchainList', () => {
14
+ let sample: BlockchainMeta[] = [];
15
+
16
+ beforeEach(() => {
17
+ sample = JSON.parse(JSON.stringify(sampleBlockchains));
18
+ });
19
+
20
+ it('should sort blockchains by most used ones.', () => {
21
+ const sortedBlockchainsList = sample.sort(sortByMostUsedBlockchains);
22
+
23
+ const mostUsedCount = MOST_USED_BLOCKChAINS.length;
24
+ const expected = MOST_USED_BLOCKChAINS;
25
+ const received = sortedBlockchainsList
26
+ .map((blockchain) => blockchain.name)
27
+ .slice(0, mostUsedCount);
28
+
29
+ expect(expected).toEqual(received);
30
+ });
31
+
32
+ it('should sort blockchains by user preferences', () => {
33
+ const preferredBlockchains = ['UMEE', 'BANDCHAIN', 'LINEA'];
34
+ const sortedBlockchainsList = sample.sort(
35
+ generateSortByPreferredBlockchainsFor(preferredBlockchains)
36
+ );
37
+
38
+ const expected = [
39
+ 'UMEE',
40
+ 'BANDCHAIN',
41
+ 'LINEA',
42
+ 'ETH',
43
+ 'BSC',
44
+ 'ARBITRUM',
45
+ 'POLYGON',
46
+ 'ZKSYNC',
47
+ 'STARKNET',
48
+ 'OPTIMISM',
49
+ 'AVAX_CCHAIN',
50
+ 'POLYGONZK',
51
+ 'TRON',
52
+ 'BTC',
53
+ 'COSMOS',
54
+ 'OSMOSIS',
55
+ 'NEUTRON',
56
+ 'NOBLE',
57
+ 'SOLANA',
58
+ 'CRONOS',
59
+ 'BNB',
60
+ 'AURORA',
61
+ 'MAYA',
62
+ 'THOR',
63
+ 'BOBA',
64
+ 'MOONBEAM',
65
+ 'MOONRIVER',
66
+ 'OKC',
67
+ 'BOBA_AVALANCHE',
68
+ 'LTC',
69
+ 'BCH',
70
+ 'HECO',
71
+ 'STARGAZE',
72
+ 'CRYPTO_ORG',
73
+ 'CHIHUAHUA',
74
+ 'COMDEX',
75
+ 'REGEN',
76
+ 'IRIS',
77
+ 'EMONEY',
78
+ 'JUNO',
79
+ 'STRIDE',
80
+ 'MARS',
81
+ 'TERRA',
82
+ 'BITSONG',
83
+ 'AKASH',
84
+ 'KI',
85
+ 'PERSISTENCE',
86
+ 'MEDIBLOC',
87
+ 'KUJIRA',
88
+ 'SENTINEL',
89
+ 'INJECTIVE',
90
+ 'SECRET',
91
+ 'KONSTELLATION',
92
+ 'STARNAME',
93
+ 'BITCANNA',
94
+ 'DESMOS',
95
+ 'LUMNETWORK',
96
+ ];
97
+ const received = sortedBlockchainsList.map((blockchain) => blockchain.name);
98
+
99
+ expect(expected).toEqual(received);
100
+ });
101
+
102
+ it('should prepare the list by most used and user preferences', () => {
103
+ const listLimit = 10;
104
+ const preferredBlockchains = ['BTC', 'SOLANA', 'COSMOS', 'ETH'];
105
+ const expected = [
106
+ 'BTC',
107
+ 'SOLANA',
108
+ 'ETH',
109
+ 'COSMOS',
110
+ 'OSMOSIS',
111
+ 'BSC',
112
+ 'ARBITRUM',
113
+ 'POLYGON',
114
+ 'ZKSYNC',
115
+ 'STARKNET',
116
+ 'OPTIMISM',
117
+ 'AVAX_CCHAIN',
118
+ 'POLYGONZK',
119
+ 'LINEA',
120
+ 'TRON',
121
+ 'NEUTRON',
122
+ 'NOBLE',
123
+ 'CRONOS',
124
+ 'BNB',
125
+ 'AURORA',
126
+ 'MAYA',
127
+ 'THOR',
128
+ 'BOBA',
129
+ 'MOONBEAM',
130
+ 'MOONRIVER',
131
+ 'OKC',
132
+ 'BOBA_AVALANCHE',
133
+ 'LTC',
134
+ 'BCH',
135
+ 'HECO',
136
+ 'STARGAZE',
137
+ 'CRYPTO_ORG',
138
+ 'CHIHUAHUA',
139
+ 'BANDCHAIN',
140
+ 'COMDEX',
141
+ 'REGEN',
142
+ 'IRIS',
143
+ 'EMONEY',
144
+ 'JUNO',
145
+ 'STRIDE',
146
+ 'MARS',
147
+ 'TERRA',
148
+ 'BITSONG',
149
+ 'AKASH',
150
+ 'KI',
151
+ 'PERSISTENCE',
152
+ 'MEDIBLOC',
153
+ 'KUJIRA',
154
+ 'SENTINEL',
155
+ 'INJECTIVE',
156
+ 'SECRET',
157
+ 'KONSTELLATION',
158
+ 'STARNAME',
159
+ 'BITCANNA',
160
+ 'UMEE',
161
+ 'DESMOS',
162
+ 'LUMNETWORK',
163
+ ];
164
+ const received = prepare(sample, preferredBlockchains, {
165
+ limit: listLimit,
166
+ });
167
+
168
+ const receivedListNames = received.list.map(
169
+ (blockchain) => blockchain.name
170
+ );
171
+ const receivedMoreNames = received.more.map(
172
+ (blockchain) => blockchain.name
173
+ );
174
+
175
+ expect(received.list).toHaveLength(listLimit);
176
+ expect(received.more).toHaveLength(expected.length - listLimit);
177
+ expect(expected).toEqual([...receivedListNames, ...receivedMoreNames]);
178
+
179
+ // Check duplication
180
+ receivedListNames.forEach((listName) => {
181
+ expect(receivedMoreNames).not.toContain(listName);
182
+ });
183
+
184
+ // Check preferred blockchains to be on the main list
185
+ preferredBlockchains.forEach((blockchain) => {
186
+ expect(receivedListNames).toContain(blockchain);
187
+ });
188
+ });
189
+
190
+ it('should prepare the list correctly if user has a long list of preferences ', () => {
191
+ const listLimit = 10;
192
+ const preferredBlockchains = [
193
+ 'ETH',
194
+ 'BTC',
195
+ 'SOLANA',
196
+ 'CRYPTO_ORG',
197
+ 'TRON',
198
+ 'BOBA_AVALANCHE',
199
+ 'AKASH',
200
+ 'LUMNETWORK',
201
+ 'KONSTELLATION',
202
+ 'BANDCHAIN',
203
+ 'INJECTIVE',
204
+ ];
205
+ const expected = [
206
+ 'ETH',
207
+ 'BTC',
208
+ 'SOLANA',
209
+ 'CRYPTO_ORG',
210
+ 'TRON',
211
+ 'BOBA_AVALANCHE',
212
+ 'AKASH',
213
+ 'LUMNETWORK',
214
+ 'KONSTELLATION',
215
+ 'BANDCHAIN',
216
+ 'INJECTIVE',
217
+ 'COSMOS',
218
+ 'OSMOSIS',
219
+ 'BSC',
220
+ 'ARBITRUM',
221
+ 'POLYGON',
222
+ 'ZKSYNC',
223
+ 'STARKNET',
224
+ 'OPTIMISM',
225
+ 'AVAX_CCHAIN',
226
+ 'POLYGONZK',
227
+ 'LINEA',
228
+ 'NEUTRON',
229
+ 'NOBLE',
230
+ 'CRONOS',
231
+ 'BNB',
232
+ 'AURORA',
233
+ 'MAYA',
234
+ 'THOR',
235
+ 'BOBA',
236
+ 'MOONBEAM',
237
+ 'MOONRIVER',
238
+ 'OKC',
239
+ 'LTC',
240
+ 'BCH',
241
+ 'HECO',
242
+ 'STARGAZE',
243
+ 'CHIHUAHUA',
244
+ 'COMDEX',
245
+ 'REGEN',
246
+ 'IRIS',
247
+ 'EMONEY',
248
+ 'JUNO',
249
+ 'STRIDE',
250
+ 'MARS',
251
+ 'TERRA',
252
+ 'BITSONG',
253
+ 'KI',
254
+ 'PERSISTENCE',
255
+ 'MEDIBLOC',
256
+ 'KUJIRA',
257
+ 'SENTINEL',
258
+ 'SECRET',
259
+ 'STARNAME',
260
+ 'BITCANNA',
261
+ 'UMEE',
262
+ 'DESMOS',
263
+ ];
264
+ const received = prepare(sample, preferredBlockchains, {
265
+ limit: listLimit,
266
+ });
267
+
268
+ expect(expected).toEqual([
269
+ ...received.list.map((blockchain) => blockchain.name),
270
+ ...received.more.map((blockchain) => blockchain.name),
271
+ ]);
272
+ });
273
+ });
@@ -0,0 +1,38 @@
1
+ import type {
2
+ PrepareListOptions,
3
+ PrepareListOutput,
4
+ } from './usePrepareBlockchainList.types';
5
+ import type { BlockchainMeta } from 'rango-sdk';
6
+
7
+ import { useEffect } from 'react';
8
+
9
+ import { useSettingsStore } from '../../store/settings';
10
+
11
+ import { prepare } from './usePrepareBlockchainList.helpers';
12
+
13
+ /**
14
+ *
15
+ * UI needs some specific logics like limiting the list and sorting,
16
+ * this function is getting the raw blockchains list and return a list for showing in UI.
17
+ *
18
+ */
19
+ export function usePrepareBlockchainList(
20
+ blockchains: BlockchainMeta[],
21
+ options?: PrepareListOptions
22
+ ): PrepareListOutput {
23
+ const { preferredBlockchains, addPreferredBlockchain } = useSettingsStore();
24
+
25
+ useEffect(() => {
26
+ if (options?.selected) {
27
+ addPreferredBlockchain(options?.selected);
28
+ }
29
+ }, [options?.selected]);
30
+
31
+ const output = prepare(blockchains, preferredBlockchains, options);
32
+
33
+ return {
34
+ list: output.list,
35
+ more: output.more,
36
+ history: [],
37
+ };
38
+ }
@@ -0,0 +1,12 @@
1
+ import type { BlockchainMeta } from 'rango-sdk';
2
+
3
+ export interface PrepareListOptions {
4
+ limit?: number;
5
+ selected?: string;
6
+ }
7
+
8
+ export interface PrepareListOutput {
9
+ list: BlockchainMeta[];
10
+ more: BlockchainMeta[];
11
+ history: string[];
12
+ }
@@ -1,7 +1,7 @@
1
1
  import type { WidgetConfig } from '../types';
2
2
  import type { Asset } from 'rango-sdk';
3
3
 
4
- import { useEffect, useRef } from 'react';
4
+ import { useEffect, useMemo, useRef } from 'react';
5
5
 
6
6
  import { useBestRouteStore } from '../store/bestRoute';
7
7
  import { useMetaStore } from '../store/meta';
@@ -15,6 +15,10 @@ export function useSyncStoresWithConfig(config: WidgetConfig | undefined) {
15
15
  setToBlockchain,
16
16
  setFromBlockchain,
17
17
  setFromToken,
18
+ fromToken,
19
+ toToken,
20
+ fromBlockchain,
21
+ toBlockchain,
18
22
  } = useBestRouteStore();
19
23
 
20
24
  const {
@@ -25,6 +29,22 @@ export function useSyncStoresWithConfig(config: WidgetConfig | undefined) {
25
29
  const { setAffiliateRef, setAffiliatePercent, setAffiliateWallets } =
26
30
  useSettingsStore();
27
31
 
32
+ const fromTokensConfig = useMemo(
33
+ () => config?.from?.tokens,
34
+ [config?.from?.tokens]
35
+ );
36
+ const fromBlockchainsConfig = useMemo(
37
+ () => config?.from?.blockchains,
38
+ [config?.from?.blockchains]
39
+ );
40
+ const toTokensConfig = useMemo(
41
+ () => config?.to?.tokens,
42
+ [config?.to?.tokens]
43
+ );
44
+ const toBlockchainsConfig = useMemo(
45
+ () => config?.to?.blockchains,
46
+ [config?.to?.blockchains]
47
+ );
28
48
  const prevConfigFromToken = useRef<Asset | undefined>(undefined);
29
49
  const prevConfigToToken = useRef<Asset | undefined>(undefined);
30
50
  const prevConfigFromBlockchain = useRef<string | undefined>(undefined);
@@ -62,6 +82,34 @@ export function useSyncStoresWithConfig(config: WidgetConfig | undefined) {
62
82
  loadingMetaStatus,
63
83
  ]);
64
84
 
85
+ useEffect(() => {
86
+ if (fromToken && fromTokensConfig) {
87
+ if (!fromTokensConfig.some((token) => tokensAreEqual(token, fromToken))) {
88
+ setFromToken(null);
89
+ }
90
+ }
91
+
92
+ if (fromBlockchain && fromBlockchainsConfig) {
93
+ if (!fromBlockchainsConfig.includes(fromBlockchain.name)) {
94
+ setFromBlockchain(null);
95
+ }
96
+ }
97
+ }, [fromTokensConfig, fromBlockchainsConfig]);
98
+
99
+ useEffect(() => {
100
+ if (toToken && toTokensConfig) {
101
+ if (!toTokensConfig.some((token) => tokensAreEqual(token, toToken))) {
102
+ setToToken(null);
103
+ }
104
+ }
105
+
106
+ if (toBlockchain && toBlockchainsConfig) {
107
+ if (!toBlockchainsConfig.includes(toBlockchain.name)) {
108
+ setToBlockchain(null);
109
+ }
110
+ }
111
+ }, [toTokensConfig, toBlockchainsConfig]);
112
+
65
113
  useEffect(() => {
66
114
  if (loadingMetaStatus === 'success') {
67
115
  const chain = blockchains.find(
@@ -1,22 +1,20 @@
1
+ /* eslint-disable @typescript-eslint/no-magic-numbers */
1
2
  import type { WidgetTheme } from '../types';
2
3
 
3
4
  import {
4
5
  createTheme,
5
- darkTheme,
6
- lightTheme,
7
- darkColors as mainDarkColors,
8
- theme as mainTheme,
6
+ darkTheme as defaultDarkTheme,
7
+ lightTheme as defaultLightTheme,
9
8
  } from '@rango-dev/ui';
10
9
  import { useEffect, useState } from 'react';
11
10
 
12
- import { DEFAULT_FONT_FAMILY } from '../constants/fonts';
13
- import { useMetaStore } from '../store/meta';
14
11
  import { useSettingsStore } from '../store/settings';
15
- import { generateColors } from '../utils/colors';
16
12
  import {
13
+ DEFAULT_FONT_FAMILY,
17
14
  DEFAULT_PRIMARY_RADIUS,
18
15
  DEFAULT_SECONDARY_RADIUS,
19
16
  } from '../utils/configs';
17
+ import { customizedThemeTokens } from '../utils/ui';
20
18
 
21
19
  export function useTheme(props: WidgetTheme) {
22
20
  const {
@@ -26,12 +24,14 @@ export function useTheme(props: WidgetTheme) {
26
24
  secondaryBorderRadius = DEFAULT_SECONDARY_RADIUS,
27
25
  mode = 'auto',
28
26
  } = props;
29
- const theme = useSettingsStore.use.theme();
30
- const mainColors = mainTheme.colors;
31
27
 
32
- const fetchMeta = useMetaStore.use.fetchMeta();
28
+ const [OSTheme, setOSTheme] = useState('light');
29
+ const theme = useSettingsStore.use.theme();
33
30
  const setTheme = useSettingsStore.use.setTheme();
34
- const customTheme = createTheme({
31
+
32
+ const { dark, light } = customizedThemeTokens(colors);
33
+
34
+ const baseTheme = createTheme({
35
35
  radii: {
36
36
  primary: `${borderRadius}px`,
37
37
  secondary: `${secondaryBorderRadius}px`,
@@ -40,49 +40,24 @@ export function useTheme(props: WidgetTheme) {
40
40
  widget: fontFamily,
41
41
  },
42
42
  });
43
+ const lightThemeClasses = [baseTheme.className, defaultLightTheme.className];
44
+ const darkThemeClasses = [baseTheme.className, defaultDarkTheme.className];
43
45
 
44
- const darkColors = generateColors(
45
- {
46
- ...mainColors,
47
- ...mainDarkColors,
48
- },
49
- colors?.dark
50
- );
51
- const lightColors = generateColors(mainColors, colors?.light);
52
- const customLightTheme = Object.keys(lightColors).length
53
- ? createTheme({
54
- colors: lightColors,
55
- })
56
- : lightTheme;
57
- const customDarkTheme = Object.keys(darkColors).length
58
- ? createTheme({
59
- colors: {
60
- ...darkColors,
61
- neutral100: darkColors.neutral900,
62
- neutral200: darkColors.neutral800,
63
- neutral300: darkColors.neutral700,
64
- neutral400: darkColors.neutral600,
65
- neutral500: darkColors.neutral500,
66
- neutral600: darkColors.neutral400,
67
- neutral700: darkColors.neutral300,
68
- neutral800: darkColors.neutral200,
69
- neutral900: darkColors.neutral100,
70
- },
71
- })
72
- : darkTheme;
73
-
74
- const lightClassName = `${customTheme.className} ${customLightTheme.className}`;
75
- const darkClassName = `${customTheme.className} ${customDarkTheme.className}`;
76
-
77
- const [OSTheme, setOSTheme] = useState('light');
46
+ /*
47
+ * If theme has been customized, we will push the customized theme to override the default themes.
48
+ * To be overridden, it should be last thing that has been pushed.
49
+ */
50
+ if (light) {
51
+ const customizedLightTheme = createTheme(light.id, light.tokens);
52
+ lightThemeClasses.push(customizedLightTheme.className);
53
+ }
54
+ if (dark) {
55
+ const customizedDarkTheme = createTheme(dark.id, dark.tokens);
56
+ darkThemeClasses.push(customizedDarkTheme.className);
57
+ }
78
58
 
79
59
  useEffect(() => {
80
- const fetchData = async () => {
81
- await fetchMeta();
82
- };
83
- void fetchData();
84
-
85
- const switchTheme = (event: MediaQueryListEvent) => {
60
+ const switchThemeListener = (event: MediaQueryListEvent) => {
86
61
  if (event.matches) {
87
62
  setOSTheme('dark');
88
63
  } else {
@@ -99,13 +74,14 @@ export function useTheme(props: WidgetTheme) {
99
74
 
100
75
  window
101
76
  .matchMedia('(prefers-color-scheme: dark)')
102
- .addEventListener('change', switchTheme);
77
+ .addEventListener('change', switchThemeListener);
103
78
  return () => {
104
79
  window
105
80
  .matchMedia('(prefers-color-scheme: dark)')
106
- .removeEventListener('change', switchTheme);
81
+ .removeEventListener('change', switchThemeListener);
107
82
  };
108
83
  }, []);
84
+
109
85
  useEffect(() => {
110
86
  if (mode !== 'auto') {
111
87
  setTheme(mode);
@@ -113,11 +89,13 @@ export function useTheme(props: WidgetTheme) {
113
89
  }, [mode]);
114
90
 
115
91
  const getActiveTheme = () => {
92
+ const lightClassNames = lightThemeClasses.join(' ');
93
+ const darkClassNames = darkThemeClasses.join(' ');
116
94
  if (theme === 'auto') {
117
- return OSTheme === 'dark' ? darkClassName : lightClassName;
95
+ return OSTheme === 'dark' ? darkClassNames : lightClassNames;
118
96
  }
119
- return theme === 'dark' ? darkClassName : lightClassName;
97
+ return theme === 'dark' ? darkClassNames : lightClassNames;
120
98
  };
121
99
 
122
- return { activeTheme: getActiveTheme() };
100
+ return { activeTheme: getActiveTheme };
123
101
  }
@@ -363,7 +363,7 @@ export function ConfirmSwapPage(props: PropTypes) {
363
363
  size="small"
364
364
  variant="ghost"
365
365
  onClick={() => navigate('/' + navigationRoutes.settings)}>
366
- <Typography variant="label" size="medium" color="$neutral900">
366
+ <Typography variant="label" size="medium" color="$neutral700">
367
367
  {i18n.t('Change settings')}
368
368
  </Typography>
369
369
  </Button>
@@ -382,26 +382,17 @@ export function ConfirmSwapPage(props: PropTypes) {
382
382
  description={
383
383
  confirmSwapResult.warnings.slippage.type ===
384
384
  SlippageWarningType.HIGH_SLIPPAGE
385
- ? i18n.t(
386
- 'highSlippage',
387
- { selectedSlippage },
388
- {
389
- message:
390
- ' Caution, your slippage is high (={selectedSlippage}). Your trade may be front run.',
391
- }
392
- )
393
- : i18n.t(
394
- 'increaseSlippage',
395
-
396
- {
385
+ ? i18n.t({
386
+ id: ' Caution, your slippage is high (={selectedSlippage}). Your trade may be front run.',
387
+ values: { selectedSlippage },
388
+ })
389
+ : i18n.t({
390
+ id: 'We recommend you to increase slippage to at least {minRequiredSlippage} for this route.',
391
+ values: {
397
392
  minRequiredSlippage:
398
393
  confirmSwapResult.warnings.slippage.slippage,
399
394
  },
400
- {
401
- message:
402
- 'We recommend you to increase slippage to at least {minRequiredSlippage} for this route.',
403
- }
404
- )
395
+ })
405
396
  }>
406
397
  <Divider size={18} />
407
398
  <Divider size={32} />
@@ -245,18 +245,17 @@ export function Home() {
245
245
  title={recommendation}
246
246
  footer={
247
247
  <FooterAlert>
248
- <Typography size="xsmall" variant="body" color="neutral900">
248
+ <Typography size="xsmall" variant="body" color="neutral700">
249
249
  {fromAmountRangeError}
250
250
  </Typography>
251
251
  <Divider direction="horizontal" size={8} />
252
- <Typography size="xsmall" variant="body" color="neutral900">
252
+ <Typography size="xsmall" variant="body" color="neutral700">
253
253
  |
254
254
  </Typography>
255
255
  <Divider direction="horizontal" size={8} />
256
- <Typography size="xsmall" variant="body" color="neutral900">
256
+ <Typography size="xsmall" variant="body" color="neutral700">
257
257
  {i18n.t({
258
- id: 'yourSymbol',
259
- message: 'Yours: {amount} {symbol}',
258
+ id: 'Yours: {amount} {symbol}',
260
259
  values: {
261
260
  amount: numberToString(
262
261
  swapHasError?.fromAmount || null,
@@ -347,7 +346,7 @@ export function Home() {
347
346
  USD_VALUE_MAX_DECIMALS
348
347
  ),
349
348
  error: priceImpactInputCanNotBeComputed
350
- ? errorMessages.unknownPriceError.impactTitle
349
+ ? errorMessages().unknownPriceError.impactTitle
351
350
  : undefined,
352
351
  }}
353
352
  disabled={loadingMetaStatus === 'failed'}
@@ -398,7 +397,7 @@ export function Home() {
398
397
  USD_VALUE_MAX_DECIMALS
399
398
  ),
400
399
  error: priceImpactOutputCanNotBeComputed
401
- ? errorMessages.unknownPriceError.impactTitle
400
+ ? errorMessages().unknownPriceError.impactTitle
402
401
  : undefined,
403
402
  }}
404
403
  onClickToken={() => navigate('to-swap')}