import { always, clamp, cond, isEmpty, T } from 'ramda'; import { type ChangeEvent, useState } from 'react'; import TextField, { type TextProps } from '../Text'; export interface NumberProps extends Omit { /** * The initial value which will be used by the input for the first render */ defaultValue?: number; /** * This value will be used when the input is cleared */ fallbackValue?: number; /** * The change function with the actual value as parameter. This parameter will be the value when the input is filled but it will be the fallbackValue when the input is cleared out */ onChange: (actualValue: number) => void; } const NumberField = ({ fallbackValue = 0, defaultValue, onChange, ...props }: NumberProps): JSX.Element => { const [placeholder, setPlaceholder] = useState(); const [actualValue, setActualValue] = useState( defaultValue ? `${defaultValue}` : '' ); const { textFieldSlotsAndSlotProps } = props; const changeValue = (event: ChangeEvent): void => { const inputValue = event.target.value; const number = Number(inputValue); const campledNumber = cond([ [() => isEmpty(inputValue), always(fallbackValue)], [() => Number.isNaN(number), always(number)], [ T, always( clamp( ( textFieldSlotsAndSlotProps?.slotProps?.htmlInput as | Record | undefined )?.min || Number.NEGATIVE_INFINITY, ( textFieldSlotsAndSlotProps?.slotProps?.htmlInput as | Record | undefined )?.max || Number.POSITIVE_INFINITY, number ) ) ] ])(); onChange(campledNumber); setPlaceholder(isEmpty(inputValue) ? `${fallbackValue}` : undefined); setActualValue(isEmpty(inputValue) ? inputValue : `${campledNumber}`); }; return ( ); }; export default NumberField;