UNPKG

@itwin/presentation-components

Version:

React components based on iTwin.js Presentation library

97 lines 4.3 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ import { useEffect, useRef, useState } from "react"; import { assert } from "@itwin/core-bentley"; import { IModelApp } from "@itwin/core-frontend"; import { KoqPropertyValueFormatter } from "@itwin/presentation-common"; import { getPersistenceUnitRoundingError } from "./Utils.js"; const PLACEHOLDER_RAW_VALUE = 12.34; /** * Custom hook that manages state for quantity values input. * @internal */ export function useQuantityValueInput({ initialRawValue, schemaContext, koqName }) { const initialRawValueRef = useRef(initialRawValue); const [{ quantityValue, placeholder }, setState] = useState(() => ({ quantityValue: { rawValue: initialRawValueRef.current, formattedValue: "", roundingError: undefined, }, placeholder: "", })); const { formatter, parser } = useFormatterAndParser(koqName, schemaContext); useEffect(() => { if (!formatter || !parser) { return; } setState((prev) => { const newPlaceholder = formatter.applyFormatting(initialRawValueRef.current ?? PLACEHOLDER_RAW_VALUE); const newFormattedValue = prev.quantityValue.rawValue !== undefined ? formatter.applyFormatting(prev.quantityValue.rawValue) : ""; const roundingError = getPersistenceUnitRoundingError(newFormattedValue, parser); return { ...prev, quantityValue: { ...prev.quantityValue, formattedValue: newFormattedValue, roundingError, }, placeholder: newPlaceholder, }; }); }, [formatter, parser]); const onChange = (e) => { assert(parser !== undefined); // input should be disabled if parser is `undefined` const newValue = e.currentTarget.value; const parseResult = parser.parseToQuantityValue(newValue); const roundingError = getPersistenceUnitRoundingError(newValue, parser); setState((prev) => ({ ...prev, quantityValue: { formattedValue: newValue, rawValue: parseResult.ok ? parseResult.value : undefined, roundingError: parseResult.ok ? roundingError : undefined, }, })); }; return { quantityValue, inputProps: { onChange, placeholder, value: quantityValue.formattedValue, disabled: !formatter || !parser, }, }; } function useFormatterAndParser(koqName, schemaContext) { const [state, setState] = useState(); useEffect(() => { const findFormatterAndParser = async () => { // eslint-disable-next-line @typescript-eslint/no-deprecated const koqFormatter = new KoqPropertyValueFormatter(schemaContext, undefined, IModelApp.formatsProvider); const formatterSpec = await koqFormatter.getFormatterSpec({ koqName, unitSystem: IModelApp.quantityFormatter.activeUnitSystem }); const parserSpec = await koqFormatter.getParserSpec({ koqName, unitSystem: IModelApp.quantityFormatter.activeUnitSystem }); if (formatterSpec && parserSpec) { setState({ formatterSpec, parserSpec }); return; } setState(undefined); }; void findFormatterAndParser(); const listeners = [IModelApp.quantityFormatter.onActiveFormattingUnitSystemChanged.addListener(findFormatterAndParser)]; if (IModelApp.formatsProvider) { listeners.push(IModelApp.formatsProvider.onFormatsChanged.addListener(findFormatterAndParser)); } return () => { listeners.forEach((listener) => listener()); }; }, [koqName, schemaContext]); return { formatter: state?.formatterSpec, parser: state?.parserSpec, }; } //# sourceMappingURL=UseQuantityValueInput.js.map