OptionsSelector.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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. import DropdownButton from 'react-bootstrap/es/DropdownButton';
  8. import MenuItem from 'react-bootstrap/es/MenuItem';
  9. export default class OptionsSelector extends React.Component {
  10. constructor(props) {
  11. super(props);
  12. this.state = {
  13. editorOptions: this.props.editorOptions || new EditorOptions(),
  14. previewOptions: this.props.previewOptions || new PreviewOptions(),
  15. }
  16. this.availableThemes = [
  17. 'elegant', 'neo', 'mdn-like', 'material', 'monokai', 'twilight'
  18. ]
  19. this.onChangeTheme = this.onChangeTheme.bind(this);
  20. this.onClickStyleActiveLine = this.onClickStyleActiveLine.bind(this);
  21. this.onClickRenderMathJaxInRealtime = this.onClickRenderMathJaxInRealtime.bind(this);
  22. }
  23. componentDidMount() {
  24. this.init();
  25. }
  26. init() {
  27. this.themeSelectorInputEl.value = this.state.editorOptions.theme;
  28. }
  29. onChangeTheme() {
  30. const newValue = this.themeSelectorInputEl.value;
  31. const newOpts = Object.assign(this.state.editorOptions, {theme: newValue});
  32. this.setState({editorOptions: newOpts});
  33. // dispatch event
  34. this.dispatchOnChange();
  35. }
  36. onClickStyleActiveLine(event) {
  37. const newValue = !this.state.editorOptions.styleActiveLine;
  38. const newOpts = Object.assign(this.state.editorOptions, {styleActiveLine: newValue});
  39. this.setState({editorOptions: newOpts});
  40. // dispatch event
  41. this.dispatchOnChange();
  42. }
  43. onClickRenderMathJaxInRealtime(event) {
  44. const newValue = !this.state.previewOptions.renderMathJaxInRealtime;
  45. const newOpts = Object.assign(this.state.previewOptions, {renderMathJaxInRealtime: newValue});
  46. this.setState({previewOptions: newOpts});
  47. // dispatch event
  48. this.dispatchOnChange();
  49. }
  50. dispatchOnChange() {
  51. if (this.props.onChange != null) {
  52. this.props.onChange(this.state.editorOptions, this.state.previewOptions);
  53. }
  54. }
  55. renderThemeSelector() {
  56. const optionElems = this.availableThemes.map((theme) => {
  57. return <option key={theme} value={theme}>{theme}</option>;
  58. });
  59. return (
  60. <FormGroup controlId="formControlsSelect">
  61. <ControlLabel>Theme:</ControlLabel>
  62. <FormControl componentClass="select" placeholder="select"
  63. onChange={this.onChangeTheme}
  64. inputRef={ el => this.themeSelectorInputEl=el }>
  65. {optionElems}
  66. </FormControl>
  67. </FormGroup>
  68. )
  69. }
  70. renderStyleActiveLineSelector() {
  71. const bool = this.state.editorOptions.styleActiveLine;
  72. return (
  73. <FormGroup controlId="formControlsSelect">
  74. <Button active={bool} className="btn-style-active-line"
  75. onClick={this.onClickStyleActiveLine}>
  76. Active Line
  77. </Button>
  78. </FormGroup>
  79. )
  80. }
  81. renderRealtimeMathJaxSelector() {
  82. const bool = this.state.previewOptions.renderMathJaxInRealtime;
  83. return (
  84. <FormGroup controlId="formControlsSelect">
  85. <Button active={bool} className="btn-render-mathjax-in-realtime"
  86. onClick={this.onClickRenderMathJaxInRealtime}>
  87. <i className="fa fa-superscript" aria-hidden="true"></i>
  88. </Button>
  89. </FormGroup>
  90. )
  91. }
  92. render() {
  93. return <span>{this.renderThemeSelector()} {this.renderStyleActiveLineSelector()} {this.renderRealtimeMathJaxSelector()}</span>
  94. }
  95. }
  96. export class EditorOptions {
  97. constructor(props) {
  98. this.theme = 'elegant';
  99. this.styleActiveLine = false;
  100. Object.assign(this, props);
  101. }
  102. }
  103. export class PreviewOptions {
  104. constructor(props) {
  105. this.renderMathJaxInRealtime = false;
  106. Object.assign(this, props);
  107. }
  108. }
  109. OptionsSelector.propTypes = {
  110. editorOptions: PropTypes.instanceOf(EditorOptions),
  111. previewOptions: PropTypes.instanceOf(PreviewOptions),
  112. onChange: PropTypes.func,
  113. };