numericInputComponent.tsx 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import * as React from "react";
  2. import { GlobalState } from '../globalState';
  3. interface INumericInputComponentProps {
  4. label: string;
  5. value: number;
  6. step?: number;
  7. onChange: (value: number) => void;
  8. globalState: GlobalState;
  9. }
  10. export class NumericInputComponent extends React.Component<INumericInputComponentProps, { value: string }> {
  11. static defaultProps = {
  12. step: 1,
  13. };
  14. private _localChange = false;
  15. constructor(props: INumericInputComponentProps) {
  16. super(props);
  17. this.state = { value: this.props.value.toFixed(3) }
  18. }
  19. shouldComponentUpdate(nextProps: INumericInputComponentProps, nextState: { value: string }) {
  20. if (this._localChange) {
  21. this._localChange = false;
  22. return true;
  23. }
  24. if (nextProps.value.toString() !== nextState.value) {
  25. nextState.value = nextProps.value.toFixed(3);
  26. return true;
  27. }
  28. return false;
  29. }
  30. updateValue(evt: any) {
  31. let value = evt.target.value;
  32. if (/[^0-9\.\-]/g.test(value)) {
  33. return;
  34. }
  35. let valueAsNumber = parseFloat(value);
  36. this._localChange = true;
  37. this.setState({ value: value });
  38. if (isNaN(valueAsNumber)) {
  39. return;
  40. }
  41. this.props.onChange(valueAsNumber);
  42. }
  43. render() {
  44. return (
  45. <div className="numeric">
  46. {
  47. this.props.label &&
  48. <div className="numeric-label" title={this.props.label}>
  49. {`${this.props.label}: `}
  50. </div>
  51. }
  52. <input type="number"
  53. onFocus={() => this.props.globalState.blockKeyboardEvents = true}
  54. onBlur={evt => {
  55. this.props.globalState.blockKeyboardEvents = false;
  56. }}
  57. step={this.props.step} className="numeric-input" value={this.state.value} onChange={evt => this.updateValue(evt)} />
  58. </div>
  59. )
  60. }
  61. }