2
0

OptionsSelector.js 4.5 KB

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