import * as React from 'react' ; import * as ReactDom from 'react-dom' ; import { IPropertyPaneField , PropertyPaneFieldType } from '@microsoft/sp-webpart-base' ; import { IPropertyFieldSpinButtonProps , IPropertyFieldSpinButtonPropsInternal } from './IPropertyFieldSpinButton' ; import { IPropertyFieldSpinButtonHostProps } from './IPropertyFieldSpinButtonHost' ; import PropertyFieldSpinButtonHost from './PropertyFieldSpinButtonHost' ; import { setPropertyValue } from '../../helpers/GeneralHelper' ; class PropertyFieldSpinButtonBuilder implements IPropertyPaneField < IPropertyFieldSpinButtonProps > { public type : PropertyPaneFieldType = PropertyPaneFieldType . Custom ; public targetProperty : string ; public properties : IPropertyFieldSpinButtonPropsInternal ; private elem : HTMLElement ; private svalue : number ; private changeCB ? : ( targetProperty ? : string , newValue ? : any ) => void ; public constructor ( _targetProperty , _properties ) { this . targetProperty = _targetProperty ; this . properties = { key : _properties . key , label : _properties . label , step : _properties . step || 1 , min : _properties . min , max : _properties . max , onPropertyChange : _properties . onPropertyChange , disabled : _properties . disabled , properties : _properties . properties , incrementIconName : _properties . incrementIconName , decrementIconName : _properties . decrementIconName , suffix : _properties . suffix , decimalPlaces : _properties . decimalPlaces || 0 , onRender : this . onRender . bind ( this ) } ; this . svalue = _properties . initialValue || this . properties . min || 0 ; } public render ( ) { if ( ! this . elem ) { return ; } this . onRender ( this . elem ) ; } private onRender ( elem , ctx ? , changeCallback ? ) { if ( ! this . elem ) { this . elem = elem ; } this . changeCB = changeCallback ; const element = React . createElement ( PropertyFieldSpinButtonHost , { label : this . properties . label , disabled : this . properties . disabled , value : this . formatValueString ( this . svalue ) , incrementIconName : this . properties . incrementIconName || 'ChevronUpSmall' , decrementIconName : this . properties . decrementIconName || 'ChevronDownSmall' , onValidate : this . validate . bind ( this ) , onIncrement : this . increment . bind ( this ) , onDecrement : this . decrement . bind ( this ) } ) ; ReactDom . render ( element , elem ) ; } private validate ( rawValue ) { let numValue = this . extractNumValue ( rawValue ) ; return this . validateNumber ( numValue ) ; } private validateNumber ( numValue ) { if ( typeof this . properties . max !== "undefined" && numValue > this . properties . max ) { numValue = this . properties . max ; } if ( typeof this . properties . min !== "undefined" && numValue < this . properties . min ) { numValue = this . properties . min ; } numValue = + numValue . toFixed ( this . properties . decimalPlaces ) ; if ( numValue !== this . svalue ) { this . onValueChanged ( numValue ) ; } return this . formatValueString ( numValue ) ; } private increment ( rawValue ) { let numValue = this . extractNumValue ( rawValue ) ; numValue += this . properties . step ; return this . validateNumber ( numValue ) ; } private decrement ( rawValue ) { let numValue = this . extractNumValue ( rawValue ) ; numValue -= this . properties . step ; return this . validateNumber ( numValue ) ; } private extractNumValue ( rawValue ) { let numValue ; let baseValue = this . removeSuffix ( rawValue ) ; if ( isNaN ( + baseValue ) ) { if ( this . properties . min ) { numValue = Math . max ( this . properties . min , 0 ) ; } else { numValue = 0 ; } } else { numValue = + baseValue ; } return numValue ; } private hasSuffix ( rawValue ) { if ( ! this . properties . suffix ) { return false ; } let subString = rawValue . substr ( rawValue . length - this . properties . suffix . length ) ; return subString === this . properties . suffix ; } private removeSuffix ( rawValue ) { if ( ! this . hasSuffix ( rawValue ) ) { return rawValue ; } return rawValue . substr ( 0 , rawValue . length - this . properties . suffix . length ) ; } private formatValueString ( numValue ) { return this . addSuffix ( numValue . toFixed ( this . properties . decimalPlaces ) ) ; } private addSuffix ( stringValue ) { if ( ! this . properties . suffix ) { return stringValue ; } return stringValue + this . properties . suffix ; } private onValueChanged ( newValue ) { if ( this . properties . onPropertyChange && newValue !== null ) { this . properties . onPropertyChange ( this . targetProperty , this . svalue , newValue ) ; this . svalue = newValue ; setPropertyValue ( this . properties . properties , this . targetProperty , newValue ) ; if ( typeof this . changeCB !== 'undefined' && this . changeCB !== null ) { this . changeCB ( this . targetProperty , newValue ) ; } } } } export function PropertyFieldSpinButton ( targetProperty , properties ) { return new PropertyFieldSpinButtonBuilder ( targetProperty , properties ) ; }