fix: Mermaid diagrams do not respect dark mode (#4564)

* wip

* Move event binding
This commit is contained in:
Tom Moor
2022-12-11 11:33:17 -08:00
committed by GitHub
parent e4da92a359
commit 80780eedda
5 changed files with 50 additions and 7 deletions

View File

@@ -23,8 +23,12 @@ const Theme: React.FC = ({ children }) => {
: resolvedTheme; : resolvedTheme;
React.useEffect(() => { React.useEffect(() => {
window.dispatchEvent(new Event("theme-changed")); window.dispatchEvent(
}, [theme]); new CustomEvent("theme-changed", {
detail: { isDark: ui.resolvedTheme === "dark" },
})
);
}, [ui.resolvedTheme]);
return ( return (
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>

View File

@@ -210,6 +210,7 @@ export class Editor extends React.PureComponent<
*/ */
public componentDidMount() { public componentDidMount() {
this.init(); this.init();
window.addEventListener("theme-changed", this.dispatchThemeChanged);
if (this.props.scrollTo) { if (this.props.scrollTo) {
this.scrollToAnchor(this.props.scrollTo); this.scrollToAnchor(this.props.scrollTo);
@@ -278,6 +279,10 @@ export class Editor extends React.PureComponent<
} }
} }
public componentWillUnmount(): void {
window.removeEventListener("theme-changed", this.dispatchThemeChanged);
}
private init() { private init() {
this.extensions = this.createExtensions(); this.extensions = this.createExtensions();
this.nodes = this.createNodes(); this.nodes = this.createNodes();
@@ -398,7 +403,9 @@ export class Editor extends React.PureComponent<
plugins: [ plugins: [
...this.plugins, ...this.plugins,
...this.keymaps, ...this.keymaps,
dropCursor({ color: this.props.theme.cursor }), dropCursor({
color: this.props.theme.cursor,
}),
gapCursor(), gapCursor(),
inputRules({ inputRules({
rules: this.inputRules, rules: this.inputRules,
@@ -468,6 +475,10 @@ export class Editor extends React.PureComponent<
return view; return view;
} }
private dispatchThemeChanged = (event: CustomEvent) => {
this.view.dispatch(this.view.state.tr.setMeta("theme", event.detail));
};
public scrollToAnchor(hash: string) { public scrollToAnchor(hash: string) {
if (!hash) { if (!hash) {
return; return;

View File

@@ -338,7 +338,10 @@ export default class CodeFence extends Node {
name: this.name, name: this.name,
lineNumbers: this.showLineNumbers, lineNumbers: this.showLineNumbers,
}), }),
Mermaid({ name: this.name }), Mermaid({
name: this.name,
isDark: this.editor.props.theme.isDark,
}),
new Plugin({ new Plugin({
key: new PluginKey("triple-click"), key: new PluginKey("triple-click"),
props: { props: {

View File

@@ -7,6 +7,7 @@ import { v4 as uuidv4 } from "uuid";
type MermaidState = { type MermaidState = {
decorationSet: DecorationSet; decorationSet: DecorationSet;
diagramVisibility: Record<number, boolean>; diagramVisibility: Record<number, boolean>;
isDark: boolean;
}; };
function getNewState({ function getNewState({
@@ -65,6 +66,7 @@ function getNewState({
flowchart: { flowchart: {
htmlLabels: false, htmlLabels: false,
}, },
theme: pluginState.isDark ? "dark" : "default",
fontFamily: "inherit", fontFamily: "inherit",
}); });
try { try {
@@ -114,10 +116,17 @@ function getNewState({
return { return {
decorationSet: DecorationSet.create(doc, decorations), decorationSet: DecorationSet.create(doc, decorations),
diagramVisibility: pluginState.diagramVisibility, diagramVisibility: pluginState.diagramVisibility,
isDark: pluginState.isDark,
}; };
} }
export default function Mermaid({ name }: { name: string }) { export default function Mermaid({
name,
isDark,
}: {
name: string;
isDark: boolean;
}) {
let diagramShown = false; let diagramShown = false;
return new Plugin({ return new Plugin({
@@ -127,6 +136,7 @@ export default function Mermaid({ name }: { name: string }) {
const pluginState: MermaidState = { const pluginState: MermaidState = {
decorationSet: DecorationSet.create(doc, []), decorationSet: DecorationSet.create(doc, []),
diagramVisibility: {}, diagramVisibility: {},
isDark,
}; };
return pluginState; return pluginState;
}, },
@@ -142,7 +152,13 @@ export default function Mermaid({ name }: { name: string }) {
transaction.docChanged && [nodeName, previousNodeName].includes(name); transaction.docChanged && [nodeName, previousNodeName].includes(name);
const ySyncEdit = !!transaction.getMeta("y-sync$"); const ySyncEdit = !!transaction.getMeta("y-sync$");
const mermaidMeta = transaction.getMeta("mermaid"); const mermaidMeta = transaction.getMeta("mermaid");
const themeMeta = transaction.getMeta("theme");
const diagramToggled = mermaidMeta?.toggleDiagram !== undefined; const diagramToggled = mermaidMeta?.toggleDiagram !== undefined;
const themeToggled = themeMeta?.isDark !== undefined;
if (themeToggled) {
pluginState.isDark = themeMeta.isDark;
}
if (diagramToggled) { if (diagramToggled) {
pluginState.diagramVisibility[ pluginState.diagramVisibility[
@@ -150,7 +166,13 @@ export default function Mermaid({ name }: { name: string }) {
] = !pluginState.diagramVisibility[mermaidMeta.toggleDiagram]; ] = !pluginState.diagramVisibility[mermaidMeta.toggleDiagram];
} }
if (!diagramShown || codeBlockChanged || diagramToggled || ySyncEdit) { if (
!diagramShown ||
themeToggled ||
codeBlockChanged ||
diagramToggled ||
ySyncEdit
) {
diagramShown = true; diagramShown = true;
return getNewState({ return getNewState({
doc: transaction.doc, doc: transaction.doc,
@@ -165,6 +187,7 @@ export default function Mermaid({ name }: { name: string }) {
transaction.doc transaction.doc
), ),
diagramVisibility: pluginState.diagramVisibility, diagramVisibility: pluginState.diagramVisibility,
isDark: pluginState.isDark,
}; };
}, },
}, },
@@ -178,6 +201,7 @@ export default function Mermaid({ name }: { name: string }) {
view.dispatch(view.state.tr.setMeta("mermaid", { loaded: true })); view.dispatch(view.state.tr.setMeta("mermaid", { loaded: true }));
}, 10); }, 10);
} }
return {}; return {};
}, },
props: { props: {

View File

@@ -22,6 +22,7 @@ const colors = {
black05: "rgba(0, 0, 0, 0.05)", black05: "rgba(0, 0, 0, 0.05)",
black10: "rgba(0, 0, 0, 0.1)", black10: "rgba(0, 0, 0, 0.1)",
black50: "rgba(0, 0, 0, 0.50)", black50: "rgba(0, 0, 0, 0.50)",
black75: "rgba(0, 0, 0, 0.75)",
primary: "#0366d6", primary: "#0366d6",
yellow: "#EDBA07", yellow: "#EDBA07",
warmGrey: "#EDF2F7", warmGrey: "#EDF2F7",
@@ -204,7 +205,7 @@ export const dark = {
toastText: colors.lightBlack, toastText: colors.lightBlack,
quote: colors.almostWhite, quote: colors.almostWhite,
code: colors.almostWhite, code: colors.almostWhite,
codeBackground: colors.black, codeBackground: colors.black75,
codeBorder: colors.black50, codeBorder: colors.black50,
codeString: "#3d8fd1", codeString: "#3d8fd1",
embedBorder: colors.black50, embedBorder: colors.black50,