EditorOptionsSelector.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import FormGroup from 'react-bootstrap/es/FormGroup';
  4. import FormControl from 'react-bootstrap/es/FormControl';
  5. import ControlLabel from 'react-bootstrap/es/ControlLabel';
  6. import Button from 'react-bootstrap/es/Button';
  7. export class EditorOptions {
  8. constructor(props) {
  9. this.theme = 'elegant';
  10. this.styleActiveLine = false;
  11. Object.assign(this, props);
  12. }
  13. }
  14. export class PreviewOptions {
  15. constructor(props) {
  16. this.renderMathJaxInRealtime = false;
  17. Object.assign(this, props);
  18. }
  19. }
  20. export default class EditorOptionsSelector extends React.Component {
  21. constructor(props) {
  22. super(props);
  23. this.state = {
  24. editorOptions: this.props.editorOptions || new EditorOptions(),
  25. previewOptions: this.props.previewOptions || new PreviewOptions(),
  26. }
  27. this.availableThemes = [
  28. 'elegant', 'neo', 'mdn-like', 'material', 'monokai', 'twilight'
  29. ]
  30. this.onChangeTheme = this.onChangeTheme.bind(this);
  31. this.onClickStyleActiveLine = this.onClickStyleActiveLine.bind(this);
  32. }
  33. componentDidMount() {
  34. this.init();
  35. }
  36. init() {
  37. this.themeSelectorInputEl.value = this.state.editorOptions.theme;
  38. }
  39. onChangeTheme() {
  40. const newValue = this.themeSelectorInputEl.value;
  41. const newOpts = Object.assign(this.state.editorOptions, {theme: newValue});
  42. this.setState({editorOptions: newOpts});
  43. // dispatch event
  44. this.dispatchOnChange();
  45. }
  46. onClickStyleActiveLine(event) {
  47. const newValue = !this.state.editorOptions.styleActiveLine;
  48. const newOpts = Object.assign(this.state.editorOptions, {styleActiveLine: newValue});
  49. this.setState({editorOptions: newOpts});
  50. // dispatch event
  51. this.dispatchOnChange();
  52. }
  53. dispatchOnChange() {
  54. if (this.props.onChange != null) {
  55. this.props.onChange(this.state.editorOptions, this.state.previewOptions);
  56. }
  57. }
  58. renderThemeSelector() {
  59. const optionElems = this.availableThemes.map((theme) => {
  60. return <option key={theme} value={theme}>{theme}</option>;
  61. });
  62. return (
  63. <FormGroup controlId="formControlsSelect">
  64. <ControlLabel>Theme:</ControlLabel>
  65. <FormControl componentClass="select" placeholder="select"
  66. onChange={this.onChangeTheme}
  67. inputRef={ el => this.themeSelectorInputEl=el }>
  68. {optionElems}
  69. </FormControl>
  70. </FormGroup>
  71. )
  72. }
  73. renderStyleActiveLineSelector() {
  74. const bool = this.state.editorOptions.styleActiveLine || false;
  75. return (
  76. <FormGroup controlId="formControlsSelect">
  77. <Button active={bool} className="btn-style-active-line"
  78. onClick={this.onClickStyleActiveLine}
  79. ref="styleActiveLineButton">
  80. Active Line
  81. </Button>
  82. </FormGroup>
  83. )
  84. }
  85. render() {
  86. return <span>{this.renderThemeSelector()} {this.renderStyleActiveLineSelector()}</span>
  87. }
  88. }
  89. EditorOptionsSelector.propTypes = {
  90. editorOptions: PropTypes.instanceOf(EditorOptions),
  91. previewOptions: PropTypes.instanceOf(PreviewOptions),
  92. onChange: PropTypes.func,
  93. };