diff --git a/src/components/input/NumericInputWithUnit.tsx b/src/components/input/NumericInputWithUnit.tsx index 690fa2b..34077ee 100644 --- a/src/components/input/NumericInputWithUnit.tsx +++ b/src/components/input/NumericInputWithUnit.tsx @@ -1,16 +1,29 @@ import React, { useState, useEffect } from 'react'; -import { Grid, TextField } from '@mui/material'; +import { Grid, TextField, Select, MenuItem } from '@mui/material'; import TextFieldWithDesc from '@components/options/TextFieldWithDesc'; import Autocomplete from '@mui/material/Autocomplete'; import Qty from 'js-quantities'; -import { parse } from 'path'; -import { b } from 'vitest/dist/suite-IbNSsUWN.js'; +// + +const siPrefixes: { [key: string]: number } = { + '': 1, + k: 1000, + M: 1000000, + G: 1000000000, + T: 1000000000000, + m: 0.001, + u: 0.000001, + n: 0.000000001, + p: 0.000000000001 +}; export default function NumericInputWithUnit(props: { value: { value: number; unit: string }; onOwnChange: (value: { value: number; unit: string }, ...baseProps) => void; + defaultPrefix?: string; }) { const [inputValue, setInputValue] = useState(props.value.value); + const [prefix, setPrefix] = useState(props.defaultPrefix || ''); const [unit, setUnit] = useState(props.value.unit); const [unitOptions, setUnitOptions] = useState([]); @@ -34,7 +47,7 @@ export default function NumericInputWithUnit(props: { setInputValue(newValue); if (props.onOwnChange) { try { - const qty = Qty(newValue, unit).to(val.unit); + const qty = Qty(newValue * siPrefixes[prefix], unit).to(val.unit); props.onOwnChange({ unit: val.unit, value: qty.scalar }); } catch (error) { console.error('Conversion error', error); @@ -42,11 +55,31 @@ export default function NumericInputWithUnit(props: { } }; + const handlePrefixChange = (newPrefix: string) => { + const oldPrefixValue = siPrefixes[prefix]; + const newPrefixValue = siPrefixes[newPrefix]; + + setPrefix(newPrefix); + + // Value does not change, it is just re-formatted for display + // handleValueChange({ + // value: (inputValue * oldPrefixValue) / newPrefixValue, + // unit: unit + // }); + }; + const handleUnitChange = (newUnit: string) => { if (!newUnit) return; + const oldInputValue = inputValue; + const oldUnit = unit; setUnit(newUnit); + setPrefix(''); + try { - const convertedValue = Qty(inputValue, unit).to(newUnit).scalar; + const convertedValue = Qty( + oldInputValue * siPrefixes[prefix], + oldUnit + ).to(newUnit).scalar; setInputValue(convertedValue); } catch (error) { console.error('Unit conversion error', error); @@ -63,20 +96,46 @@ export default function NumericInputWithUnit(props: { }; return ( - + handleValueChange({ value: parseFloat(value), unit: unit }) } label="Value" /> - + + + + + + ({}); const [extraOutputs, setExtraOutputs] = useState<{ - [key: string]: string; + [key: string]: number; }>({}); const updateVarField = ( @@ -240,8 +239,8 @@ export default async function makeTool( ( {extraOutput.title} - {extraOutputs[extraOutput.title]} + + + {extraOutput.unit} @@ -345,7 +354,9 @@ export default async function makeTool( const result: nerdamer.Expression = expr.evaluate(); if (result) { - extraOutputs[extraOutput.title] = result.toDecimal(); + extraOutputs[extraOutput.title] = parseFloat( + result.toDecimal() + ); } } }