console.log(e.detail.theme)}
- tokens={{ "button-primary": "violet" }}
- render="toggle"
- toggle={{
- themes: ["g10", "g90"],
- labelA: "",
- labelB: "",
- }}
- select={{
- themes: ["g10", "g90"],
- labelText: "",
- }}
-/>
diff --git a/tests/Theme/Theme.test.svelte b/tests/Theme/Theme.test.svelte
new file mode 100644
index 00000000..1fadc6b3
--- /dev/null
+++ b/tests/Theme/Theme.test.svelte
@@ -0,0 +1,23 @@
+
+
+
+
+
+ {
+ console.log("update", detail);
+ }}
+ >
+
+
+
diff --git a/tests/Theme/Theme.test.ts b/tests/Theme/Theme.test.ts
new file mode 100644
index 00000000..9758855a
--- /dev/null
+++ b/tests/Theme/Theme.test.ts
@@ -0,0 +1,168 @@
+import { render, screen } from "@testing-library/svelte";
+import { tick } from "svelte";
+import { user } from "../setup-tests";
+import Theme from "./Theme.test.svelte";
+import ThemeSelect from "./ThemeSelect.test.svelte";
+import ThemeSelectCustom from "./ThemeSelectCustom.test.svelte";
+import ThemeToggle from "./ThemeToggle.test.svelte";
+import ThemeToggleCustom from "./ThemeToggleCustom.test.svelte";
+
+describe("Theme", () => {
+ let documentMock: {
+ setAttribute: ReturnType;
+ style: { setProperty: ReturnType };
+ };
+ let consoleLog: ReturnType;
+ let localStorageMock: Record;
+ let originalLocalStorage: Storage;
+
+ beforeEach(() => {
+ documentMock = {
+ setAttribute: vi.spyOn(document.documentElement, "setAttribute"),
+ style: {
+ setProperty: vi.spyOn(document.documentElement.style, "setProperty"),
+ },
+ };
+ consoleLog = vi.spyOn(console, "log");
+ originalLocalStorage = global.localStorage;
+ localStorageMock = {};
+
+ global.localStorage = {
+ getItem: vi.fn((key) => localStorageMock[key] || null),
+ setItem: vi.fn((key, value) => {
+ localStorageMock[key] = value;
+ }),
+ removeItem: vi.fn((key) => {
+ delete localStorageMock[key];
+ }),
+ clear: vi.fn(() => {
+ localStorageMock = {};
+ }),
+ length: 0,
+ key: vi.fn(),
+ };
+ });
+
+ afterEach(() => {
+ vi.restoreAllMocks();
+ global.localStorage = originalLocalStorage;
+ localStorage.clear();
+ localStorageMock = {};
+ });
+
+ it("should set default theme to white", () => {
+ render(Theme);
+ expect(documentMock.setAttribute).toHaveBeenCalledWith("theme", "white");
+ });
+
+ it("should update theme attribute when theme changes", async () => {
+ const { component } = render(Theme);
+
+ component.$set({ theme: "g100" });
+ await tick();
+
+ expect(documentMock.setAttribute).toHaveBeenCalledWith("theme", "g100");
+ expect(consoleLog).toHaveBeenCalledWith("update", { theme: "g100" });
+ });
+
+ it("should apply custom tokens", async () => {
+ const tokens = {
+ "interactive-01": "#ff0000",
+ "ui-background": "#ffffff",
+ };
+
+ render(Theme, { props: { tokens } });
+ await tick();
+
+ expect(documentMock.style.setProperty).toHaveBeenCalledWith(
+ "--cds-interactive-01",
+ "#ff0000",
+ );
+ expect(documentMock.style.setProperty).toHaveBeenCalledWith(
+ "--cds-ui-background",
+ "#ffffff",
+ );
+ });
+
+ it("should persist theme in localStorage when persist is true", async () => {
+ render(Theme, { props: { persist: true } });
+ await tick();
+
+ expect(localStorage.setItem).toHaveBeenCalledWith("theme", "white");
+ });
+
+ it("should load persisted theme from localStorage", async () => {
+ localStorageMock["theme"] = "g90";
+
+ render(Theme, { props: { persist: true } });
+ await tick();
+
+ expect(documentMock.setAttribute).toHaveBeenCalledWith("theme", "g90");
+ });
+
+ it("should warn on invalid theme", async () => {
+ const consoleWarn = vi.spyOn(console, "warn");
+ const { component } = render(Theme);
+
+ // @ts-ignore - Testing invalid theme
+ component.$set({ theme: "invalid" });
+ await tick();
+
+ expect(consoleWarn).toHaveBeenCalledWith(
+ expect.stringContaining('invalid theme "invalid"'),
+ );
+ });
+
+ it("should render toggle when render prop is set to toggle", async () => {
+ render(ThemeToggle);
+
+ const toggle = screen.getByLabelText("Dark mode");
+ expect(toggle).toBeInTheDocument();
+ expect(toggle).toHaveAttribute("type", "checkbox");
+
+ await user.click(toggle);
+ expect(consoleLog).toHaveBeenCalledWith("update", { theme: "g100" });
+
+ await user.click(toggle);
+ expect(consoleLog).toHaveBeenCalledWith("update", { theme: "white" });
+ });
+
+ it("should render custom toggle when render prop is set to toggle and custom toggle options are provided", async () => {
+ render(ThemeToggleCustom);
+
+ const toggle = screen.getAllByText("Enable dark mode")[0];
+ expect(toggle).toBeInTheDocument();
+
+ await user.click(toggle);
+ expect(consoleLog).toHaveBeenCalledWith("update", { theme: "g80" });
+
+ await user.click(toggle);
+ expect(consoleLog).toHaveBeenCalledWith("update", { theme: "g10" });
+ });
+
+ it("should render select when render prop is set to select", async () => {
+ render(ThemeSelect);
+
+ const select = screen.getByLabelText("Themes");
+ expect(select).toBeInTheDocument();
+
+ await user.selectOptions(select, "g100");
+ expect(consoleLog).toHaveBeenCalledWith("update", { theme: "g100" });
+
+ await user.selectOptions(select, "white");
+ expect(consoleLog).toHaveBeenCalledWith("update", { theme: "white" });
+ });
+
+ it("should render custom select when render prop is set to select and custom select options are provided", async () => {
+ render(ThemeSelectCustom);
+
+ const select = screen.getByLabelText("Select a theme");
+ expect(select).toBeInTheDocument();
+
+ await user.selectOptions(select, "g100");
+ expect(consoleLog).toHaveBeenCalledWith("update", { theme: "g100" });
+
+ await user.selectOptions(select, "white");
+ expect(consoleLog).toHaveBeenCalledWith("update", { theme: "white" });
+ });
+});
diff --git a/tests/Theme/ThemeSelect.test.svelte b/tests/Theme/ThemeSelect.test.svelte
new file mode 100644
index 00000000..3648b3ef
--- /dev/null
+++ b/tests/Theme/ThemeSelect.test.svelte
@@ -0,0 +1,10 @@
+
+
+ {
+ console.log("update", detail);
+ }}
+/>
diff --git a/tests/Theme/ThemeSelectCustom.test.svelte b/tests/Theme/ThemeSelectCustom.test.svelte
new file mode 100644
index 00000000..93fbfea3
--- /dev/null
+++ b/tests/Theme/ThemeSelectCustom.test.svelte
@@ -0,0 +1,15 @@
+
+
+ {
+ console.log("update", detail);
+ }}
+/>
diff --git a/tests/Theme/ThemeToggle.test.svelte b/tests/Theme/ThemeToggle.test.svelte
new file mode 100644
index 00000000..6512a23d
--- /dev/null
+++ b/tests/Theme/ThemeToggle.test.svelte
@@ -0,0 +1,10 @@
+
+
+ {
+ console.log("update", detail);
+ }}
+/>
diff --git a/tests/Theme/ThemeToggleCustom.test.svelte b/tests/Theme/ThemeToggleCustom.test.svelte
new file mode 100644
index 00000000..c3f8a01e
--- /dev/null
+++ b/tests/Theme/ThemeToggleCustom.test.svelte
@@ -0,0 +1,17 @@
+
+
+ {
+ console.log("update", detail);
+ }}
+/>