公式编辑器组件封装

This commit is contained in:
黎永顺 2023-04-13 16:42:57 +08:00
parent 247432ebde
commit 7bdf55be6a
3 changed files with 98 additions and 58 deletions

View File

@ -1,16 +1,16 @@
export const keyboardBaseBtns=[
{ key:"1", label: "+" },
{ key:"2", label: "-" },
{ key:"3", label: ">" },
{ key:"4", label: ">=" },
{ key:"5", label: "=" },
{ key:"6", label: "*" },
{ key:"7", label: "/" },
{ key:"8", label: "<" },
{ key:"9", label: "<=" },
{ key:"10", label: "!=" },
{ key:"11", label: "(" },
{ key:"12", label: ")" },
{ key:"13", label: "%" },
{ key:"space", label: "space" },
{ key:"+", label: "+" },
{ key:"-", label: "-" },
{ key:">", label: ">" },
{ key:">=", label: ">=" },
{ key:"=", label: "=" },
{ key:"*", label: "*" },
{ key:"/", label: "/" },
{ key:"<", label: "<" },
{ key:"<=", label: "<=" },
{ key:"!=", label: "!=" },
{ key:"()", label: "(" },
{ key:")", label: ")" },
{ key:"%", label: "%" },
{ key:" ", label: "space" },
]

View File

@ -1,4 +1,5 @@
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";
@ -35,46 +36,60 @@ class ExcelEditor extends Component {
this.editorRef = null;
}
/*
* Author: 黎永顺
* Description: 插入字符
* Params:
* Date: 2023/4/13
*/
insertText = text => {
let cursor = this.editorRef.getCursor();
console.log(cursor);
this.editorRef.replaceRange(text, cursor);
};
replaceToWidget = (editor, data, value, inlineWidgetOpts) => {
editor.getAllMarks().forEach(m => m.clear());
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();
});
// 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: 黎永顺
@ -104,15 +119,12 @@ class ExcelEditor extends Component {
regex: /useObject\("[^)]+"\)/,
render: (objId) => {
return (
<div
className="border iblock"
style={{ padding: "5px" }}
onClick={() => alert(objId)}
>{objId}</div>
<span className="cm-excel-default">{objId}</span>
);
}
}
};
const { widgets } = this.state;
return (
<React.Fragment>
<div className="excel-codeWrap">
@ -140,6 +152,11 @@ class ExcelEditor extends Component {
placeholder: ""
}}
/>
{widgets.map((w, i) => {
return (
<Widget key={i} info={w}/>
);
})}
</div>
<div className="excel-codeBox-keyboard">
<div className="excel-codeBox-keyboard-operate">
@ -149,14 +166,17 @@ class ExcelEditor extends Component {
const { key, label } = item;
return <Button
key={key} title={label} size="small"
className={cs(key === "space" ? "excel-codeBox-keyboard-space" : "excel-codeBox-keyboard-base")}
className={cs(key === " " ? "excel-codeBox-keyboard-space" : "excel-codeBox-keyboard-base")}
onClick={() => this.insertText(key)}
>{label}</Button>;
})
}
</div>
<div className="excel-codeBox-keyboard-operate-clear">
<Button title="←" size="small" className="excel-codeBox-keyboard-del"></Button>
<Button title="C" size="small" className="excel-codeBox-keyboard-clear">C</Button>
<Button title="←" size="small" className="excel-codeBox-keyboard-del"
onClick={() => this.insertText(`useObject("←")`)}></Button>
<Button title="C" size="small" className="excel-codeBox-keyboard-clear"
onClick={() => this.setState({ value: "", widgets: [] })}>C</Button>
</div>
</div>
</div>
@ -187,3 +207,13 @@ class ExcelEditor extends Component {
}
export default ExcelEditor;
class Widget extends React.Component {
render() {
let { info } = this.props;
return ReactDOM.createPortal(
info.render(),
info.mountToDom
);
}
}

View File

@ -11,6 +11,16 @@
box-sizing: content-box;
border: 1px solid #e5e5e5;
span {
font-family: Liberation Mono, LiberationMonoRegular, Courier New, monospace;
}
.CodeMirror-code {
font-size: 16px;
}
.CodeMirror-scroll {
overflow-x: visible !important;
padding: 4px;