diff --git a/.changeset/plenty-flowers-live.md b/.changeset/plenty-flowers-live.md new file mode 100644 index 000000000..934645c37 --- /dev/null +++ b/.changeset/plenty-flowers-live.md @@ -0,0 +1,5 @@ +--- +'@ant-design/web3': patch +--- + +feat: Optimize the input interaction of the CryptoInput component diff --git a/packages/web3/src/crypto-input/__tests__/index.test.tsx b/packages/web3/src/crypto-input/__tests__/index.test.tsx index 1429ceaaf..422e40a36 100644 --- a/packages/web3/src/crypto-input/__tests__/index.test.tsx +++ b/packages/web3/src/crypto-input/__tests__/index.test.tsx @@ -80,7 +80,11 @@ describe('CryptoInput component', () => { it('should call onChange with selected token and amount input', () => { const TestComponent = (props: CryptoInputProps) => { - const [crypto, setCrypto] = useState(); + const [crypto, setCrypto] = useState({ + inputString: '10', + amount: 0n, + token: undefined, + }); return ( { value={crypto} onChange={(newCrypto) => { setCrypto(newCrypto); - props.onChange?.(newCrypto); }} /> @@ -99,18 +102,24 @@ describe('CryptoInput component', () => { const { baseElement } = render(); - fireEvent.mouseDown(baseElement.querySelector('.ant-select-selector') as Element); - - const selectOptions = baseElement.querySelectorAll('.ant-select-item'); - - fireEvent.click(selectOptions[0]); + fireEvent.change(baseElement.querySelector('.ant-input-number-input') as Element, { + target: { value: '' }, + }); - expect(handleChange).toHaveBeenCalledWith({ token: mockTokens[0] }); + expect(handleChange).toHaveBeenCalledWith({}); fireEvent.change(baseElement.querySelector('.ant-input-number-input') as Element, { target: { value: '10' }, }); + expect(handleChange).toHaveBeenCalledWith({ inputString: '10' }); + + fireEvent.mouseDown(baseElement.querySelector('.ant-select-selector') as Element); + + const selectOptions = baseElement.querySelectorAll('.ant-select-item'); + + fireEvent.click(selectOptions[0]); + expect(handleChange).toHaveBeenCalledWith({ token: mockTokens[0], amount: 10000000000000000000n, diff --git a/packages/web3/src/crypto-input/index.tsx b/packages/web3/src/crypto-input/index.tsx index 20c596657..0a56e7ed4 100644 --- a/packages/web3/src/crypto-input/index.tsx +++ b/packages/web3/src/crypto-input/index.tsx @@ -70,6 +70,44 @@ export const CryptoInput: React.FC = ({ : undefined, ); + // 将 InputNumber 的 onChange 和 TokenSelect 的 onChange 合并 + const handleChange = (amt: string | null, curToken?: Token) => { + if (!amt && !curToken) { + onChange?.({}); + return; + } else if (!curToken) { + onChange?.({ inputString: amt! }); + return; + } else if (!amt) { + onChange?.({ token: curToken }); + return; + } + + const [integers, decimals] = String(amt).split('.'); + + let inputAmt = amt; + + // if precision is more than token decimal, cut it + if (decimals?.length > curToken.decimal) { + inputAmt = `${integers}.${decimals.slice(0, curToken.decimal)}`; + } + + // covert string amt to bigint + + const newAmt = BigInt( + new Decimal100(inputAmt) + .times(Decimal100.pow(10, curToken.decimal)) + .toFixed(0, Decimal100.ROUND_DOWN), + ); + + onChange?.({ + ...value, + amount: newAmt, + inputString: inputAmt, + token: curToken, + }); + }; + return wrapSSR( {header &&
{header}
} @@ -82,48 +120,13 @@ export const CryptoInput: React.FC = ({ placeholder={messages.placeholder} value={inputString} // remove unnecessary 0 at the end of the number - onChange={(amt) => { - // if amount is null or token is not selected, clean the value - if (isNull(amt) || !token) { - onChange?.({ - token, - }); - return; - } - - const [integers, decimals] = String(amt).split('.'); - - let inputAmt = amt; - - // if precision is more than token decimal, cut it - if (decimals?.length > token.decimal) { - inputAmt = `${integers}.${decimals.slice(0, token.decimal)}`; - } - - // covert string amt to bigint - - const newAmt = BigInt( - new Decimal100(inputAmt) - .times(Decimal100.pow(10, token.decimal)) - .toFixed(0, Decimal100.ROUND_DOWN), - ); - - onChange?.({ - ...value, - amount: newAmt, - inputString: inputAmt, - }); - }} + onChange={(amt) => handleChange(amt, token)} addonAfter={ - onChange?.({ - token: newToken, - }) - } + onChange={(newToken) => handleChange(inputString || '', newToken)} size={size} /> }