I take a reference from official document
https://chakra-ui.com/docs/components/number-input
The example user can click inc and dec icon to change value also directly input in the text box.
import {
ChakraProvider,
Stack,
HStack,
Button,
Input,
useNumberInput
} from "@chakra-ui/react";
const { getInputProps, getIncrementButtonProps, getDecrementButtonProps } =
useNumberInput({
step: 0.01,
defaultValue: 0.5,
min: 0.01,
max: 1.0,
precision: 2,
})
const inc = getIncrementButtonProps()
const dec = getDecrementButtonProps()
const input = getInputProps()
return (
<Stack>
<HStack maxW='320px'>
<Button {...inc}>+</Button>
<Input {...input} />
<Button {...dec}>-</Button>
</HStack>
</Stack>
);
Then I want to change the value with other buttons, so I try to use setState, After some attempts, I found that I couldn't use defaultValue in useNumberInput, so I use value and onChange.
const [limiInputValue, setLimitInputValue] = useState(0.5);
const { getInputProps, getIncrementButtonProps, getDecrementButtonProps } =
useNumberInput({
step: 0.01,
// defaultValue: limiInputValue,
min: 0.01,
max: 1.0,
precision: 2,
value: limiInputValue,
onChange: value => {
console.log('onChange value', value);
setLimitInputValue(Number(value));
},
})
const inc = getIncrementButtonProps()
const dec = getDecrementButtonProps()
const input = getInputProps()
return (
<Stack>
<HStack maxW='320px'>
<Button {...inc}>+</Button>
<Input {...input} />
<Button {...dec}>-</Button>
</HStack>
<Button onClick={() => setLimitInputValue(0.25)}>Set</Button>
</Stack>
);
Everything is fine, but I have a problem is user can't type decimal point in Input directly.
How to fix it ?
Here is my sandbox example:
https://codesandbox.io/p/devbox/twk7v6?file=%2Fsrc%2Findex.tsx%3A19%2C18
The issue you are experiencing is, In your
onChangefunction, you are converting the value to a number immediately withNumber(value). This can create problems when typing decimal numbers because as soon as you type the decimal point (without following numbers),Number(value)will return0if the input is not a valid number, which effectively removes the decimal point from the input.To fix this, Allow the user to input decimals by not immediately converting the input value to a number inside the
onChangehandler. Only update thelimiInputValuestate if the new value is a valid number within the specified range.Follow the below code :-