"use client"; import { MotionConfig } from "framer-motion"; import * as React from "react"; /** * The provider for Coline Sites (SDK 2.1). A site has no Coline host to * hand it a theme, so this follows the visitor's light or dark preference * (or a fixed `theme`) by toggling `.dark` on the root element, which is * how every component's tokens switch. Wrap the site's page in it once, * instead of `ColineAppProvider`, which only works inside Coline. */ export type ColineSiteTheme = "system" | "light" | "dark"; const SiteColorSchemeContext = React.createContext<"light" | "dark">("light"); function systemScheme(): "light" | "dark" { return typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; } export function ColineSiteProvider({ theme = "system", children, }: { /** `system` (the default) follows the visitor's device and changes with it. */ theme?: ColineSiteTheme; children: React.ReactNode; }) { const [system, setSystem] = React.useState<"light" | "dark">(systemScheme); React.useEffect(() => { if (theme !== "system") return; const media = window.matchMedia("(prefers-color-scheme: dark)"); const update = () => setSystem(media.matches ? "dark" : "light"); update(); media.addEventListener("change", update); return () => media.removeEventListener("change", update); }, [theme]); const scheme = theme === "system" ? system : theme; React.useLayoutEffect(() => { const root = document.documentElement; root.classList.toggle("dark", scheme === "dark"); root.style.colorScheme = scheme; }, [scheme]); return ( {children} ); } /** The light or dark scheme a site is showing. */ export function useSiteColorScheme(): "light" | "dark" { return React.useContext(SiteColorSchemeContext); }