Now with unit conversions

This commit is contained in:
Daniel Dunn
2025-04-03 05:32:47 -06:00
parent 6b27595a89
commit 70480d0920
4 changed files with 88 additions and 15 deletions

View File

@@ -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<string[]>([]);
@@ -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 (
<Grid container spacing={2} alignItems="center">
<Grid
container
spacing={2}
alignItems="center"
style={{ minWidth: '20rem' }}
>
<Grid item xs={6}>
<TextFieldWithDesc
{...props.baseProps}
type="number"
fullWidth
value={inputValue}
value={(inputValue / siPrefixes[prefix])
.toFixed(9)
.replace(/(\d*\.\d+?)0+$/, '$1')}
onOwnChange={(value) =>
handleValueChange({ value: parseFloat(value), unit: unit })
}
label="Value"
/>
</Grid>
<Grid item xs={6}>
<Grid item xs={3}>
<Select
fullWidth
label="Prefix"
title="Prefix"
value={prefix}
onChange={(event, newValue) => {
handlePrefixChange(newValue.props.value || '');
}}
>
{Object.keys(siPrefixes).map((key) => (
<MenuItem key={key} value={key}>
{key}
</MenuItem>
))}
</Select>
</Grid>
<Grid item xs={3}>
<Autocomplete
options={unitOptions}
value={unit}