UNPKG

fumadocs-ui

Version:

The Radix UI version of Fumadocs UI

74 lines (73 loc) 2.49 kB
"use client"; import { I18nProvider } from "../contexts/i18n.js"; import { SearchProvider } from "../contexts/search.js"; import { jsx, jsxs } from "react/jsx-runtime"; import { useEffect, useEffectEvent } from "react"; import { ThemeProvider, useTheme, useTheme as useTheme$1 } from "next-themes"; import { flushSync } from "react-dom"; import { DirectionProvider } from "@radix-ui/react-direction"; //#region src/provider/base.tsx /** * Whether the event should be ignored because the user is interacting with an editable element, * or an opened dialog (e.g. the search dialog). */ function isTypingTarget(target) { if (!(target instanceof HTMLElement)) return false; if (target.isContentEditable) return true; if ([ "INPUT", "TEXTAREA", "SELECT" ].includes(target.tagName)) return true; return target.closest("[role=\"dialog\"]") !== null; } /** * Toggle between light/dark mode with a hotkey, must be placed under `next-themes` provider. */ function ThemeHotKey({ hotKey }) { const { setTheme, resolvedTheme } = useTheme$1(); const onKeyDown = useEffectEvent((e) => { if (e.defaultPrevented || e.isComposing) return; if (isTypingTarget(e.target)) return; if (!(typeof hotKey === "string" ? !e.metaKey && !e.ctrlKey && !e.altKey && e.key.toLowerCase() === hotKey.toLowerCase() : hotKey(e))) return; e.preventDefault(); const next = resolvedTheme === "dark" ? "light" : "dark"; if (document?.startViewTransition) document.startViewTransition(() => flushSync(() => setTheme(next))); else setTheme(next); }); useEffect(() => { window.addEventListener("keydown", onKeyDown); return () => { window.removeEventListener("keydown", onKeyDown); }; }, []); return null; } function RootProvider({ children, dir = "ltr", theme = {}, search, i18n }) { let body = children; if (search?.enabled !== false) body = /* @__PURE__ */ jsx(SearchProvider, { ...search, children: body }); if (theme?.enabled !== false) { const { enabled: _, hotKey = "d", ...themeProps } = theme; body = /* @__PURE__ */ jsxs(ThemeProvider, { attribute: "class", defaultTheme: "system", enableSystem: true, disableTransitionOnChange: true, ...themeProps, children: [hotKey !== false && /* @__PURE__ */ jsx(ThemeHotKey, { hotKey }), body] }); } if (i18n) body = /* @__PURE__ */ jsx(I18nProvider, { ...i18n, children: body }); return /* @__PURE__ */ jsx(DirectionProvider, { dir, children: body }); } //#endregion export { RootProvider, useTheme };