floatLineComponent.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import * as React from "react";
  2. import { Observable } from "babylonjs/Misc/observable";
  3. import { PropertyChangedEvent } from "./propertyChangedEvent";
  4. interface IFloatLineComponentProps {
  5. label: string;
  6. target: any;
  7. propertyName: string;
  8. onChange?: (newValue: number) => void;
  9. isInteger?: boolean;
  10. onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
  11. additionalClass?: string;
  12. step?: string,
  13. digits?: number;
  14. }
  15. export class FloatLineComponent extends React.Component<IFloatLineComponentProps, { value: string }> {
  16. private _localChange = false;
  17. private _store: number;
  18. constructor(props: IFloatLineComponentProps) {
  19. super(props);
  20. let currentValue = this.props.target[this.props.propertyName];
  21. this.state = { value: currentValue ? (this.props.isInteger ? currentValue.toFixed(0) : currentValue.toFixed(this.props.digits || 3)) : "0" };
  22. this._store = currentValue;
  23. }
  24. shouldComponentUpdate(nextProps: IFloatLineComponentProps, nextState: { value: string }) {
  25. if (this._localChange) {
  26. this._localChange = false;
  27. return true;
  28. }
  29. const newValue = nextProps.target[nextProps.propertyName];
  30. const newValueString = newValue ? this.props.isInteger ? newValue.toFixed(0) : newValue.toFixed(this.props.digits || 3) : "0";
  31. if (newValueString !== nextState.value) {
  32. nextState.value = newValueString;
  33. return true;
  34. }
  35. return false;
  36. }
  37. raiseOnPropertyChanged(newValue: number, previousValue: number) {
  38. if (this.props.onChange) {
  39. this.props.onChange(newValue);
  40. }
  41. if (!this.props.onPropertyChangedObservable) {
  42. return;
  43. }
  44. this.props.onPropertyChangedObservable.notifyObservers({
  45. object: this.props.target,
  46. property: this.props.propertyName,
  47. value: newValue,
  48. initialValue: previousValue
  49. });
  50. }
  51. updateValue(valueString: string) {
  52. if (/[^0-9\.\-]/g.test(valueString)) {
  53. return;
  54. }
  55. let valueAsNumber: number;
  56. if (this.props.isInteger) {
  57. valueAsNumber = parseInt(valueString);
  58. } else {
  59. valueAsNumber = parseFloat(valueString);
  60. }
  61. this._localChange = true;
  62. this.setState({ value: valueString });
  63. if (isNaN(valueAsNumber)) {
  64. return;
  65. }
  66. this.raiseOnPropertyChanged(valueAsNumber, this._store);
  67. this.props.target[this.props.propertyName] = valueAsNumber;
  68. this._store = valueAsNumber;
  69. }
  70. render() {
  71. return (
  72. <div>
  73. {
  74. <div className={this.props.additionalClass ? this.props.additionalClass + " floatLine" : "floatLine"}>
  75. <div className="label">
  76. {this.props.label}
  77. </div>
  78. <div className="value">
  79. <input type="number" step={this.props.step || "0.01"} className="numeric-input" value={this.state.value} onChange={evt => this.updateValue(evt.target.value)} />
  80. </div>
  81. </div>
  82. }
  83. </div>
  84. );
  85. }
  86. }