I spent 2 days trying to make it work. I put it here for future reference.
import * as React from 'react';
import { Input } from "@fluentui/react-components";
import { useState } from "react";
export interface INumericInputProps {
minimumFractionDigits?: number,
maximumFractionDigits?: number,
placeholder?: string,
disabled?: boolean,
value?: number,
onChange: (value?: number) => void
}
const NumericInput : React.FC<INumericInputProps> = (props) => {
const locale = "it-IT";
const [textValue, setTextValue] = useState(props.value?.toLocaleString(locale) || "");
const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
const allowedKeys = [
'ArrowUp',
'ArrowDown',
'ArrowLeft',
'ArrowRight',
'Tab',
'Shift',
'Control',
'Home',
'End',
'Backspace',
'Delete',
'Enter',
'Escape',
'Canc'
];
if (!/[0-9,]/.test(event.key) && !allowedKeys.includes(event.key)) {
event.preventDefault();
}
};
const ontTextChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setTextValue(event.target.value);
}
const onTextBlur = () => {
const cleanedText = textValue.replace(/\./g, '').replace(",", ".");
const value = Number(cleanedText);
let formattedValue = new Intl.NumberFormat('it-IT', {
minimumFractionDigits: props.minimumFractionDigits || 0,
maximumFractionDigits: props.maximumFractionDigits || 0,
}).format(value);
if (formattedValue === "NaN") {
formattedValue = "";
}
setTextValue(formattedValue);
if (formattedValue !== "") {
props.onChange(value);
}
}
return <Input
type="text"
appearance="filled-darker"
placeholder={props.placeholder}
disabled={props.disabled ?? false}
onKeyDown={onKeyDown}
onChange={ontTextChange}
onBlur={onTextBlur}
value={textValue}/>;
};
export default NumericInput;
Planned improvement: localization. As of now supports only Italian locale.
Top comments (0)