diff --git a/package.json b/package.json index 43497f77..1f99a0f1 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "build:react:clean": "yarn clean:react && yarn build:react", "clean:paybutton": "rm -rf paybutton/node_modules paybutton/dist", "clean:app": "yarn clean:react && yarn clean:paybutton", - "clean:build": "yarn clean:app && yarn build" + "clean:build": "yarn clean:app && yarn build", + "clean:watch": "yarn clean:build && yarn watch" } } diff --git a/react/lib/components/Widget/Widget.tsx b/react/lib/components/Widget/Widget.tsx index 4f09b610..6670a4b6 100644 --- a/react/lib/components/Widget/Widget.tsx +++ b/react/lib/components/Widget/Widget.tsx @@ -25,6 +25,7 @@ import { openCashtabPayment, initializeCashtabStatus, DECIMALS, + MAX_AMOUNT, CurrencyObject, getCurrencyObject, formatPrice, @@ -985,7 +986,6 @@ export const Widget: React.FunctionComponent = props => { }, [disabled, to, opReturn, userDonationRate, donationAddress, donationEnabled, shouldApplyDonation] ) - const stripFormatting = (s: string) => { return s.replace(/,/g, '').replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.0+$/, ''); } @@ -1183,7 +1183,6 @@ export const Widget: React.FunctionComponent = props => { ) : null} - {isPropsTrue(editable) ? ( = props => { onKeyDown={(e: React.KeyboardEvent) => { if (e.key === 'Enter' && isDraftValid && !isSameAmount) { applyDraftAmount(); - } + } }} thousandSeparator allowLeadingZeros={false} decimalScale={8} inputRef={inputRef} customInput={TextField} + isAllowed={(values) => { + const { floatValue, value } = values + + if (floatValue === undefined) { + return true + } + + const maxAmount = MAX_AMOUNT[thisAddressType] ?? MAX_AMOUNT.XEC + if (floatValue < 0 || floatValue > maxAmount) { + return false + } + + const stepDecimals = DECIMALS[thisAddressType] ?? DECIMALS.XEC + const decimals = value.split('.')[1]?.length ?? 0 + + // Do not allow more decimal places than step supports + if (decimals > stepDecimals) { + return false + } + + return true + }} label="Edit amount" + name="Amount" + placeholder="Enter Amount" + id="userEditedAmount" disabled={success} InputProps={{ endAdornment: ( @@ -1210,18 +1234,18 @@ export const Widget: React.FunctionComponent = props => { onClick={applyDraftAmount} sx={{ padding: '4px 10px', - fontSize: '0.75rem', - fontWeight: 500, - color: '#fff', - backgroundColor: theme.palette.primary, - border: 'none', - borderRadius: '4px', - cursor: 'pointer', - transition: 'background-color 0.2s ease, opacity 0.2s ease', - visibility: isDraftValid && !isSameAmount ? 'visible' : 'hidden', - '&:hover': { - backgroundColor: theme.palette.logo ?? theme.palette.primary, - }, + fontSize: '0.75rem', + fontWeight: 500, + color: '#fff', + backgroundColor: theme.palette.primary, + border: 'none', + borderRadius: '4px', + cursor: 'pointer', + transition: 'background-color 0.2s ease, opacity 0.2s ease', + visibility: isDraftValid && !isSameAmount ? 'visible' : 'hidden', + '&:hover': { + backgroundColor: theme.palette.logo ?? theme.palette.primary, + }, }} > Confirm diff --git a/react/lib/util/constants.ts b/react/lib/util/constants.ts index 586838c7..fcdf68f4 100644 --- a/react/lib/util/constants.ts +++ b/react/lib/util/constants.ts @@ -8,6 +8,11 @@ export const DECIMALS: { [key: string]: number } = { FIAT: 2, }; +export const MAX_AMOUNT: { [key: string]: number } = { + BCH: 999999.99999999, + XEC: 999999999999.99, +}; + // Default delay (ms) before auto-closing success dialog when autoClose is enabled export const AUTO_CLOSE_DEFAULT_MS = 2000;