mirror of
https://github.com/wavetermdev/waveterm
synced 2026-05-06 06:58:21 +00:00
Adds a new setting for the gap size between tiles in a layout. Also updates the resize handle calculations so they are dynamically generated based on the gap size. Also updates the styling for the resize handles to be more robust. This also updates the default gap size to 3px. This also slims out the Block Frame padding so it is just enough that the blocks don't overlap when there's no gap.
129 lines
3.9 KiB
TypeScript
129 lines
3.9 KiB
TypeScript
// Copyright 2024, Command Line Inc.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import { atoms } from "@/app/store/global";
|
|
import loader from "@monaco-editor/loader";
|
|
import { Editor, Monaco } from "@monaco-editor/react";
|
|
import { atom, useAtomValue } from "jotai";
|
|
import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api";
|
|
import React, { useMemo, useRef } from "react";
|
|
import "./codeeditor.less";
|
|
|
|
// there is a global monaco variable (TODO get the correct TS type)
|
|
declare var monaco: Monaco;
|
|
|
|
export function loadMonaco() {
|
|
loader.config({ paths: { vs: "monaco" } });
|
|
loader
|
|
.init()
|
|
.then(() => {
|
|
monaco.editor.defineTheme("wave-theme-dark", {
|
|
base: "vs-dark",
|
|
inherit: true,
|
|
rules: [],
|
|
colors: {
|
|
"editor.background": "#00000000",
|
|
"minimap.background": "#00000077",
|
|
focusBorder: "#00000000",
|
|
},
|
|
});
|
|
monaco.editor.defineTheme("wave-theme-light", {
|
|
base: "vs",
|
|
inherit: true,
|
|
rules: [],
|
|
colors: {
|
|
"editor.background": "#fefefe",
|
|
focusBorder: "#00000000",
|
|
},
|
|
});
|
|
|
|
// Disable default validation errors for typescript and javascript
|
|
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
|
|
noSemanticValidation: true,
|
|
});
|
|
})
|
|
.catch((e) => {
|
|
console.error("error loading monaco", e);
|
|
});
|
|
}
|
|
|
|
function defaultEditorOptions(): MonacoTypes.editor.IEditorOptions {
|
|
const opts: MonacoTypes.editor.IEditorOptions = {
|
|
scrollBeyondLastLine: false,
|
|
fontSize: 12,
|
|
fontFamily: "Hack",
|
|
smoothScrolling: true,
|
|
scrollbar: {
|
|
useShadows: false,
|
|
verticalScrollbarSize: 5,
|
|
horizontalScrollbarSize: 5,
|
|
},
|
|
minimap: {
|
|
enabled: true,
|
|
},
|
|
};
|
|
return opts;
|
|
}
|
|
|
|
interface CodeEditorProps {
|
|
text: string;
|
|
filename: string;
|
|
language?: string;
|
|
onChange?: (text: string) => void;
|
|
onMount?: (monacoPtr: MonacoTypes.editor.IStandaloneCodeEditor, monaco: Monaco) => () => void;
|
|
}
|
|
|
|
const minimapEnabledAtom = atom((get) => {
|
|
const settings = get(atoms.settingsAtom);
|
|
return settings["editor:minimapenabled"] ?? false;
|
|
});
|
|
|
|
export function CodeEditor({ text, language, filename, onChange, onMount }: CodeEditorProps) {
|
|
const divRef = useRef<HTMLDivElement>(null);
|
|
const unmountRef = useRef<() => void>(null);
|
|
const minimapEnabled = useAtomValue(minimapEnabledAtom);
|
|
const theme = "wave-theme-dark";
|
|
|
|
React.useEffect(() => {
|
|
return () => {
|
|
// unmount function
|
|
if (unmountRef.current) {
|
|
unmountRef.current();
|
|
}
|
|
};
|
|
}, []);
|
|
|
|
function handleEditorChange(text: string, ev: MonacoTypes.editor.IModelContentChangedEvent) {
|
|
if (onChange) {
|
|
onChange(text);
|
|
}
|
|
}
|
|
|
|
function handleEditorOnMount(editor: MonacoTypes.editor.IStandaloneCodeEditor, monaco: Monaco) {
|
|
if (onMount) {
|
|
unmountRef.current = onMount(editor, monaco);
|
|
}
|
|
}
|
|
|
|
const editorOpts = useMemo(() => {
|
|
const opts = defaultEditorOptions();
|
|
opts.minimap.enabled = minimapEnabled;
|
|
return opts;
|
|
}, [minimapEnabled]);
|
|
|
|
return (
|
|
<div className="code-editor-wrapper">
|
|
<div className="code-editor" ref={divRef}>
|
|
<Editor
|
|
theme={theme}
|
|
value={text}
|
|
options={editorOpts}
|
|
onChange={handleEditorChange}
|
|
onMount={handleEditorOnMount}
|
|
path={filename}
|
|
language={language}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|