@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
JavaScript
"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