'use client'; import { useCallback, useEffect, useMemo } from 'react'; import { useAnalytics } from '@/core/analytics/hooks/useAnalytics'; import { SwapEvent } from '@/core/analytics/types'; import { TextInput } from '@/internal/components/TextInput'; import { useValue } from '@/internal/hooks/useValue'; import { getRoundedAmount } from '@/internal/utils/getRoundedAmount'; import { isValidAmount } from '@/internal/utils/isValidAmount'; import { cn, pressable, text } from '@/styles/theme'; import type { Token } from '@/token'; import { TokenChip, TokenSelectDropdown } from '@/token'; import type { SwapAmountInputProps } from '../types'; import { formatToDecimalString, formatUSD } from '@/internal/utils/formatter'; import { useSwapContext } from './SwapProvider'; export function SwapAmountInput({ className, delayMs = 1000, label, token, type, swappableTokens, render, }: SwapAmountInputProps) { const { address, to, from, handleAmountChange } = useSwapContext(); const { sendAnalytics } = useAnalytics(); const source = useValue(type === 'from' ? from : to); const destination = useValue(type === 'from' ? to : from); const { setToken, setAmount, balance, amount, amountUSD } = source; useEffect(() => { if (token) { setToken?.(token); } }, [token, setToken]); const handleMaxButtonClick = useCallback(() => { if (!balance) { return; } setAmount(balance); handleAmountChange(type, balance); }, [balance, setAmount, handleAmountChange, type]); const handleChange = useCallback( (amount: string) => { handleAmountChange(type, amount); }, [handleAmountChange, type], ); const handleAnalyticsTokenSelected = useCallback( (token: Token) => { sendAnalytics(SwapEvent.TokenSelected, { token: token.symbol, }); }, [sendAnalytics], ); const handleSetToken = useCallback( (token: Token) => { setToken?.(token); handleAmountChange(type, amount, token); handleAnalyticsTokenSelected(token); }, [amount, setToken, handleAmountChange, handleAnalyticsTokenSelected, type], ); // We are mocking the token selectors so I'm not able // to test this since the components aren't actually rendering const sourceTokenOptions = useMemo(() => { return ( swappableTokens?.filter( ({ symbol }: Token) => symbol !== destination.token?.symbol, ) ?? [] ); }, [swappableTokens, destination.token]); const hasInsufficientBalance = type === 'from' && Number(balance) < Number(amount); if (render) { return render({ token: source, hasInsufficientBalance, setAmountToMax: handleMaxButtonClick, onSetToken: handleSetToken, }); } return (
{label}
{sourceTokenOptions.length > 0 ? ( ) : ( source.token && ( ) )}
~{formatUSD(amountUSD)}
{balance && {`Balance: ${getRoundedAmount(balance, 8)}`}} {type === 'from' && address && ( )}
); }