diff --git a/e2e/tests/playground/settings.developer-controls.spec.ts b/e2e/tests/playground/settings.developer-controls.spec.ts index c8542e7e8..744ec90d7 100644 --- a/e2e/tests/playground/settings.developer-controls.spec.ts +++ b/e2e/tests/playground/settings.developer-controls.spec.ts @@ -1003,11 +1003,12 @@ test.describe('Playground settings — Developer controls (Widget events)', () = await widget.settingsButton.click() }) - await test.step('expand Route priority and click Fastest to change the setting', async () => { - // Clicking Route priority expands the accordion; then clicking the Fastest tab calls - // setValue('routePriority', 'FASTEST') which emits WidgetEvent.SettingUpdated. + await test.step('open Route priority and click Fastest to change the setting', async () => { + // Clicking Route priority navigates to the dedicated Route priority page; then clicking + // the Fastest list item calls setValue('routePriority', 'FASTEST') which emits + // WidgetEvent.SettingUpdated. await settings.routePriorityButton.click() - await widget.root.getByRole('tab', { name: /fastest/i }).click() + await widget.root.getByRole('button', { name: /fastest/i }).click() }) await test.step('settingUpdated appears in console output', async () => { diff --git a/packages/widget/src/AppDefault.tsx b/packages/widget/src/AppDefault.tsx index 2641289ca..11918cee0 100644 --- a/packages/widget/src/AppDefault.tsx +++ b/packages/widget/src/AppDefault.tsx @@ -12,6 +12,7 @@ import { NotFound } from './components/NotFound.js' import { ActivitiesPage } from './pages/ActivitiesPage/ActivitiesPage.js' import { LanguagesPage } from './pages/LanguagesPage.js' import { MainPage } from './pages/MainPage/MainPage.js' +import { RoutePriorityPage } from './pages/RoutePriorityPage.js' import { RoutesPage } from './pages/RoutesPage/RoutesPage.js' import { SelectChainPage } from './pages/SelectChainPage/SelectChainPage.js' import { SelectEnabledToolsPage } from './pages/SelectEnabledToolsPage.js' @@ -22,6 +23,7 @@ import { RecentWalletsPage } from './pages/SendToWallet/RecentWalletsPage.js' import { SendToConfiguredWalletPage } from './pages/SendToWallet/SendToConfiguredWalletPage.js' import { SendToWalletPage } from './pages/SendToWallet/SendToWalletPage.js' import { SettingsPage } from './pages/SettingsPage/SettingsPage.js' +import { SlippagePage } from './pages/SettingsPage/SlippageSettings/SlippagePage.js' import { TransactionDetailsPage } from './pages/TransactionDetailsPage/TransactionDetailsPage.js' import { TransactionPage } from './pages/TransactionPage/TransactionPage.js' import { navigationRoutes } from './utils/navigationRoutes.js' @@ -66,6 +68,18 @@ const settingsLanguagesRoute = createRoute({ component: LanguagesPage, }) +const settingsRoutePriorityRoute = createRoute({ + getParentRoute: () => settingsLayoutRoute, + path: navigationRoutes.routePriority, + component: RoutePriorityPage, +}) + +const settingsSlippageRoute = createRoute({ + getParentRoute: () => settingsLayoutRoute, + path: navigationRoutes.slippage, + component: SlippagePage, +}) + const fromTokenLayoutRoute = createRoute({ getParentRoute: () => rootRoute, path: navigationRoutes.fromToken, @@ -214,6 +228,8 @@ const routeTree = rootRoute.addChildren([ settingsLayoutRoute.addChildren([ settingsIndexRoute, settingsLanguagesRoute, + settingsRoutePriorityRoute, + settingsSlippageRoute, settingsBridgesRoute, settingsExchangesRoute, ]), diff --git a/packages/widget/src/components/QuickSettings/QuickSettings.style.tsx b/packages/widget/src/components/QuickSettings/QuickSettings.style.tsx new file mode 100644 index 000000000..70c8d6d15 --- /dev/null +++ b/packages/widget/src/components/QuickSettings/QuickSettings.style.tsx @@ -0,0 +1,41 @@ +import { Box, ButtonBase, styled, Typography } from '@mui/material' +import type React from 'react' + +export const QuickSettingsContainer: React.FC< + React.ComponentProps +> = styled(Box)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1), +})) + +export const QuickSettingButton: React.FC< + React.ComponentProps +> = styled(ButtonBase)(({ theme }) => ({ + display: 'flex', + width: '100%', + justifyContent: 'space-between', + alignItems: 'center', + gap: theme.spacing(1), + padding: theme.spacing(1.5), + borderRadius: theme.vars.shape.borderRadius, +})) + +export const QuickSettingTitle: React.FC< + React.ComponentProps +> = styled(Typography)(({ theme }) => ({ + fontSize: 14, + lineHeight: 1, + fontWeight: 700, + color: theme.vars.palette.text.primary, +})) + +export const QuickSettingValue: React.FC< + React.ComponentProps +> = styled(Typography)(({ theme }) => ({ + fontSize: 14, + lineHeight: 1, + fontWeight: 500, + color: theme.vars.palette.text.secondary, + whiteSpace: 'nowrap', +})) diff --git a/packages/widget/src/components/QuickSettings/QuickSettings.tsx b/packages/widget/src/components/QuickSettings/QuickSettings.tsx new file mode 100644 index 000000000..06aa643cb --- /dev/null +++ b/packages/widget/src/components/QuickSettings/QuickSettings.tsx @@ -0,0 +1,69 @@ +import type { BoxProps } from '@mui/material' +import { useNavigate } from '@tanstack/react-router' +import type { JSX } from 'react' +import { useTranslation } from 'react-i18next' +import { useSplitMode } from '../../stores/navigationTabs/useNavigationTabsStore.js' +import { useSettingsStore } from '../../stores/settings/SettingsStore.js' +import { useSettings } from '../../stores/settings/useSettings.js' +import { navigationRoutes } from '../../utils/navigationRoutes.js' +import { Card } from '../Card/Card.js' +import { + QuickSettingButton, + QuickSettingsContainer, + QuickSettingTitle, + QuickSettingValue, +} from './QuickSettings.style.js' +import { + bridgeQuickSettings, + type QuickSettingKey, + quickSettingsConfig, + swapQuickSettings, +} from './quickSettingsRows.js' + +export const QuickSettings: React.FC = (props): JSX.Element => { + const { t } = useTranslation() + const navigate = useNavigate() + const splitMode = useSplitMode() + const { slippage, routePriority } = useSettings(['slippage', 'routePriority']) + const [enabledBridges, totalBridges, enabledExchanges, totalExchanges] = + useSettingsStore((state) => [ + Object.values(state._enabledBridges).filter(Boolean).length, + Object.values(state._enabledBridges).length, + Object.values(state._enabledExchanges).filter(Boolean).length, + Object.values(state._enabledExchanges).length, + ]) + + const rows = splitMode === 'bridge' ? bridgeQuickSettings : swapQuickSettings + + const valueByKey: Record = { + routePriority: t( + `settings.routePriorityOptions.${(routePriority ?? 'CHEAPEST').toLowerCase()}.title` as any + ), + exchanges: `${enabledExchanges}/${totalExchanges}`, + bridges: `${enabledBridges}/${totalBridges}`, + slippage: slippage ? `${slippage}%` : t('button.auto'), + } + + const handleClick = (key: QuickSettingKey) => { + const { route } = quickSettingsConfig[key] + navigate({ + to: `/${navigationRoutes.settings}/${navigationRoutes[route]}`, + }) + } + + return ( + + {rows.map((key) => { + const { labelKey } = quickSettingsConfig[key] + return ( + + handleClick(key)} disableRipple> + {t(labelKey as any)} + {valueByKey[key]} + + + ) + })} + + ) +} diff --git a/packages/widget/src/components/QuickSettings/quickSettingsRows.ts b/packages/widget/src/components/QuickSettings/quickSettingsRows.ts new file mode 100644 index 000000000..fe8fad96a --- /dev/null +++ b/packages/widget/src/components/QuickSettings/quickSettingsRows.ts @@ -0,0 +1,50 @@ +import type { NavigationTabKey } from '../../types/widget.js' + +export type QuickSettingKey = + | 'routePriority' + | 'exchanges' + | 'bridges' + | 'slippage' + +/** Navigation tabs that surface quick settings on the main page. */ +export const advancedNavigationTabKeys: NavigationTabKey[] = [ + 'swap-advanced', + 'bridge-advanced', +] + +interface QuickSettingConfig { + /** i18n key for the row label. */ + labelKey: string + /** Dedicated settings sub-route to navigate to. */ + route: 'bridges' | 'exchanges' | 'routePriority' | 'slippage' +} + +export const quickSettingsConfig: Record = + { + routePriority: { + labelKey: 'settings.routePriority', + route: 'routePriority', + }, + exchanges: { + labelKey: 'settings.enabledExchanges', + route: 'exchanges', + }, + bridges: { + labelKey: 'settings.enabledBridges', + route: 'bridges', + }, + slippage: { + labelKey: 'settings.slippage', + route: 'slippage', + }, + } + +// Swap is same-chain, so bridges are not relevant. +export const swapQuickSettings: QuickSettingKey[] = ['exchanges', 'slippage'] + +export const bridgeQuickSettings: QuickSettingKey[] = [ + 'routePriority', + 'exchanges', + 'bridges', + 'slippage', +] diff --git a/packages/widget/src/i18n/en.json b/packages/widget/src/i18n/en.json index 4effbebb2..ebfb84204 100644 --- a/packages/widget/src/i18n/en.json +++ b/packages/widget/src/i18n/en.json @@ -333,7 +333,22 @@ "title": "Gas price" }, "routePriority": "Route priority", + "routePriorityOptions": { + "recommended": { + "title": "Best Return", + "description": "Maximum tokens after all fees" + }, + "fastest": { + "title": "Fastest", + "description": "Shortest execution time" + }, + "cheapest": { + "title": "Cheapest", + "description": "Lowest network cost" + } + }, "slippage": "Max. slippage", + "slippageAutoDescription": "Optimised per route", "custom": "Custom", "resetSettings": "You're using custom settings that can affect the number or sorting of available routes.", "hideSmallBalances": "Hide small balances" diff --git a/packages/widget/src/pages/MainPage/MainPage.tsx b/packages/widget/src/pages/MainPage/MainPage.tsx index bcf3f896f..77f16f4f4 100644 --- a/packages/widget/src/pages/MainPage/MainPage.tsx +++ b/packages/widget/src/pages/MainPage/MainPage.tsx @@ -5,6 +5,8 @@ import { ContractComponent } from '../../components/ContractComponent/ContractCo import { GasRefuelMessage } from '../../components/Messages/GasRefuelMessage.js' import { PageContainer } from '../../components/PageContainer.js' import { PoweredBy } from '../../components/PoweredBy/PoweredBy.js' +import { QuickSettings } from '../../components/QuickSettings/QuickSettings.js' +import { advancedNavigationTabKeys } from '../../components/QuickSettings/quickSettingsRows.js' import { Routes } from '../../components/Routes/Routes.js' import { SelectChainAndToken } from '../../components/SelectChainAndToken.js' import { SendToWalletButton } from '../../components/SendToWallet/SendToWalletButton.js' @@ -12,6 +14,7 @@ import { SendToWalletExpandButton } from '../../components/SendToWallet/SendToWa import { useHeader } from '../../hooks/useHeader.js' import { useWideVariant } from '../../hooks/useWideVariant.js' import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js' +import { useNavigationTabsStore } from '../../stores/navigationTabs/useNavigationTabsStore.js' import { MainWarningMessages } from './MainWarningMessages.js' import { ReviewButton } from './ReviewButton.js' @@ -20,6 +23,10 @@ export const MainPage: React.FC = () => { const wideVariant = useWideVariant() const { mode, modeOptions, contractComponent, hiddenUI } = useWidgetConfig() const custom = mode === 'custom' + const activeTab = useNavigationTabsStore((state) => state.activeTab) + // Surface quick settings on the main page for advanced navigation tabs. + const advancedMode = + !!activeTab && advancedNavigationTabKeys.includes(activeTab) const showPoweredBy = !hiddenUI?.poweredBy const showGasRefuelMessage = !hiddenUI?.gasRefuelMessage @@ -51,6 +58,7 @@ export const MainPage: React.FC = () => { {!custom || modeOptions?.custom?.type === 'deposit' ? ( ) : null} + {advancedMode ? : null} {!wideVariant ? : null} {showGasRefuelMessage ? : null} diff --git a/packages/widget/src/pages/RoutePriorityPage.tsx b/packages/widget/src/pages/RoutePriorityPage.tsx new file mode 100644 index 000000000..5bdb3800e --- /dev/null +++ b/packages/widget/src/pages/RoutePriorityPage.tsx @@ -0,0 +1,48 @@ +import type { Order } from '@lifi/sdk' +import Check from '@mui/icons-material/Check' +import { List } from '@mui/material' +import { useTranslation } from 'react-i18next' +import { ListItemText } from '../components/ListItemText.js' +import { PageContainer } from '../components/PageContainer.js' +import { SettingsListItemButton } from '../components/SettingsListItemButton.js' +import { useHeader } from '../hooks/useHeader.js' +import { useSettings } from '../stores/settings/useSettings.js' +import { useSettingsActions } from '../stores/settings/useSettingsActions.js' + +const Priorities: Order[] = ['RECOMMENDED', 'FASTEST', 'CHEAPEST'] + +export const RoutePriorityPage: React.FC = () => { + const { t } = useTranslation() + const { setValue } = useSettingsActions() + const { routePriority } = useSettings(['routePriority']) + + useHeader(t('settings.routePriority')) + + return ( + + + {Priorities.map((priority) => { + const key = priority.toLowerCase() + return ( + setValue('routePriority', priority)} + > + + {routePriority === priority && } + + ) + })} + + + ) +} diff --git a/packages/widget/src/pages/SettingsPage/RoutePrioritySettings.tsx b/packages/widget/src/pages/SettingsPage/RoutePrioritySettings.tsx index c372170de..3a23d713e 100644 --- a/packages/widget/src/pages/SettingsPage/RoutePrioritySettings.tsx +++ b/packages/widget/src/pages/SettingsPage/RoutePrioritySettings.tsx @@ -1,57 +1,34 @@ -import type { Order } from '@lifi/sdk' import Route from '@mui/icons-material/Route' +import { useNavigate } from '@tanstack/react-router' import { useTranslation } from 'react-i18next' -import { CardTabs, Tab } from '../../components/Tabs/Tabs.style.js' +import { CardButton } from '../../components/Card/CardButton.js' import { useSettingMonitor } from '../../hooks/useSettingMonitor.js' import { useSettings } from '../../stores/settings/useSettings.js' -import { useSettingsActions } from '../../stores/settings/useSettingsActions.js' +import { navigationRoutes } from '../../utils/navigationRoutes.js' import { BadgedValue } from './SettingsCard/BadgedValue.js' -import { SettingCardExpandable } from './SettingsCard/SettingCardExpandable.js' - -const Priorities: Order[] = ['CHEAPEST', 'FASTEST'] export const RoutePrioritySettings: React.FC = () => { const { t } = useTranslation() - const { setValue } = useSettingsActions() + const navigate = useNavigate() const { isRoutePriorityChanged } = useSettingMonitor() const { routePriority } = useSettings(['routePriority']) - const currentRoutePriority = routePriority ?? '' + const currentRoutePriority = (routePriority ?? 'CHEAPEST').toLowerCase() - const handleRoutePriorityChange = ( - _: React.SyntheticEvent, - routePriority: Order - ) => { - setValue('routePriority', routePriority) + const handleClick = () => { + navigate({ to: navigationRoutes.routePriority }) } return ( - - {t(`main.tags.${currentRoutePriority.toLowerCase()}` as any)} - - } + } title={t('settings.routePriority')} > - - {Priorities.map((priority) => { - return ( - - ) - })} - - + + {t( + `settings.routePriorityOptions.${currentRoutePriority}.title` as any + )} + + ) } diff --git a/packages/widget/src/pages/SettingsPage/SlippageSettings/SlippagePage.tsx b/packages/widget/src/pages/SettingsPage/SlippageSettings/SlippagePage.tsx new file mode 100644 index 000000000..266660b1b --- /dev/null +++ b/packages/widget/src/pages/SettingsPage/SlippageSettings/SlippagePage.tsx @@ -0,0 +1,160 @@ +import Check from '@mui/icons-material/Check' +import WarningRounded from '@mui/icons-material/WarningRounded' +import { Box, List, Typography } from '@mui/material' +import type { ChangeEventHandler, FocusEventHandler } from 'react' +import { useRef, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { ListItemText } from '../../../components/ListItemText.js' +import { PageContainer } from '../../../components/PageContainer.js' +import { SettingsListItemButton } from '../../../components/SettingsListItemButton.js' +import { useHeader } from '../../../hooks/useHeader.js' +import { useSettingMonitor } from '../../../hooks/useSettingMonitor.js' +import { defaultSlippage } from '../../../stores/settings/createSettingsStore.js' +import { useSettings } from '../../../stores/settings/useSettings.js' +import { useSettingsActions } from '../../../stores/settings/useSettingsActions.js' +import { formatInputAmount, formatSlippage } from '../../../utils/format.js' +import { + SettingsCustomInput, + SettingsFieldSet, + SlippageLimitsWarningContainer, +} from './SlippageSettings.style.js' + +const slippagePresets = ['0.5', '1', '3'] +const maxFractionDigits = 5 + +export const SlippagePage: React.FC = () => { + const { t } = useTranslation() + const { + isSlippageNotRecommended, + isSlippageUnderRecommendedLimits, + isSlippageOutsideRecommendedLimits, + } = useSettingMonitor() + const { slippage } = useSettings(['slippage']) + const { setValue } = useSettingsActions() + const defaultValue = useRef(slippage) + + useHeader(t('settings.slippage')) + + const isAuto = !slippage || slippage === defaultSlippage + const isPreset = !!slippage && slippagePresets.includes(slippage) + const isCustom = !isAuto && !isPreset + + const [customMode, setCustomMode] = useState(isCustom) + const [inputValue, setInputValue] = useState(isCustom ? slippage : '') + + const handleAuto = () => { + setCustomMode(false) + setValue('slippage', defaultSlippage) + } + + const handlePreset = (preset: string) => { + setCustomMode(false) + setValue('slippage', preset) + } + + const handleCustom = () => { + setCustomMode(true) + if (inputValue) { + setValue('slippage', inputValue) + } + } + + const formatAndSetSlippage = (value: string, returnInitial = false) => { + const formattedSlippage = formatSlippage( + value, + defaultValue.current, + returnInitial + ) + const formattedValue = + Number(formattedSlippage) === 0 && !returnInitial + ? '0' + : formatInputAmount(formattedSlippage, maxFractionDigits, returnInitial) + const maxLength = + Number(formattedValue) < 10 + ? maxFractionDigits + 2 + : maxFractionDigits + 3 + const slicedValue = formattedValue.slice(0, maxLength) + setInputValue(slicedValue) + setValue('slippage', slicedValue.length ? slicedValue : defaultSlippage) + } + + const handleInputUpdate: ChangeEventHandler = (event) => { + formatAndSetSlippage(event.target.value, true) + } + + const handleInputFocus: FocusEventHandler = (event) => { + formatAndSetSlippage(event.target.value) + } + + const handleInputBlur: FocusEventHandler = (event) => { + formatAndSetSlippage(event.target.value) + } + + const slippageWarningText = isSlippageOutsideRecommendedLimits + ? t('warning.message.slippageOutsideRecommendedLimits') + : isSlippageUnderRecommendedLimits + ? t('warning.message.slippageUnderRecommendedLimits') + : '' + + return ( + + + + + {isAuto && } + + {slippagePresets.map((preset) => ( + handlePreset(preset)} + > + + {slippage === preset && } + + ))} + + + {isCustom && } + + + {customMode && ( + + + + + + )} + {isSlippageNotRecommended && ( + + + + {slippageWarningText} + + + )} + + ) +} diff --git a/packages/widget/src/pages/SettingsPage/SlippageSettings/SlippageSettings.style.tsx b/packages/widget/src/pages/SettingsPage/SlippageSettings/SlippageSettings.style.tsx index df20b480f..a72cf3a55 100644 --- a/packages/widget/src/pages/SettingsPage/SlippageSettings/SlippageSettings.style.tsx +++ b/packages/widget/src/pages/SettingsPage/SlippageSettings/SlippageSettings.style.tsx @@ -1,11 +1,5 @@ import type { Theme } from '@mui/material' -import { - Box, - ButtonBase, - InputBase, - inputBaseClasses, - styled, -} from '@mui/material' +import { Box, InputBase, inputBaseClasses, styled } from '@mui/material' import type React from 'react' export const SettingsFieldSet: React.FC< @@ -36,30 +30,6 @@ interface SettingsControlProps { selected?: boolean } -export const SettingsDefaultButton: React.FC< - React.ComponentProps & SettingsControlProps -> = styled(ButtonBase)(({ theme, selected }) => { - const settingsControlSelectedStyles = settingsControlSelected(theme) - const selectedStyle = selected - ? { - '&:not(:focus)': { - ...settingsControlSelectedStyles, - }, - } - : {} - - return { - height: '100%', - width: '100%', - fontSize: '1rem', - fontWeight: 700, - '&:focus': { - ...settingsControlSelectedStyles, - }, - ...selectedStyle, - } -}) - export const SettingsCustomInput: React.FC< React.ComponentProps & SettingsControlProps > = styled(InputBase)(({ theme, selected }) => { diff --git a/packages/widget/src/pages/SettingsPage/SlippageSettings/SlippageSettings.tsx b/packages/widget/src/pages/SettingsPage/SlippageSettings/SlippageSettings.tsx index c865fcf73..dcec82c82 100644 --- a/packages/widget/src/pages/SettingsPage/SlippageSettings/SlippageSettings.tsx +++ b/packages/widget/src/pages/SettingsPage/SlippageSettings/SlippageSettings.tsx @@ -1,82 +1,17 @@ import Percent from '@mui/icons-material/Percent' -import WarningRounded from '@mui/icons-material/WarningRounded' -import { Box, Typography } from '@mui/material' -import type { ChangeEventHandler, FocusEventHandler } from 'react' -import { useRef, useState } from 'react' +import { useNavigate } from '@tanstack/react-router' import { useTranslation } from 'react-i18next' +import { CardButton } from '../../../components/Card/CardButton.js' import { useSettingMonitor } from '../../../hooks/useSettingMonitor.js' -import { defaultSlippage } from '../../../stores/settings/createSettingsStore.js' import { useSettings } from '../../../stores/settings/useSettings.js' -import { useSettingsActions } from '../../../stores/settings/useSettingsActions.js' -import { formatInputAmount, formatSlippage } from '../../../utils/format.js' +import { navigationRoutes } from '../../../utils/navigationRoutes.js' import { BadgedValue } from '../SettingsCard/BadgedValue.js' -import { SettingCardExpandable } from '../SettingsCard/SettingCardExpandable.js' -import { - SettingsCustomInput, - SettingsDefaultButton, - SettingsFieldSet, - SlippageLimitsWarningContainer, -} from './SlippageSettings.style.js' - -const defaultSlippageInputValue = '0.5' -const maxFractionDigits = 5 export const SlippageSettings: React.FC = () => { const { t } = useTranslation() - const { - isSlippageNotRecommended, - isSlippageUnderRecommendedLimits, - isSlippageOutsideRecommendedLimits, - isSlippageChanged, - } = useSettingMonitor() + const navigate = useNavigate() + const { isSlippageNotRecommended, isSlippageChanged } = useSettingMonitor() const { slippage } = useSettings(['slippage']) - const { setValue } = useSettingsActions() - const defaultValue = useRef(slippage) - const [focused, setFocused] = useState<'input' | 'button'>() - - const customInputValue = - !slippage || slippage === defaultSlippage - ? defaultSlippageInputValue - : slippage - - const [inputValue, setInputValue] = useState(customInputValue) - - const handleDefaultClick = () => { - setValue('slippage', defaultSlippage) - } - - const formatAndSetSlippage = (value: string, returnInitial = false) => { - const formattedSlippage = formatSlippage( - value, - defaultValue.current, - returnInitial - ) - const formattedValue = - Number(formattedSlippage) === 0 && !returnInitial - ? '0' - : formatInputAmount(formattedSlippage, maxFractionDigits, returnInitial) - const maxLength = - Number(formattedValue) < 10 - ? maxFractionDigits + 2 - : maxFractionDigits + 3 - const slicedValue = formattedValue.slice(0, maxLength) - setInputValue(slicedValue) - setValue('slippage', slicedValue.length ? slicedValue : defaultSlippage) - } - - const handleInputUpdate: ChangeEventHandler = (event) => { - formatAndSetSlippage(event.target.value, true) - } - - const handleInputFocus: FocusEventHandler = (event) => { - setFocused('input') - formatAndSetSlippage(event.target.value) - } - - const handleInputBlur: FocusEventHandler = (event) => { - setFocused(undefined) - formatAndSetSlippage(event.target.value) - } const badgeColor = isSlippageNotRecommended ? 'warning' @@ -84,68 +19,19 @@ export const SlippageSettings: React.FC = () => { ? 'info' : undefined - const slippageWarningText = isSlippageOutsideRecommendedLimits - ? t('warning.message.slippageOutsideRecommendedLimits') - : isSlippageUnderRecommendedLimits - ? t('warning.message.slippageUnderRecommendedLimits') - : '' + const handleClick = () => { + navigate({ to: navigationRoutes.slippage }) + } return ( - - {slippage ? `${slippage}%` : t('button.auto')} - - } + } title={t('settings.slippage')} > - - - { - setFocused('button') - }} - onBlur={() => { - setFocused(undefined) - }} - onClick={handleDefaultClick} - disableRipple - > - {t('button.auto')} - - - - {isSlippageNotRecommended && ( - - - - {slippageWarningText} - - - )} - - + + {slippage ? `${slippage}%` : t('button.auto')} + + ) } diff --git a/packages/widget/src/utils/navigationRoutes.ts b/packages/widget/src/utils/navigationRoutes.ts index f8be09230..5c45fe533 100644 --- a/packages/widget/src/utils/navigationRoutes.ts +++ b/packages/widget/src/utils/navigationRoutes.ts @@ -8,6 +8,8 @@ export const navigationRoutes = { languages: 'languages', routes: 'routes', settings: 'settings', + routePriority: 'route-priority', + slippage: 'slippage', toChain: 'to-chain', toToken: 'to-token', toTokenNative: 'to-token-native', @@ -30,6 +32,8 @@ export const stickyHeaderRoutes: string[] = [ navigationRoutes.home, navigationRoutes.routes, navigationRoutes.settings, + navigationRoutes.routePriority, + navigationRoutes.slippage, navigationRoutes.toChain, navigationRoutes.toTokenNative, navigationRoutes.transactionDetails, @@ -50,6 +54,8 @@ export const backButtonRoutes: string[] = [ navigationRoutes.fromToken, navigationRoutes.routes, navigationRoutes.settings, + navigationRoutes.routePriority, + navigationRoutes.slippage, navigationRoutes.toChain, navigationRoutes.toToken, navigationRoutes.toTokenNative,