@lifi/widget 3.23.3 → 3.24.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 (156) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/LICENSE +165 -0
  3. package/README.md +14 -14
  4. package/dist/esm/components/AppContainer.js +22 -8
  5. package/dist/esm/components/AppContainer.js.map +1 -1
  6. package/dist/esm/components/Avatar/Avatar.d.ts +6 -1
  7. package/dist/esm/components/Avatar/Avatar.js +4 -4
  8. package/dist/esm/components/Avatar/Avatar.js.map +1 -1
  9. package/dist/esm/components/Avatar/Avatar.style.d.ts +13 -4
  10. package/dist/esm/components/Avatar/Avatar.style.js +20 -10
  11. package/dist/esm/components/Avatar/Avatar.style.js.map +1 -1
  12. package/dist/esm/components/Avatar/SmallAvatar.d.ts +8 -2
  13. package/dist/esm/components/Avatar/SmallAvatar.js +7 -5
  14. package/dist/esm/components/Avatar/SmallAvatar.js.map +1 -1
  15. package/dist/esm/components/Avatar/TokenAvatar.d.ts +6 -0
  16. package/dist/esm/components/Avatar/TokenAvatar.js +7 -7
  17. package/dist/esm/components/Avatar/TokenAvatar.js.map +1 -1
  18. package/dist/esm/components/Avatar/utils.d.ts +1 -8
  19. package/dist/esm/components/Avatar/utils.js +5 -8
  20. package/dist/esm/components/Avatar/utils.js.map +1 -1
  21. package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.js +6 -1
  22. package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.js.map +1 -1
  23. package/dist/esm/components/Header/Header.style.d.ts +4 -1
  24. package/dist/esm/components/Header/Header.style.js +8 -5
  25. package/dist/esm/components/Header/Header.style.js.map +1 -1
  26. package/dist/esm/components/RouteCard/RouteCardEssentials.js +2 -8
  27. package/dist/esm/components/RouteCard/RouteCardEssentials.js.map +1 -1
  28. package/dist/esm/components/Routes/RoutesExpanded.js.map +1 -1
  29. package/dist/esm/components/SelectTokenButton/SelectTokenButton.style.js +2 -2
  30. package/dist/esm/components/SendToWallet/SendToWalletButton.js +2 -1
  31. package/dist/esm/components/SendToWallet/SendToWalletButton.js.map +1 -1
  32. package/dist/esm/components/Step/CircularProgress.style.js +22 -17
  33. package/dist/esm/components/Step/CircularProgress.style.js.map +1 -1
  34. package/dist/esm/components/StepActions/StepActions.style.d.ts +4 -1
  35. package/dist/esm/components/TokenList/TokenDetailsSheet.d.ts +6 -0
  36. package/dist/esm/components/TokenList/TokenDetailsSheet.js +24 -0
  37. package/dist/esm/components/TokenList/TokenDetailsSheet.js.map +1 -0
  38. package/dist/esm/components/TokenList/TokenDetailsSheetContent.d.ts +8 -0
  39. package/dist/esm/components/TokenList/TokenDetailsSheetContent.js +67 -0
  40. package/dist/esm/components/TokenList/TokenDetailsSheetContent.js.map +1 -0
  41. package/dist/esm/components/TokenList/TokenDetailsSheetContent.style.d.ts +5 -0
  42. package/dist/esm/components/TokenList/TokenDetailsSheetContent.style.js +28 -0
  43. package/dist/esm/components/TokenList/TokenDetailsSheetContent.style.js.map +1 -0
  44. package/dist/esm/components/TokenList/TokenList.js +2 -2
  45. package/dist/esm/components/TokenList/TokenList.js.map +1 -1
  46. package/dist/esm/components/TokenList/TokenListItem.js +29 -11
  47. package/dist/esm/components/TokenList/TokenListItem.js.map +1 -1
  48. package/dist/esm/components/TokenList/VirtualizedTokenList.js +45 -40
  49. package/dist/esm/components/TokenList/VirtualizedTokenList.js.map +1 -1
  50. package/dist/esm/components/TokenList/types.d.ts +7 -0
  51. package/dist/esm/config/version.d.ts +1 -1
  52. package/dist/esm/config/version.js +1 -1
  53. package/dist/esm/hooks/useTokenBalances.d.ts +2 -1
  54. package/dist/esm/hooks/useTokenBalances.js +2 -2
  55. package/dist/esm/hooks/useTokenBalances.js.map +1 -1
  56. package/dist/esm/hooks/useTokenSearch.d.ts +2 -1
  57. package/dist/esm/hooks/useTokenSearch.js +7 -2
  58. package/dist/esm/hooks/useTokenSearch.js.map +1 -1
  59. package/dist/esm/hooks/useTokens.d.ts +2 -1
  60. package/dist/esm/hooks/useTokens.js +6 -13
  61. package/dist/esm/hooks/useTokens.js.map +1 -1
  62. package/dist/esm/i18n/bn.json +5 -0
  63. package/dist/esm/i18n/de.json +5 -0
  64. package/dist/esm/i18n/en.json +4 -0
  65. package/dist/esm/i18n/es.json +5 -0
  66. package/dist/esm/i18n/fr.json +5 -0
  67. package/dist/esm/i18n/hi.json +5 -0
  68. package/dist/esm/i18n/id.json +5 -0
  69. package/dist/esm/i18n/it.json +5 -0
  70. package/dist/esm/i18n/ja.json +5 -0
  71. package/dist/esm/i18n/ko.json +5 -0
  72. package/dist/esm/i18n/pt.json +5 -0
  73. package/dist/esm/i18n/th.json +5 -0
  74. package/dist/esm/i18n/tr.json +5 -0
  75. package/dist/esm/i18n/uk.json +5 -0
  76. package/dist/esm/i18n/vi.json +5 -0
  77. package/dist/esm/i18n/zh.json +5 -0
  78. package/dist/esm/icons/lifi.d.ts +1 -1
  79. package/dist/esm/icons/lifi.js +1 -1
  80. package/dist/esm/icons/lifi.js.map +1 -1
  81. package/dist/esm/index.d.ts +1 -0
  82. package/dist/esm/index.js +1 -0
  83. package/dist/esm/index.js.map +1 -1
  84. package/dist/esm/pages/ActiveTransactionsPage/ActiveTransactionsPage.js +1 -1
  85. package/dist/esm/pages/ActiveTransactionsPage/ActiveTransactionsPage.js.map +1 -1
  86. package/dist/esm/pages/RoutesPage/RoutesPage.js +1 -1
  87. package/dist/esm/pages/RoutesPage/RoutesPage.js.map +1 -1
  88. package/dist/esm/pages/SelectChainPage/SelectChainPage.js +1 -1
  89. package/dist/esm/pages/SelectChainPage/SelectChainPage.js.map +1 -1
  90. package/dist/esm/pages/SelectEnabledToolsPage.js +1 -1
  91. package/dist/esm/pages/SelectEnabledToolsPage.js.map +1 -1
  92. package/dist/esm/pages/TransactionHistoryPage/TransactionHistoryPage.js +1 -1
  93. package/dist/esm/pages/TransactionHistoryPage/TransactionHistoryPage.js.map +1 -1
  94. package/dist/esm/pages/TransactionPage/StatusBottomSheet.style.js +18 -7
  95. package/dist/esm/pages/TransactionPage/StatusBottomSheet.style.js.map +1 -1
  96. package/dist/esm/types/widget.d.ts +2 -0
  97. package/dist/esm/utils/format.d.ts +1 -0
  98. package/dist/esm/utils/format.js +16 -0
  99. package/dist/esm/utils/format.js.map +1 -1
  100. package/dist/esm/utils/item.d.ts +7 -2
  101. package/dist/esm/utils/item.js +10 -3
  102. package/dist/esm/utils/item.js.map +1 -1
  103. package/package.json +18 -18
  104. package/package.json.tmp +18 -18
  105. package/src/components/AppContainer.tsx +26 -8
  106. package/src/components/Avatar/Avatar.style.tsx +23 -11
  107. package/src/components/Avatar/Avatar.tsx +11 -6
  108. package/src/components/Avatar/SmallAvatar.tsx +13 -5
  109. package/src/components/Avatar/TokenAvatar.tsx +38 -8
  110. package/src/components/Avatar/utils.ts +5 -10
  111. package/src/components/BaseTransactionButton/BaseTransactionButton.tsx +5 -1
  112. package/src/components/Header/Header.style.ts +11 -6
  113. package/src/components/RouteCard/RouteCardEssentials.tsx +2 -9
  114. package/src/components/Routes/RoutesExpanded.tsx +7 -2
  115. package/src/components/SelectTokenButton/SelectTokenButton.style.tsx +2 -2
  116. package/src/components/SendToWallet/SendToWalletButton.tsx +3 -2
  117. package/src/components/Step/CircularProgress.style.tsx +25 -17
  118. package/src/components/TokenList/TokenDetailsSheet.tsx +48 -0
  119. package/src/components/TokenList/TokenDetailsSheetContent.style.tsx +34 -0
  120. package/src/components/TokenList/TokenDetailsSheetContent.tsx +200 -0
  121. package/src/components/TokenList/TokenList.tsx +7 -2
  122. package/src/components/TokenList/TokenListItem.tsx +117 -50
  123. package/src/components/TokenList/VirtualizedTokenList.tsx +95 -74
  124. package/src/components/TokenList/types.ts +8 -0
  125. package/src/config/version.ts +1 -1
  126. package/src/hooks/useTokenBalances.ts +9 -3
  127. package/src/hooks/useTokenSearch.ts +11 -2
  128. package/src/hooks/useTokens.ts +10 -21
  129. package/src/i18n/bn.json +5 -0
  130. package/src/i18n/de.json +5 -0
  131. package/src/i18n/en.json +4 -0
  132. package/src/i18n/es.json +5 -0
  133. package/src/i18n/fr.json +5 -0
  134. package/src/i18n/hi.json +5 -0
  135. package/src/i18n/id.json +5 -0
  136. package/src/i18n/it.json +5 -0
  137. package/src/i18n/ja.json +5 -0
  138. package/src/i18n/ko.json +5 -0
  139. package/src/i18n/pt.json +5 -0
  140. package/src/i18n/th.json +5 -0
  141. package/src/i18n/tr.json +5 -0
  142. package/src/i18n/uk.json +5 -0
  143. package/src/i18n/vi.json +5 -0
  144. package/src/i18n/zh.json +5 -0
  145. package/src/icons/lifi.ts +1 -1
  146. package/src/index.ts +1 -0
  147. package/src/pages/ActiveTransactionsPage/ActiveTransactionsPage.tsx +1 -0
  148. package/src/pages/RoutesPage/RoutesPage.tsx +1 -1
  149. package/src/pages/SelectChainPage/SelectChainPage.tsx +1 -1
  150. package/src/pages/SelectEnabledToolsPage.tsx +1 -1
  151. package/src/pages/TransactionHistoryPage/TransactionHistoryPage.tsx +1 -0
  152. package/src/pages/TransactionPage/StatusBottomSheet.style.tsx +19 -11
  153. package/src/types/widget.ts +2 -0
  154. package/src/utils/format.ts +19 -0
  155. package/src/utils/item.ts +29 -4
  156. package/LICENSE.md +0 -201
@@ -42,6 +42,12 @@ export const AppExpandedContainer = styled(Box, {
42
42
  export const RelativeContainer = styled(Box, {
43
43
  shouldForwardProp: (prop) => prop !== 'variant',
44
44
  })<{ variant?: WidgetVariant }>(({ theme }) => {
45
+ const maxHeight =
46
+ theme.container?.height === 'fit-content'
47
+ ? 'none'
48
+ : theme.container?.maxHeight ||
49
+ theme.container?.height ||
50
+ defaultMaxHeight
45
51
  return {
46
52
  position: 'relative',
47
53
  boxSizing: 'content-box',
@@ -56,9 +62,7 @@ export const RelativeContainer = styled(Box, {
56
62
  maxHeight:
57
63
  theme.container?.display === 'flex' && !theme.container?.height
58
64
  ? '100%'
59
- : theme.container?.maxHeight
60
- ? theme.container?.maxHeight
61
- : theme.container?.height || defaultMaxHeight,
65
+ : maxHeight,
62
66
  variants: [
63
67
  {
64
68
  props: {
@@ -84,9 +88,12 @@ const CssBaselineContainer = styled(ScopedCssBaseline, {
84
88
  shouldForwardProp: (prop) =>
85
89
  !['variant', 'paddingTopAdjustment', 'elementId'].includes(prop as string),
86
90
  })<CssBaselineContainerProps>(({ theme, variant, paddingTopAdjustment }) => {
87
- const fullContainerHeight = theme.container?.maxHeight
88
- ? theme.container?.maxHeight
89
- : theme.container?.height || defaultMaxHeight
91
+ const maxHeight =
92
+ theme.container?.height === 'fit-content'
93
+ ? 'none'
94
+ : theme.container?.maxHeight ||
95
+ theme.container?.height ||
96
+ defaultMaxHeight
90
97
  return {
91
98
  display: 'flex',
92
99
  flex: 1,
@@ -97,13 +104,24 @@ const CssBaselineContainer = styled(ScopedCssBaseline, {
97
104
  maxHeight:
98
105
  variant === 'drawer' || theme.container?.display === 'flex'
99
106
  ? 'none'
100
- : fullContainerHeight,
107
+ : maxHeight,
101
108
  overflowY: 'auto',
102
109
  height: theme.container?.display === 'flex' ? 'auto' : '100%',
103
110
  paddingTop: paddingTopAdjustment,
104
111
  // This allows FullPageContainer.tsx to expand and fill the available vertical space in max height and default layout modes
105
112
  '&:has(.full-page-container)': {
106
- height: fullContainerHeight,
113
+ height:
114
+ theme.container?.maxHeight ||
115
+ theme.container?.height ||
116
+ defaultMaxHeight,
117
+ },
118
+ '&:has(.long-list)': {
119
+ maxHeight:
120
+ theme.container?.maxHeight ||
121
+ (theme.container?.height !== 'fit-content'
122
+ ? theme.container?.height
123
+ : undefined) ||
124
+ defaultMaxHeight,
107
125
  },
108
126
  }
109
127
  })
@@ -7,11 +7,17 @@ import {
7
7
  badgeClasses,
8
8
  styled,
9
9
  } from '@mui/material'
10
- import { avatarMask16 } from './utils.js'
10
+ import { getAvatarMask } from './utils.js'
11
11
 
12
- export const AvatarMasked = styled(MuiAvatar)(() => ({
13
- mask: avatarMask16,
14
- }))
12
+ export const AvatarMasked = styled(MuiAvatar, {
13
+ shouldForwardProp: (prop) => prop !== 'avatarSize' && prop !== 'badgeSize',
14
+ })<{ avatarSize?: number; badgeSize?: number }>(
15
+ ({ avatarSize = 40, badgeSize = 16 }) => ({
16
+ width: avatarSize,
17
+ height: avatarSize,
18
+ mask: getAvatarMask(badgeSize),
19
+ })
20
+ )
15
21
 
16
22
  export const TokenAvatarGroup = styled(AvatarGroup)(({ theme }) => ({
17
23
  [`& .${badgeClasses.badge}:last-of-type .${avatarClasses.root}`]: {
@@ -30,7 +36,9 @@ export const TokenAvatarGroup = styled(AvatarGroup)(({ theme }) => ({
30
36
  },
31
37
  }))
32
38
 
33
- export const AvatarDefault = styled(Box)(({ theme }) => {
39
+ export const AvatarDefault = styled(Box, {
40
+ shouldForwardProp: (prop) => prop !== 'badgeSize',
41
+ })<{ badgeSize?: number }>(({ theme, badgeSize = 16 }) => {
34
42
  const root = theme.components?.MuiAvatar?.styleOverrides?.root as CSSObject
35
43
  return {
36
44
  display: 'flex',
@@ -40,7 +48,7 @@ export const AvatarDefault = styled(Box)(({ theme }) => {
40
48
  height: root?.height,
41
49
  width: root?.width,
42
50
  color: theme.vars.palette.text.secondary,
43
- mask: avatarMask16,
51
+ mask: getAvatarMask(badgeSize),
44
52
  background: theme.vars.palette.grey[300],
45
53
  ...theme.applyStyles('dark', {
46
54
  background: theme.vars.palette.grey[800],
@@ -48,11 +56,13 @@ export const AvatarDefault = styled(Box)(({ theme }) => {
48
56
  }
49
57
  })
50
58
 
51
- export const AvatarDefaultBadge = styled(Box)(({ theme }) => {
59
+ export const AvatarDefaultBadge = styled(Box, {
60
+ shouldForwardProp: (prop) => prop !== 'size',
61
+ })<{ size?: number }>(({ theme, size = 16 }) => {
52
62
  return {
53
63
  borderRadius: '50%',
54
- height: 16,
55
- width: 16,
64
+ height: size,
65
+ width: size,
56
66
  background: theme.vars.palette.grey[300],
57
67
  ...theme.applyStyles('dark', {
58
68
  background: theme.vars.palette.grey[800],
@@ -65,8 +75,10 @@ export const AvatarSkeletonContainer = styled(Box)(({ theme }) => ({
65
75
  borderRadius: '50%',
66
76
  }))
67
77
 
68
- export const AvatarSkeletonMaskedContainer = styled(Box)(({ theme }) => ({
78
+ export const AvatarSkeletonMaskedContainer = styled(Box, {
79
+ shouldForwardProp: (prop) => prop !== 'badgeSize',
80
+ })<{ badgeSize?: number }>(({ theme, badgeSize = 16 }) => ({
69
81
  background: theme.vars.palette.background.paper,
70
82
  borderRadius: '50%',
71
- mask: avatarMask16,
83
+ mask: getAvatarMask(badgeSize),
72
84
  }))
@@ -24,23 +24,28 @@ export const AvatarBadgedDefault: React.FC<{
24
24
 
25
25
  export const AvatarBadgedSkeleton: React.FC<{
26
26
  sx?: SxProps<Theme>
27
- }> = ({ sx }) => {
27
+ avatarSize?: number
28
+ badgeSize?: number
29
+ }> = ({ sx, avatarSize = 40, badgeSize = 16 }) => {
28
30
  return (
29
31
  <Badge
30
32
  overlap="circular"
31
33
  anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
32
- badgeContent={<SmallAvatarSkeleton />}
34
+ badgeContent={<SmallAvatarSkeleton size={badgeSize} />}
33
35
  sx={sx}
34
36
  >
35
- <AvatarSkeleton />
37
+ <AvatarSkeleton avatarSize={avatarSize} badgeSize={badgeSize} />
36
38
  </Badge>
37
39
  )
38
40
  }
39
41
 
40
- export const AvatarSkeleton = () => {
42
+ export const AvatarSkeleton: React.FC<{
43
+ avatarSize: number
44
+ badgeSize: number
45
+ }> = ({ avatarSize, badgeSize }) => {
41
46
  return (
42
- <AvatarSkeletonMaskedContainer>
43
- <Skeleton width={40} height={40} variant="circular" />
47
+ <AvatarSkeletonMaskedContainer badgeSize={badgeSize}>
48
+ <Skeleton width={avatarSize} height={avatarSize} variant="circular" />
44
49
  </AvatarSkeletonMaskedContainer>
45
50
  )
46
51
  }
@@ -1,16 +1,24 @@
1
1
  import { Avatar, Skeleton, styled } from '@mui/material'
2
2
  import { AvatarSkeletonContainer } from './Avatar.style.js'
3
3
 
4
- export const SmallAvatar = styled(Avatar)(({ theme }) => ({
4
+ interface SmallAvatarProps {
5
+ size?: number
6
+ }
7
+
8
+ export const SmallAvatar = styled(Avatar, {
9
+ shouldForwardProp: (prop) => prop !== 'size',
10
+ })<SmallAvatarProps>(({ theme, size = 16 }) => ({
5
11
  background: theme.vars.palette.background.paper,
6
- width: 16,
7
- height: 16,
12
+ width: size,
13
+ height: size,
8
14
  }))
9
15
 
10
- export const SmallAvatarSkeleton = () => {
16
+ export const SmallAvatarSkeleton: React.FC<{
17
+ size?: number
18
+ }> = ({ size = 16 }) => {
11
19
  return (
12
20
  <AvatarSkeletonContainer>
13
- <Skeleton width={16} height={16} variant="circular" />
21
+ <Skeleton width={size} height={size} variant="circular" />
14
22
  </AvatarSkeletonContainer>
15
23
  )
16
24
  }
@@ -12,9 +12,26 @@ export const TokenAvatar: React.FC<{
12
12
  chain?: Chain
13
13
  isLoading?: boolean
14
14
  sx?: SxProps<Theme>
15
- }> = ({ token, chain, isLoading, sx }) => {
15
+ tokenAvatarSize?: number
16
+ chainAvatarSize?: number
17
+ }> = ({
18
+ token,
19
+ chain,
20
+ isLoading,
21
+ sx,
22
+ tokenAvatarSize = 40,
23
+ chainAvatarSize = 16,
24
+ }) => {
16
25
  if (!chain || !token?.logoURI) {
17
- return <TokenAvatarFallback token={token} isLoading={isLoading} sx={sx} />
26
+ return (
27
+ <TokenAvatarFallback
28
+ token={token}
29
+ isLoading={isLoading}
30
+ sx={sx}
31
+ tokenAvatarSize={tokenAvatarSize}
32
+ chainAvatarSize={chainAvatarSize}
33
+ />
34
+ )
18
35
  }
19
36
  return (
20
37
  <TokenAvatarBase
@@ -22,6 +39,8 @@ export const TokenAvatar: React.FC<{
22
39
  chain={chain}
23
40
  isLoading={isLoading}
24
41
  sx={sx}
42
+ avatarSize={tokenAvatarSize}
43
+ badgeSize={chainAvatarSize}
25
44
  />
26
45
  )
27
46
  }
@@ -30,7 +49,9 @@ export const TokenAvatarFallback: React.FC<{
30
49
  token?: StaticToken
31
50
  isLoading?: boolean
32
51
  sx?: SxProps<Theme>
33
- }> = ({ token, isLoading, sx }) => {
52
+ tokenAvatarSize: number
53
+ chainAvatarSize: number
54
+ }> = ({ token, isLoading, sx, tokenAvatarSize, chainAvatarSize }) => {
34
55
  const { chain } = useChain(token?.chainId)
35
56
  const { token: chainToken, isLoading: isLoadingToken } = useToken(
36
57
  token?.chainId,
@@ -42,6 +63,8 @@ export const TokenAvatarFallback: React.FC<{
42
63
  isLoading={isLoading || isLoadingToken}
43
64
  chain={chain}
44
65
  sx={sx}
66
+ avatarSize={tokenAvatarSize}
67
+ badgeSize={chainAvatarSize}
45
68
  />
46
69
  )
47
70
  }
@@ -51,25 +74,32 @@ export const TokenAvatarBase: React.FC<{
51
74
  chain?: Chain
52
75
  isLoading?: boolean
53
76
  sx?: SxProps<Theme>
54
- }> = ({ token, chain, isLoading, sx }) => {
77
+ avatarSize: number
78
+ badgeSize: number
79
+ }> = ({ token, chain, isLoading, sx, avatarSize, badgeSize }) => {
55
80
  return isLoading ? (
56
- <AvatarBadgedSkeleton />
81
+ <AvatarBadgedSkeleton avatarSize={avatarSize} badgeSize={badgeSize} />
57
82
  ) : (
58
83
  <Badge
59
84
  overlap="circular"
60
85
  anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
61
86
  badgeContent={
62
87
  chain ? (
63
- <SmallAvatar src={chain.logoURI} alt={chain.name}>
88
+ <SmallAvatar src={chain.logoURI} alt={chain.name} size={badgeSize}>
64
89
  {chain.name[0]}
65
90
  </SmallAvatar>
66
91
  ) : (
67
- <AvatarDefaultBadge />
92
+ <AvatarDefaultBadge size={badgeSize} />
68
93
  )
69
94
  }
70
95
  sx={sx}
71
96
  >
72
- <AvatarMasked src={token?.logoURI} alt={token?.symbol}>
97
+ <AvatarMasked
98
+ src={token?.logoURI}
99
+ alt={token?.symbol}
100
+ avatarSize={avatarSize}
101
+ badgeSize={badgeSize}
102
+ >
73
103
  {token?.symbol?.[0]}
74
104
  </AvatarMasked>
75
105
  </Badge>
@@ -1,11 +1,6 @@
1
- /**
2
- * Avatar mask for 16px badge
3
- */
4
- export const avatarMask16 =
5
- 'radial-gradient(circle 10.5px at calc(100% - 5.5px) calc(100% - 5.5px), #fff0 96%, #fff) 100% 100% / 100% 100% no-repeat'
1
+ const borderWidthPx = 2.5
6
2
 
7
- /**
8
- * Avatar mask for 12px badge
9
- */
10
- export const avatarMask12 =
11
- 'radial-gradient(circle 8.5px at calc(100% - 3.5px) calc(100% - 3.5px), #fff0 96%, #fff) 100% 100% / 100% 100% no-repeat'
3
+ // 14% is the right bottom offset of the MUI's badge (MuiBadge-badge class)
4
+ export const getAvatarMask = (badgeSize: number) => {
5
+ return `radial-gradient(circle ${badgeSize / 2 + borderWidthPx}px at calc(100% - 14%) calc(100% - 14%), #fff0 96%, #fff) 100% 100% / 100% 100% no-repeat`
6
+ }
@@ -30,7 +30,11 @@ export const BaseTransactionButton: React.FC<BaseTransactionButtonProps> = ({
30
30
  } else if (walletConfig?.onConnect) {
31
31
  walletConfig.onConnect()
32
32
  } else {
33
- openWalletMenu()
33
+ if (missingChain) {
34
+ openWalletMenu({ chain: missingChain })
35
+ } else {
36
+ openWalletMenu()
37
+ }
34
38
  }
35
39
  }
36
40
 
@@ -7,7 +7,7 @@ import {
7
7
  styled,
8
8
  } from '@mui/material'
9
9
  import type { WidgetSubvariant } from '../../types/widget.js'
10
- import { avatarMask12 } from '../Avatar/utils.js'
10
+ import { getAvatarMask } from '../Avatar/utils.js'
11
11
 
12
12
  export const HeaderAppBar = styled(AppBar)(({ theme }) => ({
13
13
  backgroundColor: 'transparent',
@@ -34,6 +34,7 @@ export const Container = styled(Box, {
34
34
  gap: theme.spacing(0.5),
35
35
  padding: theme.spacing(1.5, 3, 1.5, 3),
36
36
  overflow: 'auto',
37
+ borderRadius: theme.container?.borderRadius ?? 0,
37
38
  ...theme.header,
38
39
  ...(theme.header?.position === 'fixed'
39
40
  ? {
@@ -101,8 +102,12 @@ export const HeaderControlsContainer = styled(Box)(({ theme }) => ({
101
102
  }),
102
103
  }))
103
104
 
104
- export const WalletAvatar = styled(Avatar)(() => ({
105
- mask: avatarMask12,
106
- width: 24,
107
- height: 24,
108
- }))
105
+ export const WalletAvatar = styled(Avatar, {
106
+ shouldForwardProp: (prop) => prop !== 'avatarSize' && prop !== 'badgeSize',
107
+ })<{ avatarSize?: number; badgeSize?: number }>(
108
+ ({ avatarSize = 24, badgeSize = 12 }) => ({
109
+ mask: getAvatarMask(badgeSize),
110
+ width: avatarSize,
111
+ height: avatarSize,
112
+ })
113
+ )
@@ -4,6 +4,7 @@ import LocalGasStationRounded from '@mui/icons-material/LocalGasStationRounded'
4
4
  import { Box, Tooltip, Typography } from '@mui/material'
5
5
  import { useTranslation } from 'react-i18next'
6
6
  import { getAccumulatedFeeCostsBreakdown } from '../../utils/fees.js'
7
+ import { formatDuration } from '../../utils/format.js'
7
8
  import { FeeBreakdownTooltip } from '../FeeBreakdownTooltip.js'
8
9
  import { IconTypography } from '../IconTypography.js'
9
10
  import { TokenRate } from '../TokenRate/TokenRate.js'
@@ -19,7 +20,6 @@ export const RouteCardEssentials: React.FC<RouteCardEssentialsProps> = ({
19
20
  0
20
21
  )
21
22
  )
22
- const executionTimeMinutes = Math.floor(executionTimeSeconds / 60)
23
23
  const { gasCosts, feeCosts, combinedFeesUSD } =
24
24
  getAccumulatedFeeCostsBreakdown(route)
25
25
  const hasGaslessSupport = route.steps.some(isGaslessStep)
@@ -90,14 +90,7 @@ export const RouteCardEssentials: React.FC<RouteCardEssentialsProps> = ({
90
90
  lineHeight: 1,
91
91
  }}
92
92
  >
93
- {(executionTimeSeconds < 60
94
- ? executionTimeSeconds
95
- : executionTimeMinutes
96
- ).toLocaleString(i18n.language, {
97
- style: 'unit',
98
- unit: executionTimeSeconds < 60 ? 'second' : 'minute',
99
- unitDisplay: 'narrow',
100
- })}
93
+ {formatDuration(executionTimeSeconds, i18n.language)}
101
94
  </Typography>
102
95
  </Box>
103
96
  </Tooltip>
@@ -127,12 +127,17 @@ export const RoutesExpandedElement = () => {
127
127
 
128
128
  return (
129
129
  <RoutesExpandedCollapse
130
- timeout={timeout.enter}
130
+ timeout={timeout.enter as number}
131
131
  in={expanded}
132
132
  orientation="horizontal"
133
133
  onExited={onExit}
134
134
  >
135
- <Grow timeout={timeout.enter} in={expanded} mountOnEnter unmountOnExit>
135
+ <Grow
136
+ timeout={timeout.enter as number}
137
+ in={expanded}
138
+ mountOnEnter
139
+ unmountOnExit
140
+ >
136
141
  <Container enableColorScheme minimumHeight={isLoading}>
137
142
  <ScrollableContainer>
138
143
  <Header>
@@ -106,9 +106,9 @@ export const CardContent = styled(MuiCardContent, {
106
106
  ...(cardVariant === 'filled' && {
107
107
  '&:hover': {
108
108
  cursor: 'pointer',
109
- backgroundColor: `color-mix(in srgb, ${theme.vars.palette.background.paper} 98%, white)`,
109
+ backgroundColor: `color-mix(in srgb, ${theme.vars.palette.background.paper} 98%, black)`,
110
110
  ...theme.applyStyles('dark', {
111
- backgroundColor: `color-mix(in srgb, ${theme.vars.palette.background.paper} 98%, black)`,
111
+ backgroundColor: `color-mix(in srgb, ${theme.vars.palette.background.paper} 98%, white)`,
112
112
  }),
113
113
  },
114
114
  }),
@@ -113,9 +113,10 @@ export const SendToWalletButton: React.FC<CardProps> = (props) => {
113
113
  // Timeout is needed here to push the collapseTransitionTime update to the back of the event loop so that it doesn't fired too quickly
114
114
  // biome-ignore lint/correctness/useExhaustiveDependencies:
115
115
  useEffect(() => {
116
- setTimeout(() => {
116
+ const timeout = setTimeout(() => {
117
117
  collapseTransitionTime.current = 225
118
118
  }, 0)
119
+ return () => clearTimeout(timeout)
119
120
  }, [collapseTransitionTime])
120
121
 
121
122
  const isOpenCollapse =
@@ -128,7 +129,7 @@ export const SendToWalletButton: React.FC<CardProps> = (props) => {
128
129
 
129
130
  return (
130
131
  <Collapse
131
- timeout={collapseTransitionTime.current}
132
+ timeout={collapseTransitionTime.current as number}
132
133
  in={isOpenCollapse}
133
134
  mountOnEnter
134
135
  unmountOnExit
@@ -24,29 +24,37 @@ const getStatusColor = (
24
24
  case 'FAILED':
25
25
  return `rgba(${theme.vars.palette.error.mainChannel} / 0.12)`
26
26
  default:
27
- return theme.vars.palette.grey[theme.palette.mode === 'light' ? 300 : 800]
27
+ return null
28
28
  }
29
29
  }
30
30
 
31
31
  export const CircularIcon = styled(Box, {
32
32
  shouldForwardProp: (prop: string) => !['status', 'substatus'].includes(prop),
33
33
  })<{ status?: ProcessStatus; substatus?: Substatus }>(
34
- ({ theme, status, substatus }) => ({
35
- backgroundColor: ['ACTION_REQUIRED', 'DONE', 'FAILED'].includes(status!)
36
- ? getStatusColor(theme, status, substatus)
37
- : theme.vars.palette.background.paper,
38
- borderStyle: 'solid',
39
- borderColor: getStatusColor(theme, status, substatus),
40
- borderWidth: !['ACTION_REQUIRED', 'DONE', 'FAILED'].includes(status!)
41
- ? 3
42
- : 0,
43
- display: 'grid',
44
- position: 'relative',
45
- placeItems: 'center',
46
- width: 40,
47
- height: 40,
48
- borderRadius: '50%',
49
- })
34
+ ({ theme, status, substatus }) => {
35
+ const statusColor = getStatusColor(theme, status, substatus)
36
+ const isSpecialStatus = ['ACTION_REQUIRED', 'DONE', 'FAILED'].includes(
37
+ status!
38
+ )
39
+
40
+ return {
41
+ backgroundColor: isSpecialStatus
42
+ ? statusColor!
43
+ : theme.vars.palette.background.paper,
44
+ borderStyle: 'solid',
45
+ borderColor: statusColor || theme.vars.palette.grey[300],
46
+ borderWidth: !isSpecialStatus ? 3 : 0,
47
+ display: 'grid',
48
+ position: 'relative',
49
+ placeItems: 'center',
50
+ width: 40,
51
+ height: 40,
52
+ borderRadius: '50%',
53
+ ...theme.applyStyles('dark', {
54
+ borderColor: statusColor || theme.vars.palette.grey[800],
55
+ }),
56
+ }
57
+ }
50
58
  )
51
59
 
52
60
  const circleAnimation = keyframes`
@@ -0,0 +1,48 @@
1
+ import { forwardRef, useImperativeHandle, useRef, useState } from 'react'
2
+ import { BottomSheet } from '../BottomSheet/BottomSheet.js'
3
+ import type { BottomSheetBase } from '../BottomSheet/types.js'
4
+ import { TokenDetailsSheetContent } from './TokenDetailsSheetContent.js'
5
+ import type { TokenDetailsSheetBase } from './types.js'
6
+ interface TokenDetailsSheetProps {
7
+ chainId: number | undefined
8
+ }
9
+
10
+ export const TokenDetailsSheet = forwardRef<
11
+ TokenDetailsSheetBase,
12
+ TokenDetailsSheetProps
13
+ >(({ chainId }, ref) => {
14
+ const bottomSheetRef = useRef<BottomSheetBase>(null)
15
+ const [tokenAddress, setTokenAddress] = useState<string | undefined>(
16
+ undefined
17
+ )
18
+ const [withoutContractAddress, setWithoutContractAddress] = useState(false)
19
+
20
+ useImperativeHandle(
21
+ ref,
22
+ () => ({
23
+ isOpen: () => bottomSheetRef.current?.isOpen(),
24
+ open: (address: string, noContractAddress: boolean) => {
25
+ setTokenAddress(address)
26
+ setWithoutContractAddress(noContractAddress)
27
+ bottomSheetRef.current?.open()
28
+ },
29
+ close: () => {
30
+ bottomSheetRef.current?.close()
31
+ setTokenAddress(undefined)
32
+ setWithoutContractAddress(false)
33
+ },
34
+ }),
35
+ []
36
+ )
37
+
38
+ return (
39
+ <BottomSheet ref={bottomSheetRef}>
40
+ <TokenDetailsSheetContent
41
+ ref={ref}
42
+ tokenAddress={tokenAddress}
43
+ withoutContractAddress={withoutContractAddress}
44
+ chainId={chainId}
45
+ />
46
+ </BottomSheet>
47
+ )
48
+ })
@@ -0,0 +1,34 @@
1
+ import { Box, Typography, styled } from '@mui/material'
2
+ import type { PageContainerProps } from '../PageContainer.js'
3
+ import { PageContainer } from '../PageContainer.js'
4
+
5
+ export const TokenDetailsSheetContainer = styled(
6
+ PageContainer
7
+ )<PageContainerProps>(({ theme }) => ({
8
+ display: 'flex',
9
+ flexDirection: 'column',
10
+ gap: theme.spacing(2),
11
+ paddingTop: theme.spacing(3),
12
+ paddingBottom: theme.spacing(3),
13
+ }))
14
+
15
+ export const TokenDetailsSheetHeader = styled(Box)(({ theme }) => ({
16
+ display: 'flex',
17
+ flexDirection: 'row',
18
+ alignItems: 'flex-start',
19
+ justifyContent: 'space-between',
20
+ gap: theme.spacing(2),
21
+ }))
22
+
23
+ export const Label = styled(Typography)(({ theme }) => ({
24
+ fontWeight: 500,
25
+ fontSize: '12px',
26
+ lineHeight: '16px',
27
+ color: theme.vars.palette.text.secondary,
28
+ }))
29
+
30
+ export const MetricContainer = styled(Box)(({ theme }) => ({
31
+ display: 'flex',
32
+ flexDirection: 'column',
33
+ gap: theme.spacing(1),
34
+ }))