Skip to content

Commit

Permalink
fix: re-colorize command codeblocks when theme changes (#1731)
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
dsmmcken authored Jan 16, 2024
1 parent f919a7e commit b1e42f5
Showing 1 changed file with 36 additions and 40 deletions.
76 changes: 36 additions & 40 deletions packages/console/src/common/Code.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,47 @@
import React, { Component, ReactElement, ReactNode } from 'react';
import React, { useEffect, useState, ReactNode } from 'react';
import * as monaco from 'monaco-editor';
import { useTheme } from '@deephaven/components';

interface CodeProps {
children: ReactNode;
language: string;
}

class Code extends Component<CodeProps, Record<string, never>> {
constructor(props: CodeProps) {
super(props);

this.container = null;
}

componentDidMount(): void {
this.colorize();
}

container: HTMLDivElement | null;

colorize(): void {
const { children } = this.props;
if (this.container && children != null) {
monaco.editor.colorizeElement(this.container, {
theme: 'dh-dark',
});
function Code({ children, language }: CodeProps): JSX.Element {
const [colorizedHtml, setColorizedHtml] = useState<string | null>(null);
const { activeThemes } = useTheme();

useEffect(() => {
let isCanceled = false;
async function colorize() {
if (children != null && activeThemes != null) {
const result = await monaco.editor.colorize(
children.toString(),
language,
{}
);
if (!isCanceled) {
setColorizedHtml(result);
}
}
}
}

render(): ReactElement {
const { children, language } = this.props;
return (
<div>
<div
data-lang={language}
ref={container => {
this.container = container;
}}
// Add pointerEvents: 'none' has huge benefits on performance with Hit Test testing on large colorized elements.
// You can still select the text event with this set
style={{ pointerEvents: 'none' }}
>
{children}
</div>
</div>
);
}
colorize();
return () => {
isCanceled = true;
};
}, [activeThemes, children, language]);

return (
<div
// Add pointerEvents: 'none' has huge benefits on performance with Hit Test testing on large colorized elements.
// You can still select the text event with this set
style={{ pointerEvents: 'none' }}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={
colorizedHtml != null ? { __html: colorizedHtml } : undefined
}
/>
);
}

export default Code;

0 comments on commit b1e42f5

Please sign in to comment.