import React from 'react';
import PropTypes from 'prop-types';
import FormGroup from 'react-bootstrap/es/FormGroup';
import FormControl from 'react-bootstrap/es/FormControl';
import ControlLabel from 'react-bootstrap/es/ControlLabel';
import Dropdown from 'react-bootstrap/es/Dropdown';
import MenuItem from 'react-bootstrap/es/MenuItem';
export default class OptionsSelector extends React.Component {
constructor(props) {
super(props);
const config = this.props.crowi.getConfig();
const isMathJaxEnabled = !!config.env.MATHJAX;
this.state = {
editorOptions: this.props.editorOptions || new EditorOptions(),
previewOptions: this.props.previewOptions || new PreviewOptions(),
isCddMenuOpened: false,
isMathJaxEnabled,
};
this.availableThemes = [
'eclipse', 'elegant', 'neo', 'mdn-like', 'material', 'dracula', 'monokai', 'twilight'
];
this.keymapModes = {
default: 'Default',
vim: 'Vim',
emacs: 'Emacs',
sublime: 'Sublime Text',
};
this.onChangeTheme = this.onChangeTheme.bind(this);
this.onChangeKeymapMode = this.onChangeKeymapMode.bind(this);
this.onClickStyleActiveLine = this.onClickStyleActiveLine.bind(this);
this.onClickRenderMathJaxInRealtime = this.onClickRenderMathJaxInRealtime.bind(this);
this.onToggleConfigurationDropdown = this.onToggleConfigurationDropdown.bind(this);
}
componentDidMount() {
this.init();
}
init() {
this.themeSelectorInputEl.value = this.state.editorOptions.theme;
this.keymapModeSelectorInputEl.value = this.state.editorOptions.keymapMode;
}
onChangeTheme() {
const newValue = this.themeSelectorInputEl.value;
const newOpts = Object.assign(this.state.editorOptions, {theme: newValue});
this.setState({editorOptions: newOpts});
// dispatch event
this.dispatchOnChange();
}
onChangeKeymapMode() {
const newValue = this.keymapModeSelectorInputEl.value;
const newOpts = Object.assign(this.state.editorOptions, {keymapMode: newValue});
this.setState({editorOptions: newOpts});
// dispatch event
this.dispatchOnChange();
}
onClickStyleActiveLine(event) {
// keep dropdown opened
this._cddForceOpen = true;
const newValue = !this.state.editorOptions.styleActiveLine;
const newOpts = Object.assign(this.state.editorOptions, {styleActiveLine: newValue});
this.setState({editorOptions: newOpts});
// dispatch event
this.dispatchOnChange();
}
onClickRenderMathJaxInRealtime(event) {
// keep dropdown opened
this._cddForceOpen = true;
const newValue = !this.state.previewOptions.renderMathJaxInRealtime;
const newOpts = Object.assign(this.state.previewOptions, {renderMathJaxInRealtime: newValue});
this.setState({previewOptions: newOpts});
// dispatch event
this.dispatchOnChange();
}
/*
* see: https://github.com/react-bootstrap/react-bootstrap/issues/1490#issuecomment-207445759
*/
onToggleConfigurationDropdown(newValue) {
if (this._cddForceOpen) {
this.setState({ isCddMenuOpened: true });
this._cddForceOpen = false;
}
else {
this.setState({ isCddMenuOpened: newValue });
}
}
/**
* dispatch onChange event
*/
dispatchOnChange() {
if (this.props.onChange != null) {
this.props.onChange(this.state.editorOptions, this.state.previewOptions);
}
}
renderThemeSelector() {
const optionElems = this.availableThemes.map((theme) => {
return ;
});
const bsClassName = 'form-control-dummy'; // set form-control* to shrink width
return (
Theme:
this.themeSelectorInputEl=el }>
{optionElems}
);
}
renderKeymapModeSelector() {
const optionElems = [];
for (let mode in this.keymapModes) {
const label = this.keymapModes[mode];
const dataContent = (mode === 'default')
? label
: `
${label}`;
optionElems.push(
);
}
const bsClassName = 'form-control-dummy'; // set form-control* to shrink width
return (
Keymap:
this.keymapModeSelectorInputEl=el }>
{optionElems}
);
}
renderConfigurationDropdown() {
return (
{this.renderActiveLineMenuItem()}
{this.renderRealtimeMathJaxMenuItem()}
{/* */}
);
}
renderActiveLineMenuItem() {
const isActive = this.state.editorOptions.styleActiveLine;
const iconClasses = ['text-info'];
if (isActive) {
iconClasses.push('ti-check');
}
const iconClassName = iconClasses.join(' ');
return (
);
}
renderRealtimeMathJaxMenuItem() {
if (!this.state.isMathJaxEnabled) {
return;
}
const isEnabled = this.state.isMathJaxEnabled;
const isActive = isEnabled && this.state.previewOptions.renderMathJaxInRealtime;
const iconClasses = ['text-info'];
if (isActive) {
iconClasses.push('ti-check');
}
const iconClassName = iconClasses.join(' ');
return (
);
}
render() {
return
{this.renderThemeSelector()}
{this.renderKeymapModeSelector()}
{this.renderConfigurationDropdown()}
;
}
}
export class EditorOptions {
constructor(props) {
this.theme = 'elegant';
this.keymapMode = 'default';
this.styleActiveLine = false;
Object.assign(this, props);
}
}
export class PreviewOptions {
constructor(props) {
this.renderMathJaxInRealtime = false;
Object.assign(this, props);
}
}
OptionsSelector.propTypes = {
crowi: PropTypes.object.isRequired,
editorOptions: PropTypes.instanceOf(EditorOptions),
previewOptions: PropTypes.instanceOf(PreviewOptions),
onChange: PropTypes.func,
};