@space-man/react-theme-animation 1.1.1 → 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.
- package/README.md +129 -380
- package/dist/cjs/components/NextThemeProvider.d.ts +81 -0
- package/dist/cjs/components/NextThemeProvider.js +223 -0
- package/dist/cjs/components/SpacemanThemeProvider.d.ts +8 -2
- package/dist/cjs/components/SpacemanThemeProvider.js +16 -4
- package/dist/cjs/components/TanStackThemeProvider.d.ts +68 -0
- package/dist/cjs/components/TanStackThemeProvider.js +183 -0
- package/dist/cjs/components/ViteThemeProvider.d.ts +49 -7
- package/dist/cjs/components/ViteThemeProvider.js +115 -60
- package/dist/cjs/hooks/use-theme-animation.js +51 -37
- package/dist/cjs/index.d.ts +2 -1
- package/dist/cjs/index.js +8 -1
- package/dist/cjs/types/index.d.ts +8 -2
- package/dist/esm/components/NextThemeProvider.d.ts +81 -0
- package/dist/esm/components/NextThemeProvider.js +185 -0
- package/dist/esm/components/SpacemanThemeProvider.d.ts +8 -2
- package/dist/esm/components/SpacemanThemeProvider.js +16 -4
- package/dist/esm/components/TanStackThemeProvider.d.ts +68 -0
- package/dist/esm/components/TanStackThemeProvider.js +178 -0
- package/dist/esm/components/ViteThemeProvider.d.ts +49 -7
- package/dist/esm/components/ViteThemeProvider.js +117 -62
- package/dist/esm/hooks/use-theme-animation.js +51 -37
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +3 -0
- package/dist/esm/types/index.d.ts +8 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,29 +4,29 @@ https://github.com/user-attachments/assets/2819cf70-c474-478e-b821-6b26457c8d4a
|
|
|
4
4
|
|
|
5
5
|
React theme switching with smooth view transition animations, multi-theme support, and synchronized state management.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
## What's New in v2.1
|
|
8
|
+
|
|
9
|
+
- **animationOff Parameter**: Instantly switch themes without animation via optional parameter on all toggle functions
|
|
10
|
+
- **Universal SSR Support**: Pre-hydration script prevents flash in Next.js, Remix, and SSR frameworks
|
|
11
|
+
- **Three Framework-Specific Providers**: NextThemeProvider (SSR/Next.js), TanStackThemeProvider (TanStack Start), ViteThemeProvider (Vite SPAs)
|
|
12
|
+
- **Consistent Hook API**: All providers expose identical hook interface with 15+ methods
|
|
13
|
+
- **Enhanced Theme Control**: Direct functions for toggleLightTheme(), toggleDarkTheme(), createColorThemeToggle()
|
|
11
14
|
|
|
12
15
|
## Live Demo
|
|
13
16
|
|
|
14
|
-
[Live Demo
|
|
17
|
+
[View Live Demo](https://spaceman-rta-vite.netlify.app/)
|
|
15
18
|
|
|
16
19
|
## Features
|
|
17
20
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
- 🔧 **TypeScript**: Full TypeScript support with comprehensive types
|
|
28
|
-
- 🎛️ **Customizable**: Extensive configuration options
|
|
29
|
-
- 🔙 **Backward Compatible**: Works with existing implementations
|
|
21
|
+
- Smooth view transition animations with customizable origins
|
|
22
|
+
- Multi-theme support (light, dark, system)
|
|
23
|
+
- Color theme variants (brand colors, custom themes)
|
|
24
|
+
- Three framework-optimized providers
|
|
25
|
+
- Powerful useThemeAnimation hook for custom implementations
|
|
26
|
+
- Ready-to-use ThemeSwitcher and ThemeSelector components
|
|
27
|
+
- State synchronization across components
|
|
28
|
+
- Full TypeScript support
|
|
29
|
+
- Performance optimized with reduced motion support
|
|
30
30
|
|
|
31
31
|
## Installation
|
|
32
32
|
|
|
@@ -34,435 +34,184 @@ React theme switching with smooth view transition animations, multi-theme suppor
|
|
|
34
34
|
npm install @space-man/react-theme-animation
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
##
|
|
38
|
-
|
|
39
|
-
This library supports multiple usage patterns:
|
|
40
|
-
|
|
41
|
-
1. **Hook-Only Usage**: Direct hook usage for custom implementations
|
|
42
|
-
2. **Provider Pattern**: Centralized state management (recommended)
|
|
43
|
-
3. **ViteThemeProvider**: Specialized provider for Vite React SPAs
|
|
44
|
-
|
|
45
|
-
📚 **[See the complete Getting Started Guide](./getting-started.md)** for detailed examples, advanced configurations, and best practices.
|
|
37
|
+
## Provider Selection
|
|
46
38
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
⚡ **[View the Vite React SPA Demo](https://github.com/tonyedgal/spaceman-rta-framework-guides/tree/main/example-vite)** for a complete Vite implementation using ViteThemeProvider.
|
|
50
|
-
|
|
51
|
-
---
|
|
39
|
+
Choose the right provider for your framework:
|
|
52
40
|
|
|
53
|
-
|
|
41
|
+
| Provider | Best For | Key Features |
|
|
42
|
+
| --------------------- | ------------------------------ | ------------------------------------------------ |
|
|
43
|
+
| NextThemeProvider | Next.js, Remix, SSR frameworks | Pre-hydration script, CSP support, animations |
|
|
44
|
+
| TanStackThemeProvider | TanStack Start apps | Isomorphic rendering, useHydrated() integration |
|
|
45
|
+
| ViteThemeProvider | Vite React SPAs | Lightweight, transition control, no SSR overhead |
|
|
54
46
|
|
|
55
|
-
|
|
47
|
+
## Quick Start
|
|
56
48
|
|
|
57
|
-
|
|
49
|
+
Basic pattern that works across all providers:
|
|
58
50
|
|
|
59
51
|
```tsx
|
|
60
|
-
import {
|
|
61
|
-
|
|
62
|
-
function ThemeToggle() {
|
|
63
|
-
const { theme, toggleTheme, ref } = useThemeAnimation()
|
|
64
|
-
|
|
65
|
-
return (
|
|
66
|
-
<button ref={ref} onClick={toggleTheme} className="theme-toggle-btn">
|
|
67
|
-
{theme === 'light' ? '🌙' : '🌞'} {theme}
|
|
68
|
-
</button>
|
|
69
|
-
)
|
|
70
|
-
}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
---
|
|
74
|
-
|
|
75
|
-
## 2. Provider Pattern (Recommended)
|
|
76
|
-
|
|
77
|
-
The most powerful pattern using `SpacemanThemeProvider` for centralized theme state management. This prevents state drift and provides synchronized animations.
|
|
78
|
-
|
|
79
|
-
### Basic Provider Setup
|
|
80
|
-
|
|
81
|
-
```tsx
|
|
82
|
-
import {
|
|
83
|
-
SpacemanThemeProvider,
|
|
84
|
-
ThemeSwitcher,
|
|
85
|
-
ThemeSelector,
|
|
86
|
-
} from '@space-man/react-theme-animation'
|
|
52
|
+
import { SpacemanThemeProvider, useSpacemanTheme } from '@space-man/react-theme-animation'
|
|
87
53
|
|
|
88
54
|
function App() {
|
|
89
55
|
return (
|
|
90
|
-
<SpacemanThemeProvider>
|
|
91
|
-
<
|
|
92
|
-
<header>
|
|
93
|
-
<ThemeSwitcher />
|
|
94
|
-
</header>
|
|
95
|
-
|
|
96
|
-
<aside>
|
|
97
|
-
<ThemeSelector colorThemes={['default', 'supabase', 'mono']} />
|
|
98
|
-
</aside>
|
|
99
|
-
|
|
100
|
-
<main>
|
|
101
|
-
<YourAppContent />
|
|
102
|
-
</main>
|
|
103
|
-
</div>
|
|
104
|
-
</SpacemanThemeProvider>
|
|
105
|
-
)
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
---
|
|
110
|
-
|
|
111
|
-
## 3. ViteThemeProvider (Vite React SPAs)
|
|
112
|
-
|
|
113
|
-
Specialized theme provider optimized for Vite React single-page applications. Provides essential theme management without animation features.
|
|
114
|
-
|
|
115
|
-
### Basic Vite Setup
|
|
116
|
-
|
|
117
|
-
```tsx
|
|
118
|
-
import { ViteThemeProvider, useViteTheme } from '@space-man/react-theme-animation'
|
|
119
|
-
|
|
120
|
-
function App() {
|
|
121
|
-
return (
|
|
122
|
-
<ViteThemeProvider defaultTheme="system" storageKey="my-app-theme" attribute="class">
|
|
123
|
-
<div className="app">
|
|
124
|
-
<header>
|
|
125
|
-
<ThemeToggle />
|
|
126
|
-
</header>
|
|
127
|
-
<main>
|
|
128
|
-
<ThemeSection />
|
|
129
|
-
</main>
|
|
130
|
-
</div>
|
|
131
|
-
</ViteThemeProvider>
|
|
132
|
-
)
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function ThemeSection() {
|
|
136
|
-
return (
|
|
137
|
-
<SpacemanThemeProvider>
|
|
138
|
-
<div className="app">
|
|
139
|
-
<header>
|
|
140
|
-
<ThemeSwitcher />
|
|
141
|
-
</header>
|
|
142
|
-
|
|
143
|
-
<aside>
|
|
144
|
-
<ThemeSelector colorThemes={['default', 'supabase', 'mono']} />
|
|
145
|
-
</aside>
|
|
146
|
-
|
|
147
|
-
<main>
|
|
148
|
-
<YourAppContent />
|
|
149
|
-
</main>
|
|
150
|
-
</div>
|
|
56
|
+
<SpacemanThemeProvider defaultTheme="system" defaultColorTheme="default">
|
|
57
|
+
<YourApp />
|
|
151
58
|
</SpacemanThemeProvider>
|
|
152
59
|
)
|
|
153
60
|
}
|
|
154
61
|
|
|
155
62
|
function ThemeToggle() {
|
|
156
|
-
const { theme,
|
|
63
|
+
const { theme, toggleTheme, ref } = useSpacemanTheme()
|
|
157
64
|
|
|
158
65
|
return (
|
|
159
|
-
<button onClick={() =>
|
|
160
|
-
{
|
|
66
|
+
<button ref={ref} onClick={() => toggleTheme()}>
|
|
67
|
+
{theme === 'light' ? 'Dark' : 'Light'}
|
|
161
68
|
</button>
|
|
162
69
|
)
|
|
163
70
|
}
|
|
164
71
|
```
|
|
165
72
|
|
|
166
|
-
|
|
73
|
+
**Choose your framework setup guide:**
|
|
74
|
+
|
|
75
|
+
- **[Next.js / SSR Setup Guide](./docs/nextjs-setup.md)** - Complete guide with App Router, Pages Router, CSP support
|
|
76
|
+
- **[TanStack Start Setup Guide](./docs/tanstack-start-setup.md)** - Isomorphic rendering, hydration-safe patterns
|
|
77
|
+
- **[Vite React SPA Setup Guide](./docs/vite-setup.md)** - Client-side setup, flash prevention, routing
|
|
167
78
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
79
|
+
**[View Complete Examples](./example/)** - Next.js implementation with both hook and provider patterns
|
|
80
|
+
|
|
81
|
+
## API Reference
|
|
82
|
+
|
|
83
|
+
### Shared Hook Return (All Providers)
|
|
84
|
+
|
|
85
|
+
All providers expose the same hook interface:
|
|
86
|
+
|
|
87
|
+
| Property | Type | Description |
|
|
88
|
+
| ---------------------- | ------------------------------------------------------- | ---------------------------------- |
|
|
89
|
+
| theme | Theme | Current theme |
|
|
90
|
+
| colorTheme | ColorTheme | Current color theme |
|
|
91
|
+
| resolvedTheme | 'light' \| 'dark' | Resolved theme (system → actual) |
|
|
92
|
+
| systemTheme | 'light' \| 'dark' | OS theme preference |
|
|
93
|
+
| ref | RefObject<HTMLElement> | Ref for animation origin |
|
|
94
|
+
| setTheme | (theme: Theme) => void | Set theme instantly |
|
|
95
|
+
| setColorTheme | (colorTheme: ColorTheme) => void | Set color theme |
|
|
96
|
+
| switchTheme | (theme: Theme, animationOff?: boolean) => Promise<void> | Switch with animation |
|
|
97
|
+
| switchColorTheme | (colorTheme: string) => void | Switch color theme with animation |
|
|
98
|
+
| toggleTheme | (animationOff?: boolean) => Promise<void> | Toggle light/dark |
|
|
99
|
+
| toggleLightTheme | (animationOff?: boolean) => Promise<void> | Toggle to light |
|
|
100
|
+
| toggleDarkTheme | (animationOff?: boolean) => Promise<void> | Toggle to dark |
|
|
101
|
+
| toggleColorTheme | () => void | Toggle between color themes |
|
|
102
|
+
| createColorThemeToggle | (colorTheme: string) => () => void | Create color theme toggle |
|
|
103
|
+
| isColorThemeActive | (colorTheme: string) => boolean | Check if color theme active |
|
|
104
|
+
| switchThemeFromElement | (theme: Theme, element: HTMLElement) => Promise<void> | Switch with animation from element |
|
|
105
|
+
|
|
106
|
+
### Provider Props
|
|
107
|
+
|
|
108
|
+
| Prop | Spaceman | NextTheme | TanStack | Vite | Type | Default |
|
|
109
|
+
| ------------------------- | -------- | --------- | -------- | ---- | ------------------ | --------------------------- |
|
|
110
|
+
| defaultTheme | ✓ | ✓ | ✓ | ✓ | Theme | 'system' |
|
|
111
|
+
| defaultColorTheme | ✓ | ✓ | ✓ | ✓ | ColorTheme | 'default' |
|
|
112
|
+
| themes | ✓ | ✓ | ✓ | ✓ | Theme[] | ['light', 'dark', 'system'] |
|
|
113
|
+
| colorThemes | ✓ | ✓ | ✓ | ✓ | ColorTheme[] | ['default'] |
|
|
114
|
+
| animationType | ✓ | ✓ | ✓ | ✓ | ThemeAnimationType | CIRCLE |
|
|
115
|
+
| duration | ✓ | ✓ | ✓ | ✓ | number | 500 |
|
|
116
|
+
| storageKey | ✓ | ✓ | ✓ | ✓ | string | varies |
|
|
117
|
+
| colorStorageKey | ✓ | ✓ | ✓ | ✓ | string | varies |
|
|
118
|
+
| nonce | ✗ | ✓ | ✗ | ✗ | string | - |
|
|
119
|
+
| disablePreHydrationScript | ✗ | ✓ | ✗ | ✗ | boolean | false |
|
|
120
|
+
| disableTransitionOnChange | ✗ | ✗ | ✗ | ✓ | boolean | false |
|
|
121
|
+
| onThemeChange | ✓ | ✓ | ✓ | ✓ | function | - |
|
|
122
|
+
| onColorThemeChange | ✓ | ✓ | ✓ | ✓ | function | - |
|
|
123
|
+
|
|
124
|
+
### Components
|
|
125
|
+
|
|
126
|
+
**ThemeSwitcher**: Pre-built theme toggle buttons with animations
|
|
127
|
+
**ThemeSelector**: Dropdown selector for color themes
|
|
128
|
+
|
|
129
|
+
See framework-specific guides for component usage examples.
|
|
176
130
|
|
|
177
131
|
---
|
|
178
132
|
|
|
179
|
-
|
|
133
|
+
<details>
|
|
134
|
+
<summary>CSS Variables Setup</summary>
|
|
180
135
|
|
|
181
|
-
|
|
136
|
+
Define theme variables in your global CSS file:
|
|
182
137
|
|
|
183
138
|
```css
|
|
184
|
-
/* Base theme variables */
|
|
185
139
|
:root {
|
|
186
140
|
--background: 0 0% 100%;
|
|
187
141
|
--foreground: 222.2 84% 4.9%;
|
|
142
|
+
--primary: 221.2 83.2% 53.3%;
|
|
188
143
|
}
|
|
189
144
|
|
|
190
|
-
/* Dark theme */
|
|
191
145
|
.dark {
|
|
192
146
|
--background: 222.2 84% 4.9%;
|
|
193
147
|
--foreground: 210 40% 98%;
|
|
148
|
+
--primary: 217.2 91.2% 59.8%;
|
|
194
149
|
}
|
|
195
150
|
|
|
196
|
-
/*
|
|
197
|
-
|
|
198
|
-
.
|
|
199
|
-
--background: oklch(0.9911 0 0);
|
|
200
|
-
--foreground: oklch(0.2046 0 0);
|
|
151
|
+
/* Color theme variants */
|
|
152
|
+
.theme-blue {
|
|
153
|
+
--primary: 221.2 83.2% 53.3%;
|
|
201
154
|
}
|
|
202
155
|
|
|
203
|
-
.theme-
|
|
204
|
-
--
|
|
205
|
-
--foreground: oklch(0.9288 0.0126 255.5078);
|
|
156
|
+
.theme-blue.dark {
|
|
157
|
+
--primary: 217.2 91.2% 59.8%;
|
|
206
158
|
}
|
|
207
159
|
|
|
208
|
-
.theme-
|
|
209
|
-
--
|
|
210
|
-
--foreground: oklch(0.1448 0 0);
|
|
160
|
+
.theme-green {
|
|
161
|
+
--primary: 142.1 76.2% 36.3%;
|
|
211
162
|
}
|
|
212
163
|
|
|
213
|
-
.theme-
|
|
214
|
-
--
|
|
215
|
-
--foreground: oklch(1 0 0);
|
|
164
|
+
.theme-green.dark {
|
|
165
|
+
--primary: 142.1 70.6% 45.3%;
|
|
216
166
|
}
|
|
217
167
|
```
|
|
218
168
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
## API Reference
|
|
222
|
-
|
|
223
|
-
### SpacemanThemeProvider
|
|
224
|
-
|
|
225
|
-
Context provider for centralized theme state management for the ThemeSelector and ThemeSwitcher components. The SpacemanThemeProvider allows you to manage themes and color themes in your application with smooth animations and synchronized state and provide a state reference for the ThemeSelector and ThemeSwitcher components.
|
|
226
|
-
|
|
227
|
-
```tsx
|
|
228
|
-
<SpacemanThemeProvider
|
|
229
|
-
defaultTheme="system"
|
|
230
|
-
defaultColorTheme="blue"
|
|
231
|
-
themes={['light', 'dark', 'system']}
|
|
232
|
-
colorThemes={['default', 'blue', 'green', 'purple']}
|
|
233
|
-
animationType={ThemeAnimationType.CIRCLE}
|
|
234
|
-
duration={800}
|
|
235
|
-
onThemeChange={theme => console.log('Theme:', theme)}
|
|
236
|
-
onColorThemeChange={colorTheme => console.log('Color:', colorTheme)}
|
|
237
|
-
>
|
|
238
|
-
{children}
|
|
239
|
-
</SpacemanThemeProvider>
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
#### SpacemanThemeProvider Props
|
|
243
|
-
|
|
244
|
-
| Property | Type | Default | Description |
|
|
245
|
-
| -------------------- | ---------------------------------- | ----------------------------- | ------------------------------------- |
|
|
246
|
-
| `defaultTheme` | `Theme` | `'system'` | Initial theme |
|
|
247
|
-
| `defaultColorTheme` | `ColorTheme` | `'default'` | Initial color theme |
|
|
248
|
-
| `themes` | `Theme[]` | `['light', 'dark', 'system']` | Available themes |
|
|
249
|
-
| `colorThemes` | `ColorTheme[]` | `['default']` | Available color themes |
|
|
250
|
-
| `animationType` | `ThemeAnimationType` | `ThemeAnimationType.CIRCLE` | Animation type |
|
|
251
|
-
| `duration` | `number` | `500` | Animation duration in ms |
|
|
252
|
-
| `blurAmount` | `number` | `2` | Blur amount for blur-circle animation |
|
|
253
|
-
| `onThemeChange` | `(theme: Theme) => void` | - | Global theme change callback |
|
|
254
|
-
| `onColorThemeChange` | `(colorTheme: ColorTheme) => void` | - | Global color theme change callback |
|
|
255
|
-
|
|
256
|
-
### useSpacemanTheme
|
|
169
|
+
</details>
|
|
257
170
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
```tsx
|
|
261
|
-
const { theme, colorTheme, switchTheme, setColorTheme, switchThemeFromElement, ref } =
|
|
262
|
-
useSpacemanTheme()
|
|
263
|
-
```
|
|
171
|
+
<details>
|
|
172
|
+
<summary>Browser Support</summary>
|
|
264
173
|
|
|
265
|
-
|
|
174
|
+
- View Transitions API: Chrome 111+, Edge 111+
|
|
175
|
+
- Fallback: All modern browsers with CSS transitions
|
|
176
|
+
- Reduced Motion: Respects prefers-reduced-motion
|
|
177
|
+
- Framework Support: React 16.8+ (hooks required)
|
|
266
178
|
|
|
267
|
-
|
|
268
|
-
| ------------------------ | ------------------------------------------------------- | ------------------------------------------------- |
|
|
269
|
-
| `theme` | `Theme` | Current theme |
|
|
270
|
-
| `colorTheme` | `ColorTheme` | Current color theme |
|
|
271
|
-
| `switchTheme` | `(theme: Theme) => Promise<void>` | Switch to specific theme |
|
|
272
|
-
| `setColorTheme` | `(colorTheme: ColorTheme) => void` | Set color theme |
|
|
273
|
-
| `switchThemeFromElement` | `(theme: Theme, element: HTMLElement) => Promise<void>` | Switch theme with animation from specific element |
|
|
274
|
-
| `ref` | `RefObject<HTMLElement>` | Ref for animation origin |
|
|
179
|
+
</details>
|
|
275
180
|
|
|
276
|
-
|
|
181
|
+
<details>
|
|
182
|
+
<summary>Advanced Configuration</summary>
|
|
277
183
|
|
|
278
|
-
|
|
184
|
+
### Animation Control
|
|
279
185
|
|
|
280
186
|
```tsx
|
|
281
|
-
const {
|
|
282
|
-
themes: ['light', 'dark', 'system'],
|
|
283
|
-
colorThemes: ['default', 'blue', 'green', 'purple'],
|
|
284
|
-
animationType: ThemeAnimationType.SLIDE,
|
|
285
|
-
duration: 800,
|
|
286
|
-
onThemeChange: theme => console.log('Theme changed:', theme),
|
|
287
|
-
onColorThemeChange: colorTheme => console.log('Color changed:', colorTheme),
|
|
288
|
-
})
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
#### Options
|
|
292
|
-
|
|
293
|
-
| Property | Type | Default | Description |
|
|
294
|
-
| -------------------- | ---------------------------------- | ----------------------------- | --------------------------------------------------- |
|
|
295
|
-
| `themes` | `Theme[]` | `['light', 'dark', 'system']` | Available themes |
|
|
296
|
-
| `colorThemes` | `ColorTheme[]` | `['default']` | Available color themes |
|
|
297
|
-
| `theme` | `Theme` | `'system'` | Initial theme |
|
|
298
|
-
| `colorTheme` | `ColorTheme` | `'default'` | Initial color theme |
|
|
299
|
-
| `animationType` | `ThemeAnimationType` | `ThemeAnimationType.CIRCLE` | Animation type. Options: CIRCLE, BLUR_CIRCLE, SLIDE |
|
|
300
|
-
| `duration` | `number` | `500` | Animation duration in ms |
|
|
301
|
-
| `blurAmount` | `number` | `2` | Blur amount for blur-circle animation |
|
|
302
|
-
| `onThemeChange` | `(theme: Theme) => void` | - | Theme change callback |
|
|
303
|
-
| `onColorThemeChange` | `(colorTheme: ColorTheme) => void` | - | Color theme change callback |
|
|
304
|
-
| `slideDirection` | `SlideDirection` | `left` | Animation slide direction |
|
|
305
|
-
|
|
306
|
-
#### Return
|
|
307
|
-
|
|
308
|
-
| Property | Type | Description |
|
|
309
|
-
| --------------- | ---------------------------------- | ------------------------- |
|
|
310
|
-
| `theme` | `Theme` | Current theme |
|
|
311
|
-
| `colorTheme` | `ColorTheme` | Current color theme |
|
|
312
|
-
| `switchTheme` | `(theme: Theme) => Promise<void>` | Switch to specific theme |
|
|
313
|
-
| `setColorTheme` | `(colorTheme: ColorTheme) => void` | Set color theme |
|
|
314
|
-
| `toggleTheme` | `() => Promise<void>` | Toggle between light/dark |
|
|
315
|
-
| `ref` | `RefObject<HTMLElement>` | Ref for animation origin |
|
|
316
|
-
|
|
317
|
-
### ThemeSwitcher
|
|
187
|
+
const { switchTheme, toggleTheme } = useSpacemanTheme()
|
|
318
188
|
|
|
319
|
-
|
|
189
|
+
// With animation (default)
|
|
190
|
+
await switchTheme('dark')
|
|
320
191
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
currentTheme="light"
|
|
325
|
-
onThemeChange={theme => console.log(theme)}
|
|
326
|
-
animationType={ThemeAnimationType.CIRCLE}
|
|
327
|
-
duration={600}
|
|
328
|
-
className="custom-class"
|
|
329
|
-
/>
|
|
192
|
+
// Without animation
|
|
193
|
+
await switchTheme('dark', true)
|
|
194
|
+
await toggleTheme(true)
|
|
330
195
|
```
|
|
331
196
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
| Property | Type | Default | Description |
|
|
335
|
-
| --------------- | ------------------------ | ----------------------------- | ----------------------------------- |
|
|
336
|
-
| `themes` | `Theme[]` | `['light', 'dark', 'system']` | Available themes |
|
|
337
|
-
| `currentTheme` | `Theme` | - | Controlled current theme (optional) |
|
|
338
|
-
| `onThemeChange` | `(theme: Theme) => void` | - | Theme change callback (optional) |
|
|
339
|
-
| `animationType` | `ThemeAnimationType` | `ThemeAnimationType.CIRCLE` | Animation type |
|
|
340
|
-
| `duration` | `number` | `500` | Animation duration in ms |
|
|
341
|
-
| `className` | `string` | - | Additional CSS classes |
|
|
342
|
-
|
|
343
|
-
> **Note**: When used with `SpacemanThemeProvider`, `currentTheme` and `onThemeChange` are automatically handled by the context.
|
|
344
|
-
|
|
345
|
-
### ThemeSelector
|
|
346
|
-
|
|
347
|
-
Dropdown selector for color themes.
|
|
348
|
-
|
|
349
|
-
```tsx
|
|
350
|
-
<ThemeSelector
|
|
351
|
-
colorThemes={['default', 'blue', 'green', 'purple']}
|
|
352
|
-
currentColorTheme="blue"
|
|
353
|
-
onColorThemeChange={colorTheme => console.log(colorTheme)}
|
|
354
|
-
animationType={ThemeAnimationType.BLUR_CIRCLE}
|
|
355
|
-
duration={400}
|
|
356
|
-
/>
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
#### ThemeSelector Props
|
|
360
|
-
|
|
361
|
-
| Property | Type | Default | Description |
|
|
362
|
-
| -------------------- | ---------------------------------- | ----------------------------- | ----------------------------------------- |
|
|
363
|
-
| `themes` | `Theme[]` | `['light', 'dark', 'system']` | Available themes (for standalone hook) |
|
|
364
|
-
| `colorThemes` | `ColorTheme[]` | `['default']` | Available color themes |
|
|
365
|
-
| `currentColorTheme` | `ColorTheme` | - | Controlled current color theme (optional) |
|
|
366
|
-
| `onColorThemeChange` | `(colorTheme: ColorTheme) => void` | - | Color theme change callback (optional) |
|
|
367
|
-
| `animationType` | `ThemeAnimationType` | `ThemeAnimationType.CIRCLE` | Animation type |
|
|
368
|
-
| `duration` | `number` | `500` | Animation duration in ms |
|
|
369
|
-
|
|
370
|
-
> **Note**: When used with `SpacemanThemeProvider`, `currentColorTheme` and `onColorThemeChange` are automatically handled by the context.
|
|
371
|
-
|
|
372
|
-
### ThemeAnimationType
|
|
373
|
-
|
|
374
|
-
Animation types for theme transitions.
|
|
197
|
+
### Custom Hook Usage
|
|
375
198
|
|
|
376
199
|
```tsx
|
|
377
|
-
|
|
378
|
-
CIRCLE = 'circle',
|
|
379
|
-
BLUR_CIRCLE = 'blur-circle',
|
|
380
|
-
}
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
### Types
|
|
384
|
-
|
|
385
|
-
```tsx
|
|
386
|
-
type Theme = 'light' | 'dark' | 'system'
|
|
387
|
-
type ColorTheme = string // e.g., 'default', 'blue', 'green', etc.
|
|
388
|
-
|
|
389
|
-
interface SpacemanThemeProviderProps {
|
|
390
|
-
children: React.ReactNode
|
|
391
|
-
defaultTheme?: Theme
|
|
392
|
-
defaultColorTheme?: ColorTheme
|
|
393
|
-
themes?: Theme[]
|
|
394
|
-
colorThemes?: ColorTheme[]
|
|
395
|
-
animationType?: ThemeAnimationType
|
|
396
|
-
duration?: number
|
|
397
|
-
blurAmount?: number
|
|
398
|
-
onThemeChange?: (theme: Theme) => void
|
|
399
|
-
onColorThemeChange?: (colorTheme: ColorTheme) => void
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
interface UseThemeAnimationProps {
|
|
403
|
-
themes?: Theme[]
|
|
404
|
-
colorThemes?: ColorTheme[]
|
|
405
|
-
theme?: Theme
|
|
406
|
-
colorTheme?: ColorTheme
|
|
407
|
-
animationType?: ThemeAnimationType
|
|
408
|
-
duration?: number
|
|
409
|
-
blurAmount?: number
|
|
410
|
-
onThemeChange?: (theme: Theme) => void
|
|
411
|
-
onColorThemeChange?: (colorTheme: ColorTheme) => void
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
interface UseThemeAnimationReturn {
|
|
415
|
-
theme: Theme
|
|
416
|
-
colorTheme: ColorTheme
|
|
417
|
-
switchTheme: (theme: Theme) => Promise<void>
|
|
418
|
-
setColorTheme: (colorTheme: ColorTheme) => void
|
|
419
|
-
toggleTheme: () => Promise<void>
|
|
420
|
-
ref: RefObject<HTMLElement>
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
interface ThemeSwitcherProps {
|
|
424
|
-
themes?: Theme[]
|
|
425
|
-
currentTheme?: Theme
|
|
426
|
-
onThemeChange?: (theme: Theme) => void
|
|
427
|
-
animationType?: ThemeAnimationType
|
|
428
|
-
duration?: number
|
|
429
|
-
className?: string
|
|
430
|
-
}
|
|
200
|
+
import { useThemeAnimation } from '@space-man/react-theme-animation'
|
|
431
201
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
duration?: number
|
|
439
|
-
}
|
|
202
|
+
const { theme, toggleTheme, ref } = useThemeAnimation({
|
|
203
|
+
animationType: ThemeAnimationType.BLUR_CIRCLE,
|
|
204
|
+
duration: 750,
|
|
205
|
+
colorThemes: ['default', 'blue', 'green'],
|
|
206
|
+
onThemeChange: theme => console.log('Theme:', theme),
|
|
207
|
+
})
|
|
440
208
|
```
|
|
441
209
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
---
|
|
445
|
-
|
|
446
|
-
## Browser Support
|
|
447
|
-
|
|
448
|
-
- **View Transitions API**: Chrome 111+, Edge 111+
|
|
449
|
-
- **Fallback**: All modern browsers with CSS transitions
|
|
450
|
-
- **Reduced Motion**: Respects `prefers-reduced-motion` setting
|
|
451
|
-
- **Framework Support**: React 16.8+ (hooks required)
|
|
452
|
-
|
|
453
|
-
---
|
|
454
|
-
|
|
455
|
-
## Performance
|
|
456
|
-
|
|
457
|
-
- Animations use the View Transitions API when available
|
|
458
|
-
- Optimized for 60fps animations
|
|
459
|
-
- Respects `prefers-reduced-motion` setting
|
|
460
|
-
|
|
461
|
-
---
|
|
210
|
+
</details>
|
|
462
211
|
|
|
463
212
|
## Contributing
|
|
464
213
|
|
|
465
|
-
|
|
214
|
+
Fork the repository, make your changes, and submit a merge request for review.
|
|
466
215
|
|
|
467
216
|
## License
|
|
468
217
|
|