plot-plan-designer
Version:
Design Editor Tools with React.js + ant.design + fabric.js
146 lines (145 loc) • 5.87 kB
JavaScript
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Form, Row, Col } from 'antd';
import debounce from 'lodash/debounce';
import ReactAce from 'react-ace';
import 'ace-builds/src-noconflict/mode-html';
import 'ace-builds/src-noconflict/mode-css';
import 'ace-builds/src-noconflict/mode-javascript';
import 'ace-builds/src-noconflict/theme-github';
import AcePreview from './AcePreview';
const defaultStyle = {
padding: 12,
};
class AceEditor extends Component {
constructor() {
super(...arguments);
this.handlers = {
onChangeHTML: debounce((value) => {
this.setState({
html: value,
htmlAnnotations: this.htmlRef.editor.getSession().getAnnotations(),
}, () => {
if (this.props.onChangeHTML) {
this.props.onChangeHTML(value);
}
});
}, 500),
onChangeCSS: debounce((value) => {
this.setState({
css: value,
cssAnnotations: this.cssRef.editor.getSession().getAnnotations(),
}, () => {
if (this.props.onChangeCSS) {
this.props.onChangeCSS(value);
}
});
}, 500),
onChangeJS: debounce((value) => {
this.setState({
js: value,
jsAnnotations: this.jsRef.editor.getSession().getAnnotations(),
}, () => {
if (this.props.onChangeJS) {
this.props.onChangeJS(value);
}
});
}, 500),
onValidateHTML: (annotations) => {
let i = annotations.length;
const len = annotations.length;
while (i--) {
if (/doctype first\. Expected/.test(annotations[i].text)) {
annotations.splice(i, 1);
}
else if (/Unexpected End of file\. Expected/.test(annotations[i].text)) {
annotations.splice(i, 1);
}
}
if (len > annotations.length) {
this.htmlRef.editor.getSession().setAnnotations(annotations);
}
},
getAnnotations: () => {
const { htmlAnnotations, cssAnnotations, jsAnnotations } = this.state;
return {
htmlAnnotations,
cssAnnotations,
jsAnnotations,
};
},
getCodes: () => {
const { html, css, js } = this.state;
return {
html,
css,
js,
};
},
};
this.state = {
html: this.props.html,
css: this.props.css,
js: this.props.js,
htmlAnnotations: [],
cssAnnotations: [],
jsAnnotations: [],
};
}
componentWillUnmount() {
this.htmlRef.editor.destroy();
this.cssRef.editor.destroy();
this.jsRef.editor.destroy();
}
render() {
const { isHTML, isCSS, isJS, isPreview } = this.props;
const { html, css, js } = this.state;
return (React.createElement(Row, null,
isHTML ? (React.createElement(Col, { span: 12, style: defaultStyle },
React.createElement(Form.Item, { label: "HTML", colon: false },
React.createElement(ReactAce, { ref: (c) => {
this.htmlRef = c;
}, mode: "html", theme: "github", width: "100%", height: "200px", defaultValue: html, value: html, editorProps: {
$blockScrolling: true,
}, onChange: this.handlers.onChangeHTML })))) : null,
isCSS ? (React.createElement(Col, { span: 12, style: defaultStyle },
React.createElement(Form.Item, { label: "CSS", colon: false },
React.createElement(ReactAce, { ref: (c) => {
this.cssRef = c;
}, mode: "css", theme: "github", width: "100%", height: "200px", defaultValue: css, value: css, editorProps: {
$blockScrolling: true,
}, onChange: this.handlers.onChangeCSS })))) : null,
isJS ? (React.createElement(Col, { span: 12, style: defaultStyle },
React.createElement(Form.Item, { label: "JS", colon: false },
React.createElement(ReactAce, { ref: (c) => {
this.jsRef = c;
}, mode: "javascript", theme: "github", width: "100%", height: "200px", defaultValue: js, value: js, editorProps: {
$blockScrolling: true,
}, onChange: this.handlers.onChangeJS })))) : null,
isPreview ? (React.createElement(Col, { span: 12, style: defaultStyle },
React.createElement(Form.Item, { label: "Preview", colon: false },
React.createElement(AcePreview, { html: html, css: css, js: js })))) : null));
}
}
AceEditor.propTypes = {
isHTML: PropTypes.bool,
isCSS: PropTypes.bool,
isJS: PropTypes.bool,
isPreview: PropTypes.bool,
html: PropTypes.string,
css: PropTypes.string,
js: PropTypes.string,
onChangeJS: PropTypes.func,
onChangeCSS: PropTypes.func,
onChangeHTML: PropTypes.func,
};
AceEditor.defaultProps = {
isHTML: true,
isCSS: true,
isJS: true,
isPreview: true,
html: '',
css: '',
js: '',
};
export default AceEditor;