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

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 (134) hide show
  1. package/dist/components/AppRoutes.d.ts.map +1 -1
  2. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts +1 -283
  3. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts.map +1 -1
  4. package/dist/components/ConfirmWalletsModal/ConfirmWalletsModal.d.ts.map +1 -1
  5. package/dist/components/HeaderButtons/HeaderButtons.d.ts.map +1 -1
  6. package/dist/components/HeaderButtons/HeaderButtons.styles.d.ts +489 -1
  7. package/dist/components/HeaderButtons/HeaderButtons.styles.d.ts.map +1 -1
  8. package/dist/components/HeaderButtons/InProgressTransactionBadge.d.ts +4 -0
  9. package/dist/components/HeaderButtons/InProgressTransactionBadge.d.ts.map +1 -0
  10. package/dist/components/HeaderButtons/RefreshButton.d.ts.map +1 -1
  11. package/dist/components/HeaderButtons/UnreadNotificationsBadge.d.ts.map +1 -1
  12. package/dist/components/HeaderButtons/WalletButton.d.ts.map +1 -1
  13. package/dist/components/Layout/Layout.styles.d.ts.map +1 -1
  14. package/dist/components/LoadingLiquiditySourceList/LoadingLiquiditySourceList.styles.d.ts +1 -1
  15. package/dist/components/LoadingLiquiditySourceList/LoadingLiquiditySourceList.styles.d.ts.map +1 -1
  16. package/dist/components/NoResult/NoResult.d.ts.map +1 -1
  17. package/dist/components/NoResult/NoResult.helpers.d.ts +8 -0
  18. package/dist/components/NoResult/NoResult.helpers.d.ts.map +1 -1
  19. package/dist/components/NoResult/NoResult.styles.d.ts +167 -1
  20. package/dist/components/NoResult/NoResult.styles.d.ts.map +1 -1
  21. package/dist/components/NoResult/NoResult.types.d.ts +1 -0
  22. package/dist/components/NoResult/NoResult.types.d.ts.map +1 -1
  23. package/dist/components/NotificationContent/NotificationContent.d.ts.map +1 -1
  24. package/dist/components/NotificationContent/NotificationContent.styles.d.ts +165 -0
  25. package/dist/components/NotificationContent/NotificationContent.styles.d.ts.map +1 -1
  26. package/dist/components/Quote/Quote.d.ts.map +1 -1
  27. package/dist/components/Quote/Quote.styles.d.ts.map +1 -1
  28. package/dist/components/Quote/Quote.types.d.ts +1 -0
  29. package/dist/components/Quote/Quote.types.d.ts.map +1 -1
  30. package/dist/components/Quote/QuoteTrigger.d.ts.map +1 -1
  31. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.d.ts.map +1 -1
  32. package/dist/components/Quotes/Quotes.d.ts.map +1 -1
  33. package/dist/components/Quotes/Quotes.types.d.ts +1 -0
  34. package/dist/components/Quotes/Quotes.types.d.ts.map +1 -1
  35. package/dist/components/Quotes/SelectStrategy.d.ts.map +1 -1
  36. package/dist/components/Slippage/Slippage.d.ts.map +1 -1
  37. package/dist/components/TokenList/TokenList.d.ts.map +1 -1
  38. package/dist/components/common/ActivateTabAlert/ActivateTabAlert.d.ts.map +1 -1
  39. package/dist/constants/navigationRoutes.d.ts +0 -1
  40. package/dist/constants/navigationRoutes.d.ts.map +1 -1
  41. package/dist/constants/settings.d.ts +6 -0
  42. package/dist/constants/settings.d.ts.map +1 -0
  43. package/dist/containers/App/App.styles.d.ts.map +1 -1
  44. package/dist/containers/ExpandedQuotes/ExpandedQuotes.d.ts.map +1 -1
  45. package/dist/containers/ExpandedQuotes/ExpandedQuotes.styles.d.ts +3 -1
  46. package/dist/containers/ExpandedQuotes/ExpandedQuotes.styles.d.ts.map +1 -1
  47. package/dist/containers/QuoteInfo/QuoteInfo.d.ts.map +1 -1
  48. package/dist/containers/QuoteInfo/QuoteInfo.types.d.ts +1 -0
  49. package/dist/containers/QuoteInfo/QuoteInfo.types.d.ts.map +1 -1
  50. package/dist/containers/Settings/Lists.d.ts +3 -0
  51. package/dist/containers/Settings/Lists.d.ts.map +1 -0
  52. package/dist/hooks/useScreenDetect.d.ts +9 -0
  53. package/dist/hooks/useScreenDetect.d.ts.map +1 -0
  54. package/dist/hooks/useSwapInput.d.ts.map +1 -1
  55. package/dist/index.js +2 -2
  56. package/dist/index.js.map +4 -4
  57. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  58. package/dist/pages/Home.d.ts.map +1 -1
  59. package/dist/pages/LiquiditySourcePage.d.ts.map +1 -1
  60. package/dist/pages/SettingsPage.d.ts.map +1 -1
  61. package/dist/store/slices/data.d.ts.map +1 -1
  62. package/dist/store/slices/settings.d.ts.map +1 -1
  63. package/dist/types/config.d.ts +9 -5
  64. package/dist/types/config.d.ts.map +1 -1
  65. package/dist/utils/colors.d.ts +5 -3
  66. package/dist/utils/colors.d.ts.map +1 -1
  67. package/dist/utils/configs.d.ts +2 -1
  68. package/dist/utils/configs.d.ts.map +1 -1
  69. package/dist/utils/swap.d.ts +2 -0
  70. package/dist/utils/swap.d.ts.map +1 -1
  71. package/dist/utils/ui.d.ts +5 -2
  72. package/dist/utils/ui.d.ts.map +1 -1
  73. package/package.json +6 -6
  74. package/src/components/AppRoutes.tsx +0 -5
  75. package/src/components/ConfirmWalletsModal/ConfirmWallets.styles.ts +6 -12
  76. package/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx +7 -11
  77. package/src/components/ConfirmWalletsModal/WalletList.tsx +2 -2
  78. package/src/components/HeaderButtons/HeaderButtons.styles.ts +43 -2
  79. package/src/components/HeaderButtons/HeaderButtons.tsx +2 -0
  80. package/src/components/HeaderButtons/InProgressTransactionBadge.tsx +26 -0
  81. package/src/components/HeaderButtons/RefreshButton.tsx +2 -1
  82. package/src/components/HeaderButtons/UnreadNotificationsBadge.tsx +10 -2
  83. package/src/components/HeaderButtons/WalletButton.tsx +26 -6
  84. package/src/components/Layout/Layout.styles.ts +3 -0
  85. package/src/components/Layout/Layout.tsx +4 -4
  86. package/src/components/LoadingLiquiditySourceList/LoadingLiquiditySourceList.styles.ts +1 -1
  87. package/src/components/LoadingLiquiditySourceList/LoadingLiquiditySourceList.tsx +4 -4
  88. package/src/components/NoResult/NoResult.helpers.ts +13 -0
  89. package/src/components/NoResult/NoResult.styles.ts +19 -1
  90. package/src/components/NoResult/NoResult.tsx +27 -16
  91. package/src/components/NoResult/NoResult.types.ts +1 -0
  92. package/src/components/NotificationContent/NotificationContent.styles.ts +14 -1
  93. package/src/components/NotificationContent/NotificationContent.tsx +49 -39
  94. package/src/components/Quote/Quote.styles.ts +13 -14
  95. package/src/components/Quote/Quote.tsx +166 -145
  96. package/src/components/Quote/Quote.types.ts +1 -0
  97. package/src/components/Quote/QuoteTrigger.tsx +7 -8
  98. package/src/components/QuoteSkeleton/QuoteSkeleton.styles.ts +1 -1
  99. package/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts +2 -3
  100. package/src/components/Quotes/Quotes.tsx +21 -10
  101. package/src/components/Quotes/Quotes.types.ts +1 -0
  102. package/src/components/Quotes/SelectStrategy.tsx +3 -11
  103. package/src/components/Slippage/Slippage.tsx +11 -13
  104. package/src/components/SwapDetails/SwapDetails.tsx +1 -1
  105. package/src/components/TokenList/TokenList.tsx +9 -8
  106. package/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx +2 -4
  107. package/src/constants/navigationRoutes.ts +0 -1
  108. package/src/constants/settings.ts +5 -0
  109. package/src/containers/App/App.styles.ts +0 -4
  110. package/src/containers/ExpandedQuotes/ExpandedQuotes.styles.ts +13 -0
  111. package/src/containers/ExpandedQuotes/ExpandedQuotes.tsx +5 -0
  112. package/src/containers/QuoteInfo/QuoteInfo.tsx +2 -0
  113. package/src/containers/QuoteInfo/QuoteInfo.types.ts +1 -0
  114. package/src/containers/Settings/Lists.tsx +264 -0
  115. package/src/hooks/useScreenDetect.ts +49 -0
  116. package/src/hooks/useSwapInput.ts +7 -2
  117. package/src/pages/ConfirmSwapPage.tsx +7 -3
  118. package/src/pages/Home.tsx +31 -7
  119. package/src/pages/LiquiditySourcePage.tsx +4 -3
  120. package/src/pages/SettingsPage.tsx +6 -185
  121. package/src/store/slices/config.ts +2 -2
  122. package/src/store/slices/data.ts +8 -5
  123. package/src/store/slices/settings.ts +7 -3
  124. package/src/types/config.ts +9 -5
  125. package/src/utils/colors.ts +106 -75
  126. package/src/utils/configs.ts +12 -1
  127. package/src/utils/swap.ts +11 -0
  128. package/src/utils/ui.ts +7 -5
  129. package/dist/hooks/useMobileDetect.d.ts +0 -3
  130. package/dist/hooks/useMobileDetect.d.ts.map +0 -1
  131. package/dist/pages/ThemePage.d.ts +0 -3
  132. package/dist/pages/ThemePage.d.ts.map +0 -1
  133. package/src/hooks/useMobileDetect.ts +0 -21
  134. package/src/pages/ThemePage.tsx +0 -90
@@ -11,7 +11,7 @@ import {
11
11
  } from '@rango-dev/ui';
12
12
  import React from 'react';
13
13
 
14
- import useMobileDetect from '../../hooks/useMobileDetect';
14
+ import useScreenDetect from '../../hooks/useScreenDetect';
15
15
  import { getContainer } from '../../utils/common';
16
16
  import { getUniqueBlockchains } from '../../utils/quote';
17
17
 
@@ -48,7 +48,7 @@ export function QuoteTrigger(props: QuoteTriggerProps) {
48
48
  const tooltipContainer = getContainer();
49
49
  const numberOfSteps = steps.length;
50
50
  const blockchains = getUniqueBlockchains(steps);
51
- const isMobile = useMobileDetect();
51
+ const { isTablet, isMobile } = useScreenDetect();
52
52
 
53
53
  return (
54
54
  <Trigger
@@ -72,15 +72,15 @@ export function QuoteTrigger(props: QuoteTriggerProps) {
72
72
  </IconContainer>
73
73
  );
74
74
 
75
- return isMobile ? (
76
- <>
75
+ return isMobile || isTablet ? (
76
+ <React.Fragment key={key}>
77
77
  <ImageComponent
78
78
  content={step.swapper.displayName}
79
79
  src={step.swapper.image}
80
80
  state={step.state}
81
81
  />
82
82
  {index !== numberOfSteps - 1 && <>{arrow}</>}
83
- </>
83
+ </React.Fragment>
84
84
  ) : (
85
85
  <React.Fragment key={key}>
86
86
  {numberOfSteps <= MAX_STEPS ||
@@ -148,12 +148,11 @@ export function QuoteTrigger(props: QuoteTriggerProps) {
148
148
  </Typography>
149
149
  <Divider direction="horizontal" size={4} />
150
150
  {blockchains.map((blockchain, index) => (
151
- <>
151
+ <React.Fragment key={blockchain.displayName}>
152
152
  {blockchains.length <= MAX_BLOCKCHAINS ||
153
153
  (blockchains.length > MAX_BLOCKCHAINS &&
154
154
  index < MAX_BLOCKCHAINS - 1) ? (
155
155
  <ImageComponent
156
- key={blockchain.displayName}
157
156
  content={''}
158
157
  src={blockchain.image}
159
158
  open={false}
@@ -190,7 +189,7 @@ export function QuoteTrigger(props: QuoteTriggerProps) {
190
189
  </Tooltip>
191
190
  )
192
191
  )}
193
- </>
192
+ </React.Fragment>
194
193
  ))}
195
194
 
196
195
  <Divider direction="horizontal" size={32} />
@@ -27,7 +27,7 @@ export const Steps = styled('div', {
27
27
  });
28
28
 
29
29
  export const StepSeparator = styled('div', {
30
- borderLeft: '1px dashed black',
30
+ borderLeft: '1px dashed $foreground',
31
31
  minHeight: ' 0',
32
32
  margin: '0px 11.5px',
33
33
  alignSelf: 'stretch',
@@ -23,13 +23,12 @@ export function makeAlerts(
23
23
  const alertInfo: AlertInfo = {
24
24
  alertType: 'warning',
25
25
  title: '',
26
- action: 'show-info',
26
+ action: null,
27
27
  };
28
28
  if (error) {
29
29
  alertInfo.alertType = 'error';
30
30
  if (error.type === QuoteErrorType.BRIDGE_LIMIT) {
31
31
  alertInfo.title = error.recommendation;
32
- alertInfo.action = 'show-info';
33
32
  }
34
33
 
35
34
  if (error.type === QuoteErrorType.INSUFFICIENT_SLIPPAGE) {
@@ -50,7 +49,7 @@ export function makeAlerts(
50
49
  if (warningLevel === 'high') {
51
50
  alertInfo.alertType = 'error';
52
51
  }
53
- alertInfo.action = null;
52
+ alertInfo.action = 'show-info';
54
53
  alertInfo.title = errorMessages().highValueLossError.title;
55
54
  }
56
55
  if (warning.type === QuoteWarningType.UNKNOWN_PRICE) {
@@ -2,7 +2,7 @@ import type { PropTypes } from './Quotes.types';
2
2
  import type { MultiRouteSimulationResult } from 'rango-sdk';
3
3
 
4
4
  import { i18n } from '@lingui/core';
5
- import { Divider, Typography } from '@rango-dev/ui';
5
+ import { Divider, FullExpandedQuote, Typography } from '@rango-dev/ui';
6
6
  import React from 'react';
7
7
 
8
8
  import { QuoteInfo } from '../../containers/QuoteInfo';
@@ -26,6 +26,7 @@ export function Quotes(props: PropTypes) {
26
26
  fetch,
27
27
  showModalFee,
28
28
  hasSort = true,
29
+ fullExpandedMode = false,
29
30
  } = props;
30
31
  const {
31
32
  selectedQuote,
@@ -69,12 +70,16 @@ export function Quotes(props: PropTypes) {
69
70
  {loading &&
70
71
  Array.from({ length: ITEM_SKELETON_COUNT }, (_, index) => (
71
72
  <React.Fragment key={index}>
72
- <QuoteSkeleton
73
- tagHidden={false}
74
- type="list-item"
75
- expanded={false}
76
- />
77
- <Divider size={16} />
73
+ {fullExpandedMode ? (
74
+ <FullExpandedQuote loading />
75
+ ) : (
76
+ <QuoteSkeleton
77
+ tagHidden={false}
78
+ type="list-item"
79
+ expanded={false}
80
+ />
81
+ )}
82
+ {index !== ITEM_SKELETON_COUNT - 1 && <Divider size={16} />}
78
83
  </React.Fragment>
79
84
  ))}
80
85
 
@@ -92,9 +97,10 @@ export function Quotes(props: PropTypes) {
92
97
  </>
93
98
  )}
94
99
  {hasQuotes
95
- ? sortQuotes.map((quote) => {
100
+ ? sortQuotes.map((quote, index) => {
96
101
  const quoteWarning = getQuoteWarning(quote);
97
102
  const quoteError = getQuoteError(quote.swaps);
103
+ const lastIndex = sortQuotes.length - 1 === index;
98
104
 
99
105
  return (
100
106
  <React.Fragment key={quote.requestId}>
@@ -106,6 +112,7 @@ export function Quotes(props: PropTypes) {
106
112
  loading={loading}
107
113
  error={quoteError?.options || null}
108
114
  warning={quoteWarning}
115
+ fullExpandedMode={fullExpandedMode}
109
116
  onClick={(quote) => {
110
117
  if (!quoteError) {
111
118
  updateQuotePartialState('warning', quoteWarning);
@@ -118,13 +125,17 @@ export function Quotes(props: PropTypes) {
118
125
  }}
119
126
  type="list-item"
120
127
  />
121
- <Divider size={16} />
128
+ {!lastIndex && <Divider size={16} />}
122
129
  </React.Fragment>
123
130
  );
124
131
  })
125
132
  : showNoResultMessage && (
126
133
  <ErrorsContainer>
127
- <NoResult error={error} fetch={fetch} />
134
+ <NoResult
135
+ size={fullExpandedMode ? 'large' : 'small'}
136
+ error={error}
137
+ fetch={fetch}
138
+ />
128
139
  </ErrorsContainer>
129
140
  )}
130
141
  </>
@@ -6,4 +6,5 @@ export type PropTypes = {
6
6
  fetch: (shouldChangeSelectedQuote?: boolean) => void;
7
7
  showModalFee?: boolean;
8
8
  hasSort?: boolean;
9
+ fullExpandedMode?: boolean;
9
10
  };
@@ -1,5 +1,3 @@
1
- import type { PreferenceType } from 'rango-sdk';
2
-
3
1
  import { Select } from '@rango-dev/ui';
4
2
  import React from 'react';
5
3
 
@@ -16,17 +14,11 @@ export function SelectStrategy(props: { container: HTMLElement }) {
16
14
  <Select
17
15
  container={props.container}
18
16
  options={ROUTE_STRATEGY}
19
- value={
20
- ROUTE_STRATEGY.find(
21
- (strategy) => strategy.value === sortStrategy
22
- ) as {
23
- value: PreferenceType;
24
- label: string;
25
- }
26
- }
17
+ value={sortStrategy}
27
18
  handleItemClick={(item) => {
28
- updateQuotePartialState('sortStrategy', item.value as PreferenceType);
19
+ updateQuotePartialState('sortStrategy', item.value);
29
20
  }}
21
+ variant="filled"
30
22
  />
31
23
  </SelectContainer>
32
24
  );
@@ -47,19 +47,17 @@ export function Slippage() {
47
47
  {SLIPPAGES.map((slippageItem, index) => {
48
48
  const key = `slippage-${index}`;
49
49
  return (
50
- <>
51
- <SlippageChip
52
- key={key}
53
- onClick={() => {
54
- if (customSlippage) {
55
- setCustomSlippage(null);
56
- }
57
- setSlippage(slippageItem);
58
- }}
59
- selected={!customSlippage && slippageItem === slippage}
60
- label={`${slippageItem.toString()}%`}
61
- />
62
- </>
50
+ <SlippageChip
51
+ key={key}
52
+ onClick={() => {
53
+ if (customSlippage) {
54
+ setCustomSlippage(null);
55
+ }
56
+ setSlippage(slippageItem);
57
+ }}
58
+ selected={!customSlippage && slippageItem === slippage}
59
+ label={`${slippageItem.toString()}%`}
60
+ />
63
61
  );
64
62
  })}
65
63
  <TextField
@@ -111,7 +111,7 @@ export function SwapDetails(props: SwapDetailsProps) {
111
111
  setAsRead(swap.requestId);
112
112
  }
113
113
  }
114
- }, [swap.status]);
114
+ }, [swap.status, swap.requestId]);
115
115
 
116
116
  useEffect(() => {
117
117
  if (showSwitchNetwork) {
@@ -19,7 +19,7 @@ import React, { useEffect, useState } from 'react';
19
19
 
20
20
  import { useAppStore } from '../../store/AppStore';
21
21
  import { useWalletsStore } from '../../store/wallets';
22
- import { generateRangeColors } from '../../utils/colors';
22
+ import { generateShade, isBright } from '../../utils/colors';
23
23
  import { formatBalance } from '../../utils/wallets';
24
24
 
25
25
  import { LoadingTokenList } from './LoadingTokenList';
@@ -133,23 +133,24 @@ export function TokenList(props: PropTypes) {
133
133
  const blockchain = blockchains.find(
134
134
  (blockchain) => blockchain.name === token.blockchain
135
135
  );
136
- const color = generateRangeColors(
137
- token.symbol,
138
- blockchain?.color || ''
136
+ const lightShade = generateShade(
137
+ blockchain?.color || '',
138
+ isBright(blockchain?.color || '') ? 5 : 125
139
139
  );
140
+ const darkShade = generateShade(blockchain?.color || '', -100);
140
141
 
141
142
  const customCssForTag = {
142
- $$color: color[`${token.symbol}100`],
143
+ $$color: lightShade,
143
144
  [`.${darkTheme} &`]: {
144
- $$color: color[`${token.symbol}900`],
145
+ $$color: darkShade,
145
146
  },
146
147
  backgroundColor: '$$color',
147
148
  };
148
149
 
149
150
  const customCssForTagTitle = {
150
- $$color: color[`${token.symbol}700`],
151
+ $$color: darkShade,
151
152
  [`.${darkTheme} &`]: {
152
- $$color: color[`${token.symbol}100`],
153
+ $$color: lightShade,
153
154
  },
154
155
  color: '$$color',
155
156
  };
@@ -13,14 +13,12 @@ export function ActivateTabAlert(props: PropTypes) {
13
13
  variant="contained"
14
14
  size="xxsmall"
15
15
  type="warning">
16
- {i18n.t('Activate')}
16
+ {i18n.t('Activate this tab')}
17
17
  </Button>
18
18
  }
19
19
  type="warning"
20
20
  variant="alarm"
21
- title={i18n.t(
22
- 'Another tab is open and handles transactions. You can activate this tab.'
23
- )}
21
+ title={i18n.t('Another tab is open and handles transactions.')}
24
22
  />
25
23
  );
26
24
  }
@@ -5,7 +5,6 @@ export const navigationRoutes = {
5
5
  blockchains: 'blockchains',
6
6
  settings: 'settings',
7
7
  liquiditySources: 'liquidity-sources',
8
- themes: 'themes',
9
8
  bridges: 'bridges',
10
9
  exchanges: 'exchanges',
11
10
  languages: 'languages',
@@ -0,0 +1,5 @@
1
+ export enum ThemeModeEnum {
2
+ DARK = 'dark',
3
+ LIGHT = 'light',
4
+ AUTO = 'auto',
5
+ }
@@ -1,13 +1,9 @@
1
1
  import { styled } from '@rango-dev/ui';
2
2
 
3
3
  export const MainContainer = styled('div', {
4
- display: 'flex',
5
- justifyContent: 'center',
6
- alignItems: 'center',
7
4
  fontFamily: '$widget',
8
5
  boxSizing: 'border-box',
9
6
  textAlign: 'left',
10
-
11
7
  '& *, *::before, *::after': {
12
8
  boxSizing: 'inherit',
13
9
  },
@@ -10,8 +10,21 @@ export const Container = styled('div', {
10
10
  [`.${darkTheme} &`]: {
11
11
  backgroundColor: '$neutral300',
12
12
  },
13
+
14
+ variants: {
15
+ expandMode: {
16
+ default: {
17
+ width: '390px',
18
+ },
19
+ full: {
20
+ width: '719px',
21
+ },
22
+ },
23
+ },
24
+
13
25
  '&.is-hidden': {
14
26
  width: 0,
27
+ height: 0,
15
28
  opacity: 0,
16
29
  marginLeft: 0,
17
30
  },
@@ -9,6 +9,7 @@ import { LayoutContainer } from '../../components/Layout/Layout.styles';
9
9
  import { Quotes } from '../../components/Quotes';
10
10
  import { SelectStrategy } from '../../components/Quotes/SelectStrategy';
11
11
  import { WIDGET_UI_ID } from '../../constants';
12
+ import { useAppStore } from '../../store/AppStore';
12
13
  import { getExpanded } from '../../utils/common';
13
14
 
14
15
  import { Container, Content } from './ExpandedQuotes.styles';
@@ -19,6 +20,8 @@ export function ExpandedQuotes(props: PropTypes) {
19
20
  const { fetch, loading, onClickOnQuote, onClickRefresh, isVisible } = props;
20
21
  const [isDelayedVisible, setIsDelayedVisible] = useState(false);
21
22
  const containerClass = isDelayedVisible ? '' : 'is-hidden';
23
+ const { config } = useAppStore();
24
+ const fullExpandedMode = config?.variant === 'full-expanded';
22
25
 
23
26
  useEffect(() => {
24
27
  let timeout: ReturnType<typeof setTimeout> | null = null;
@@ -43,6 +46,7 @@ export function ExpandedQuotes(props: PropTypes) {
43
46
 
44
47
  return (
45
48
  <Container
49
+ expandMode={config?.variant === 'full-expanded' ? 'full' : 'default'}
46
50
  className={`${containerClass} ${LayoutContainer()}`}
47
51
  id={WIDGET_UI_ID.EXPANDED_BOX_ID}>
48
52
  <Header
@@ -64,6 +68,7 @@ export function ExpandedQuotes(props: PropTypes) {
64
68
  hasSort={false}
65
69
  loading={loading}
66
70
  onClickOnQuote={onClickOnQuote}
71
+ fullExpandedMode={fullExpandedMode}
67
72
  />
68
73
  </Content>
69
74
  </Container>
@@ -25,6 +25,7 @@ export function QuoteInfo(props: PropTypes) {
25
25
  showModalFee,
26
26
  selected,
27
27
  onClickAllRoutes,
28
+ fullExpandedMode = false,
28
29
  } = props;
29
30
  const { inputAmount, inputUsdValue, toToken } = useQuoteStore();
30
31
 
@@ -65,6 +66,7 @@ export function QuoteInfo(props: PropTypes) {
65
66
  type={type}
66
67
  expanded={expanded}
67
68
  onClickAllRoutes={onClickAllRoutes}
69
+ fullExpandedMode={fullExpandedMode}
68
70
  input={{
69
71
  value: inputAmount,
70
72
  usdValue: inputUsdValue?.toString() ?? '',
@@ -14,4 +14,5 @@ export type PropTypes = {
14
14
  onClickAllRoutes?: () => void;
15
15
  selected?: boolean;
16
16
  showModalFee?: boolean;
17
+ fullExpandedMode?: boolean;
17
18
  };
@@ -0,0 +1,264 @@
1
+ import type { ThemeMode } from '../../store/slices/settings';
2
+ import type { ListPropTypes, SvgIconProps } from '@rango-dev/ui';
3
+
4
+ import { i18n } from '@lingui/core';
5
+ import {
6
+ AutoThemeIcon,
7
+ BridgeIcon,
8
+ ChevronRightIcon,
9
+ DarkModeIcon,
10
+ Divider,
11
+ DoneIcon,
12
+ ExchangeIcon,
13
+ InfoIcon,
14
+ LanguageIcon,
15
+ LightModeIcon,
16
+ List,
17
+ ListItem,
18
+ ListItemButton,
19
+ Skeleton,
20
+ styled,
21
+ Switch,
22
+ Tabs,
23
+ Tooltip,
24
+ Typography,
25
+ } from '@rango-dev/ui';
26
+ import React from 'react';
27
+ import { useNavigate } from 'react-router-dom';
28
+
29
+ import { SlippageTooltipContainer as TooltipContainer } from '../../components/Slippage/Slippage.styles';
30
+ import { navigationRoutes } from '../../constants/navigationRoutes';
31
+ import { ThemeModeEnum } from '../../constants/settings';
32
+ import { useAppStore } from '../../store/AppStore';
33
+ import { getContainer } from '../../utils/common';
34
+ import { getUniqueSwappersGroups, isFeatureHidden } from '../../utils/settings';
35
+
36
+ const ThemeSection = styled('div', {
37
+ width: '202px',
38
+ height: '$40',
39
+ });
40
+
41
+ const themesList = [
42
+ {
43
+ id: ThemeModeEnum.LIGHT,
44
+ icon: <LightModeIcon color="black" size={16} />,
45
+ tooltip: (
46
+ <Typography size="xsmall" variant="body">
47
+ {i18n.t('Light')}
48
+ </Typography>
49
+ ),
50
+ },
51
+ {
52
+ id: ThemeModeEnum.DARK,
53
+ icon: <DarkModeIcon color="black" size={14} />,
54
+ tooltip: (
55
+ <Typography size="xsmall" variant="body">
56
+ {i18n.t('Dark')}
57
+ </Typography>
58
+ ),
59
+ },
60
+ {
61
+ id: ThemeModeEnum.AUTO,
62
+ icon: <AutoThemeIcon color="black" size={16} />,
63
+ tooltip: (
64
+ <Typography size="xsmall" variant="body">
65
+ {i18n.t('Auto')}
66
+ </Typography>
67
+ ),
68
+ },
69
+ ];
70
+
71
+ const getThemeIcon = (theme: ThemeMode) => {
72
+ const iconProps: SvgIconProps = { color: 'gray', size: 14 };
73
+
74
+ switch (theme) {
75
+ case 'auto':
76
+ return <AutoThemeIcon {...iconProps} />;
77
+ case 'dark':
78
+ return <DarkModeIcon {...iconProps} />;
79
+ default:
80
+ return <LightModeIcon {...iconProps} />;
81
+ }
82
+ };
83
+
84
+ export function SettingsLists() {
85
+ const navigate = useNavigate();
86
+ const { theme: themeConfig } = useAppStore().config;
87
+ const { setTheme, theme } = useAppStore();
88
+
89
+ const fetchStatus = useAppStore().fetchStatus;
90
+ const swappers = useAppStore().swappers();
91
+ const disabledLiquiditySources = useAppStore().getDisabledLiquiditySources();
92
+ const {
93
+ config: { features },
94
+ } = useAppStore();
95
+ const isThemeHidden = isFeatureHidden('theme', features);
96
+ const isLiquidityHidden = isFeatureHidden('liquiditySource', features);
97
+ const isLanguageHidden = isFeatureHidden('language', features);
98
+
99
+ const infiniteApprove = useAppStore().infiniteApprove;
100
+ const toggleInfiniteApprove = useAppStore().toggleInfiniteApprove;
101
+
102
+ const supportedUniqueSwappersGroups = getUniqueSwappersGroups(
103
+ swappers,
104
+ disabledLiquiditySources
105
+ );
106
+
107
+ const bridgeSources = supportedUniqueSwappersGroups.filter((uniqueItem) =>
108
+ ['BRIDGE', 'AGGREGATOR', 'OFF_CHAIN'].includes(uniqueItem.type)
109
+ );
110
+
111
+ const totalBridgeSources = bridgeSources.length;
112
+ const totalSelectedBridgeSources = bridgeSources.filter(
113
+ (uniqueItem) => uniqueItem.selected
114
+ ).length;
115
+
116
+ const exchangeSources = supportedUniqueSwappersGroups.filter(
117
+ (uniqueItem) => uniqueItem.type === 'DEX'
118
+ );
119
+
120
+ const totalExchangeSources = exchangeSources.length;
121
+ const totalSelectedExchangeSources = exchangeSources.filter(
122
+ (uniqueItem) => uniqueItem.selected
123
+ ).length;
124
+
125
+ const handleEndItem = (totalSelected: number, total: number) => {
126
+ switch (fetchStatus) {
127
+ case 'loading':
128
+ return <Skeleton variant="text" size="medium" width={50} />;
129
+ case 'failed':
130
+ return (
131
+ <Typography variant="body" size="medium" color="$error500">
132
+ {i18n.t('Loading failed')}
133
+ </Typography>
134
+ );
135
+ default:
136
+ return (
137
+ <Typography variant="body" size="medium">
138
+ {`${totalSelected} / ${total}`}
139
+ </Typography>
140
+ );
141
+ }
142
+ };
143
+
144
+ const bridgeItem = {
145
+ id: 'bridge-item',
146
+ title: (
147
+ <Typography variant="title" size="xmedium">
148
+ {i18n.t('Enabled bridges')}
149
+ </Typography>
150
+ ),
151
+ end: (
152
+ <>
153
+ {handleEndItem(totalSelectedBridgeSources, totalBridgeSources)}
154
+ <Divider direction="horizontal" size={8} />
155
+ <ChevronRightIcon color="black" />
156
+ </>
157
+ ),
158
+ onClick: () => navigate(navigationRoutes.bridges),
159
+ start: <BridgeIcon color="gray" size={14} />,
160
+ };
161
+
162
+ const exchangeItem = {
163
+ id: 'exchange-item',
164
+ title: (
165
+ <Typography variant="title" size="xmedium">
166
+ {i18n.t('Enabled exchanges')}
167
+ </Typography>
168
+ ),
169
+ end: (
170
+ <>
171
+ {handleEndItem(totalSelectedExchangeSources, totalExchangeSources)}
172
+ <Divider direction="horizontal" size={8} />
173
+ <ChevronRightIcon color="gray" />
174
+ </>
175
+ ),
176
+ start: <ExchangeIcon color="gray" size={14} />,
177
+ onClick: () => navigate(navigationRoutes.exchanges),
178
+ };
179
+
180
+ const languageItem = {
181
+ id: 'language-item',
182
+ title: (
183
+ <Typography variant="title" size="xmedium">
184
+ {i18n.t('Language')}
185
+ </Typography>
186
+ ),
187
+ start: <LanguageIcon color="gray" size={14} />,
188
+ end: <ChevronRightIcon color="gray" />,
189
+ onClick: () => navigate(navigationRoutes.languages),
190
+ };
191
+
192
+ const infiniteApprovalItem = {
193
+ id: 'infinite-approval-item',
194
+ title: (
195
+ <>
196
+ <Typography variant="title" size="xmedium">
197
+ {i18n.t('Infinite approval')}
198
+ </Typography>
199
+ <Divider direction="horizontal" size={4} />
200
+ <Tooltip
201
+ side="top"
202
+ sideOffset={4}
203
+ container={getContainer()}
204
+ content={
205
+ <TooltipContainer>
206
+ <Typography variant="label" size="medium" color="neutral700">
207
+ {i18n.t(
208
+ "Enabling the 'Infinite approval' mode grants unrestricted access to smart contracts of DEXes/Bridges, allowing them to utilize the approved token amount without limitations."
209
+ )}
210
+ </Typography>
211
+ </TooltipContainer>
212
+ }>
213
+ <InfoIcon color="gray" />
214
+ </Tooltip>
215
+ </>
216
+ ),
217
+ start: <DoneIcon color="gray" size={14} />,
218
+ end: <Switch checked={infiniteApprove} />,
219
+ onClick: toggleInfiniteApprove,
220
+ };
221
+
222
+ const themeItem = {
223
+ id: 'theme-item',
224
+ type: <ListItem />,
225
+ title: (
226
+ <Typography variant="title" size="xmedium">
227
+ {i18n.t('Theme')}
228
+ </Typography>
229
+ ),
230
+ end: (
231
+ <ThemeSection>
232
+ <Tabs
233
+ container={getContainer()}
234
+ items={themesList}
235
+ value={theme}
236
+ onChange={(item) => setTheme(item.id as ThemeMode)}
237
+ type="primary"
238
+ borderRadius="small"
239
+ />
240
+ </ThemeSection>
241
+ ),
242
+ start: getThemeIcon(theme),
243
+ };
244
+
245
+ const settingItems: ListPropTypes['items'] = isLiquidityHidden
246
+ ? []
247
+ : [bridgeItem, exchangeItem];
248
+
249
+ if (!isLanguageHidden) {
250
+ settingItems.push(languageItem);
251
+ }
252
+ settingItems.push(infiniteApprovalItem);
253
+
254
+ if (!themeConfig?.singleTheme && !isThemeHidden) {
255
+ settingItems.push(themeItem);
256
+ }
257
+
258
+ return (
259
+ <List
260
+ type={<ListItemButton hasDivider id="_" onClick={() => console.log()} />}
261
+ items={settingItems}
262
+ />
263
+ );
264
+ }