'use client'; import { useAnalytics } from '@/core/analytics/hooks/useAnalytics'; import { SwapEvent } from '@/core/analytics/types'; import { ComponentProps, useCallback, useId, useState } from 'react'; import { cn, pressable, text } from '@/styles/theme'; import type { SwapSettingsSlippageInputProps } from '../types'; import { useSwapContext } from './SwapProvider'; import { TextInput } from '@/internal/components/TextInput'; import { SLIPPAGE_SETTINGS, SlippageSettingsType } from '../constants'; export function SwapSettingsSlippageInput({ className, render, }: SwapSettingsSlippageInputProps) { const { sendAnalytics } = useAnalytics(); const { config: { maxSlippage: defaultMaxSlippage }, updateLifecycleStatus, lifecycleStatus, } = useSwapContext(); // Set initial slippage values to match previous selection or default, // ensuring consistency when dropdown is reopened const [slippageSetting, setSlippageSetting] = useState( lifecycleStatus.statusData.maxSlippage === defaultMaxSlippage ? SLIPPAGE_SETTINGS.AUTO : SLIPPAGE_SETTINGS.CUSTOM, ); const handleAnalyticsSlippageChange = useCallback( (previousSlippage: number, newSlippage: number) => { sendAnalytics(SwapEvent.SlippageChanged, { previousSlippage, slippage: newSlippage, }); }, [sendAnalytics], ); const updateSlippage = useCallback( (newSlippage: number) => { const currentSlippage = lifecycleStatus.statusData.maxSlippage; if (newSlippage !== currentSlippage) { handleAnalyticsSlippageChange(currentSlippage, newSlippage); if (slippageSetting === SLIPPAGE_SETTINGS.AUTO) { setSlippageSetting(SLIPPAGE_SETTINGS.CUSTOM); } updateLifecycleStatus({ statusName: 'slippageChange', statusData: { maxSlippage: newSlippage, }, }); } }, [ lifecycleStatus.statusData.maxSlippage, updateLifecycleStatus, handleAnalyticsSlippageChange, slippageSetting, ], ); // Handles user input for custom slippage. // Parses the input and updates slippage state. const handleSlippageChange: ComponentProps['onChange'] = useCallback( (newSlippage: string) => { const parsedSlippage = Number.parseFloat(newSlippage); const isValidNumber = !Number.isNaN(parsedSlippage); // Update slippage to parsed value if valid, otherwise set to 0 updateSlippage(isValidNumber ? parsedSlippage : 0); }, [updateSlippage], ); // Toggles between auto and custom slippage settings // Resets to default slippage when auto is selected const handleSlippageSettingChange = useCallback( (setting: string) => { setSlippageSetting(setting as SlippageSettingsType); if (setting === SLIPPAGE_SETTINGS.AUTO) { updateSlippage(defaultMaxSlippage); } }, [defaultMaxSlippage, updateSlippage], ); const slippageInputId = useId(); if (render) { return render({ slippageSetting, setSlippageSetting: handleSlippageSettingChange, setSlippageValue: updateSlippage, }); } return (
Slippage Setting {Object.values(SLIPPAGE_SETTINGS).map((setting) => ( ))}
%
); }