mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-21 16:38:23 +01:00
Make default monaco theme transparent, remove import errors (#308)
This makes the background for the "wave-theme-dark" theme transparent. The light theme is still opaque because otherwise it will look somewhat dark. This also suppresses TypeScript/JavaScript import errors in the default linter, since we don't have support for project directories. This also reworks the useWidth and useHeight hooks to use the useResizeObserver hook, which limits the number of ResizeObserver instances floating around, thereby improving performance
This commit is contained in:
parent
eeceb17c75
commit
6413d49119
@ -1,6 +1,13 @@
|
|||||||
import debounce from "lodash.debounce";
|
import useResizeObserver from "@react-hook/resize-observer";
|
||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useRef, useState } from "react";
|
||||||
|
import { debounce } from "throttle-debounce";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current dimensions for the specified element, and whether it is currently changing size. Update when the element resizes.
|
||||||
|
* @param ref The reference to the element to observe.
|
||||||
|
* @param delay The debounce delay to use for updating the dimensions.
|
||||||
|
* @returns The dimensions of the element, and direction in which the dimensions are changing.
|
||||||
|
*/
|
||||||
const useDimensions = (ref: React.RefObject<HTMLElement>, delay = 0) => {
|
const useDimensions = (ref: React.RefObject<HTMLElement>, delay = 0) => {
|
||||||
const [dimensions, setDimensions] = useState<{
|
const [dimensions, setDimensions] = useState<{
|
||||||
height: number | null;
|
height: number | null;
|
||||||
@ -17,73 +24,42 @@ const useDimensions = (ref: React.RefObject<HTMLElement>, delay = 0) => {
|
|||||||
width: null,
|
width: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateDimensions = useCallback(() => {
|
const updateDimensions = useCallback((entry: ResizeObserverEntry) => {
|
||||||
if (ref.current) {
|
const parentHeight = entry.contentRect.height;
|
||||||
const element = ref.current;
|
const parentWidth = entry.contentRect.width;
|
||||||
const style = window.getComputedStyle(element);
|
|
||||||
const paddingTop = parseFloat(style.paddingTop);
|
|
||||||
const paddingBottom = parseFloat(style.paddingBottom);
|
|
||||||
const paddingLeft = parseFloat(style.paddingLeft);
|
|
||||||
const paddingRight = parseFloat(style.paddingRight);
|
|
||||||
const marginTop = parseFloat(style.marginTop);
|
|
||||||
const marginBottom = parseFloat(style.marginBottom);
|
|
||||||
const marginLeft = parseFloat(style.marginLeft);
|
|
||||||
const marginRight = parseFloat(style.marginRight);
|
|
||||||
|
|
||||||
const parentHeight = element.clientHeight - paddingTop - paddingBottom - marginTop - marginBottom;
|
let widthDirection = "";
|
||||||
const parentWidth = element.clientWidth - paddingLeft - paddingRight - marginLeft - marginRight;
|
let heightDirection = "";
|
||||||
|
|
||||||
let widthDirection = "";
|
if (previousDimensions.current.width !== null && previousDimensions.current.height !== null) {
|
||||||
let heightDirection = "";
|
if (parentWidth > previousDimensions.current.width) {
|
||||||
|
widthDirection = "expanding";
|
||||||
if (previousDimensions.current.width !== null && previousDimensions.current.height !== null) {
|
} else if (parentWidth < previousDimensions.current.width) {
|
||||||
if (parentWidth > previousDimensions.current.width) {
|
widthDirection = "shrinking";
|
||||||
widthDirection = "expanding";
|
} else {
|
||||||
} else if (parentWidth < previousDimensions.current.width) {
|
widthDirection = "unchanged";
|
||||||
widthDirection = "shrinking";
|
|
||||||
} else {
|
|
||||||
widthDirection = "unchanged";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parentHeight > previousDimensions.current.height) {
|
|
||||||
heightDirection = "expanding";
|
|
||||||
} else if (parentHeight < previousDimensions.current.height) {
|
|
||||||
heightDirection = "shrinking";
|
|
||||||
} else {
|
|
||||||
heightDirection = "unchanged";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
previousDimensions.current = { height: parentHeight, width: parentWidth };
|
if (parentHeight > previousDimensions.current.height) {
|
||||||
|
heightDirection = "expanding";
|
||||||
setDimensions({ height: parentHeight, width: parentWidth, widthDirection, heightDirection });
|
} else if (parentHeight < previousDimensions.current.height) {
|
||||||
|
heightDirection = "shrinking";
|
||||||
|
} else {
|
||||||
|
heightDirection = "unchanged";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [ref]);
|
|
||||||
|
|
||||||
const fUpdateDimensions = useCallback(delay > 0 ? debounce(updateDimensions, delay) : updateDimensions, [
|
previousDimensions.current = { height: parentHeight, width: parentWidth };
|
||||||
|
|
||||||
|
setDimensions({ height: parentHeight, width: parentWidth, widthDirection, heightDirection });
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const fUpdateDimensions = useCallback(delay > 0 ? debounce(delay, updateDimensions) : updateDimensions, [
|
||||||
updateDimensions,
|
updateDimensions,
|
||||||
delay,
|
delay,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useResizeObserver(ref, fUpdateDimensions);
|
||||||
const resizeObserver = new ResizeObserver(() => {
|
|
||||||
fUpdateDimensions();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (ref.current) {
|
|
||||||
resizeObserver.observe(ref.current);
|
|
||||||
fUpdateDimensions();
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
if (ref.current) {
|
|
||||||
resizeObserver.unobserve(ref.current);
|
|
||||||
}
|
|
||||||
if (delay > 0) {
|
|
||||||
fUpdateDimensions.cancel();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [fUpdateDimensions]);
|
|
||||||
|
|
||||||
return dimensions;
|
return dimensions;
|
||||||
};
|
};
|
||||||
|
@ -1,46 +1,26 @@
|
|||||||
// Copyright 2024, Command Line Inc.
|
// Copyright 2024, Command Line Inc.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import debounce from "lodash.debounce";
|
import useResizeObserver from "@react-hook/resize-observer";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
|
import { debounce } from "throttle-debounce";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the height of the specified element and update it when the element resizes.
|
||||||
|
* @param ref The reference to the element to observe.
|
||||||
|
* @param delay The debounce delay to use for updating the height.
|
||||||
|
* @returns The current height of the element, or null if the element is not yet mounted.
|
||||||
|
*/
|
||||||
const useHeight = (ref: React.RefObject<HTMLElement>, delay = 0) => {
|
const useHeight = (ref: React.RefObject<HTMLElement>, delay = 0) => {
|
||||||
const [height, setHeight] = useState<number | null>(null);
|
const [height, setHeight] = useState<number | null>(null);
|
||||||
|
|
||||||
const updateHeight = useCallback(() => {
|
const updateHeight = useCallback((entry: ResizeObserverEntry) => {
|
||||||
if (ref.current) {
|
setHeight(entry.contentRect.height);
|
||||||
const element = ref.current;
|
|
||||||
const style = window.getComputedStyle(element);
|
|
||||||
const paddingTop = parseFloat(style.paddingTop);
|
|
||||||
const paddingBottom = parseFloat(style.paddingBottom);
|
|
||||||
const marginTop = parseFloat(style.marginTop);
|
|
||||||
const marginBottom = parseFloat(style.marginBottom);
|
|
||||||
const parentHeight = element.clientHeight - paddingTop - paddingBottom - marginTop - marginBottom;
|
|
||||||
setHeight(parentHeight);
|
|
||||||
}
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const fUpdateHeight = useCallback(delay > 0 ? debounce(updateHeight, delay) : updateHeight, [updateHeight, delay]);
|
const fUpdateHeight = useCallback(delay > 0 ? debounce(delay, updateHeight) : updateHeight, [updateHeight, delay]);
|
||||||
|
|
||||||
useEffect(() => {
|
useResizeObserver(ref, fUpdateHeight);
|
||||||
const resizeObserver = new ResizeObserver(() => {
|
|
||||||
fUpdateHeight();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (ref.current) {
|
|
||||||
resizeObserver.observe(ref.current);
|
|
||||||
fUpdateHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
if (ref.current) {
|
|
||||||
resizeObserver.unobserve(ref.current);
|
|
||||||
}
|
|
||||||
if (delay > 0) {
|
|
||||||
fUpdateHeight.cancel();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [fUpdateHeight]);
|
|
||||||
|
|
||||||
return height;
|
return height;
|
||||||
};
|
};
|
||||||
|
@ -1,46 +1,26 @@
|
|||||||
// Copyright 2024, Command Line Inc.
|
// Copyright 2024, Command Line Inc.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import debounce from "lodash.debounce";
|
import useResizeObserver from "@react-hook/resize-observer";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
|
import { debounce } from "throttle-debounce";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the width of the specified element and update it when the element resizes.
|
||||||
|
* @param ref The reference to the element to observe.
|
||||||
|
* @param delay The debounce delay to use for updating the width.
|
||||||
|
* @returns The current width of the element, or null if the element is not yet mounted.
|
||||||
|
*/
|
||||||
const useWidth = (ref: React.RefObject<HTMLElement>, delay = 0) => {
|
const useWidth = (ref: React.RefObject<HTMLElement>, delay = 0) => {
|
||||||
const [width, setWidth] = useState<number | null>(null);
|
const [width, setWidth] = useState<number | null>(null);
|
||||||
|
|
||||||
const updateWidth = useCallback(() => {
|
const updateWidth = useCallback((entry: ResizeObserverEntry) => {
|
||||||
if (ref.current) {
|
setWidth(entry.contentRect.width);
|
||||||
const element = ref.current;
|
|
||||||
const style = window.getComputedStyle(element);
|
|
||||||
const paddingLeft = parseFloat(style.paddingLeft);
|
|
||||||
const paddingRight = parseFloat(style.paddingRight);
|
|
||||||
const marginLeft = parseFloat(style.marginLeft);
|
|
||||||
const marginRight = parseFloat(style.marginRight);
|
|
||||||
const parentWidth = element.clientWidth - paddingLeft - paddingRight - marginLeft - marginRight;
|
|
||||||
setWidth(parentWidth);
|
|
||||||
}
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const fUpdateWidth = useCallback(delay > 0 ? debounce(updateWidth, delay) : updateWidth, [updateWidth, delay]);
|
const fUpdateWidth = useCallback(delay > 0 ? debounce(delay, updateWidth) : updateWidth, [updateWidth, delay]);
|
||||||
|
|
||||||
useEffect(() => {
|
useResizeObserver(ref, fUpdateWidth);
|
||||||
const resizeObserver = new ResizeObserver(() => {
|
|
||||||
fUpdateWidth();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (ref.current) {
|
|
||||||
resizeObserver.observe(ref.current);
|
|
||||||
fUpdateWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
if (ref.current) {
|
|
||||||
resizeObserver.unobserve(ref.current);
|
|
||||||
}
|
|
||||||
if (delay > 0) {
|
|
||||||
fUpdateWidth.cancel();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [fUpdateWidth]);
|
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
};
|
};
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import { useHeight } from "@/app/hook/useHeight";
|
import { useHeight } from "@/app/hook/useHeight";
|
||||||
|
import { useWidth } from "@/app/hook/useWidth";
|
||||||
import loader from "@monaco-editor/loader";
|
import loader from "@monaco-editor/loader";
|
||||||
import { Editor, Monaco } from "@monaco-editor/react";
|
import { Editor, Monaco } from "@monaco-editor/react";
|
||||||
import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api";
|
import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api";
|
||||||
import React, { useRef } from "react";
|
import React, { useRef } from "react";
|
||||||
|
|
||||||
import "./codeeditor.less";
|
import "./codeeditor.less";
|
||||||
|
|
||||||
// there is a global monaco variable (TODO get the correct TS type)
|
// there is a global monaco variable (TODO get the correct TS type)
|
||||||
@ -18,21 +18,29 @@ export function loadMonaco() {
|
|||||||
.init()
|
.init()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
monaco.editor.defineTheme("wave-theme-dark", {
|
monaco.editor.defineTheme("wave-theme-dark", {
|
||||||
base: "hc-black",
|
base: "vs-dark",
|
||||||
inherit: true,
|
inherit: true,
|
||||||
rules: [],
|
rules: [],
|
||||||
colors: {
|
colors: {
|
||||||
"editor.background": "#000000",
|
"editor.background": "#00000000",
|
||||||
|
"minimap.background": "#00000077",
|
||||||
|
focusBorder: "#00000000",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
monaco.editor.defineTheme("wave-theme-light", {
|
monaco.editor.defineTheme("wave-theme-light", {
|
||||||
base: "hc-light",
|
base: "vs",
|
||||||
inherit: true,
|
inherit: true,
|
||||||
rules: [],
|
rules: [],
|
||||||
colors: {
|
colors: {
|
||||||
"editor.background": "#fefefe",
|
"editor.background": "#fefefe",
|
||||||
|
focusBorder: "#00000000",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Disable default validation errors for typescript and javascript
|
||||||
|
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
|
||||||
|
noSemanticValidation: true,
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.error("error loading monaco", e);
|
console.error("error loading monaco", e);
|
||||||
@ -50,6 +58,9 @@ function defaultEditorOptions(): MonacoTypes.editor.IEditorOptions {
|
|||||||
verticalScrollbarSize: 5,
|
verticalScrollbarSize: 5,
|
||||||
horizontalScrollbarSize: 5,
|
horizontalScrollbarSize: 5,
|
||||||
},
|
},
|
||||||
|
minimap: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
return opts;
|
return opts;
|
||||||
}
|
}
|
||||||
@ -67,6 +78,7 @@ export function CodeEditor({ parentRef, text, language, filename, onChange, onMo
|
|||||||
const divRef = useRef<HTMLDivElement>(null);
|
const divRef = useRef<HTMLDivElement>(null);
|
||||||
const unmountRef = useRef<() => void>(null);
|
const unmountRef = useRef<() => void>(null);
|
||||||
const parentHeight = useHeight(parentRef);
|
const parentHeight = useHeight(parentRef);
|
||||||
|
const parentWidth = useWidth(parentRef);
|
||||||
const theme = "wave-theme-dark";
|
const theme = "wave-theme-dark";
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
@ -97,9 +109,10 @@ export function CodeEditor({ parentRef, text, language, filename, onChange, onMo
|
|||||||
<div className="code-editor" ref={divRef}>
|
<div className="code-editor" ref={divRef}>
|
||||||
<Editor
|
<Editor
|
||||||
theme={theme}
|
theme={theme}
|
||||||
height={parentHeight}
|
|
||||||
value={text}
|
value={text}
|
||||||
options={editorOpts}
|
options={editorOpts}
|
||||||
|
height={parentHeight}
|
||||||
|
width={parentWidth}
|
||||||
onChange={handleEditorChange}
|
onChange={handleEditorChange}
|
||||||
onMount={handleEditorOnMount}
|
onMount={handleEditorOnMount}
|
||||||
path={filename}
|
path={filename}
|
||||||
|
Loading…
Reference in New Issue
Block a user