diff --git a/packages/elements/__tests__/persona.test.tsx b/packages/elements/__tests__/persona.test.tsx
index 01bb276f..086ed593 100644
--- a/packages/elements/__tests__/persona.test.tsx
+++ b/packages/elements/__tests__/persona.test.tsx
@@ -691,6 +691,71 @@ describe("persona - Dynamic Color", () => {
});
});
+ it("prefers explicit light class over a dark OS preference", async () => {
+ setupPersonaTests();
+ const mockSetRgb = vi.fn();
+ mockUseViewModelInstanceColor.mockReturnValue({ setRgb: mockSetRgb });
+
+ const matchMediaSpy = vi.spyOn(window, "matchMedia").mockReturnValue({
+ addEventListener: vi.fn(),
+ matches: true,
+ removeEventListener: vi.fn(),
+ } as unknown as MediaQueryList);
+ document.documentElement.classList.add("light");
+
+ render();
+
+ await waitFor(() => {
+ expect(mockSetRgb).toHaveBeenCalledWith(0, 0, 0);
+ });
+
+ document.documentElement.classList.remove("light");
+ matchMediaSpy.mockRestore();
+ });
+
+ it("prefers explicit dark class over a light OS preference", async () => {
+ setupPersonaTests();
+ const mockSetRgb = vi.fn();
+ mockUseViewModelInstanceColor.mockReturnValue({ setRgb: mockSetRgb });
+
+ const matchMediaSpy = vi.spyOn(window, "matchMedia").mockReturnValue({
+ addEventListener: vi.fn(),
+ matches: false,
+ removeEventListener: vi.fn(),
+ } as unknown as MediaQueryList);
+ document.documentElement.classList.add("dark");
+
+ render();
+
+ await waitFor(() => {
+ expect(mockSetRgb).toHaveBeenCalledWith(255, 255, 255);
+ });
+
+ document.documentElement.classList.remove("dark");
+ matchMediaSpy.mockRestore();
+ });
+
+ it("falls back to the OS preference when no theme class is set", async () => {
+ setupPersonaTests();
+ const mockSetRgb = vi.fn();
+ mockUseViewModelInstanceColor.mockReturnValue({ setRgb: mockSetRgb });
+
+ const matchMediaSpy = vi.spyOn(window, "matchMedia").mockReturnValue({
+ addEventListener: vi.fn(),
+ matches: true,
+ removeEventListener: vi.fn(),
+ } as unknown as MediaQueryList);
+ document.documentElement.classList.remove("light", "dark");
+
+ render();
+
+ await waitFor(() => {
+ expect(mockSetRgb).toHaveBeenCalledWith(255, 255, 255);
+ });
+
+ matchMediaSpy.mockRestore();
+ });
+
it("does not set RGB for non-dynamic-color variants", async () => {
setupPersonaTests();
const mockSetRgb = vi.fn();
diff --git a/packages/elements/src/persona.tsx b/packages/elements/src/persona.tsx
index 521d23ce..b079d222 100644
--- a/packages/elements/src/persona.tsx
+++ b/packages/elements/src/persona.tsx
@@ -92,9 +92,13 @@ const sources = {
const getCurrentTheme = (): "light" | "dark" => {
if (typeof window !== "undefined") {
- if (document.documentElement.classList.contains("dark")) {
+ const { classList } = document.documentElement;
+ if (classList.contains("dark")) {
return "dark";
}
+ if (classList.contains("light")) {
+ return "light";
+ }
if (window.matchMedia?.("(prefers-color-scheme: dark)").matches) {
return "dark";
}