From b1e42f58df5c9c478ff47d4823b517e23a94709f Mon Sep 17 00:00:00 2001 From: Don Date: Tue, 16 Jan 2024 18:36:28 -0500 Subject: [PATCH] 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) --- packages/console/src/common/Code.tsx | 76 +++++++++++++--------------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/packages/console/src/common/Code.tsx b/packages/console/src/common/Code.tsx index 4da8e9cf86..373c7de5c4 100644 --- a/packages/console/src/common/Code.tsx +++ b/packages/console/src/common/Code.tsx @@ -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> { - 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(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 ( -
-
{ - 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} -
-
- ); - } + colorize(); + return () => { + isCanceled = true; + }; + }, [activeThemes, children, language]); + + return ( +
+ ); } export default Code;