'use strict';

var jsxRuntime = require('../../node_modules/.pnpm/react@18.2.0/node_modules/react/jsx-runtime.cjs');
var React = require('react');

const colorSchemes = ["light", "dark"];
const MEDIA = "(prefers-color-scheme: dark)";
const isServer = typeof window === "undefined";
const ThemeContext = React.createContext(undefined);
const defaultContext = { setTheme: (_) => { }, themes: [] };
const useTheme = () => React.useContext(ThemeContext) ?? defaultContext;
const ThemeProvider = (props) => {
    const context = React.useContext(ThemeContext);
    // Ignore nested context providers, just passthrough children
    if (context)
        return jsxRuntime.jsxRuntimeExports.jsx(React.Fragment, { children: props.children });
    return jsxRuntime.jsxRuntimeExports.jsx(Theme, { ...props });
};
const defaultThemes = ["light", "dark"];
const Theme = ({ forcedTheme, disableTransitionOnChange = false, enableSystem = true, enableColorScheme = true, storageKey = "theme", themes = defaultThemes, defaultTheme = enableSystem ? "system" : "light", attribute = "data-theme", value, children, nonce, style = "modern", accentColor = "indigo", grayColor = "gray", }) => {
    const [theme, setThemeState] = React.useState(() => getTheme(storageKey, defaultTheme));
    const [resolvedTheme, setResolvedTheme] = React.useState(() => getTheme(storageKey));
    const attrs = !value ? themes : Object.values(value);
    const applyTheme = React.useCallback((theme) => {
        let resolved = theme;
        if (!resolved)
            return;
        // If theme is system, resolve it before setting theme
        if (theme === "system" && enableSystem) {
            resolved = getSystemTheme();
        }
        const name = value ? value[resolved] : resolved;
        const enable = disableTransitionOnChange ? disableAnimation() : null;
        const d = document.documentElement;
        if (attribute === "class") {
            d.classList.remove(...attrs);
            if (name)
                d.classList.add(name);
        }
        else {
            if (name) {
                d.setAttribute(attribute, name);
            }
            else {
                d.removeAttribute(attribute);
            }
        }
        d.setAttribute('data-style', style);
        d.setAttribute('data-accent-color', accentColor);
        d.setAttribute('data-gray-color', grayColor);
        if (enableColorScheme) {
            const fallback = colorSchemes.includes(defaultTheme)
                ? defaultTheme
                : null;
            const colorScheme = colorSchemes.includes(resolved) ? resolved : fallback;
            // @ts-ignore
            d.style.colorScheme = colorScheme;
        }
        enable?.();
    }, [style, accentColor, grayColor, attribute, attrs, value, enableSystem, enableColorScheme, defaultTheme]);
    const setTheme = React.useCallback((theme) => {
        setThemeState(theme);
        // Save to storage
        try {
            localStorage.setItem(storageKey, theme);
        }
        catch (e) {
            // Unsupported
        }
    }, [forcedTheme]);
    const handleMediaQuery = React.useCallback((e) => {
        const resolved = getSystemTheme(e);
        setResolvedTheme(resolved);
        if (theme === "system" && enableSystem && !forcedTheme) {
            applyTheme("system");
        }
    }, [theme, forcedTheme]);
    // Always listen to System preference
    React.useEffect(() => {
        const media = window.matchMedia(MEDIA);
        media.addEventListener('change', handleMediaQuery);
        handleMediaQuery(media);
        return () => media.removeEventListener('change', handleMediaQuery);
    }, [handleMediaQuery]);
    // localStorage event handling
    React.useEffect(() => {
        const handleStorage = (e) => {
            if (e.key !== storageKey) {
                return;
            }
            // If default theme set, use it if localstorage === null (happens on local storage manual deletion)
            const theme = e.newValue || defaultTheme;
            setTheme(theme);
        };
        window.addEventListener("storage", handleStorage);
        return () => window.removeEventListener("storage", handleStorage);
    }, [setTheme]);
    // Whenever theme or forcedTheme changes, apply it
    React.useEffect(() => {
        // @ts-ignore
        applyTheme(forcedTheme ?? theme);
    }, [forcedTheme, theme]);
    const providerValue = React.useMemo(() => ({
        theme,
        setTheme,
        forcedTheme,
        resolvedTheme: theme === "system" ? resolvedTheme : theme,
        themes: enableSystem ? [...themes, "system"] : themes,
        systemTheme: (enableSystem ? resolvedTheme : undefined),
        style,
        accentColor,
        grayColor,
    }), [theme, setTheme, forcedTheme, resolvedTheme, enableSystem, themes, style, accentColor, grayColor]);
    return (jsxRuntime.jsxRuntimeExports.jsxs(ThemeContext.Provider, { value: providerValue, children: [jsxRuntime.jsxRuntimeExports.jsx(ThemeScript, { forcedTheme,
                disableTransitionOnChange,
                enableSystem,
                enableColorScheme,
                storageKey,
                themes,
                defaultTheme,
                attribute,
                value,
                children,
                attrs,
                nonce,
                style,
                accentColor,
                grayColor }), children] }));
};
const ThemeScript = React.memo(({ forcedTheme, storageKey, attribute, enableSystem, enableColorScheme, defaultTheme, value, attrs, nonce, style, accentColor, grayColor, }) => {
    const defaultSystem = defaultTheme === "system";
    // Code-golfing the amount of characters in the script
    const optimization = (() => {
        if (attribute === "class") {
            const removeClasses = `c.remove(${attrs
                .map((t) => `'${t}'`)
                .join(",")})`;
            return `var d=document.documentElement,c=d.classList;${removeClasses};`;
        }
        else {
            return `var d=document.documentElement,n='${attribute}',s='setAttribute';`;
        }
    })();
    const fallbackColorScheme = (() => {
        if (!enableColorScheme) {
            return "";
        }
        const fallback = colorSchemes.includes(defaultTheme)
            ? defaultTheme
            : null;
        if (fallback) {
            return `if(e==='light'||e==='dark'||!e)d.style.colorScheme=e||'${defaultTheme}'`;
        }
        else {
            return `if(e==='light'||e==='dark')d.style.colorScheme=e`;
        }
    })();
    const updateDOM = (name, literal = false, setColorScheme = true) => {
        const resolvedName = value ? value[name] : name;
        const val = literal ? name + `|| ''` : `'${resolvedName}'`;
        let text = "";
        // MUCH faster to set colorScheme alongside HTML attribute/class
        // as it only incurs 1 style recalculation rather than 2
        // This can save over 250ms of work for pages with big DOM
        if (enableColorScheme &&
            setColorScheme &&
            !literal &&
            colorSchemes.includes(name)) {
            text += `d.style.colorScheme = '${name}';`;
        }
        if (attribute === "class") {
            if (literal || resolvedName) {
                text += `c.add(${val})`;
            }
            else {
                text += `null`;
            }
        }
        else {
            if (resolvedName) {
                text += `d[s](n,${val})`;
            }
        }
        return text;
    };
    const scriptSrc = (() => {
        if (forcedTheme) {
            return `!function(){${optimization}${updateDOM(forcedTheme)};d.setAttribute('data-style','${style}');d.setAttribute('data-accent-color','${accentColor}');d.setAttribute('data-gray-color','${grayColor}');}()`;
        }
        if (enableSystem) {
            return `!function(){try{${optimization}var e=localStorage.getItem('${storageKey}');if('system'===e||(!e&&${defaultSystem})){var t='${MEDIA}',m=window.matchMedia(t);if(m.media!==t||m.matches){${updateDOM("dark")}}else{${updateDOM("light")}}}else if(e){${value ? `var x=${JSON.stringify(value)};` : ""}${updateDOM(value ? `x[e]` : "e", true)}}${!defaultSystem
                ? `else{` + updateDOM(defaultTheme, false, false) + "}"
                : ""}${fallbackColorScheme};d.setAttribute('data-style','${style}');d.setAttribute('data-accent-color','${accentColor}');d.setAttribute('data-gray-color','${grayColor}');}catch(e){}}()`;
        }
        return `!function(){try{${optimization}var e=localStorage.getItem('${storageKey}');if(e){${value ? `var x=${JSON.stringify(value)};` : ""}${updateDOM(value ? `x[e]` : "e", true)}}else{${updateDOM(defaultTheme, false, false)};}${fallbackColorScheme};d.setAttribute('data-style','${style}');d.setAttribute('data-accent-color','${accentColor}');d.setAttribute('data-gray-color','${grayColor}');}catch(t){}}();`;
    })();
    return (jsxRuntime.jsxRuntimeExports.jsx("script", { nonce: nonce, dangerouslySetInnerHTML: { __html: scriptSrc } }));
}, 
// Never re-render this component
() => true);
// Helpers
const getTheme = (key, fallback) => {
    if (isServer)
        return undefined;
    let theme;
    try {
        theme = localStorage.getItem(key) || undefined;
    }
    catch (e) {
        // Unsupported
    }
    return theme || fallback;
};
const disableAnimation = () => {
    const css = document.createElement("style");
    css.appendChild(document.createTextNode(`*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}`));
    document.head.appendChild(css);
    return () => {
        // Force restyle
        (() => window.getComputedStyle(document.body))();
        // Wait for next tick before removing
        setTimeout(() => {
            document.head.removeChild(css);
        }, 1);
    };
};
const getSystemTheme = (e) => {
    if (!e)
        e = window.matchMedia(MEDIA);
    const isDark = e.matches;
    const systemTheme = isDark ? "dark" : "light";
    return systemTheme;
};

exports.ThemeProvider = ThemeProvider;
exports.useTheme = useTheme;
//# sourceMappingURL=theme.cjs.map
