UNPKG

@lifi/widget

Version:

LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.

115 lines 6.15 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useLayoutEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useToken } from '../../hooks/useToken.js'; import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'; import { FormKeyHelper } from '../../stores/form/types.js'; import { useFieldActions } from '../../stores/form/useFieldActions.js'; import { useFieldValues } from '../../stores/form/useFieldValues.js'; import { useInputModeStore } from '../../stores/inputMode/useInputModeStore.js'; import { DisabledUI } from '../../types/widget.js'; import { formatInputAmount, formatTokenPrice, priceToTokenAmount, } from '../../utils/format.js'; import { fitInputText } from '../../utils/input.js'; import { InputCard } from '../Card/InputCard.js'; import { AmountInputCardHeader, AmountInputCardTitle, FormContainer, FormControl, Input, maxInputFontSize, minInputFontSize, } from './AmountInput.style.js'; import { AmountInputEndAdornment } from './AmountInputEndAdornment.js'; import { AmountInputStartAdornment } from './AmountInputStartAdornment.js'; import { PriceFormHelperText } from './PriceFormHelperText.js'; const USD_DECIMALS = 2; export const AmountInput = ({ formType, ...props }) => { const { disabledUI } = useWidgetConfig(); const [chainId, tokenAddress] = useFieldValues(FormKeyHelper.getChainKey(formType), FormKeyHelper.getTokenKey(formType)); const { token } = useToken(chainId, tokenAddress); const disabled = disabledUI?.includes(DisabledUI.FromAmount); return (_jsx(AmountInputBase, { formType: formType, token: token, endAdornment: !disabled ? _jsx(AmountInputEndAdornment, { formType: formType }) : undefined, bottomAdornment: _jsx(PriceFormHelperText, { formType: formType }), disabled: disabled, ...props })); }; export const AmountInputBase = ({ formType, token, startAdornment, endAdornment, bottomAdornment, disabled, ...props }) => { const { t } = useTranslation(); const { subvariant, subvariantOptions } = useWidgetConfig(); const ref = useRef(null); const isEditingRef = useRef(false); const [formattedPriceInput, setFormattedPriceInput] = useState(''); const amountKey = FormKeyHelper.getAmountKey(formType); const [value] = useFieldValues(amountKey); const { setFieldValue } = useFieldActions(); const { inputMode } = useInputModeStore(); const currentInputMode = inputMode[formType]; let displayValue; if (isEditingRef.current) { if (currentInputMode === 'price') { displayValue = formattedPriceInput; } else { displayValue = value; } } else { if (currentInputMode === 'price') { const priceValue = formatTokenPrice(value, token?.priceUSD); displayValue = formatInputAmount(priceValue.toFixed(USD_DECIMALS), USD_DECIMALS); } else { displayValue = value; } } const handleChange = (event) => { const { value: inputValue } = event.target; isEditingRef.current = true; let formattedValue; if (currentInputMode === 'price') { const cleanInputValue = inputValue.replace('$', ''); formattedValue = formatInputAmount(cleanInputValue, USD_DECIMALS, true); const tokenValue = priceToTokenAmount(formattedValue, token?.priceUSD); setFormattedPriceInput(formattedValue); setFieldValue(amountKey, tokenValue, { isDirty: true, isTouched: true }); } else { formattedValue = formatInputAmount(inputValue, token?.decimals, true); setFieldValue(amountKey, formattedValue, { isDirty: true, isTouched: true, }); } }; const handleBlur = (event) => { const { value: inputValue } = event.target; isEditingRef.current = false; let formattedValue; if (currentInputMode === 'price') { const cleanInputValue = inputValue.replace('$', ''); formattedValue = formatInputAmount(cleanInputValue, USD_DECIMALS); const tokenValue = priceToTokenAmount(formattedValue, token?.priceUSD); const formattedAmount = formatInputAmount(tokenValue, token?.decimals); setFieldValue(amountKey, formattedAmount, { isDirty: true, isTouched: true, }); } else { formattedValue = formatInputAmount(inputValue, token?.decimals); setFieldValue(amountKey, formattedValue, { isDirty: true, isTouched: true, }); } }; // biome-ignore lint/correctness/useExhaustiveDependencies: we need run effect on value change useLayoutEffect(() => { if (ref.current) { fitInputText(maxInputFontSize, minInputFontSize, ref.current); } }, [displayValue]); const title = subvariant === 'custom' ? subvariantOptions?.custom === 'deposit' ? t('header.amount') : t('header.youPay') : t('header.send'); return (_jsxs(InputCard, { ...props, children: [_jsxs(AmountInputCardHeader, { children: [_jsx(AmountInputCardTitle, { children: title }), endAdornment] }), _jsxs(FormContainer, { children: [_jsx(AmountInputStartAdornment, { formType: formType }), _jsxs(FormControl, { fullWidth: true, children: [_jsx(Input, { inputRef: ref, size: "small", autoComplete: "off", placeholder: currentInputMode === 'price' ? '$0' : '0', startAdornment: startAdornment, inputProps: { inputMode: 'decimal', }, onChange: handleChange, onBlur: handleBlur, value: currentInputMode === 'price' ? displayValue ? `$${displayValue}` : '' : displayValue, name: amountKey, disabled: disabled, required: true }), bottomAdornment] })] })] })); }; //# sourceMappingURL=AmountInput.js.map