import { InputNumber } from 'exchange-elements/v2';
import { FormEvent, memo, SyntheticEvent, useCallback, useEffect, useState } from 'react';
import styles from './index.module.scss';
interface NumberFieldProps {
label: string;
value?: number;
initialValue?: number;
min?: number;
max?: number;
onValueChange: (value: number) => void;
}
type HandleChange = {
(event: FormEvent<HTMLInputElement>): void;
(item: number, event?: SyntheticEvent): void;
};
export const NumberField = memo(({ label, value, initialValue, min, max, onValueChange }: NumberFieldProps) => {
const [localValue, setLocalValue] = useState(initialValue ?? value ?? 0);
useEffect(() => {
if (value !== undefined) {
setLocalValue(value);
}
}, [value]);
const handleChange = useCallback<HandleChange>(
(valueOrEvent: number | FormEvent<HTMLInputElement>) => {
const nextValue =
typeof valueOrEvent === 'number'
? valueOrEvent
: Number((valueOrEvent?.currentTarget as HTMLInputElement)?.value);
const normalizedValue = normalizeValue(nextValue, min, max);
setLocalValue(normalizedValue);
onValueChange(normalizedValue);
},
[min, max, onValueChange],
);
return (
<InputNumber
className={styles.input}
value={localValue}
onChange={handleChange}
label={label}
labelPos="top"
size="sm"
/>
);
});
function normalizeValue(value: number, min?: number, max?: number): number {
if (Number.isNaN(value)) {
return min ?? 0;
}
if (min !== undefined && value < min) {
return min;
}
if (max !== undefined && value > max) {
return max;
}
return value;
}