diff --git a/components/AssetInput/WhaleInput.tsx b/components/AssetInput/WhaleInput.tsx index 28e354ba..404c9e01 100644 --- a/components/AssetInput/WhaleInput.tsx +++ b/components/AssetInput/WhaleInput.tsx @@ -5,7 +5,8 @@ import { HStack, IconButton, Image, - Input, + NumberInput, + NumberInputField, Stack, Text, forwardRef, @@ -15,6 +16,7 @@ import { TokenBalance } from 'components/Pages/Bonding/BondingActions/Bond' import { kBorderRadius } from 'constants/visualComponentConstants' import { useTokenInfo } from 'hooks/useTokenInfo' +import { amountInputValidation } from '../../util/amountInputValidation' import AssetSelectModal from './AssetSelectModal' interface AssetInputProps { @@ -103,20 +105,30 @@ ref) => { paddingRight={3} > - { - onChange({ ...token, - amount: target.value }) - }} - /> + isValidCharacter={(char) => Boolean(char.match(/[.0-9]/u))} + value={value.amount || ''} + > + { + onChange({ + ...token, + amount: amountInputValidation(target.value), + }); + }} + /> + diff --git a/components/Pages/Trade/Swap/SwapSettings.tsx b/components/Pages/Trade/Swap/SwapSettings.tsx index 7eb731f2..dca190d5 100644 --- a/components/Pages/Trade/Swap/SwapSettings.tsx +++ b/components/Pages/Trade/Swap/SwapSettings.tsx @@ -5,9 +5,10 @@ import { Button, HStack, IconButton, - Input, InputGroup, InputRightElement, + NumberInput, + NumberInputField, Popover, PopoverArrow, PopoverBody, @@ -21,6 +22,7 @@ import { slippageAtom } from 'components/Pages/Trade/Swap/swapAtoms' import { kBorderRadius } from 'constants/visualComponentConstants' import { useRecoilState } from 'recoil' + const SwapSettings = () => { const [slippage, setSlippage] = useRecoilState(slippageAtom) const [auto, setAuto] = useBoolean(slippage === 0) @@ -36,11 +38,11 @@ const SwapSettings = () => { } const onSlippageChange = ({ target }) => { + if (auto === true) { setAuto.off() } - - if (target?.value && Number(target?.value) < 100) { + if (target?.value && Number(target?.value) <= 100 && (Number(target?.value) >= 0.01 || Number(target?.value) == 0) && String(target.value).length <= 4) { if (error) { setError(false) } @@ -96,23 +98,29 @@ const SwapSettings = () => { borderRadius="100px" border="1px solid rgba(255, 255, 255, 0.1)" borderColor={slippage === 0 ? 'white' : 'brand.500'} - paddingY={1} > - Boolean(char.match(/[.0-9]/u))} value={slippage === 0 ? '' : slippage} - onChange={onSlippageChange} - /> + > + + % @@ -122,7 +130,7 @@ const SwapSettings = () => { {error && ( - Slippage must be under 100 + Slippage must be between 0.01 - 100 % )} diff --git a/util/amountInputValidation.ts b/util/amountInputValidation.ts new file mode 100644 index 00000000..b1e02788 --- /dev/null +++ b/util/amountInputValidation.ts @@ -0,0 +1,19 @@ +/** + * General use validation function for when the user supplies a positive decimal value. + * For example it is used with token and slippage amounts. + * @param input The user supplied value + * @returns Validated string that has invalid patterns removed + */ +export const amountInputValidation = (input: string): string => { + const amount = input. + // Limiting the number of characters to be 32 + slice(0, 32). + // Disallowing leading decimal place and multiple zeros before decimal place + replace(/^(?:\.|0{2,}\.)/u, '0.'). + // Eliminating multiple leading zeros before the numbers between 1-9 + replace(/^0+(?=[0-9])/u, '') + // Ensuring multiple decimal points can't be used + return input.indexOf('.') !== amount.lastIndexOf('.') ? + amount.slice(0, amount.indexOf('.') + 1) + amount.slice(amount.indexOf('.')).replaceAll('.', '') + : amount; +}