Skip to content

Commit

Permalink
[@mantine/core] NumberInput: Fix removeTrailingZeros prop not worki…
Browse files Browse the repository at this point in the history
…ng for initial value (#2638)

* [@mantine/core] NumberInput: implement parsePrecision function

* [@mantine/core] NumberInput: implement parsePrecision function
  • Loading branch information
PointSingularity committed Oct 11, 2022
1 parent d4ab38a commit 1b5a135
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 23 deletions.
24 changes: 24 additions & 0 deletions src/mantine-core/src/NumberInput/NumberInput.test.tsx
Expand Up @@ -141,6 +141,30 @@ describe('@mantine/core/NumberInput', () => {
expect(spy).toHaveBeenLastCalledWith(6.123);
});

it('supports removing trailing zero with increment/decrement', async () => {
const spy = jest.fn();
const { container } = render(
<NumberInput
defaultValue={0.05}
removeTrailingZeros
precision={2}
min={-1}
step={0.05}
max={1}
onChange={spy}
/>
);
await clickIncrement(container);
expectValue('0.1');
expect(spy).toHaveBeenLastCalledWith(0.1);
await clickDecrement(container);
expectValue('0.05');
expect(spy).toHaveBeenLastCalledWith(0.05);
await clickDecrement(container);
expectValue('0');
expect(spy).toHaveBeenLastCalledWith(0);
});

it('supports removing trailing zeros and decimal separator with precision', async () => {
const spy = jest.fn();
render(<NumberInput precision={8} removeTrailingZeros onChange={spy} />);
Expand Down
46 changes: 23 additions & 23 deletions src/mantine-core/src/NumberInput/NumberInput.tsx
Expand Up @@ -165,13 +165,27 @@ export const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>((props
{ classNames, styles, unstyled, name: 'NumberInput' }
);

const parsePrecision = (val: number | undefined) => {
if (val === undefined) return undefined;

let result = val.toFixed(precision);
if (removeTrailingZeros && precision > 0) {
result = result.replace(new RegExp(`[0]{0,${precision}}$`), '');
if (result.endsWith('.') || result.endsWith(decimalSeparator)) {
result = result.slice(0, -1);
}
}

return result;
};

const [focused, setFocused] = useState(false);
const [_value, setValue] = useState(
typeof value === 'number' ? value : typeof defaultValue === 'number' ? defaultValue : undefined
);
const finalValue = typeof value === 'number' ? value : _value;
const [tempValue, setTempValue] = useState(
typeof finalValue === 'number' ? finalValue.toFixed(precision) : ''
typeof finalValue === 'number' ? parsePrecision(finalValue) : ''
);
const inputRef = useRef<HTMLInputElement>();
const handleValueChange = (val: number | undefined) => {
Expand Down Expand Up @@ -208,9 +222,9 @@ export const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>((props
incrementRef.current = () => {
if (_value === undefined) {
handleValueChange(startValue ?? min ?? 0);
setTempValue(startValue?.toFixed(precision) ?? min?.toFixed(precision) ?? '0');
setTempValue(parsePrecision(startValue) ?? parsePrecision(min) ?? '0');
} else {
const result = clamp(_value + step, _min, _max).toFixed(precision);
const result = parsePrecision(clamp(_value + step, _min, _max));

handleValueChange(parseFloat(result));
setTempValue(result);
Expand All @@ -221,9 +235,9 @@ export const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>((props
decrementRef.current = () => {
if (_value === undefined) {
handleValueChange(startValue ?? min ?? 0);
setTempValue(startValue?.toFixed(precision) ?? min?.toFixed(precision) ?? '0');
setTempValue(parsePrecision(startValue) ?? parsePrecision(min) ?? '0');
} else {
const result = clamp(_value - step, _min, _max).toFixed(precision);
const result = parsePrecision(clamp(_value - step, _min, _max));
handleValueChange(parseFloat(result));
setTempValue(result);
}
Expand All @@ -234,7 +248,7 @@ export const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>((props
useEffect(() => {
if (typeof value === 'number' && !focused) {
setValue(value);
setTempValue(value.toFixed(precision));
setTempValue(parsePrecision(value));
}
if (defaultValue === undefined && value === undefined && !focused) {
setValue(value);
Expand Down Expand Up @@ -359,25 +373,11 @@ export const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>((props

if (!Number.isNaN(val)) {
if (!noClampOnBlur) {
if (removeTrailingZeros) {
const valNoZeros = val
.toFixed(precision)
.replace(new RegExp(`[0]{0,${precision}}$`), '');

if (valNoZeros.endsWith(decimalSeparator) || valNoZeros.endsWith('.')) {
setTempValue(valNoZeros.slice(0, -1));
handleValueChange(parseFloat(valNoZeros.slice(0, -1)));
} else {
setTempValue(valNoZeros);
handleValueChange(parseFloat(valNoZeros));
}
} else {
setTempValue(val.toFixed(precision));
handleValueChange(parseFloat(val.toFixed(precision)));
}
setTempValue(parsePrecision(val));
handleValueChange(parseFloat(parsePrecision(val)));
}
} else {
setTempValue(finalValue?.toFixed(precision) ?? '');
setTempValue(parsePrecision(finalValue) ?? '');
}
}

Expand Down

0 comments on commit 1b5a135

Please sign in to comment.