UNPKG

@wener/console

Version:
179 lines (178 loc) 6.35 kB
import { useContext, useEffect } from "react"; import { deepEqual } from "@wener/utils"; import { z } from "zod"; import { useStore } from "zustand"; import { useShallow } from "zustand/react/shallow"; import { getPrefersColorSchema } from "../../utils/getPrefersColorSchema.js"; import { getSupportedThemes } from "./getSupportedThemes.js"; import { DaisyThemeStoreContext } from "./useTheme.js"; (function (DaisyTheme) { var Context = DaisyThemeStoreContext; DaisyTheme.Root = function () { return; }; function useThemeStore() { return useContext(Context); } DaisyTheme.useThemeStore = useThemeStore; function useThemeState() { var store = useThemeStore(); var state = useStore(store, useShallow(function (s) { return s; })); return [ state, function (update) { store.setState(update); } ]; } DaisyTheme.useThemeState = useThemeState; DaisyTheme.Sidecar = function () { var store = useContext(Context); useEffect(function () { var storage = globalThis.localStorage; if (!storage && typeof window === "undefined") { return; } var StateSchema = z.object({ light: z.string().optional(), dark: z.string().optional(), theme: z.string().optional(), custom: z.record(z.string(), z.any()).optional() }); var closer = []; var loadState = function (s) { if (!s) { return; } try { var loaded = StateSchema.parse(JSON.parse(s)); store.setState(loaded, true); } catch (e) { console.warn("Failed to parse theme state", e); } }; var storageKey = "THEME_STATE"; // load previous loadState(storage.getItem(storageKey)); // watch storage change { var handleStorageChange = function (e) { if (e.key !== storageKey) { return; } loadState(e.newValue); }; window.addEventListener("storage", handleStorageChange); closer.push(function () { window.removeEventListener("storage", handleStorageChange); }); } // system { store.setState(function (s) { s.system = getPrefersColorSchema(); }); closer.push(watchPrefersColorSchema(function () { store.setState(function (s) { s.system = getPrefersColorSchema(); }); })); } // persist { var last = StateSchema.parse(store.getState()); var unsub = store.subscribe(function (s) { var current = StateSchema.parse(s); if (deepEqual(last, current)) { return; } storage.setItem(storageKey, JSON.stringify(current)); last = current; }); // closer.push(unsub); } // active { // const element = document.documentElement; store.subscribe(function (s) { var _globalThis_document; var active = getActiveTheme(s); var schema = getThemeSchema(active); if (s.active === active && s.schema === schema) { return; } store.setState({ active: active, schema: schema }); var el = (_globalThis_document = globalThis.document) === null || _globalThis_document === void 0 ? void 0 : _globalThis_document.documentElement; // setElementThemeAttribute(active, element); el === null || el === void 0 ? void 0 : el.setAttribute("data-theme", active); el === null || el === void 0 ? void 0 : el.setAttribute("data-color-mode", schema); }); } return function () { closer.forEach(function (c) { return c(); }); }; }, [ store ]); /* data-color-mode="dark" */ return null; }; function useThemeSchema() { var store = useThemeStore(); return useStore(store, function (param) { var theme = param.theme; return getThemeSchema(theme); }); } DaisyTheme.useThemeSchema = useThemeSchema; })(DaisyTheme || (DaisyTheme = {})); function getThemeSchema(theme) { switch (theme) { case "system": return getPrefersColorSchema(); case "dark": case "light": return theme; default: var _getSupportedThemes_find; var _ref; return (_ref = (_getSupportedThemes_find = getSupportedThemes().find(function (v) { return v.value === theme; })) === null || _getSupportedThemes_find === void 0 ? void 0 : _getSupportedThemes_find.schema) !== null && _ref !== void 0 ? _ref : "light"; } } function watchPrefersColorSchema(cb) { var listener = function (event) { cb(event.matches); }; var target = window.matchMedia("(prefers-color-scheme: light)"); cb(target.matches); target.addEventListener("change", listener); return function () { target.removeEventListener("change", listener); }; } function getActiveTheme(s) { var theme = s.theme || "system"; if (theme === "system") { theme = s.system || "light"; switch (theme) { case "dark": return s.dark || theme; case "light": return s.light || theme; } } return theme || "light"; } export var DaisyTheme;