Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 1x 3x 3x 3x 1x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x | import {useEffect, useState} from "react";
// Type for available themes
export type ThemeName = "system" | "light" | "dark" | "cupcake" | "cyberpunk" | "corporate" | "forest" | "aqua";
function isDarkMode(): boolean {
return matchMedia && matchMedia("(prefers-color-scheme: dark)").matches;
}
export function useTheme() {
const [theme, setThemeState] = useState<ThemeName>(() => {
// Check local storage or default to light theme
const savedTheme = localStorage.getItem("app-theme") as ThemeName | null;
return savedTheme || "system";
});
const [textSize, setTextSize] = useState<number>(() => {
// Check local storage or default to 16
const savedTextSize = localStorage.getItem("app-text-size");
return savedTextSize ? Number(savedTextSize) : 16;
});
// Set theme and persist to local storage
function setTheme(newTheme: ThemeName) {
setThemeState(newTheme);
localStorage.setItem("app-theme", newTheme);
}
// Update text size and persist to local storage
function updateTextSize(size: number) {
setTextSize(size);
localStorage.setItem("app-text-size", size.toString());
// Set the base font size on the html element
document.documentElement.style.fontSize = `${size}px`;
// Set a scaling factor for non-text elements
const scaleFactor = size / 16;
document.documentElement.style.setProperty("--scale-factor", scaleFactor.toString());
}
// Apply theme and initial text size
useEffect(() => {
let newTheme: ThemeName;
if (theme === "system") {
newTheme = isDarkMode() ? "dark" : "light";
} else {
newTheme = theme;
}
document.documentElement.setAttribute("data-theme", newTheme);
function updateSystemTheme(event: MediaQueryListEvent) {
if (theme === "system") {
const newTheme = event.matches ? "dark" : "light";
document.documentElement.setAttribute("data-theme", newTheme);
}
}
if (matchMedia) {
const darkModeMatchMedia = matchMedia("(prefers-color-scheme: dark)");
darkModeMatchMedia.addEventListener("change", updateSystemTheme);
return () => darkModeMatchMedia.removeEventListener("change", updateSystemTheme);
}
}, [theme]);
useEffect(() => updateTextSize(textSize), [textSize]);
return {
theme,
setTheme,
textSize,
setTextSize: updateTextSize
};
}
|