fix: update wysiwyg color on theme change (#10618)
This commit is contained in:
@@ -8,7 +8,10 @@ import {
|
|||||||
KEYS,
|
KEYS,
|
||||||
FONT_FAMILY,
|
FONT_FAMILY,
|
||||||
TEXT_ALIGN,
|
TEXT_ALIGN,
|
||||||
|
THEME,
|
||||||
VERTICAL_ALIGN,
|
VERTICAL_ALIGN,
|
||||||
|
applyDarkModeFilter,
|
||||||
|
tinycolor,
|
||||||
} from "@excalidraw/common";
|
} from "@excalidraw/common";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
@@ -22,6 +25,7 @@ import { Keyboard, Pointer, UI } from "../tests/helpers/ui";
|
|||||||
import { getTextEditor, updateTextEditor } from "../tests/queries/dom";
|
import { getTextEditor, updateTextEditor } from "../tests/queries/dom";
|
||||||
import {
|
import {
|
||||||
GlobalTestState,
|
GlobalTestState,
|
||||||
|
act,
|
||||||
render,
|
render,
|
||||||
screen,
|
screen,
|
||||||
unmountComponent,
|
unmountComponent,
|
||||||
@@ -1662,4 +1666,60 @@ describe("textWysiwyg", () => {
|
|||||||
expect(h.elements[1].angle).toBe(30);
|
expect(h.elements[1].angle).toBe(30);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Test theme change", () => {
|
||||||
|
const { h } = window;
|
||||||
|
|
||||||
|
// Helper to compare colors (browser may return rgb format)
|
||||||
|
const colorsAreEqual = (color1: string, color2: string) => {
|
||||||
|
return tinycolor(color1).toHex() === tinycolor(color2).toHex();
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await render(
|
||||||
|
<Excalidraw
|
||||||
|
handleKeyboardGlobally={true}
|
||||||
|
initialData={{
|
||||||
|
appState: {
|
||||||
|
theme: THEME.LIGHT,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
API.setElements([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should update textarea color when theme changes to dark mode and back", async () => {
|
||||||
|
const originalColor = "#ff0000";
|
||||||
|
|
||||||
|
const textElement = API.createElement({
|
||||||
|
type: "text",
|
||||||
|
text: "test",
|
||||||
|
strokeColor: originalColor,
|
||||||
|
});
|
||||||
|
|
||||||
|
API.setElements([textElement]);
|
||||||
|
|
||||||
|
mouse.doubleClickOn(textElement as ExcalidrawTextElement);
|
||||||
|
|
||||||
|
const editor = await getTextEditor({ waitForEditor: true });
|
||||||
|
|
||||||
|
expect(colorsAreEqual(editor.style.color, originalColor)).toBe(true);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
h.setState({ theme: THEME.DARK });
|
||||||
|
// Trigger element mutation to fire onChange callback
|
||||||
|
h.app.scene.mutateElement(textElement, {});
|
||||||
|
});
|
||||||
|
expect(
|
||||||
|
colorsAreEqual(editor.style.color, applyDarkModeFilter(originalColor)),
|
||||||
|
).toBe(true);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
h.setState({ theme: THEME.LIGHT });
|
||||||
|
h.app.scene.mutateElement(textElement, {});
|
||||||
|
});
|
||||||
|
expect(colorsAreEqual(editor.style.color, originalColor)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -132,7 +132,11 @@ export const textWysiwyg = ({
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let LAST_THEME = app.state.theme;
|
||||||
|
|
||||||
const updateWysiwygStyle = () => {
|
const updateWysiwygStyle = () => {
|
||||||
|
LAST_THEME = app.state.theme;
|
||||||
|
|
||||||
const appState = app.state;
|
const appState = app.state;
|
||||||
const updatedTextElement = app.scene.getElement<ExcalidrawTextElement>(id);
|
const updatedTextElement = app.scene.getElement<ExcalidrawTextElement>(id);
|
||||||
|
|
||||||
@@ -598,6 +602,7 @@ export const textWysiwyg = ({
|
|||||||
window.removeEventListener("blur", handleSubmit);
|
window.removeEventListener("blur", handleSubmit);
|
||||||
window.removeEventListener("beforeunload", handleSubmit);
|
window.removeEventListener("beforeunload", handleSubmit);
|
||||||
unbindUpdate();
|
unbindUpdate();
|
||||||
|
unsubOnChange();
|
||||||
unbindOnScroll();
|
unbindOnScroll();
|
||||||
|
|
||||||
editable.remove();
|
editable.remove();
|
||||||
@@ -696,6 +701,13 @@ export const textWysiwyg = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// FIXME after we start emitting updates from Store for appState.theme
|
||||||
|
const unsubOnChange = app.onChangeEmitter.on((elements) => {
|
||||||
|
if (app.state.theme !== LAST_THEME) {
|
||||||
|
updateWysiwygStyle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// handle updates of textElement properties of editing element
|
// handle updates of textElement properties of editing element
|
||||||
const unbindUpdate = app.scene.onUpdate(() => {
|
const unbindUpdate = app.scene.onUpdate(() => {
|
||||||
updateWysiwygStyle();
|
updateWysiwygStyle();
|
||||||
|
|||||||
Reference in New Issue
Block a user