function setInitialColorModeClass() {
const htmlElement = document.documentElement;
// Default to light mode
htmlElement.classList.remove("dark-mode");
}
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";
// Configuration embedded within the script
let colorModeDuration = attr(0.5, "0.5"); // Default duration
let colorModeEase = attr("power1.out", "power1.out"); // Default ease function
const cssVariables = "text,background,button-primary,alternate-text,subtle-text,border-color,card-background"; // Variables list
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");
togglePressed = "true";
} else {
localStorage.setItem("dark-mode", "false");
htmlElement.classList.remove("dark-mode");
togglePressed = "false";
}
if (typeof toggleEl !== "undefined") {
toggleEl.forEach(function (element) {
element.setAttribute("aria-pressed", togglePressed);
});
}
// Update colors
setColors(dark ? darkColors : lightColors, animate);
// Update grid-screenshot_svg classes based on dark mode
const gridScreenshotSvgElements = document.querySelectorAll('.grid-screenshot_svg');
gridScreenshotSvgElements.forEach(function(element) {
if (dark) {
element.classList.add("dark");
element.classList.remove("light");
} else {
element.classList.remove("dark");
element.classList.remove("light"); // Ensure no class is added by default
}
});
}
function checkPreference(e) {
goDark(e.matches, false);
}
const colorPreference = window.matchMedia("(prefers-color-scheme: dark)");
colorPreference.addEventListener("change", (e) => {
checkPreference(e);
});
let osPreference = false; // Default to light mode
let storagePreference = localStorage.getItem("dark-mode");
if (storagePreference !== null) {
osPreference = null;
storagePreference === "true" ? goDark(true, false) : goDark(false, false);
}
if (osPreference !== null) {
goDark(osPreference, false);
}
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);
element.addEventListener("click", function () {
let darkClass = htmlElement.classList.contains("dark-mode");
darkClass ? goDark(false, true) : goDark(true, true);
// Save the state of tr-color-toggle
localStorage.setItem("color-mode", !darkClass);
// Update grid-screenshot_svg classes in real-time
updateDynamicElementsColorMode();
});
});
// New toggle logic for logo mode
let logoMode = localStorage.getItem("logo-mode") || "false";
function toggleLogoMode() {
logoMode = logoMode === "true" ? "false" : "true";
localStorage.setItem("logo-mode", logoMode);
updateDynamicElementsColorMode(); // Ensure dynamic elements are updated when logo mode changes
}
const logoModeEl = document.querySelectorAll("[tr-logo-mode]");
logoModeEl.forEach(function (element) {
element.setAttribute("aria-label", "Toggle Logo Mode");
element.setAttribute("role", "button");
element.setAttribute("aria-pressed", logoMode);
element.addEventListener("click", function () {
toggleLogoMode();
element.setAttribute("aria-pressed", logoMode);
// When logo mode is toggled, update the dynamic elements
updateDynamicElementsColorMode();
});
});
// Ensure tr-color-toggle state is remembered
const colorToggleState = localStorage.getItem("color-mode");
if (colorToggleState === "true") {
// Toggle on if previously saved state is true
goDark(true, false);
} else {
// Toggle off if previously saved state is false or not set
goDark(false, false);
}
});
}
function updateDynamicElementsColorMode() {
const gridScreenshotSvgElements = document.querySelectorAll('.grid-screenshot_svg');
const logoMode = localStorage.getItem("logo-mode");
const colorToggleState = localStorage.getItem("color-mode");
gridScreenshotSvgElements.forEach(function(element) {
if (logoMode === "true") {
// Remove dark/light classes if logo mode is active
element.classList.remove("dark", "light");
} else if (colorToggleState === "true") {
// Add dark class if color toggle state is true
element.classList.add("dark");
element.classList.remove("light");
} else {
// Default to no class if color toggle state is false
element.classList.remove("dark", "light");
}
});
}
function observeDynamicElements() {
const observer = new MutationObserver(function(mutationsList, observer) {
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
updateDynamicElementsColorMode();
}
}
});
observer.observe(document.body, { childList: true, subtree: true });
}
document.addEventListener("DOMContentLoaded", function() {
colorModeToggle();
setInitialColorModeClass();
observeDynamicElements();
updateDynamicElementsColorMode(); // Ensure dynamic elements are updated on page load
});