@space-man/react-theme-animation 2.0.0 → 2.1.0

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.
@@ -3,6 +3,29 @@ import { createContext, useContext, useCallback } from 'react';
3
3
  import { useThemeAnimation } from '../hooks/use-theme-animation';
4
4
  import { ThemeAnimationType } from '../types';
5
5
  const ViteThemeContext = createContext(undefined);
6
+ /**
7
+ * Vite Theme Provider - Optimized for Vite SPA applications
8
+ *
9
+ * This provider is designed for Vite-based single-page applications with optional
10
+ * transition disabling to prevent flash during theme switches.
11
+ *
12
+ * Note: For flash prevention on initial load, add a script to your index.html
13
+ * or inject it via Vite plugin to apply theme before React loads.
14
+ *
15
+ * @param children - React children to wrap with theme context
16
+ * @param themes - Available theme options
17
+ * @param colorThemes - Available color theme options
18
+ * @param defaultTheme - Default theme to use
19
+ * @param defaultColorTheme - Default color theme to use
20
+ * @param animationType - Animation type for theme transitions
21
+ * @param duration - Animation duration in milliseconds
22
+ * @param attribute - HTML attribute to use for theme ('class' or 'data-theme')
23
+ * @param disableTransitionOnChange - Temporarily disable CSS transitions during theme switch
24
+ * @param storageKey - LocalStorage key for theme preference
25
+ * @param colorStorageKey - LocalStorage key for color theme preference
26
+ * @param globalClassName - Class name for dark theme (when using 'class' attribute)
27
+ * @param colorThemePrefix - Prefix for color theme classes
28
+ */
6
29
  export const ViteThemeProvider = ({ children, themes = ['light', 'dark', 'system'], colorThemes = ['default'], defaultTheme = 'system', defaultColorTheme = 'default', animationType = ThemeAnimationType.CIRCLE, duration = 750, attribute = 'class', disableTransitionOnChange = false, storageKey = 'vite-theme', colorStorageKey = 'vite-color-theme', globalClassName = 'dark', colorThemePrefix = 'theme-', }) => {
7
30
  const themeState = useThemeAnimation({
8
31
  themes,
@@ -34,24 +57,24 @@ export const ViteThemeProvider = ({ children, themes = ['light', 'dark', 'system
34
57
  themeState.setTheme(theme);
35
58
  cleanup();
36
59
  }, [themeState.setTheme, applyTransitionDisable]);
37
- const wrappedSwitchTheme = useCallback(async (theme) => {
60
+ const wrappedSwitchTheme = useCallback(async (theme, animationOff = false) => {
38
61
  const cleanup = applyTransitionDisable();
39
- await themeState.switchTheme(theme);
62
+ await themeState.switchTheme(theme, animationOff);
40
63
  cleanup();
41
64
  }, [themeState.switchTheme, applyTransitionDisable]);
42
- const wrappedToggleTheme = useCallback(async () => {
65
+ const wrappedToggleTheme = useCallback(async (animationOff = false) => {
43
66
  const cleanup = applyTransitionDisable();
44
- await themeState.toggleTheme();
67
+ await themeState.toggleTheme(animationOff);
45
68
  cleanup();
46
69
  }, [themeState.toggleTheme, applyTransitionDisable]);
47
- const wrappedToggleLightTheme = useCallback(async () => {
70
+ const wrappedToggleLightTheme = useCallback(async (animationOff = false) => {
48
71
  const cleanup = applyTransitionDisable();
49
- await themeState.toggleLightTheme();
72
+ await themeState.toggleLightTheme(animationOff);
50
73
  cleanup();
51
74
  }, [themeState.toggleLightTheme, applyTransitionDisable]);
52
- const wrappedToggleDarkTheme = useCallback(async () => {
75
+ const wrappedToggleDarkTheme = useCallback(async (animationOff = false) => {
53
76
  const cleanup = applyTransitionDisable();
54
- await themeState.toggleDarkTheme();
77
+ await themeState.toggleDarkTheme(animationOff);
55
78
  cleanup();
56
79
  }, [themeState.toggleDarkTheme, applyTransitionDisable]);
57
80
  const switchThemeFromElement = async (theme, element) => {
@@ -83,8 +83,8 @@ export const useThemeAnimation = (props = {}) => {
83
83
  onColorThemeChange(newColorTheme);
84
84
  }
85
85
  }, [onColorThemeChange, externalColorTheme, colorStorageKey]);
86
- const switchTheme = useCallback(async (newTheme) => {
87
- if (!ref.current || !supportsViewTransitions() || prefersReducedMotion()) {
86
+ const switchTheme = useCallback(async (newTheme, animationOff = false) => {
87
+ if (!ref.current || !supportsViewTransitions() || prefersReducedMotion() || animationOff) {
88
88
  setTheme(newTheme);
89
89
  return;
90
90
  }
@@ -179,19 +179,19 @@ export const useThemeAnimation = (props = {}) => {
179
179
  }
180
180
  setColorTheme(newColorTheme);
181
181
  }, [colorThemes, setColorTheme]);
182
- const toggleTheme = useCallback(async () => {
182
+ const toggleTheme = useCallback(async (animationOff = false) => {
183
183
  const newTheme = resolvedTheme === 'dark' ? 'light' : 'dark';
184
- await switchTheme(newTheme);
184
+ await switchTheme(newTheme, animationOff);
185
185
  }, [resolvedTheme, switchTheme]);
186
- const toggleLightTheme = useCallback(async () => {
186
+ const toggleLightTheme = useCallback(async (animationOff = false) => {
187
187
  if (resolvedTheme === 'light')
188
188
  return;
189
- await switchTheme('light');
189
+ await switchTheme('light', animationOff);
190
190
  }, [resolvedTheme, switchTheme]);
191
- const toggleDarkTheme = useCallback(async () => {
191
+ const toggleDarkTheme = useCallback(async (animationOff = false) => {
192
192
  if (resolvedTheme === 'dark')
193
193
  return;
194
- await switchTheme('dark');
194
+ await switchTheme('dark', animationOff);
195
195
  }, [resolvedTheme, switchTheme]);
196
196
  const toggleColorTheme = useCallback(() => {
197
197
  const currentIndex = colorThemes.indexOf(currentColorTheme);
@@ -2,6 +2,8 @@ export { useThemeAnimation } from './hooks/use-theme-animation';
2
2
  export { ThemeSwitcher } from './components/ThemeSwitcher';
3
3
  export { ThemeSelector } from './components/ThemeSelector';
4
4
  export { SpacemanThemeProvider, useSpacemanTheme } from './components/SpacemanThemeProvider';
5
+ export { NextThemeProvider, useNextTheme } from './components/NextThemeProvider';
6
+ export { TanStackThemeProvider, useTanStackTheme } from './components/TanStackThemeProvider';
5
7
  export { ViteThemeProvider, useViteTheme } from './components/ViteThemeProvider';
6
8
  export type { UseThemeAnimationProps, UseThemeAnimationReturn, ThemeSwitcherProps, ThemeSelectorProps, Theme, ColorTheme, SlideDirection, } from './types';
7
9
  export { ThemeAnimationType } from './types';
package/dist/esm/index.js CHANGED
@@ -2,6 +2,9 @@ export { useThemeAnimation } from './hooks/use-theme-animation';
2
2
  export { ThemeSwitcher } from './components/ThemeSwitcher';
3
3
  export { ThemeSelector } from './components/ThemeSelector';
4
4
  export { SpacemanThemeProvider, useSpacemanTheme } from './components/SpacemanThemeProvider';
5
+ // Framework-specific optimized providers
6
+ export { NextThemeProvider, useNextTheme } from './components/NextThemeProvider';
7
+ export { TanStackThemeProvider, useTanStackTheme } from './components/TanStackThemeProvider';
5
8
  export { ViteThemeProvider, useViteTheme } from './components/ViteThemeProvider';
6
9
  export { ThemeAnimationType } from './types';
7
10
  export { injectBaseStyles, getSystemTheme, resolveTheme, supportsViewTransitions, prefersReducedMotion, } from './utils/animations';
@@ -38,11 +38,11 @@ export interface UseThemeAnimationReturn {
38
38
  resolvedTheme: 'light' | 'dark';
39
39
  setTheme: (theme: Theme) => void;
40
40
  setColorTheme: (colorTheme: ColorTheme) => void;
41
- switchTheme: (theme: Theme) => Promise<void>;
41
+ switchTheme: (theme: Theme, animationOff?: boolean) => Promise<void>;
42
42
  switchColorTheme: (colorTheme: string) => void;
43
- toggleTheme: () => Promise<void>;
44
- toggleLightTheme: () => Promise<void>;
45
- toggleDarkTheme: () => Promise<void>;
43
+ toggleTheme: (animationOff?: boolean) => Promise<void>;
44
+ toggleLightTheme: (animationOff?: boolean) => Promise<void>;
45
+ toggleDarkTheme: (animationOff?: boolean) => Promise<void>;
46
46
  toggleColorTheme: () => void;
47
47
  createColorThemeToggle: (targetColorTheme: string) => () => void;
48
48
  isColorThemeActive: (targetColorTheme: string) => boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@space-man/react-theme-animation",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "React theme switching with smooth view transition animations and multi-theme support",
5
5
  "keywords": [
6
6
  "react",