import React, { useState } from 'react'; import { formatEditableNumber } from './unitSystem'; interface NumberFieldProps extends Omit, 'value' | 'onChange' | 'type'> { /** Value in display units. */ value: number; /** Called with the parsed display-unit number on blur / Enter only. */ onCommit: (value: number) => void; } /** * Numeric input for unit-converted values. A controlled * whose value is display(model(typed)) gets rewritten mid-typing whenever the * ft/m or flow-unit round trip isn't exact (typing "216.4" in a US model ended * up as 3.9999999999999996). Keeping the typed text as a local draft and * committing only on blur/Enter avoids that round trip while editing. */ export const NumberField: React.FC = ({ value, onCommit, onBlur, onKeyDown, ...rest }) => { const [draft, setDraft] = useState(null); const commit = () => { if (draft === null) return; const parsed = Number(draft); setDraft(null); if (draft.trim() !== '' && Number.isFinite(parsed)) onCommit(parsed); }; return ( setDraft(e.target.value)} onBlur={(e) => { commit(); onBlur?.(e); }} onKeyDown={(e) => { if (e.key === 'Enter') commit(); if (e.key === 'Escape') setDraft(null); onKeyDown?.(e); }} /> ); };