packageDocumentation module import "./NumericInputEditor.scss" ; import classnames from "classnames" ; import * as React from "react" ; import { InputEditorSizeParams , PropertyEditorParams , PropertyEditorParamTypes , PropertyValue , PropertyValueFormat , RangeEditorParams , StandardEditorNames , StandardTypeNames , } from "@itwin/appui-abstract" ; import { NumberInput } from "@itwin/core-react" ; import { PropertyEditorProps , TypeEditor } from "./EditorContainer" ; import { PropertyEditorBase , PropertyEditorManager } from "./PropertyEditorManager" ; internal interface NumericInputEditorState { value : number ; readonly : boolean ; isDisabled ? : boolean ; size ? : number ; maxLength ? : number ; min ? : number ; max ? : number ; step ? : number ; precision ? : number ; } public export class NumericInputEditor extends React . PureComponent < PropertyEditorProps , NumericInputEditorState > implements TypeEditor { private _isMounted = false ; private _inputElement : React . RefObject < HTMLInputElement > = React . createRef ( ) ; public hasFocus = false ; internal public override readonly state : Readonly < NumericInputEditorState > = { value : 0 , readonly : false } ; public async getPropertyValue ( ) { const record = this . props . propertyRecord ; let propertyValue ; if ( record && record . value . valueFormat === PropertyValueFormat . Primitive ) { propertyValue = { valueFormat : PropertyValueFormat . Primitive , value : this . state . value , displayValue : "" } ; } return propertyValue ; } public get htmlElement ( ) : HTMLElement | null { return this . _inputElement . current ; } private _handleCommit = async ( ) : Promise < void > => { if ( this . props . propertyRecord && this . props . onCommit ) { const propertyValue = await this . getPropertyValue ( ) ; if ( propertyValue !== undefined ) { this . props . onCommit ( { propertyRecord : this . props . propertyRecord , newValue : propertyValue } ) ; } } } ; private _updateValue = ( value , _stringValue ) : void => { const newValue = value !== undefined ? value : 0 ; if ( this . _isMounted ) this . setState ( { value : newValue } , async ( ) => { await this . _handleCommit ( ) ; } ) ; } ; internal public override componentDidMount ( ) { this . _isMounted = true ; this . setStateFromProps ( ) ; } internal public override componentWillUnmount ( ) { this . _isMounted = false ; } internal public override componentDidUpdate ( prevProps ) { if ( this . props . propertyRecord !== prevProps . propertyRecord ) { this . setStateFromProps ( ) ; } } private async setStateFromProps ( ) { const record = this . props . propertyRecord ; let initialValue = 0 ; if ( record && record . value . valueFormat === PropertyValueFormat . Primitive ) { initialValue = record . value . value as number ; } const readonly = record && undefined !== record . isReadonly ? record . isReadonly : false ; let size ; let maxLength ; let min ; let max ; let step ; let precision ; const isDisabled = record ? record . isDisabled : undefined ; if ( record && record . property && record . property . editor && record . property . editor . params ) { const editorSizeParams = record . property . editor . params . find ( ( param ) => param . type === PropertyEditorParamTypes . InputEditorSize ) as InputEditorSizeParams ; if ( editorSizeParams ) { if ( editorSizeParams . size ) size = editorSizeParams . size ; if ( editorSizeParams . maxLength ) maxLength = editorSizeParams . maxLength ; } const rangeParams = record . property . editor . params . find ( ( param ) => param . type === PropertyEditorParamTypes . Range ) as RangeEditorParams ; if ( rangeParams ) { min = rangeParams . minimum ; max = rangeParams . maximum ; step = rangeParams . step ; precision = rangeParams . precision ; } } if ( this . _isMounted ) this . setState ( { value : initialValue , readonly , size , maxLength , isDisabled , min , max , step , precision } ) ; } internal public override render ( ) { const className = classnames ( "components-cell-editor" , "components-numeric-input-editor" , this . props . className ) ; const minSize = this . state . size ? this . state . size : 8 ; const style = { ... this . props . style , minWidth : `${ minSize * 0.75 }em` } ; return ( < NumberInput ref = { this . _inputElement } className = { className } style = { style } value = { this . state . value } min = { this . state . min } max = { this . state . max } step = { this . state . step } precision = { this . state . precision } readOnly = { this . state . readonly } maxLength = { this . state . maxLength } onBlur = { this . props . onBlur } onChange = { this . _updateValue } setFocus = { this . props . setFocus && ! this . state . isDisabled } / > ) ; } } public export class NumericInputPropertyEditor extends PropertyEditorBase { public get reactNode ( ) : React . ReactNode { return < NumericInputEditor />; } public override get containerHandlesEnter ( ) : boolean { return false ; } } PropertyEditorManager . registerEditor ( StandardTypeNames . Number , NumericInputPropertyEditor , StandardEditorNames . NumericInput ) ; PropertyEditorManager . registerEditor ( StandardTypeNames . Int , NumericInputPropertyEditor , StandardEditorNames . NumericInput ) ; PropertyEditorManager . registerEditor ( StandardTypeNames . Float , NumericInputPropertyEditor , StandardEditorNames . NumericInput ) ; PropertyEditorManager . registerEditor ( StandardTypeNames . Double , NumericInputPropertyEditor , StandardEditorNames . NumericInput ) ;