vartheme 0.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 +252 -0
- package/dist/index.d.mts +70 -0
- package/dist/index.d.ts +70 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +26 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# vartheme β¨
|
|
2
|
+
### Zero-config, CSS variable based theme switching for React
|
|
3
|
+
**Dark mode in one line. Clean. Fast. Modern.**
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/vartheme)
|
|
6
|
+
[](https://bundlephobia.com/package/vartheme)
|
|
7
|
+
[](./LICENSE)
|
|
8
|
+
[](https://www.npmjs.com/package/vartheme)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## π Why vartheme?
|
|
13
|
+
|
|
14
|
+
Most theme libraries are either:
|
|
15
|
+
- β Complex to set up
|
|
16
|
+
- β Framework dependent
|
|
17
|
+
- β Not CSS variable friendly
|
|
18
|
+
- β Missing UI components
|
|
19
|
+
|
|
20
|
+
**vartheme solves this.**
|
|
21
|
+
|
|
22
|
+
π Zero configuration
|
|
23
|
+
π CSS variables by default
|
|
24
|
+
π Built-in toggle
|
|
25
|
+
π System theme detection
|
|
26
|
+
π TypeScript ready
|
|
27
|
+
π Works with Tailwind, CSS, design systems
|
|
28
|
+
π Production ready
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## β‘ Demo (concept)
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
import { ThemeProvider, ThemeToggle } from 'vartheme'
|
|
36
|
+
|
|
37
|
+
export default function App() {
|
|
38
|
+
return (
|
|
39
|
+
<ThemeProvider>
|
|
40
|
+
<ThemeToggle />
|
|
41
|
+
</ThemeProvider>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Thatβs it. Dark mode is done.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## β¨ Features
|
|
51
|
+
|
|
52
|
+
- β‘ Zero config
|
|
53
|
+
- π¨ CSS variable driven
|
|
54
|
+
- π Auto system detection
|
|
55
|
+
- π Smooth transitions
|
|
56
|
+
- π§© Built-in toggle
|
|
57
|
+
- π¦ ~5kb bundle
|
|
58
|
+
- π§ Framework-agnostic core
|
|
59
|
+
- π§ Custom colors
|
|
60
|
+
- π‘ Fully typed
|
|
61
|
+
- π Scalable for large apps
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## π Comparison
|
|
66
|
+
|
|
67
|
+
| Feature | vartheme | next-themes | manual |
|
|
68
|
+
|---------|----------|-------------|--------|
|
|
69
|
+
| Zero config | β
| β | β |
|
|
70
|
+
| CSS variables | β
| β | β
|
|
|
71
|
+
| System detect | β
| β
| β |
|
|
72
|
+
| Built-in UI | β
| β | β |
|
|
73
|
+
| Framework agnostic | β
| β | β
|
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## π¦ Installation
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npm install vartheme
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## β‘ Quick Start
|
|
86
|
+
|
|
87
|
+
### 1. Wrap your app
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import { ThemeProvider } from 'vartheme'
|
|
91
|
+
|
|
92
|
+
function Main() {
|
|
93
|
+
return (
|
|
94
|
+
<ThemeProvider config={{ mode: 'system', transitions: true }}>
|
|
95
|
+
<App />
|
|
96
|
+
</ThemeProvider>
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
### 2. Use the hook
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
import { useThemeContext } from 'vartheme'
|
|
107
|
+
|
|
108
|
+
function Navbar() {
|
|
109
|
+
const { resolvedMode, toggle } = useThemeContext()
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<button onClick={toggle}>
|
|
113
|
+
{resolvedMode === 'dark' ? 'βοΈ Light' : 'π Dark'}
|
|
114
|
+
</button>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
### 3. Built-in toggle
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
import { ThemeToggle } from 'vartheme'
|
|
125
|
+
|
|
126
|
+
export default function Navbar() {
|
|
127
|
+
return <ThemeToggle size={48} />
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
### 4. CSS variables
|
|
134
|
+
|
|
135
|
+
```css
|
|
136
|
+
.card {
|
|
137
|
+
background: var(--vt-surface);
|
|
138
|
+
color: var(--vt-text);
|
|
139
|
+
border: 1px solid var(--vt-border);
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## π¨ Default Variables
|
|
146
|
+
|
|
147
|
+
| Variable | Light | Dark |
|
|
148
|
+
|----------|------|------|
|
|
149
|
+
| `--vt-primary` | `#7C3AED` | `#A78BFA` |
|
|
150
|
+
| `--vt-background` | `#FFFFFF` | `#0F172A` |
|
|
151
|
+
| `--vt-surface` | `#F8FAFC` | `#1E293B` |
|
|
152
|
+
| `--vt-text` | `#0F172A` | `#F8FAFC` |
|
|
153
|
+
| `--vt-border` | `#E2E8F0` | `#334155` |
|
|
154
|
+
| `--vt-accent` | `#06B6D4` | `#22D3EE` |
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## π― Custom Colors
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
<ThemeProvider
|
|
162
|
+
config={{
|
|
163
|
+
colors: {
|
|
164
|
+
primary: '#EC4899',
|
|
165
|
+
accent: '#F59E0B',
|
|
166
|
+
},
|
|
167
|
+
}}
|
|
168
|
+
>
|
|
169
|
+
<App />
|
|
170
|
+
</ThemeProvider>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Dynamic:
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
const { setColors } = useThemeContext()
|
|
177
|
+
setColors({ primary: '#10B981' })
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## π§ API
|
|
183
|
+
|
|
184
|
+
### ThemeProvider
|
|
185
|
+
|
|
186
|
+
| Prop | Type |
|
|
187
|
+
|------|------|
|
|
188
|
+
| mode | `'light' \| 'dark' \| 'system'` |
|
|
189
|
+
| colors | ThemeColors |
|
|
190
|
+
| transitions | boolean |
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### useThemeContext
|
|
195
|
+
|
|
196
|
+
- mode
|
|
197
|
+
- resolvedMode
|
|
198
|
+
- colors
|
|
199
|
+
- toggle()
|
|
200
|
+
- setMode()
|
|
201
|
+
- setColors()
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
### ThemeToggle
|
|
206
|
+
|
|
207
|
+
| Prop | Default |
|
|
208
|
+
|------|------|
|
|
209
|
+
| size | 48 |
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## π§© TypeScript
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
import type { ThemeMode, ThemeColors, ThemeConfig } from 'vartheme'
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## π Use Cases
|
|
222
|
+
|
|
223
|
+
- SaaS dashboards
|
|
224
|
+
- Design systems
|
|
225
|
+
- Portfolios
|
|
226
|
+
- Startups
|
|
227
|
+
- Component libraries
|
|
228
|
+
- Large scale apps
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## π€ Contributing
|
|
233
|
+
|
|
234
|
+
We welcome contributions.
|
|
235
|
+
Open issues, submit PRs, or suggest ideas.
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## β Support
|
|
240
|
+
|
|
241
|
+
If you like this project:
|
|
242
|
+
|
|
243
|
+
- β Star the repo
|
|
244
|
+
- π¦ Share on Twitter
|
|
245
|
+
- π¬ Tell your friends
|
|
246
|
+
- π Help grow the community
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## π License
|
|
251
|
+
|
|
252
|
+
MIT Β© 2026 vartheme
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
type ThemeMode = "light" | "dark" | "system";
|
|
5
|
+
type ThemeName = "default" | "ocean" | "forest" | "sunset" | "rose" | (string & {});
|
|
6
|
+
interface ThemeColors {
|
|
7
|
+
primary?: string;
|
|
8
|
+
background?: string;
|
|
9
|
+
surface?: string;
|
|
10
|
+
text?: string;
|
|
11
|
+
border?: string;
|
|
12
|
+
accent?: string;
|
|
13
|
+
}
|
|
14
|
+
interface ThemeConfig {
|
|
15
|
+
mode?: ThemeMode;
|
|
16
|
+
colors?: ThemeColors;
|
|
17
|
+
transitions?: boolean;
|
|
18
|
+
}
|
|
19
|
+
interface ThemeState {
|
|
20
|
+
mode: ThemeMode;
|
|
21
|
+
resolvedMode: "light" | "dark";
|
|
22
|
+
colors: ThemeColors;
|
|
23
|
+
theme: ThemeName;
|
|
24
|
+
toggle: () => void;
|
|
25
|
+
setMode: (mode: ThemeMode) => void;
|
|
26
|
+
setColors: (colors: ThemeColors) => void;
|
|
27
|
+
setTheme: (theme: ThemeName) => void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare function injectCSSVariables(colors: ThemeColors, mode: "light" | "dark"): void;
|
|
31
|
+
declare function getDefaultColors(mode: "light" | "dark"): ThemeColors;
|
|
32
|
+
|
|
33
|
+
declare function saveMode(mode: ThemeMode): void;
|
|
34
|
+
declare function loadMode(): ThemeMode | null;
|
|
35
|
+
declare function saveColors(colors: ThemeColors): void;
|
|
36
|
+
declare function loadColors(): ThemeColors | null;
|
|
37
|
+
declare function clearStorage(): void;
|
|
38
|
+
|
|
39
|
+
type SystemMode = "light" | "dark";
|
|
40
|
+
type SystemModeListener = (mode: SystemMode) => void;
|
|
41
|
+
declare function getSystemMode(): SystemMode;
|
|
42
|
+
declare function watchSystemMode(callback: SystemModeListener): () => void;
|
|
43
|
+
declare function isBrowser(): boolean;
|
|
44
|
+
|
|
45
|
+
interface ThemeToggleProps {
|
|
46
|
+
size?: number;
|
|
47
|
+
}
|
|
48
|
+
declare function ThemeToggle({ size }: ThemeToggleProps): react_jsx_runtime.JSX.Element;
|
|
49
|
+
|
|
50
|
+
interface ThemePreset {
|
|
51
|
+
name: string;
|
|
52
|
+
light: ThemeColors;
|
|
53
|
+
dark: ThemeColors;
|
|
54
|
+
}
|
|
55
|
+
declare const BUILT_IN_THEMES: Record<string, ThemePreset>;
|
|
56
|
+
declare function getTheme(name: string): ThemePreset;
|
|
57
|
+
|
|
58
|
+
declare function useTheme(initial?: ThemeMode, initialTheme?: ThemeName): ThemeState;
|
|
59
|
+
|
|
60
|
+
interface ThemeProviderProps {
|
|
61
|
+
children: ReactNode;
|
|
62
|
+
mode?: ThemeMode;
|
|
63
|
+
theme?: ThemeName;
|
|
64
|
+
colors?: ThemeColors;
|
|
65
|
+
transitions?: boolean;
|
|
66
|
+
}
|
|
67
|
+
declare function ThemeProvider({ children, mode, theme, colors, transitions, }: ThemeProviderProps): react_jsx_runtime.JSX.Element;
|
|
68
|
+
declare function useThemeContext(): ThemeState;
|
|
69
|
+
|
|
70
|
+
export { BUILT_IN_THEMES, type ThemeColors, type ThemeConfig, type ThemeMode, type ThemeName, ThemeProvider, type ThemeState, ThemeToggle, clearStorage, getDefaultColors, getSystemMode, getTheme, injectCSSVariables, isBrowser, loadColors, loadMode, saveColors, saveMode, useTheme, useThemeContext, watchSystemMode };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
type ThemeMode = "light" | "dark" | "system";
|
|
5
|
+
type ThemeName = "default" | "ocean" | "forest" | "sunset" | "rose" | (string & {});
|
|
6
|
+
interface ThemeColors {
|
|
7
|
+
primary?: string;
|
|
8
|
+
background?: string;
|
|
9
|
+
surface?: string;
|
|
10
|
+
text?: string;
|
|
11
|
+
border?: string;
|
|
12
|
+
accent?: string;
|
|
13
|
+
}
|
|
14
|
+
interface ThemeConfig {
|
|
15
|
+
mode?: ThemeMode;
|
|
16
|
+
colors?: ThemeColors;
|
|
17
|
+
transitions?: boolean;
|
|
18
|
+
}
|
|
19
|
+
interface ThemeState {
|
|
20
|
+
mode: ThemeMode;
|
|
21
|
+
resolvedMode: "light" | "dark";
|
|
22
|
+
colors: ThemeColors;
|
|
23
|
+
theme: ThemeName;
|
|
24
|
+
toggle: () => void;
|
|
25
|
+
setMode: (mode: ThemeMode) => void;
|
|
26
|
+
setColors: (colors: ThemeColors) => void;
|
|
27
|
+
setTheme: (theme: ThemeName) => void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare function injectCSSVariables(colors: ThemeColors, mode: "light" | "dark"): void;
|
|
31
|
+
declare function getDefaultColors(mode: "light" | "dark"): ThemeColors;
|
|
32
|
+
|
|
33
|
+
declare function saveMode(mode: ThemeMode): void;
|
|
34
|
+
declare function loadMode(): ThemeMode | null;
|
|
35
|
+
declare function saveColors(colors: ThemeColors): void;
|
|
36
|
+
declare function loadColors(): ThemeColors | null;
|
|
37
|
+
declare function clearStorage(): void;
|
|
38
|
+
|
|
39
|
+
type SystemMode = "light" | "dark";
|
|
40
|
+
type SystemModeListener = (mode: SystemMode) => void;
|
|
41
|
+
declare function getSystemMode(): SystemMode;
|
|
42
|
+
declare function watchSystemMode(callback: SystemModeListener): () => void;
|
|
43
|
+
declare function isBrowser(): boolean;
|
|
44
|
+
|
|
45
|
+
interface ThemeToggleProps {
|
|
46
|
+
size?: number;
|
|
47
|
+
}
|
|
48
|
+
declare function ThemeToggle({ size }: ThemeToggleProps): react_jsx_runtime.JSX.Element;
|
|
49
|
+
|
|
50
|
+
interface ThemePreset {
|
|
51
|
+
name: string;
|
|
52
|
+
light: ThemeColors;
|
|
53
|
+
dark: ThemeColors;
|
|
54
|
+
}
|
|
55
|
+
declare const BUILT_IN_THEMES: Record<string, ThemePreset>;
|
|
56
|
+
declare function getTheme(name: string): ThemePreset;
|
|
57
|
+
|
|
58
|
+
declare function useTheme(initial?: ThemeMode, initialTheme?: ThemeName): ThemeState;
|
|
59
|
+
|
|
60
|
+
interface ThemeProviderProps {
|
|
61
|
+
children: ReactNode;
|
|
62
|
+
mode?: ThemeMode;
|
|
63
|
+
theme?: ThemeName;
|
|
64
|
+
colors?: ThemeColors;
|
|
65
|
+
transitions?: boolean;
|
|
66
|
+
}
|
|
67
|
+
declare function ThemeProvider({ children, mode, theme, colors, transitions, }: ThemeProviderProps): react_jsx_runtime.JSX.Element;
|
|
68
|
+
declare function useThemeContext(): ThemeState;
|
|
69
|
+
|
|
70
|
+
export { BUILT_IN_THEMES, type ThemeColors, type ThemeConfig, type ThemeMode, type ThemeName, ThemeProvider, type ThemeState, ThemeToggle, clearStorage, getDefaultColors, getSystemMode, getTheme, injectCSSVariables, isBrowser, loadColors, loadMode, saveColors, saveMode, useTheme, useThemeContext, watchSystemMode };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';var react=require('react'),jsxRuntime=require('react/jsx-runtime');var M={primary:"#7C3AED",background:"#FFFFFF",surface:"#F8FAFC",text:"#0F172A",border:"#E2E8F0",accent:"#06B6D4"},B={primary:"#A78BFA",background:"#0F172A",surface:"#1E293B",text:"#F8FAFC",border:"#334155",accent:"#22D3EE"};function u(e,r){let o=document.documentElement,t={...r==="dark"?B:M,...e};o.setAttribute("data-theme",r),Object.entries(t).forEach(([s,i])=>{o.style.setProperty(`--vt-${s}`,i);});}function I(){let e=document.createElement("style");e.id="vartheme-transitions",e.textContent=`
|
|
2
|
+
*, *::before, *::after {
|
|
3
|
+
transition:
|
|
4
|
+
background-color 0.3s ease,
|
|
5
|
+
color 0.3s ease,
|
|
6
|
+
border-color 0.3s ease !important;
|
|
7
|
+
}
|
|
8
|
+
`,document.head.appendChild(e);}function T(e){return e==="dark"?B:M}var y="vartheme-mode",C="vartheme-colors";function f(e){try{localStorage.setItem(y,e);}catch(r){console.warn("vartheme: localStorage not available");}}function b(){try{let e=localStorage.getItem(y);return e==="light"||e==="dark"||e==="system"?e:null}catch(e){return null}}function x(e){try{localStorage.setItem(C,JSON.stringify(e));}catch(r){console.warn("vartheme: localStorage not available");}}function v(){try{let e=localStorage.getItem(C);return e?JSON.parse(e):null}catch(e){return null}}function $(){try{localStorage.removeItem(y),localStorage.removeItem(C);}catch(e){console.warn("vartheme: localStorage not available");}}function c(){return typeof window=="undefined"?"light":window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function E(e){if(typeof window=="undefined")return ()=>{};let r=window.matchMedia("(prefers-color-scheme: dark)"),o=a=>{e(a.matches?"dark":"light");};return r.addEventListener("change",o),()=>{r.removeEventListener("change",o);}}function j(){return typeof window!="undefined"}var k={default:{name:"default",light:{primary:"#7C3AED",background:"#FFFFFF",surface:"#F8FAFC",text:"#0F172A",border:"#E2E8F0",accent:"#06B6D4"},dark:{primary:"#A78BFA",background:"#0F172A",surface:"#1E293B",text:"#F8FAFC",border:"#334155",accent:"#22D3EE"}},ocean:{name:"ocean",light:{primary:"#0284C7",background:"#F0F9FF",surface:"#E0F2FE",text:"#0C4A6E",border:"#BAE6FD",accent:"#0D9488"},dark:{primary:"#38BDF8",background:"#0C1A2E",surface:"#0F2744",text:"#E0F2FE",border:"#1E3A5F",accent:"#2DD4BF"}},forest:{name:"forest",light:{primary:"#16A34A",background:"#F0FDF4",surface:"#DCFCE7",text:"#14532D",border:"#BBF7D0",accent:"#84CC16"},dark:{primary:"#4ADE80",background:"#0A1F0F",surface:"#0F2D17",text:"#DCFCE7",border:"#166534",accent:"#A3E635"}},sunset:{name:"sunset",light:{primary:"#EA580C",background:"#FFF7ED",surface:"#FFEDD5",text:"#431407",border:"#FED7AA",accent:"#DB2777"},dark:{primary:"#FB923C",background:"#1A0A00",surface:"#2D1200",text:"#FFEDD5",border:"#7C2D12",accent:"#F472B6"}},rose:{name:"rose",light:{primary:"#E11D48",background:"#FFF1F2",surface:"#FFE4E6",text:"#4C0519",border:"#FECDD3",accent:"#BE185D"},dark:{primary:"#FB7185",background:"#1A0008",surface:"#2D000F",text:"#FFE4E6",border:"#881337",accent:"#F472B6"}}};function p(e){return k[e]||k.default}function S(e,r){let[o,a]=react.useState(()=>b()||e||"system"),[t,s]=react.useState(r||"default"),[i,R]=react.useState(()=>v()||{}),m=o==="system"?c():o;react.useEffect(()=>{let n=p(t),d=m==="dark"?n.dark:n.light;u({...d,...i},m);},[m,i,t]),react.useEffect(()=>o!=="system"?void 0:E(()=>{let d=p(t),h=c()==="dark"?d.dark:d.light;u({...h,...i},c());}),[o,i,t]);let L=react.useCallback(()=>{let n=m==="light"?"dark":"light";a(n),f(n);},[m]),_=react.useCallback(n=>{a(n),f(n);},[]),O=react.useCallback(n=>{R(d=>{let h={...d,...n};return x(h),h});},[]),U=react.useCallback(n=>{s(n);},[]);return {mode:o,resolvedMode:m,theme:t,colors:{...T(m),...i},toggle:L,setMode:_,setColors:O,setTheme:U}}var N=react.createContext(null);function K({children:e,mode:r,theme:o="default",colors:a,transitions:t}){let s=S(r,o);return t&&I(),a&&s.setColors(a),jsxRuntime.jsx(N.Provider,{value:s,children:e})}function A(){let e=react.useContext(N);if(!e)throw new Error("useThemeContext must be used inside <ThemeProvider />");return e}function Y({size:e=48}){let{resolvedMode:r,toggle:o}=A(),a=r==="dark";return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("style",{children:`
|
|
9
|
+
@keyframes vt-spin {
|
|
10
|
+
from { transform: rotate(0deg); }
|
|
11
|
+
to { transform: rotate(360deg); }
|
|
12
|
+
}
|
|
13
|
+
@keyframes vt-twinkle {
|
|
14
|
+
0% { opacity: 0.2; transform: scale(0.6); }
|
|
15
|
+
100% { opacity: 1; transform: scale(1.2); }
|
|
16
|
+
}
|
|
17
|
+
@keyframes vt-glow-sun {
|
|
18
|
+
0% { box-shadow: 0 0 10px 2px #FCD34D66; }
|
|
19
|
+
100% { box-shadow: 0 0 22px 6px #FCD34DAA; }
|
|
20
|
+
}
|
|
21
|
+
@keyframes vt-glow-moon {
|
|
22
|
+
0% { box-shadow: 0 0 10px 2px #A78BFA55; }
|
|
23
|
+
100% { box-shadow: 0 0 22px 6px #A78BFA99; }
|
|
24
|
+
}
|
|
25
|
+
`}),jsxRuntime.jsxs("button",{onClick:o,"aria-label":"Toggle theme",style:{width:e,height:e,borderRadius:"50%",border:"none",cursor:"pointer",position:"relative",background:a?"radial-gradient(circle, #1E293B, #0F172A)":"radial-gradient(circle, #FEF3C7, #FDE68A)",animation:a?"vt-glow-moon 2s infinite alternate":"vt-glow-sun 2s infinite alternate",transition:"background 0.5s ease",display:"flex",alignItems:"center",justifyContent:"center",overflow:"visible"},children:[!a&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{style:{width:e*.38,height:e*.38,borderRadius:"50%",background:"#F59E0B",boxShadow:"0 0 8px #FCD34D",zIndex:2}}),[0,45,90,135,180,225,270,315].map((t,s)=>jsxRuntime.jsx("div",{style:{position:"absolute",width:3,height:e*.18,borderRadius:4,background:"#FCD34D",top:"50%",left:"50%",transformOrigin:"50% 0%",transform:`translateX(-50%) rotate(${t}deg) translateY(-${e*.54}px)`,animation:"vt-spin 8s linear infinite",animationDelay:`${s*.05}s`,opacity:.9}},s))]}),a&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{style:{width:e*.45,height:e*.45,borderRadius:"50%",background:"#E2E8F0",boxShadow:"0 0 8px #A78BFA",position:"relative",zIndex:2,overflow:"hidden"},children:jsxRuntime.jsx("div",{style:{position:"absolute",width:e*.38,height:e*.38,borderRadius:"50%",background:"#0F172A",top:-e*.08,right:-e*.08}})}),[{top:-6,right:-4,s:4,delay:"0s"},{top:4,right:-10,s:3,delay:"0.5s"},{bottom:2,right:-8,s:2,delay:"1s"},{top:-4,left:2,s:2,delay:"1.5s"}].map((t,s)=>jsxRuntime.jsx("div",{style:{position:"absolute",width:t.s,height:t.s,borderRadius:"50%",background:"#E2E8F0",top:t.top,right:t.right,left:t.left,bottom:t.bottom,animation:"vt-twinkle 1.5s infinite alternate",animationDelay:t.delay}},s))]})]})]})}exports.BUILT_IN_THEMES=k;exports.ThemeProvider=K;exports.ThemeToggle=Y;exports.clearStorage=$;exports.getDefaultColors=T;exports.getSystemMode=c;exports.getTheme=p;exports.injectCSSVariables=u;exports.isBrowser=j;exports.loadColors=v;exports.loadMode=b;exports.saveColors=x;exports.saveMode=f;exports.useTheme=S;exports.useThemeContext=A;exports.watchSystemMode=E;//# sourceMappingURL=index.js.map
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/engine.ts","../src/core/storage.ts","../src/core/system.ts","../src/core/themes.ts","../src/react/useTheme.ts","../src/react/ThemeProvider.tsx","../src/react/ThemeToggle.tsx"],"names":["DEFAULT_LIGHT","DEFAULT_DARK","injectCSSVariables","colors","mode","root","merged","key","value","applyTransitions","style","getDefaultColors","STORAGE_KEY_MODE","STORAGE_KEY_COLORS","saveMode","e","loadMode","saved","saveColors","loadColors","clearStorage","getSystemMode","watchSystemMode","callback","mediaQuery","handler","isBrowser","BUILT_IN_THEMES","getTheme","name","useTheme","initial","initialTheme","setModeState","useState","theme","setThemeState","setColorsState","resolvedMode","useEffect","preset","presetColors","toggle","useCallback","next","setMode","newMode","setColors","newColors","prev","setTheme","newTheme","ThemeContext","createContext","ThemeProvider","children","transitions","themeState","jsx","useThemeContext","context","useContext","ThemeToggle","size","isDark","jsxs","Fragment","deg","i","star"],"mappings":"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","file":"index.js","sourcesContent":["import { ThemeColors, ThemeMode } from \"../types\";\n\nconst DEFAULT_LIGHT: ThemeColors = {\n primary: \"#7C3AED\",\n background: \"#FFFFFF\",\n surface: \"#F8FAFC\",\n text: \"#0F172A\",\n border: \"#E2E8F0\",\n accent: \"#06B6D4\",\n};\n\nconst DEFAULT_DARK: ThemeColors = {\n primary: \"#A78BFA\",\n background: \"#0F172A\",\n surface: \"#1E293B\",\n text: \"#F8FAFC\",\n border: \"#334155\",\n accent: \"#22D3EE\",\n};\n\nexport function injectCSSVariables(\n colors: ThemeColors,\n mode: \"light\" | \"dark\"\n): void {\n const root = document.documentElement;\n const defaults = mode === \"dark\" ? DEFAULT_DARK : DEFAULT_LIGHT;\n const merged = { ...defaults, ...colors };\n\n root.setAttribute(\"data-theme\", mode);\n\n Object.entries(merged).forEach(([key, value]) => {\n root.style.setProperty(`--vt-${key}`, value as string);\n });\n}\n\nexport function applyTransitions(): void {\n const style = document.createElement(\"style\");\n style.id = \"vartheme-transitions\";\n style.textContent = `\n *, *::before, *::after {\n transition: \n background-color 0.3s ease,\n color 0.3s ease,\n border-color 0.3s ease !important;\n }\n `;\n document.head.appendChild(style);\n}\n\nexport function removeTransitions(): void {\n const style = document.getElementById(\"vartheme-transitions\");\n if (style) style.remove();\n}\n\nexport function getDefaultColors(mode: \"light\" | \"dark\"): ThemeColors {\n return mode === \"dark\" ? DEFAULT_DARK : DEFAULT_LIGHT;\n}","import { ThemeMode, ThemeColors } from \"../types\";\n\nconst STORAGE_KEY_MODE = \"vartheme-mode\";\nconst STORAGE_KEY_COLORS = \"vartheme-colors\";\n\nexport function saveMode(mode: ThemeMode): void {\n try {\n localStorage.setItem(STORAGE_KEY_MODE, mode);\n } catch {\n console.warn(\"vartheme: localStorage not available\");\n }\n}\n\nexport function loadMode(): ThemeMode | null {\n try {\n const saved = localStorage.getItem(STORAGE_KEY_MODE);\n if (saved === \"light\" || saved === \"dark\" || saved === \"system\") {\n return saved;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport function saveColors(colors: ThemeColors): void {\n try {\n localStorage.setItem(STORAGE_KEY_COLORS, JSON.stringify(colors));\n } catch {\n console.warn(\"vartheme: localStorage not available\");\n }\n}\n\nexport function loadColors(): ThemeColors | null {\n try {\n const saved = localStorage.getItem(STORAGE_KEY_COLORS);\n if (saved) return JSON.parse(saved) as ThemeColors;\n return null;\n } catch {\n return null;\n }\n}\n\nexport function clearStorage(): void {\n try {\n localStorage.removeItem(STORAGE_KEY_MODE);\n localStorage.removeItem(STORAGE_KEY_COLORS);\n } catch {\n console.warn(\"vartheme: localStorage not available\");\n }\n}","type SystemMode = \"light\" | \"dark\";\ntype SystemModeListener = (mode: SystemMode) => void;\n\nexport function getSystemMode(): SystemMode {\n if (typeof window === \"undefined\") return \"light\";\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n ? \"dark\"\n : \"light\";\n}\n\nexport function watchSystemMode(callback: SystemModeListener): () => void {\n if (typeof window === \"undefined\") return () => {};\n\n const mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\n const handler = (e: MediaQueryListEvent) => {\n callback(e.matches ? \"dark\" : \"light\");\n };\n\n mediaQuery.addEventListener(\"change\", handler);\n\n // cleanup function return ho raha hai\n return () => {\n mediaQuery.removeEventListener(\"change\", handler);\n };\n}\n\nexport function isBrowser(): boolean {\n return typeof window !== \"undefined\";\n}","import { ThemeColors } from \"../types\";\n\nexport interface ThemePreset {\n name: string;\n light: ThemeColors;\n dark: ThemeColors;\n}\n\nexport const BUILT_IN_THEMES: Record<string, ThemePreset> = {\n default: {\n name: \"default\",\n light: {\n primary: \"#7C3AED\",\n background: \"#FFFFFF\",\n surface: \"#F8FAFC\",\n text: \"#0F172A\",\n border: \"#E2E8F0\",\n accent: \"#06B6D4\",\n },\n dark: {\n primary: \"#A78BFA\",\n background: \"#0F172A\",\n surface: \"#1E293B\",\n text: \"#F8FAFC\",\n border: \"#334155\",\n accent: \"#22D3EE\",\n },\n },\n\n ocean: {\n name: \"ocean\",\n light: {\n primary: \"#0284C7\",\n background: \"#F0F9FF\",\n surface: \"#E0F2FE\",\n text: \"#0C4A6E\",\n border: \"#BAE6FD\",\n accent: \"#0D9488\",\n },\n dark: {\n primary: \"#38BDF8\",\n background: \"#0C1A2E\",\n surface: \"#0F2744\",\n text: \"#E0F2FE\",\n border: \"#1E3A5F\",\n accent: \"#2DD4BF\",\n },\n },\n\n forest: {\n name: \"forest\",\n light: {\n primary: \"#16A34A\",\n background: \"#F0FDF4\",\n surface: \"#DCFCE7\",\n text: \"#14532D\",\n border: \"#BBF7D0\",\n accent: \"#84CC16\",\n },\n dark: {\n primary: \"#4ADE80\",\n background: \"#0A1F0F\",\n surface: \"#0F2D17\",\n text: \"#DCFCE7\",\n border: \"#166534\",\n accent: \"#A3E635\",\n },\n },\n\n sunset: {\n name: \"sunset\",\n light: {\n primary: \"#EA580C\",\n background: \"#FFF7ED\",\n surface: \"#FFEDD5\",\n text: \"#431407\",\n border: \"#FED7AA\",\n accent: \"#DB2777\",\n },\n dark: {\n primary: \"#FB923C\",\n background: \"#1A0A00\",\n surface: \"#2D1200\",\n text: \"#FFEDD5\",\n border: \"#7C2D12\",\n accent: \"#F472B6\",\n },\n },\n\n rose: {\n name: \"rose\",\n light: {\n primary: \"#E11D48\",\n background: \"#FFF1F2\",\n surface: \"#FFE4E6\",\n text: \"#4C0519\",\n border: \"#FECDD3\",\n accent: \"#BE185D\",\n },\n dark: {\n primary: \"#FB7185\",\n background: \"#1A0008\",\n surface: \"#2D000F\",\n text: \"#FFE4E6\",\n border: \"#881337\",\n accent: \"#F472B6\",\n },\n },\n};\n\nexport function getTheme(name: string): ThemePreset {\n return BUILT_IN_THEMES[name] || BUILT_IN_THEMES.default;\n}","import { useState, useEffect, useCallback } from \"react\";\nimport { ThemeMode, ThemeColors, ThemeState, ThemeName } from \"../types\";\nimport { injectCSSVariables, getDefaultColors } from \"../core/engine\";\nimport { saveMode, loadMode, saveColors, loadColors } from \"../core/storage\";\nimport { getSystemMode, watchSystemMode } from \"../core/system\";\nimport { getTheme } from \"../core/themes\";\n\nexport function useTheme(\n initial?: ThemeMode,\n initialTheme?: ThemeName\n): ThemeState {\n const [mode, setModeState] = useState<ThemeMode>(() => {\n return loadMode() || initial || \"system\";\n });\n\n const [theme, setThemeState] = useState<ThemeName>(\n initialTheme || \"default\"\n );\n\n const [colors, setColorsState] = useState<ThemeColors>(() => {\n return loadColors() || {};\n });\n\n const resolvedMode = mode === \"system\" ? getSystemMode() : mode;\n\n useEffect(() => {\n const preset = getTheme(theme);\n const presetColors = resolvedMode === \"dark\" ? preset.dark : preset.light;\n injectCSSVariables({ ...presetColors, ...colors }, resolvedMode);\n }, [resolvedMode, colors, theme]);\n\n useEffect(() => {\n if (mode !== \"system\") return;\n const cleanup = watchSystemMode(() => {\n const preset = getTheme(theme);\n const presetColors =\n getSystemMode() === \"dark\" ? preset.dark : preset.light;\n injectCSSVariables({ ...presetColors, ...colors }, getSystemMode());\n });\n return cleanup;\n }, [mode, colors, theme]);\n\n const toggle = useCallback(() => {\n const next = resolvedMode === \"light\" ? \"dark\" : \"light\";\n setModeState(next);\n saveMode(next);\n }, [resolvedMode]);\n\n const setMode = useCallback((newMode: ThemeMode) => {\n setModeState(newMode);\n saveMode(newMode);\n }, []);\n\n const setColors = useCallback((newColors: ThemeColors) => {\n setColorsState((prev) => {\n const merged = { ...prev, ...newColors };\n saveColors(merged);\n return merged;\n });\n }, []);\n\n const setTheme = useCallback((newTheme: ThemeName) => {\n setThemeState(newTheme);\n }, []);\n\n return {\n mode,\n resolvedMode,\n theme,\n colors: { ...getDefaultColors(resolvedMode), ...colors },\n toggle,\n setMode,\n setColors,\n setTheme,\n };\n}","import { createContext, useContext, ReactNode } from \"react\";\nimport { ThemeState, ThemeMode, ThemeColors, ThemeName } from \"../types\";\nimport { useTheme } from \"./useTheme\";\nimport { applyTransitions } from \"../core/engine\";\n\nconst ThemeContext = createContext<ThemeState | null>(null);\n\ninterface ThemeProviderProps {\n children: ReactNode;\n mode?: ThemeMode;\n theme?: ThemeName;\n colors?: ThemeColors;\n transitions?: boolean;\n}\n\nexport function ThemeProvider({\n children,\n mode,\n theme = \"default\",\n colors,\n transitions,\n}: ThemeProviderProps) {\n const themeState = useTheme(mode, theme);\n\n if (transitions) {\n applyTransitions();\n }\n\n if (colors) {\n themeState.setColors(colors);\n }\n\n return (\n <ThemeContext.Provider value={themeState}>\n {children}\n </ThemeContext.Provider>\n );\n}\n\nexport function useThemeContext(): ThemeState {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error(\n \"useThemeContext must be used inside <ThemeProvider />\"\n );\n }\n return context;\n}","import { useThemeContext } from \"./ThemeProvider\";\n\ninterface ThemeToggleProps {\n size?: number;\n}\n\nexport function ThemeToggle({ size = 48 }: ThemeToggleProps) {\n const { resolvedMode, toggle } = useThemeContext();\n const isDark = resolvedMode === \"dark\";\n\n return (\n <>\n <style>{`\n @keyframes vt-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n @keyframes vt-twinkle {\n 0% { opacity: 0.2; transform: scale(0.6); }\n 100% { opacity: 1; transform: scale(1.2); }\n }\n @keyframes vt-glow-sun {\n 0% { box-shadow: 0 0 10px 2px #FCD34D66; }\n 100% { box-shadow: 0 0 22px 6px #FCD34DAA; }\n }\n @keyframes vt-glow-moon {\n 0% { box-shadow: 0 0 10px 2px #A78BFA55; }\n 100% { box-shadow: 0 0 22px 6px #A78BFA99; }\n }\n `}</style>\n\n <button\n onClick={toggle}\n aria-label=\"Toggle theme\"\n style={{\n width: size,\n height: size,\n borderRadius: \"50%\",\n border: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n background: isDark\n ? \"radial-gradient(circle, #1E293B, #0F172A)\"\n : \"radial-gradient(circle, #FEF3C7, #FDE68A)\",\n animation: isDark ? \"vt-glow-moon 2s infinite alternate\" : \"vt-glow-sun 2s infinite alternate\",\n transition: \"background 0.5s ease\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n overflow: \"visible\",\n }}\n >\n {/* Sun Mode */}\n {!isDark && (\n <>\n {/* Center circle */}\n <div style={{\n width: size * 0.38,\n height: size * 0.38,\n borderRadius: \"50%\",\n background: \"#F59E0B\",\n boxShadow: \"0 0 8px #FCD34D\",\n zIndex: 2,\n }} />\n\n {/* Rays */}\n {[0,45,90,135,180,225,270,315].map((deg, i) => (\n <div key={i} style={{\n position: \"absolute\",\n width: 3,\n height: size * 0.18,\n borderRadius: 4,\n background: \"#FCD34D\",\n top: \"50%\",\n left: \"50%\",\n transformOrigin: \"50% 0%\",\n transform: `translateX(-50%) rotate(${deg}deg) translateY(-${size * 0.54}px)`,\n animation: \"vt-spin 8s linear infinite\",\n animationDelay: `${i * 0.05}s`,\n opacity: 0.9,\n }} />\n ))}\n </>\n )}\n\n {/* Moon Mode */}\n {isDark && (\n <>\n {/* Crescent using two circles */}\n <div style={{\n width: size * 0.45,\n height: size * 0.45,\n borderRadius: \"50%\",\n background: \"#E2E8F0\",\n boxShadow: \"0 0 8px #A78BFA\",\n position: \"relative\",\n zIndex: 2,\n overflow: \"hidden\",\n }}>\n {/* Inner circle to create crescent */}\n <div style={{\n position: \"absolute\",\n width: size * 0.38,\n height: size * 0.38,\n borderRadius: \"50%\",\n background: \"#0F172A\",\n top: -size * 0.08,\n right: -size * 0.08,\n }} />\n </div>\n\n {/* Stars */}\n {[\n { top: -6, right: -4, s: 4, delay: \"0s\" },\n { top: 4, right: -10, s: 3, delay: \"0.5s\" },\n { bottom: 2, right: -8, s: 2, delay: \"1s\" },\n { top: -4, left: 2, s: 2, delay: \"1.5s\" },\n ].map((star, i) => (\n <div key={i} style={{\n position: \"absolute\",\n width: star.s,\n height: star.s,\n borderRadius: \"50%\",\n background: \"#E2E8F0\",\n top: star.top,\n right: (star as any).right,\n left: (star as any).left,\n bottom: (star as any).bottom,\n animation: `vt-twinkle 1.5s infinite alternate`,\n animationDelay: star.delay,\n }} />\n ))}\n </>\n )}\n </button>\n </>\n );\n}"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {createContext,useState,useEffect,useCallback,useContext}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var M={primary:"#7C3AED",background:"#FFFFFF",surface:"#F8FAFC",text:"#0F172A",border:"#E2E8F0",accent:"#06B6D4"},B={primary:"#A78BFA",background:"#0F172A",surface:"#1E293B",text:"#F8FAFC",border:"#334155",accent:"#22D3EE"};function u(e,r){let o=document.documentElement,t={...r==="dark"?B:M,...e};o.setAttribute("data-theme",r),Object.entries(t).forEach(([s,i])=>{o.style.setProperty(`--vt-${s}`,i);});}function I(){let e=document.createElement("style");e.id="vartheme-transitions",e.textContent=`
|
|
2
|
+
*, *::before, *::after {
|
|
3
|
+
transition:
|
|
4
|
+
background-color 0.3s ease,
|
|
5
|
+
color 0.3s ease,
|
|
6
|
+
border-color 0.3s ease !important;
|
|
7
|
+
}
|
|
8
|
+
`,document.head.appendChild(e);}function T(e){return e==="dark"?B:M}var y="vartheme-mode",C="vartheme-colors";function f(e){try{localStorage.setItem(y,e);}catch(r){console.warn("vartheme: localStorage not available");}}function b(){try{let e=localStorage.getItem(y);return e==="light"||e==="dark"||e==="system"?e:null}catch(e){return null}}function x(e){try{localStorage.setItem(C,JSON.stringify(e));}catch(r){console.warn("vartheme: localStorage not available");}}function v(){try{let e=localStorage.getItem(C);return e?JSON.parse(e):null}catch(e){return null}}function $(){try{localStorage.removeItem(y),localStorage.removeItem(C);}catch(e){console.warn("vartheme: localStorage not available");}}function c(){return typeof window=="undefined"?"light":window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function E(e){if(typeof window=="undefined")return ()=>{};let r=window.matchMedia("(prefers-color-scheme: dark)"),o=a=>{e(a.matches?"dark":"light");};return r.addEventListener("change",o),()=>{r.removeEventListener("change",o);}}function j(){return typeof window!="undefined"}var k={default:{name:"default",light:{primary:"#7C3AED",background:"#FFFFFF",surface:"#F8FAFC",text:"#0F172A",border:"#E2E8F0",accent:"#06B6D4"},dark:{primary:"#A78BFA",background:"#0F172A",surface:"#1E293B",text:"#F8FAFC",border:"#334155",accent:"#22D3EE"}},ocean:{name:"ocean",light:{primary:"#0284C7",background:"#F0F9FF",surface:"#E0F2FE",text:"#0C4A6E",border:"#BAE6FD",accent:"#0D9488"},dark:{primary:"#38BDF8",background:"#0C1A2E",surface:"#0F2744",text:"#E0F2FE",border:"#1E3A5F",accent:"#2DD4BF"}},forest:{name:"forest",light:{primary:"#16A34A",background:"#F0FDF4",surface:"#DCFCE7",text:"#14532D",border:"#BBF7D0",accent:"#84CC16"},dark:{primary:"#4ADE80",background:"#0A1F0F",surface:"#0F2D17",text:"#DCFCE7",border:"#166534",accent:"#A3E635"}},sunset:{name:"sunset",light:{primary:"#EA580C",background:"#FFF7ED",surface:"#FFEDD5",text:"#431407",border:"#FED7AA",accent:"#DB2777"},dark:{primary:"#FB923C",background:"#1A0A00",surface:"#2D1200",text:"#FFEDD5",border:"#7C2D12",accent:"#F472B6"}},rose:{name:"rose",light:{primary:"#E11D48",background:"#FFF1F2",surface:"#FFE4E6",text:"#4C0519",border:"#FECDD3",accent:"#BE185D"},dark:{primary:"#FB7185",background:"#1A0008",surface:"#2D000F",text:"#FFE4E6",border:"#881337",accent:"#F472B6"}}};function p(e){return k[e]||k.default}function S(e,r){let[o,a]=useState(()=>b()||e||"system"),[t,s]=useState(r||"default"),[i,R]=useState(()=>v()||{}),m=o==="system"?c():o;useEffect(()=>{let n=p(t),d=m==="dark"?n.dark:n.light;u({...d,...i},m);},[m,i,t]),useEffect(()=>o!=="system"?void 0:E(()=>{let d=p(t),h=c()==="dark"?d.dark:d.light;u({...h,...i},c());}),[o,i,t]);let L=useCallback(()=>{let n=m==="light"?"dark":"light";a(n),f(n);},[m]),_=useCallback(n=>{a(n),f(n);},[]),O=useCallback(n=>{R(d=>{let h={...d,...n};return x(h),h});},[]),U=useCallback(n=>{s(n);},[]);return {mode:o,resolvedMode:m,theme:t,colors:{...T(m),...i},toggle:L,setMode:_,setColors:O,setTheme:U}}var N=createContext(null);function K({children:e,mode:r,theme:o="default",colors:a,transitions:t}){let s=S(r,o);return t&&I(),a&&s.setColors(a),jsx(N.Provider,{value:s,children:e})}function A(){let e=useContext(N);if(!e)throw new Error("useThemeContext must be used inside <ThemeProvider />");return e}function Y({size:e=48}){let{resolvedMode:r,toggle:o}=A(),a=r==="dark";return jsxs(Fragment,{children:[jsx("style",{children:`
|
|
9
|
+
@keyframes vt-spin {
|
|
10
|
+
from { transform: rotate(0deg); }
|
|
11
|
+
to { transform: rotate(360deg); }
|
|
12
|
+
}
|
|
13
|
+
@keyframes vt-twinkle {
|
|
14
|
+
0% { opacity: 0.2; transform: scale(0.6); }
|
|
15
|
+
100% { opacity: 1; transform: scale(1.2); }
|
|
16
|
+
}
|
|
17
|
+
@keyframes vt-glow-sun {
|
|
18
|
+
0% { box-shadow: 0 0 10px 2px #FCD34D66; }
|
|
19
|
+
100% { box-shadow: 0 0 22px 6px #FCD34DAA; }
|
|
20
|
+
}
|
|
21
|
+
@keyframes vt-glow-moon {
|
|
22
|
+
0% { box-shadow: 0 0 10px 2px #A78BFA55; }
|
|
23
|
+
100% { box-shadow: 0 0 22px 6px #A78BFA99; }
|
|
24
|
+
}
|
|
25
|
+
`}),jsxs("button",{onClick:o,"aria-label":"Toggle theme",style:{width:e,height:e,borderRadius:"50%",border:"none",cursor:"pointer",position:"relative",background:a?"radial-gradient(circle, #1E293B, #0F172A)":"radial-gradient(circle, #FEF3C7, #FDE68A)",animation:a?"vt-glow-moon 2s infinite alternate":"vt-glow-sun 2s infinite alternate",transition:"background 0.5s ease",display:"flex",alignItems:"center",justifyContent:"center",overflow:"visible"},children:[!a&&jsxs(Fragment,{children:[jsx("div",{style:{width:e*.38,height:e*.38,borderRadius:"50%",background:"#F59E0B",boxShadow:"0 0 8px #FCD34D",zIndex:2}}),[0,45,90,135,180,225,270,315].map((t,s)=>jsx("div",{style:{position:"absolute",width:3,height:e*.18,borderRadius:4,background:"#FCD34D",top:"50%",left:"50%",transformOrigin:"50% 0%",transform:`translateX(-50%) rotate(${t}deg) translateY(-${e*.54}px)`,animation:"vt-spin 8s linear infinite",animationDelay:`${s*.05}s`,opacity:.9}},s))]}),a&&jsxs(Fragment,{children:[jsx("div",{style:{width:e*.45,height:e*.45,borderRadius:"50%",background:"#E2E8F0",boxShadow:"0 0 8px #A78BFA",position:"relative",zIndex:2,overflow:"hidden"},children:jsx("div",{style:{position:"absolute",width:e*.38,height:e*.38,borderRadius:"50%",background:"#0F172A",top:-e*.08,right:-e*.08}})}),[{top:-6,right:-4,s:4,delay:"0s"},{top:4,right:-10,s:3,delay:"0.5s"},{bottom:2,right:-8,s:2,delay:"1s"},{top:-4,left:2,s:2,delay:"1.5s"}].map((t,s)=>jsx("div",{style:{position:"absolute",width:t.s,height:t.s,borderRadius:"50%",background:"#E2E8F0",top:t.top,right:t.right,left:t.left,bottom:t.bottom,animation:"vt-twinkle 1.5s infinite alternate",animationDelay:t.delay}},s))]})]})]})}export{k as BUILT_IN_THEMES,K as ThemeProvider,Y as ThemeToggle,$ as clearStorage,T as getDefaultColors,c as getSystemMode,p as getTheme,u as injectCSSVariables,j as isBrowser,v as loadColors,b as loadMode,x as saveColors,f as saveMode,S as useTheme,A as useThemeContext,E as watchSystemMode};//# sourceMappingURL=index.mjs.map
|
|
26
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/engine.ts","../src/core/storage.ts","../src/core/system.ts","../src/core/themes.ts","../src/react/useTheme.ts","../src/react/ThemeProvider.tsx","../src/react/ThemeToggle.tsx"],"names":["DEFAULT_LIGHT","DEFAULT_DARK","injectCSSVariables","colors","mode","root","merged","key","value","applyTransitions","style","getDefaultColors","STORAGE_KEY_MODE","STORAGE_KEY_COLORS","saveMode","e","loadMode","saved","saveColors","loadColors","clearStorage","getSystemMode","watchSystemMode","callback","mediaQuery","handler","isBrowser","BUILT_IN_THEMES","getTheme","name","useTheme","initial","initialTheme","setModeState","useState","theme","setThemeState","setColorsState","resolvedMode","useEffect","preset","presetColors","toggle","useCallback","next","setMode","newMode","setColors","newColors","prev","setTheme","newTheme","ThemeContext","createContext","ThemeProvider","children","transitions","themeState","jsx","useThemeContext","context","useContext","ThemeToggle","size","isDark","jsxs","Fragment","deg","i","star"],"mappings":"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","file":"index.mjs","sourcesContent":["import { ThemeColors, ThemeMode } from \"../types\";\n\nconst DEFAULT_LIGHT: ThemeColors = {\n primary: \"#7C3AED\",\n background: \"#FFFFFF\",\n surface: \"#F8FAFC\",\n text: \"#0F172A\",\n border: \"#E2E8F0\",\n accent: \"#06B6D4\",\n};\n\nconst DEFAULT_DARK: ThemeColors = {\n primary: \"#A78BFA\",\n background: \"#0F172A\",\n surface: \"#1E293B\",\n text: \"#F8FAFC\",\n border: \"#334155\",\n accent: \"#22D3EE\",\n};\n\nexport function injectCSSVariables(\n colors: ThemeColors,\n mode: \"light\" | \"dark\"\n): void {\n const root = document.documentElement;\n const defaults = mode === \"dark\" ? DEFAULT_DARK : DEFAULT_LIGHT;\n const merged = { ...defaults, ...colors };\n\n root.setAttribute(\"data-theme\", mode);\n\n Object.entries(merged).forEach(([key, value]) => {\n root.style.setProperty(`--vt-${key}`, value as string);\n });\n}\n\nexport function applyTransitions(): void {\n const style = document.createElement(\"style\");\n style.id = \"vartheme-transitions\";\n style.textContent = `\n *, *::before, *::after {\n transition: \n background-color 0.3s ease,\n color 0.3s ease,\n border-color 0.3s ease !important;\n }\n `;\n document.head.appendChild(style);\n}\n\nexport function removeTransitions(): void {\n const style = document.getElementById(\"vartheme-transitions\");\n if (style) style.remove();\n}\n\nexport function getDefaultColors(mode: \"light\" | \"dark\"): ThemeColors {\n return mode === \"dark\" ? DEFAULT_DARK : DEFAULT_LIGHT;\n}","import { ThemeMode, ThemeColors } from \"../types\";\n\nconst STORAGE_KEY_MODE = \"vartheme-mode\";\nconst STORAGE_KEY_COLORS = \"vartheme-colors\";\n\nexport function saveMode(mode: ThemeMode): void {\n try {\n localStorage.setItem(STORAGE_KEY_MODE, mode);\n } catch {\n console.warn(\"vartheme: localStorage not available\");\n }\n}\n\nexport function loadMode(): ThemeMode | null {\n try {\n const saved = localStorage.getItem(STORAGE_KEY_MODE);\n if (saved === \"light\" || saved === \"dark\" || saved === \"system\") {\n return saved;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport function saveColors(colors: ThemeColors): void {\n try {\n localStorage.setItem(STORAGE_KEY_COLORS, JSON.stringify(colors));\n } catch {\n console.warn(\"vartheme: localStorage not available\");\n }\n}\n\nexport function loadColors(): ThemeColors | null {\n try {\n const saved = localStorage.getItem(STORAGE_KEY_COLORS);\n if (saved) return JSON.parse(saved) as ThemeColors;\n return null;\n } catch {\n return null;\n }\n}\n\nexport function clearStorage(): void {\n try {\n localStorage.removeItem(STORAGE_KEY_MODE);\n localStorage.removeItem(STORAGE_KEY_COLORS);\n } catch {\n console.warn(\"vartheme: localStorage not available\");\n }\n}","type SystemMode = \"light\" | \"dark\";\ntype SystemModeListener = (mode: SystemMode) => void;\n\nexport function getSystemMode(): SystemMode {\n if (typeof window === \"undefined\") return \"light\";\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n ? \"dark\"\n : \"light\";\n}\n\nexport function watchSystemMode(callback: SystemModeListener): () => void {\n if (typeof window === \"undefined\") return () => {};\n\n const mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\n const handler = (e: MediaQueryListEvent) => {\n callback(e.matches ? \"dark\" : \"light\");\n };\n\n mediaQuery.addEventListener(\"change\", handler);\n\n // cleanup function return ho raha hai\n return () => {\n mediaQuery.removeEventListener(\"change\", handler);\n };\n}\n\nexport function isBrowser(): boolean {\n return typeof window !== \"undefined\";\n}","import { ThemeColors } from \"../types\";\n\nexport interface ThemePreset {\n name: string;\n light: ThemeColors;\n dark: ThemeColors;\n}\n\nexport const BUILT_IN_THEMES: Record<string, ThemePreset> = {\n default: {\n name: \"default\",\n light: {\n primary: \"#7C3AED\",\n background: \"#FFFFFF\",\n surface: \"#F8FAFC\",\n text: \"#0F172A\",\n border: \"#E2E8F0\",\n accent: \"#06B6D4\",\n },\n dark: {\n primary: \"#A78BFA\",\n background: \"#0F172A\",\n surface: \"#1E293B\",\n text: \"#F8FAFC\",\n border: \"#334155\",\n accent: \"#22D3EE\",\n },\n },\n\n ocean: {\n name: \"ocean\",\n light: {\n primary: \"#0284C7\",\n background: \"#F0F9FF\",\n surface: \"#E0F2FE\",\n text: \"#0C4A6E\",\n border: \"#BAE6FD\",\n accent: \"#0D9488\",\n },\n dark: {\n primary: \"#38BDF8\",\n background: \"#0C1A2E\",\n surface: \"#0F2744\",\n text: \"#E0F2FE\",\n border: \"#1E3A5F\",\n accent: \"#2DD4BF\",\n },\n },\n\n forest: {\n name: \"forest\",\n light: {\n primary: \"#16A34A\",\n background: \"#F0FDF4\",\n surface: \"#DCFCE7\",\n text: \"#14532D\",\n border: \"#BBF7D0\",\n accent: \"#84CC16\",\n },\n dark: {\n primary: \"#4ADE80\",\n background: \"#0A1F0F\",\n surface: \"#0F2D17\",\n text: \"#DCFCE7\",\n border: \"#166534\",\n accent: \"#A3E635\",\n },\n },\n\n sunset: {\n name: \"sunset\",\n light: {\n primary: \"#EA580C\",\n background: \"#FFF7ED\",\n surface: \"#FFEDD5\",\n text: \"#431407\",\n border: \"#FED7AA\",\n accent: \"#DB2777\",\n },\n dark: {\n primary: \"#FB923C\",\n background: \"#1A0A00\",\n surface: \"#2D1200\",\n text: \"#FFEDD5\",\n border: \"#7C2D12\",\n accent: \"#F472B6\",\n },\n },\n\n rose: {\n name: \"rose\",\n light: {\n primary: \"#E11D48\",\n background: \"#FFF1F2\",\n surface: \"#FFE4E6\",\n text: \"#4C0519\",\n border: \"#FECDD3\",\n accent: \"#BE185D\",\n },\n dark: {\n primary: \"#FB7185\",\n background: \"#1A0008\",\n surface: \"#2D000F\",\n text: \"#FFE4E6\",\n border: \"#881337\",\n accent: \"#F472B6\",\n },\n },\n};\n\nexport function getTheme(name: string): ThemePreset {\n return BUILT_IN_THEMES[name] || BUILT_IN_THEMES.default;\n}","import { useState, useEffect, useCallback } from \"react\";\nimport { ThemeMode, ThemeColors, ThemeState, ThemeName } from \"../types\";\nimport { injectCSSVariables, getDefaultColors } from \"../core/engine\";\nimport { saveMode, loadMode, saveColors, loadColors } from \"../core/storage\";\nimport { getSystemMode, watchSystemMode } from \"../core/system\";\nimport { getTheme } from \"../core/themes\";\n\nexport function useTheme(\n initial?: ThemeMode,\n initialTheme?: ThemeName\n): ThemeState {\n const [mode, setModeState] = useState<ThemeMode>(() => {\n return loadMode() || initial || \"system\";\n });\n\n const [theme, setThemeState] = useState<ThemeName>(\n initialTheme || \"default\"\n );\n\n const [colors, setColorsState] = useState<ThemeColors>(() => {\n return loadColors() || {};\n });\n\n const resolvedMode = mode === \"system\" ? getSystemMode() : mode;\n\n useEffect(() => {\n const preset = getTheme(theme);\n const presetColors = resolvedMode === \"dark\" ? preset.dark : preset.light;\n injectCSSVariables({ ...presetColors, ...colors }, resolvedMode);\n }, [resolvedMode, colors, theme]);\n\n useEffect(() => {\n if (mode !== \"system\") return;\n const cleanup = watchSystemMode(() => {\n const preset = getTheme(theme);\n const presetColors =\n getSystemMode() === \"dark\" ? preset.dark : preset.light;\n injectCSSVariables({ ...presetColors, ...colors }, getSystemMode());\n });\n return cleanup;\n }, [mode, colors, theme]);\n\n const toggle = useCallback(() => {\n const next = resolvedMode === \"light\" ? \"dark\" : \"light\";\n setModeState(next);\n saveMode(next);\n }, [resolvedMode]);\n\n const setMode = useCallback((newMode: ThemeMode) => {\n setModeState(newMode);\n saveMode(newMode);\n }, []);\n\n const setColors = useCallback((newColors: ThemeColors) => {\n setColorsState((prev) => {\n const merged = { ...prev, ...newColors };\n saveColors(merged);\n return merged;\n });\n }, []);\n\n const setTheme = useCallback((newTheme: ThemeName) => {\n setThemeState(newTheme);\n }, []);\n\n return {\n mode,\n resolvedMode,\n theme,\n colors: { ...getDefaultColors(resolvedMode), ...colors },\n toggle,\n setMode,\n setColors,\n setTheme,\n };\n}","import { createContext, useContext, ReactNode } from \"react\";\nimport { ThemeState, ThemeMode, ThemeColors, ThemeName } from \"../types\";\nimport { useTheme } from \"./useTheme\";\nimport { applyTransitions } from \"../core/engine\";\n\nconst ThemeContext = createContext<ThemeState | null>(null);\n\ninterface ThemeProviderProps {\n children: ReactNode;\n mode?: ThemeMode;\n theme?: ThemeName;\n colors?: ThemeColors;\n transitions?: boolean;\n}\n\nexport function ThemeProvider({\n children,\n mode,\n theme = \"default\",\n colors,\n transitions,\n}: ThemeProviderProps) {\n const themeState = useTheme(mode, theme);\n\n if (transitions) {\n applyTransitions();\n }\n\n if (colors) {\n themeState.setColors(colors);\n }\n\n return (\n <ThemeContext.Provider value={themeState}>\n {children}\n </ThemeContext.Provider>\n );\n}\n\nexport function useThemeContext(): ThemeState {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error(\n \"useThemeContext must be used inside <ThemeProvider />\"\n );\n }\n return context;\n}","import { useThemeContext } from \"./ThemeProvider\";\n\ninterface ThemeToggleProps {\n size?: number;\n}\n\nexport function ThemeToggle({ size = 48 }: ThemeToggleProps) {\n const { resolvedMode, toggle } = useThemeContext();\n const isDark = resolvedMode === \"dark\";\n\n return (\n <>\n <style>{`\n @keyframes vt-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n @keyframes vt-twinkle {\n 0% { opacity: 0.2; transform: scale(0.6); }\n 100% { opacity: 1; transform: scale(1.2); }\n }\n @keyframes vt-glow-sun {\n 0% { box-shadow: 0 0 10px 2px #FCD34D66; }\n 100% { box-shadow: 0 0 22px 6px #FCD34DAA; }\n }\n @keyframes vt-glow-moon {\n 0% { box-shadow: 0 0 10px 2px #A78BFA55; }\n 100% { box-shadow: 0 0 22px 6px #A78BFA99; }\n }\n `}</style>\n\n <button\n onClick={toggle}\n aria-label=\"Toggle theme\"\n style={{\n width: size,\n height: size,\n borderRadius: \"50%\",\n border: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n background: isDark\n ? \"radial-gradient(circle, #1E293B, #0F172A)\"\n : \"radial-gradient(circle, #FEF3C7, #FDE68A)\",\n animation: isDark ? \"vt-glow-moon 2s infinite alternate\" : \"vt-glow-sun 2s infinite alternate\",\n transition: \"background 0.5s ease\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n overflow: \"visible\",\n }}\n >\n {/* Sun Mode */}\n {!isDark && (\n <>\n {/* Center circle */}\n <div style={{\n width: size * 0.38,\n height: size * 0.38,\n borderRadius: \"50%\",\n background: \"#F59E0B\",\n boxShadow: \"0 0 8px #FCD34D\",\n zIndex: 2,\n }} />\n\n {/* Rays */}\n {[0,45,90,135,180,225,270,315].map((deg, i) => (\n <div key={i} style={{\n position: \"absolute\",\n width: 3,\n height: size * 0.18,\n borderRadius: 4,\n background: \"#FCD34D\",\n top: \"50%\",\n left: \"50%\",\n transformOrigin: \"50% 0%\",\n transform: `translateX(-50%) rotate(${deg}deg) translateY(-${size * 0.54}px)`,\n animation: \"vt-spin 8s linear infinite\",\n animationDelay: `${i * 0.05}s`,\n opacity: 0.9,\n }} />\n ))}\n </>\n )}\n\n {/* Moon Mode */}\n {isDark && (\n <>\n {/* Crescent using two circles */}\n <div style={{\n width: size * 0.45,\n height: size * 0.45,\n borderRadius: \"50%\",\n background: \"#E2E8F0\",\n boxShadow: \"0 0 8px #A78BFA\",\n position: \"relative\",\n zIndex: 2,\n overflow: \"hidden\",\n }}>\n {/* Inner circle to create crescent */}\n <div style={{\n position: \"absolute\",\n width: size * 0.38,\n height: size * 0.38,\n borderRadius: \"50%\",\n background: \"#0F172A\",\n top: -size * 0.08,\n right: -size * 0.08,\n }} />\n </div>\n\n {/* Stars */}\n {[\n { top: -6, right: -4, s: 4, delay: \"0s\" },\n { top: 4, right: -10, s: 3, delay: \"0.5s\" },\n { bottom: 2, right: -8, s: 2, delay: \"1s\" },\n { top: -4, left: 2, s: 2, delay: \"1.5s\" },\n ].map((star, i) => (\n <div key={i} style={{\n position: \"absolute\",\n width: star.s,\n height: star.s,\n borderRadius: \"50%\",\n background: \"#E2E8F0\",\n top: star.top,\n right: (star as any).right,\n left: (star as any).left,\n bottom: (star as any).bottom,\n animation: `vt-twinkle 1.5s infinite alternate`,\n animationDelay: star.delay,\n }} />\n ))}\n </>\n )}\n </button>\n </>\n );\n}"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vartheme",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Zero config, CSS variable based theme switching for React",
|
|
5
|
+
"author": "Your Name",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"module": "./dist/index.mjs",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.mjs",
|
|
14
|
+
"require": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": ["dist"],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"dev": "tsup --watch",
|
|
21
|
+
"test": "vitest",
|
|
22
|
+
"lint": "tsc --noEmit"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"react": ">=17.0.0",
|
|
26
|
+
"react-dom": ">=17.0.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/react": "^18.0.0",
|
|
30
|
+
"@types/react-dom": "^18.0.0",
|
|
31
|
+
"react": "^18.0.0",
|
|
32
|
+
"react-dom": "^18.0.0",
|
|
33
|
+
"tsup": "^8.0.0",
|
|
34
|
+
"typescript": "^5.0.0",
|
|
35
|
+
"vitest": "^1.0.0"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"theme",
|
|
39
|
+
"dark-mode",
|
|
40
|
+
"css-variables",
|
|
41
|
+
"react",
|
|
42
|
+
"theming"
|
|
43
|
+
]
|
|
44
|
+
}
|