"use client"; import * as React from "react"; import { ThemeProvider as NextThemesProvider, useTheme as useNextTheme, } from "next-themes"; import type { ThemeProviderProps as NextThemesProviderProps } from "next-themes/dist/types"; /** * ODS theme system — thin wrapper over `next-themes`. * * We deliberately do NOT hand-roll a provider/no-flash script: `next-themes` * is already a dependency, is battle-tested in Next.js (App & Pages router), * injects its own pre-paint anti-flash script, handles SSR + localStorage + * cross-tab sync, and also works in plain React (Vite/Tauri). * * Product model (locked): a MANUAL light/dark switch, default DARK, * persisted to localStorage. No "system" mode (`enableSystem={false}`). * * Drives styling by setting `data-theme="light|dark"` on ; * `src/styles/ods-colors.css` swaps the `--ods-*` primitives accordingly. * * Public API exposed by this module: * • `` — preconfigured next-themes provider. * • `useTheme()` — raw next-themes hook (advanced cases). * • `useThemeToggle()`— headless convenience hook for building toggle UI * in consumer apps (no styled component on purpose; * apps own their button visuals via the lib's * existing ` * * The mount gate avoids hydration mismatch (next-themes only knows the * persisted preference on the client after mount). */ export function useThemeToggle(): UseThemeToggleResult { const { resolvedTheme, theme, setTheme } = useTheme(); const [mounted, setMounted] = React.useState(false); React.useEffect(() => setMounted(true), []); const active: Theme = mounted ? resolvedTheme === "light" || theme === "light" ? "light" : "dark" : DEFAULT_THEME; const setOdsTheme = React.useCallback( (next: Theme) => setTheme(next), [setTheme], ); const toggle = React.useCallback( () => setTheme(active === "dark" ? "light" : "dark"), [active, setTheme], ); return { mounted, theme: active, isDark: active === "dark", isLight: active === "light", toggle, setTheme: setOdsTheme, }; }