Skip to content

Commit

Permalink
[@mantine/core] NumberInput: Remove increment/decrement control if va…
Browse files Browse the repository at this point in the history
…lue cannot be safely incremented (is larger than Number.MAX_SAFE_INTEGER) (#7033)
  • Loading branch information
rtivital committed Nov 16, 2024
1 parent d1e48bf commit 5af034c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import { NumberInput, NumberInputHandlers } from './NumberInput';
export default { title: 'NumberInput' };

export function Usage() {
const [value, setValue] = useState<number | string>('345');
const [value, setValue] = useState<number | string>('');
return (
<div style={{ padding: 40 }}>
<NumberInput
value={value}
label="Number input"
placeholder="Number input"
onChange={setValue}
onValueChange={console.log}
// onValueChange={console.log}
/>
{typeof value === 'number' ? `${value} number` : `${value === '' ? 'empty' : value} string`}
<Button onClick={() => setValue(245.32)}>Set value to float</Button>
Expand Down
23 changes: 21 additions & 2 deletions packages/@mantine/core/src/components/NumberInput/NumberInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,15 @@ export interface NumberInputHandlers {
}

function isNumberString(value: unknown) {
return typeof value === 'string' && !Number.isNaN(Number(value));
return typeof value === 'string' && value !== '' && !Number.isNaN(Number(value));
}

function canIncrement(value: number | string) {
if (typeof value === 'number') {
return value < Number.MAX_SAFE_INTEGER;
}

return value === '';
}

function getDecimalPlaces(inputValue: string | number): number {
Expand Down Expand Up @@ -247,6 +255,7 @@ export const NumberInput = factory<NumberInputFactory>((_props, ref) => {
const [_value, setValue] = useUncontrolled({
value,
defaultValue,
finalValue: '',
onChange,
});

Expand Down Expand Up @@ -284,6 +293,10 @@ export const NumberInput = factory<NumberInputFactory>((_props, ref) => {

const incrementRef = useRef<() => void>();
incrementRef.current = () => {
if (!canIncrement(_value)) {
return;
}

let val: number;
const currentValuePrecision = getDecimalPlaces(_value);
const stepPrecision = getDecimalPlaces(step!);
Expand Down Expand Up @@ -311,6 +324,10 @@ export const NumberInput = factory<NumberInputFactory>((_props, ref) => {

const decrementRef = useRef<() => void>();
decrementRef.current = () => {
if (!canIncrement(_value)) {
return;
}

let val: number;
const minValue = min !== undefined ? min : !allowNegative ? 0 : Number.MIN_SAFE_INTEGER;
const currentValuePrecision = getDecimalPlaces(_value);
Expand Down Expand Up @@ -454,7 +471,9 @@ export const NumberInput = factory<NumberInputFactory>((_props, ref) => {
value={_value}
getInputRef={useMergedRef(ref, inputRef)}
onValueChange={handleValueChange}
rightSection={hideControls || readOnly ? rightSection : rightSection || controls}
rightSection={
hideControls || readOnly || !canIncrement(_value) ? rightSection : rightSection || controls
}
classNames={resolvedClassNames}
styles={resolvedStyles}
unstyled={unstyled}
Expand Down

0 comments on commit 5af034c

Please sign in to comment.