/** * Copyright (c) TonTech. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ import { useCallback, useMemo, useState } from 'react'; import type { FC, ComponentProps } from 'react'; import clsx from 'clsx'; import { useI18n } from '../../../settings/hooks/use-i18n'; import { useSelectedWallet } from '../../../wallets'; import { SwapConfirmModal } from '../swap-confirm-modal'; import { SwapField } from '../swap-field'; import { SwapFlipButton } from '../swap-flip-button'; import { SwapInfo } from '../swap-info'; import { SwapSettingsModal } from '../swap-settings-modal'; import { SwapTokenSelectModal } from '../swap-token-select-modal'; import { LowBalanceModal } from '../../../../components/shared/low-balance-modal'; import styles from './swap-widget-ui.module.css'; import type { SwapContextType } from '../swap-widget-provider'; import { ButtonWithConnect } from '../../../../components/shared/button-with-connect'; import { SettingsButton } from '../../../../components/shared/settings-button'; export type SwapWidgetRenderProps = SwapContextType & ComponentProps<'div'>; export const SwapWidgetUI: FC = ({ fromToken, toToken, tokens, fromAmount, toAmount, fiatSymbol, fromBalance, toBalance, isFromBalanceLoading, isToBalanceLoading, canSubmit, quote, isQuoteLoading, error, slippage, swapProvider, swapProviders, setSwapProviderId, onFlip, onMaxClick, setFromAmount, setFromToken, setToToken, setSlippage, sendSwapTransaction, isSendingTransaction, isLowBalanceWarningOpen, lowBalanceMode, lowBalanceRequiredTon, onLowBalanceChange, onLowBalanceCancel, className, ...props }) => { const [wallet] = useSelectedWallet(); const isWalletConnected = wallet !== null; const { t } = useI18n(); const [activeField, setActiveField] = useState<'from' | 'to' | null>(null); const [isSettingsOpen, setIsSettingsOpen] = useState(false); const [isConfirmOpen, setIsConfirmOpen] = useState(false); const [isFlipped, setIsFlipped] = useState(false); const handleFlip = useCallback(() => { setIsFlipped((prev) => !prev); onFlip(); }, [onFlip]); // Close the modal immediately; the build/send result (including errors) is surfaced // back in the widget's main button via the `error` from the provider. const handleConfirm = useCallback(() => { setIsConfirmOpen(false); sendSwapTransaction().catch(() => { // Error is captured by the mutation and shown through the validator's `error` output. }); }, [sendSwapTransaction]); const buttonText = useMemo(() => { if (isSendingTransaction || isQuoteLoading) return t('swap.loading'); if (!fromToken || !toToken) return t('swap.selectToken'); if (error) return t(error); if (canSubmit) return t('swap.continue'); return t('swap.enterAmount'); }, [isSendingTransaction, isQuoteLoading, error, fromToken, toToken, canSubmit, t]); return (
setActiveField('from')} isWalletConnected={isWalletConnected} fiatSymbol={fiatSymbol} />
setActiveField('to')} loading={isQuoteLoading} isWalletConnected={isWalletConnected} fiatSymbol={fiatSymbol} />
setActiveField(null)} tokens={tokens} onSelect={(token) => { if (activeField === 'from') setFromToken(token); else setToToken(token); }} /> setIsSettingsOpen(false)} slippage={slippage} onSlippageChange={setSlippage} provider={swapProvider} providers={swapProviders} onProviderChange={setSwapProviderId} /> setIsConfirmOpen(false)} onConfirm={handleConfirm} fromToken={fromToken} toToken={toToken} fromAmount={fromAmount} toAmount={toAmount} fiatSymbol={fiatSymbol} quote={quote} swapProvider={swapProvider} slippage={slippage} isQuoteLoading={isQuoteLoading} />
setIsConfirmOpen(true)} > {buttonText} setIsSettingsOpen(true)} />
); };