packageDocumentation module import * as React from "react" ; import { CustomFormatPropEditorSpec , getQuantityTypeKey , IModelApp , isCheckboxFormatPropEditorSpec , isCustomQuantityTypeDefinition , isTextInputFormatPropEditorSpec , isTextSelectFormatPropEditorSpec , QuantityTypeArg , } from "@itwin/core-frontend" ; import { FormatProps , UnitProps , UnitsProvider } from "@itwin/core-quantity" ; import { CommonProps , Select } from "@itwin/core-react" ; import { Checkbox , Input } from "@itwin/itwinui-react" ; import { FormatPanel } from "./FormatPanel" ; import { DeepCompare } from "@itwin/core-geometry" ; function createTextInputFormatPropEditor ( key , label , inProps , getString , setString , fireFormatChange ) { const value = getString ( inProps ) ; return ( < React . Fragment key = { `${ key }` } > < span key = { `${ key }-label` } className = { "uicore-label" } > { label } < /span> < Input data - testid = { `${ key }-editor` } key = { `${ key }-editor` } value = { value } size = "small" onChange = { ( e ) => { const newProps = setString ( inProps , e . currentTarget . value ) ; fireFormatChange ( newProps ) ; } } /> < /React.Fragment>); } function createSelectFormatPropEditor ( key , label , options , inProps , getString , setString , fireFormatChange ) { const value = getString ( inProps ) ; return ( < React . Fragment key = { `${ key }` } > < span key = { `${ key }-label` } className = { "uicore-label" } > { label } < /span> { } { } < Select data - testid = { `${ key }-editor` } key = { `${ key }-editor` } value = { value } options = { options } onChange = { ( e ) => { const newProps = setString ( inProps , e . currentTarget . value ) ; fireFormatChange ( newProps ) ; } } /> < /React.Fragment>); } function createCheckboxFormatPropEditor ( key , label , inProps , getBool , setBool , fireFormatChange ) { const isChecked = getBool ( inProps ) ; return ( < React . Fragment key = { `${ key }` } > < span key = { `${ key }-label` } className = { "uicore-label" } > { label } < /span> < Checkbox data - testid = { `${ key }-editor` } key = { `${ key }-editor` } checked = { isChecked } onChange = { ( e ) => { const newProps = setBool ( inProps , e . target . checked ) ; fireFormatChange ( newProps ) ; } } /> < /React.Fragment>); } function formatAreEqual ( obj1 , obj2 ) { const compare = new DeepCompare ( ) ; return compare . compare ( obj1 , obj2 ) ; } alpha export interface QuantityFormatPanelProps extends CommonProps { quantityType : QuantityTypeArg ; onFormatChange ? : ( format : FormatProps ) => void ; /** props below are to be passed on to FormatPanel */ showSample ? : boolean ; initialMagnitude ? : number ; enableMinimumProperties ? : boolean ; } alpha export function QuantityFormatPanel ( props ) { const { quantityType , onFormatChange , ... otherProps } = props ; const [ formatProps , setFormatProps ] = React . useState < FormatProps > ( ) ; const initialFormatProps = React . useRef < FormatProps > ( ) ; const [ persistenceUnit , setPersistenceUnit ] = React . useState ( ( ) => { const quantityTypeKey = getQuantityTypeKey ( quantityType ) ; const quantityTypeDefinition = IModelApp . quantityFormatter . quantityTypesRegistry . get ( quantityTypeKey ) ; if ( quantityTypeDefinition ) return quantityTypeDefinition . persistenceUnit ; else throw Error ( `Unable to locate a quantity type with type ${ quantityType }` ) ; } ) ; React . useEffect ( ( ) => { const newFormatProps = IModelApp . quantityFormatter . getFormatPropsByQuantityType ( quantityType ) ; if ( ! initialFormatProps . current ) initialFormatProps . current = newFormatProps ; setFormatProps ( newFormatProps ) ; } , [ quantityType ] ) ; React . useEffect ( ( ) => { const newFormatProps = IModelApp . quantityFormatter . getFormatPropsByQuantityType ( quantityType ) ; if ( initialFormatProps . current && newFormatProps ) { if ( ! formatAreEqual ( newFormatProps , initialFormatProps . current ) ) { initialFormatProps . current = newFormatProps ; setFormatProps ( newFormatProps ) ; } } } ) ; React . useEffect ( ( ) => { const quantityTypeKey = getQuantityTypeKey ( quantityType ) ; const quantityTypeDefinition = IModelApp . quantityFormatter . quantityTypesRegistry . get ( quantityTypeKey ) ; if ( quantityTypeDefinition ) setPersistenceUnit ( quantityTypeDefinition . persistenceUnit ) ; } , [ quantityType ] ) ; const handleOnFormatChanged = React . useCallback ( async ( newProps ) => { setFormatProps ( newProps ) ; onFormatChange && onFormatChange ( newProps ) ; } , [ onFormatChange ] ) ; const createCustomPropEditors = React . useCallback ( ( specs , inProps , fireFormatChange ) => { return specs . map ( ( spec , index ) => { if ( isCheckboxFormatPropEditorSpec ( spec ) ) return createCheckboxFormatPropEditor ( `${ spec . editorType }-${ index }` , spec . label , inProps , spec . getBool , spec . setBool , fireFormatChange ) ; if ( isTextSelectFormatPropEditorSpec ( spec ) ) return createSelectFormatPropEditor ( `${ spec . editorType }-${ index }` , spec . label , spec . selectOptions , inProps , spec . getString , spec . setString , fireFormatChange ) ; if ( isTextInputFormatPropEditorSpec ( spec ) ) return createTextInputFormatPropEditor ( `${ spec . editorType }-${ index }` , spec . label , inProps , spec . getString , spec . setString , fireFormatChange ) ; return < div key = { index } />; } ) ; } , [ ] ) ; const providePrimaryChildren = React . useCallback ( ( inProps , fireFormatChange ) => { const quantityTypeKey = getQuantityTypeKey ( quantityType ) ; const quantityTypeDefinition = IModelApp . quantityFormatter . quantityTypesRegistry . get ( quantityTypeKey ) ; if ( quantityTypeDefinition && isCustomQuantityTypeDefinition ( quantityTypeDefinition ) && quantityTypeDefinition . isCompatibleFormatProps ( inProps ) ) { if ( quantityTypeDefinition . primaryPropEditorSpecs ) return createCustomPropEditors ( quantityTypeDefinition . primaryPropEditorSpecs , inProps , fireFormatChange ) ; } return null ; } , [ createCustomPropEditors , quantityType ] ) ; const provideSecondaryChildren = React . useCallback ( ( inProps , fireFormatChange ) => { const quantityTypeKey = getQuantityTypeKey ( quantityType ) ; const quantityTypeDefinition = IModelApp . quantityFormatter . quantityTypesRegistry . get ( quantityTypeKey ) ; if ( quantityTypeDefinition && isCustomQuantityTypeDefinition ( quantityTypeDefinition ) && quantityTypeDefinition . isCompatibleFormatProps ( inProps ) ) { if ( quantityTypeDefinition . secondaryPropEditorSpecs ) return createCustomPropEditors ( quantityTypeDefinition . secondaryPropEditorSpecs , inProps , fireFormatChange ) ; } return null ; } , [ createCustomPropEditors , quantityType ] ) ; const provideFormatSpec = React . useCallback ( async ( inProps , _persistenceUnit , _unitsProvider ) => { return IModelApp . quantityFormatter . generateFormatterSpecByType ( quantityType , inProps ) ; } , [ quantityType ] ) ; return ( < div className = "components-quantityFormat-quantityPanel" > { persistenceUnit && formatProps && < FormatPanel onFormatChange = { handleOnFormatChanged } { ... otherProps } initialFormat = { formatProps } unitsProvider = { IModelApp . quantityFormatter . unitsProvider } persistenceUnit = { persistenceUnit } providePrimaryChildren = { providePrimaryChildren } provideSecondaryChildren = { provideSecondaryChildren } provideFormatSpec = { provideFormatSpec } / > } < /div>); }