@itwin/quantity-formatting-react
Version:
React components and utilities for quantity formatting
107 lines • 5.5 kB
JavaScript
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from "react";
import { Input, Select } from "@itwin/itwinui-react";
import { useTranslation } from "../../../../useTranslation.js";
async function getUnitConversionData(possibleUnits, toUnit, unitsProvider) {
const unitConversionEntries = possibleUnits.map(async (unit) => {
const conversion = await unitsProvider.getConversion(unit, toUnit);
return { conversion, unitProps: unit };
});
return unitConversionEntries;
}
async function getPossibleUnits(parentUnit, unitsProvider, ensureCompatibleComposite) {
const phenomenon = parentUnit.phenomenon;
const possibleUnits = await unitsProvider.getUnitsByFamily(phenomenon);
if (!ensureCompatibleComposite)
return possibleUnits;
const conversionPromises = await getUnitConversionData(possibleUnits, parentUnit, unitsProvider);
const conversionEntries = await Promise.all(conversionPromises);
// sort the entries so the best potential sub unit will be the first one in the array
return conversionEntries
.filter((entry) => entry.unitProps.system === parentUnit.system &&
entry.conversion.factor < 1)
.sort((a, b) => b.conversion.factor - a.conversion.factor)
.map((value) => value.unitProps);
}
/** @internal */
export function getUnitName(fullUnitName) {
const nameParts = fullUnitName.split(/[.:]/);
if (nameParts.length > 0)
return nameParts[nameParts.length - 1];
throw Error("Bad unit name encountered");
}
/** Component use to display dropdown list of possible units.
* @internal
*/
export function UnitDescr(props) {
const { name, label, parentUnitName, index, onUnitChange, onLabelChange, readonly, unitsProvider, } = props;
const [unitOptions, setUnitOptions] = React.useState([
{ value: name, label: getUnitName(name) },
]);
const [currentUnit, setCurrentUnit] = React.useState({ name, label });
const { translate } = useTranslation();
React.useEffect(() => {
let disposed = false;
const fetchAllowableUnitSelections = async () => {
const currentUnitProps = await unitsProvider.findUnitByName(name);
const parentUnit = await unitsProvider.findUnitByName(parentUnitName ? parentUnitName : name);
if (parentUnit && currentUnitProps) {
let potentialSubUnit;
const potentialUnits = await getPossibleUnits(parentUnit, unitsProvider, index !== 0);
if (index < 3) {
const potentialSubUnits = await getPossibleUnits(currentUnitProps, unitsProvider, true);
if (potentialSubUnits.length)
potentialSubUnit = potentialSubUnits[0];
}
const options = potentialUnits.length > 0
? potentialUnits
.map((unitValue) => {
return {
value: `${unitValue.name}:${unitValue.label}`,
label: getUnitName(unitValue.name),
};
})
.sort((a, b) => a.label.localeCompare(b.label))
: [
{
value: `${currentUnitProps.name}:${currentUnitProps.label}`,
label: getUnitName(name),
},
];
if (potentialSubUnit) {
// construct an entry that will provide the name and label of the unit to add
options.push({
value: `ADDSUBUNIT:${potentialSubUnit.name}:${potentialSubUnit.label}`,
label: translate("QuantityFormat:labels.addSubUnit"),
});
}
if (index !== 0)
options.push({
value: "REMOVEUNIT",
label: translate("QuantityFormat:labels.removeUnit"),
});
if (disposed)
return;
setUnitOptions(options);
setCurrentUnit(currentUnitProps);
}
};
void fetchAllowableUnitSelections();
return () => {
disposed = true;
};
}, [index, label, name, parentUnitName, translate, unitsProvider]);
const handleOnUnitChange = React.useCallback((newValue) => {
onUnitChange(newValue, index);
}, [index, onUnitChange]);
const handleOnLabelChange = React.useCallback((e) => {
e.preventDefault();
onLabelChange(e.target.value, index);
}, [index, onLabelChange]);
return (_jsxs(_Fragment, { children: [_jsx(Select, { options: unitOptions, "data-testid": `unit-${currentUnit.name}`, value: `${currentUnit.name}:${currentUnit.label}`, onChange: handleOnUnitChange, disabled: readonly, size: "small" }), _jsx(Input, { "data-testid": `unit-label-${currentUnit.name}`, value: label, onChange: handleOnLabelChange, size: "small" })] }));
}
//# sourceMappingURL=UnitDescr.js.map