feat(web): MS15 Phase 1 — Design System & App Shell (#451)
All checks were successful
ci/woodpecker/push/web Pipeline was successful
All checks were successful
ci/woodpecker/push/web Pipeline was successful
Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #451.
This commit is contained in:
@@ -29,6 +29,21 @@ function getStoredTheme(): Theme {
|
||||
return "system";
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the resolved theme to the <html> element via data-theme attribute.
|
||||
* The default (no attribute or data-theme="dark") renders dark — dark is default.
|
||||
* Light theme requires data-theme="light".
|
||||
*/
|
||||
function applyThemeAttribute(resolved: "light" | "dark"): void {
|
||||
const root = document.documentElement;
|
||||
if (resolved === "light") {
|
||||
root.setAttribute("data-theme", "light");
|
||||
} else {
|
||||
// Remove the attribute so the default (dark) CSS variables apply.
|
||||
root.removeAttribute("data-theme");
|
||||
}
|
||||
}
|
||||
|
||||
interface ThemeProviderProps {
|
||||
children: ReactNode;
|
||||
defaultTheme?: Theme;
|
||||
@@ -46,19 +61,18 @@ export function ThemeProvider({
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
const storedTheme = getStoredTheme();
|
||||
const resolved = storedTheme === "system" ? getSystemTheme() : storedTheme;
|
||||
setThemeState(storedTheme);
|
||||
setResolvedTheme(storedTheme === "system" ? getSystemTheme() : storedTheme);
|
||||
setResolvedTheme(resolved);
|
||||
applyThemeAttribute(resolved);
|
||||
}, []);
|
||||
|
||||
// Apply theme class to html element
|
||||
// Apply theme via data-theme attribute on html element
|
||||
useEffect(() => {
|
||||
if (!mounted) return;
|
||||
|
||||
const root = document.documentElement;
|
||||
const resolved = theme === "system" ? getSystemTheme() : theme;
|
||||
|
||||
root.classList.remove("light", "dark");
|
||||
root.classList.add(resolved);
|
||||
applyThemeAttribute(resolved);
|
||||
setResolvedTheme(resolved);
|
||||
}, [theme, mounted]);
|
||||
|
||||
@@ -68,9 +82,9 @@ export function ThemeProvider({
|
||||
|
||||
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
const handleChange = (e: MediaQueryListEvent): void => {
|
||||
setResolvedTheme(e.matches ? "dark" : "light");
|
||||
document.documentElement.classList.remove("light", "dark");
|
||||
document.documentElement.classList.add(e.matches ? "dark" : "light");
|
||||
const resolved = e.matches ? "dark" : "light";
|
||||
setResolvedTheme(resolved);
|
||||
applyThemeAttribute(resolved);
|
||||
};
|
||||
|
||||
mediaQuery.addEventListener("change", handleChange);
|
||||
|
||||
Reference in New Issue
Block a user