1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/renderer/components/ace-editor/ace-editor.tsx
Roman b7974827d2
Lens restructure (#540)
Signed-off-by: Roman <ixrock@gmail.com>
2020-06-30 14:35:16 +03:00

158 lines
3.6 KiB
TypeScript

// Ace code editor - https://ace.c9.io
// Playground - https://ace.c9.io/build/kitchen-sink.html
import "./ace-editor.scss"
import React from "react"
import { observer } from "mobx-react";
import AceBuild, { Ace } from "ace-builds"
import { autobind, cssNames } from "../../utils";
import { themeStore } from "../../theme.store";
interface Props extends Partial<Ace.EditorOptions> {
className?: string;
autoFocus?: boolean;
hidden?: boolean;
cursorPos?: Ace.Point;
onChange?(value: string, delta: Ace.Delta): void;
onCursorPosChange?(point: Ace.Point): void;
}
interface State {
ready?: boolean;
}
const defaultProps: Partial<Props> = {
value: "",
mode: "yaml",
tabSize: 2,
showGutter: true, // line-numbers
foldStyle: "markbegin",
printMargin: false,
useWorker: false,
};
@observer
export class AceEditor extends React.Component<Props, State> {
static defaultProps = defaultProps as object;
private editor: Ace.Editor;
private elem: HTMLElement;
constructor(props: Props) {
super(props);
require("ace-builds/src-noconflict/mode-yaml")
require("ace-builds/src-noconflict/theme-dreamweaver")
require("ace-builds/src-noconflict/theme-terminal")
require("ace-builds/src-noconflict/ext-searchbox")
}
get theme() {
switch (themeStore.activeTheme.type) {
case "light":
return "dreamweaver"
case "dark":
return "terminal";
}
}
async componentDidMount() {
const {
mode, autoFocus, className, hidden, cursorPos,
onChange, onCursorPosChange, children,
...options
} = this.props;
// setup editor
this.editor = AceBuild.edit(this.elem, options);
this.setTheme(this.theme);
this.setMode(mode);
this.setCursorPos(cursorPos);
// bind events
this.editor.on("change", this.onChange);
this.editor.selection.on("changeCursor", this.onCursorPosChange);
if (autoFocus) {
this.focus();
}
}
componentDidUpdate() {
if (!this.editor) return;
const { value, cursorPos } = this.props;
if (value !== this.getValue()) {
this.editor.setValue(value);
this.editor.clearSelection();
this.setCursorPos(cursorPos || this.editor.getCursorPosition());
}
}
componentWillUnmount() {
if (this.editor) {
this.editor.destroy();
}
}
resize() {
if (this.editor) {
this.editor.resize();
}
}
focus() {
if (this.editor) {
this.editor.focus();
}
}
getValue() {
return this.editor.getValue()
}
setValue(value: string, cursorPos?: number) {
return this.editor.setValue(value, cursorPos);
}
async setMode(mode: string) {
this.editor.session.setMode(`ace/mode/${mode}`);
}
async setTheme(theme: string) {
this.editor.setTheme(`ace/theme/${theme}`);
}
setCursorPos(pos: Ace.Point) {
if (!pos) return;
const { row, column } = pos;
this.editor.moveCursorToPosition(pos);
requestAnimationFrame(() => {
this.editor.gotoLine(row + 1, column, false);
});
}
@autobind()
onCursorPosChange() {
const { onCursorPosChange } = this.props;
if (onCursorPosChange) {
onCursorPosChange(this.editor.getCursorPosition());
}
}
@autobind()
onChange(delta: Ace.Delta) {
const { onChange } = this.props;
if (onChange) {
onChange(this.getValue(), delta);
}
}
render() {
const { className, hidden } = this.props;
const themeType = themeStore.activeTheme.type;
return (
<div className={cssNames("AceEditor", className, { hidden }, themeType)}>
<div className="editor" ref={e => this.elem = e}/>
</div>
)
}
}