import React, { Component } from "react"; import ReactDOM from "react-dom"; import { Button } from "antd"; import { Controlled as CodeMirror } from "react-codemirror2"; import { keyboardBaseBtns } from "./constants"; import CodeAction from "./components/codeAction"; import cs from "classnames"; import "./index.less"; import "codemirror/lib/codemirror.css"; import "codemirror/lib/codemirror.js"; //代码折叠 import "codemirror/addon/fold/foldgutter.css"; import "codemirror/addon/lint/lint.css"; import "codemirror/addon/fold/foldcode.js"; import "codemirror/addon/fold/foldgutter.js"; import "codemirror/addon/fold/brace-fold.js"; import "codemirror/addon/hint/javascript-hint.js"; import "codemirror/addon/hint/show-hint.js"; import "codemirror/addon/lint/lint.js"; import "codemirror/addon/lint/json-lint.js"; import "codemirror/addon/lint/javascript-lint.js"; import "codemirror/addon/display/placeholder.js"; import "codemirror/mode/javascript/javascript.js"; import "codemirror/mode/sql/sql.js"; // const sqlFormatter = require('sql-formatter'); class ExcelEditor extends Component { constructor(props) { super(props); this.state = { value: "", widgets: [] }; this.editorRef = null; } // componentDidMount() { // window.addEventListener("keydown", this.onkeyDown, { passive: false }); // } // // componentWillUnmount() { // window.removeEventListener("keydown", this.onkeyDown); // } // // onkeyDown = (e) => { // if (e.keyCode === 8) { // console.log(e); // e.nativeEvent.stopImmediatePropagation() // e.preventDefault(); // // this.handleEditorRedo(); // } // }; /* * Author: 黎永顺 * Description: 插入字符 * Params: * Date: 2023/4/13 */ insertText = text => { const cursor = this.editorRef.getCursor(); this.editorRef.replaceRange(text, cursor); }; replaceToWidget = (editor, data, value, inlineWidgetOpts) => { editor.getAllMarks().forEach(m => m.clear()); editor.refresh(); editor.focus(); // let posInfos = _.flatMap(_.keys(inlineWidgetOpts), widgetName => { // let { regex, render } = inlineWidgetOpts[widgetName]; // let res = [], newRe = new RegExp(regex, "g"), m; // do { // m = newRe.exec(value); // if (m) { // const mountToDom = document.createElement("span"); // let text = m[0]; // res.push({ // widgetName, // text, // startAt: m.index, // endAt: m.index + text.length, // render: () => { // let x = `((...args) => args)${text.replace(new RegExp(`^${widgetName}`), "")}`; // let args = eval(x); // return render(...args); // }, // mountToDom: mountToDom // }); // } // } while (m); // return res; // }); // posInfos.forEach(posInfo => { // let from = { line: 0, ch: posInfo.startAt }; // let to = { line: 0, ch: posInfo.endAt }; // editor.markText(from, to, { // replacedWith: posInfo.mountToDom, // clearWhenEmpty: false // }); // }); // this.setState({ // widgets: posInfos // }, () => { // editor.refresh(); // editor.focus(); // }); }; /* * Author: 黎永顺 * Description:格式化 * Params: * Date: 2023/4/13 */ autoFormatSelection = () => { let editor = this.editorRef.editor; if (this.props.type != "sql") { const script_length = editor.getValue().length; const startPos = { line: 0, ch: 0, sticky: null }; const endPos = editor.doc.posFromIndex(script_length); // editor.setSelection(startPos, endPos); // editor.autoFormatRange(startPos, endPos); // editor.commentRange(false, startPos, endPos); } else { let splCont = ""; splCont = editor.getValue(); // editor.setValue(sqlFormatter.format(splCont)); } }; handleVariSelect = str => this.insertText(`{${str}}`); handleFuncSelect = str => { const cursor = this.editorRef.getCursor(); this.editorRef.replaceRange(`${str}()`, cursor); console.log(this.editorRef); console.log(this.editorRef.doc); this.editorRef.doc.goColumnLeft(); }; handleEditorRedo = () => { const { ch, line } = this.editorRef.getCursor(); const delStr = this.editorRef.getRange({ line, ch: ch - 1 }, { line, ch }); const codeValue = this.editorRef.getValue(); if (delStr === "}") { if (codeValue.slice(0, ch).lastIndexOf("{") === -1) { this.editorRef.replaceRange("", { line, ch: ch - 1 }, { line, ch }); } else { this.editorRef.replaceRange("", { line, ch: codeValue.slice(0, ch).lastIndexOf("{") }, { line, ch }); } } else { this.editorRef.replaceRange("", { line, ch: ch - 1 }, { line, ch }); } }; handleBackSpaceRedo = () => { const { ch, line } = this.editorRef.getCursor(); const delStr = this.editorRef.getRange({ line, ch: ch - 1 }, { line, ch }); const codeValue = this.editorRef.getValue(); if (delStr === "}") { if (codeValue.slice(0, ch).lastIndexOf("{") === -1) { this.editorRef.replaceRange("", { line, ch: ch - 1 }, { line, ch }); } else { this.editorRef.replaceRange("", { line, ch: codeValue.slice(0, ch).lastIndexOf("{") + 1 }, { line, ch }); } } }; render() { const inlineWidgetOpts = { useObject: { regex: /useObject\("[^)]+"\)/, render: (objId) => { return ( {objId} ); } } }; const { widgets } = this.state; return (
this.editorRef = editor} value={this.state.value} onBeforeChange={(editor, data, value) => { this.setState({ value }); }} onChange={(editor, data, value) => { this.replaceToWidget(editor, data, value, inlineWidgetOpts); }} options={{ lineNumbers: false, mode: { name: this.props.type === "sql" ? "text/x-sql" : "application/json" }, autofocus: false, styleActiveLine: true, lineWrapping: true, foldGutter: true, gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"], lint: false, indentUnit: 2, cursorHeight: 0.85, placeholder: "", showCursorWhenSelecting: true }} onKeyDown={(_, { keyCode }) => keyCode === 8 && this.handleBackSpaceRedo()} /> {widgets.map((w, i) => { return ( ); })}
{ _.map(keyboardBaseBtns, item => { const { key, label } = item; return ; }) }
{/*公式参数列表*/}
); } } export default ExcelEditor; class Widget extends React.Component { render() { let { info } = this.props; return ReactDOM.createPortal( info.render(), info.mountToDom ); } }