Skip to content

Commit b1e42f5

Browse files
authored
fix: re-colorize command codeblocks when theme changes (#1731)
Fixes an issues where the command history doesn't get re-colorized when the theme changes. Steps to reproduce: Run a command, then change theme (depends on which theme you started on, but history will look wrong): ![image](https://github.com/deephaven/web-client-ui/assets/1576283/a3087cc5-0f00-4d3f-b8c3-c778515b57fa)
1 parent f919a7e commit b1e42f5

1 file changed

Lines changed: 36 additions & 40 deletions

File tree

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,47 @@
1-
import React, { Component, ReactElement, ReactNode } from 'react';
1+
import React, { useEffect, useState, ReactNode } from 'react';
22
import * as monaco from 'monaco-editor';
3+
import { useTheme } from '@deephaven/components';
34

45
interface CodeProps {
56
children: ReactNode;
67
language: string;
78
}
89

9-
class Code extends Component<CodeProps, Record<string, never>> {
10-
constructor(props: CodeProps) {
11-
super(props);
12-
13-
this.container = null;
14-
}
15-
16-
componentDidMount(): void {
17-
this.colorize();
18-
}
19-
20-
container: HTMLDivElement | null;
21-
22-
colorize(): void {
23-
const { children } = this.props;
24-
if (this.container && children != null) {
25-
monaco.editor.colorizeElement(this.container, {
26-
theme: 'dh-dark',
27-
});
10+
function Code({ children, language }: CodeProps): JSX.Element {
11+
const [colorizedHtml, setColorizedHtml] = useState<string | null>(null);
12+
const { activeThemes } = useTheme();
13+
14+
useEffect(() => {
15+
let isCanceled = false;
16+
async function colorize() {
17+
if (children != null && activeThemes != null) {
18+
const result = await monaco.editor.colorize(
19+
children.toString(),
20+
language,
21+
{}
22+
);
23+
if (!isCanceled) {
24+
setColorizedHtml(result);
25+
}
26+
}
2827
}
29-
}
30-
31-
render(): ReactElement {
32-
const { children, language } = this.props;
33-
return (
34-
<div>
35-
<div
36-
data-lang={language}
37-
ref={container => {
38-
this.container = container;
39-
}}
40-
// Add pointerEvents: 'none' has huge benefits on performance with Hit Test testing on large colorized elements.
41-
// You can still select the text event with this set
42-
style={{ pointerEvents: 'none' }}
43-
>
44-
{children}
45-
</div>
46-
</div>
47-
);
48-
}
28+
colorize();
29+
return () => {
30+
isCanceled = true;
31+
};
32+
}, [activeThemes, children, language]);
33+
34+
return (
35+
<div
36+
// Add pointerEvents: 'none' has huge benefits on performance with Hit Test testing on large colorized elements.
37+
// You can still select the text event with this set
38+
style={{ pointerEvents: 'none' }}
39+
// eslint-disable-next-line react/no-danger
40+
dangerouslySetInnerHTML={
41+
colorizedHtml != null ? { __html: colorizedHtml } : undefined
42+
}
43+
/>
44+
);
4945
}
5046

5147
export default Code;

0 commit comments

Comments
 (0)