Repository navigation
Expand file tree
/
Copy pathdark-mode-toggle.js
More file actions
113 lines (102 loc) · 3.7 KB
/
Copy pathdark-mode-toggle.js
File metadata and controls
113 lines (102 loc) · 3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
function colorModeToggle() {
function attr(defaultVal, attrVal) {
const defaultValType = typeof defaultVal;
if (typeof attrVal !== "string" || attrVal.trim() === "") return defaultVal;
if (attrVal === "true" && defaultValType === "boolean") return true;
if (attrVal === "false" && defaultValType === "boolean") return false;
if (isNaN(attrVal) && defaultValType === "string") return attrVal;
if (!isNaN(attrVal) && defaultValType === "number") return +attrVal;
return defaultVal;
}
const htmlElement = document.documentElement;
const computed = getComputedStyle(htmlElement);
let toggleEl;
let togglePressed = "false";
const scriptTag = document.querySelector("[tr-color-vars]");
if (!scriptTag) {
console.warn("Script tag with tr-color-vars attribute not found");
return;
}
let colorModeDuration = attr(0.5, scriptTag.getAttribute("duration"));
let colorModeEase = attr("power1.out", scriptTag.getAttribute("ease"));
const cssVariables = scriptTag.getAttribute("tr-color-vars");
if (!cssVariables.length) {
console.warn("Value of tr-color-vars attribute not found");
return;
}
let lightColors = {};
let darkColors = {};
cssVariables.split(",").forEach(function (item) {
let lightValue = computed.getPropertyValue(`--color--${item}`);
let darkValue = computed.getPropertyValue(`--dark--${item}`);
if (lightValue.length) {
if (!darkValue.length) darkValue = lightValue;
lightColors[`--color--${item}`] = lightValue;
darkColors[`--color--${item}`] = darkValue;
}
});
if (!Object.keys(lightColors).length) {
console.warn("No variables found matching tr-color-vars attribute value");
return;
}
function setColors(colorObject, animate) {
if (typeof gsap !== "undefined" && animate) {
gsap.to(htmlElement, {
...colorObject,
duration: colorModeDuration,
ease: colorModeEase,
});
} else {
Object.keys(colorObject).forEach(function (key) {
htmlElement.style.setProperty(key, colorObject[key]);
});
}
}
function goDark(dark, animate) {
if (dark) {
localStorage.setItem("dark-mode", "true");
htmlElement.classList.add("dark-mode");
setColors(darkColors, animate);
togglePressed = "true";
} else {
localStorage.setItem("dark-mode", "false");
htmlElement.classList.remove("dark-mode");
setColors(lightColors, animate);
togglePressed = "false";
}
if (typeof toggleEl !== "undefined") {
toggleEl.forEach(function (element) {
element.setAttribute("aria-pressed", togglePressed);
});
}
}
function checkPreference(e) {
goDark(e.matches, false);
}
const colorPreference = window.matchMedia("(prefers-color-scheme: dark)");
colorPreference.addEventListener("change", (e) => {
checkPreference(e);
});
let storagePreference = localStorage.getItem("dark-mode");
if (storagePreference !== null) {
storagePreference === "true" ? goDark(true, false) : goDark(false, false);
} else {
checkPreference(colorPreference);
}
window.addEventListener("DOMContentLoaded", (event) => {
toggleEl = document.querySelectorAll("[tr-color-toggle]");
toggleEl.forEach(function (element) {
element.setAttribute("aria-label", "View Dark Mode");
element.setAttribute("role", "button");
element.setAttribute("aria-pressed", togglePressed);
});
document.addEventListener("click", function (e) {
const targetElement = e.target.closest("[tr-color-toggle]");
if (targetElement) {
let darkClass = htmlElement.classList.contains("dark-mode");
darkClass ? goDark(false, true) : goDark(true, true);
}
});
});
}
colorModeToggle();