@lifi/widget 4.1.0 → 4.2.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/dist/esm/AppDefault.js +14 -0
- package/dist/esm/AppDefault.js.map +1 -1
- package/dist/esm/components/AmountInput/AmountInput.js +2 -1
- package/dist/esm/components/AmountInput/AmountInput.js.map +1 -1
- package/dist/esm/components/AmountInput/AmountInputEndAdornment.js +4 -2
- package/dist/esm/components/AmountInput/AmountInputEndAdornment.js.map +1 -1
- package/dist/esm/components/AmountInput/AmountInputEndAdornment.style.js +1 -1
- package/dist/esm/components/AmountInput/AmountInputEndAdornment.style.js.map +1 -1
- package/dist/esm/components/AmountInput/PriceFormHelperText.js +4 -2
- package/dist/esm/components/AmountInput/PriceFormHelperText.js.map +1 -1
- package/dist/esm/components/AmountInputCard/AmountInputCard.style.js +98 -0
- package/dist/esm/components/AmountInputCard/AmountInputCard.style.js.map +1 -0
- package/dist/esm/components/AmountInputCard/AmountInputCardPair.js +25 -0
- package/dist/esm/components/AmountInputCard/AmountInputCardPair.js.map +1 -0
- package/dist/esm/components/AmountInputCard/BalanceDisplay.js +35 -0
- package/dist/esm/components/AmountInputCard/BalanceDisplay.js.map +1 -0
- package/dist/esm/components/AmountInputCard/BalanceDisplay.style.js +11 -0
- package/dist/esm/components/AmountInputCard/BalanceDisplay.style.js.map +1 -0
- package/dist/esm/components/AmountInputCard/FiatValueToggle.js +41 -0
- package/dist/esm/components/AmountInputCard/FiatValueToggle.js.map +1 -0
- package/dist/esm/components/AmountInputCard/PercentageChips.js +80 -0
- package/dist/esm/components/AmountInputCard/PercentageChips.js.map +1 -0
- package/dist/esm/components/AmountInputCard/PercentageChips.style.js +43 -0
- package/dist/esm/components/AmountInputCard/PercentageChips.style.js.map +1 -0
- package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js +137 -0
- package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js.map +1 -0
- package/dist/esm/components/AmountInputCard/SendAmountCard.js +102 -0
- package/dist/esm/components/AmountInputCard/SendAmountCard.js.map +1 -0
- package/dist/esm/components/Avatar/Avatar.js +12 -3
- package/dist/esm/components/Avatar/Avatar.js.map +1 -1
- package/dist/esm/components/Chains/VirtualizedChainList.js +2 -1
- package/dist/esm/components/Chains/VirtualizedChainList.js.map +1 -1
- package/dist/esm/components/Header/HeaderNavigationTabs.js +14 -1
- package/dist/esm/components/Header/HeaderNavigationTabs.js.map +1 -1
- package/dist/esm/components/IconCircle/IconCircle.style.js +1 -1
- package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.js +99 -0
- package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.js.map +1 -0
- package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.style.js +52 -0
- package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.style.js.map +1 -0
- package/dist/esm/components/LimitPriceCard/LimitPriceCard.js +115 -0
- package/dist/esm/components/LimitPriceCard/LimitPriceCard.js.map +1 -0
- package/dist/esm/components/LimitPriceCard/LimitPriceCard.style.js +89 -0
- package/dist/esm/components/LimitPriceCard/LimitPriceCard.style.js.map +1 -0
- package/dist/esm/components/LimitPriceCard/LimitPricePresets.js +91 -0
- package/dist/esm/components/LimitPriceCard/LimitPricePresets.js.map +1 -0
- package/dist/esm/components/RouteCard/RouteProviderCard.js +118 -0
- package/dist/esm/components/RouteCard/RouteProviderCard.js.map +1 -0
- package/dist/esm/components/Routes/LimitOrderRoutes.js +34 -0
- package/dist/esm/components/Routes/LimitOrderRoutes.js.map +1 -0
- package/dist/esm/components/Routes/Routes.js +2 -2
- package/dist/esm/components/Routes/Routes.js.map +1 -1
- package/dist/esm/components/SettingsPanel/SettingsPanel.js +51 -0
- package/dist/esm/components/SettingsPanel/SettingsPanel.js.map +1 -0
- package/dist/esm/components/SettingsPanel/SettingsPanel.style.js +33 -0
- package/dist/esm/components/SettingsPanel/SettingsPanel.style.js.map +1 -0
- package/dist/esm/components/SettingsPanel/utils.js +14 -0
- package/dist/esm/components/SettingsPanel/utils.js.map +1 -0
- package/dist/esm/components/SwapButton/SwapButton.js +50 -0
- package/dist/esm/components/SwapButton/SwapButton.js.map +1 -0
- package/dist/esm/components/SwapButton/SwapButton.style.js +24 -0
- package/dist/esm/components/SwapButton/SwapButton.style.js.map +1 -0
- package/dist/esm/components/TokenPillButton/TokenPillButton.js +52 -0
- package/dist/esm/components/TokenPillButton/TokenPillButton.js.map +1 -0
- package/dist/esm/components/TokenPillButton/TokenPillButton.style.js +39 -0
- package/dist/esm/components/TokenPillButton/TokenPillButton.style.js.map +1 -0
- 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/useChainSearch.js +2 -1
- package/dist/esm/hooks/useChainSearch.js.map +1 -1
- package/dist/esm/hooks/useLimitMarketRate.js +24 -0
- package/dist/esm/hooks/useLimitMarketRate.js.map +1 -0
- package/dist/esm/hooks/useLinkedLimitFields.js +49 -0
- package/dist/esm/hooks/useLinkedLimitFields.js.map +1 -0
- package/dist/esm/hooks/useRoutes.js +23 -6
- package/dist/esm/hooks/useRoutes.js.map +1 -1
- package/dist/esm/hooks/useTokens.js +16 -14
- package/dist/esm/hooks/useTokens.js.map +1 -1
- package/dist/esm/hooks/useWideVariant.js +5 -2
- package/dist/esm/hooks/useWideVariant.js.map +1 -1
- package/dist/esm/i18n/en.json +22 -0
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/pages/MainPage/LimitPageContent.js +23 -0
- package/dist/esm/pages/MainPage/LimitPageContent.js.map +1 -0
- package/dist/esm/pages/MainPage/MainPage.js +19 -22
- package/dist/esm/pages/MainPage/MainPage.js.map +1 -1
- package/dist/esm/pages/MainPage/MainPageActions.js +28 -0
- package/dist/esm/pages/MainPage/MainPageActions.js.map +1 -0
- package/dist/esm/pages/MainPage/ReviewButton.js +9 -2
- package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
- package/dist/esm/pages/RoutePriorityPage.js +48 -0
- package/dist/esm/pages/RoutePriorityPage.js.map +1 -0
- package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js +2 -2
- package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js +12 -27
- package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippagePage.js +133 -0
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippagePage.js.map +1 -0
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js +14 -72
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.style.js +26 -14
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.style.js.map +1 -1
- package/dist/esm/pages/SettingsPage/ThemeSettings.js +4 -0
- package/dist/esm/pages/SettingsPage/ThemeSettings.js.map +1 -1
- package/dist/esm/pages/TransactionPage/TransactionReview.js +4 -1
- package/dist/esm/pages/TransactionPage/TransactionReview.js.map +1 -1
- package/dist/esm/providers/I18nProvider/I18nProvider.js +1 -1
- package/dist/esm/providers/I18nProvider/enResource.d.ts +1 -1
- package/dist/esm/providers/I18nProvider/enResource.js +1 -1
- package/dist/esm/providers/I18nProvider/types.d.ts +2 -2
- package/dist/esm/providers/SDKClientProvider.js +25 -24
- package/dist/esm/providers/SDKClientProvider.js.map +1 -1
- package/dist/esm/providers/WidgetProvider/WidgetProvider.js +22 -21
- package/dist/esm/providers/WidgetProvider/WidgetProvider.js.map +1 -1
- package/dist/esm/stores/form/URLSearchParamsBuilder.js +14 -3
- package/dist/esm/stores/form/URLSearchParamsBuilder.js.map +1 -1
- package/dist/esm/stores/form/createFormStore.js +6 -2
- package/dist/esm/stores/form/createFormStore.js.map +1 -1
- package/dist/esm/stores/form/getDefaultValuesFromQueryString.js +3 -0
- package/dist/esm/stores/form/getDefaultValuesFromQueryString.js.map +1 -1
- package/dist/esm/stores/form/types.d.ts +9 -1
- package/dist/esm/stores/form/types.d.ts.map +1 -1
- package/dist/esm/stores/form/types.js.map +1 -1
- package/dist/esm/stores/form/useClearAmountFields.js +1 -0
- package/dist/esm/stores/form/useClearAmountFields.js.map +1 -1
- package/dist/esm/stores/navigationTabs/useNavigationTabsStore.js +4 -2
- package/dist/esm/stores/navigationTabs/useNavigationTabsStore.js.map +1 -1
- package/dist/esm/stores/navigationTabs/utils.js +38 -8
- package/dist/esm/stores/navigationTabs/utils.js.map +1 -1
- package/dist/esm/types/events.d.ts +10 -1
- package/dist/esm/types/events.d.ts.map +1 -1
- package/dist/esm/types/events.js +2 -0
- package/dist/esm/types/events.js.map +1 -1
- package/dist/esm/types/widget.d.ts +9 -0
- package/dist/esm/types/widget.d.ts.map +1 -1
- package/dist/esm/types/widget.js.map +1 -1
- package/dist/esm/utils/format.d.ts +1 -1
- package/dist/esm/utils/format.d.ts.map +1 -1
- package/dist/esm/utils/format.js +2 -2
- package/dist/esm/utils/format.js.map +1 -1
- package/dist/esm/utils/limitOrder.js +61 -0
- package/dist/esm/utils/limitOrder.js.map +1 -0
- package/dist/esm/utils/navigationRoutes.d.ts +2 -0
- package/dist/esm/utils/navigationRoutes.d.ts.map +1 -1
- package/dist/esm/utils/navigationRoutes.js +6 -0
- package/dist/esm/utils/navigationRoutes.js.map +1 -1
- package/package.json +11 -11
- package/src/AppDefault.tsx +16 -0
- package/src/components/AmountInput/AmountInputEndAdornment.style.ts +1 -1
- package/src/components/AmountInput/AmountInputEndAdornment.tsx +5 -2
- package/src/components/AmountInputCard/AmountInputCard.style.tsx +157 -0
- package/src/components/AmountInputCard/AmountInputCardPair.tsx +25 -0
- package/src/components/AmountInputCard/BalanceDisplay.style.tsx +9 -0
- package/src/components/AmountInputCard/BalanceDisplay.tsx +46 -0
- package/src/components/AmountInputCard/FiatValueToggle.tsx +55 -0
- package/src/components/AmountInputCard/PercentageChips.style.tsx +60 -0
- package/src/components/AmountInputCard/PercentageChips.tsx +100 -0
- package/src/components/AmountInputCard/ReceiveAmountCard.tsx +219 -0
- package/src/components/AmountInputCard/SendAmountCard.tsx +179 -0
- package/src/components/Avatar/Avatar.tsx +8 -3
- package/src/components/Header/HeaderNavigationTabs.tsx +19 -2
- package/src/components/LimitOrderSettings/LimitOrderSettings.style.tsx +69 -0
- package/src/components/LimitOrderSettings/LimitOrderSettings.tsx +124 -0
- package/src/components/LimitPriceCard/LimitPriceCard.style.tsx +103 -0
- package/src/components/LimitPriceCard/LimitPriceCard.tsx +153 -0
- package/src/components/LimitPriceCard/LimitPricePresets.tsx +139 -0
- package/src/components/RouteCard/RouteProviderCard.tsx +113 -0
- package/src/components/Routes/LimitOrderRoutes.tsx +64 -0
- package/src/components/Routes/Routes.tsx +3 -2
- package/src/components/SettingsPanel/SettingsPanel.style.tsx +41 -0
- package/src/components/SettingsPanel/SettingsPanel.tsx +73 -0
- package/src/components/SettingsPanel/utils.ts +27 -0
- package/src/components/SwapButton/SwapButton.style.tsx +28 -0
- package/src/components/SwapButton/SwapButton.tsx +71 -0
- package/src/components/TokenPillButton/TokenPillButton.style.tsx +50 -0
- package/src/components/TokenPillButton/TokenPillButton.tsx +81 -0
- package/src/config/version.ts +1 -1
- package/src/hooks/useLimitMarketRate.ts +39 -0
- package/src/hooks/useLinkedLimitFields.ts +74 -0
- package/src/hooks/useRoutes.ts +45 -4
- package/src/hooks/useWideVariant.ts +8 -2
- package/src/pages/MainPage/LimitPageContent.tsx +18 -0
- package/src/pages/MainPage/MainPage.tsx +43 -30
- package/src/pages/MainPage/MainPageActions.tsx +35 -0
- package/src/pages/MainPage/ReviewButton.tsx +13 -1
- package/src/pages/RoutePriorityPage.tsx +55 -0
- package/src/pages/SettingsPage/RoutePrioritySettings.tsx +14 -38
- package/src/pages/SettingsPage/SlippageSettings/SlippagePage.tsx +176 -0
- package/src/pages/SettingsPage/SlippageSettings/SlippageSettings.style.tsx +32 -25
- package/src/pages/SettingsPage/SlippageSettings/SlippageSettings.tsx +14 -128
- package/src/pages/SettingsPage/ThemeSettings.tsx +4 -0
- package/src/stores/form/URLSearchParamsBuilder.tsx +25 -3
- package/src/stores/form/createFormStore.ts +7 -3
- package/src/stores/form/getDefaultValuesFromQueryString.ts +11 -0
- package/src/stores/form/types.ts +14 -1
- package/src/stores/form/useClearAmountFields.ts +1 -0
- package/src/stores/navigationTabs/types.ts +6 -0
- package/src/stores/navigationTabs/useNavigationTabsStore.tsx +8 -3
- package/src/stores/navigationTabs/utils.ts +67 -5
- package/src/types/events.ts +12 -0
- package/src/types/widget.ts +9 -0
- package/src/utils/format.ts +6 -2
- package/src/utils/limitOrder.ts +88 -0
- package/src/utils/navigationRoutes.ts +6 -0
|
@@ -1,26 +1,38 @@
|
|
|
1
|
-
import { Box } from '@mui/material'
|
|
2
1
|
import { useTranslation } from 'react-i18next'
|
|
3
2
|
import { AmountInput } from '../../components/AmountInput/AmountInput.js'
|
|
3
|
+
import { AmountInputCardPair } from '../../components/AmountInputCard/AmountInputCardPair.js'
|
|
4
4
|
import { ContractComponent } from '../../components/ContractComponent/ContractComponent.js'
|
|
5
5
|
import { GasRefuelMessage } from '../../components/Messages/GasRefuelMessage.js'
|
|
6
6
|
import { PageContainer } from '../../components/PageContainer.js'
|
|
7
|
-
import { PoweredBy } from '../../components/PoweredBy/PoweredBy.js'
|
|
8
7
|
import { Routes } from '../../components/Routes/Routes.js'
|
|
9
8
|
import { SelectChainAndToken } from '../../components/SelectChainAndToken.js'
|
|
10
9
|
import { SendToWalletButton } from '../../components/SendToWallet/SendToWalletButton.js'
|
|
11
|
-
import {
|
|
10
|
+
import { SettingsPanel } from '../../components/SettingsPanel/SettingsPanel.js'
|
|
11
|
+
import { advancedNavigationTabKeys } from '../../components/SettingsPanel/utils.js'
|
|
12
12
|
import { useHeader } from '../../hooks/useHeader.js'
|
|
13
13
|
import { useWideVariant } from '../../hooks/useWideVariant.js'
|
|
14
14
|
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
15
|
+
import { useNavigationTabsStore } from '../../stores/navigationTabs/useNavigationTabsStore.js'
|
|
16
|
+
import { LimitPageContent } from './LimitPageContent.js'
|
|
17
|
+
import { MainPageActions } from './MainPageActions.js'
|
|
18
|
+
|
|
19
|
+
const marginSx = { marginBottom: 2 }
|
|
17
20
|
|
|
18
21
|
export const MainPage: React.FC = () => {
|
|
19
22
|
const { t } = useTranslation()
|
|
20
23
|
const wideVariant = useWideVariant()
|
|
21
|
-
const { mode, modeOptions, contractComponent, hiddenUI } =
|
|
24
|
+
const { mode, modeOptions, contractComponent, hiddenUI, defaultUI } =
|
|
25
|
+
useWidgetConfig()
|
|
26
|
+
const activeTab = useNavigationTabsStore((state) => state.activeTab)
|
|
27
|
+
|
|
22
28
|
const custom = mode === 'custom'
|
|
23
|
-
|
|
29
|
+
// Surface the settings panel on the main page for advanced navigation tabs.
|
|
30
|
+
const advancedMode =
|
|
31
|
+
!!activeTab && advancedNavigationTabKeys.includes(activeTab)
|
|
32
|
+
const showSendReceiveCards = defaultUI?.layout === 'cards'
|
|
33
|
+
// Custom non-deposit contract flows have no amount entry — they keep the
|
|
34
|
+
// chain/token selectors only, in both layouts.
|
|
35
|
+
const showAmountEntry = !custom || modeOptions?.custom?.type === 'deposit'
|
|
24
36
|
const showGasRefuelMessage = !hiddenUI?.gasRefuelMessage
|
|
25
37
|
|
|
26
38
|
const splitTitle =
|
|
@@ -30,41 +42,42 @@ export const MainPage: React.FC = () => {
|
|
|
30
42
|
? t('header.swap')
|
|
31
43
|
: undefined
|
|
32
44
|
const title =
|
|
33
|
-
mode === '
|
|
34
|
-
? t(
|
|
35
|
-
: mode === '
|
|
36
|
-
? t(
|
|
37
|
-
: mode === '
|
|
38
|
-
?
|
|
39
|
-
:
|
|
45
|
+
mode === 'limit'
|
|
46
|
+
? t('header.limit')
|
|
47
|
+
: mode === 'custom'
|
|
48
|
+
? t(`header.${modeOptions?.custom?.type ?? 'checkout'}`)
|
|
49
|
+
: mode === 'refuel'
|
|
50
|
+
? t('header.gas')
|
|
51
|
+
: mode === 'split' && splitTitle
|
|
52
|
+
? splitTitle
|
|
53
|
+
: t('header.exchange')
|
|
40
54
|
|
|
41
55
|
useHeader(title)
|
|
42
56
|
|
|
43
|
-
|
|
57
|
+
if (mode === 'limit') {
|
|
58
|
+
return <LimitPageContent />
|
|
59
|
+
}
|
|
44
60
|
|
|
45
61
|
return (
|
|
46
62
|
<PageContainer topGutters>
|
|
47
63
|
{custom ? (
|
|
48
64
|
<ContractComponent sx={marginSx}>{contractComponent}</ContractComponent>
|
|
49
65
|
) : null}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
66
|
+
{showSendReceiveCards && showAmountEntry ? (
|
|
67
|
+
<AmountInputCardPair sx={marginSx} />
|
|
68
|
+
) : (
|
|
69
|
+
<>
|
|
70
|
+
<SelectChainAndToken sx={marginSx} />
|
|
71
|
+
{!showSendReceiveCards && showAmountEntry ? (
|
|
72
|
+
<AmountInput formType="from" sx={marginSx} />
|
|
73
|
+
) : null}
|
|
74
|
+
</>
|
|
75
|
+
)}
|
|
76
|
+
{advancedMode ? <SettingsPanel sx={marginSx} /> : null}
|
|
54
77
|
{!wideVariant ? <Routes sx={marginSx} /> : null}
|
|
55
78
|
<SendToWalletButton sx={marginSx} />
|
|
56
79
|
{showGasRefuelMessage ? <GasRefuelMessage sx={marginSx} /> : null}
|
|
57
|
-
<
|
|
58
|
-
<Box
|
|
59
|
-
sx={{
|
|
60
|
-
display: 'flex',
|
|
61
|
-
mb: showPoweredBy ? 1 : 3,
|
|
62
|
-
}}
|
|
63
|
-
>
|
|
64
|
-
<ReviewButton />
|
|
65
|
-
<SendToWalletExpandButton />
|
|
66
|
-
</Box>
|
|
67
|
-
{showPoweredBy ? <PoweredBy /> : null}
|
|
80
|
+
<MainPageActions showSendToWalletExpand />
|
|
68
81
|
</PageContainer>
|
|
69
82
|
)
|
|
70
83
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Box } from '@mui/material'
|
|
2
|
+
import { PoweredBy } from '../../components/PoweredBy/PoweredBy.js'
|
|
3
|
+
import { SendToWalletExpandButton } from '../../components/SendToWallet/SendToWalletExpandButton.js'
|
|
4
|
+
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
|
|
5
|
+
import { MainWarningMessages } from './MainWarningMessages.js'
|
|
6
|
+
import { ReviewButton } from './ReviewButton.js'
|
|
7
|
+
|
|
8
|
+
interface MainPageActionsProps {
|
|
9
|
+
showSendToWalletExpand?: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const marginSx = { marginBottom: 2 }
|
|
13
|
+
|
|
14
|
+
export const MainPageActions: React.FC<MainPageActionsProps> = ({
|
|
15
|
+
showSendToWalletExpand,
|
|
16
|
+
}) => {
|
|
17
|
+
const { hiddenUI } = useWidgetConfig()
|
|
18
|
+
const showPoweredBy = !hiddenUI?.poweredBy
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<>
|
|
22
|
+
<MainWarningMessages sx={marginSx} />
|
|
23
|
+
<Box
|
|
24
|
+
sx={{
|
|
25
|
+
display: 'flex',
|
|
26
|
+
mb: showPoweredBy ? 1 : 3,
|
|
27
|
+
}}
|
|
28
|
+
>
|
|
29
|
+
<ReviewButton />
|
|
30
|
+
{showSendToWalletExpand ? <SendToWalletExpandButton /> : null}
|
|
31
|
+
</Box>
|
|
32
|
+
{showPoweredBy ? <PoweredBy /> : null}
|
|
33
|
+
</>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
@@ -5,6 +5,7 @@ import { useRoutes } from '../../hooks/useRoutes.js'
|
|
|
5
5
|
import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js'
|
|
6
6
|
import { useWidgetEvents } from '../../hooks/useWidgetEvents.js'
|
|
7
7
|
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
|
|
8
|
+
import { useFieldValues } from '../../stores/form/useFieldValues.js'
|
|
8
9
|
import { useSplitMode } from '../../stores/navigationTabs/useNavigationTabsStore.js'
|
|
9
10
|
import { WidgetEvent } from '../../types/events.js'
|
|
10
11
|
import { navigationRoutes } from '../../utils/navigationRoutes.js'
|
|
@@ -17,8 +18,15 @@ export const ReviewButton: React.FC = () => {
|
|
|
17
18
|
const splitState = useSplitMode()
|
|
18
19
|
const { toAddress, requiredToAddress } = useToAddressRequirements()
|
|
19
20
|
const { routes, setReviewableRoute } = useRoutes()
|
|
21
|
+
const [selectedRouteId] = useFieldValues('selectedRouteId')
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
// The provider pick only applies in limit mode (it's the only flow that sets
|
|
24
|
+
// it). Honoring it in other modes would be wrong, since provider/tool keys
|
|
25
|
+
// can collide across modes. Everywhere else, fall back to the best route.
|
|
26
|
+
const currentRoute =
|
|
27
|
+
(mode === 'limit'
|
|
28
|
+
? routes?.find((route) => route.id === selectedRouteId)
|
|
29
|
+
: undefined) ?? routes?.[0]
|
|
22
30
|
|
|
23
31
|
const handleClick = async () => {
|
|
24
32
|
if (!currentRoute) {
|
|
@@ -43,6 +51,8 @@ export const ReviewButton: React.FC = () => {
|
|
|
43
51
|
return t(`button.${modeOptions?.custom?.type ?? 'checkout'}Review`)
|
|
44
52
|
case 'refuel':
|
|
45
53
|
return t('button.getGas')
|
|
54
|
+
case 'limit':
|
|
55
|
+
return t('button.review')
|
|
46
56
|
default: {
|
|
47
57
|
const transactionType =
|
|
48
58
|
currentRoute.fromChainId === currentRoute.toChainId
|
|
@@ -59,6 +69,8 @@ export const ReviewButton: React.FC = () => {
|
|
|
59
69
|
: t('button.buy')
|
|
60
70
|
case 'refuel':
|
|
61
71
|
return t('button.getGas')
|
|
72
|
+
case 'limit':
|
|
73
|
+
return t('button.review')
|
|
62
74
|
case 'split':
|
|
63
75
|
if (splitState) {
|
|
64
76
|
return t(`button.${splitState}`)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Order } from '@lifi/sdk'
|
|
2
|
+
import Check from '@mui/icons-material/Check'
|
|
3
|
+
import { List } from '@mui/material'
|
|
4
|
+
import { useRef } from 'react'
|
|
5
|
+
import { useTranslation } from 'react-i18next'
|
|
6
|
+
import { ListItemText } from '../components/ListItemText.js'
|
|
7
|
+
import { PageContainer } from '../components/PageContainer.js'
|
|
8
|
+
import { SettingsListItemButton } from '../components/SettingsListItemButton.js'
|
|
9
|
+
import { useHeader } from '../hooks/useHeader.js'
|
|
10
|
+
import { useListHeight } from '../hooks/useListHeight.js'
|
|
11
|
+
import { useSettings } from '../stores/settings/useSettings.js'
|
|
12
|
+
import { useSettingsActions } from '../stores/settings/useSettingsActions.js'
|
|
13
|
+
|
|
14
|
+
const routePriorities: Order[] = ['CHEAPEST', 'FASTEST']
|
|
15
|
+
|
|
16
|
+
export const RoutePriorityPage: React.FC = () => {
|
|
17
|
+
const { t } = useTranslation()
|
|
18
|
+
const { setValue } = useSettingsActions()
|
|
19
|
+
const { routePriority } = useSettings(['routePriority'])
|
|
20
|
+
const listParentRef = useRef<HTMLUListElement | null>(null)
|
|
21
|
+
const { listHeight } = useListHeight({ listParentRef })
|
|
22
|
+
|
|
23
|
+
useHeader(t('settings.routePriority'))
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<PageContainer disableGutters>
|
|
27
|
+
<List
|
|
28
|
+
className="long-list"
|
|
29
|
+
ref={listParentRef}
|
|
30
|
+
style={{ height: listHeight, overflow: 'auto' }}
|
|
31
|
+
sx={{
|
|
32
|
+
padding: 1.5,
|
|
33
|
+
}}
|
|
34
|
+
>
|
|
35
|
+
{routePriorities.map((priority) => {
|
|
36
|
+
const key = priority.toLowerCase()
|
|
37
|
+
return (
|
|
38
|
+
<SettingsListItemButton
|
|
39
|
+
key={priority}
|
|
40
|
+
onClick={() => setValue('routePriority', priority)}
|
|
41
|
+
>
|
|
42
|
+
<ListItemText
|
|
43
|
+
primary={t(`settings.routePriorityOptions.${key}.title` as any)}
|
|
44
|
+
secondary={t(
|
|
45
|
+
`settings.routePriorityOptions.${key}.description` as any
|
|
46
|
+
)}
|
|
47
|
+
/>
|
|
48
|
+
{routePriority === priority && <Check color="primary" />}
|
|
49
|
+
</SettingsListItemButton>
|
|
50
|
+
)
|
|
51
|
+
})}
|
|
52
|
+
</List>
|
|
53
|
+
</PageContainer>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
@@ -1,57 +1,33 @@
|
|
|
1
|
-
import type { Order } from '@lifi/sdk'
|
|
2
1
|
import Route from '@mui/icons-material/Route'
|
|
2
|
+
import { useNavigate } from '@tanstack/react-router'
|
|
3
3
|
import { useTranslation } from 'react-i18next'
|
|
4
|
-
import {
|
|
4
|
+
import { CardButton } from '../../components/Card/CardButton.js'
|
|
5
5
|
import { useSettingMonitor } from '../../hooks/useSettingMonitor.js'
|
|
6
6
|
import { useSettings } from '../../stores/settings/useSettings.js'
|
|
7
|
-
import {
|
|
7
|
+
import { navigationRoutes } from '../../utils/navigationRoutes.js'
|
|
8
8
|
import { BadgedValue } from './SettingsCard/BadgedValue.js'
|
|
9
|
-
import { SettingCardExpandable } from './SettingsCard/SettingCardExpandable.js'
|
|
10
|
-
|
|
11
|
-
const Priorities: Order[] = ['CHEAPEST', 'FASTEST']
|
|
12
9
|
|
|
13
10
|
export const RoutePrioritySettings: React.FC = () => {
|
|
14
11
|
const { t } = useTranslation()
|
|
15
|
-
const
|
|
12
|
+
const navigate = useNavigate()
|
|
16
13
|
const { isRoutePriorityChanged } = useSettingMonitor()
|
|
17
14
|
const { routePriority } = useSettings(['routePriority'])
|
|
18
|
-
const currentRoutePriority = routePriority ?? ''
|
|
19
15
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
routePriority: Order
|
|
23
|
-
) => {
|
|
24
|
-
setValue('routePriority', routePriority)
|
|
16
|
+
const handleClick = () => {
|
|
17
|
+
navigate({ to: navigationRoutes.routePriority })
|
|
25
18
|
}
|
|
26
19
|
|
|
27
20
|
return (
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
<BadgedValue badgeColor="info" showBadge={isRoutePriorityChanged}>
|
|
31
|
-
{t(`main.tags.${currentRoutePriority.toLowerCase()}` as any)}
|
|
32
|
-
</BadgedValue>
|
|
33
|
-
}
|
|
21
|
+
<CardButton
|
|
22
|
+
onClick={handleClick}
|
|
34
23
|
icon={<Route />}
|
|
35
24
|
title={t('settings.routePriority')}
|
|
36
25
|
>
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
>
|
|
44
|
-
{Priorities.map((priority) => {
|
|
45
|
-
return (
|
|
46
|
-
<Tab
|
|
47
|
-
key={priority}
|
|
48
|
-
label={t(`main.tags.${priority.toLowerCase()}` as any)}
|
|
49
|
-
value={priority}
|
|
50
|
-
disableRipple
|
|
51
|
-
/>
|
|
52
|
-
)
|
|
53
|
-
})}
|
|
54
|
-
</CardTabs>
|
|
55
|
-
</SettingCardExpandable>
|
|
26
|
+
<BadgedValue badgeColor="info" showBadge={isRoutePriorityChanged}>
|
|
27
|
+
{routePriority === 'FASTEST'
|
|
28
|
+
? t('settings.routePriorityOptions.fastest.title')
|
|
29
|
+
: t('settings.routePriorityOptions.cheapest.title')}
|
|
30
|
+
</BadgedValue>
|
|
31
|
+
</CardButton>
|
|
56
32
|
)
|
|
57
33
|
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import Check from '@mui/icons-material/Check'
|
|
2
|
+
import CloseRounded from '@mui/icons-material/CloseRounded'
|
|
3
|
+
import WarningRounded from '@mui/icons-material/WarningRounded'
|
|
4
|
+
import { Box, Collapse, List, Typography } from '@mui/material'
|
|
5
|
+
import type { ChangeEventHandler, FocusEventHandler } from 'react'
|
|
6
|
+
import { useRef, useState } from 'react'
|
|
7
|
+
import { useTranslation } from 'react-i18next'
|
|
8
|
+
import { ListItemText } from '../../../components/ListItemText.js'
|
|
9
|
+
import { PageContainer } from '../../../components/PageContainer.js'
|
|
10
|
+
import { SettingsListItemButton } from '../../../components/SettingsListItemButton.js'
|
|
11
|
+
import { useHeader } from '../../../hooks/useHeader.js'
|
|
12
|
+
import { useListHeight } from '../../../hooks/useListHeight.js'
|
|
13
|
+
import { useSettingMonitor } from '../../../hooks/useSettingMonitor.js'
|
|
14
|
+
import { defaultSlippage } from '../../../stores/settings/createSettingsStore.js'
|
|
15
|
+
import { useSettings } from '../../../stores/settings/useSettings.js'
|
|
16
|
+
import { useSettingsActions } from '../../../stores/settings/useSettingsActions.js'
|
|
17
|
+
import { formatInputAmount, formatSlippage } from '../../../utils/format.js'
|
|
18
|
+
import {
|
|
19
|
+
SlippageClearButton,
|
|
20
|
+
SlippageInput,
|
|
21
|
+
SlippageLimitsWarningContainer,
|
|
22
|
+
} from './SlippageSettings.style.js'
|
|
23
|
+
|
|
24
|
+
const slippagePresets = ['0.5', '1']
|
|
25
|
+
const maxFractionDigits = 5
|
|
26
|
+
|
|
27
|
+
export const SlippagePage: React.FC = () => {
|
|
28
|
+
const { t } = useTranslation()
|
|
29
|
+
const {
|
|
30
|
+
isSlippageNotRecommended,
|
|
31
|
+
isSlippageUnderRecommendedLimits,
|
|
32
|
+
isSlippageOutsideRecommendedLimits,
|
|
33
|
+
} = useSettingMonitor()
|
|
34
|
+
const { slippage } = useSettings(['slippage'])
|
|
35
|
+
const { setValue } = useSettingsActions()
|
|
36
|
+
const defaultValue = useRef(slippage)
|
|
37
|
+
const listParentRef = useRef<HTMLUListElement | null>(null)
|
|
38
|
+
const { listHeight } = useListHeight({ listParentRef })
|
|
39
|
+
|
|
40
|
+
useHeader(t('settings.slippage'))
|
|
41
|
+
|
|
42
|
+
const isAuto = !slippage || slippage === defaultSlippage
|
|
43
|
+
const isPreset = !!slippage && slippagePresets.includes(slippage)
|
|
44
|
+
const isCustom = !isAuto && !isPreset
|
|
45
|
+
|
|
46
|
+
const [customMode, setCustomMode] = useState(isCustom)
|
|
47
|
+
const [inputValue, setInputValue] = useState(isCustom ? (slippage ?? '') : '')
|
|
48
|
+
|
|
49
|
+
const handleAuto = () => {
|
|
50
|
+
setCustomMode(false)
|
|
51
|
+
setInputValue('')
|
|
52
|
+
setValue('slippage', defaultSlippage)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const handlePreset = (preset: string) => {
|
|
56
|
+
setCustomMode(false)
|
|
57
|
+
setValue('slippage', preset)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const handleCustom = () => {
|
|
61
|
+
setCustomMode(true)
|
|
62
|
+
const initialValue = slippage || ''
|
|
63
|
+
if (initialValue) {
|
|
64
|
+
setInputValue(initialValue)
|
|
65
|
+
setValue('slippage', initialValue)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const formatAndSetSlippage = (value: string, returnInitial = false) => {
|
|
70
|
+
const formattedSlippage = formatSlippage(
|
|
71
|
+
value,
|
|
72
|
+
defaultValue.current,
|
|
73
|
+
returnInitial
|
|
74
|
+
)
|
|
75
|
+
const formattedValue =
|
|
76
|
+
Number(formattedSlippage) === 0 && !returnInitial
|
|
77
|
+
? '0'
|
|
78
|
+
: formatInputAmount(formattedSlippage, maxFractionDigits, returnInitial)
|
|
79
|
+
const maxLength =
|
|
80
|
+
Number(formattedValue) < 10
|
|
81
|
+
? maxFractionDigits + 2
|
|
82
|
+
: maxFractionDigits + 3
|
|
83
|
+
const slicedValue = formattedValue.slice(0, maxLength)
|
|
84
|
+
setInputValue(slicedValue)
|
|
85
|
+
setValue('slippage', slicedValue.length ? slicedValue : defaultSlippage)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const handleInputUpdate: ChangeEventHandler<HTMLInputElement> = (event) => {
|
|
89
|
+
formatAndSetSlippage(event.target.value, true)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const handleInputFocus: FocusEventHandler<HTMLInputElement> = (event) => {
|
|
93
|
+
formatAndSetSlippage(event.target.value)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const handleInputBlur: FocusEventHandler<HTMLInputElement> = (event) => {
|
|
97
|
+
formatAndSetSlippage(event.target.value)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const slippageWarningText = isSlippageOutsideRecommendedLimits
|
|
101
|
+
? t('warning.message.slippageOutsideRecommendedLimits')
|
|
102
|
+
: isSlippageUnderRecommendedLimits
|
|
103
|
+
? t('warning.message.slippageUnderRecommendedLimits')
|
|
104
|
+
: ''
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<PageContainer disableGutters>
|
|
108
|
+
<List
|
|
109
|
+
className="long-list"
|
|
110
|
+
ref={listParentRef}
|
|
111
|
+
style={{ height: listHeight, overflow: 'auto' }}
|
|
112
|
+
sx={{
|
|
113
|
+
padding: 1.5,
|
|
114
|
+
}}
|
|
115
|
+
>
|
|
116
|
+
<SettingsListItemButton onClick={handleAuto}>
|
|
117
|
+
<ListItemText
|
|
118
|
+
primary={t('button.auto')}
|
|
119
|
+
secondary={t('settings.slippageAutoDescription')}
|
|
120
|
+
/>
|
|
121
|
+
{!customMode && isAuto && <Check color="primary" />}
|
|
122
|
+
</SettingsListItemButton>
|
|
123
|
+
{slippagePresets.map((preset) => (
|
|
124
|
+
<SettingsListItemButton
|
|
125
|
+
key={preset}
|
|
126
|
+
onClick={() => handlePreset(preset)}
|
|
127
|
+
>
|
|
128
|
+
<ListItemText primary={`${preset}%`} />
|
|
129
|
+
{!customMode && slippage === preset && <Check color="primary" />}
|
|
130
|
+
</SettingsListItemButton>
|
|
131
|
+
))}
|
|
132
|
+
<SettingsListItemButton onClick={handleCustom}>
|
|
133
|
+
<ListItemText primary={t('settings.custom')} />
|
|
134
|
+
{customMode && <Check color="primary" />}
|
|
135
|
+
</SettingsListItemButton>
|
|
136
|
+
<Collapse in={customMode}>
|
|
137
|
+
<Box sx={{ px: 1.5, pt: 1 }}>
|
|
138
|
+
<SlippageInput
|
|
139
|
+
placeholder="0.5"
|
|
140
|
+
inputProps={{ inputMode: 'decimal' }}
|
|
141
|
+
value={inputValue}
|
|
142
|
+
onChange={handleInputUpdate}
|
|
143
|
+
onFocus={handleInputFocus}
|
|
144
|
+
onBlur={handleInputBlur}
|
|
145
|
+
autoComplete="off"
|
|
146
|
+
endAdornment={
|
|
147
|
+
!isAuto && (
|
|
148
|
+
<SlippageClearButton
|
|
149
|
+
size="small"
|
|
150
|
+
onClick={handleAuto}
|
|
151
|
+
aria-label="Clear"
|
|
152
|
+
>
|
|
153
|
+
<CloseRounded fontSize="small" />
|
|
154
|
+
</SlippageClearButton>
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
/>
|
|
158
|
+
{isSlippageNotRecommended && (
|
|
159
|
+
<SlippageLimitsWarningContainer>
|
|
160
|
+
<WarningRounded color="warning" />
|
|
161
|
+
<Typography
|
|
162
|
+
sx={{
|
|
163
|
+
fontSize: 13,
|
|
164
|
+
fontWeight: 400,
|
|
165
|
+
}}
|
|
166
|
+
>
|
|
167
|
+
{slippageWarningText}
|
|
168
|
+
</Typography>
|
|
169
|
+
</SlippageLimitsWarningContainer>
|
|
170
|
+
)}
|
|
171
|
+
</Box>
|
|
172
|
+
</Collapse>
|
|
173
|
+
</List>
|
|
174
|
+
</PageContainer>
|
|
175
|
+
)
|
|
176
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Theme } from '@mui/material'
|
|
2
2
|
import {
|
|
3
3
|
Box,
|
|
4
|
-
|
|
4
|
+
IconButton,
|
|
5
5
|
InputBase,
|
|
6
6
|
inputBaseClasses,
|
|
7
7
|
styled,
|
|
@@ -36,30 +36,6 @@ interface SettingsControlProps {
|
|
|
36
36
|
selected?: boolean
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
export const SettingsDefaultButton: React.FC<
|
|
40
|
-
React.ComponentProps<typeof ButtonBase> & SettingsControlProps
|
|
41
|
-
> = styled(ButtonBase)<SettingsControlProps>(({ theme, selected }) => {
|
|
42
|
-
const settingsControlSelectedStyles = settingsControlSelected(theme)
|
|
43
|
-
const selectedStyle = selected
|
|
44
|
-
? {
|
|
45
|
-
'&:not(:focus)': {
|
|
46
|
-
...settingsControlSelectedStyles,
|
|
47
|
-
},
|
|
48
|
-
}
|
|
49
|
-
: {}
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
height: '100%',
|
|
53
|
-
width: '100%',
|
|
54
|
-
fontSize: '1rem',
|
|
55
|
-
fontWeight: 700,
|
|
56
|
-
'&:focus': {
|
|
57
|
-
...settingsControlSelectedStyles,
|
|
58
|
-
},
|
|
59
|
-
...selectedStyle,
|
|
60
|
-
}
|
|
61
|
-
})
|
|
62
|
-
|
|
63
39
|
export const SettingsCustomInput: React.FC<
|
|
64
40
|
React.ComponentProps<typeof InputBase> & SettingsControlProps
|
|
65
41
|
> = styled(InputBase)<SettingsControlProps>(({ theme, selected }) => {
|
|
@@ -100,3 +76,34 @@ export const SlippageLimitsWarningContainer: React.FC<
|
|
|
100
76
|
gap: theme.spacing(1.25),
|
|
101
77
|
marginTop: theme.spacing(1.5),
|
|
102
78
|
}))
|
|
79
|
+
|
|
80
|
+
export const SlippageInput: React.FC<React.ComponentProps<typeof InputBase>> =
|
|
81
|
+
styled(InputBase)(({ theme }) => ({
|
|
82
|
+
minHeight: 44,
|
|
83
|
+
width: '100%',
|
|
84
|
+
backgroundColor: theme.vars.palette.background.default,
|
|
85
|
+
border: '1px solid',
|
|
86
|
+
borderColor: theme.vars.palette.divider,
|
|
87
|
+
borderRadius: theme.vars.shape.borderRadius,
|
|
88
|
+
paddingRight: theme.spacing(1),
|
|
89
|
+
[`.${inputBaseClasses.input}`]: {
|
|
90
|
+
padding: theme.spacing(1.5),
|
|
91
|
+
fontSize: 16,
|
|
92
|
+
fontWeight: 500,
|
|
93
|
+
lineHeight: '20px',
|
|
94
|
+
'&::placeholder': {
|
|
95
|
+
opacity: 1,
|
|
96
|
+
color: theme.vars.palette.text.secondary,
|
|
97
|
+
},
|
|
98
|
+
'&::-webkit-outer-spin-button, &::-webkit-inner-spin-button': {
|
|
99
|
+
display: 'none',
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
}))
|
|
103
|
+
|
|
104
|
+
export const SlippageClearButton: React.FC<
|
|
105
|
+
React.ComponentProps<typeof IconButton>
|
|
106
|
+
> = styled(IconButton)(({ theme }) => ({
|
|
107
|
+
padding: theme.spacing(0.5),
|
|
108
|
+
flexShrink: 0,
|
|
109
|
+
}))
|