textInputLineComponent.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import * as React from "react";
  2. import { Observable } from "babylonjs/Misc/observable";
  3. import { PropertyChangedEvent } from "./propertyChangedEvent";
  4. import { GlobalState } from '../globalState';
  5. interface ITextInputLineComponentProps {
  6. label: string;
  7. globalState: GlobalState;
  8. target?: any;
  9. propertyName?: string;
  10. value?: string;
  11. multilines?: boolean;
  12. onChange?: (value: string) => void;
  13. validator?: (value: string) => boolean;
  14. onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
  15. }
  16. export class TextInputLineComponent extends React.Component<ITextInputLineComponentProps, { value: string }> {
  17. private _localChange = false;
  18. constructor(props: ITextInputLineComponentProps) {
  19. super(props);
  20. this.state = { value: this.props.value !== undefined ? this.props.value : this.props.target[this.props.propertyName!] || "" };
  21. }
  22. shouldComponentUpdate(nextProps: ITextInputLineComponentProps, nextState: { value: string }) {
  23. if (this._localChange) {
  24. this._localChange = false;
  25. return true;
  26. }
  27. const newValue = nextProps.value !== undefined ? nextProps.value : nextProps.target[nextProps.propertyName!];
  28. if (newValue !== nextState.value) {
  29. nextState.value = newValue || "";
  30. return true;
  31. }
  32. return false;
  33. }
  34. raiseOnPropertyChanged(newValue: string, previousValue: string) {
  35. if (this.props.onChange) {
  36. this.props.onChange(newValue);
  37. return;
  38. }
  39. if (!this.props.onPropertyChangedObservable) {
  40. return;
  41. }
  42. this.props.onPropertyChangedObservable.notifyObservers({
  43. object: this.props.target,
  44. property: this.props.propertyName!,
  45. value: newValue,
  46. initialValue: previousValue
  47. });
  48. }
  49. updateValue(value: string, raisePropertyChanged: boolean) {
  50. this._localChange = true;
  51. const store = this.props.value !== undefined ? this.props.value : this.props.target[this.props.propertyName!];
  52. if (this.props.validator && raisePropertyChanged) {
  53. if (this.props.validator(value) == false) {
  54. value = store;
  55. }
  56. }
  57. this.setState({ value: value });
  58. if (raisePropertyChanged) {
  59. this.raiseOnPropertyChanged(value, store);
  60. }
  61. if (this.props.propertyName) {
  62. this.props.target[this.props.propertyName] = value;
  63. }
  64. }
  65. render() {
  66. return (
  67. <div className={this.props.multilines ? "textInputArea" : "textInputLine"}>
  68. <div className="label" title={this.props.label}>
  69. {this.props.label}
  70. </div>
  71. <div className="value">
  72. {this.props.multilines && <>
  73. <textarea value={this.state.value}
  74. onFocus={() => this.props.globalState.blockKeyboardEvents = true}
  75. onChange={(evt) => this.updateValue(evt.target.value, false)}
  76. onKeyDown={(evt) => {
  77. if (evt.keyCode !== 13) {
  78. return;
  79. }
  80. this.updateValue(this.state.value, true);
  81. }} onBlur={(evt) => {
  82. this.updateValue(evt.target.value, true);
  83. this.props.globalState.blockKeyboardEvents = false;
  84. }}/>
  85. </>}
  86. {!this.props.multilines && <>
  87. <input value={this.state.value}
  88. onFocus={() => this.props.globalState.blockKeyboardEvents = true}
  89. onChange={(evt) => this.updateValue(evt.target.value, false)}
  90. onKeyDown={(evt) => {
  91. if (evt.keyCode !== 13) {
  92. return;
  93. }
  94. this.updateValue(this.state.value, true);
  95. }} onBlur={(evt) => {
  96. this.updateValue(evt.target.value, true);
  97. this.props.globalState.blockKeyboardEvents = false;
  98. }}/>
  99. </>}
  100. </div>
  101. </div>
  102. );
  103. }
  104. }