From 304ec1a2939a0968529418511916811755349608 Mon Sep 17 00:00:00 2001 From: Charlie McKenzie Date: Wed, 14 Feb 2024 14:11:53 +1100 Subject: [PATCH] fix: [WT-2150] Checkout Widget amount inputs correctly handle decimal inputs (#1473) --- .../SelectInput/SelectInput.tsx | 5 ++- .../TextInputForm/TextInputForm.cy.tsx | 44 +++++++++++++++++++ .../TextInputForm/TextInputForm.tsx | 9 +++- .../widgets/bridge/components/BridgeForm.tsx | 12 +++-- .../src/widgets/swap/components/SwapForm.tsx | 2 + 5 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 packages/checkout/widgets-lib/src/components/FormComponents/TextInputForm/TextInputForm.cy.tsx diff --git a/packages/checkout/widgets-lib/src/components/FormComponents/SelectInput/SelectInput.tsx b/packages/checkout/widgets-lib/src/components/FormComponents/SelectInput/SelectInput.tsx index b8b410c5d3..b98ccdfa65 100644 --- a/packages/checkout/widgets-lib/src/components/FormComponents/SelectInput/SelectInput.tsx +++ b/packages/checkout/widgets-lib/src/components/FormComponents/SelectInput/SelectInput.tsx @@ -5,7 +5,7 @@ import { selectStyle, } from './SelectInputStyles'; import { SelectForm } from '../SelectForm/SelectForm'; -import { TextInputForm } from '../TextInputForm/TextInputForm'; +import { TextInputForm, TextInputType } from '../TextInputForm/TextInputForm'; import { CoinSelectorOptionProps } from '../../CoinSelector/CoinSelectorOption'; interface SelectInputProps { @@ -17,6 +17,7 @@ interface SelectInputProps { textInputPlaceholder?: string; textInputSubtext?: string; textInputErrorMessage?: string; + textInputType?: TextInputType; selectSubtext?: string; selectErrorMessage?: string; coinSelectorHeading: string; @@ -37,6 +38,7 @@ export function SelectInput({ textInputValue, textInputPlaceholder, textInputValidator, + textInputType, onTextInputChange, onTextInputBlur, onTextInputFocus, @@ -70,6 +72,7 @@ export function SelectInput({ { + describe('type number', () => { + it('should convert . into zero number when type is number input', () => { + mount( + + true} + onTextInputChange={() => {}} + /> + , + ); + cySmartGet('text-input-form-test-select__input').type('.'); + cySmartGet('text-input-form-test-select__input').trigger('change'); + cySmartGet('text-input-form-test-select__target__controlledLabel').should('have.text', '0.'); + }); + }); + + describe('type text or no type', () => { + it('should preserve . as .', () => { + mount( + + true} + onTextInputChange={() => {}} + /> + , + ); + cySmartGet('text-input-form-test-select__input').type('.'); + cySmartGet('text-input-form-test-select__input').trigger('change'); + cySmartGet('text-input-form-test-select__target__controlledLabel').should('have.text', '.'); + }); + }); +}); diff --git a/packages/checkout/widgets-lib/src/components/FormComponents/TextInputForm/TextInputForm.tsx b/packages/checkout/widgets-lib/src/components/FormComponents/TextInputForm/TextInputForm.tsx index 52a61fc806..67df78fc7d 100644 --- a/packages/checkout/widgets-lib/src/components/FormComponents/TextInputForm/TextInputForm.tsx +++ b/packages/checkout/widgets-lib/src/components/FormComponents/TextInputForm/TextInputForm.tsx @@ -7,6 +7,7 @@ interface TextInputFormProps { placeholder?: string; subtext?: string; textAlign?: 'left' | 'right'; + type?: TextInputType; errorMessage?: string; disabled?: boolean; validator: (value: string) => boolean; @@ -17,6 +18,8 @@ interface TextInputFormProps { maxButtonClick?: () => void; } +export type TextInputType = 'text' | 'number'; + export function TextInputForm({ testId, value, @@ -28,12 +31,16 @@ export function TextInputForm({ onTextInputFocus, onTextInputEnter, textAlign, + type, subtext, maxButtonClick, disabled, }: TextInputFormProps) { const handleOnChange = (event: React.ChangeEvent, previousValue: string) => { - const inputValue = event.target.value; + let inputValue = event.target.value; + if (type === 'number' && inputValue === '.') { + inputValue = '0.'; + } if (!validator(inputValue)) { // TODO: is there a better solution to this, cypress tests having issues with typing 'abc' and it still being set onTextInputChange(previousValue ?? ''); diff --git a/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeForm.tsx b/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeForm.tsx index 4800399f71..7ab2cea31e 100644 --- a/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeForm.tsx +++ b/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeForm.tsx @@ -196,15 +196,20 @@ export function BridgeForm(props: BridgeFormProps) { }, [tokenBalances, formToken, formAmount]); const handleBridgeAmountChange = (value: string) => { - setFormAmount(value); + // Ensure that starting with a decimal is formatted correctly + let inputValue = value; + if (inputValue === '.') { + inputValue = '0.'; + } + setFormAmount(inputValue); if (amountError) { - const validateAmountError = validateAmount(value, formToken?.formattedBalance); + const validateAmountError = validateAmount(inputValue, formToken?.formattedBalance); setAmountError(validateAmountError); } if (!formToken) return; setAmountFiatValue(calculateCryptoToFiat( - value, + inputValue, formToken.token.symbol, cryptoFiatState.conversions, )); @@ -343,6 +348,7 @@ export function BridgeForm(props: BridgeFormProps) { />