Skip to content

Commit 051a4b5

Browse files
committed
feat: CustomEvent in 2 states switch script
1 parent ad2426c commit 051a4b5

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

scripts/ColorSchemeSwitchTwoStates/js/switch-script.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
};
1010

1111
window.inlineScripts.switchColorScheme = function () {
12+
const previousScheme = localStorage.colorScheme;
1213
const isDark = document.documentElement.classList.contains("__DARK__");
1314

1415
if (isDark) {
@@ -18,6 +19,15 @@
1819
setColorScheme("__DARK__");
1920
localStorage.colorScheme = "__DARK__";
2021
}
22+
23+
const event = new CustomEvent("colorSchemeChanged", {
24+
detail: {
25+
previousScheme: previousScheme,
26+
currentScheme: localStorage.colorScheme,
27+
},
28+
});
29+
30+
document.dispatchEvent(event);
2131
};
2232

2333
document.addEventListener("keydown", (event) => {

tests/js/color-scheme-switch-two-states/switch-script.test.js

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ function dispatchKeydown(key, { ctrlKey = false, altKey = false, metaKey = false
4444

4545
// IIFE = Immediately Invoked Function Expression
4646
describe("ColorSchemeSwitchScript.js IIFE behavior (two states)", () => {
47+
let keydownListeners = [];
48+
4749
beforeEach(() => {
4850
document.documentElement.className = "";
4951
try {
@@ -58,6 +60,26 @@ describe("ColorSchemeSwitchScript.js IIFE behavior (two states)", () => {
5860
clear: () => store.clear(),
5961
};
6062
}
63+
64+
// Clear window.inlineScripts before each test
65+
if (window.inlineScripts) {
66+
delete window.inlineScripts.switchColorScheme;
67+
}
68+
69+
// Remove any previously tracked keydown listeners
70+
keydownListeners.forEach((listener) => {
71+
document.removeEventListener("keydown", listener);
72+
});
73+
keydownListeners = [];
74+
75+
// Store original addEventListener to track new listeners
76+
const originalAddEventListener = document.addEventListener.bind(document);
77+
document.addEventListener = function (type, listener, options) {
78+
if (type === "keydown") {
79+
keydownListeners.push(listener);
80+
}
81+
return originalAddEventListener(type, listener, options);
82+
};
6183
});
6284

6385
it("toggles dark class and updates localStorage on default key press", () => {
@@ -204,4 +226,95 @@ describe("ColorSchemeSwitchScript.js IIFE behavior (two states)", () => {
204226
// Clean up
205227
document.body.removeChild(input);
206228
});
229+
230+
it("dispatches colorSchemeChanged event when toggling color scheme", () => {
231+
runSwitchScript();
232+
233+
let eventDetail = null;
234+
235+
// Listen for the custom event - first toggle
236+
const handler1 = (e) => {
237+
eventDetail = e.detail;
238+
};
239+
document.addEventListener("colorSchemeChanged", handler1, { once: true });
240+
241+
// Initially no scheme is set
242+
expect(localStorage.getItem("colorScheme")).toBe(null);
243+
244+
// Toggle to dark
245+
dispatchKeydown(DEFAULT_TOGGLE_KEY);
246+
247+
expect(eventDetail).not.toBe(null);
248+
expect(eventDetail).toEqual({
249+
previousScheme: undefined,
250+
currentScheme: DEFAULT_DARK,
251+
});
252+
253+
// Reset for next toggle
254+
eventDetail = null;
255+
256+
// Listen for the custom event - second toggle
257+
const handler2 = (e) => {
258+
eventDetail = e.detail;
259+
};
260+
document.addEventListener("colorSchemeChanged", handler2, { once: true });
261+
262+
// Toggle back to light
263+
dispatchKeydown(DEFAULT_TOGGLE_KEY);
264+
265+
expect(eventDetail).not.toBe(null);
266+
expect(eventDetail).toEqual({
267+
previousScheme: DEFAULT_DARK,
268+
currentScheme: DEFAULT_LIGHT,
269+
});
270+
});
271+
272+
it("dispatches colorSchemeChanged event when calling switchColorScheme directly", () => {
273+
runSwitchScript();
274+
275+
let eventDetail = null;
276+
277+
// Listen for the custom event
278+
const handler = (e) => {
279+
eventDetail = e.detail;
280+
};
281+
document.addEventListener("colorSchemeChanged", handler, { once: true });
282+
283+
// Set initial scheme
284+
localStorage.setItem("colorScheme", DEFAULT_LIGHT);
285+
286+
// Call switchColorScheme directly
287+
window.inlineScripts.switchColorScheme();
288+
289+
expect(eventDetail).not.toBe(null);
290+
expect(eventDetail).toEqual({
291+
previousScheme: DEFAULT_LIGHT,
292+
currentScheme: DEFAULT_DARK,
293+
});
294+
});
295+
296+
it("includes correct previousScheme in event detail when scheme was previously set", () => {
297+
runSwitchScript();
298+
299+
// Set initial scheme to dark
300+
localStorage.setItem("colorScheme", DEFAULT_DARK);
301+
document.documentElement.classList.add(DEFAULT_DARK);
302+
303+
let eventDetail = null;
304+
305+
// Listen for the custom event
306+
const handler = (e) => {
307+
eventDetail = e.detail;
308+
};
309+
document.addEventListener("colorSchemeChanged", handler, { once: true });
310+
311+
// Toggle to light
312+
dispatchKeydown(DEFAULT_TOGGLE_KEY);
313+
314+
expect(eventDetail).not.toBe(null);
315+
expect(eventDetail).toEqual({
316+
previousScheme: DEFAULT_DARK,
317+
currentScheme: DEFAULT_LIGHT,
318+
});
319+
});
207320
});

0 commit comments

Comments
 (0)