UNPKG

@yamada-ui/react

Version:

React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion

119 lines (115 loc) 4.31 kB
"use client"; import { utils_exports } from "../../utils/index.js"; import { THEME_SCHEME_STORAGE_KEY } from "../constant.js"; import { useEnvironment } from "./environment-provider.js"; import { createStorageManager } from "./storage-manager.js"; import { useSystem } from "./system-provider.js"; import { css } from "../css/css.js"; import { use, useCallback, useEffect, useMemo, useState } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; import { Global, ThemeContext, ThemeProvider } from "@emotion/react"; //#region src/core/system/theme-provider.tsx const getPreventTransition = (environment) => { const { getDocument, getWindow } = environment; const win = getWindow(); const doc = getDocument(); if (!win || !doc) return; const css$1 = doc.createElement("style"); const node = doc.createTextNode(`*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}`); css$1.appendChild(node); doc.head.appendChild(css$1); return () => { const forceReflow = () => win.getComputedStyle(doc.body); forceReflow(); requestAnimationFrame(() => { requestAnimationFrame(() => { document.head.removeChild(css$1); }); }); }; }; const ThemeProvider$1 = ({ children, config, cookie, storage = !!cookie ? "cookie" : "localStorage", storageKey = THEME_SCHEME_STORAGE_KEY, theme = {} }) => { const { defaultThemeScheme = "base", disableTransitionOnChange } = config ?? {}; const storageManager = useMemo(() => createStorageManager(storage, storageKey, defaultThemeScheme, cookie), [ cookie, defaultThemeScheme, storage, storageKey ]); const environment = useEnvironment(); const [themeScheme, setThemeScheme] = useState(storageManager.get()); const changeThemeScheme = useCallback((themeScheme$1) => { const { getDocument } = environment; const doc = getDocument(); const cleanup = disableTransitionOnChange ? getPreventTransition(environment) : void 0; if (doc) doc.documentElement.dataset.theme = themeScheme$1; cleanup?.(); setThemeScheme(themeScheme$1); storageManager.set(themeScheme$1); }, [ disableTransitionOnChange, environment, storageManager ]); useEffect(() => { changeThemeScheme(storageManager.get()); }, [changeThemeScheme, storageManager]); return /* @__PURE__ */ jsxs(ThemeProvider, { theme: { changeThemeScheme, themeScheme, ...theme }, children: [/* @__PURE__ */ jsx(GlobalStyles, {}), children] }); }; const GlobalStyles = () => { const system = useSystem(); const { theme } = useTheme(); const { atRule, wrap } = system.layers; const resetStyle = useMemo(() => { const style = theme.styles?.resetStyle; if (!style || (0, utils_exports.isEmptyObject)(style)) return void 0; return css(system, theme)(style); }, [system, theme]); const globalStyle = useMemo(() => { const style = theme.styles?.globalStyle; if (!style || (0, utils_exports.isEmptyObject)(style)) return void 0; return css(system, theme)(style); }, [system, theme]); return /* @__PURE__ */ jsx(Global, { styles: [ atRule, wrap("tokens", useMemo(() => { return { ":host, :root, [data-mode]": system.cssVars }; }, [system])), wrap("reset", resetStyle), wrap("global", globalStyle) ] }); }; /** * `useTheme` is a custom hook that returns a function for retrieving and switching themes. * * @see https://yamada-ui.com/docs/hooks/use-theme */ const useTheme = () => { const internalTheme = use(ThemeContext); const theme = useMemo(() => { const { themeScheme } = internalTheme; if ((0, utils_exports.isUndefined)(themeScheme) || themeScheme === "base") return internalTheme; const nestedTheme = "themeSchemes" in internalTheme && (0, utils_exports.isObject)(internalTheme.themeSchemes) ? internalTheme.themeSchemes[themeScheme] : void 0; if (!nestedTheme) return internalTheme; return (0, utils_exports.merge)(internalTheme, nestedTheme); }, [internalTheme]); return useMemo(() => { const { changeThemeScheme, themeScheme } = internalTheme; return { changeThemeScheme, internalTheme, theme, themeScheme }; }, [theme, internalTheme]); }; //#endregion export { GlobalStyles, ThemeProvider$1 as ThemeProvider, getPreventTransition, useTheme }; //# sourceMappingURL=theme-provider.js.map