@rango-dev/widget-embedded 0.1.10 → 0.1.11-next.10

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 (88) hide show
  1. package/dist/App.d.ts +3 -3
  2. package/dist/App.d.ts.map +1 -1
  3. package/dist/QueueManager.d.ts.map +1 -1
  4. package/dist/components/AppRouter.d.ts +1 -7
  5. package/dist/components/AppRouter.d.ts.map +1 -1
  6. package/dist/components/AppRoutes.d.ts +2 -2
  7. package/dist/components/AppRoutes.d.ts.map +1 -1
  8. package/dist/components/Layout.d.ts +3 -3
  9. package/dist/components/Layout.d.ts.map +1 -1
  10. package/dist/components/PercentageChange.d.ts +9 -0
  11. package/dist/components/PercentageChange.d.ts.map +1 -0
  12. package/dist/components/TokenInfo.d.ts.map +1 -1
  13. package/dist/components/TokenPreview.d.ts +2 -1
  14. package/dist/components/TokenPreview.d.ts.map +1 -1
  15. package/dist/hooks/useConfirmSwap.d.ts.map +1 -1
  16. package/dist/hooks/useTheme.d.ts +2 -5
  17. package/dist/hooks/useTheme.d.ts.map +1 -1
  18. package/dist/lib.d.ts +2 -2
  19. package/dist/lib.d.ts.map +1 -1
  20. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  21. package/dist/pages/Home.d.ts +1 -7
  22. package/dist/pages/Home.d.ts.map +1 -1
  23. package/dist/pages/LiquiditySourcesPage.d.ts +1 -2
  24. package/dist/pages/LiquiditySourcesPage.d.ts.map +1 -1
  25. package/dist/pages/SelectChainPage.d.ts +1 -2
  26. package/dist/pages/SelectChainPage.d.ts.map +1 -1
  27. package/dist/pages/SelectTokenPage.d.ts +2 -2
  28. package/dist/pages/SelectTokenPage.d.ts.map +1 -1
  29. package/dist/pages/SettingsPage.d.ts +1 -2
  30. package/dist/pages/SettingsPage.d.ts.map +1 -1
  31. package/dist/pages/SwapDetailsPage.d.ts.map +1 -1
  32. package/dist/pages/WalletsPage.d.ts +1 -1
  33. package/dist/pages/WalletsPage.d.ts.map +1 -1
  34. package/dist/services/httpService.d.ts +2 -1
  35. package/dist/services/httpService.d.ts.map +1 -1
  36. package/dist/store/bestRoute.d.ts +1 -0
  37. package/dist/store/bestRoute.d.ts.map +1 -1
  38. package/dist/store/meta.d.ts.map +1 -1
  39. package/dist/store/settings.d.ts +2 -0
  40. package/dist/store/settings.d.ts.map +1 -1
  41. package/dist/types/config.d.ts +27 -29
  42. package/dist/types/config.d.ts.map +1 -1
  43. package/dist/types/routing.d.ts +14 -1
  44. package/dist/types/routing.d.ts.map +1 -1
  45. package/dist/utils/configs.d.ts +7 -0
  46. package/dist/utils/configs.d.ts.map +1 -0
  47. package/dist/utils/routing.d.ts +2 -2
  48. package/dist/utils/routing.d.ts.map +1 -1
  49. package/dist/utils/swap.d.ts +2 -6
  50. package/dist/utils/swap.d.ts.map +1 -1
  51. package/dist/widget-embedded.cjs.development.js +232 -223
  52. package/dist/widget-embedded.cjs.development.js.map +1 -1
  53. package/dist/widget-embedded.cjs.production.min.js +232 -223
  54. package/dist/widget-embedded.cjs.production.min.js.map +1 -1
  55. package/dist/widget-embedded.esm.js +232 -223
  56. package/dist/widget-embedded.esm.js.map +1 -1
  57. package/package.json +6 -4
  58. package/readme.md +1 -1
  59. package/src/App.tsx +36 -14
  60. package/src/QueueManager.tsx +9 -3
  61. package/src/components/AppRouter.tsx +7 -16
  62. package/src/components/AppRoutes.tsx +13 -32
  63. package/src/components/HeaderButtons.tsx +1 -1
  64. package/src/components/Layout.tsx +37 -27
  65. package/src/components/PercentageChange.tsx +33 -0
  66. package/src/components/TokenInfo.tsx +24 -12
  67. package/src/components/TokenPreview.tsx +19 -15
  68. package/src/hooks/useConfirmSwap.ts +6 -5
  69. package/src/hooks/useTheme.ts +21 -9
  70. package/src/lib.tsx +30 -36
  71. package/src/pages/ConfirmSwapPage.tsx +14 -7
  72. package/src/pages/Home.tsx +10 -22
  73. package/src/pages/LiquiditySourcesPage.tsx +3 -6
  74. package/src/pages/SelectChainPage.tsx +6 -6
  75. package/src/pages/SelectTokenPage.tsx +16 -18
  76. package/src/pages/SettingsPage.tsx +8 -18
  77. package/src/pages/SwapDetailsPage.tsx +2 -4
  78. package/src/pages/WalletsPage.tsx +2 -2
  79. package/src/services/httpService.ts +12 -3
  80. package/src/store/bestRoute.ts +39 -9
  81. package/src/store/meta.ts +6 -4
  82. package/src/store/settings.ts +7 -0
  83. package/src/store/wallets.ts +1 -1
  84. package/src/types/config.ts +28 -29
  85. package/src/types/routing.ts +17 -1
  86. package/src/utils/configs.ts +24 -0
  87. package/src/utils/routing.ts +29 -23
  88. package/src/utils/swap.ts +5 -97
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/widget-embedded",
3
- "version": "0.1.10",
3
+ "version": "0.1.11-next.10",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -10,7 +10,9 @@
10
10
  ],
11
11
  "browserslist": "> 0.5%, last 2 versions, not dead",
12
12
  "scripts": {
13
+ "watch-tsc": "tsc --watch --noEmit",
13
14
  "dev": "parcel public/index.html -p 3001 --cache-dir=.parcel-cache",
15
+ "dev-tsc": "npm-run-all --parallel watch-tsc dev",
14
16
  "build:app": "parcel build --cache-dir=.parcel-cache",
15
17
  "build": "tsdx build --entry ./src/lib.tsx"
16
18
  },
@@ -27,10 +29,10 @@
27
29
  },
28
30
  "dependencies": {
29
31
  "@rango-dev/provider-all": "^0.1.11-next.84",
30
- "@rango-dev/queue-manager-core": "^0.1.10-next.82",
31
- "@rango-dev/queue-manager-rango-preset": "^0.1.10-next.102",
32
+ "@rango-dev/queue-manager-core": "^0.1.11-next.0",
33
+ "@rango-dev/queue-manager-rango-preset": "^0.1.11-next.3",
32
34
  "@rango-dev/queue-manager-react": "^0.1.10-next.76",
33
- "@rango-dev/ui": "^0.1.10-next.75",
35
+ "@rango-dev/ui": "^0.1.11-next.4",
34
36
  "@rango-dev/wallets-core": "^0.1.11-next.88",
35
37
  "@rango-dev/wallets-shared": "^0.1.11-next.84",
36
38
  "bignumber.js": "^9.1.1",
package/readme.md CHANGED
@@ -1 +1 @@
1
- # @rango-dev/widget-embedded
1
+ # @rango-dev/widget-embedded
package/src/App.tsx CHANGED
@@ -1,5 +1,5 @@
1
1
  import { SwapContainer } from '@rango-dev/ui';
2
- import React, { useState } from 'react';
2
+ import React, { useEffect, useMemo, useState } from 'react';
3
3
  import { AppRouter } from './components/AppRouter';
4
4
  import { useMetaStore } from './store/meta';
5
5
  import './app.css';
@@ -17,24 +17,29 @@ import { globalFont, globalStyles } from './globalStyles';
17
17
  import { useTheme } from './hooks/useTheme';
18
18
  import QueueManager from './QueueManager';
19
19
  import { isEvmBlockchain } from 'rango-sdk';
20
- import { Configs } from './types';
20
+ import { WidgetConfig } from './types';
21
21
  import './i18n';
22
22
  import { useUiStore } from './store/ui';
23
23
  import { navigationRoutes } from './constants/navigationRoutes';
24
+ import { initConfig } from './utils/configs';
24
25
 
25
26
  const providers = allProviders();
26
27
 
27
28
  export type WidgetProps = {
28
- configs?: Configs;
29
+ config?: WidgetConfig;
29
30
  };
30
31
 
31
- export function App({ configs }: WidgetProps) {
32
+ export function App({ config }: WidgetProps) {
32
33
  globalStyles();
33
- globalFont(configs?.fontFamily || 'Roboto');
34
- const { activeTheme } = useTheme({
35
- ...configs?.colors,
36
- borderRadius: configs?.borderRadius,
37
- });
34
+ globalFont(config?.theme?.fontFamily || 'Roboto');
35
+ const { activeTheme } = useTheme({ ...config?.theme });
36
+ useMemo(() => {
37
+ if (config?.apiKey) {
38
+ initConfig({
39
+ API_KEY: config?.apiKey,
40
+ });
41
+ }
42
+ }, [config]);
38
43
 
39
44
  const { blockchains } = useMetaStore.use.meta();
40
45
  const disconnectWallet = useWalletsStore.use.disconnectWallet();
@@ -49,6 +54,12 @@ export function App({ configs }: WidgetProps) {
49
54
  .filter(isEvmBlockchain)
50
55
  .map((chain) => chain.name);
51
56
 
57
+ const themeBackground = activeTheme?.colors?.background?.value;
58
+
59
+ useEffect(() => {
60
+ document.body.style.background = themeBackground;
61
+ }, [themeBackground]);
62
+
52
63
  const onUpdateState: EventHandler = (
53
64
  type,
54
65
  event,
@@ -95,18 +106,29 @@ export function App({ configs }: WidgetProps) {
95
106
  >
96
107
  <div id="pageContainer" className={activeTheme}>
97
108
  <QueueManager>
98
- <SwapContainer fixedHeight={currentPage != navigationRoutes.home}>
109
+ <SwapContainer
110
+ // style={
111
+ // currentPage !== navigationRoutes.home && config?.theme?.height
112
+ // ? {
113
+ // height: config?.theme?.height,
114
+ // width: config?.theme?.width || 'auto',
115
+ // }
116
+ // : config?.theme?.width
117
+ // ? {
118
+ // width: config?.theme?.width || 'auto',
119
+ // }
120
+ // : undefined
121
+ // }
122
+ fixedHeight={currentPage !== navigationRoutes.home}
123
+ >
99
124
  <AppRouter
100
- title={configs?.title}
101
- titleSize={configs?.titleSize}
102
- titleWeight={configs?.titleWeight}
103
125
  lastConnectedWallet={lastConnectedWalletWithNetwork}
104
126
  disconnectedWallet={disconnectedWallet}
105
127
  clearDisconnectedWallet={() => {
106
128
  setDisconnectedWallet(undefined);
107
129
  }}
108
130
  >
109
- <Layout configs={configs} />
131
+ <Layout config={config} />
110
132
  </AppRouter>
111
133
  </SwapContainer>
112
134
  </QueueManager>
@@ -1,7 +1,7 @@
1
- import React, { PropsWithChildren } from 'react';
1
+ import React, { PropsWithChildren, useMemo } from 'react';
2
2
  import { Provider as ManagerProvider } from '@rango-dev/queue-manager-react';
3
3
  import {
4
- swapQueueDef,
4
+ makeQueueDefinition,
5
5
  SwapQueueContext,
6
6
  checkWaitingForNetworkChange,
7
7
  } from '@rango-dev/queue-manager-rango-preset';
@@ -15,6 +15,7 @@ import { useMetaStore } from './store/meta';
15
15
  import { useWalletsStore } from './store/wallets';
16
16
  import { walletAndSupportedChainsNames } from './utils/wallets';
17
17
  import { isEvmBlockchain } from 'rango-sdk';
18
+ import { getConfig } from './utils/configs';
18
19
 
19
20
  function QueueManager(props: PropsWithChildren<{}>) {
20
21
  const {
@@ -26,6 +27,11 @@ function QueueManager(props: PropsWithChildren<{}>) {
26
27
  getWalletInfo,
27
28
  } = useWallets();
28
29
 
30
+ const swapQueueDef = useMemo(() => {
31
+ return makeQueueDefinition({
32
+ API_KEY: getConfig('API_KEY'),
33
+ });
34
+ }, []);
29
35
  const { blockchains } = useMetaStore.use.meta();
30
36
  const balances = useWalletsStore.use.balances();
31
37
 
@@ -63,7 +69,7 @@ function QueueManager(props: PropsWithChildren<{}>) {
63
69
  blockchains: allBlockchains,
64
70
  evmBasedChains: evmBasedChains,
65
71
  evmNetworkChainInfo:
66
- convertEvmBlockchainMetaToEvmChainInfo(evmBasedChains),
72
+ convertEvmBlockchainMetaToEvmChainInfo(evmBasedChains),
67
73
  getSupportedChainNames,
68
74
  },
69
75
  getSigners,
@@ -13,15 +13,7 @@ import { UpdateUrl } from './UpdateUrl';
13
13
  import { Home } from '../pages/Home';
14
14
  import { useMetaStore } from '../store/meta';
15
15
 
16
- interface PropTypes {
17
- title?: string;
18
- titleSize?: number;
19
- titleWeight?: number;
20
- }
21
- const Route: React.FC = ({
22
- children,
23
- ...props
24
- }: PropTypes & PropsWithChildren) => {
16
+ const Route: React.FC = ({ children }: PropsWithChildren) => {
25
17
  const location = useLocation();
26
18
  const navigate = useNavigate();
27
19
  const ref = useRef(true);
@@ -34,7 +26,7 @@ const Route: React.FC = ({
34
26
  }, []);
35
27
 
36
28
  if (location.pathname === navigationRoutes.confirmSwap && ref.current)
37
- return <Home {...props} />;
29
+ return <Home />;
38
30
 
39
31
  return <> {children}</>;
40
32
  };
@@ -42,12 +34,11 @@ const Route: React.FC = ({
42
34
  export function AppRouter({
43
35
  children,
44
36
  ...props
45
- }: PropTypes &
46
- PropsWithChildren & {
47
- lastConnectedWallet: string;
48
- disconnectedWallet: WalletType | undefined;
49
- clearDisconnectedWallet: () => void;
50
- }) {
37
+ }: PropsWithChildren & {
38
+ lastConnectedWallet: string;
39
+ disconnectedWallet: WalletType | undefined;
40
+ clearDisconnectedWallet: () => void;
41
+ }) {
51
42
  const isRouterInContext = useInRouterContext();
52
43
  const Router = isRouterInContext ? Route : MemoryRouter;
53
44
  const { blockchains } = useMetaStore.use.meta();
@@ -10,76 +10,57 @@ import { SelectTokenPage } from '../pages/SelectTokenPage';
10
10
  import { SettingsPage } from '../pages/SettingsPage';
11
11
  import { WalletsPage } from '../pages/WalletsPage';
12
12
  import { SwapDetailsPage } from '../pages/SwapDetailsPage';
13
- import { Configs } from '../types';
13
+ import { WidgetConfig } from '../types';
14
14
 
15
15
  const getAbsolutePath = (path: string) => path.replace('/', '');
16
16
 
17
17
  interface PropTypes {
18
- configs?: Configs;
18
+ config?: WidgetConfig;
19
19
  }
20
20
 
21
21
  export function AppRoutes(props: PropTypes) {
22
- const { configs } = props;
22
+ const { config } = props;
23
23
 
24
24
  return useRoutes([
25
25
  {
26
26
  path: getAbsolutePath(navigationRoutes.home),
27
- element: (
28
- <Home
29
- title={configs?.title}
30
- titleSize={configs?.titleSize}
31
- titleWeight={configs?.titleWeight}
32
- />
33
- ),
27
+ element: <Home />,
34
28
  },
35
29
  {
36
30
  path: getAbsolutePath(navigationRoutes.fromChain),
37
31
  element: (
38
32
  <SelectChainPage
39
33
  type="from"
40
- supportedChains={configs?.fromChains || 'all'}
34
+ supportedChains={config?.from?.blockchains}
41
35
  />
42
36
  ),
43
37
  },
44
38
  {
45
39
  path: getAbsolutePath(navigationRoutes.toChain),
46
40
  element: (
47
- <SelectChainPage
48
- type="to"
49
- supportedChains={configs?.toChains || 'all'}
50
- />
41
+ <SelectChainPage type="to" supportedChains={config?.to?.blockchains} />
51
42
  ),
52
43
  },
53
44
  {
54
45
  path: getAbsolutePath(navigationRoutes.fromToken),
55
46
  element: (
56
- <SelectTokenPage
57
- type="from"
58
- supportedTokens={configs?.fromTokens || 'all'}
59
- />
47
+ <SelectTokenPage type="from" supportedTokens={config?.from?.tokens} />
60
48
  ),
61
49
  },
62
50
  {
63
51
  path: getAbsolutePath(navigationRoutes.toToken),
64
52
  element: (
65
- <SelectTokenPage
66
- type="to"
67
- supportedTokens={configs?.toTokens || 'all'}
68
- />
53
+ <SelectTokenPage type="to" supportedTokens={config?.to?.tokens} />
69
54
  ),
70
55
  },
71
56
  {
72
57
  path: getAbsolutePath(navigationRoutes.settings),
73
- element: (
74
- <SettingsPage supportedSwappers={configs?.liquiditySources || 'all'} />
75
- ),
58
+ element: <SettingsPage supportedSwappers={config?.liquiditySources} />,
76
59
  },
77
60
  {
78
61
  path: getAbsolutePath(navigationRoutes.liquiditySources),
79
62
  element: (
80
- <LiquiditySourcePage
81
- supportedSwappers={configs?.liquiditySources || 'all'}
82
- />
63
+ <LiquiditySourcePage supportedSwappers={config?.liquiditySources} />
83
64
  ),
84
65
  },
85
66
  { path: getAbsolutePath(navigationRoutes.swaps), element: <HistoryPage /> },
@@ -91,11 +72,11 @@ export function AppRoutes(props: PropTypes) {
91
72
  path: getAbsolutePath(navigationRoutes.wallets),
92
73
  element: (
93
74
  <WalletsPage
94
- supportedWallets={configs?.wallets || 'all'}
75
+ supportedWallets={config?.wallets}
95
76
  multiWallets={
96
- typeof configs?.multiWallets === 'undefined'
77
+ typeof config?.multiWallets === 'undefined'
97
78
  ? true
98
- : configs.multiWallets
79
+ : config.multiWallets
99
80
  }
100
81
  />
101
82
  ),
@@ -30,7 +30,7 @@ export function HeaderButtons(props: PropTypes) {
30
30
  onClick={onClickRefresh}
31
31
  disabled={!onClickRefresh}
32
32
  >
33
- <RetryIcon size={24} />
33
+ <RetryIcon size={24} disabled={!onClickRefresh} />
34
34
  </Button>
35
35
  </Tooltip>
36
36
  <Tooltip content="Transactions History">
@@ -15,12 +15,15 @@ import { fetchingBalanceSelector, useWalletsStore } from '../store/wallets';
15
15
  import {
16
16
  calculateWalletUsdValue,
17
17
  getSelectableWallets,
18
+ tokensAreEqual,
18
19
  } from '../utils/wallets';
19
20
  import { removeDuplicateFrom } from '../utils/common';
20
- import { Configs } from '../types';
21
+ import { WidgetConfig } from '../types';
21
22
  import { useTranslation } from 'react-i18next';
22
23
  import { useBestRouteStore } from '../store/bestRoute';
23
24
  import { useMetaStore } from '../store/meta';
25
+ import { useSettingsStore } from '../store/settings';
26
+ import { Image } from '@rango-dev/ui';
24
27
 
25
28
  const Header = styled('div', {
26
29
  display: 'flex',
@@ -31,19 +34,17 @@ const Header = styled('div', {
31
34
  },
32
35
  });
33
36
 
34
- const WalletImage = styled('img', {
35
- width: '$24',
36
- height: '$24',
37
+ const WalletImageContainer = styled('div', {
37
38
  marginLeft: -15,
38
39
  marginRight: '$6',
39
40
  borderRadius: '99999px',
40
41
  });
41
42
 
42
43
  export type LayoutProps = {
43
- configs?: Configs;
44
+ config?: WidgetConfig;
44
45
  };
45
46
 
46
- export function Layout({ configs }: LayoutProps) {
47
+ export function Layout({ config }: LayoutProps) {
47
48
  const navigate = useNavigate();
48
49
  const { balances, accounts, selectedWallets } = useWalletsStore();
49
50
  const { getWalletInfo } = useWallets();
@@ -52,12 +53,13 @@ export function Layout({ configs }: LayoutProps) {
52
53
  (w) => w.image
53
54
  )
54
55
  );
55
-
56
+ const { blockchains, tokens } = useMetaStore.use.meta();
56
57
  const setFromChain = useBestRouteStore.use.setFromChain();
57
58
  const setFromToken = useBestRouteStore.use.setFromToken();
58
59
  const setToChain = useBestRouteStore.use.setToChain();
59
60
  const setToToken = useBestRouteStore.use.setToToken();
60
61
  const setInputAmount = useBestRouteStore.use.setInputAmount();
62
+ const setAffiliateRef = useSettingsStore.use.setAffiliateRef();
61
63
 
62
64
  const totalBalance = calculateWalletUsdValue(balances);
63
65
  const connectWalletsButtonDisabled =
@@ -67,29 +69,35 @@ export function Layout({ configs }: LayoutProps) {
67
69
 
68
70
  const { t } = useTranslation();
69
71
  useEffect(() => {
70
- setToChain(configs?.toChain || null);
71
- setToToken(configs?.toToken || null);
72
- }, [configs?.toChain, configs?.toToken]);
72
+ const chain = blockchains.find(
73
+ (chain) => chain.name === config?.to?.blockchain
74
+ );
75
+ const token = tokens.find((t) =>
76
+ tokensAreEqual(t, config?.to?.token || null)
77
+ );
78
+ setToChain(chain || null);
79
+ setToToken(token || null);
80
+ }, [config?.to?.token, config?.to?.blockchain]);
81
+
73
82
  useEffect(() => {
74
- setInputAmount(configs?.fromAmount?.toString() || '');
75
- }, [configs?.fromAmount]);
83
+ setInputAmount(config?.amount?.toString() || '');
84
+ }, [config?.amount]);
76
85
 
77
86
  useEffect(() => {
78
- setFromToken(configs?.fromToken || null);
79
- setFromChain(configs?.fromChain || null);
80
- }, [configs?.fromToken, configs?.fromChain]);
87
+ const chain = blockchains.find(
88
+ (chain) => chain.name === config?.from?.blockchain
89
+ );
90
+ const token = tokens.find((t) =>
91
+ tokensAreEqual(t, config?.from?.token || null)
92
+ );
93
+
94
+ setFromChain(chain || null);
95
+ setFromToken(token || null);
96
+ }, [config?.from?.token, config?.from?.blockchain]);
81
97
 
82
98
  useEffect(() => {
83
- setToChain(null);
84
- setFromChain(null);
85
- setFromToken(null);
86
- setToToken(null);
87
- }, [
88
- configs?.fromChains,
89
- configs?.toChains,
90
- configs?.fromTokens,
91
- configs?.toTokens,
92
- ]);
99
+ setAffiliateRef(config?.affiliateRef || null);
100
+ }, [config?.affiliateRef]);
93
101
  return (
94
102
  <>
95
103
  <Header>
@@ -107,7 +115,9 @@ export function Layout({ configs }: LayoutProps) {
107
115
  >
108
116
  {connectedWalletsImages?.length ? (
109
117
  connectedWalletsImages.map((walletImage, index) => (
110
- <WalletImage key={index} src={walletImage} />
118
+ <WalletImageContainer key={index}>
119
+ <Image src={walletImage} size={24} />
120
+ </WalletImageContainer>
111
121
  ))
112
122
  ) : (
113
123
  <></>
@@ -122,7 +132,7 @@ export function Layout({ configs }: LayoutProps) {
122
132
  </div>
123
133
  </Button>
124
134
  </Header>
125
- <AppRoutes configs={configs} />
135
+ <AppRoutes config={config} />
126
136
  </>
127
137
  );
128
138
  }
@@ -0,0 +1,33 @@
1
+ import BigNumber from 'bignumber.js';
2
+ import React from 'react';
3
+ import { getPercentageChange } from '../utils/swap';
4
+ import { Typography } from '@rango-dev/ui';
5
+ import { numberToString } from '../utils/numbers';
6
+
7
+ interface PropTypes {
8
+ inputUsdValue: BigNumber | null;
9
+ outputUsdValue: BigNumber | null;
10
+ }
11
+
12
+ export function PercentageChange(props: PropTypes) {
13
+ const { inputUsdValue, outputUsdValue } = props;
14
+
15
+ if (!inputUsdValue || !outputUsdValue || !outputUsdValue.gt(0)) return null;
16
+
17
+ const percentageChange = getPercentageChange(
18
+ inputUsdValue.toNumber(),
19
+ outputUsdValue.toNumber()
20
+ );
21
+
22
+ const showPercentageChange = percentageChange?.lt(0);
23
+
24
+ return (
25
+ <>
26
+ {showPercentageChange && (
27
+ <Typography variant="caption" color="$error500">
28
+ {`(${numberToString(percentageChange, 0, 2)}%)`}
29
+ </Typography>
30
+ )}
31
+ </>
32
+ );
33
+ }
@@ -6,6 +6,8 @@ import {
6
6
  styled,
7
7
  TextField,
8
8
  Typography,
9
+ Image,
10
+ Spacer,
9
11
  } from '@rango-dev/ui';
10
12
  import { useMetaStore } from '../store/meta';
11
13
  import { BlockchainMeta, Token } from 'rango-sdk';
@@ -16,7 +18,7 @@ import BigNumber from 'bignumber.js';
16
18
  import { getBalanceFromWallet } from '../utils/wallets';
17
19
  import { useWalletsStore } from '../store/wallets';
18
20
  import { useTranslation } from 'react-i18next';
19
- import { Spacer } from '@rango-dev/ui';
21
+ import { PercentageChange } from './PercentageChange';
20
22
 
21
23
  type PropTypes = (
22
24
  | {
@@ -80,11 +82,13 @@ const Container = styled('div', {
80
82
  width: '30%',
81
83
  },
82
84
  },
83
- });
84
-
85
- const StyledImage = styled('img', {
86
- width: '$24',
87
- maxHeight: '$24',
85
+ '.output-usd': {
86
+ display: 'flex',
87
+ div: {
88
+ display: 'flex',
89
+ paddingLeft: '$8',
90
+ },
91
+ },
88
92
  });
89
93
 
90
94
  const Options = styled('div', {
@@ -201,10 +205,18 @@ export function TokenInfo(props: PropTypes) {
201
205
  </div>
202
206
  </Options>
203
207
  ) : (
204
- <Typography
205
- variant="caption"
206
- color="neutrals600"
207
- >{`$${numberToString(props.outputUsdValue)}`}</Typography>
208
+ <div className="output-usd">
209
+ <PercentageChange
210
+ inputUsdValue={inputUsdValue}
211
+ outputUsdValue={props.outputUsdValue}
212
+ />
213
+ <div>
214
+ <Typography
215
+ variant="caption"
216
+ color="neutrals600"
217
+ >{`$${numberToString(props.outputUsdValue)}`}</Typography>
218
+ </div>
219
+ </div>
208
220
  )}
209
221
  </div>
210
222
  <div className="form">
@@ -218,7 +230,7 @@ export function TokenInfo(props: PropTypes) {
218
230
  loading={loadingStatus === 'loading'}
219
231
  prefix={
220
232
  loadingStatus === 'success' && chain ? (
221
- <StyledImage src={chain.logo} />
233
+ <Image src={chain.logo} size={24} />
222
234
  ) : (
223
235
  <ImagePlaceholder />
224
236
  )
@@ -246,7 +258,7 @@ export function TokenInfo(props: PropTypes) {
246
258
  loading={loadingStatus === 'loading'}
247
259
  prefix={
248
260
  loadingStatus === 'success' && token ? (
249
- <StyledImage src={token.image} />
261
+ <Image src={token.image} size={24} />
250
262
  ) : (
251
263
  <ImagePlaceholder />
252
264
  )
@@ -1,10 +1,11 @@
1
- import React from 'react';
1
+ import React, { ReactNode } from 'react';
2
2
  import { Button, InfoCircleIcon, styled, Typography } from '@rango-dev/ui';
3
3
  import { LoadingStatus } from '../store/meta';
4
4
  import { useTranslation } from 'react-i18next';
5
5
  import { Spacer } from '@rango-dev/ui';
6
6
  import BigNumber from 'bignumber.js';
7
7
  import { numberToString } from '../utils/numbers';
8
+ import { Image } from '@rango-dev/ui';
8
9
 
9
10
  const Box = styled('div', {
10
11
  display: 'flex',
@@ -37,6 +38,9 @@ const Container = styled('div', {
37
38
  justifyContent: 'space-between',
38
39
  alignItems: 'center',
39
40
  minHeight: '32px',
41
+ '.usd-value': {
42
+ paddingLeft: '$8',
43
+ },
40
44
  },
41
45
  '.form': {
42
46
  display: 'flex',
@@ -57,11 +61,6 @@ const Container = styled('div', {
57
61
  },
58
62
  });
59
63
 
60
- const StyledImage = styled('img', {
61
- width: '$24',
62
- maxHeight: '$24',
63
- });
64
-
65
64
  const ImagePlaceholder = styled('span', {
66
65
  width: '24px',
67
66
  height: '24px',
@@ -95,10 +94,11 @@ interface PropTypes {
95
94
  symbol: string;
96
95
  image: string;
97
96
  };
97
+ percentageChange?: ReactNode;
98
98
  }
99
99
 
100
100
  export function TokenPreview(props: PropTypes) {
101
- const { chain, token, loadingStatus } = props;
101
+ const { chain, token, loadingStatus, percentageChange } = props;
102
102
  const { t } = useTranslation();
103
103
 
104
104
  const ItemSuffix = (
@@ -120,12 +120,16 @@ export function TokenPreview(props: PropTypes) {
120
120
  <Typography variant="body2" color="neutrals800">
121
121
  {props.label}
122
122
  </Typography>
123
- {props.usdValue && (
124
- <Typography
125
- variant="caption"
126
- color="neutrals600"
127
- >{`$${numberToString(props.usdValue)}`}</Typography>
128
- )}
123
+ <div>
124
+ {percentageChange}
125
+ {props.usdValue && (
126
+ <Typography
127
+ variant="caption"
128
+ color="neutrals600"
129
+ className="usd-value"
130
+ >{`$${numberToString(props.usdValue)}`}</Typography>
131
+ )}
132
+ </div>
129
133
  </div>
130
134
  <div className="form">
131
135
  <Button
@@ -134,7 +138,7 @@ export function TokenPreview(props: PropTypes) {
134
138
  loading={loadingStatus === 'loading'}
135
139
  prefix={
136
140
  loadingStatus === 'success' && chain ? (
137
- <StyledImage src={chain.logo} />
141
+ <Image src={chain.logo} size={24} />
138
142
  ) : (
139
143
  <ImagePlaceholder />
140
144
  )
@@ -154,7 +158,7 @@ export function TokenPreview(props: PropTypes) {
154
158
  loading={loadingStatus === 'loading'}
155
159
  prefix={
156
160
  loadingStatus === 'success' && token ? (
157
- <StyledImage src={token.image} />
161
+ <Image src={token.image} size={24} />
158
162
  ) : (
159
163
  <ImagePlaceholder />
160
164
  )