@tamagui/next-theme 1.0.1-beta.166 → 1.0.1-beta.168

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -26,22 +26,25 @@ var NextTheme_exports = {};
26
26
  __export(NextTheme_exports, {
27
27
  NextThemeProvider: () => NextThemeProvider,
28
28
  useRootTheme: () => useRootTheme,
29
- useTheme: () => useTheme
29
+ useTheme: () => useTheme,
30
+ useThemeSetting: () => useThemeSetting
30
31
  });
31
32
  module.exports = __toCommonJS(NextTheme_exports);
32
33
  var import_jsx_runtime = require("react/jsx-runtime");
34
+ var import_use_event = require("@tamagui/use-event");
33
35
  var import_head = __toESM(require("next/head"));
34
36
  var React = __toESM(require("react"));
35
37
  var import_react = require("react");
36
38
  const useIsomorphicLayoutEffect = typeof window !== "undefined" ? import_react.useLayoutEffect : import_react.useEffect;
37
- const ThemeContext = (0, import_react.createContext)({
38
- toggleTheme: () => {
39
+ const ThemeSettingContext = (0, import_react.createContext)({
40
+ toggle: () => {
39
41
  },
40
- setTheme: (_) => {
42
+ set: (_) => {
41
43
  },
42
44
  themes: []
43
45
  });
44
- const useTheme = () => (0, import_react.useContext)(ThemeContext);
46
+ const useTheme = () => (0, import_react.useContext)(ThemeSettingContext);
47
+ const useThemeSetting = () => (0, import_react.useContext)(ThemeSettingContext);
45
48
  const colorSchemes = ["light", "dark"];
46
49
  const MEDIA = "(prefers-color-scheme: dark)";
47
50
  const useRootTheme = () => {
@@ -69,20 +72,17 @@ const NextThemeProvider = ({
69
72
  const [theme, setThemeState] = (0, import_react.useState)(() => getTheme(storageKey, defaultTheme));
70
73
  const [resolvedTheme, setResolvedTheme] = (0, import_react.useState)(() => getTheme(storageKey));
71
74
  const attrs = !value ? themes : Object.values(value);
72
- const handleMediaQuery = (0, import_react.useCallback)(
73
- (e) => {
74
- const systemTheme = getSystemTheme(e);
75
- React.startTransition(() => {
76
- setResolvedTheme(systemTheme);
77
- });
78
- if (theme === "system" && !forcedTheme)
79
- handleChangeTheme(systemTheme, false);
80
- },
81
- [theme, forcedTheme]
82
- );
75
+ const handleMediaQuery = (0, import_use_event.useEvent)((e) => {
76
+ const systemTheme = getSystemTheme(e);
77
+ React.startTransition(() => {
78
+ setResolvedTheme(systemTheme);
79
+ });
80
+ if (theme === "system" && !forcedTheme)
81
+ handleChangeTheme(systemTheme, false);
82
+ });
83
83
  const mediaListener = (0, import_react.useRef)(handleMediaQuery);
84
84
  mediaListener.current = handleMediaQuery;
85
- const handleChangeTheme = (0, import_react.useCallback)((theme2, updateStorage = true, updateDOM = true) => {
85
+ const handleChangeTheme = (0, import_use_event.useEvent)((theme2, updateStorage = true, updateDOM = true) => {
86
86
  let name = (value == null ? void 0 : value[theme2]) || theme2;
87
87
  if (updateStorage) {
88
88
  try {
@@ -104,7 +104,7 @@ const NextThemeProvider = ({
104
104
  d.setAttribute(attribute, name);
105
105
  }
106
106
  }
107
- }, []);
107
+ });
108
108
  useIsomorphicLayoutEffect(() => {
109
109
  const handler = (...args) => mediaListener.current(...args);
110
110
  const media = window.matchMedia(MEDIA);
@@ -114,30 +114,27 @@ const NextThemeProvider = ({
114
114
  media.removeListener(handler);
115
115
  };
116
116
  }, []);
117
- const setTheme = (0, import_react.useCallback)(
118
- (newTheme) => {
119
- if (forcedTheme) {
120
- handleChangeTheme(newTheme, true, false);
121
- } else {
122
- handleChangeTheme(newTheme);
123
- }
124
- setThemeState(newTheme);
125
- },
126
- [forcedTheme]
127
- );
117
+ const set = (0, import_use_event.useEvent)((newTheme) => {
118
+ if (forcedTheme) {
119
+ handleChangeTheme(newTheme, true, false);
120
+ } else {
121
+ handleChangeTheme(newTheme);
122
+ }
123
+ setThemeState(newTheme);
124
+ });
128
125
  (0, import_react.useEffect)(() => {
129
126
  const handleStorage = (e) => {
130
127
  if (e.key !== storageKey) {
131
128
  return;
132
129
  }
133
130
  const theme2 = e.newValue || defaultTheme;
134
- setTheme(theme2);
131
+ set(theme2);
135
132
  };
136
133
  window.addEventListener("storage", handleStorage);
137
134
  return () => {
138
135
  window.removeEventListener("storage", handleStorage);
139
136
  };
140
- }, []);
137
+ }, [defaultTheme, set, storageKey]);
141
138
  useIsomorphicLayoutEffect(() => {
142
139
  if (!enableColorScheme)
143
140
  return;
@@ -149,21 +146,23 @@ const NextThemeProvider = ({
149
146
  }
150
147
  }, [enableColorScheme, theme, resolvedTheme, forcedTheme]);
151
148
  const contextValue = (0, import_react.useMemo)(() => {
152
- return {
149
+ const value2 = {
153
150
  theme,
154
- setTheme,
155
- toggleTheme() {
151
+ current: theme,
152
+ set,
153
+ toggle() {
156
154
  const order = resolvedTheme === "dark" ? ["system", "light", "dark"] : ["system", "dark", "light"];
157
155
  const next = order[(order.indexOf(theme) + 1) % order.length];
158
- setTheme(next);
156
+ set(next);
159
157
  },
160
158
  forcedTheme,
161
159
  resolvedTheme: theme === "system" ? resolvedTheme : theme,
162
160
  themes: enableSystem ? [...themes, "system"] : themes,
163
161
  systemTheme: enableSystem ? resolvedTheme : void 0
164
162
  };
165
- }, [theme, forcedTheme, resolvedTheme, enableSystem]);
166
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ThemeContext.Provider, {
163
+ return value2;
164
+ }, [theme, set, forcedTheme, resolvedTheme, enableSystem, themes]);
165
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ThemeSettingContext.Provider, {
167
166
  value: contextValue,
168
167
  children: [
169
168
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeScript, {
@@ -253,6 +252,7 @@ const getSystemTheme = (e) => {
253
252
  0 && (module.exports = {
254
253
  NextThemeProvider,
255
254
  useRootTheme,
256
- useTheme
255
+ useTheme,
256
+ useThemeSetting
257
257
  });
258
258
  //# sourceMappingURL=NextTheme.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/NextTheme.tsx"],
4
- "sourcesContent": ["// https://raw.githubusercontent.com/pacocoursey/next-themes/master/index.tsx\n// forked temporarily due to buggy theme change\n\nimport NextHead from 'next/head'\nimport * as React from 'react'\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nconst useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nexport interface UseThemeProps {\n /** List of all available theme names */\n themes: string[]\n /** Forced theme name for the current page */\n forcedTheme?: string\n /** Update the theme */\n setTheme: (theme: string) => void\n toggleTheme: () => void\n /** Active theme name */\n theme?: string\n /** If `enableSystem` is true and the active theme is \"system\", this returns whether the system preference resolved to \"dark\" or \"light\". Otherwise, identical to `theme` */\n resolvedTheme?: string\n /** If enableSystem is true, returns the System theme preference (\"dark\" or \"light\"), regardless what the active theme is */\n systemTheme?: 'dark' | 'light'\n}\n\nexport interface ThemeProviderProps {\n children?: any\n /** List of all available theme names */\n themes?: string[]\n /** Forced theme name for the current page */\n forcedTheme?: string\n /** Whether to switch between dark and light themes based on prefers-color-scheme */\n enableSystem?: boolean\n systemTheme?: string\n /** Disable all CSS transitions when switching themes */\n disableTransitionOnChange?: boolean\n /** Whether to indicate to browsers which color scheme is used (dark or light) for built-in UI like inputs and buttons */\n enableColorScheme?: boolean\n /** Key used to store theme setting in localStorage */\n storageKey?: string\n /** Default theme name (for v0.0.12 and lower the default was light). If `enableSystem` is false, the default theme is light */\n defaultTheme?: string\n /** HTML attribute modified based on the active theme. Accepts `class` and `data-*` (meaning any data attribute, `data-mode`, `data-color`, etc.) */\n attribute?: string | 'class'\n /** Mapping of theme name to HTML attribute value. Object where key is the theme name and value is the attribute value */\n value?: ValueObject\n onChangeTheme?: (name: string) => void\n}\n\nconst ThemeContext = createContext<UseThemeProps>({\n toggleTheme: () => {},\n setTheme: (_) => {},\n themes: [],\n})\nexport const useTheme = () => useContext(ThemeContext)\n\nconst colorSchemes = ['light', 'dark']\nconst MEDIA = '(prefers-color-scheme: dark)'\n\ninterface ValueObject {\n [themeName: string]: string\n}\n\nexport const useRootTheme = () => {\n const isClient = typeof document !== 'undefined'\n // @ts-ignore\n const classes = isClient ? [...document.documentElement.classList] : []\n const isDark = classes.includes('t_dark')\n return useState(isDark ? 'dark' : 'light')\n}\n\nexport const NextThemeProvider: React.FC<ThemeProviderProps> = ({\n forcedTheme,\n disableTransitionOnChange = true,\n enableSystem = true,\n enableColorScheme = true,\n storageKey = 'theme',\n themes = ['light', 'dark'],\n defaultTheme = enableSystem ? 'system' : 'light',\n attribute = 'class',\n onChangeTheme,\n value = {\n dark: 't_dark',\n light: 't_light',\n },\n children,\n}) => {\n const [theme, setThemeState] = useState(() => getTheme(storageKey, defaultTheme))\n const [resolvedTheme, setResolvedTheme] = useState(() => getTheme(storageKey))\n // const resolvedTheme = React.useDeferredValue(resolvedThemeFast)\n const attrs = !value ? themes : Object.values(value)\n\n const handleMediaQuery = useCallback(\n (e?) => {\n const systemTheme = getSystemTheme(e)\n React.startTransition(() => {\n setResolvedTheme(systemTheme)\n })\n if (theme === 'system' && !forcedTheme) handleChangeTheme(systemTheme, false)\n },\n [theme, forcedTheme]\n )\n\n // Ref hack to avoid adding handleMediaQuery as a dep\n const mediaListener = useRef(handleMediaQuery)\n mediaListener.current = handleMediaQuery\n\n const handleChangeTheme = useCallback((theme, updateStorage = true, updateDOM = true) => {\n let name = value?.[theme] || theme\n\n if (updateStorage) {\n try {\n localStorage.setItem(storageKey, theme)\n } catch (e) {\n // Unsupported\n }\n }\n\n if (theme === 'system' && enableSystem) {\n const resolved = getSystemTheme()\n name = value?.[resolved] || resolved\n }\n\n onChangeTheme?.(name.replace('t_', ''))\n\n if (updateDOM) {\n const d = document.documentElement\n if (attribute === 'class') {\n d.classList.remove(...attrs)\n d.classList.add(name)\n } else {\n d.setAttribute(attribute, name)\n }\n }\n }, [])\n\n useIsomorphicLayoutEffect(() => {\n const handler = (...args: any) => mediaListener.current(...args)\n // Always listen to System preference\n const media = window.matchMedia(MEDIA)\n // Intentionally use deprecated listener methods to support iOS & old browsers\n media.addListener(handler)\n handler(media)\n return () => {\n media.removeListener(handler)\n }\n }, [])\n\n const setTheme = useCallback(\n (newTheme) => {\n if (forcedTheme) {\n handleChangeTheme(newTheme, true, false)\n } else {\n handleChangeTheme(newTheme)\n }\n setThemeState(newTheme)\n },\n [forcedTheme]\n )\n\n // localStorage event handling\n useEffect(() => {\n const handleStorage = (e: StorageEvent) => {\n if (e.key !== storageKey) {\n return\n }\n // If default theme set, use it if localstorage === null (happens on local storage manual deletion)\n const theme = e.newValue || defaultTheme\n setTheme(theme)\n }\n window.addEventListener('storage', handleStorage)\n return () => {\n window.removeEventListener('storage', handleStorage)\n }\n }, [])\n\n // color-scheme handling\n useIsomorphicLayoutEffect(() => {\n if (!enableColorScheme) return\n\n const colorScheme =\n // If theme is forced to light or dark, use that\n forcedTheme && colorSchemes.includes(forcedTheme)\n ? forcedTheme\n : // If regular theme is light or dark\n theme && colorSchemes.includes(theme)\n ? theme\n : // If theme is system, use the resolved version\n theme === 'system'\n ? resolvedTheme || null\n : null\n\n // color-scheme tells browser how to render built-in elements like forms, scrollbars, etc.\n // if color-scheme is null, this will remove the property\n const userPrefers =\n typeof window !== 'undefined' &&\n window.matchMedia &&\n window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light'\n\n const wePrefer = colorScheme || 'light'\n\n // avoid running this because it causes full page reflow\n if (userPrefers !== wePrefer) {\n document.documentElement.style.setProperty('color-scheme', colorScheme)\n }\n }, [enableColorScheme, theme, resolvedTheme, forcedTheme])\n\n const contextValue = useMemo(() => {\n return {\n theme,\n setTheme,\n toggleTheme() {\n const order =\n resolvedTheme === 'dark' ? ['system', 'light', 'dark'] : ['system', 'dark', 'light']\n const next = order[(order.indexOf(theme) + 1) % order.length]\n setTheme(next)\n },\n forcedTheme,\n resolvedTheme: theme === 'system' ? resolvedTheme : theme,\n themes: enableSystem ? [...themes, 'system'] : themes,\n systemTheme: (enableSystem ? resolvedTheme : undefined) as 'light' | 'dark' | undefined,\n } as const\n }, [theme, forcedTheme, resolvedTheme, enableSystem])\n\n return (\n <ThemeContext.Provider value={contextValue}>\n <ThemeScript\n {...{\n forcedTheme,\n storageKey,\n systemTheme: resolvedTheme,\n attribute,\n value,\n enableSystem,\n defaultTheme,\n attrs,\n }}\n />\n {children}\n </ThemeContext.Provider>\n )\n}\n\nconst ThemeScript = memo(\n ({\n forcedTheme,\n storageKey,\n attribute,\n enableSystem,\n defaultTheme,\n value,\n attrs,\n }: {\n forcedTheme?: string\n storageKey: string\n attribute?: string\n enableSystem?: boolean\n defaultTheme: string\n value?: ValueObject\n attrs: any\n }) => {\n // Code-golfing the amount of characters in the script\n const optimization = (() => {\n if (attribute === 'class') {\n const removeClasses = attrs.map((t: string) => `d.remove('${t}')`).join(';')\n return `var d=document.documentElement.classList;${removeClasses};`\n } else {\n return `var d=document.documentElement;`\n }\n })()\n\n const updateDOM = (name: string, literal?: boolean) => {\n name = value?.[name] || name\n const val = literal ? name : `'${name}'`\n\n if (attribute === 'class') {\n return `d.add(${val})`\n }\n\n return `d.setAttribute('${attribute}', ${val})`\n }\n\n const defaultSystem = defaultTheme === 'system'\n\n return (\n <NextHead>\n {forcedTheme ? (\n <script\n key=\"next-themes-script\"\n dangerouslySetInnerHTML={{\n // These are minified via Terser and then updated by hand, don't recommend\n // prettier-ignore\n __html: `!function(){${optimization}${updateDOM(forcedTheme)}}()`,\n }}\n />\n ) : enableSystem ? (\n <script\n key=\"next-themes-script\"\n dangerouslySetInnerHTML={{\n // prettier-ignore\n __html: `!function(){try {${optimization}var e=localStorage.getItem('${storageKey}');${!defaultSystem ? updateDOM(defaultTheme) + ';' : ''}if(\"system\"===e||(!e&&${defaultSystem})){var t=\"${MEDIA}\",m=window.matchMedia(t);m.media!==t||m.matches?${updateDOM('dark')}:${updateDOM('light')}}else if(e) ${value ? `var x=${JSON.stringify(value)};` : ''}${updateDOM(value ? 'x[e]' : 'e', true)}}catch(e){}}()`,\n }}\n />\n ) : (\n <script\n key=\"next-themes-script\"\n dangerouslySetInnerHTML={{\n // prettier-ignore\n __html: `!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)};}}catch(t){}}();`,\n }}\n />\n )}\n </NextHead>\n )\n },\n (prevProps, nextProps) => {\n // Only re-render when forcedTheme changes\n // the rest of the props should be completely stable\n if (prevProps.forcedTheme !== nextProps.forcedTheme) return false\n return true\n }\n)\n\n// Helpers\nconst getTheme = (key: string, fallback?: string) => {\n if (typeof window === 'undefined') return undefined\n let theme\n try {\n theme = localStorage.getItem(key) || undefined\n } catch (e) {\n // Unsupported\n }\n return theme || fallback\n}\n\nconst getSystemTheme = (e?: MediaQueryList) => {\n if (!e) {\n e = window.matchMedia(MEDIA)\n }\n\n const isDark = e.matches\n const systemTheme = isDark ? 'dark' : 'light'\n return systemTheme\n}\n"],
5
- "mappings": "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",
6
- "names": ["theme", "NextHead"]
4
+ "sourcesContent": ["// https://raw.githubusercontent.com/pacocoursey/next-themes/master/index.tsx\n// forked temporarily due to buggy theme change\n\nimport { useEvent } from '@tamagui/use-event'\nimport NextHead from 'next/head'\nimport * as React from 'react'\nimport {\n createContext,\n memo,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nconst useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nexport interface UseThemeProps {\n /** List of all available theme names */\n themes: string[]\n /** Forced theme name for the current page */\n forcedTheme?: string\n /** Update the theme */\n set: (theme: string) => void\n toggle: () => void\n /** Active theme name - will return \"system\" if not overriden, see \"resolvedTheme\" for getting resolved system value */\n current?: string\n /** @deprecated Use `current` instead (deprecating avoid confusion with useTheme) */\n theme?: string\n /** If `enableSystem` is true and the active theme is \"system\", this returns whether the system preference resolved to \"dark\" or \"light\". Otherwise, identical to `theme` */\n resolvedTheme?: string\n /** If enableSystem is true, returns the System theme preference (\"dark\" or \"light\"), regardless what the active theme is */\n systemTheme?: 'dark' | 'light'\n}\n\nexport interface ThemeProviderProps {\n children?: any\n /** List of all available theme names */\n themes?: string[]\n /** Forced theme name for the current page */\n forcedTheme?: string\n /** Whether to switch between dark and light themes based on prefers-color-scheme */\n enableSystem?: boolean\n systemTheme?: string\n /** Disable all CSS transitions when switching themes */\n disableTransitionOnChange?: boolean\n /** Whether to indicate to browsers which color scheme is used (dark or light) for built-in UI like inputs and buttons */\n enableColorScheme?: boolean\n /** Key used to store theme setting in localStorage */\n storageKey?: string\n /** Default theme name (for v0.0.12 and lower the default was light). If `enableSystem` is false, the default theme is light */\n defaultTheme?: string\n /** HTML attribute modified based on the active theme. Accepts `class` and `data-*` (meaning any data attribute, `data-mode`, `data-color`, etc.) */\n attribute?: string | 'class'\n /** Mapping of theme name to HTML attribute value. Object where key is the theme name and value is the attribute value */\n value?: ValueObject\n onChangeTheme?: (name: string) => void\n}\n\nconst ThemeSettingContext = createContext<UseThemeProps>({\n toggle: () => {},\n set: (_) => {},\n themes: [],\n})\n\n/**\n * @deprecated renamed to `useThemeSetting` to avoid confusion with core `useTheme` hook\n */\nexport const useTheme = () => useContext(ThemeSettingContext)\n\nexport const useThemeSetting = () => useContext(ThemeSettingContext)\n\nconst colorSchemes = ['light', 'dark']\nconst MEDIA = '(prefers-color-scheme: dark)'\n\ninterface ValueObject {\n [themeName: string]: string\n}\n\nexport const useRootTheme = () => {\n const isClient = typeof document !== 'undefined'\n // @ts-ignore\n const classes = isClient ? [...document.documentElement.classList] : []\n const isDark = classes.includes('t_dark')\n return useState(isDark ? 'dark' : 'light')\n}\n\nexport const NextThemeProvider: React.FC<ThemeProviderProps> = ({\n forcedTheme,\n disableTransitionOnChange = true,\n enableSystem = true,\n enableColorScheme = true,\n storageKey = 'theme',\n themes = ['light', 'dark'],\n defaultTheme = enableSystem ? 'system' : 'light',\n attribute = 'class',\n onChangeTheme,\n value = {\n dark: 't_dark',\n light: 't_light',\n },\n children,\n}) => {\n const [theme, setThemeState] = useState(() => getTheme(storageKey, defaultTheme))\n const [resolvedTheme, setResolvedTheme] = useState(() => getTheme(storageKey))\n // const resolvedTheme = React.useDeferredValue(resolvedThemeFast)\n const attrs = !value ? themes : Object.values(value)\n\n const handleMediaQuery = useEvent((e?) => {\n const systemTheme = getSystemTheme(e)\n React.startTransition(() => {\n setResolvedTheme(systemTheme)\n })\n if (theme === 'system' && !forcedTheme) handleChangeTheme(systemTheme, false)\n })\n\n // Ref hack to avoid adding handleMediaQuery as a dep\n const mediaListener = useRef(handleMediaQuery)\n mediaListener.current = handleMediaQuery\n\n const handleChangeTheme = useEvent((theme, updateStorage = true, updateDOM = true) => {\n let name = value?.[theme] || theme\n\n if (updateStorage) {\n try {\n localStorage.setItem(storageKey, theme)\n } catch (e) {\n // Unsupported\n }\n }\n\n if (theme === 'system' && enableSystem) {\n const resolved = getSystemTheme()\n name = value?.[resolved] || resolved\n }\n\n onChangeTheme?.(name.replace('t_', ''))\n\n if (updateDOM) {\n const d = document.documentElement\n if (attribute === 'class') {\n d.classList.remove(...attrs)\n d.classList.add(name)\n } else {\n d.setAttribute(attribute, name)\n }\n }\n })\n\n useIsomorphicLayoutEffect(() => {\n const handler = (...args: any) => mediaListener.current(...args)\n // Always listen to System preference\n const media = window.matchMedia(MEDIA)\n // Intentionally use deprecated listener methods to support iOS & old browsers\n media.addListener(handler)\n handler(media)\n return () => {\n media.removeListener(handler)\n }\n }, [])\n\n const set = useEvent((newTheme) => {\n if (forcedTheme) {\n handleChangeTheme(newTheme, true, false)\n } else {\n handleChangeTheme(newTheme)\n }\n setThemeState(newTheme)\n })\n\n // localStorage event handling\n useEffect(() => {\n const handleStorage = (e: StorageEvent) => {\n if (e.key !== storageKey) {\n return\n }\n // If default theme set, use it if localstorage === null (happens on local storage manual deletion)\n const theme = e.newValue || defaultTheme\n set(theme)\n }\n window.addEventListener('storage', handleStorage)\n return () => {\n window.removeEventListener('storage', handleStorage)\n }\n }, [defaultTheme, set, storageKey])\n\n // color-scheme handling\n useIsomorphicLayoutEffect(() => {\n if (!enableColorScheme) return\n\n const colorScheme =\n // If theme is forced to light or dark, use that\n forcedTheme && colorSchemes.includes(forcedTheme)\n ? forcedTheme\n : // If regular theme is light or dark\n theme && colorSchemes.includes(theme)\n ? theme\n : // If theme is system, use the resolved version\n theme === 'system'\n ? resolvedTheme || null\n : null\n\n // color-scheme tells browser how to render built-in elements like forms, scrollbars, etc.\n // if color-scheme is null, this will remove the property\n const userPrefers =\n typeof window !== 'undefined' &&\n window.matchMedia &&\n window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light'\n\n const wePrefer = colorScheme || 'light'\n\n // avoid running this because it causes full page reflow\n if (userPrefers !== wePrefer) {\n document.documentElement.style.setProperty('color-scheme', colorScheme)\n }\n }, [enableColorScheme, theme, resolvedTheme, forcedTheme])\n\n const contextValue = useMemo(() => {\n const value: UseThemeProps = {\n theme,\n current: theme,\n set,\n toggle() {\n const order =\n resolvedTheme === 'dark' ? ['system', 'light', 'dark'] : ['system', 'dark', 'light']\n const next = order[(order.indexOf(theme) + 1) % order.length]\n set(next)\n },\n forcedTheme,\n resolvedTheme: theme === 'system' ? resolvedTheme : theme,\n themes: enableSystem ? [...themes, 'system'] : themes,\n systemTheme: (enableSystem ? resolvedTheme : undefined) as 'light' | 'dark' | undefined,\n } as const\n\n return value\n }, [theme, set, forcedTheme, resolvedTheme, enableSystem, themes])\n\n return (\n <ThemeSettingContext.Provider value={contextValue}>\n <ThemeScript\n {...{\n forcedTheme,\n storageKey,\n systemTheme: resolvedTheme,\n attribute,\n value,\n enableSystem,\n defaultTheme,\n attrs,\n }}\n />\n {children}\n </ThemeSettingContext.Provider>\n )\n}\n\nconst ThemeScript = memo(\n ({\n forcedTheme,\n storageKey,\n attribute,\n enableSystem,\n defaultTheme,\n value,\n attrs,\n }: {\n forcedTheme?: string\n storageKey: string\n attribute?: string\n enableSystem?: boolean\n defaultTheme: string\n value?: ValueObject\n attrs: any\n }) => {\n // Code-golfing the amount of characters in the script\n const optimization = (() => {\n if (attribute === 'class') {\n const removeClasses = attrs.map((t: string) => `d.remove('${t}')`).join(';')\n return `var d=document.documentElement.classList;${removeClasses};`\n } else {\n return `var d=document.documentElement;`\n }\n })()\n\n const updateDOM = (name: string, literal?: boolean) => {\n name = value?.[name] || name\n const val = literal ? name : `'${name}'`\n\n if (attribute === 'class') {\n return `d.add(${val})`\n }\n\n return `d.setAttribute('${attribute}', ${val})`\n }\n\n const defaultSystem = defaultTheme === 'system'\n\n return (\n <NextHead>\n {forcedTheme ? (\n <script\n key=\"next-themes-script\"\n dangerouslySetInnerHTML={{\n // These are minified via Terser and then updated by hand, don't recommend\n // prettier-ignore\n __html: `!function(){${optimization}${updateDOM(forcedTheme)}}()`,\n }}\n />\n ) : enableSystem ? (\n <script\n key=\"next-themes-script\"\n dangerouslySetInnerHTML={{\n // prettier-ignore\n __html: `!function(){try {${optimization}var e=localStorage.getItem('${storageKey}');${!defaultSystem ? updateDOM(defaultTheme) + ';' : ''}if(\"system\"===e||(!e&&${defaultSystem})){var t=\"${MEDIA}\",m=window.matchMedia(t);m.media!==t||m.matches?${updateDOM('dark')}:${updateDOM('light')}}else if(e) ${value ? `var x=${JSON.stringify(value)};` : ''}${updateDOM(value ? 'x[e]' : 'e', true)}}catch(e){}}()`,\n }}\n />\n ) : (\n <script\n key=\"next-themes-script\"\n dangerouslySetInnerHTML={{\n // prettier-ignore\n __html: `!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)};}}catch(t){}}();`,\n }}\n />\n )}\n </NextHead>\n )\n },\n (prevProps, nextProps) => {\n // Only re-render when forcedTheme changes\n // the rest of the props should be completely stable\n if (prevProps.forcedTheme !== nextProps.forcedTheme) return false\n return true\n }\n)\n\n// Helpers\nconst getTheme = (key: string, fallback?: string) => {\n if (typeof window === 'undefined') return undefined\n let theme\n try {\n theme = localStorage.getItem(key) || undefined\n } catch (e) {\n // Unsupported\n }\n return theme || fallback\n}\n\nconst getSystemTheme = (e?: MediaQueryList) => {\n if (!e) {\n e = window.matchMedia(MEDIA)\n }\n\n const isDark = e.matches\n const systemTheme = isDark ? 'dark' : 'light'\n return systemTheme\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["theme", "value", "NextHead"]
7
7
  }
@@ -1,10 +1,10 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useEvent } from "@tamagui/use-event";
2
3
  import NextHead from "next/head";
3
4
  import * as React from "react";
4
5
  import {
5
6
  createContext,
6
7
  memo,
7
- useCallback,
8
8
  useContext,
9
9
  useEffect,
10
10
  useLayoutEffect,
@@ -13,14 +13,15 @@ import {
13
13
  useState
14
14
  } from "react";
15
15
  const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
16
- const ThemeContext = createContext({
17
- toggleTheme: () => {
16
+ const ThemeSettingContext = createContext({
17
+ toggle: () => {
18
18
  },
19
- setTheme: (_) => {
19
+ set: (_) => {
20
20
  },
21
21
  themes: []
22
22
  });
23
- const useTheme = () => useContext(ThemeContext);
23
+ const useTheme = () => useContext(ThemeSettingContext);
24
+ const useThemeSetting = () => useContext(ThemeSettingContext);
24
25
  const colorSchemes = ["light", "dark"];
25
26
  const MEDIA = "(prefers-color-scheme: dark)";
26
27
  const useRootTheme = () => {
@@ -48,20 +49,17 @@ const NextThemeProvider = ({
48
49
  const [theme, setThemeState] = useState(() => getTheme(storageKey, defaultTheme));
49
50
  const [resolvedTheme, setResolvedTheme] = useState(() => getTheme(storageKey));
50
51
  const attrs = !value ? themes : Object.values(value);
51
- const handleMediaQuery = useCallback(
52
- (e) => {
53
- const systemTheme = getSystemTheme(e);
54
- React.startTransition(() => {
55
- setResolvedTheme(systemTheme);
56
- });
57
- if (theme === "system" && !forcedTheme)
58
- handleChangeTheme(systemTheme, false);
59
- },
60
- [theme, forcedTheme]
61
- );
52
+ const handleMediaQuery = useEvent((e) => {
53
+ const systemTheme = getSystemTheme(e);
54
+ React.startTransition(() => {
55
+ setResolvedTheme(systemTheme);
56
+ });
57
+ if (theme === "system" && !forcedTheme)
58
+ handleChangeTheme(systemTheme, false);
59
+ });
62
60
  const mediaListener = useRef(handleMediaQuery);
63
61
  mediaListener.current = handleMediaQuery;
64
- const handleChangeTheme = useCallback((theme2, updateStorage = true, updateDOM = true) => {
62
+ const handleChangeTheme = useEvent((theme2, updateStorage = true, updateDOM = true) => {
65
63
  let name = (value == null ? void 0 : value[theme2]) || theme2;
66
64
  if (updateStorage) {
67
65
  try {
@@ -83,7 +81,7 @@ const NextThemeProvider = ({
83
81
  d.setAttribute(attribute, name);
84
82
  }
85
83
  }
86
- }, []);
84
+ });
87
85
  useIsomorphicLayoutEffect(() => {
88
86
  const handler = (...args) => mediaListener.current(...args);
89
87
  const media = window.matchMedia(MEDIA);
@@ -93,30 +91,27 @@ const NextThemeProvider = ({
93
91
  media.removeListener(handler);
94
92
  };
95
93
  }, []);
96
- const setTheme = useCallback(
97
- (newTheme) => {
98
- if (forcedTheme) {
99
- handleChangeTheme(newTheme, true, false);
100
- } else {
101
- handleChangeTheme(newTheme);
102
- }
103
- setThemeState(newTheme);
104
- },
105
- [forcedTheme]
106
- );
94
+ const set = useEvent((newTheme) => {
95
+ if (forcedTheme) {
96
+ handleChangeTheme(newTheme, true, false);
97
+ } else {
98
+ handleChangeTheme(newTheme);
99
+ }
100
+ setThemeState(newTheme);
101
+ });
107
102
  useEffect(() => {
108
103
  const handleStorage = (e) => {
109
104
  if (e.key !== storageKey) {
110
105
  return;
111
106
  }
112
107
  const theme2 = e.newValue || defaultTheme;
113
- setTheme(theme2);
108
+ set(theme2);
114
109
  };
115
110
  window.addEventListener("storage", handleStorage);
116
111
  return () => {
117
112
  window.removeEventListener("storage", handleStorage);
118
113
  };
119
- }, []);
114
+ }, [defaultTheme, set, storageKey]);
120
115
  useIsomorphicLayoutEffect(() => {
121
116
  if (!enableColorScheme)
122
117
  return;
@@ -128,21 +123,23 @@ const NextThemeProvider = ({
128
123
  }
129
124
  }, [enableColorScheme, theme, resolvedTheme, forcedTheme]);
130
125
  const contextValue = useMemo(() => {
131
- return {
126
+ const value2 = {
132
127
  theme,
133
- setTheme,
134
- toggleTheme() {
128
+ current: theme,
129
+ set,
130
+ toggle() {
135
131
  const order = resolvedTheme === "dark" ? ["system", "light", "dark"] : ["system", "dark", "light"];
136
132
  const next = order[(order.indexOf(theme) + 1) % order.length];
137
- setTheme(next);
133
+ set(next);
138
134
  },
139
135
  forcedTheme,
140
136
  resolvedTheme: theme === "system" ? resolvedTheme : theme,
141
137
  themes: enableSystem ? [...themes, "system"] : themes,
142
138
  systemTheme: enableSystem ? resolvedTheme : void 0
143
139
  };
144
- }, [theme, forcedTheme, resolvedTheme, enableSystem]);
145
- return /* @__PURE__ */ jsxs(ThemeContext.Provider, {
140
+ return value2;
141
+ }, [theme, set, forcedTheme, resolvedTheme, enableSystem, themes]);
142
+ return /* @__PURE__ */ jsxs(ThemeSettingContext.Provider, {
146
143
  value: contextValue,
147
144
  children: [
148
145
  /* @__PURE__ */ jsx(ThemeScript, {
@@ -231,6 +228,7 @@ const getSystemTheme = (e) => {
231
228
  export {
232
229
  NextThemeProvider,
233
230
  useRootTheme,
234
- useTheme
231
+ useTheme,
232
+ useThemeSetting
235
233
  };
236
234
  //# sourceMappingURL=NextTheme.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/NextTheme.tsx"],
4
- "sourcesContent": ["// https://raw.githubusercontent.com/pacocoursey/next-themes/master/index.tsx\n// forked temporarily due to buggy theme change\n\nimport NextHead from 'next/head'\nimport * as React from 'react'\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nconst useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nexport interface UseThemeProps {\n /** List of all available theme names */\n themes: string[]\n /** Forced theme name for the current page */\n forcedTheme?: string\n /** Update the theme */\n setTheme: (theme: string) => void\n toggleTheme: () => void\n /** Active theme name */\n theme?: string\n /** If `enableSystem` is true and the active theme is \"system\", this returns whether the system preference resolved to \"dark\" or \"light\". Otherwise, identical to `theme` */\n resolvedTheme?: string\n /** If enableSystem is true, returns the System theme preference (\"dark\" or \"light\"), regardless what the active theme is */\n systemTheme?: 'dark' | 'light'\n}\n\nexport interface ThemeProviderProps {\n children?: any\n /** List of all available theme names */\n themes?: string[]\n /** Forced theme name for the current page */\n forcedTheme?: string\n /** Whether to switch between dark and light themes based on prefers-color-scheme */\n enableSystem?: boolean\n systemTheme?: string\n /** Disable all CSS transitions when switching themes */\n disableTransitionOnChange?: boolean\n /** Whether to indicate to browsers which color scheme is used (dark or light) for built-in UI like inputs and buttons */\n enableColorScheme?: boolean\n /** Key used to store theme setting in localStorage */\n storageKey?: string\n /** Default theme name (for v0.0.12 and lower the default was light). If `enableSystem` is false, the default theme is light */\n defaultTheme?: string\n /** HTML attribute modified based on the active theme. Accepts `class` and `data-*` (meaning any data attribute, `data-mode`, `data-color`, etc.) */\n attribute?: string | 'class'\n /** Mapping of theme name to HTML attribute value. Object where key is the theme name and value is the attribute value */\n value?: ValueObject\n onChangeTheme?: (name: string) => void\n}\n\nconst ThemeContext = createContext<UseThemeProps>({\n toggleTheme: () => {},\n setTheme: (_) => {},\n themes: [],\n})\nexport const useTheme = () => useContext(ThemeContext)\n\nconst colorSchemes = ['light', 'dark']\nconst MEDIA = '(prefers-color-scheme: dark)'\n\ninterface ValueObject {\n [themeName: string]: string\n}\n\nexport const useRootTheme = () => {\n const isClient = typeof document !== 'undefined'\n // @ts-ignore\n const classes = isClient ? [...document.documentElement.classList] : []\n const isDark = classes.includes('t_dark')\n return useState(isDark ? 'dark' : 'light')\n}\n\nexport const NextThemeProvider: React.FC<ThemeProviderProps> = ({\n forcedTheme,\n disableTransitionOnChange = true,\n enableSystem = true,\n enableColorScheme = true,\n storageKey = 'theme',\n themes = ['light', 'dark'],\n defaultTheme = enableSystem ? 'system' : 'light',\n attribute = 'class',\n onChangeTheme,\n value = {\n dark: 't_dark',\n light: 't_light',\n },\n children,\n}) => {\n const [theme, setThemeState] = useState(() => getTheme(storageKey, defaultTheme))\n const [resolvedTheme, setResolvedTheme] = useState(() => getTheme(storageKey))\n // const resolvedTheme = React.useDeferredValue(resolvedThemeFast)\n const attrs = !value ? themes : Object.values(value)\n\n const handleMediaQuery = useCallback(\n (e?) => {\n const systemTheme = getSystemTheme(e)\n React.startTransition(() => {\n setResolvedTheme(systemTheme)\n })\n if (theme === 'system' && !forcedTheme) handleChangeTheme(systemTheme, false)\n },\n [theme, forcedTheme]\n )\n\n // Ref hack to avoid adding handleMediaQuery as a dep\n const mediaListener = useRef(handleMediaQuery)\n mediaListener.current = handleMediaQuery\n\n const handleChangeTheme = useCallback((theme, updateStorage = true, updateDOM = true) => {\n let name = value?.[theme] || theme\n\n if (updateStorage) {\n try {\n localStorage.setItem(storageKey, theme)\n } catch (e) {\n // Unsupported\n }\n }\n\n if (theme === 'system' && enableSystem) {\n const resolved = getSystemTheme()\n name = value?.[resolved] || resolved\n }\n\n onChangeTheme?.(name.replace('t_', ''))\n\n if (updateDOM) {\n const d = document.documentElement\n if (attribute === 'class') {\n d.classList.remove(...attrs)\n d.classList.add(name)\n } else {\n d.setAttribute(attribute, name)\n }\n }\n }, [])\n\n useIsomorphicLayoutEffect(() => {\n const handler = (...args: any) => mediaListener.current(...args)\n // Always listen to System preference\n const media = window.matchMedia(MEDIA)\n // Intentionally use deprecated listener methods to support iOS & old browsers\n media.addListener(handler)\n handler(media)\n return () => {\n media.removeListener(handler)\n }\n }, [])\n\n const setTheme = useCallback(\n (newTheme) => {\n if (forcedTheme) {\n handleChangeTheme(newTheme, true, false)\n } else {\n handleChangeTheme(newTheme)\n }\n setThemeState(newTheme)\n },\n [forcedTheme]\n )\n\n // localStorage event handling\n useEffect(() => {\n const handleStorage = (e: StorageEvent) => {\n if (e.key !== storageKey) {\n return\n }\n // If default theme set, use it if localstorage === null (happens on local storage manual deletion)\n const theme = e.newValue || defaultTheme\n setTheme(theme)\n }\n window.addEventListener('storage', handleStorage)\n return () => {\n window.removeEventListener('storage', handleStorage)\n }\n }, [])\n\n // color-scheme handling\n useIsomorphicLayoutEffect(() => {\n if (!enableColorScheme) return\n\n const colorScheme =\n // If theme is forced to light or dark, use that\n forcedTheme && colorSchemes.includes(forcedTheme)\n ? forcedTheme\n : // If regular theme is light or dark\n theme && colorSchemes.includes(theme)\n ? theme\n : // If theme is system, use the resolved version\n theme === 'system'\n ? resolvedTheme || null\n : null\n\n // color-scheme tells browser how to render built-in elements like forms, scrollbars, etc.\n // if color-scheme is null, this will remove the property\n const userPrefers =\n typeof window !== 'undefined' &&\n window.matchMedia &&\n window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light'\n\n const wePrefer = colorScheme || 'light'\n\n // avoid running this because it causes full page reflow\n if (userPrefers !== wePrefer) {\n document.documentElement.style.setProperty('color-scheme', colorScheme)\n }\n }, [enableColorScheme, theme, resolvedTheme, forcedTheme])\n\n const contextValue = useMemo(() => {\n return {\n theme,\n setTheme,\n toggleTheme() {\n const order =\n resolvedTheme === 'dark' ? ['system', 'light', 'dark'] : ['system', 'dark', 'light']\n const next = order[(order.indexOf(theme) + 1) % order.length]\n setTheme(next)\n },\n forcedTheme,\n resolvedTheme: theme === 'system' ? resolvedTheme : theme,\n themes: enableSystem ? [...themes, 'system'] : themes,\n systemTheme: (enableSystem ? resolvedTheme : undefined) as 'light' | 'dark' | undefined,\n } as const\n }, [theme, forcedTheme, resolvedTheme, enableSystem])\n\n return (\n <ThemeContext.Provider value={contextValue}>\n <ThemeScript\n {...{\n forcedTheme,\n storageKey,\n systemTheme: resolvedTheme,\n attribute,\n value,\n enableSystem,\n defaultTheme,\n attrs,\n }}\n />\n {children}\n </ThemeContext.Provider>\n )\n}\n\nconst ThemeScript = memo(\n ({\n forcedTheme,\n storageKey,\n attribute,\n enableSystem,\n defaultTheme,\n value,\n attrs,\n }: {\n forcedTheme?: string\n storageKey: string\n attribute?: string\n enableSystem?: boolean\n defaultTheme: string\n value?: ValueObject\n attrs: any\n }) => {\n // Code-golfing the amount of characters in the script\n const optimization = (() => {\n if (attribute === 'class') {\n const removeClasses = attrs.map((t: string) => `d.remove('${t}')`).join(';')\n return `var d=document.documentElement.classList;${removeClasses};`\n } else {\n return `var d=document.documentElement;`\n }\n })()\n\n const updateDOM = (name: string, literal?: boolean) => {\n name = value?.[name] || name\n const val = literal ? name : `'${name}'`\n\n if (attribute === 'class') {\n return `d.add(${val})`\n }\n\n return `d.setAttribute('${attribute}', ${val})`\n }\n\n const defaultSystem = defaultTheme === 'system'\n\n return (\n <NextHead>\n {forcedTheme ? (\n <script\n key=\"next-themes-script\"\n dangerouslySetInnerHTML={{\n // These are minified via Terser and then updated by hand, don't recommend\n // prettier-ignore\n __html: `!function(){${optimization}${updateDOM(forcedTheme)}}()`,\n }}\n />\n ) : enableSystem ? (\n <script\n key=\"next-themes-script\"\n dangerouslySetInnerHTML={{\n // prettier-ignore\n __html: `!function(){try {${optimization}var e=localStorage.getItem('${storageKey}');${!defaultSystem ? updateDOM(defaultTheme) + ';' : ''}if(\"system\"===e||(!e&&${defaultSystem})){var t=\"${MEDIA}\",m=window.matchMedia(t);m.media!==t||m.matches?${updateDOM('dark')}:${updateDOM('light')}}else if(e) ${value ? `var x=${JSON.stringify(value)};` : ''}${updateDOM(value ? 'x[e]' : 'e', true)}}catch(e){}}()`,\n }}\n />\n ) : (\n <script\n key=\"next-themes-script\"\n dangerouslySetInnerHTML={{\n // prettier-ignore\n __html: `!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)};}}catch(t){}}();`,\n }}\n />\n )}\n </NextHead>\n )\n },\n (prevProps, nextProps) => {\n // Only re-render when forcedTheme changes\n // the rest of the props should be completely stable\n if (prevProps.forcedTheme !== nextProps.forcedTheme) return false\n return true\n }\n)\n\n// Helpers\nconst getTheme = (key: string, fallback?: string) => {\n if (typeof window === 'undefined') return undefined\n let theme\n try {\n theme = localStorage.getItem(key) || undefined\n } catch (e) {\n // Unsupported\n }\n return theme || fallback\n}\n\nconst getSystemTheme = (e?: MediaQueryList) => {\n if (!e) {\n e = window.matchMedia(MEDIA)\n }\n\n const isDark = e.matches\n const systemTheme = isDark ? 'dark' : 'light'\n return systemTheme\n}\n"],
5
- "mappings": "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",
6
- "names": ["theme"]
4
+ "sourcesContent": ["// https://raw.githubusercontent.com/pacocoursey/next-themes/master/index.tsx\n// forked temporarily due to buggy theme change\n\nimport { useEvent } from '@tamagui/use-event'\nimport NextHead from 'next/head'\nimport * as React from 'react'\nimport {\n createContext,\n memo,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nconst useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nexport interface UseThemeProps {\n /** List of all available theme names */\n themes: string[]\n /** Forced theme name for the current page */\n forcedTheme?: string\n /** Update the theme */\n set: (theme: string) => void\n toggle: () => void\n /** Active theme name - will return \"system\" if not overriden, see \"resolvedTheme\" for getting resolved system value */\n current?: string\n /** @deprecated Use `current` instead (deprecating avoid confusion with useTheme) */\n theme?: string\n /** If `enableSystem` is true and the active theme is \"system\", this returns whether the system preference resolved to \"dark\" or \"light\". Otherwise, identical to `theme` */\n resolvedTheme?: string\n /** If enableSystem is true, returns the System theme preference (\"dark\" or \"light\"), regardless what the active theme is */\n systemTheme?: 'dark' | 'light'\n}\n\nexport interface ThemeProviderProps {\n children?: any\n /** List of all available theme names */\n themes?: string[]\n /** Forced theme name for the current page */\n forcedTheme?: string\n /** Whether to switch between dark and light themes based on prefers-color-scheme */\n enableSystem?: boolean\n systemTheme?: string\n /** Disable all CSS transitions when switching themes */\n disableTransitionOnChange?: boolean\n /** Whether to indicate to browsers which color scheme is used (dark or light) for built-in UI like inputs and buttons */\n enableColorScheme?: boolean\n /** Key used to store theme setting in localStorage */\n storageKey?: string\n /** Default theme name (for v0.0.12 and lower the default was light). If `enableSystem` is false, the default theme is light */\n defaultTheme?: string\n /** HTML attribute modified based on the active theme. Accepts `class` and `data-*` (meaning any data attribute, `data-mode`, `data-color`, etc.) */\n attribute?: string | 'class'\n /** Mapping of theme name to HTML attribute value. Object where key is the theme name and value is the attribute value */\n value?: ValueObject\n onChangeTheme?: (name: string) => void\n}\n\nconst ThemeSettingContext = createContext<UseThemeProps>({\n toggle: () => {},\n set: (_) => {},\n themes: [],\n})\n\n/**\n * @deprecated renamed to `useThemeSetting` to avoid confusion with core `useTheme` hook\n */\nexport const useTheme = () => useContext(ThemeSettingContext)\n\nexport const useThemeSetting = () => useContext(ThemeSettingContext)\n\nconst colorSchemes = ['light', 'dark']\nconst MEDIA = '(prefers-color-scheme: dark)'\n\ninterface ValueObject {\n [themeName: string]: string\n}\n\nexport const useRootTheme = () => {\n const isClient = typeof document !== 'undefined'\n // @ts-ignore\n const classes = isClient ? [...document.documentElement.classList] : []\n const isDark = classes.includes('t_dark')\n return useState(isDark ? 'dark' : 'light')\n}\n\nexport const NextThemeProvider: React.FC<ThemeProviderProps> = ({\n forcedTheme,\n disableTransitionOnChange = true,\n enableSystem = true,\n enableColorScheme = true,\n storageKey = 'theme',\n themes = ['light', 'dark'],\n defaultTheme = enableSystem ? 'system' : 'light',\n attribute = 'class',\n onChangeTheme,\n value = {\n dark: 't_dark',\n light: 't_light',\n },\n children,\n}) => {\n const [theme, setThemeState] = useState(() => getTheme(storageKey, defaultTheme))\n const [resolvedTheme, setResolvedTheme] = useState(() => getTheme(storageKey))\n // const resolvedTheme = React.useDeferredValue(resolvedThemeFast)\n const attrs = !value ? themes : Object.values(value)\n\n const handleMediaQuery = useEvent((e?) => {\n const systemTheme = getSystemTheme(e)\n React.startTransition(() => {\n setResolvedTheme(systemTheme)\n })\n if (theme === 'system' && !forcedTheme) handleChangeTheme(systemTheme, false)\n })\n\n // Ref hack to avoid adding handleMediaQuery as a dep\n const mediaListener = useRef(handleMediaQuery)\n mediaListener.current = handleMediaQuery\n\n const handleChangeTheme = useEvent((theme, updateStorage = true, updateDOM = true) => {\n let name = value?.[theme] || theme\n\n if (updateStorage) {\n try {\n localStorage.setItem(storageKey, theme)\n } catch (e) {\n // Unsupported\n }\n }\n\n if (theme === 'system' && enableSystem) {\n const resolved = getSystemTheme()\n name = value?.[resolved] || resolved\n }\n\n onChangeTheme?.(name.replace('t_', ''))\n\n if (updateDOM) {\n const d = document.documentElement\n if (attribute === 'class') {\n d.classList.remove(...attrs)\n d.classList.add(name)\n } else {\n d.setAttribute(attribute, name)\n }\n }\n })\n\n useIsomorphicLayoutEffect(() => {\n const handler = (...args: any) => mediaListener.current(...args)\n // Always listen to System preference\n const media = window.matchMedia(MEDIA)\n // Intentionally use deprecated listener methods to support iOS & old browsers\n media.addListener(handler)\n handler(media)\n return () => {\n media.removeListener(handler)\n }\n }, [])\n\n const set = useEvent((newTheme) => {\n if (forcedTheme) {\n handleChangeTheme(newTheme, true, false)\n } else {\n handleChangeTheme(newTheme)\n }\n setThemeState(newTheme)\n })\n\n // localStorage event handling\n useEffect(() => {\n const handleStorage = (e: StorageEvent) => {\n if (e.key !== storageKey) {\n return\n }\n // If default theme set, use it if localstorage === null (happens on local storage manual deletion)\n const theme = e.newValue || defaultTheme\n set(theme)\n }\n window.addEventListener('storage', handleStorage)\n return () => {\n window.removeEventListener('storage', handleStorage)\n }\n }, [defaultTheme, set, storageKey])\n\n // color-scheme handling\n useIsomorphicLayoutEffect(() => {\n if (!enableColorScheme) return\n\n const colorScheme =\n // If theme is forced to light or dark, use that\n forcedTheme && colorSchemes.includes(forcedTheme)\n ? forcedTheme\n : // If regular theme is light or dark\n theme && colorSchemes.includes(theme)\n ? theme\n : // If theme is system, use the resolved version\n theme === 'system'\n ? resolvedTheme || null\n : null\n\n // color-scheme tells browser how to render built-in elements like forms, scrollbars, etc.\n // if color-scheme is null, this will remove the property\n const userPrefers =\n typeof window !== 'undefined' &&\n window.matchMedia &&\n window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light'\n\n const wePrefer = colorScheme || 'light'\n\n // avoid running this because it causes full page reflow\n if (userPrefers !== wePrefer) {\n document.documentElement.style.setProperty('color-scheme', colorScheme)\n }\n }, [enableColorScheme, theme, resolvedTheme, forcedTheme])\n\n const contextValue = useMemo(() => {\n const value: UseThemeProps = {\n theme,\n current: theme,\n set,\n toggle() {\n const order =\n resolvedTheme === 'dark' ? ['system', 'light', 'dark'] : ['system', 'dark', 'light']\n const next = order[(order.indexOf(theme) + 1) % order.length]\n set(next)\n },\n forcedTheme,\n resolvedTheme: theme === 'system' ? resolvedTheme : theme,\n themes: enableSystem ? [...themes, 'system'] : themes,\n systemTheme: (enableSystem ? resolvedTheme : undefined) as 'light' | 'dark' | undefined,\n } as const\n\n return value\n }, [theme, set, forcedTheme, resolvedTheme, enableSystem, themes])\n\n return (\n <ThemeSettingContext.Provider value={contextValue}>\n <ThemeScript\n {...{\n forcedTheme,\n storageKey,\n systemTheme: resolvedTheme,\n attribute,\n value,\n enableSystem,\n defaultTheme,\n attrs,\n }}\n />\n {children}\n </ThemeSettingContext.Provider>\n )\n}\n\nconst ThemeScript = memo(\n ({\n forcedTheme,\n storageKey,\n attribute,\n enableSystem,\n defaultTheme,\n value,\n attrs,\n }: {\n forcedTheme?: string\n storageKey: string\n attribute?: string\n enableSystem?: boolean\n defaultTheme: string\n value?: ValueObject\n attrs: any\n }) => {\n // Code-golfing the amount of characters in the script\n const optimization = (() => {\n if (attribute === 'class') {\n const removeClasses = attrs.map((t: string) => `d.remove('${t}')`).join(';')\n return `var d=document.documentElement.classList;${removeClasses};`\n } else {\n return `var d=document.documentElement;`\n }\n })()\n\n const updateDOM = (name: string, literal?: boolean) => {\n name = value?.[name] || name\n const val = literal ? name : `'${name}'`\n\n if (attribute === 'class') {\n return `d.add(${val})`\n }\n\n return `d.setAttribute('${attribute}', ${val})`\n }\n\n const defaultSystem = defaultTheme === 'system'\n\n return (\n <NextHead>\n {forcedTheme ? (\n <script\n key=\"next-themes-script\"\n dangerouslySetInnerHTML={{\n // These are minified via Terser and then updated by hand, don't recommend\n // prettier-ignore\n __html: `!function(){${optimization}${updateDOM(forcedTheme)}}()`,\n }}\n />\n ) : enableSystem ? (\n <script\n key=\"next-themes-script\"\n dangerouslySetInnerHTML={{\n // prettier-ignore\n __html: `!function(){try {${optimization}var e=localStorage.getItem('${storageKey}');${!defaultSystem ? updateDOM(defaultTheme) + ';' : ''}if(\"system\"===e||(!e&&${defaultSystem})){var t=\"${MEDIA}\",m=window.matchMedia(t);m.media!==t||m.matches?${updateDOM('dark')}:${updateDOM('light')}}else if(e) ${value ? `var x=${JSON.stringify(value)};` : ''}${updateDOM(value ? 'x[e]' : 'e', true)}}catch(e){}}()`,\n }}\n />\n ) : (\n <script\n key=\"next-themes-script\"\n dangerouslySetInnerHTML={{\n // prettier-ignore\n __html: `!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)};}}catch(t){}}();`,\n }}\n />\n )}\n </NextHead>\n )\n },\n (prevProps, nextProps) => {\n // Only re-render when forcedTheme changes\n // the rest of the props should be completely stable\n if (prevProps.forcedTheme !== nextProps.forcedTheme) return false\n return true\n }\n)\n\n// Helpers\nconst getTheme = (key: string, fallback?: string) => {\n if (typeof window === 'undefined') return undefined\n let theme\n try {\n theme = localStorage.getItem(key) || undefined\n } catch (e) {\n // Unsupported\n }\n return theme || fallback\n}\n\nconst getSystemTheme = (e?: MediaQueryList) => {\n if (!e) {\n e = window.matchMedia(MEDIA)\n }\n\n const isDark = e.matches\n const systemTheme = isDark ? 'dark' : 'light'\n return systemTheme\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["theme", "value"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamagui/next-theme",
3
- "version": "1.0.1-beta.166",
3
+ "version": "1.0.1-beta.168",
4
4
  "sideEffects": false,
5
5
  "source": "src/index.ts",
6
6
  "types": "./types/index.d.ts",
@@ -15,11 +15,14 @@
15
15
  "build": "tamagui-build",
16
16
  "watch": "tamagui-build --watch"
17
17
  },
18
+ "dependencies": {
19
+ "@tamagui/use-event": "^1.0.1-beta.168"
20
+ },
18
21
  "peerDependencies": {
19
22
  "react": "*"
20
23
  },
21
24
  "devDependencies": {
22
- "@tamagui/build": "^1.0.1-beta.166",
25
+ "@tamagui/build": "^1.0.1-beta.168",
23
26
  "react": "*"
24
27
  },
25
28
  "publishConfig": {
package/src/NextTheme.tsx CHANGED
@@ -1,12 +1,12 @@
1
1
  // https://raw.githubusercontent.com/pacocoursey/next-themes/master/index.tsx
2
2
  // forked temporarily due to buggy theme change
3
3
 
4
+ import { useEvent } from '@tamagui/use-event'
4
5
  import NextHead from 'next/head'
5
6
  import * as React from 'react'
6
7
  import {
7
8
  createContext,
8
9
  memo,
9
- useCallback,
10
10
  useContext,
11
11
  useEffect,
12
12
  useLayoutEffect,
@@ -23,9 +23,11 @@ export interface UseThemeProps {
23
23
  /** Forced theme name for the current page */
24
24
  forcedTheme?: string
25
25
  /** Update the theme */
26
- setTheme: (theme: string) => void
27
- toggleTheme: () => void
28
- /** Active theme name */
26
+ set: (theme: string) => void
27
+ toggle: () => void
28
+ /** Active theme name - will return "system" if not overriden, see "resolvedTheme" for getting resolved system value */
29
+ current?: string
30
+ /** @deprecated Use `current` instead (deprecating avoid confusion with useTheme) */
29
31
  theme?: string
30
32
  /** If `enableSystem` is true and the active theme is "system", this returns whether the system preference resolved to "dark" or "light". Otherwise, identical to `theme` */
31
33
  resolvedTheme?: string
@@ -57,12 +59,18 @@ export interface ThemeProviderProps {
57
59
  onChangeTheme?: (name: string) => void
58
60
  }
59
61
 
60
- const ThemeContext = createContext<UseThemeProps>({
61
- toggleTheme: () => {},
62
- setTheme: (_) => {},
62
+ const ThemeSettingContext = createContext<UseThemeProps>({
63
+ toggle: () => {},
64
+ set: (_) => {},
63
65
  themes: [],
64
66
  })
65
- export const useTheme = () => useContext(ThemeContext)
67
+
68
+ /**
69
+ * @deprecated renamed to `useThemeSetting` to avoid confusion with core `useTheme` hook
70
+ */
71
+ export const useTheme = () => useContext(ThemeSettingContext)
72
+
73
+ export const useThemeSetting = () => useContext(ThemeSettingContext)
66
74
 
67
75
  const colorSchemes = ['light', 'dark']
68
76
  const MEDIA = '(prefers-color-scheme: dark)'
@@ -100,22 +108,19 @@ export const NextThemeProvider: React.FC<ThemeProviderProps> = ({
100
108
  // const resolvedTheme = React.useDeferredValue(resolvedThemeFast)
101
109
  const attrs = !value ? themes : Object.values(value)
102
110
 
103
- const handleMediaQuery = useCallback(
104
- (e?) => {
105
- const systemTheme = getSystemTheme(e)
106
- React.startTransition(() => {
107
- setResolvedTheme(systemTheme)
108
- })
109
- if (theme === 'system' && !forcedTheme) handleChangeTheme(systemTheme, false)
110
- },
111
- [theme, forcedTheme]
112
- )
111
+ const handleMediaQuery = useEvent((e?) => {
112
+ const systemTheme = getSystemTheme(e)
113
+ React.startTransition(() => {
114
+ setResolvedTheme(systemTheme)
115
+ })
116
+ if (theme === 'system' && !forcedTheme) handleChangeTheme(systemTheme, false)
117
+ })
113
118
 
114
119
  // Ref hack to avoid adding handleMediaQuery as a dep
115
120
  const mediaListener = useRef(handleMediaQuery)
116
121
  mediaListener.current = handleMediaQuery
117
122
 
118
- const handleChangeTheme = useCallback((theme, updateStorage = true, updateDOM = true) => {
123
+ const handleChangeTheme = useEvent((theme, updateStorage = true, updateDOM = true) => {
119
124
  let name = value?.[theme] || theme
120
125
 
121
126
  if (updateStorage) {
@@ -142,7 +147,7 @@ export const NextThemeProvider: React.FC<ThemeProviderProps> = ({
142
147
  d.setAttribute(attribute, name)
143
148
  }
144
149
  }
145
- }, [])
150
+ })
146
151
 
147
152
  useIsomorphicLayoutEffect(() => {
148
153
  const handler = (...args: any) => mediaListener.current(...args)
@@ -156,17 +161,14 @@ export const NextThemeProvider: React.FC<ThemeProviderProps> = ({
156
161
  }
157
162
  }, [])
158
163
 
159
- const setTheme = useCallback(
160
- (newTheme) => {
161
- if (forcedTheme) {
162
- handleChangeTheme(newTheme, true, false)
163
- } else {
164
- handleChangeTheme(newTheme)
165
- }
166
- setThemeState(newTheme)
167
- },
168
- [forcedTheme]
169
- )
164
+ const set = useEvent((newTheme) => {
165
+ if (forcedTheme) {
166
+ handleChangeTheme(newTheme, true, false)
167
+ } else {
168
+ handleChangeTheme(newTheme)
169
+ }
170
+ setThemeState(newTheme)
171
+ })
170
172
 
171
173
  // localStorage event handling
172
174
  useEffect(() => {
@@ -176,13 +178,13 @@ export const NextThemeProvider: React.FC<ThemeProviderProps> = ({
176
178
  }
177
179
  // If default theme set, use it if localstorage === null (happens on local storage manual deletion)
178
180
  const theme = e.newValue || defaultTheme
179
- setTheme(theme)
181
+ set(theme)
180
182
  }
181
183
  window.addEventListener('storage', handleStorage)
182
184
  return () => {
183
185
  window.removeEventListener('storage', handleStorage)
184
186
  }
185
- }, [])
187
+ }, [defaultTheme, set, storageKey])
186
188
 
187
189
  // color-scheme handling
188
190
  useIsomorphicLayoutEffect(() => {
@@ -218,24 +220,27 @@ export const NextThemeProvider: React.FC<ThemeProviderProps> = ({
218
220
  }, [enableColorScheme, theme, resolvedTheme, forcedTheme])
219
221
 
220
222
  const contextValue = useMemo(() => {
221
- return {
223
+ const value: UseThemeProps = {
222
224
  theme,
223
- setTheme,
224
- toggleTheme() {
225
+ current: theme,
226
+ set,
227
+ toggle() {
225
228
  const order =
226
229
  resolvedTheme === 'dark' ? ['system', 'light', 'dark'] : ['system', 'dark', 'light']
227
230
  const next = order[(order.indexOf(theme) + 1) % order.length]
228
- setTheme(next)
231
+ set(next)
229
232
  },
230
233
  forcedTheme,
231
234
  resolvedTheme: theme === 'system' ? resolvedTheme : theme,
232
235
  themes: enableSystem ? [...themes, 'system'] : themes,
233
236
  systemTheme: (enableSystem ? resolvedTheme : undefined) as 'light' | 'dark' | undefined,
234
237
  } as const
235
- }, [theme, forcedTheme, resolvedTheme, enableSystem])
238
+
239
+ return value
240
+ }, [theme, set, forcedTheme, resolvedTheme, enableSystem, themes])
236
241
 
237
242
  return (
238
- <ThemeContext.Provider value={contextValue}>
243
+ <ThemeSettingContext.Provider value={contextValue}>
239
244
  <ThemeScript
240
245
  {...{
241
246
  forcedTheme,
@@ -249,7 +254,7 @@ export const NextThemeProvider: React.FC<ThemeProviderProps> = ({
249
254
  }}
250
255
  />
251
256
  {children}
252
- </ThemeContext.Provider>
257
+ </ThemeSettingContext.Provider>
253
258
  )
254
259
  }
255
260
 
@@ -1,28 +1,49 @@
1
1
  import * as React from 'react';
2
2
  export interface UseThemeProps {
3
+ /** List of all available theme names */
3
4
  themes: string[];
5
+ /** Forced theme name for the current page */
4
6
  forcedTheme?: string;
5
- setTheme: (theme: string) => void;
6
- toggleTheme: () => void;
7
+ /** Update the theme */
8
+ set: (theme: string) => void;
9
+ toggle: () => void;
10
+ /** Active theme name - will return "system" if not overriden, see "resolvedTheme" for getting resolved system value */
11
+ current?: string;
12
+ /** @deprecated Use `current` instead (deprecating avoid confusion with useTheme) */
7
13
  theme?: string;
14
+ /** If `enableSystem` is true and the active theme is "system", this returns whether the system preference resolved to "dark" or "light". Otherwise, identical to `theme` */
8
15
  resolvedTheme?: string;
16
+ /** If enableSystem is true, returns the System theme preference ("dark" or "light"), regardless what the active theme is */
9
17
  systemTheme?: 'dark' | 'light';
10
18
  }
11
19
  export interface ThemeProviderProps {
12
20
  children?: any;
21
+ /** List of all available theme names */
13
22
  themes?: string[];
23
+ /** Forced theme name for the current page */
14
24
  forcedTheme?: string;
25
+ /** Whether to switch between dark and light themes based on prefers-color-scheme */
15
26
  enableSystem?: boolean;
16
27
  systemTheme?: string;
28
+ /** Disable all CSS transitions when switching themes */
17
29
  disableTransitionOnChange?: boolean;
30
+ /** Whether to indicate to browsers which color scheme is used (dark or light) for built-in UI like inputs and buttons */
18
31
  enableColorScheme?: boolean;
32
+ /** Key used to store theme setting in localStorage */
19
33
  storageKey?: string;
34
+ /** Default theme name (for v0.0.12 and lower the default was light). If `enableSystem` is false, the default theme is light */
20
35
  defaultTheme?: string;
36
+ /** HTML attribute modified based on the active theme. Accepts `class` and `data-*` (meaning any data attribute, `data-mode`, `data-color`, etc.) */
21
37
  attribute?: string | 'class';
38
+ /** Mapping of theme name to HTML attribute value. Object where key is the theme name and value is the attribute value */
22
39
  value?: ValueObject;
23
40
  onChangeTheme?: (name: string) => void;
24
41
  }
42
+ /**
43
+ * @deprecated renamed to `useThemeSetting` to avoid confusion with core `useTheme` hook
44
+ */
25
45
  export declare const useTheme: () => UseThemeProps;
46
+ export declare const useThemeSetting: () => UseThemeProps;
26
47
  interface ValueObject {
27
48
  [themeName: string]: string;
28
49
  }