diff --git a/src/app/common/elements/index.tsx b/src/app/common/elements/index.tsx index 75f99280e..215ba6dbe 100644 --- a/src/app/common/elements/index.tsx +++ b/src/app/common/elements/index.tsx @@ -18,3 +18,4 @@ export { Toggle } from "./toggle"; export { Tooltip } from "./tooltip"; export { TabIcon } from "./tabicon"; export { DatePicker } from "./datepicker"; +export { StyleBlock } from "./styleblock"; diff --git a/src/app/common/elements/styleblock.tsx b/src/app/common/elements/styleblock.tsx new file mode 100644 index 000000000..91eb58d67 --- /dev/null +++ b/src/app/common/elements/styleblock.tsx @@ -0,0 +1,66 @@ +// Copyright 2023, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +import * as React from "react"; +import * as mobxReact from "mobx-react"; +import * as mobx from "mobx"; +import { GlobalModel } from "@/models"; +import { isBlank } from "@/util/util"; + +@mobxReact.observer +class StyleBlock extends React.Component< + { themeSrcEl: HTMLElement; themeKey: string; className: string; termTheme: TermThemeType }, + { styleRules: string } +> { + styleRules: OV = mobx.observable.box("", { name: "StyleBlock-styleRules" }); + theme: string; + + componentDidMount(): void { + GlobalModel.termThemeSrcEl.set(this.props.themeSrcEl); + this.loadThemeStyles(); + } + + componentDidUpdate(prevProps): void { + const { themeKey, termTheme } = this.props; + const currTheme = termTheme[themeKey]; + if (themeKey !== prevProps.themeKey || currTheme !== this.theme) { + this.loadThemeStyles(); + } + if (this.props.themeSrcEl !== prevProps.themeSrcEl) { + GlobalModel.termThemeSrcEl.set(this.props.themeSrcEl); + } + } + + async loadThemeStyles() { + const { themeKey, className, termTheme } = this.props; + const currTheme = termTheme[themeKey]; + + if (currTheme !== this.theme && currTheme) { + const rtn = GlobalModel.getTermThemeJson(currTheme); + rtn.then((termThemeJson) => { + if (termThemeJson && typeof termThemeJson === "object") { + const styleProperties = Object.entries(termThemeJson) + .map(([key, value]) => `--term-${key}: ${value};`) + .join(" "); + + this.styleRules.set(`.${className} { ${styleProperties} }`); + GlobalModel.bumpTermRenderVersion(); + this.theme = currTheme; + } else { + console.error("termThemeJson is not an object:", termThemeJson); + } + }).catch((error) => { + console.error("error loading theme styles:", error); + }); + } + } + + render() { + if (isBlank(this.styleRules.get())) { + return null; + } + return ; + } +} + +export { StyleBlock };