From 737a271b3eb60b20f3b40b47395e803d0104af62 Mon Sep 17 00:00:00 2001 From: Jonathan Olson Date: Sat, 5 Mar 2022 13:47:57 -0700 Subject: [PATCH] TypeScript conversion for Panel, ComboBox (and assorted types), see https://github.com/phetsims/scenery-phet/issues/726 --- ...NumberControl.js => ComboNumberControl.ts} | 105 +++++++++--------- 1 file changed, 50 insertions(+), 55 deletions(-) rename js/common/view/{ComboNumberControl.js => ComboNumberControl.ts} (72%) diff --git a/js/common/view/ComboNumberControl.js b/js/common/view/ComboNumberControl.ts similarity index 72% rename from js/common/view/ComboNumberControl.js rename to js/common/view/ComboNumberControl.ts index bee9253e..ed445f9b 100644 --- a/js/common/view/ComboNumberControl.js +++ b/js/common/view/ComboNumberControl.ts @@ -12,58 +12,64 @@ import Property from '../../../../axon/js/Property.js'; import Dimension2 from '../../../../dot/js/Dimension2.js'; import Range from '../../../../dot/js/Range.js'; import merge from '../../../../phet-core/js/merge.js'; +import optionize from '../../../../phet-core/js/optionize.js'; import StringUtils from '../../../../phetcommon/js/util/StringUtils.js'; -import NumberControl from '../../../../scenery-phet/js/NumberControl.js'; +import NumberControl, { NumberControlOptions } from '../../../../scenery-phet/js/NumberControl.js'; import PhetFont from '../../../../scenery-phet/js/PhetFont.js'; -import { Node } from '../../../../scenery/js/imports.js'; +import { Node, VBoxOptions } from '../../../../scenery/js/imports.js'; import { Text } from '../../../../scenery/js/imports.js'; import { VBox } from '../../../../scenery/js/imports.js'; -import ComboBox from '../../../../sun/js/ComboBox.js'; +import ComboBox, { ComboBoxOptions } from '../../../../sun/js/ComboBox.js'; +import ComboBoxItem from '../../../../sun/js/ComboBoxItem.js'; import SunConstants from '../../../../sun/js/SunConstants.js'; import densityBuoyancyCommon from '../../densityBuoyancyCommon.js'; import DensityBuoyancyCommonConstants from '../DensityBuoyancyCommonConstants.js'; -class ComboNumberControl extends VBox { - /** - * @param {Object} config - */ - constructor( config ) { +type SelfOptions = { + title: string; + valuePattern: string; // with {{value}} placeholder + property: Property; + range: Range; - const disposalCallbacks = []; - const numberDisplayVisibleProperty = new BooleanProperty( true ); + // Converts the Property values into numeric values + toNumericValue: ( t: T ) => number; - config = merge( { - // {string} - required - title: null, + // Given a numeric value, creates the corresponding rich object + createCustomValue: ( n: number ) => T; - // {string} - required, with {{value}} placeholder - valuePattern: null, + // Given a main value, returns whether it is a custom value or not + isCustomValue: ( t: T ) => boolean; - // {Property.<*>} - required - property: null, + listParent: Node; - // {Range} - required - range: null, + comboItems: ComboBoxItem[]; - // {function(*):number} - Converts the Property values into numeric values - toNumericValue: null, + // The token value in items that is the designated custom value + customValue: T; - // {function(number):*} - Given a numeric value, creates the corresponding rich object - createCustomValue: null, + getFallbackNode?: ( t: T ) => Node | null; - // {function(*):boolean} - Given a main value, returns whether it is a custom value or not - isCustomValue: null, + numberControlOptions?: NumberControlOptions; + comboBoxOptions?: ComboBoxOptions; +}; - // {Node} - required - listParent: null, +export type ComboNumberControlOptions = SelfOptions & VBoxOptions; - // {Array.} - See ComboBox's items - comboItems: null, +class ComboNumberControl extends VBox { - // {*} - The token value in items that is the designated custom value - customValue: null, + private property: Property; + private numberProperty: Property; + private comboProperty: Property; + private disposalCallbacks: ( () => void )[]; + private numberControl: NumberControl; + private comboBox: ComboBox; + + constructor( providedConfig: SelfOptions ) { + + const disposalCallbacks: ( () => void )[] = []; + const numberDisplayVisibleProperty = new BooleanProperty( true ); - // {function(*):Node|null} + const config = optionize, SelfOptions, VBoxOptions>( { getFallbackNode: () => null, // {Object} Options for the number control @@ -81,8 +87,8 @@ class ComboNumberControl extends VBox { ] } ); - const listener = value => { - const fallbackNode = config.getFallbackNode( value ); + const listener = ( value: T ) => { + const fallbackNode = getFallbackNode( value ); const hasFallback = fallbackNode !== null; bottomBox.visible = !hasFallback; @@ -111,7 +117,7 @@ class ComboNumberControl extends VBox { textOptions: { font: DensityBuoyancyCommonConstants.READOUT_FONT }, - valuePattern: StringUtils.fillIn( config.valuePattern, { value: SunConstants.VALUE_NAMED_PLACEHOLDER } ), + valuePattern: StringUtils.fillIn( providedConfig.valuePattern, { value: SunConstants.VALUE_NAMED_PLACEHOLDER } ), maxWidth: 100, decimalPlaces: 2, useRichText: true, @@ -126,19 +132,16 @@ class ComboNumberControl extends VBox { thumbTouchAreaXDilation: 5, thumbTouchAreaYDilation: 4, majorTicks: [ { - value: config.range.min, - label: new Text( config.range.min, { font: new PhetFont( 12 ), maxWidth: 50 } ) + value: providedConfig.range.min, + label: new Text( providedConfig.range.min, { font: new PhetFont( 12 ), maxWidth: 50 } ) }, { - value: config.range.max, - label: new Text( config.range.max, { font: new PhetFont( 12 ), maxWidth: 50 } ) + value: providedConfig.range.max, + label: new Text( providedConfig.range.max, { font: new PhetFont( 12 ), maxWidth: 50 } ) } ], trackSize: new Dimension2( 120, 0.5 ) } }, - // {Object} Options for the number control - numberControlLayoutOptions: null, - // {Object} Options for the combo box comboBoxOptions: { cornerRadius: 3, @@ -149,7 +152,7 @@ class ComboNumberControl extends VBox { // VBox options spacing: 10, align: 'center' - }, config ); + }, providedConfig ); assert && assert( !config.children, 'Children should not be specified for ComboNumberControl' ); assert && assert( typeof config.title === 'string' ); @@ -162,21 +165,16 @@ class ComboNumberControl extends VBox { assert && assert( Array.isArray( config.comboItems ) ); assert && assert( config.customValue ); + const getFallbackNode = config.getFallbackNode; + super(); - const getNumericValue = value => config.toNumericValue( value ); - const getComboValue = value => config.isCustomValue( value ) ? config.customValue : value; + const getNumericValue = ( value: T ) => config.toNumericValue( value ); + const getComboValue = ( value: T ) => config.isCustomValue( value ) ? config.customValue : value; - // @private {Property.<*>} this.property = config.property; - - // @private {Property.} this.numberProperty = new NumberProperty( getNumericValue( this.property.value ) ); - - // @private {Property.<*>} this.comboProperty = new Property( getComboValue( this.property.value ) ); - - // @private {Array.} this.disposalCallbacks = disposalCallbacks; let locked = false; @@ -217,14 +215,12 @@ class ComboNumberControl extends VBox { } } ); - // @private {NumberControl} this.numberControl = new NumberControl( config.title, this.numberProperty, config.range, merge( { sliderOptions: { phetioLinkedProperty: this.property } }, config.numberControlOptions ) ); - // @private {ComboBox} this.comboBox = new ComboBox( config.comboItems, this.comboProperty, config.listParent, config.comboBoxOptions ); config.children = [ @@ -237,7 +233,6 @@ class ComboNumberControl extends VBox { /** * Releases references. - * @public */ dispose() { this.numberControl.dispose();