* feat: added transaction loader screen to modals * tidy: refactor * 🐛 fix: borrow not updating vault values (#436) * ⚡ Merge FundAccount and AccountFund (#431) * ⚡ Merge FundAccount and AccountFund * fix build * 🐛 fundAccount not showing, small typos/text corrections * MP-3376: overpay on repay (#438) * MP-3376: overpay on repay * fix: remove Buffer and fix NaN on useSpring * feat: added transaction loader screen to modals * fix: updated AccountFundContent * fix: fixed the animated-loader issues * 🐛 UNSAFE_COMPONENT error (#439) * 🐛 UNSAFE_COMPONENT error * 🐛 fix unit tests for react-helmet-async * Small text fixes (#440) * 🐛 text fix on fund for new account * 🐛 make toggle account-wide lending on new-account * Styling alert dialog (#441) * 🐛 text fix on fund for new account * 🐛 make toggle account-wide lending on new-account * 💅🏼Update styling of alertDialogs * Fixes bob (#443) * 🐛 Trading chart title * 🐛 Trading chart title * 🐛 fix incorrect vault deposit amounts * 🐛 fix incorrect vault borrow calc * 🧽 run format * 🧽 fix comments * 🧽 update code owners * Build(deps): bump bignumber.js from 9.1.1 to 9.1.2 (#444) Bumps [bignumber.js](https://github.com/MikeMcl/bignumber.js) from 9.1.1 to 9.1.2. - [Release notes](https://github.com/MikeMcl/bignumber.js/releases) - [Changelog](https://github.com/MikeMcl/bignumber.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/MikeMcl/bignumber.js/compare/v9.1.1...v9.1.2) --- updated-dependencies: - dependency-name: bignumber.js dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Build(deps-dev): bump @types/react from 18.2.19 to 18.2.21 (#448) Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 18.2.19 to 18.2.21. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react) --- updated-dependencies: - dependency-name: "@types/react" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Build(deps): bump next from 13.4.9 to 13.4.19 (#446) Bumps [next](https://github.com/vercel/next.js) from 13.4.9 to 13.4.19. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v13.4.9...v13.4.19) --- updated-dependencies: - dependency-name: next dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Build(deps-dev): bump @types/node from 20.4.8 to 20.6.0 (#447) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.4.8 to 20.6.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Linkie Link <linkielink.dev@gmail.com> * feat: refactored the toast responses (#442) * feat: refactored the toast responses * fix: fixed the map return * feat: added a recent transaction center * tidy: removed logs * fix: fixed autolend * feat: added global lending on first account funding * fix: added endOfLine setting * feat: added eslint warnings for lineEnds * fix: made the vault message generic * feat: added transaction loader screen to modals * 🐛 fix: borrow not updating vault values (#436) * ⚡ Merge FundAccount and AccountFund (#431) * ⚡ Merge FundAccount and AccountFund * fix build * 🐛 fundAccount not showing, small typos/text corrections * feat: added transaction loader screen to modals * fix: updated AccountFundContent * fix: fixed the animated-loader issues * tidy: refactor * fix: set pendingTransaction inside the broadcast slice * fix: fixed the pipeline * fix: setting showTxLoader * fix: fixed the pipeline --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Bob van der Helm <34470358+bobthebuidlr@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
166 lines
4.9 KiB
TypeScript
166 lines
4.9 KiB
TypeScript
import BigNumber from 'bignumber.js'
|
|
import classNames from 'classnames'
|
|
import React, { useEffect, useState } from 'react'
|
|
|
|
import { BN_ZERO } from 'constants/math'
|
|
import { demagnify, formatValue, magnify } from 'utils/formatters'
|
|
import { BN } from 'utils/helpers'
|
|
|
|
interface Props {
|
|
asset: Asset | PseudoAsset
|
|
amount: BigNumber
|
|
min?: BigNumber
|
|
max?: BigNumber
|
|
className: string
|
|
maxDecimals: number
|
|
maxLength?: number
|
|
allowNegative?: boolean
|
|
style?: {}
|
|
disabled?: boolean
|
|
placeholder?: string
|
|
onChange: (amount: BigNumber) => void
|
|
onBlur?: () => void
|
|
onFocus?: () => void
|
|
onRef?: (ref: React.RefObject<HTMLInputElement>) => void
|
|
}
|
|
|
|
export default function NumberInput(props: Props) {
|
|
const inputRef = React.useRef<HTMLInputElement>(null)
|
|
const cursorRef = React.useRef(0)
|
|
|
|
const [formattedAmount, setFormattedAmount] = useState(
|
|
props.amount.shiftedBy(-1 * props.asset.decimals).toString(),
|
|
)
|
|
|
|
useEffect(() => {
|
|
if (props.amount.isZero()) return setFormattedAmount('')
|
|
|
|
setFormattedAmount(
|
|
formatValue(props.amount.toNumber(), {
|
|
decimals: props.asset.decimals,
|
|
minDecimals: 0,
|
|
maxDecimals: props.maxDecimals,
|
|
thousandSeparator: false,
|
|
}),
|
|
)
|
|
}, [props.amount, props.asset, props.maxDecimals])
|
|
|
|
useEffect(() => {
|
|
if (!props.onRef) return
|
|
props.onRef(inputRef)
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [inputRef, props.onRef])
|
|
|
|
const onInputFocus = () => {
|
|
inputRef.current?.select()
|
|
props.onFocus && props.onFocus()
|
|
}
|
|
|
|
const updateValues = (formatted: string, amount: BigNumber) => {
|
|
const lastChar = formatted.charAt(formatted.length - 1)
|
|
if (lastChar === '.') {
|
|
cursorRef.current = (inputRef.current?.selectionEnd || 0) + 1
|
|
} else {
|
|
cursorRef.current = inputRef.current?.selectionEnd || 0
|
|
}
|
|
setFormattedAmount(formatted)
|
|
|
|
if (!props.amount.isEqualTo(amount)) {
|
|
props.onChange(amount)
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (!inputRef.current) return
|
|
|
|
const cursor = cursorRef.current
|
|
const length = formattedAmount.length
|
|
|
|
if (cursor > length) {
|
|
inputRef.current.setSelectionRange(length, length)
|
|
return
|
|
}
|
|
|
|
inputRef.current.setSelectionRange(cursor, cursor)
|
|
}, [formattedAmount, inputRef])
|
|
|
|
const onInputChange = (formattedAmount: string) => {
|
|
const numberCount = formattedAmount.match(/[0-9]/g)?.length || 0
|
|
const decimals = formattedAmount.split('.')[1]?.length || 0
|
|
const lastChar = formattedAmount.charAt(formattedAmount.length - 1)
|
|
const isNumber = !isNaN(Number(formattedAmount))
|
|
const hasMultipleDots = (formattedAmount.match(/[.,]/g)?.length || 0) > 1
|
|
const isSeparator = lastChar === '.' || lastChar === ','
|
|
const isNegative = formattedAmount.indexOf('-') > -1
|
|
const isLowerThanMinimum =
|
|
props.min !== undefined && props.min.isGreaterThan(magnify(formattedAmount, props.asset))
|
|
const isHigherThanMaximum =
|
|
props.max !== undefined && props.max.isLessThan(magnify(formattedAmount, props.asset))
|
|
const isTooLong = props.maxLength !== undefined && numberCount > props.maxLength
|
|
const exceedsMaxDecimals = props.maxDecimals !== undefined && decimals > props.maxDecimals
|
|
|
|
if (formattedAmount === '') {
|
|
updateValues('0', BN_ZERO)
|
|
return
|
|
}
|
|
|
|
if (isNegative && !props.allowNegative) return
|
|
|
|
if (isSeparator && formattedAmount.length === 1) {
|
|
updateValues('0.', BN_ZERO)
|
|
return
|
|
}
|
|
|
|
if (isSeparator && !hasMultipleDots) {
|
|
updateValues(formattedAmount.replace(',', '.'), props.amount)
|
|
return
|
|
}
|
|
|
|
if (!isNumber || hasMultipleDots) return
|
|
|
|
if (exceedsMaxDecimals) {
|
|
formattedAmount = formattedAmount.substring(0, formattedAmount.length - 1)
|
|
}
|
|
|
|
if (isTooLong) return
|
|
|
|
if (isLowerThanMinimum && props.min) {
|
|
updateValues(String(demagnify(props.min, props.asset)), props.min)
|
|
return
|
|
}
|
|
|
|
if (isHigherThanMaximum && props.max) {
|
|
updateValues(String(demagnify(props.max, props.asset)), props.max)
|
|
return
|
|
}
|
|
|
|
const amount = BN(formattedAmount).shiftedBy(props.asset.decimals)
|
|
|
|
if (lastChar === '0' && amount.isEqualTo(props.amount)) {
|
|
cursorRef.current = (inputRef.current?.selectionEnd || 0) + 1
|
|
setFormattedAmount(formattedAmount)
|
|
return
|
|
}
|
|
|
|
updateValues(amount.shiftedBy(-1 * props.asset.decimals).toString(), amount)
|
|
}
|
|
|
|
return (
|
|
<input
|
|
ref={inputRef}
|
|
type='text'
|
|
value={formattedAmount === '0' ? '0' : formattedAmount}
|
|
onFocus={onInputFocus}
|
|
onChange={(e) => onInputChange(e.target.value)}
|
|
onBlur={props.onBlur}
|
|
disabled={props.disabled}
|
|
className={classNames(
|
|
'w-full hover:cursor-pointer appearance-none border-none bg-transparent text-right outline-none',
|
|
props.className,
|
|
)}
|
|
style={props.style}
|
|
placeholder={props.placeholder ?? '0'}
|
|
/>
|
|
)
|
|
}
|