@rango-dev/widget-embedded 0.20.1-next.2 → 0.20.1-next.20

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 (178) hide show
  1. package/dist/components/BlockchainList/BlockchainList.styles.d.ts +8 -0
  2. package/dist/components/BlockchainList/BlockchainList.styles.d.ts.map +1 -1
  3. package/dist/components/BlockchainsSection/BlockchainsSection.styles.d.ts +4 -0
  4. package/dist/components/BlockchainsSection/BlockchainsSection.styles.d.ts.map +1 -1
  5. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts +514 -1088
  6. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts.map +1 -1
  7. package/dist/components/ConfirmWalletsModal/ConfirmWalletsModal.d.ts.map +1 -1
  8. package/dist/components/ConfirmWalletsModal/WalletList.styles.d.ts +12 -0
  9. package/dist/components/ConfirmWalletsModal/WalletList.styles.d.ts.map +1 -1
  10. package/dist/components/CustomCollapsible/CustomCollapsible.d.ts +5 -0
  11. package/dist/components/CustomCollapsible/CustomCollapsible.d.ts.map +1 -0
  12. package/dist/components/CustomCollapsible/CustomCollapsible.styles.d.ts +654 -0
  13. package/dist/components/CustomCollapsible/CustomCollapsible.styles.d.ts.map +1 -0
  14. package/dist/components/CustomCollapsible/CustomCollapsible.types.d.ts +10 -0
  15. package/dist/components/CustomCollapsible/CustomCollapsible.types.d.ts.map +1 -0
  16. package/dist/components/HeaderButtons/HeaderButtons.styles.d.ts +179 -0
  17. package/dist/components/HeaderButtons/HeaderButtons.styles.d.ts.map +1 -1
  18. package/dist/components/HeaderButtons/HeaderButtons.types.d.ts +0 -1
  19. package/dist/components/HeaderButtons/HeaderButtons.types.d.ts.map +1 -1
  20. package/dist/components/HeaderButtons/HomeButtons.d.ts.map +1 -1
  21. package/dist/components/HeaderButtons/RefreshButton.d.ts +6 -0
  22. package/dist/components/HeaderButtons/RefreshButton.d.ts.map +1 -0
  23. package/dist/components/Layout/Layout.styles.d.ts +12 -0
  24. package/dist/components/Layout/Layout.styles.d.ts.map +1 -1
  25. package/dist/components/LoadingLiquiditySourceList/LoadingLiquiditySourceList.styles.d.ts +4 -0
  26. package/dist/components/LoadingLiquiditySourceList/LoadingLiquiditySourceList.styles.d.ts.map +1 -1
  27. package/dist/components/LoadingSwapDetails/LoadingSwapDetails.styles.d.ts +56 -0
  28. package/dist/components/LoadingSwapDetails/LoadingSwapDetails.styles.d.ts.map +1 -1
  29. package/dist/components/NoResult/NoResult.styles.d.ts +12 -0
  30. package/dist/components/NoResult/NoResult.styles.d.ts.map +1 -1
  31. package/dist/components/NotificationContent/NotificationContent.d.ts.map +1 -1
  32. package/dist/components/NotificationContent/NotificationContent.styles.d.ts +16 -0
  33. package/dist/components/NotificationContent/NotificationContent.styles.d.ts.map +1 -1
  34. package/dist/components/Quote/Quote.d.ts.map +1 -1
  35. package/dist/components/Quote/Quote.styles.d.ts +386 -2
  36. package/dist/components/Quote/Quote.styles.d.ts.map +1 -1
  37. package/dist/components/Quote/Quote.types.d.ts +19 -0
  38. package/dist/components/Quote/Quote.types.d.ts.map +1 -1
  39. package/dist/components/Quote/QuoteCostDetails.d.ts +4 -0
  40. package/dist/components/Quote/QuoteCostDetails.d.ts.map +1 -0
  41. package/dist/components/Quote/QuoteCostDetails.styles.d.ts +806 -0
  42. package/dist/components/Quote/QuoteCostDetails.styles.d.ts.map +1 -0
  43. package/dist/components/Quote/QuoteSummary.d.ts.map +1 -1
  44. package/dist/components/Quote/QuoteSummary.styles.d.ts +8 -0
  45. package/dist/components/Quote/QuoteSummary.styles.d.ts.map +1 -1
  46. package/dist/components/Quote/QuoteTrigger .d.ts +4 -0
  47. package/dist/components/Quote/QuoteTrigger .d.ts.map +1 -0
  48. package/dist/components/QuoteSkeleton/QuoteSkeleton.styles.d.ts +16 -0
  49. package/dist/components/QuoteSkeleton/QuoteSkeleton.styles.d.ts.map +1 -1
  50. package/dist/components/QuoteSkeleton/QuoteSummarySkeleton.styles.d.ts +40 -0
  51. package/dist/components/QuoteSkeleton/QuoteSummarySkeleton.styles.d.ts.map +1 -1
  52. package/dist/components/QuoteSkeleton/StepSkeleton.styles.d.ts +20 -0
  53. package/dist/components/QuoteSkeleton/StepSkeleton.styles.d.ts.map +1 -1
  54. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.d.ts +16 -0
  55. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.d.ts.map +1 -1
  56. package/dist/components/SearchInput/SearchInput.styles.d.ts +4 -0
  57. package/dist/components/SearchInput/SearchInput.styles.d.ts.map +1 -1
  58. package/dist/components/SettingsContainer/SettingsContainer.style.d.ts +16 -0
  59. package/dist/components/SettingsContainer/SettingsContainer.style.d.ts.map +1 -1
  60. package/dist/components/Slippage/Slippage.styles.d.ts +20 -0
  61. package/dist/components/Slippage/Slippage.styles.d.ts.map +1 -1
  62. package/dist/components/SwapDetails/SwapDetails.Placeholder.d.ts.map +1 -1
  63. package/dist/components/SwapDetails/SwapDetails.d.ts.map +1 -1
  64. package/dist/components/SwapDetails/SwapDetails.helpers.d.ts +1 -1
  65. package/dist/components/SwapDetails/SwapDetails.helpers.d.ts.map +1 -1
  66. package/dist/components/SwapDetails/SwapDetails.styles.d.ts +362 -0
  67. package/dist/components/SwapDetails/SwapDetails.styles.d.ts.map +1 -1
  68. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.d.ts.map +1 -1
  69. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.styles.d.ts +4 -0
  70. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.styles.d.ts.map +1 -1
  71. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.types.d.ts +2 -1
  72. package/dist/components/SwapDetailsAlerts/SwapDetailsAlerts.types.d.ts.map +1 -1
  73. package/dist/components/SwapDetailsModal/SwapDetailsModal.styles.d.ts +4 -0
  74. package/dist/components/SwapDetailsModal/SwapDetailsModal.styles.d.ts.map +1 -1
  75. package/dist/components/SwapsGroup/SwapsGroup.d.ts.map +1 -1
  76. package/dist/components/SwapsGroup/SwapsGroup.styles.d.ts +20 -0
  77. package/dist/components/SwapsGroup/SwapsGroup.styles.d.ts.map +1 -1
  78. package/dist/components/TokenList/TokenList.styles.d.ts +68 -0
  79. package/dist/components/TokenList/TokenList.styles.d.ts.map +1 -1
  80. package/dist/components/WalletModal/WalletModalContent.styles.d.ts +16 -0
  81. package/dist/components/WalletModal/WalletModalContent.styles.d.ts.map +1 -1
  82. package/dist/components/WidgetEvents.d.ts.map +1 -1
  83. package/dist/constants/index.d.ts +1 -0
  84. package/dist/constants/index.d.ts.map +1 -1
  85. package/dist/constants/quote.d.ts +12 -0
  86. package/dist/constants/quote.d.ts.map +1 -0
  87. package/dist/containers/App/App.d.ts.map +1 -1
  88. package/dist/containers/App/App.styles.d.ts +4 -0
  89. package/dist/containers/App/App.styles.d.ts.map +1 -1
  90. package/dist/containers/QuoteInfo/QuoteInfo.styles.d.ts +20 -0
  91. package/dist/containers/QuoteInfo/QuoteInfo.styles.d.ts.map +1 -1
  92. package/dist/containers/Wallets/Wallets.d.ts.map +1 -1
  93. package/dist/containers/WidgetInfo/WidgetInfo.d.ts.map +1 -1
  94. package/dist/containers/WidgetInfo/WidgetInfo.types.d.ts +5 -0
  95. package/dist/containers/WidgetInfo/WidgetInfo.types.d.ts.map +1 -1
  96. package/dist/containers/WidgetProvider/WidgetProvider.d.ts.map +1 -1
  97. package/dist/hooks/useLanguage.d.ts +2 -1
  98. package/dist/hooks/useLanguage.d.ts.map +1 -1
  99. package/dist/hooks/usePrepareBlockchainList/usePrepareBlockchainList.helpers.d.ts +2 -2
  100. package/dist/hooks/useSwapInput.d.ts.map +1 -1
  101. package/dist/hooks/useSyncStoresWithConfig.d.ts.map +1 -1
  102. package/dist/index.d.ts +6 -6
  103. package/dist/index.d.ts.map +1 -1
  104. package/dist/index.js +2 -1
  105. package/dist/index.js.map +4 -4
  106. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  107. package/dist/pages/Home.d.ts.map +1 -1
  108. package/dist/pages/LiquiditySourcePage.d.ts.map +1 -1
  109. package/dist/pages/SelectSwapItemsPage.d.ts.map +1 -1
  110. package/dist/store/AppStore.d.ts +2 -2
  111. package/dist/store/app.d.ts +2 -2
  112. package/dist/store/slices/data.d.ts.map +1 -1
  113. package/dist/store/slices/settings.d.ts +2 -2
  114. package/dist/store/slices/settings.d.ts.map +1 -1
  115. package/dist/types/config.d.ts +16 -3
  116. package/dist/types/config.d.ts.map +1 -1
  117. package/dist/types/notification.d.ts +1 -2
  118. package/dist/types/notification.d.ts.map +1 -1
  119. package/dist/utils/configs.d.ts +8 -0
  120. package/dist/utils/configs.d.ts.map +1 -1
  121. package/dist/utils/date.d.ts.map +1 -1
  122. package/dist/utils/quote.d.ts +5 -1
  123. package/dist/utils/quote.d.ts.map +1 -1
  124. package/dist/utils/settings.d.ts +1 -1
  125. package/dist/utils/swap.d.ts +5 -1
  126. package/dist/utils/swap.d.ts.map +1 -1
  127. package/package.json +6 -6
  128. package/src/components/ConfirmWalletsModal/ConfirmWallets.styles.ts +27 -96
  129. package/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx +25 -40
  130. package/src/components/CustomCollapsible/CustomCollapsible.styles.ts +75 -0
  131. package/src/components/CustomCollapsible/CustomCollapsible.tsx +55 -0
  132. package/src/components/CustomCollapsible/CustomCollapsible.types.ts +10 -0
  133. package/src/components/HeaderButtons/HeaderButtons.styles.ts +16 -1
  134. package/src/components/HeaderButtons/HeaderButtons.types.ts +0 -1
  135. package/src/components/HeaderButtons/HomeButtons.tsx +20 -33
  136. package/src/components/HeaderButtons/RefreshButton.tsx +81 -0
  137. package/src/components/NotificationContent/NotificationContent.tsx +10 -1
  138. package/src/components/Quote/Quote.styles.ts +44 -5
  139. package/src/components/Quote/Quote.tsx +10 -77
  140. package/src/components/Quote/Quote.types.ts +22 -0
  141. package/src/components/Quote/QuoteCostDetails.styles.ts +50 -0
  142. package/src/components/Quote/QuoteCostDetails.tsx +218 -0
  143. package/src/components/Quote/QuoteSummary.tsx +3 -2
  144. package/src/components/Quote/QuoteTrigger .tsx +215 -0
  145. package/src/components/Slippage/Slippage.tsx +5 -5
  146. package/src/components/Slippage/SlippageTooltipContent.tsx +1 -1
  147. package/src/components/SwapDetails/SwapDetails.Placeholder.tsx +12 -12
  148. package/src/components/SwapDetails/SwapDetails.helpers.tsx +43 -3
  149. package/src/components/SwapDetails/SwapDetails.styles.ts +13 -0
  150. package/src/components/SwapDetails/SwapDetails.tsx +10 -0
  151. package/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx +13 -7
  152. package/src/components/SwapDetailsAlerts/SwapDetailsAlerts.types.ts +2 -0
  153. package/src/components/SwapsGroup/SwapsGroup.tsx +18 -7
  154. package/src/components/WidgetEvents.tsx +2 -14
  155. package/src/constants/index.ts +1 -0
  156. package/src/constants/quote.ts +23 -0
  157. package/src/containers/App/App.tsx +1 -4
  158. package/src/containers/Wallets/Wallets.tsx +11 -2
  159. package/src/containers/WidgetInfo/WidgetInfo.tsx +8 -0
  160. package/src/containers/WidgetInfo/WidgetInfo.types.ts +5 -0
  161. package/src/containers/WidgetProvider/WidgetProvider.tsx +2 -1
  162. package/src/hooks/useLanguage.ts +6 -4
  163. package/src/hooks/useSwapInput.ts +6 -2
  164. package/src/hooks/useSyncStoresWithConfig.ts +17 -34
  165. package/src/index.ts +4 -2
  166. package/src/pages/ConfirmSwapPage.tsx +12 -10
  167. package/src/pages/Home.tsx +5 -1
  168. package/src/pages/LiquiditySourcePage.tsx +5 -2
  169. package/src/pages/SelectBlockchainPage.tsx +3 -3
  170. package/src/pages/SelectSwapItemsPage.tsx +5 -1
  171. package/src/store/slices/data.ts +5 -7
  172. package/src/store/slices/settings.ts +3 -3
  173. package/src/types/config.ts +16 -3
  174. package/src/types/notification.ts +0 -7
  175. package/src/utils/configs.ts +41 -0
  176. package/src/utils/date.ts +5 -4
  177. package/src/utils/quote.ts +18 -1
  178. package/src/utils/swap.ts +35 -0
@@ -0,0 +1,75 @@
1
+ import * as Collapsible from '@radix-ui/react-collapsible';
2
+ import { keyframes, styled } from '@rango-dev/ui';
3
+
4
+ export const EXPANDABLE_TRANSITION_DURATION = 300;
5
+
6
+ const slideDown = keyframes({
7
+ from: {
8
+ height: 0,
9
+ },
10
+ to: {
11
+ height: 'var(--radix-collapsible-content-height)',
12
+ },
13
+ });
14
+
15
+ const slideUp = keyframes({
16
+ from: {
17
+ height: 'var(--radix-collapsible-content-height)',
18
+ },
19
+ to: {
20
+ height: 0,
21
+ },
22
+ });
23
+
24
+ export const CollapsibleRoot = styled(Collapsible.Root, {
25
+ borderRadius: '$sm',
26
+ variants: {
27
+ selected: {
28
+ true: {
29
+ outlineWidth: 1,
30
+ outlineColor: '$secondary500',
31
+ outlineStyle: 'solid',
32
+ },
33
+ },
34
+ },
35
+ });
36
+
37
+ export const Trigger = styled(Collapsible.Trigger, {
38
+ padding: '$0',
39
+ border: 'none',
40
+ outline: 'none',
41
+ width: '100%',
42
+ backgroundColor: 'transparent',
43
+ fontFamily: 'inherit',
44
+ cursor: 'pointer',
45
+ });
46
+
47
+ export const CollapsibleContent = styled(Collapsible.Content, {
48
+ overflow: 'hidden',
49
+ variants: {
50
+ open: {
51
+ true: {
52
+ animation: `${slideDown} ${EXPANDABLE_TRANSITION_DURATION}ms ease-out`,
53
+ },
54
+ false: {
55
+ animation: `${slideUp} ${EXPANDABLE_TRANSITION_DURATION}ms ease-out`,
56
+ },
57
+ },
58
+ },
59
+ });
60
+
61
+ export const ExpandedIcon = styled('div', {
62
+ transition: `all ${EXPANDABLE_TRANSITION_DURATION}ms ease`,
63
+ display: 'flex',
64
+ alignItems: 'center',
65
+ variants: {
66
+ orientation: {
67
+ down: {
68
+ transform: 'rotate(0)',
69
+ },
70
+ up: {
71
+ transform: 'rotate(180deg)',
72
+ },
73
+ },
74
+ },
75
+ });
@@ -0,0 +1,55 @@
1
+ import type { PropTypes } from './CustomCollapsible.types';
2
+ import type { PropsWithChildren } from 'react';
3
+
4
+ import React, { useLayoutEffect, useRef } from 'react';
5
+
6
+ import {
7
+ CollapsibleContent,
8
+ CollapsibleRoot,
9
+ EXPANDABLE_TRANSITION_DURATION,
10
+ Trigger,
11
+ } from './CustomCollapsible.styles';
12
+
13
+ export function CustomCollapsible(props: PropsWithChildren<PropTypes>) {
14
+ const {
15
+ open,
16
+ hasSelected,
17
+ onOpenChange,
18
+ children,
19
+ onClickTrigger,
20
+ trigger,
21
+ triggerAnchor,
22
+ } = props;
23
+ const ref = useRef<HTMLDivElement | null>(null);
24
+
25
+ useLayoutEffect(() => {
26
+ if (open && ref.current) {
27
+ setTimeout(() => {
28
+ ref?.current?.scrollIntoView({ behavior: 'smooth' });
29
+ }, EXPANDABLE_TRANSITION_DURATION);
30
+ }
31
+ }, [open]);
32
+
33
+ return (
34
+ <CollapsibleRoot
35
+ ref={ref}
36
+ className="collapsible_root"
37
+ selected={hasSelected && open}
38
+ open={open}
39
+ onOpenChange={onOpenChange}>
40
+ {triggerAnchor === 'top' && (
41
+ <Trigger className="collapsible_trigger" onClick={onClickTrigger}>
42
+ {trigger}
43
+ </Trigger>
44
+ )}
45
+ <CollapsibleContent className="collapsible_content" open={open}>
46
+ {children}
47
+ </CollapsibleContent>
48
+ {triggerAnchor === 'bottom' && (
49
+ <Trigger className="collapsible_trigger" onClick={onClickTrigger}>
50
+ {trigger}
51
+ </Trigger>
52
+ )}
53
+ </CollapsibleRoot>
54
+ );
55
+ }
@@ -0,0 +1,10 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ export type PropTypes = {
4
+ open: boolean;
5
+ hasSelected?: boolean;
6
+ onOpenChange?: (checked: boolean) => void;
7
+ onClickTrigger: () => void;
8
+ trigger: ReactNode;
9
+ triggerAnchor: 'top' | 'bottom';
10
+ };
@@ -23,7 +23,10 @@ export const ConnectedIcon = styled('div', {
23
23
  export const SuffixContainer = styled('div', {
24
24
  display: 'flex',
25
25
  justifyContent: 'flex-end',
26
- width: '$40',
26
+ minWidth: '$40',
27
+ button: {
28
+ padding: 0,
29
+ },
27
30
  });
28
31
 
29
32
  export const NotificationsBadgeContainer = styled('div', {
@@ -38,3 +41,15 @@ export const NotificationsBadgeContainer = styled('div', {
38
41
  top: '$0',
39
42
  right: '$0',
40
43
  });
44
+
45
+ export const ProgressIcon = styled('div', {
46
+ padding: '$2',
47
+ variants: {
48
+ isRefetched: {
49
+ true: {
50
+ transform: `rotate(360deg)`,
51
+ transition: 'transform 1s ease-in-out',
52
+ },
53
+ },
54
+ },
55
+ });
@@ -8,5 +8,4 @@ export interface HomeButtonsPropTypes {
8
8
  onClickRefresh?: () => void;
9
9
  onClickHistory?: () => void;
10
10
  onClickSettings?: () => void;
11
- onClickNotifications?: () => void;
12
11
  }
@@ -4,7 +4,6 @@ import { i18n } from '@lingui/core';
4
4
  import {
5
5
  NotificationsIcon,
6
6
  Popover,
7
- RefreshIcon,
8
7
  SettingsIcon,
9
8
  Tooltip,
10
9
  TransactionIcon,
@@ -17,16 +16,11 @@ import { isFeatureHidden } from '../../utils/settings';
17
16
  import { NotificationContent } from '../NotificationContent';
18
17
 
19
18
  import { HeaderButton } from './HeaderButtons.styles';
19
+ import { RefreshButton } from './RefreshButton';
20
20
  import { UnreadNotificationsBadge } from './UnreadNotificationsBadge';
21
21
 
22
22
  export function HomeButtons(props: HomeButtonsPropTypes) {
23
- const {
24
- layoutRef,
25
- onClickRefresh,
26
- onClickHistory,
27
- onClickSettings,
28
- onClickNotifications,
29
- } = props;
23
+ const { layoutRef, onClickRefresh, onClickHistory, onClickSettings } = props;
30
24
 
31
25
  const {
32
26
  config: { features },
@@ -40,35 +34,28 @@ export function HomeButtons(props: HomeButtonsPropTypes) {
40
34
  container={getContainer()}
41
35
  side="top"
42
36
  content={i18n.t('Refresh')}>
43
- <HeaderButton
44
- variant="ghost"
45
- size="small"
46
- onClick={onClickRefresh}
47
- disabled={!onClickRefresh}>
48
- <RefreshIcon size={16} color={!onClickRefresh ? 'gray' : 'black'} />
49
- </HeaderButton>
37
+ <RefreshButton onClick={onClickRefresh} />
50
38
  </Tooltip>
51
39
 
52
40
  {!isNotificationsHidden && (
53
- <Tooltip
41
+ <Popover
42
+ align="center"
43
+ collisionBoundary={layoutRef}
44
+ collisionPadding={{ right: 20, left: 20 }}
54
45
  container={getContainer()}
55
- side="top"
56
- content={i18n.t('Notifications')}>
57
- <Popover
58
- align="center"
59
- collisionBoundary={layoutRef}
60
- collisionPadding={{ right: 20, left: 20 }}
61
- container={getContainer()}
62
- content={<NotificationContent />}>
63
- <HeaderButton
64
- size="small"
65
- variant="ghost"
66
- onClick={onClickNotifications}>
67
- <NotificationsIcon size={18} color="black" />
68
- <UnreadNotificationsBadge />
69
- </HeaderButton>
70
- </Popover>
71
- </Tooltip>
46
+ content={<NotificationContent />}>
47
+ <div>
48
+ <Tooltip
49
+ container={getContainer()}
50
+ side="top"
51
+ content={i18n.t('Notifications')}>
52
+ <HeaderButton size="small" variant="ghost">
53
+ <NotificationsIcon size={18} color="black" />
54
+ <UnreadNotificationsBadge />
55
+ </HeaderButton>
56
+ </Tooltip>
57
+ </div>
58
+ </Popover>
72
59
  )}
73
60
  <Tooltip
74
61
  container={getContainer()}
@@ -0,0 +1,81 @@
1
+ import { RefreshProgressButton } from '@rango-dev/ui';
2
+ import React, { useEffect, useState } from 'react';
3
+
4
+ import { HeaderButton, ProgressIcon } from './HeaderButtons.styles';
5
+
6
+ const REFRESH_INTERVAL = 1000;
7
+ const MAX_ELAPSED_TIME = 60;
8
+ const MAX_PERCENTAGE = 100;
9
+
10
+ function RefreshButton({ onClick }: { onClick: (() => void) | undefined }) {
11
+ const [elapsedTime, setElapsedTime] = useState(0);
12
+ const [isRefetched, setIsRefetched] = useState(false);
13
+
14
+ const handleVisibilityChange = (interval?: number) => {
15
+ if (document.hidden && interval) {
16
+ // Tab is inactive, clear the interval
17
+ clearTimeout(interval);
18
+ }
19
+ };
20
+
21
+ useEffect(() => {
22
+ let interval: number | undefined;
23
+ if (onClick) {
24
+ interval = window.setInterval(() => {
25
+ setElapsedTime((prevTime) => prevTime + 1);
26
+
27
+ if (elapsedTime === MAX_ELAPSED_TIME) {
28
+ handleRefreshClick();
29
+ }
30
+ }, REFRESH_INTERVAL);
31
+ } else {
32
+ clearTimeout(interval);
33
+ }
34
+
35
+ document.addEventListener('visibilitychange', () =>
36
+ handleVisibilityChange(interval)
37
+ );
38
+
39
+ return () => {
40
+ document.removeEventListener('visibilitychange', () =>
41
+ handleVisibilityChange(interval)
42
+ );
43
+ if (interval) {
44
+ clearInterval(interval);
45
+ }
46
+ };
47
+ }, [elapsedTime, onClick]);
48
+
49
+ const clearTimeout = (interval?: number) => {
50
+ if (interval) {
51
+ clearInterval(interval);
52
+ }
53
+ setElapsedTime(0);
54
+ };
55
+
56
+ const handleRefreshClick = () => {
57
+ onClick?.();
58
+ setElapsedTime(0);
59
+ setIsRefetched(true);
60
+ };
61
+
62
+ return (
63
+ <HeaderButton
64
+ variant="ghost"
65
+ size="small"
66
+ onClick={handleRefreshClick}
67
+ disabled={!onClick}>
68
+ <ProgressIcon
69
+ onTransitionEnd={() => setIsRefetched(false)}
70
+ isRefetched={isRefetched}>
71
+ <RefreshProgressButton
72
+ size={24}
73
+ color={!onClick ? 'gray' : 'black'}
74
+ progress={(elapsedTime / MAX_ELAPSED_TIME) * MAX_PERCENTAGE}
75
+ />
76
+ </ProgressIcon>
77
+ </HeaderButton>
78
+ );
79
+ }
80
+
81
+ export { RefreshButton };
@@ -1,6 +1,7 @@
1
1
  import type { Notification } from '../../types/notification';
2
2
 
3
3
  import { i18n } from '@lingui/core';
4
+ import { EventSeverity } from '@rango-dev/queue-manager-rango-preset';
4
5
  import {
5
6
  ChainToken,
6
7
  ChevronRightIcon,
@@ -74,7 +75,15 @@ export function NotificationContent() {
74
75
  key={notificationItem.requestId}
75
76
  onClick={() => handleOnClick(notificationItem.requestId)}
76
77
  title={
77
- <Typography variant="body" size="small" color="$neutral700">
78
+ <Typography
79
+ variant="body"
80
+ size="small"
81
+ color={
82
+ notificationItem.event.messageSeverity ===
83
+ EventSeverity.WARNING
84
+ ? '$foreground'
85
+ : '$neutral700'
86
+ }>
78
87
  {i18n.t(notificationItem.event.message)}
79
88
  </Typography>
80
89
  }
@@ -1,7 +1,7 @@
1
1
  import * as Collapsible from '@radix-ui/react-collapsible';
2
2
  import { css, darkTheme, Image, styled, Typography } from '@rango-dev/ui';
3
3
 
4
- import { CollapsibleContent } from '../ConfirmWalletsModal/ConfirmWallets.styles';
4
+ import { CollapsibleContent } from '../CustomCollapsible/CustomCollapsible.styles';
5
5
 
6
6
  export const EXPANDABLE_QUOTE_TRANSITION_DURATION = 300;
7
7
 
@@ -114,6 +114,15 @@ export const summaryStyles = css({
114
114
  cursor: 'default',
115
115
  });
116
116
 
117
+ export const rowStyles = css({
118
+ display: 'flex',
119
+ flexDirection: 'row',
120
+ justifyContent: 'center',
121
+ alignItems: 'center',
122
+ '.blockchainImage': {
123
+ marginLeft: '-$8',
124
+ },
125
+ });
117
126
  export const basicInfoStyles = css({
118
127
  paddingTop: '$10',
119
128
  display: 'flex',
@@ -127,7 +136,7 @@ export const basicInfoStyles = css({
127
136
  },
128
137
  });
129
138
 
130
- export const Chains = styled(Collapsible.Trigger, {
139
+ export const Trigger = styled(Collapsible.Trigger, {
131
140
  display: 'flex',
132
141
  width: '100%',
133
142
  justifyContent: 'space-between',
@@ -171,17 +180,27 @@ export const Chains = styled(Collapsible.Trigger, {
171
180
  },
172
181
  },
173
182
  },
174
- '& div:nth-child(1)': { display: 'flex' },
183
+ '.blockchains_section': {
184
+ display: 'none',
185
+ },
186
+ '@xs': {
187
+ '.blockchains_section': {
188
+ display: 'block',
189
+ },
190
+ },
175
191
  });
176
192
 
177
- export const ChainImageContainer = styled('div', {
193
+ export const ImageContainer = styled('div', {
178
194
  width: '18px',
179
195
  height: '18px',
180
196
  borderRadius: '100%',
181
- border: '1.5px transparent solid',
182
197
  display: 'flex',
183
198
  justifyContent: 'center',
184
199
  alignItems: 'center',
200
+ border: '1.5px transparent solid',
201
+ img: {
202
+ borderRadius: '100%',
203
+ },
185
204
  variants: {
186
205
  state: {
187
206
  error: {
@@ -252,3 +271,23 @@ export const ContainerInfoOutput = styled('div', {
252
271
  display: 'flex',
253
272
  flexWrap: 'wrap',
254
273
  });
274
+
275
+ export const MoreStep = styled('div', {
276
+ width: '18px',
277
+ height: '18px',
278
+ borderRadius: '100%',
279
+ backgroundColor: '$background',
280
+ cursor: 'default',
281
+ display: 'flex',
282
+ justifyContent: 'center',
283
+ alignItems: 'center',
284
+ border: '1.5px transparent solid',
285
+ variants: {
286
+ state: {
287
+ error: {
288
+ borderColor: '$error500',
289
+ },
290
+ warning: { borderColor: '$warning500' },
291
+ },
292
+ },
293
+ });
@@ -5,12 +5,8 @@ import type { SwapResult } from 'rango-sdk';
5
5
  import { i18n } from '@lingui/core';
6
6
  import {
7
7
  Alert,
8
- ChevronDownIcon,
9
- ChevronRightIcon,
10
8
  Divider,
11
- Image,
12
9
  InfoIcon,
13
- QuoteCost,
14
10
  StepDetails,
15
11
  TokenAmount,
16
12
  Tooltip,
@@ -20,8 +16,6 @@ import BigNumber from 'bignumber.js';
20
16
  import React, { useLayoutEffect, useRef, useState } from 'react';
21
17
 
22
18
  import {
23
- GAS_FEE_MAX_DECIMALS,
24
- GAS_FEE_MIN_DECIMALS,
25
19
  PERCENTAGE_CHANGE_MAX_DECIMALS,
26
20
  PERCENTAGE_CHANGE_MIN_DECIMALS,
27
21
  TOKEN_AMOUNT_MAX_DECIMALS,
@@ -40,32 +34,25 @@ import {
40
34
  getBlockchainShortNameFor,
41
35
  getSwapperDisplayName,
42
36
  } from '../../utils/meta';
43
- import {
44
- formatTooltipNumbers,
45
- numberToString,
46
- secondsToString,
47
- totalArrivalTime,
48
- } from '../../utils/numbers';
37
+ import { formatTooltipNumbers, numberToString } from '../../utils/numbers';
49
38
  import { getPriceImpact, getPriceImpactLevel } from '../../utils/quote';
50
- import { getTotalFeeInUsd } from '../../utils/swap';
51
39
 
52
40
  import {
53
41
  BasicInfoOutput,
54
42
  basicInfoStyles,
55
- ChainImageContainer,
56
- Chains,
57
43
  ContainerInfoOutput,
58
44
  Content,
59
45
  EXPANDABLE_QUOTE_TRANSITION_DURATION,
60
46
  FrameIcon,
61
47
  HorizontalSeparator,
62
- IconContainer,
63
48
  QuoteContainer,
64
49
  stepsDetailsStyles,
65
50
  SummaryContainer,
66
51
  summaryStyles,
67
52
  } from './Quote.styles';
53
+ import { QuoteCostDetails } from './QuoteCostDetails';
68
54
  import { QuoteSummary } from './QuoteSummary';
55
+ import { QuoteTrigger } from './QuoteTrigger ';
69
56
 
70
57
  export function Quote(props: QuoteProps) {
71
58
  const {
@@ -77,19 +64,12 @@ export function Quote(props: QuoteProps) {
77
64
  type,
78
65
  recommended = true,
79
66
  } = props;
80
- const tokens = useAppStore().tokens();
81
67
  const blockchains = useAppStore().blockchains();
82
68
  const swappers = useAppStore().swappers();
83
69
 
84
70
  const [expanded, setExpanded] = useState(props.expanded);
85
71
  const quoteRef = useRef<HTMLButtonElement | null>(null);
86
72
  const prevExpanded = useRef(expanded);
87
- const totalFee = numberToString(
88
- getTotalFeeInUsd(quote.result?.swaps ?? [], tokens),
89
- GAS_FEE_MIN_DECIMALS,
90
- GAS_FEE_MAX_DECIMALS
91
- );
92
- const totalTime = secondsToString(totalArrivalTime(quote.result?.swaps));
93
73
  const roundedInput = numberToString(
94
74
  input.value,
95
75
  TOKEN_AMOUNT_MIN_DECIMALS,
@@ -283,7 +263,6 @@ export function Quote(props: QuoteProps) {
283
263
  const steps = getQuoteSteps(quote.result?.swaps ?? []);
284
264
  const numberOfSteps = steps.length;
285
265
  const tooltipContainer = getContainer();
286
-
287
266
  useLayoutEffect(() => {
288
267
  if (expanded && !prevExpanded.current && quoteRef.current) {
289
268
  setTimeout(() => {
@@ -300,7 +279,7 @@ export function Quote(props: QuoteProps) {
300
279
  listItem={type === 'list-item'}
301
280
  basic={type === 'basic'}>
302
281
  <div className={summaryStyles()}>
303
- <QuoteCost fee={totalFee} time={totalTime} steps={numberOfSteps} />
282
+ <QuoteCostDetails steps={numberOfSteps} quote={quote} />
304
283
  {type === 'basic' && (
305
284
  <div className={basicInfoStyles()}>
306
285
  <FrameIcon>
@@ -374,59 +353,13 @@ export function Quote(props: QuoteProps) {
374
353
  recommended={recommended}
375
354
  open={expanded}
376
355
  onOpenChange={setExpanded}>
377
- <Chains
378
- ref={(ref) => (quoteRef.current = ref)}
356
+ <QuoteTrigger
357
+ quoteRef={quoteRef}
379
358
  recommended={recommended}
380
- onClick={() => setExpanded((prevState) => !prevState)}>
381
- <div>
382
- {steps.map((step, index) => {
383
- const key = `item-${index}`;
384
- const arrow = (
385
- <IconContainer>
386
- <ChevronRightIcon
387
- size={12}
388
- color="black"
389
- {...(step.state && {
390
- color: step.state === 'error' ? 'error' : 'warning',
391
- })}
392
- />
393
- </IconContainer>
394
- );
395
- return (
396
- <React.Fragment key={key}>
397
- <Tooltip
398
- container={tooltipContainer}
399
- side="bottom"
400
- sideOffset={4}
401
- content={step.from.chain.displayName}>
402
- <ChainImageContainer
403
- state={step.state || steps[index - 1]?.state}>
404
- <Image src={step.from.chain.image} size={16} />
405
- </ChainImageContainer>
406
- </Tooltip>
407
- {index === numberOfSteps - 1 && (
408
- <>
409
- {arrow}
410
- <Tooltip
411
- container={tooltipContainer}
412
- side="bottom"
413
- sideOffset={4}
414
- content={step.to.chain.displayName}>
415
- <ChainImageContainer state={step.state}>
416
- <Image src={step.to.chain.image} size={16} />
417
- </ChainImageContainer>
418
- </Tooltip>
419
- </>
420
- )}
421
- {index !== numberOfSteps - 1 && <>{arrow}</>}
422
- </React.Fragment>
423
- );
424
- })}
425
- </div>
426
- <IconContainer orientation={expanded ? 'up' : 'down'}>
427
- <ChevronDownIcon size={12} color="black" />
428
- </IconContainer>
429
- </Chains>
359
+ setExpanded={setExpanded}
360
+ expanded={expanded}
361
+ steps={steps}
362
+ />
430
363
  <Content open={expanded}>
431
364
  <HorizontalSeparator />
432
365
  <div className={stepsDetailsStyles()}>
@@ -1,4 +1,5 @@
1
1
  import type { QuoteError, QuoteWarning } from '../../types';
2
+ import type { Step } from '@rango-dev/ui';
2
3
  import type { BestRouteResponse } from 'rango-sdk';
3
4
  import type { ReactNode } from 'react';
4
5
 
@@ -13,3 +14,24 @@ export type QuoteProps = {
13
14
  output: { value: string; usdValue?: string };
14
15
  expanded?: boolean;
15
16
  };
17
+
18
+ export type QuoteTriggerProps = {
19
+ quoteRef: React.MutableRefObject<HTMLButtonElement | null>;
20
+ recommended: boolean;
21
+ setExpanded: React.Dispatch<React.SetStateAction<boolean | undefined>>;
22
+ steps: Step[];
23
+ expanded?: boolean;
24
+ };
25
+
26
+ export type QuoteTriggerImagesProps = {
27
+ content: ReactNode;
28
+ state?: 'error' | 'warning' | undefined;
29
+ src: string;
30
+ open?: boolean;
31
+ className?: string;
32
+ };
33
+
34
+ export type QuoteCostDetailsProps = {
35
+ quote: BestRouteResponse;
36
+ steps: number;
37
+ };
@@ -0,0 +1,50 @@
1
+ import { css, styled } from '@rango-dev/ui';
2
+
3
+ export const FeeSection = styled('div', {
4
+ display: 'flex',
5
+ justifyContent: 'space-between',
6
+ alignItems: 'center',
7
+ padding: '$5 0',
8
+ '&.total_payable_fee': {
9
+ padding: '$12 0',
10
+ },
11
+ });
12
+
13
+ export const Line = styled('div', {
14
+ width: '100%',
15
+ borderTop: '1px solid $neutral300',
16
+ margin: '$10 0',
17
+ });
18
+
19
+ export const ModalContainer = styled('div', {
20
+ padding: '$20 0',
21
+ display: 'flex',
22
+ flexDirection: 'column',
23
+ '& .collapsible_trigger': {
24
+ display: 'flex',
25
+ alignItems: 'center',
26
+ },
27
+ });
28
+
29
+ export const ModalHeader = styled('div', {
30
+ padding: '$20 $20 $10',
31
+ textAlign: 'center',
32
+ position: 'relative',
33
+ '._icon-button': {
34
+ position: 'absolute',
35
+ zIndex: 10,
36
+ top: '$16',
37
+ right: '$16',
38
+ },
39
+ });
40
+ export const trigger = css({
41
+ display: 'flex',
42
+ flexDirection: 'row',
43
+ alignItems: 'center',
44
+ padding: '$5',
45
+ '&:hover': {
46
+ '& ._typography, & svg': {
47
+ color: '$secondary',
48
+ },
49
+ },
50
+ });