import { useEffect, useState } from "react"; export interface NumberFieldProps { label: string; value: number; onChange: (v: number) => void; /** Display = value * scale (e.g. 1000 to show metres as millimetres) */ scale?: number; unit?: string; step?: number; min?: number; max?: number; integer?: boolean; invalid?: boolean; disabled?: boolean; title?: string; } /** A numeric input that tolerates partial typing and commits parsed values. */ export function NumberField(props: NumberFieldProps) { const { label, value, onChange, scale = 1, unit, step, min, max, integer, invalid, disabled, title } = props; const shown = formatShown(value * scale); const [text, setText] = useState(shown); useEffect(() => { // Sync from outside unless the text already means the same number if (Number(text) * 1 !== value * scale) setText(shown); // eslint-disable-next-line react-hooks/exhaustive-deps }, [value, scale]); return (