@lifi/widget 3.26.0 → 3.26.2-beta.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.
- package/CHANGELOG.md +7 -0
- package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.js +2 -1
- package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.js.map +1 -1
- package/dist/esm/components/BottomSheet/BottomSheet.js +13 -5
- package/dist/esm/components/BottomSheet/BottomSheet.js.map +1 -1
- package/dist/esm/components/Chains/ChainsExpanded.d.ts +1 -1
- package/dist/esm/components/Chains/ChainsExpanded.js +3 -2
- package/dist/esm/components/Chains/ChainsExpanded.js.map +1 -1
- package/dist/esm/components/Chains/ChainsExpanded.style.js +1 -2
- package/dist/esm/components/Chains/ChainsExpanded.style.js.map +1 -1
- package/dist/esm/components/Chains/SelectChainContent.d.ts +1 -1
- package/dist/esm/components/Chains/SelectChainContent.js +3 -2
- package/dist/esm/components/Chains/SelectChainContent.js.map +1 -1
- package/dist/esm/components/Expansion/Expansion.js +5 -16
- package/dist/esm/components/Expansion/Expansion.js.map +1 -1
- package/dist/esm/components/Expansion/Expansion.style.d.ts +32 -0
- package/dist/esm/components/Expansion/Expansion.style.js +40 -0
- package/dist/esm/components/Expansion/Expansion.style.js.map +1 -0
- package/dist/esm/components/Expansion/ExpansionTransition.d.ts +0 -1
- package/dist/esm/components/Expansion/ExpansionTransition.js +1 -30
- package/dist/esm/components/Expansion/ExpansionTransition.js.map +1 -1
- package/dist/esm/components/Header/CloseDrawerButton.js +2 -5
- package/dist/esm/components/Header/CloseDrawerButton.js.map +1 -1
- package/dist/esm/components/Header/Header.style.d.ts +1 -2
- package/dist/esm/components/Header/Header.style.js +3 -4
- package/dist/esm/components/Header/Header.style.js.map +1 -1
- package/dist/esm/components/Header/NavigationHeader.js +17 -21
- package/dist/esm/components/Header/NavigationHeader.js.map +1 -1
- package/dist/esm/components/Header/SplitNavigationTabs.d.ts +1 -0
- package/dist/esm/components/Header/{NavigationTabs.js → SplitNavigationTabs.js} +4 -5
- package/dist/esm/components/Header/SplitNavigationTabs.js.map +1 -0
- package/dist/esm/components/Header/WalletHeader.d.ts +0 -1
- package/dist/esm/components/Header/WalletHeader.js +10 -14
- package/dist/esm/components/Header/WalletHeader.js.map +1 -1
- package/dist/esm/components/Routes/RoutesContent.d.ts +2 -3
- package/dist/esm/components/Routes/RoutesContent.js +5 -21
- package/dist/esm/components/Routes/RoutesContent.js.map +1 -1
- package/dist/esm/components/Routes/RoutesExpanded.d.ts +2 -3
- package/dist/esm/components/Routes/RoutesExpanded.js +24 -8
- package/dist/esm/components/Routes/RoutesExpanded.js.map +1 -1
- package/dist/esm/components/Routes/RoutesExpanded.style.js +1 -2
- package/dist/esm/components/Routes/RoutesExpanded.style.js.map +1 -1
- package/dist/esm/components/Step/StepProcess.js +8 -3
- package/dist/esm/components/Step/StepProcess.js.map +1 -1
- package/dist/esm/components/Tabs/NavigationTabs.d.ts +4 -0
- package/dist/esm/components/Tabs/NavigationTabs.js +39 -0
- package/dist/esm/components/Tabs/NavigationTabs.js.map +1 -0
- package/dist/esm/components/TokenList/TokenListItem.js +1 -0
- package/dist/esm/components/TokenList/TokenListItem.js.map +1 -1
- package/dist/esm/components/TokenList/useTokenSelect.js +9 -2
- package/dist/esm/components/TokenList/useTokenSelect.js.map +1 -1
- package/dist/esm/config/version.d.ts +1 -1
- package/dist/esm/config/version.js +1 -1
- package/dist/esm/config/version.js.map +1 -1
- package/dist/esm/hooks/useRoutes.js +32 -4
- package/dist/esm/hooks/useRoutes.js.map +1 -1
- package/dist/esm/pages/MainPage/MainPage.js +8 -1
- package/dist/esm/pages/MainPage/MainPage.js.map +1 -1
- package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js +1 -1
- package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js.map +1 -1
- package/dist/esm/themes/azureLight.js +2 -3
- package/dist/esm/themes/azureLight.js.map +1 -1
- package/dist/esm/themes/createTheme.js +6 -0
- package/dist/esm/themes/createTheme.js.map +1 -1
- package/dist/esm/themes/types.d.ts +15 -1
- package/dist/esm/themes/watermelonLight.js +12 -0
- package/dist/esm/themes/watermelonLight.js.map +1 -1
- package/dist/esm/themes/windows95.js +11 -0
- package/dist/esm/themes/windows95.js.map +1 -1
- package/dist/esm/types/widget.d.ts +1 -1
- package/dist/esm/types/widget.js.map +1 -1
- package/package.json +7 -7
- package/package.json.tmp +6 -6
- package/src/components/BaseTransactionButton/BaseTransactionButton.tsx +2 -1
- package/src/components/BottomSheet/BottomSheet.tsx +14 -3
- package/src/components/Chains/ChainsExpanded.style.tsx +1 -2
- package/src/components/Chains/ChainsExpanded.tsx +6 -2
- package/src/components/Chains/SelectChainContent.tsx +81 -82
- package/src/components/Expansion/Expansion.style.tsx +43 -0
- package/src/components/Expansion/Expansion.tsx +8 -23
- package/src/components/Expansion/ExpansionTransition.tsx +5 -33
- package/src/components/Header/CloseDrawerButton.tsx +2 -5
- package/src/components/Header/Header.style.ts +3 -5
- package/src/components/Header/NavigationHeader.tsx +66 -73
- package/src/components/Header/{NavigationTabs.tsx → SplitNavigationTabs.tsx} +10 -14
- package/src/components/Header/WalletHeader.tsx +13 -19
- package/src/components/Routes/RoutesContent.tsx +8 -29
- package/src/components/Routes/RoutesExpanded.style.ts +1 -2
- package/src/components/Routes/RoutesExpanded.tsx +33 -13
- package/src/components/Step/StepProcess.tsx +8 -3
- package/src/components/Tabs/NavigationTabs.tsx +40 -0
- package/src/components/TokenList/TokenListItem.tsx +1 -0
- package/src/components/TokenList/useTokenSelect.ts +14 -2
- package/src/config/version.ts +1 -1
- package/src/hooks/useRoutes.ts +68 -33
- package/src/pages/MainPage/MainPage.tsx +9 -1
- package/src/pages/SettingsPage/RoutePrioritySettings.tsx +0 -1
- package/src/themes/azureLight.ts +2 -3
- package/src/themes/createTheme.ts +6 -0
- package/src/themes/types.ts +20 -0
- package/src/themes/watermelonLight.ts +12 -0
- package/src/themes/windows95.ts +12 -0
- package/src/types/widget.ts +2 -0
- package/dist/esm/components/Header/NavigationTabs.d.ts +0 -1
- package/dist/esm/components/Header/NavigationTabs.js.map +0 -1
|
@@ -27,10 +27,9 @@ import { WalletMenu } from './WalletMenu.js'
|
|
|
27
27
|
import { WalletMenuContainer } from './WalletMenu.style.js'
|
|
28
28
|
|
|
29
29
|
const useInternalWalletManagement = () => {
|
|
30
|
-
const {
|
|
30
|
+
const { hiddenUI } = useWidgetConfig()
|
|
31
31
|
const { useExternalWalletProvidersOnly } = useExternalWalletProvider()
|
|
32
32
|
|
|
33
|
-
const isSplitVariant = subvariant === 'split'
|
|
34
33
|
const isWalletMenuHidden = hiddenUI?.includes(HiddenUI.WalletMenu)
|
|
35
34
|
|
|
36
35
|
const shouldShowWalletMenu =
|
|
@@ -38,25 +37,19 @@ const useInternalWalletManagement = () => {
|
|
|
38
37
|
|
|
39
38
|
return {
|
|
40
39
|
shouldShowWalletMenu,
|
|
41
|
-
isSplitVariant,
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
42
|
|
|
45
43
|
export const WalletHeader: React.FC = () => {
|
|
46
|
-
const { shouldShowWalletMenu
|
|
44
|
+
const { shouldShowWalletMenu } = useInternalWalletManagement()
|
|
47
45
|
|
|
48
|
-
return shouldShowWalletMenu
|
|
46
|
+
return shouldShowWalletMenu ? (
|
|
49
47
|
<HeaderAppBar elevation={0} sx={{ justifyContent: 'flex-end' }}>
|
|
50
48
|
<WalletMenuButton />
|
|
51
49
|
</HeaderAppBar>
|
|
52
50
|
) : null
|
|
53
51
|
}
|
|
54
52
|
|
|
55
|
-
export const SplitWalletMenuButton: React.FC = () => {
|
|
56
|
-
const { shouldShowWalletMenu, isSplitVariant } = useInternalWalletManagement()
|
|
57
|
-
return shouldShowWalletMenu && isSplitVariant ? <WalletMenuButton /> : null
|
|
58
|
-
}
|
|
59
|
-
|
|
60
53
|
export const WalletMenuButton: React.FC = () => {
|
|
61
54
|
const { variant, hiddenUI } = useWidgetConfig()
|
|
62
55
|
const { account, accounts } = useAccount()
|
|
@@ -92,24 +85,25 @@ export const WalletMenuButton: React.FC = () => {
|
|
|
92
85
|
|
|
93
86
|
const ConnectButton = () => {
|
|
94
87
|
const { t } = useTranslation()
|
|
95
|
-
const { walletConfig,
|
|
88
|
+
const { walletConfig, variant } = useWidgetConfig()
|
|
96
89
|
const { openWalletMenu } = useWalletMenu()
|
|
97
|
-
const connect = async () => {
|
|
90
|
+
const connect = async (event: React.MouseEvent<HTMLElement>) => {
|
|
98
91
|
if (!walletConfig?.usePartialWalletManagement && walletConfig?.onConnect) {
|
|
99
92
|
walletConfig.onConnect()
|
|
100
93
|
return
|
|
101
94
|
}
|
|
102
95
|
openWalletMenu()
|
|
96
|
+
event.currentTarget.blur() // Remove focus to prevent accessibility issues when opening drawer
|
|
103
97
|
}
|
|
104
98
|
|
|
99
|
+
const walletPosition = variant === 'drawer' ? 'start' : 'end'
|
|
100
|
+
|
|
105
101
|
return (
|
|
106
102
|
<WalletButton
|
|
107
|
-
|
|
108
|
-
endIcon={
|
|
109
|
-
variant !== 'drawer' && subvariant !== 'split' ? <Wallet /> : undefined
|
|
110
|
-
}
|
|
103
|
+
withOffset={walletPosition === 'end'}
|
|
104
|
+
endIcon={walletPosition === 'end' ? <Wallet /> : undefined}
|
|
111
105
|
startIcon={
|
|
112
|
-
|
|
106
|
+
walletPosition === 'start' ? (
|
|
113
107
|
<Wallet sx={{ marginLeft: -0.25 }} />
|
|
114
108
|
) : undefined
|
|
115
109
|
}
|
|
@@ -121,13 +115,13 @@ const ConnectButton = () => {
|
|
|
121
115
|
}
|
|
122
116
|
|
|
123
117
|
const ConnectedButton = ({ account }: { account: Account }) => {
|
|
124
|
-
const { subvariant } = useWidgetConfig()
|
|
125
118
|
const { chain } = useChain(account.chainId)
|
|
126
119
|
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null)
|
|
127
120
|
const walletAddress = shortenAddress(account.address)
|
|
128
121
|
|
|
129
122
|
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
|
|
130
123
|
setAnchorEl(event.currentTarget)
|
|
124
|
+
event.currentTarget.blur() // Remove focus to prevent accessibility issues when opening drawer
|
|
131
125
|
}
|
|
132
126
|
|
|
133
127
|
const handleClose = () => {
|
|
@@ -137,7 +131,7 @@ const ConnectedButton = ({ account }: { account: Account }) => {
|
|
|
137
131
|
return (
|
|
138
132
|
<>
|
|
139
133
|
<WalletButton
|
|
140
|
-
|
|
134
|
+
withOffset
|
|
141
135
|
endIcon={<ExpandMore />}
|
|
142
136
|
startIcon={
|
|
143
137
|
chain?.logoURI ? (
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import type { ExtendedChain, Route } from '@lifi/sdk'
|
|
2
2
|
import { useAccount } from '@lifi/wallet-management'
|
|
3
3
|
import { Stack, Typography } from '@mui/material'
|
|
4
|
-
import {
|
|
4
|
+
import { memo } from 'react'
|
|
5
5
|
import { useTranslation } from 'react-i18next'
|
|
6
|
-
import { useNavigate } from 'react-router-dom'
|
|
7
6
|
import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js'
|
|
8
|
-
import { useWidgetEvents } from '../../hooks/useWidgetEvents.js'
|
|
9
7
|
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
|
|
10
8
|
import { useFieldValues } from '../../stores/form/useFieldValues.js'
|
|
11
|
-
import { WidgetEvent } from '../../types/events.js'
|
|
12
|
-
import { navigationRoutes } from '../../utils/navigationRoutes.js'
|
|
13
9
|
import { PageContainer } from '../PageContainer.js'
|
|
14
10
|
import { ProgressToNextUpdate } from '../ProgressToNextUpdate.js'
|
|
15
11
|
import { RouteCard } from '../RouteCard/RouteCard.js'
|
|
@@ -21,55 +17,38 @@ interface RoutesContentProps {
|
|
|
21
17
|
routes: Route[]
|
|
22
18
|
isFetching: boolean
|
|
23
19
|
isLoading: boolean
|
|
24
|
-
expanded: boolean
|
|
25
|
-
setReviewableRoute: (route: Route) => void
|
|
26
20
|
dataUpdatedAt: number
|
|
27
21
|
refetchTime: number
|
|
28
22
|
fromChain: ExtendedChain | undefined
|
|
29
23
|
refetch: () => void
|
|
24
|
+
onRouteClick: (route: Route) => void
|
|
30
25
|
}
|
|
31
26
|
|
|
32
27
|
const headerHeight = '64px'
|
|
33
28
|
|
|
34
|
-
export const RoutesContent = ({
|
|
29
|
+
export const RoutesContent = memo(function RoutesContent({
|
|
35
30
|
routes,
|
|
36
31
|
isFetching,
|
|
37
32
|
isLoading,
|
|
38
|
-
expanded,
|
|
39
|
-
setReviewableRoute,
|
|
40
33
|
dataUpdatedAt,
|
|
41
34
|
refetchTime,
|
|
42
35
|
fromChain,
|
|
43
36
|
refetch,
|
|
44
|
-
|
|
37
|
+
onRouteClick,
|
|
38
|
+
}: RoutesContentProps) {
|
|
45
39
|
const { t } = useTranslation()
|
|
46
|
-
|
|
47
|
-
const navigate = useNavigate()
|
|
48
40
|
const { subvariant, subvariantOptions } = useWidgetConfig()
|
|
49
41
|
|
|
50
42
|
const { account } = useAccount({ chainType: fromChain?.chainType })
|
|
51
43
|
const [toAddress] = useFieldValues('toAddress')
|
|
52
44
|
const { requiredToAddress } = useToAddressRequirements()
|
|
53
45
|
|
|
54
|
-
const emitter = useWidgetEvents()
|
|
55
|
-
|
|
56
|
-
const handleRouteClick = (route: Route) => {
|
|
57
|
-
setReviewableRoute(route)
|
|
58
|
-
navigate(navigationRoutes.transactionExecution, {
|
|
59
|
-
state: { routeId: route.id },
|
|
60
|
-
})
|
|
61
|
-
emitter.emit(WidgetEvent.RouteSelected, { route, routes: routes! })
|
|
62
|
-
}
|
|
63
46
|
const currentRoute = routes?.[0]
|
|
64
47
|
|
|
65
|
-
const routeNotFound = !currentRoute && !isLoading && !isFetching
|
|
48
|
+
const routeNotFound = !currentRoute && !isLoading && !isFetching
|
|
66
49
|
const toAddressUnsatisfied = currentRoute && requiredToAddress && !toAddress
|
|
67
50
|
const allowInteraction = account.isConnected && !toAddressUnsatisfied
|
|
68
51
|
|
|
69
|
-
useEffect(() => {
|
|
70
|
-
emitter.emit(WidgetEvent.WidgetExpanded, expanded)
|
|
71
|
-
}, [emitter, expanded])
|
|
72
|
-
|
|
73
52
|
const title =
|
|
74
53
|
subvariant === 'custom'
|
|
75
54
|
? subvariantOptions?.custom === 'deposit'
|
|
@@ -121,7 +100,7 @@ export const RoutesContent = ({
|
|
|
121
100
|
key={index}
|
|
122
101
|
route={route}
|
|
123
102
|
onClick={
|
|
124
|
-
allowInteraction ? () =>
|
|
103
|
+
allowInteraction ? () => onRouteClick(route) : undefined
|
|
125
104
|
}
|
|
126
105
|
active={index === 0}
|
|
127
106
|
expanded={routes?.length === 1}
|
|
@@ -132,4 +111,4 @@ export const RoutesContent = ({
|
|
|
132
111
|
</PageContainer>
|
|
133
112
|
</Container>
|
|
134
113
|
)
|
|
135
|
-
}
|
|
114
|
+
})
|
|
@@ -11,14 +11,13 @@ interface ContainerProps extends ScopedCssBaselineProps {
|
|
|
11
11
|
export const Container = styled(ScopedCssBaseline, {
|
|
12
12
|
shouldForwardProp: (prop) => !['minimumHeight'].includes(prop as string),
|
|
13
13
|
})<ContainerProps>(({ theme, minimumHeight }) => ({
|
|
14
|
+
...theme.container,
|
|
14
15
|
backgroundColor: theme.vars.palette.background.default,
|
|
15
16
|
overflow: 'hidden',
|
|
16
17
|
width: routesExpansionWidth,
|
|
17
18
|
display: 'flex',
|
|
18
19
|
flexDirection: 'column',
|
|
19
20
|
whiteSpace: 'normal',
|
|
20
|
-
borderRadius: theme.container?.borderRadius ?? 0,
|
|
21
|
-
boxShadow: theme.container?.boxShadow ?? 'none',
|
|
22
21
|
...(theme.container?.display !== 'flex'
|
|
23
22
|
? {
|
|
24
23
|
maxHeight:
|
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
import type { Route } from '@lifi/sdk'
|
|
2
|
-
import { useEffect, useRef } from 'react'
|
|
2
|
+
import { memo, useCallback, useEffect, useLayoutEffect, useRef } from 'react'
|
|
3
|
+
import { useNavigate } from 'react-router-dom'
|
|
3
4
|
import { useRoutes } from '../../hooks/useRoutes.js'
|
|
4
|
-
import {
|
|
5
|
+
import { useWidgetEvents } from '../../hooks/useWidgetEvents.js'
|
|
6
|
+
import { WidgetEvent } from '../../types/events.js'
|
|
7
|
+
import { navigationRoutes } from '../../utils/navigationRoutes.js'
|
|
5
8
|
import { ExpansionTransition } from '../Expansion/ExpansionTransition.js'
|
|
6
9
|
import { RoutesContent } from './RoutesContent.js'
|
|
7
10
|
import { routesExpansionWidth } from './RoutesExpanded.style.js'
|
|
8
11
|
|
|
9
12
|
interface RoutesExpandedProps {
|
|
10
|
-
|
|
13
|
+
canOpen: boolean
|
|
11
14
|
setOpenExpansion: (open: boolean) => void
|
|
12
15
|
}
|
|
13
16
|
|
|
14
|
-
export const RoutesExpanded = ({
|
|
15
|
-
|
|
17
|
+
export const RoutesExpanded = memo(function RoutesExpanded({
|
|
18
|
+
canOpen,
|
|
16
19
|
setOpenExpansion,
|
|
17
|
-
}: RoutesExpandedProps)
|
|
20
|
+
}: RoutesExpandedProps) {
|
|
21
|
+
const emitter = useWidgetEvents()
|
|
22
|
+
const navigate = useNavigate()
|
|
18
23
|
const routesRef = useRef<Route[]>(undefined)
|
|
19
|
-
|
|
20
24
|
const routesActiveRef = useRef(false)
|
|
25
|
+
|
|
21
26
|
const {
|
|
22
27
|
routes,
|
|
23
28
|
isLoading,
|
|
@@ -45,13 +50,29 @@ export const RoutesExpanded = ({
|
|
|
45
50
|
|
|
46
51
|
const expanded =
|
|
47
52
|
Boolean(routesActiveRef.current || isLoading || isFetching || isFetched) &&
|
|
48
|
-
|
|
53
|
+
canOpen
|
|
49
54
|
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: stable navigation callback that won't cause rerenders in RoutesContent
|
|
56
|
+
const onRouteClick = useCallback(
|
|
57
|
+
(route: Route) => {
|
|
58
|
+
setReviewableRoute(route)
|
|
59
|
+
navigate(navigationRoutes.transactionExecution, {
|
|
60
|
+
state: { routeId: route.id },
|
|
61
|
+
})
|
|
62
|
+
emitter.emit(WidgetEvent.RouteSelected, { route, routes: routes! })
|
|
63
|
+
},
|
|
64
|
+
[emitter, routes, setReviewableRoute]
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
// Use layout effect to update parent's width when expansion changes
|
|
68
|
+
useLayoutEffect(() => {
|
|
52
69
|
setOpenExpansion(expanded)
|
|
53
70
|
}, [expanded, setOpenExpansion])
|
|
54
71
|
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
emitter.emit(WidgetEvent.WidgetExpanded, expanded)
|
|
74
|
+
}, [emitter, expanded])
|
|
75
|
+
|
|
55
76
|
return (
|
|
56
77
|
<ExpansionTransition
|
|
57
78
|
in={expanded}
|
|
@@ -62,13 +83,12 @@ export const RoutesExpanded = ({
|
|
|
62
83
|
routes={routesRef.current || []}
|
|
63
84
|
isFetching={isFetching}
|
|
64
85
|
isLoading={isLoading}
|
|
65
|
-
expanded={expanded}
|
|
66
|
-
setReviewableRoute={setReviewableRoute}
|
|
67
86
|
dataUpdatedAt={dataUpdatedAt}
|
|
68
87
|
refetchTime={refetchTime}
|
|
69
88
|
fromChain={fromChain}
|
|
70
89
|
refetch={refetch}
|
|
90
|
+
onRouteClick={onRouteClick}
|
|
71
91
|
/>
|
|
72
92
|
</ExpansionTransition>
|
|
73
93
|
)
|
|
74
|
-
}
|
|
94
|
+
})
|
|
@@ -13,12 +13,17 @@ export const StepProcess: React.FC<{
|
|
|
13
13
|
const { title, message } = useProcessMessage(step, process)
|
|
14
14
|
const { getTransactionLink } = useExplorer()
|
|
15
15
|
|
|
16
|
-
const transactionLink = process.
|
|
16
|
+
const transactionLink = process.txHash
|
|
17
17
|
? getTransactionLink({
|
|
18
|
-
|
|
18
|
+
txHash: process.txHash,
|
|
19
19
|
chain: process.chainId,
|
|
20
20
|
})
|
|
21
|
-
:
|
|
21
|
+
: process.txLink
|
|
22
|
+
? getTransactionLink({
|
|
23
|
+
txLink: process.txLink,
|
|
24
|
+
chain: process.chainId,
|
|
25
|
+
})
|
|
26
|
+
: undefined
|
|
22
27
|
|
|
23
28
|
return (
|
|
24
29
|
<Box
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { styled, Tabs, tabsClasses } from '@mui/material'
|
|
2
|
+
import { Tab } from './Tabs.style.js'
|
|
3
|
+
|
|
4
|
+
export const NavigationTabs = styled(Tabs, {
|
|
5
|
+
name: 'MuiNavigationTabs',
|
|
6
|
+
slot: 'root',
|
|
7
|
+
})(({ theme }) => ({
|
|
8
|
+
overflow: 'visible', // Prevent shadows from being cut off
|
|
9
|
+
width: 'fit-content',
|
|
10
|
+
minHeight: theme.spacing(5),
|
|
11
|
+
maxHeight: theme.spacing(5),
|
|
12
|
+
background: 'transparent',
|
|
13
|
+
...theme.applyStyles('dark', {
|
|
14
|
+
backgroundColor: 'transparent',
|
|
15
|
+
}),
|
|
16
|
+
[`& .${tabsClasses.scroller}`]: {
|
|
17
|
+
padding: 0,
|
|
18
|
+
overflow: 'visible !important', // Enforce since overflow is set dynamically
|
|
19
|
+
},
|
|
20
|
+
[`& .${tabsClasses.indicator}`]: {
|
|
21
|
+
boxShadow: 'none',
|
|
22
|
+
top: 0,
|
|
23
|
+
left: 0,
|
|
24
|
+
height: '100%',
|
|
25
|
+
width: '100%',
|
|
26
|
+
borderRadius: theme.vars.shape.borderRadius,
|
|
27
|
+
backgroundColor: `rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.04)`,
|
|
28
|
+
...theme.applyStyles('dark', {
|
|
29
|
+
backgroundColor: `rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.08)`,
|
|
30
|
+
}),
|
|
31
|
+
},
|
|
32
|
+
}))
|
|
33
|
+
|
|
34
|
+
export const NavigationTab = styled(Tab, {
|
|
35
|
+
name: 'MuiNavigationTab',
|
|
36
|
+
slot: 'root',
|
|
37
|
+
})(({ theme }) => ({
|
|
38
|
+
minHeight: theme.spacing(5),
|
|
39
|
+
maxHeight: theme.spacing(5),
|
|
40
|
+
}))
|
|
@@ -102,6 +102,7 @@ const OpenTokenDetailsButton = ({
|
|
|
102
102
|
size="small"
|
|
103
103
|
onClick={(e) => {
|
|
104
104
|
e.stopPropagation()
|
|
105
|
+
e.currentTarget.blur() // Remove focus to prevent accessibility issues when opening drawer
|
|
105
106
|
onClick(tokenAddress, withoutContractAddress)
|
|
106
107
|
}}
|
|
107
108
|
>
|
|
@@ -6,6 +6,7 @@ import { useChainOrderStoreContext } from '../../stores/chains/ChainOrderStore.j
|
|
|
6
6
|
import type { FormType } from '../../stores/form/types.js'
|
|
7
7
|
import { FormKeyHelper } from '../../stores/form/types.js'
|
|
8
8
|
import { useFieldActions } from '../../stores/form/useFieldActions.js'
|
|
9
|
+
import { useSplitSubvariantStore } from '../../stores/settings/useSplitSubvariantStore.js'
|
|
9
10
|
import { WidgetEvent } from '../../types/events.js'
|
|
10
11
|
import type { DisabledUI } from '../../types/widget.js'
|
|
11
12
|
|
|
@@ -16,6 +17,7 @@ export type UseTokenSelectArgs = {
|
|
|
16
17
|
|
|
17
18
|
export const useTokenSelect = (formType: FormType, onClick?: () => void) => {
|
|
18
19
|
const { subvariant, disabledUI } = useWidgetConfig()
|
|
20
|
+
const splitSubvariant = useSplitSubvariantStore((store) => store.state)
|
|
19
21
|
const emitter = useWidgetEvents()
|
|
20
22
|
const { setFieldValue, getFieldValues } = useFieldActions()
|
|
21
23
|
const autoPopulateToAddress = useToAddressAutoPopulate()
|
|
@@ -47,10 +49,19 @@ export const useTokenSelect = (formType: FormType, onClick?: () => void) => {
|
|
|
47
49
|
FormKeyHelper.getChainKey(oppositeFormType),
|
|
48
50
|
'toAddress'
|
|
49
51
|
)
|
|
52
|
+
|
|
50
53
|
// TODO: remove when we enable same chain/token transfers
|
|
51
|
-
|
|
54
|
+
const isSameTokenTransfer =
|
|
52
55
|
selectedOppositeTokenAddress === tokenAddress &&
|
|
53
|
-
selectedOppositeChainId === selectedChainId
|
|
56
|
+
selectedOppositeChainId === selectedChainId
|
|
57
|
+
|
|
58
|
+
const isBridgeToSameChain =
|
|
59
|
+
subvariant === 'split' &&
|
|
60
|
+
splitSubvariant === 'bridge' &&
|
|
61
|
+
selectedOppositeChainId === selectedChainId
|
|
62
|
+
|
|
63
|
+
if (
|
|
64
|
+
(isSameTokenTransfer || isBridgeToSameChain) &&
|
|
54
65
|
subvariant !== 'custom'
|
|
55
66
|
) {
|
|
56
67
|
setFieldValue(FormKeyHelper.getTokenKey(oppositeFormType), '', {
|
|
@@ -106,6 +117,7 @@ export const useTokenSelect = (formType: FormType, onClick?: () => void) => {
|
|
|
106
117
|
onClick,
|
|
107
118
|
setFieldValue,
|
|
108
119
|
subvariant,
|
|
120
|
+
splitSubvariant,
|
|
109
121
|
tokenKey,
|
|
110
122
|
]
|
|
111
123
|
)
|
package/src/config/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const name = '@lifi/widget'
|
|
2
|
-
export const version = '3.26.0'
|
|
2
|
+
export const version = '3.26.2-beta.0'
|
package/src/hooks/useRoutes.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from '@lifi/sdk'
|
|
11
11
|
import { useAccount } from '@lifi/wallet-management'
|
|
12
12
|
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
|
13
|
+
import { useCallback, useMemo } from 'react'
|
|
13
14
|
import { parseUnits } from 'viem'
|
|
14
15
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
15
16
|
import { useFieldValues } from '../stores/form/useFieldValues.js'
|
|
@@ -137,32 +138,63 @@ export const useRoutes = ({ observableRoute }: RoutesProps = {}) => {
|
|
|
137
138
|
!isBatchingSupportedLoading
|
|
138
139
|
|
|
139
140
|
// Some values should be strictly typed and isEnabled ensures that
|
|
140
|
-
const queryKey =
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
141
|
+
const queryKey = useMemo(
|
|
142
|
+
() =>
|
|
143
|
+
[
|
|
144
|
+
getQueryKey('routes', keyPrefix),
|
|
145
|
+
account.address,
|
|
146
|
+
fromChain?.id as number,
|
|
147
|
+
fromToken?.address as string,
|
|
148
|
+
fromTokenAmount,
|
|
149
|
+
toWalletAddress,
|
|
150
|
+
toChain?.id as number,
|
|
151
|
+
toToken?.address as string,
|
|
152
|
+
toTokenAmount,
|
|
153
|
+
contractCalls,
|
|
154
|
+
slippage,
|
|
155
|
+
swapOnly,
|
|
156
|
+
disabledBridges,
|
|
157
|
+
disabledExchanges,
|
|
158
|
+
allowedBridges,
|
|
159
|
+
allowedExchanges,
|
|
160
|
+
routePriority,
|
|
161
|
+
subvariant,
|
|
162
|
+
allowSwitchChain,
|
|
163
|
+
enabledRefuel && enabledAutoRefuel,
|
|
164
|
+
gasRecommendationFromAmount,
|
|
165
|
+
feeConfig?.fee || fee,
|
|
166
|
+
!!isBatchingSupported,
|
|
167
|
+
observableRoute?.id,
|
|
168
|
+
] as const,
|
|
169
|
+
[
|
|
170
|
+
keyPrefix,
|
|
171
|
+
account.address,
|
|
172
|
+
fromChain?.id,
|
|
173
|
+
fromToken?.address,
|
|
174
|
+
fromTokenAmount,
|
|
175
|
+
toWalletAddress,
|
|
176
|
+
toChain?.id,
|
|
177
|
+
toToken?.address,
|
|
178
|
+
toTokenAmount,
|
|
179
|
+
contractCalls,
|
|
180
|
+
slippage,
|
|
181
|
+
swapOnly,
|
|
182
|
+
disabledBridges,
|
|
183
|
+
disabledExchanges,
|
|
184
|
+
allowedBridges,
|
|
185
|
+
allowedExchanges,
|
|
186
|
+
routePriority,
|
|
187
|
+
subvariant,
|
|
188
|
+
allowSwitchChain,
|
|
189
|
+
enabledRefuel,
|
|
190
|
+
enabledAutoRefuel,
|
|
191
|
+
gasRecommendationFromAmount,
|
|
192
|
+
feeConfig?.fee,
|
|
193
|
+
fee,
|
|
194
|
+
isBatchingSupported,
|
|
195
|
+
observableRoute?.id,
|
|
196
|
+
]
|
|
197
|
+
)
|
|
166
198
|
|
|
167
199
|
const { getIntermediateRoutes, setIntermediateRoutes } =
|
|
168
200
|
useIntermediateRoutesStore()
|
|
@@ -496,13 +528,16 @@ export const useRoutes = ({ observableRoute }: RoutesProps = {}) => {
|
|
|
496
528
|
},
|
|
497
529
|
})
|
|
498
530
|
|
|
499
|
-
const setReviewableRoute = (
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
531
|
+
const setReviewableRoute = useCallback(
|
|
532
|
+
(route: Route) => {
|
|
533
|
+
const queryDataKey = queryKey.toSpliced(queryKey.length - 1, 1, route.id)
|
|
534
|
+
queryClient.setQueryData(queryDataKey, [route], {
|
|
535
|
+
updatedAt: dataUpdatedAt || Date.now(),
|
|
536
|
+
})
|
|
537
|
+
setExecutableRoute(route)
|
|
538
|
+
},
|
|
539
|
+
[queryClient, dataUpdatedAt, setExecutableRoute, queryKey]
|
|
540
|
+
)
|
|
506
541
|
|
|
507
542
|
return {
|
|
508
543
|
routes: data || getIntermediateRoutes(queryKey),
|
|
@@ -25,12 +25,20 @@ export const MainPage: React.FC = () => {
|
|
|
25
25
|
const custom = subvariant === 'custom'
|
|
26
26
|
const showPoweredBy = !hiddenUI?.includes(HiddenUI.PoweredBy)
|
|
27
27
|
|
|
28
|
+
const splitTitle =
|
|
29
|
+
subvariantOptions?.split === 'bridge'
|
|
30
|
+
? t('header.bridge')
|
|
31
|
+
: subvariantOptions?.split === 'swap'
|
|
32
|
+
? t('header.swap')
|
|
33
|
+
: undefined
|
|
28
34
|
const title =
|
|
29
35
|
subvariant === 'custom'
|
|
30
36
|
? t(`header.${subvariantOptions?.custom ?? 'checkout'}`)
|
|
31
37
|
: subvariant === 'refuel'
|
|
32
38
|
? t('header.gas')
|
|
33
|
-
:
|
|
39
|
+
: subvariant === 'split' && splitTitle
|
|
40
|
+
? splitTitle
|
|
41
|
+
: t('header.exchange')
|
|
34
42
|
|
|
35
43
|
useHeader(title)
|
|
36
44
|
|
package/src/themes/azureLight.ts
CHANGED
|
@@ -48,12 +48,11 @@ export const azureLightTheme: WidgetTheme = {
|
|
|
48
48
|
defaultProps: { variant: 'filled' },
|
|
49
49
|
},
|
|
50
50
|
// Used only for 'split' subvariant and can be safely removed if not used
|
|
51
|
-
|
|
51
|
+
MuiNavigationTabs: {
|
|
52
52
|
styleOverrides: {
|
|
53
53
|
root: {
|
|
54
|
-
backgroundColor: '#f8f8fa',
|
|
55
54
|
[`.${tabsClasses.indicator}`]: {
|
|
56
|
-
backgroundColor: '#
|
|
55
|
+
backgroundColor: '#f8f8fa',
|
|
57
56
|
},
|
|
58
57
|
},
|
|
59
58
|
},
|
|
@@ -469,6 +469,12 @@ export const createTheme = (widgetTheme: WidgetTheme = {}) => {
|
|
|
469
469
|
},
|
|
470
470
|
},
|
|
471
471
|
},
|
|
472
|
+
MuiNavigationTabs: {
|
|
473
|
+
...widgetTheme.components?.MuiNavigationTabs,
|
|
474
|
+
},
|
|
475
|
+
MuiNavigationTab: {
|
|
476
|
+
...widgetTheme.components?.MuiNavigationTab,
|
|
477
|
+
},
|
|
472
478
|
},
|
|
473
479
|
})
|
|
474
480
|
|
package/src/themes/types.ts
CHANGED
|
@@ -3,6 +3,8 @@ import type {
|
|
|
3
3
|
ComponentsOverrides,
|
|
4
4
|
ComponentsVariants,
|
|
5
5
|
SimplePaletteColorOptions,
|
|
6
|
+
TabProps,
|
|
7
|
+
TabsProps,
|
|
6
8
|
} from '@mui/material'
|
|
7
9
|
import type {} from '@mui/material/themeCssVarsAugmentation'
|
|
8
10
|
import type { CSSProperties } from 'react'
|
|
@@ -42,9 +44,13 @@ declare module '@mui/material/styles' {
|
|
|
42
44
|
}
|
|
43
45
|
interface ComponentNameToClassKey {
|
|
44
46
|
MuiInputCard: 'root'
|
|
47
|
+
MuiNavigationTabs: 'root'
|
|
48
|
+
MuiNavigationTab: 'root'
|
|
45
49
|
}
|
|
46
50
|
interface ComponentsPropsList {
|
|
47
51
|
MuiInputCard: Partial<CardProps>
|
|
52
|
+
MuiNavigationTabs: Partial<TabsProps>
|
|
53
|
+
MuiNavigationTab: Partial<TabProps>
|
|
48
54
|
}
|
|
49
55
|
interface Components {
|
|
50
56
|
MuiInputCard?: {
|
|
@@ -54,6 +60,20 @@ declare module '@mui/material/styles' {
|
|
|
54
60
|
>['MuiInputCard']
|
|
55
61
|
variants?: ComponentsVariants['MuiInputCard']
|
|
56
62
|
}
|
|
63
|
+
MuiNavigationTabs?: {
|
|
64
|
+
defaultProps?: ComponentsPropsList['MuiNavigationTabs']
|
|
65
|
+
styleOverrides?: ComponentsOverrides<
|
|
66
|
+
Omit<Theme, 'components'>
|
|
67
|
+
>['MuiNavigationTabs']
|
|
68
|
+
variants?: ComponentsVariants['MuiNavigationTabs']
|
|
69
|
+
}
|
|
70
|
+
MuiNavigationTab?: {
|
|
71
|
+
defaultProps?: ComponentsPropsList['MuiNavigationTab']
|
|
72
|
+
styleOverrides?: ComponentsOverrides<
|
|
73
|
+
Omit<Theme, 'components'>
|
|
74
|
+
>['MuiNavigationTab']
|
|
75
|
+
variants?: ComponentsVariants['MuiNavigationTab']
|
|
76
|
+
}
|
|
57
77
|
}
|
|
58
78
|
interface Palette {
|
|
59
79
|
playground: Palette['primary']
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { tabsClasses } from '@mui/material'
|
|
1
2
|
import type { WidgetTheme } from '../types/widget.js'
|
|
2
3
|
|
|
3
4
|
export const watermelonLightTheme: WidgetTheme = {
|
|
@@ -46,6 +47,17 @@ export const watermelonLightTheme: WidgetTheme = {
|
|
|
46
47
|
MuiCard: {
|
|
47
48
|
defaultProps: { variant: 'elevation' },
|
|
48
49
|
},
|
|
50
|
+
MuiNavigationTabs: {
|
|
51
|
+
styleOverrides: {
|
|
52
|
+
root: ({ theme }) => ({
|
|
53
|
+
[`.${tabsClasses.indicator}`]: {
|
|
54
|
+
backgroundColor: '#ffffff',
|
|
55
|
+
filter: `drop-shadow(0 1px 4px rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.08))`,
|
|
56
|
+
borderRadius: '16px',
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
59
|
+
},
|
|
60
|
+
},
|
|
49
61
|
// MuiIconButton: {
|
|
50
62
|
// styleOverrides: {
|
|
51
63
|
// root: ({ theme }) => ({
|