UNPKG

@itwin/quantity-formatting-react

Version:

React components and utilities for quantity formatting

107 lines 5.5 kB
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