"use client"; import { useEffect, useState } from "react"; import { useTheme, resolveTheme, DARK_SURFACES } from "./theme-provider"; // The themes whose *surfaces* are dark (see app/globals.css) come from the // provider's single source of truth -- currently Dark, Ocean, Pine, Plum, // Midnight, Ember, Rosewood. Anything that used to compare // `resolvedTheme === "dark"` to pick a color variant (group card // fills/strokes, markdown widget color modes, ...) uses this instead. function useMounted(): boolean { const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); }, []); return mounted; } /** * True when the active theme has dark surfaces (Dark, Ocean, Pine, Plum, * Midnight, Ember, Rosewood, Cyberpunk). * * Reactive to UI theme switches: the value is derived from the provider's * theme state (the single source of truth), so the moment `setTheme` fires, * every consumer re-renders with the new variant in the same commit -- no * stale card colors, no manual refresh needed. * * Hydration-safe: until mounted we always report "light", matching the * server render (the no-FOUC script in app/layout.tsx covers the CSS side * of that first frame). */ export function isDarkTheme(): boolean { const mounted = useMounted(); const { theme } = useTheme(); if (!mounted) return false; return DARK_SURFACES.includes(resolveTheme(theme)); } /** * The `data-color-mode` value the markdown editor/preview widgets expect. * They only understand light/dark, so the light looks (default, sunset, * meadow, honey, rose, lavender, slate) report as light and the dark looks * report as dark. */ export function colorModeFromTheme(): "light" | "dark" { return isDarkTheme() ? "dark" : "light"; }