optionsLineComponent.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import * as React from "react";
  2. import { Observable } from "babylonjs/Misc/observable";
  3. import { PropertyChangedEvent } from "./propertyChangedEvent";
  4. class ListLineOption {
  5. public label: string;
  6. public value: number | string;
  7. }
  8. interface IOptionsLineComponentProps {
  9. label: string,
  10. target: any,
  11. propertyName: string,
  12. options: ListLineOption[],
  13. noDirectUpdate?: boolean,
  14. onSelect?: (value: number | string) => void,
  15. onPropertyChangedObservable?: Observable<PropertyChangedEvent>,
  16. valuesAreStrings?: boolean
  17. }
  18. export class OptionsLineComponent extends React.Component<IOptionsLineComponentProps, { value: number | string }> {
  19. private _localChange = false;
  20. constructor(props: IOptionsLineComponentProps) {
  21. super(props);
  22. this.state = { value: props.target[props.propertyName] };
  23. }
  24. shouldComponentUpdate(nextProps: IOptionsLineComponentProps, nextState: { value: number }) {
  25. if (this._localChange) {
  26. this._localChange = false;
  27. return true;
  28. }
  29. const newValue = nextProps.target[nextProps.propertyName];
  30. if (newValue != null && newValue !== nextState.value) {
  31. nextState.value = newValue;
  32. return true;
  33. }
  34. return false;
  35. }
  36. raiseOnPropertyChanged(newValue: number | string, previousValue: number | string) {
  37. if (!this.props.onPropertyChangedObservable) {
  38. return;
  39. }
  40. this.props.onPropertyChangedObservable.notifyObservers({
  41. object: this.props.target,
  42. property: this.props.propertyName,
  43. value: newValue,
  44. initialValue: previousValue
  45. });
  46. }
  47. updateValue(valueString: string) {
  48. const value = this.props.valuesAreStrings ? valueString : parseInt(valueString);
  49. this._localChange = true;
  50. const store = this.state.value;
  51. if (!this.props.noDirectUpdate) {
  52. this.props.target[this.props.propertyName] = value;
  53. }
  54. this.setState({ value: value });
  55. this.raiseOnPropertyChanged(value, store);
  56. if (this.props.onSelect) {
  57. this.props.onSelect(value);
  58. }
  59. }
  60. render() {
  61. return (
  62. <div className="listLine">
  63. <div className="label">
  64. {this.props.label}
  65. </div>
  66. <div className="options">
  67. <select onChange={evt => this.updateValue(evt.target.value)} value={this.state.value}>
  68. {
  69. this.props.options.map(option => {
  70. return (
  71. <option key={option.label} value={option.value}>{option.label}</option>
  72. )
  73. })
  74. }
  75. </select>
  76. </div>
  77. </div>
  78. );
  79. }
  80. }