react-theme-forge 1.0.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/dist/components/ThemeProvider.d.ts +6 -0
- package/dist/components/ThemeToggle.d.ts +18 -0
- package/dist/hooks/useThemeColor.d.ts +31 -0
- package/dist/index.d.ts +147 -0
- package/dist/index.esm.js +538 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +548 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +86 -0
- package/dist/utils/themes.d.ts +9 -0
- package/package.json +61 -0
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { createContext, useState, useEffect, useMemo, useRef, useCallback, useContext } from 'react';
|
|
3
|
+
|
|
4
|
+
// ─────────────────────────────────────────────
|
|
5
|
+
// Default Color Tokens
|
|
6
|
+
// ─────────────────────────────────────────────
|
|
7
|
+
const defaultLightColors = {
|
|
8
|
+
primary: "221 83% 53%",
|
|
9
|
+
primaryForeground: "0 0% 100%",
|
|
10
|
+
secondary: "210 40% 96%",
|
|
11
|
+
secondaryForeground: "222 47% 11%",
|
|
12
|
+
background: "0 0% 100%",
|
|
13
|
+
foreground: "222 47% 11%",
|
|
14
|
+
card: "0 0% 100%",
|
|
15
|
+
cardForeground: "222 47% 11%",
|
|
16
|
+
border: "214 32% 91%",
|
|
17
|
+
input: "214 32% 91%",
|
|
18
|
+
ring: "221 83% 53%",
|
|
19
|
+
muted: "210 40% 96%",
|
|
20
|
+
mutedForeground: "215 16% 47%",
|
|
21
|
+
accent: "210 40% 96%",
|
|
22
|
+
accentForeground: "222 47% 11%",
|
|
23
|
+
destructive: "0 84% 60%",
|
|
24
|
+
destructiveForeground: "0 0% 100%",
|
|
25
|
+
success: "142 71% 45%",
|
|
26
|
+
successForeground: "0 0% 100%",
|
|
27
|
+
warning: "38 92% 50%",
|
|
28
|
+
warningForeground: "0 0% 100%",
|
|
29
|
+
};
|
|
30
|
+
const defaultDarkColors = {
|
|
31
|
+
primary: "217 91% 60%",
|
|
32
|
+
primaryForeground: "0 0% 100%",
|
|
33
|
+
secondary: "217 33% 17%",
|
|
34
|
+
secondaryForeground: "210 40% 98%",
|
|
35
|
+
background: "222 47% 7%",
|
|
36
|
+
foreground: "210 40% 98%",
|
|
37
|
+
card: "222 47% 11%",
|
|
38
|
+
cardForeground: "210 40% 98%",
|
|
39
|
+
border: "217 33% 17%",
|
|
40
|
+
input: "217 33% 17%",
|
|
41
|
+
ring: "217 91% 60%",
|
|
42
|
+
muted: "217 33% 17%",
|
|
43
|
+
mutedForeground: "215 20% 65%",
|
|
44
|
+
accent: "217 33% 17%",
|
|
45
|
+
accentForeground: "210 40% 98%",
|
|
46
|
+
destructive: "0 62% 50%",
|
|
47
|
+
destructiveForeground: "0 0% 100%",
|
|
48
|
+
success: "142 71% 39%",
|
|
49
|
+
successForeground: "0 0% 100%",
|
|
50
|
+
warning: "38 92% 45%",
|
|
51
|
+
warningForeground: "0 0% 100%",
|
|
52
|
+
};
|
|
53
|
+
const defaultRadius = {
|
|
54
|
+
sm: "0.25rem",
|
|
55
|
+
md: "0.5rem",
|
|
56
|
+
lg: "0.75rem",
|
|
57
|
+
xl: "1rem",
|
|
58
|
+
full: "9999px",
|
|
59
|
+
};
|
|
60
|
+
const defaultFonts = {
|
|
61
|
+
sans: "Inter, system-ui, -apple-system, sans-serif",
|
|
62
|
+
mono: "JetBrains Mono, Fira Code, monospace",
|
|
63
|
+
heading: "Inter, system-ui, -apple-system, sans-serif",
|
|
64
|
+
};
|
|
65
|
+
// ─────────────────────────────────────────────
|
|
66
|
+
// Built-in Preset Themes
|
|
67
|
+
// ─────────────────────────────────────────────
|
|
68
|
+
const presetThemes = {
|
|
69
|
+
ocean: {
|
|
70
|
+
name: "ocean",
|
|
71
|
+
colors: {
|
|
72
|
+
light: {
|
|
73
|
+
primary: "201 96% 32%",
|
|
74
|
+
primaryForeground: "0 0% 100%",
|
|
75
|
+
background: "197 100% 98%",
|
|
76
|
+
foreground: "202 80% 16%",
|
|
77
|
+
card: "0 0% 100%",
|
|
78
|
+
border: "197 40% 88%",
|
|
79
|
+
accent: "197 71% 89%",
|
|
80
|
+
accentForeground: "202 80% 16%",
|
|
81
|
+
},
|
|
82
|
+
dark: {
|
|
83
|
+
primary: "200 100% 60%",
|
|
84
|
+
primaryForeground: "202 80% 10%",
|
|
85
|
+
background: "202 60% 8%",
|
|
86
|
+
foreground: "197 80% 95%",
|
|
87
|
+
card: "202 50% 12%",
|
|
88
|
+
border: "202 40% 20%",
|
|
89
|
+
accent: "202 40% 18%",
|
|
90
|
+
accentForeground: "197 80% 95%",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
forest: {
|
|
95
|
+
name: "forest",
|
|
96
|
+
colors: {
|
|
97
|
+
light: {
|
|
98
|
+
primary: "142 76% 36%",
|
|
99
|
+
primaryForeground: "0 0% 100%",
|
|
100
|
+
background: "138 40% 98%",
|
|
101
|
+
foreground: "140 40% 10%",
|
|
102
|
+
card: "0 0% 100%",
|
|
103
|
+
border: "138 30% 88%",
|
|
104
|
+
accent: "138 50% 90%",
|
|
105
|
+
accentForeground: "140 40% 10%",
|
|
106
|
+
},
|
|
107
|
+
dark: {
|
|
108
|
+
primary: "142 71% 55%",
|
|
109
|
+
primaryForeground: "140 40% 7%",
|
|
110
|
+
background: "140 30% 7%",
|
|
111
|
+
foreground: "138 40% 95%",
|
|
112
|
+
card: "140 25% 11%",
|
|
113
|
+
border: "140 25% 18%",
|
|
114
|
+
accent: "140 25% 16%",
|
|
115
|
+
accentForeground: "138 40% 95%",
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
sunset: {
|
|
120
|
+
name: "sunset",
|
|
121
|
+
colors: {
|
|
122
|
+
light: {
|
|
123
|
+
primary: "15 90% 55%",
|
|
124
|
+
primaryForeground: "0 0% 100%",
|
|
125
|
+
background: "20 100% 99%",
|
|
126
|
+
foreground: "15 40% 12%",
|
|
127
|
+
card: "0 0% 100%",
|
|
128
|
+
border: "20 40% 88%",
|
|
129
|
+
accent: "30 80% 91%",
|
|
130
|
+
accentForeground: "15 40% 12%",
|
|
131
|
+
},
|
|
132
|
+
dark: {
|
|
133
|
+
primary: "15 90% 65%",
|
|
134
|
+
primaryForeground: "15 40% 8%",
|
|
135
|
+
background: "15 40% 8%",
|
|
136
|
+
foreground: "20 60% 95%",
|
|
137
|
+
card: "15 30% 12%",
|
|
138
|
+
border: "15 30% 20%",
|
|
139
|
+
accent: "15 30% 18%",
|
|
140
|
+
accentForeground: "20 60% 95%",
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
rose: {
|
|
145
|
+
name: "rose",
|
|
146
|
+
colors: {
|
|
147
|
+
light: {
|
|
148
|
+
primary: "346 77% 50%",
|
|
149
|
+
primaryForeground: "0 0% 100%",
|
|
150
|
+
background: "345 100% 99%",
|
|
151
|
+
foreground: "346 40% 12%",
|
|
152
|
+
card: "0 0% 100%",
|
|
153
|
+
border: "345 40% 88%",
|
|
154
|
+
accent: "345 80% 93%",
|
|
155
|
+
accentForeground: "346 40% 12%",
|
|
156
|
+
},
|
|
157
|
+
dark: {
|
|
158
|
+
primary: "346 77% 65%",
|
|
159
|
+
primaryForeground: "346 40% 8%",
|
|
160
|
+
background: "346 30% 8%",
|
|
161
|
+
foreground: "345 60% 95%",
|
|
162
|
+
card: "346 25% 12%",
|
|
163
|
+
border: "346 25% 20%",
|
|
164
|
+
accent: "346 25% 18%",
|
|
165
|
+
accentForeground: "345 60% 95%",
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
violet: {
|
|
170
|
+
name: "violet",
|
|
171
|
+
colors: {
|
|
172
|
+
light: {
|
|
173
|
+
primary: "263 70% 50%",
|
|
174
|
+
primaryForeground: "0 0% 100%",
|
|
175
|
+
background: "260 100% 99%",
|
|
176
|
+
foreground: "263 40% 12%",
|
|
177
|
+
card: "0 0% 100%",
|
|
178
|
+
border: "260 40% 88%",
|
|
179
|
+
accent: "260 80% 93%",
|
|
180
|
+
accentForeground: "263 40% 12%",
|
|
181
|
+
},
|
|
182
|
+
dark: {
|
|
183
|
+
primary: "263 70% 65%",
|
|
184
|
+
primaryForeground: "263 40% 8%",
|
|
185
|
+
background: "263 30% 8%",
|
|
186
|
+
foreground: "260 60% 95%",
|
|
187
|
+
card: "263 25% 12%",
|
|
188
|
+
border: "263 25% 20%",
|
|
189
|
+
accent: "263 25% 18%",
|
|
190
|
+
accentForeground: "260 60% 95%",
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
// ─────────────────────────────────────────────
|
|
196
|
+
// CSS Variable Injector
|
|
197
|
+
// ─────────────────────────────────────────────
|
|
198
|
+
function buildCSSVariables(colors, radius = {}, fonts = {}) {
|
|
199
|
+
const colorVars = Object.entries(colors)
|
|
200
|
+
.map(([key, value]) => {
|
|
201
|
+
const cssKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
202
|
+
return ` --${cssKey}: ${value};`;
|
|
203
|
+
})
|
|
204
|
+
.join("\n");
|
|
205
|
+
const radiusVars = Object.entries(radius)
|
|
206
|
+
.map(([key, value]) => ` --radius-${key}: ${value};`)
|
|
207
|
+
.join("\n");
|
|
208
|
+
const fontVars = Object.entries(fonts)
|
|
209
|
+
.map(([key, value]) => ` --font-${key}: ${value};`)
|
|
210
|
+
.join("\n");
|
|
211
|
+
return [colorVars, radiusVars, fontVars].filter(Boolean).join("\n");
|
|
212
|
+
}
|
|
213
|
+
function injectStyles(cssVariables, isDark, darkClass, targetElement) {
|
|
214
|
+
const styleId = "react-theme-forge-styles";
|
|
215
|
+
let styleEl = document.getElementById(styleId);
|
|
216
|
+
if (!styleEl) {
|
|
217
|
+
styleEl = document.createElement("style");
|
|
218
|
+
styleEl.id = styleId;
|
|
219
|
+
document.head.appendChild(styleEl);
|
|
220
|
+
}
|
|
221
|
+
const selector = targetElement !== ":root" ? targetElement : ":root";
|
|
222
|
+
styleEl.textContent = `${selector} {\n${cssVariables}\n}`;
|
|
223
|
+
}
|
|
224
|
+
function mergeColors(base, overrides) {
|
|
225
|
+
return Object.assign(Object.assign({}, base), overrides);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// ─────────────────────────────────────────────
|
|
229
|
+
// Context
|
|
230
|
+
// ─────────────────────────────────────────────
|
|
231
|
+
const ThemeContext = createContext(null);
|
|
232
|
+
// ─────────────────────────────────────────────
|
|
233
|
+
// Provider
|
|
234
|
+
// ─────────────────────────────────────────────
|
|
235
|
+
function ThemeProvider({ children, defaultMode = "system", defaultTheme, storageKey = "rtf-theme", themes: initialThemes = [], darkClass = "dark", targetElement = ":root", disablePersistence = false, }) {
|
|
236
|
+
// ── Registered themes (presets + user-provided) ──
|
|
237
|
+
const [themes, setThemes] = useState(() => {
|
|
238
|
+
const all = Object.assign({}, presetThemes);
|
|
239
|
+
initialThemes.forEach((t) => (all[t.name] = t));
|
|
240
|
+
return all;
|
|
241
|
+
});
|
|
242
|
+
// ── Persist / restore from localStorage ──
|
|
243
|
+
const getStored = (key, fallback) => {
|
|
244
|
+
if (disablePersistence || typeof window === "undefined")
|
|
245
|
+
return fallback;
|
|
246
|
+
try {
|
|
247
|
+
const val = localStorage.getItem(`${storageKey}-${key}`);
|
|
248
|
+
return val !== null ? JSON.parse(val) : fallback;
|
|
249
|
+
}
|
|
250
|
+
catch (_a) {
|
|
251
|
+
return fallback;
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
const setStored = (key, value) => {
|
|
255
|
+
if (disablePersistence || typeof window === "undefined")
|
|
256
|
+
return;
|
|
257
|
+
try {
|
|
258
|
+
localStorage.setItem(`${storageKey}-${key}`, JSON.stringify(value));
|
|
259
|
+
}
|
|
260
|
+
catch (_a) { }
|
|
261
|
+
};
|
|
262
|
+
const [mode, setModeState] = useState(() => getStored("mode", defaultMode));
|
|
263
|
+
const [activeTheme, setActiveTheme] = useState(() => getStored("activeTheme", defaultTheme !== null && defaultTheme !== void 0 ? defaultTheme : null));
|
|
264
|
+
// ── Detect system preference ──
|
|
265
|
+
const [systemPrefersDark, setSystemPrefersDark] = useState(() => {
|
|
266
|
+
if (typeof window === "undefined")
|
|
267
|
+
return false;
|
|
268
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
269
|
+
});
|
|
270
|
+
useEffect(() => {
|
|
271
|
+
if (typeof window === "undefined")
|
|
272
|
+
return;
|
|
273
|
+
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
274
|
+
const handler = (e) => setSystemPrefersDark(e.matches);
|
|
275
|
+
mq.addEventListener("change", handler);
|
|
276
|
+
return () => mq.removeEventListener("change", handler);
|
|
277
|
+
}, []);
|
|
278
|
+
// ── Resolved theme: light or dark ──
|
|
279
|
+
const theme = useMemo(() => {
|
|
280
|
+
if (mode === "system")
|
|
281
|
+
return systemPrefersDark ? "dark" : "light";
|
|
282
|
+
return mode;
|
|
283
|
+
}, [mode, systemPrefersDark]);
|
|
284
|
+
// ── Apply CSS variables whenever theme/activeTheme changes ──
|
|
285
|
+
const prevStyles = useRef("");
|
|
286
|
+
useEffect(() => {
|
|
287
|
+
var _a, _b, _c, _d, _e, _f;
|
|
288
|
+
if (typeof document === "undefined")
|
|
289
|
+
return;
|
|
290
|
+
const isDark = theme === "dark";
|
|
291
|
+
const customTheme = activeTheme ? themes[activeTheme] : null;
|
|
292
|
+
// Merge default colors with custom theme overrides
|
|
293
|
+
const lightColors = mergeColors(defaultLightColors, (_b = (_a = customTheme === null || customTheme === void 0 ? void 0 : customTheme.colors) === null || _a === void 0 ? void 0 : _a.light) !== null && _b !== void 0 ? _b : {});
|
|
294
|
+
const darkColors = mergeColors(defaultDarkColors, (_d = (_c = customTheme === null || customTheme === void 0 ? void 0 : customTheme.colors) === null || _c === void 0 ? void 0 : _c.dark) !== null && _d !== void 0 ? _d : {});
|
|
295
|
+
const activeColors = isDark ? darkColors : lightColors;
|
|
296
|
+
const radius = Object.assign(Object.assign({}, defaultRadius), ((_e = customTheme === null || customTheme === void 0 ? void 0 : customTheme.radius) !== null && _e !== void 0 ? _e : {}));
|
|
297
|
+
const fonts = Object.assign(Object.assign({}, defaultFonts), ((_f = customTheme === null || customTheme === void 0 ? void 0 : customTheme.fonts) !== null && _f !== void 0 ? _f : {}));
|
|
298
|
+
const cssVars = buildCSSVariables(activeColors, radius, fonts);
|
|
299
|
+
if (cssVars !== prevStyles.current) {
|
|
300
|
+
injectStyles(cssVars, isDark, darkClass, targetElement);
|
|
301
|
+
prevStyles.current = cssVars;
|
|
302
|
+
}
|
|
303
|
+
// Toggle dark class on <html>
|
|
304
|
+
const root = document.documentElement;
|
|
305
|
+
if (isDark) {
|
|
306
|
+
root.classList.add(darkClass);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
root.classList.remove(darkClass);
|
|
310
|
+
}
|
|
311
|
+
// Set data-theme attribute for debugging / CSS targeting
|
|
312
|
+
root.setAttribute("data-theme", activeTheme !== null && activeTheme !== void 0 ? activeTheme : "default");
|
|
313
|
+
root.setAttribute("data-mode", theme);
|
|
314
|
+
}, [theme, activeTheme, themes, darkClass, targetElement]);
|
|
315
|
+
// ─────────────────────────────────────────────
|
|
316
|
+
// Actions
|
|
317
|
+
// ─────────────────────────────────────────────
|
|
318
|
+
const setMode = useCallback((newMode) => {
|
|
319
|
+
setModeState(newMode);
|
|
320
|
+
setStored("mode", newMode);
|
|
321
|
+
},
|
|
322
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
323
|
+
[storageKey, disablePersistence]);
|
|
324
|
+
const toggleTheme = useCallback(() => {
|
|
325
|
+
setMode(theme === "dark" ? "light" : "dark");
|
|
326
|
+
}, [theme, setMode]);
|
|
327
|
+
const applyTheme = useCallback((themeName) => {
|
|
328
|
+
setActiveTheme(themeName);
|
|
329
|
+
setStored("activeTheme", themeName);
|
|
330
|
+
},
|
|
331
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
332
|
+
[storageKey, disablePersistence]);
|
|
333
|
+
const registerTheme = useCallback((config) => {
|
|
334
|
+
setThemes((prev) => (Object.assign(Object.assign({}, prev), { [config.name]: config })));
|
|
335
|
+
}, []);
|
|
336
|
+
const removeTheme = useCallback((themeName) => {
|
|
337
|
+
setThemes((prev) => {
|
|
338
|
+
const next = Object.assign({}, prev);
|
|
339
|
+
delete next[themeName];
|
|
340
|
+
return next;
|
|
341
|
+
});
|
|
342
|
+
setActiveTheme((prev) => (prev === themeName ? null : prev));
|
|
343
|
+
}, []);
|
|
344
|
+
const resetTheme = useCallback(() => {
|
|
345
|
+
setActiveTheme(null);
|
|
346
|
+
setModeState(defaultMode);
|
|
347
|
+
setStored("activeTheme", null);
|
|
348
|
+
setStored("mode", defaultMode);
|
|
349
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
350
|
+
}, [defaultMode, storageKey, disablePersistence]);
|
|
351
|
+
// ─────────────────────────────────────────────
|
|
352
|
+
// Context Value
|
|
353
|
+
// ─────────────────────────────────────────────
|
|
354
|
+
const value = useMemo(() => ({
|
|
355
|
+
theme,
|
|
356
|
+
mode,
|
|
357
|
+
themes,
|
|
358
|
+
activeTheme,
|
|
359
|
+
toggleTheme,
|
|
360
|
+
setMode,
|
|
361
|
+
applyTheme,
|
|
362
|
+
registerTheme,
|
|
363
|
+
removeTheme,
|
|
364
|
+
resetTheme,
|
|
365
|
+
systemPrefersDark,
|
|
366
|
+
}), [
|
|
367
|
+
theme,
|
|
368
|
+
mode,
|
|
369
|
+
themes,
|
|
370
|
+
activeTheme,
|
|
371
|
+
toggleTheme,
|
|
372
|
+
setMode,
|
|
373
|
+
applyTheme,
|
|
374
|
+
registerTheme,
|
|
375
|
+
removeTheme,
|
|
376
|
+
resetTheme,
|
|
377
|
+
systemPrefersDark,
|
|
378
|
+
]);
|
|
379
|
+
return (jsx(ThemeContext.Provider, { value: value, children: children }));
|
|
380
|
+
}
|
|
381
|
+
// ─────────────────────────────────────────────
|
|
382
|
+
// Hook
|
|
383
|
+
// ─────────────────────────────────────────────
|
|
384
|
+
function useTheme() {
|
|
385
|
+
const context = useContext(ThemeContext);
|
|
386
|
+
if (!context) {
|
|
387
|
+
throw new Error("[react-theme-forge] useTheme must be used within a <ThemeProvider>.");
|
|
388
|
+
}
|
|
389
|
+
return context;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// ─────────────────────────────────────────────
|
|
393
|
+
// SVG Icons
|
|
394
|
+
// ─────────────────────────────────────────────
|
|
395
|
+
const SunIcon = () => (jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [jsx("circle", { cx: "12", cy: "12", r: "4" }), jsx("path", { d: "M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" })] }));
|
|
396
|
+
const MoonIcon = () => (jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) }));
|
|
397
|
+
const SystemIcon = () => (jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [jsx("rect", { x: "2", y: "3", width: "20", height: "14", rx: "2", ry: "2" }), jsx("line", { x1: "8", y1: "21", x2: "16", y2: "21" }), jsx("line", { x1: "12", y1: "17", x2: "12", y2: "21" })] }));
|
|
398
|
+
const sizeMap = {
|
|
399
|
+
sm: "h-7 w-7 text-xs",
|
|
400
|
+
md: "h-9 w-9 text-sm",
|
|
401
|
+
lg: "h-11 w-11 text-base",
|
|
402
|
+
};
|
|
403
|
+
function ThemeToggle({ variant = "icon", className = "", size = "md", showLabel = false, ariaLabel, }) {
|
|
404
|
+
const { theme, mode, toggleTheme, setMode } = useTheme();
|
|
405
|
+
if (variant === "segmented") {
|
|
406
|
+
return (jsx("div", { className: `inline-flex items-center rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))] p-1 gap-1 ${className}`, role: "group", "aria-label": "Theme selector", children: [
|
|
407
|
+
{ value: "light", icon: jsx(SunIcon, {}), label: "Light" },
|
|
408
|
+
{ value: "dark", icon: jsx(MoonIcon, {}), label: "Dark" },
|
|
409
|
+
{ value: "system", icon: jsx(SystemIcon, {}), label: "System" },
|
|
410
|
+
].map(({ value, icon, label }) => {
|
|
411
|
+
const isActive = mode === value;
|
|
412
|
+
return (jsxs("button", { onClick: () => setMode(value), "aria-pressed": isActive, className: [
|
|
413
|
+
"inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-all",
|
|
414
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))]",
|
|
415
|
+
isActive
|
|
416
|
+
? "bg-[hsl(var(--background))] text-[hsl(var(--foreground))] shadow-sm"
|
|
417
|
+
: "text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]",
|
|
418
|
+
].join(" "), children: [icon, jsx("span", { children: label })] }, value));
|
|
419
|
+
}) }));
|
|
420
|
+
}
|
|
421
|
+
// Icon variant
|
|
422
|
+
const label = ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : `Switch to ${theme === "dark" ? "light" : "dark"} mode`;
|
|
423
|
+
return (jsxs("button", { onClick: toggleTheme, "aria-label": label, className: [
|
|
424
|
+
"inline-flex items-center justify-center rounded-md",
|
|
425
|
+
"text-[hsl(var(--foreground))] bg-transparent",
|
|
426
|
+
"hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--accent-foreground))]",
|
|
427
|
+
"border border-[hsl(var(--border))]",
|
|
428
|
+
"transition-colors duration-200",
|
|
429
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))]",
|
|
430
|
+
sizeMap[size],
|
|
431
|
+
className,
|
|
432
|
+
].join(" "), children: [theme === "dark" ? jsx(SunIcon, {}) : jsx(MoonIcon, {}), showLabel && (jsx("span", { className: "ml-2 text-sm font-medium", children: theme === "dark" ? "Light" : "Dark" }))] }));
|
|
433
|
+
}
|
|
434
|
+
function ThemePicker({ className = "", showPreview = true }) {
|
|
435
|
+
const { themes, activeTheme, applyTheme, resetTheme } = useTheme();
|
|
436
|
+
const themeList = [
|
|
437
|
+
{ name: "default", label: "Default", primary: "221 83% 53%" },
|
|
438
|
+
...Object.values(themes).map((t) => {
|
|
439
|
+
var _a, _b, _c;
|
|
440
|
+
return ({
|
|
441
|
+
name: t.name,
|
|
442
|
+
label: t.name.charAt(0).toUpperCase() + t.name.slice(1),
|
|
443
|
+
primary: (_c = (_b = (_a = t.colors) === null || _a === void 0 ? void 0 : _a.light) === null || _b === void 0 ? void 0 : _b.primary) !== null && _c !== void 0 ? _c : "221 83% 53%",
|
|
444
|
+
});
|
|
445
|
+
}),
|
|
446
|
+
];
|
|
447
|
+
return (jsx("div", { className: `flex flex-wrap gap-2 ${className}`, role: "group", "aria-label": "Theme picker", children: themeList.map(({ name, label, primary }) => {
|
|
448
|
+
const isActive = (activeTheme !== null && activeTheme !== void 0 ? activeTheme : "default") === name;
|
|
449
|
+
return (jsxs("button", { onClick: () => (name === "default" ? resetTheme() : applyTheme(name)), "aria-pressed": isActive, title: label, className: [
|
|
450
|
+
"inline-flex items-center gap-2 px-3 py-1.5 rounded-full text-sm font-medium",
|
|
451
|
+
"border transition-all duration-200",
|
|
452
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))]",
|
|
453
|
+
isActive
|
|
454
|
+
? "border-[hsl(var(--primary))] text-[hsl(var(--primary))] bg-[hsl(var(--primary)/0.08)]"
|
|
455
|
+
: "border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))] hover:border-[hsl(var(--primary)/0.5)]",
|
|
456
|
+
].join(" "), children: [showPreview && (jsx("span", { className: "inline-block w-3 h-3 rounded-full", style: { background: `hsl(${primary})` }, "aria-hidden": "true" })), label] }, name));
|
|
457
|
+
}) }));
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// ─────────────────────────────────────────────
|
|
461
|
+
// useThemeColor
|
|
462
|
+
// Returns a CSS variable value for any token
|
|
463
|
+
// ─────────────────────────────────────────────
|
|
464
|
+
/**
|
|
465
|
+
* Get the resolved CSS variable value for a given token.
|
|
466
|
+
*
|
|
467
|
+
* @example
|
|
468
|
+
* const primary = useThemeColor("primary");
|
|
469
|
+
* // Returns: "hsl(var(--primary))"
|
|
470
|
+
*
|
|
471
|
+
* const raw = useThemeColor("primary", true);
|
|
472
|
+
* // Returns: "221 83% 53%" (raw HSL parts, no wrapper)
|
|
473
|
+
*/
|
|
474
|
+
function useThemeColor(token, raw = false) {
|
|
475
|
+
if (raw) {
|
|
476
|
+
if (typeof document === "undefined")
|
|
477
|
+
return "";
|
|
478
|
+
const value = getComputedStyle(document.documentElement)
|
|
479
|
+
.getPropertyValue(`--${token.replace(/([A-Z])/g, "-$1").toLowerCase()}`)
|
|
480
|
+
.trim();
|
|
481
|
+
return value;
|
|
482
|
+
}
|
|
483
|
+
return `hsl(var(--${token.replace(/([A-Z])/g, "-$1").toLowerCase()}))`;
|
|
484
|
+
}
|
|
485
|
+
// ─────────────────────────────────────────────
|
|
486
|
+
// useIsDark
|
|
487
|
+
// Simple boolean shortcut
|
|
488
|
+
// ─────────────────────────────────────────────
|
|
489
|
+
/**
|
|
490
|
+
* @returns true when the resolved theme is "dark"
|
|
491
|
+
*/
|
|
492
|
+
function useIsDark() {
|
|
493
|
+
const { theme } = useTheme();
|
|
494
|
+
return theme === "dark";
|
|
495
|
+
}
|
|
496
|
+
// ─────────────────────────────────────────────
|
|
497
|
+
// useThemeValue
|
|
498
|
+
// Returns a value based on current theme
|
|
499
|
+
// ─────────────────────────────────────────────
|
|
500
|
+
/**
|
|
501
|
+
* Returns a value depending on the active theme.
|
|
502
|
+
*
|
|
503
|
+
* @example
|
|
504
|
+
* const bg = useThemeValue("white", "gray-900");
|
|
505
|
+
*/
|
|
506
|
+
function useThemeValue(lightValue, darkValue) {
|
|
507
|
+
const { theme } = useTheme();
|
|
508
|
+
return theme === "dark" ? darkValue : lightValue;
|
|
509
|
+
}
|
|
510
|
+
// ─────────────────────────────────────────────
|
|
511
|
+
// useThemeTransition
|
|
512
|
+
// Smooth CSS transition helper
|
|
513
|
+
// ─────────────────────────────────────────────
|
|
514
|
+
/**
|
|
515
|
+
* Temporarily adds a CSS transition to the document root
|
|
516
|
+
* so theme changes animate smoothly.
|
|
517
|
+
*
|
|
518
|
+
* @example
|
|
519
|
+
* const withTransition = useThemeTransition();
|
|
520
|
+
* withTransition(() => applyTheme("ocean"));
|
|
521
|
+
*/
|
|
522
|
+
function useThemeTransition(duration = 300) {
|
|
523
|
+
const withTransition = useCallback((fn) => {
|
|
524
|
+
if (typeof document === "undefined") {
|
|
525
|
+
fn();
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
const style = document.createElement("style");
|
|
529
|
+
style.textContent = `*, *::before, *::after { transition: background-color ${duration}ms ease, color ${duration}ms ease, border-color ${duration}ms ease !important; }`;
|
|
530
|
+
document.head.appendChild(style);
|
|
531
|
+
fn();
|
|
532
|
+
setTimeout(() => style.remove(), duration + 50);
|
|
533
|
+
}, [duration]);
|
|
534
|
+
return withTransition;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
export { ThemePicker, ThemeProvider, ThemeToggle, presetThemes, useIsDark, useTheme, useThemeColor, useThemeTransition, useThemeValue };
|
|
538
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/utils/themes.ts","../src/components/ThemeProvider.tsx","../src/components/ThemeToggle.tsx","../src/hooks/useThemeColor.ts"],"sourcesContent":["import type { ThemeColors, ThemeConfig, ThemeRadius, ThemeFonts } from \"../types\";\n\n// ─────────────────────────────────────────────\n// Default Color Tokens\n// ─────────────────────────────────────────────\n\nexport const defaultLightColors: ThemeColors = {\n primary: \"221 83% 53%\",\n primaryForeground: \"0 0% 100%\",\n secondary: \"210 40% 96%\",\n secondaryForeground: \"222 47% 11%\",\n background: \"0 0% 100%\",\n foreground: \"222 47% 11%\",\n card: \"0 0% 100%\",\n cardForeground: \"222 47% 11%\",\n border: \"214 32% 91%\",\n input: \"214 32% 91%\",\n ring: \"221 83% 53%\",\n muted: \"210 40% 96%\",\n mutedForeground: \"215 16% 47%\",\n accent: \"210 40% 96%\",\n accentForeground: \"222 47% 11%\",\n destructive: \"0 84% 60%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"142 71% 45%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 92% 50%\",\n warningForeground: \"0 0% 100%\",\n};\n\nexport const defaultDarkColors: ThemeColors = {\n primary: \"217 91% 60%\",\n primaryForeground: \"0 0% 100%\",\n secondary: \"217 33% 17%\",\n secondaryForeground: \"210 40% 98%\",\n background: \"222 47% 7%\",\n foreground: \"210 40% 98%\",\n card: \"222 47% 11%\",\n cardForeground: \"210 40% 98%\",\n border: \"217 33% 17%\",\n input: \"217 33% 17%\",\n ring: \"217 91% 60%\",\n muted: \"217 33% 17%\",\n mutedForeground: \"215 20% 65%\",\n accent: \"217 33% 17%\",\n accentForeground: \"210 40% 98%\",\n destructive: \"0 62% 50%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"142 71% 39%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 92% 45%\",\n warningForeground: \"0 0% 100%\",\n};\n\nexport const defaultRadius: ThemeRadius = {\n sm: \"0.25rem\",\n md: \"0.5rem\",\n lg: \"0.75rem\",\n xl: \"1rem\",\n full: \"9999px\",\n};\n\nexport const defaultFonts: ThemeFonts = {\n sans: \"Inter, system-ui, -apple-system, sans-serif\",\n mono: \"JetBrains Mono, Fira Code, monospace\",\n heading: \"Inter, system-ui, -apple-system, sans-serif\",\n};\n\n// ─────────────────────────────────────────────\n// Built-in Preset Themes\n// ─────────────────────────────────────────────\n\nexport const presetThemes: Record<string, ThemeConfig> = {\n ocean: {\n name: \"ocean\",\n colors: {\n light: {\n primary: \"201 96% 32%\",\n primaryForeground: \"0 0% 100%\",\n background: \"197 100% 98%\",\n foreground: \"202 80% 16%\",\n card: \"0 0% 100%\",\n border: \"197 40% 88%\",\n accent: \"197 71% 89%\",\n accentForeground: \"202 80% 16%\",\n },\n dark: {\n primary: \"200 100% 60%\",\n primaryForeground: \"202 80% 10%\",\n background: \"202 60% 8%\",\n foreground: \"197 80% 95%\",\n card: \"202 50% 12%\",\n border: \"202 40% 20%\",\n accent: \"202 40% 18%\",\n accentForeground: \"197 80% 95%\",\n },\n },\n },\n\n forest: {\n name: \"forest\",\n colors: {\n light: {\n primary: \"142 76% 36%\",\n primaryForeground: \"0 0% 100%\",\n background: \"138 40% 98%\",\n foreground: \"140 40% 10%\",\n card: \"0 0% 100%\",\n border: \"138 30% 88%\",\n accent: \"138 50% 90%\",\n accentForeground: \"140 40% 10%\",\n },\n dark: {\n primary: \"142 71% 55%\",\n primaryForeground: \"140 40% 7%\",\n background: \"140 30% 7%\",\n foreground: \"138 40% 95%\",\n card: \"140 25% 11%\",\n border: \"140 25% 18%\",\n accent: \"140 25% 16%\",\n accentForeground: \"138 40% 95%\",\n },\n },\n },\n\n sunset: {\n name: \"sunset\",\n colors: {\n light: {\n primary: \"15 90% 55%\",\n primaryForeground: \"0 0% 100%\",\n background: \"20 100% 99%\",\n foreground: \"15 40% 12%\",\n card: \"0 0% 100%\",\n border: \"20 40% 88%\",\n accent: \"30 80% 91%\",\n accentForeground: \"15 40% 12%\",\n },\n dark: {\n primary: \"15 90% 65%\",\n primaryForeground: \"15 40% 8%\",\n background: \"15 40% 8%\",\n foreground: \"20 60% 95%\",\n card: \"15 30% 12%\",\n border: \"15 30% 20%\",\n accent: \"15 30% 18%\",\n accentForeground: \"20 60% 95%\",\n },\n },\n },\n\n rose: {\n name: \"rose\",\n colors: {\n light: {\n primary: \"346 77% 50%\",\n primaryForeground: \"0 0% 100%\",\n background: \"345 100% 99%\",\n foreground: \"346 40% 12%\",\n card: \"0 0% 100%\",\n border: \"345 40% 88%\",\n accent: \"345 80% 93%\",\n accentForeground: \"346 40% 12%\",\n },\n dark: {\n primary: \"346 77% 65%\",\n primaryForeground: \"346 40% 8%\",\n background: \"346 30% 8%\",\n foreground: \"345 60% 95%\",\n card: \"346 25% 12%\",\n border: \"346 25% 20%\",\n accent: \"346 25% 18%\",\n accentForeground: \"345 60% 95%\",\n },\n },\n },\n\n violet: {\n name: \"violet\",\n colors: {\n light: {\n primary: \"263 70% 50%\",\n primaryForeground: \"0 0% 100%\",\n background: \"260 100% 99%\",\n foreground: \"263 40% 12%\",\n card: \"0 0% 100%\",\n border: \"260 40% 88%\",\n accent: \"260 80% 93%\",\n accentForeground: \"263 40% 12%\",\n },\n dark: {\n primary: \"263 70% 65%\",\n primaryForeground: \"263 40% 8%\",\n background: \"263 30% 8%\",\n foreground: \"260 60% 95%\",\n card: \"263 25% 12%\",\n border: \"263 25% 20%\",\n accent: \"263 25% 18%\",\n accentForeground: \"260 60% 95%\",\n },\n },\n },\n};\n\n// ─────────────────────────────────────────────\n// CSS Variable Injector\n// ─────────────────────────────────────────────\n\nexport function buildCSSVariables(\n colors: Partial<ThemeColors>,\n radius: Partial<ThemeRadius> = {},\n fonts: Partial<ThemeFonts> = {}\n): string {\n const colorVars = Object.entries(colors)\n .map(([key, value]) => {\n const cssKey = key.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n return ` --${cssKey}: ${value};`;\n })\n .join(\"\\n\");\n\n const radiusVars = Object.entries(radius)\n .map(([key, value]) => ` --radius-${key}: ${value};`)\n .join(\"\\n\");\n\n const fontVars = Object.entries(fonts)\n .map(([key, value]) => ` --font-${key}: ${value};`)\n .join(\"\\n\");\n\n return [colorVars, radiusVars, fontVars].filter(Boolean).join(\"\\n\");\n}\n\nexport function injectStyles(\n cssVariables: string,\n isDark: boolean,\n darkClass: string,\n targetElement: string\n): void {\n const styleId = \"react-theme-forge-styles\";\n let styleEl = document.getElementById(styleId) as HTMLStyleElement | null;\n\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = styleId;\n document.head.appendChild(styleEl);\n }\n\n const selector = targetElement !== \":root\" ? targetElement : \":root\";\n styleEl.textContent = `${selector} {\\n${cssVariables}\\n}`;\n}\n\nexport function mergeColors(\n base: ThemeColors,\n overrides: Partial<ThemeColors>\n): ThemeColors {\n return { ...base, ...overrides };\n}\n","import React, {\n createContext,\n useContext,\n useEffect,\n useState,\n useCallback,\n useMemo,\n useRef,\n} from \"react\";\n\nimport type {\n ThemeContextValue,\n ThemeMode,\n ThemeConfig,\n ThemeProviderProps,\n} from \"../types\";\n\nimport {\n defaultLightColors,\n defaultDarkColors,\n defaultRadius,\n defaultFonts,\n presetThemes,\n buildCSSVariables,\n injectStyles,\n mergeColors,\n} from \"../utils/themes\";\n\n// ─────────────────────────────────────────────\n// Context\n// ─────────────────────────────────────────────\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null);\n\n// ─────────────────────────────────────────────\n// Provider\n// ─────────────────────────────────────────────\n\nexport function ThemeProvider({\n children,\n defaultMode = \"system\",\n defaultTheme,\n storageKey = \"rtf-theme\",\n themes: initialThemes = [],\n darkClass = \"dark\",\n targetElement = \":root\",\n disablePersistence = false,\n}: ThemeProviderProps) {\n // ── Registered themes (presets + user-provided) ──\n const [themes, setThemes] = useState<Record<string, ThemeConfig>>(() => {\n const all: Record<string, ThemeConfig> = { ...presetThemes };\n initialThemes.forEach((t) => (all[t.name] = t));\n return all;\n });\n\n // ── Persist / restore from localStorage ──\n const getStored = <T,>(key: string, fallback: T): T => {\n if (disablePersistence || typeof window === \"undefined\") return fallback;\n try {\n const val = localStorage.getItem(`${storageKey}-${key}`);\n return val !== null ? (JSON.parse(val) as T) : fallback;\n } catch {\n return fallback;\n }\n };\n\n const setStored = (key: string, value: unknown) => {\n if (disablePersistence || typeof window === \"undefined\") return;\n try {\n localStorage.setItem(`${storageKey}-${key}`, JSON.stringify(value));\n } catch {}\n };\n\n const [mode, setModeState] = useState<ThemeMode>(() =>\n getStored(\"mode\", defaultMode)\n );\n\n const [activeTheme, setActiveTheme] = useState<string | null>(() =>\n getStored(\"activeTheme\", defaultTheme ?? null)\n );\n\n // ── Detect system preference ──\n const [systemPrefersDark, setSystemPrefersDark] = useState<boolean>(() => {\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const handler = (e: MediaQueryListEvent) => setSystemPrefersDark(e.matches);\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, []);\n\n // ── Resolved theme: light or dark ──\n const theme = useMemo<\"light\" | \"dark\">(() => {\n if (mode === \"system\") return systemPrefersDark ? \"dark\" : \"light\";\n return mode;\n }, [mode, systemPrefersDark]);\n\n // ── Apply CSS variables whenever theme/activeTheme changes ──\n const prevStyles = useRef<string>(\"\");\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n\n const isDark = theme === \"dark\";\n const customTheme = activeTheme ? themes[activeTheme] : null;\n\n // Merge default colors with custom theme overrides\n const lightColors = mergeColors(\n defaultLightColors,\n customTheme?.colors?.light ?? {}\n );\n const darkColors = mergeColors(\n defaultDarkColors,\n customTheme?.colors?.dark ?? {}\n );\n\n const activeColors = isDark ? darkColors : lightColors;\n const radius = { ...defaultRadius, ...(customTheme?.radius ?? {}) };\n const fonts = { ...defaultFonts, ...(customTheme?.fonts ?? {}) };\n\n const cssVars = buildCSSVariables(activeColors, radius, fonts);\n\n if (cssVars !== prevStyles.current) {\n injectStyles(cssVars, isDark, darkClass, targetElement);\n prevStyles.current = cssVars;\n }\n\n // Toggle dark class on <html>\n const root = document.documentElement;\n if (isDark) {\n root.classList.add(darkClass);\n } else {\n root.classList.remove(darkClass);\n }\n\n // Set data-theme attribute for debugging / CSS targeting\n root.setAttribute(\"data-theme\", activeTheme ?? \"default\");\n root.setAttribute(\"data-mode\", theme);\n }, [theme, activeTheme, themes, darkClass, targetElement]);\n\n // ─────────────────────────────────────────────\n // Actions\n // ─────────────────────────────────────────────\n\n const setMode = useCallback(\n (newMode: ThemeMode) => {\n setModeState(newMode);\n setStored(\"mode\", newMode);\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [storageKey, disablePersistence]\n );\n\n const toggleTheme = useCallback(() => {\n setMode(theme === \"dark\" ? \"light\" : \"dark\");\n }, [theme, setMode]);\n\n const applyTheme = useCallback(\n (themeName: string) => {\n setActiveTheme(themeName);\n setStored(\"activeTheme\", themeName);\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [storageKey, disablePersistence]\n );\n\n const registerTheme = useCallback((config: ThemeConfig) => {\n setThemes((prev) => ({ ...prev, [config.name]: config }));\n }, []);\n\n const removeTheme = useCallback((themeName: string) => {\n setThemes((prev) => {\n const next = { ...prev };\n delete next[themeName];\n return next;\n });\n setActiveTheme((prev) => (prev === themeName ? null : prev));\n }, []);\n\n const resetTheme = useCallback(() => {\n setActiveTheme(null);\n setModeState(defaultMode);\n setStored(\"activeTheme\", null);\n setStored(\"mode\", defaultMode);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [defaultMode, storageKey, disablePersistence]);\n\n // ─────────────────────────────────────────────\n // Context Value\n // ─────────────────────────────────────────────\n\n const value = useMemo<ThemeContextValue>(\n () => ({\n theme,\n mode,\n themes,\n activeTheme,\n toggleTheme,\n setMode,\n applyTheme,\n registerTheme,\n removeTheme,\n resetTheme,\n systemPrefersDark,\n }),\n [\n theme,\n mode,\n themes,\n activeTheme,\n toggleTheme,\n setMode,\n applyTheme,\n registerTheme,\n removeTheme,\n resetTheme,\n systemPrefersDark,\n ]\n );\n\n return (\n <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>\n );\n}\n\n// ─────────────────────────────────────────────\n// Hook\n// ─────────────────────────────────────────────\n\nexport function useTheme(): ThemeContextValue {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error(\n \"[react-theme-forge] useTheme must be used within a <ThemeProvider>.\"\n );\n }\n return context;\n}\n\nexport { ThemeContext };\n","import React from \"react\";\nimport { useTheme } from \"./ThemeProvider\";\n\n// ─────────────────────────────────────────────\n// SVG Icons\n// ─────────────────────────────────────────────\n\nconst SunIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <path d=\"M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\" />\n </svg>\n);\n\nconst MoonIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n </svg>\n);\n\nconst SystemIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\" />\n <line x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\" />\n <line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\" />\n </svg>\n);\n\n// ─────────────────────────────────────────────\n// ThemeToggle\n// ─────────────────────────────────────────────\n\nexport interface ThemeToggleProps {\n /** \"icon\" shows one button that toggles, \"segmented\" shows Light/Dark/System buttons */\n variant?: \"icon\" | \"segmented\";\n /** Additional CSS classes */\n className?: string;\n /** Size of the icon button. Default: \"md\" */\n size?: \"sm\" | \"md\" | \"lg\";\n /** Show label next to icon */\n showLabel?: boolean;\n /** Custom aria-label */\n ariaLabel?: string;\n}\n\nconst sizeMap = {\n sm: \"h-7 w-7 text-xs\",\n md: \"h-9 w-9 text-sm\",\n lg: \"h-11 w-11 text-base\",\n};\n\nexport function ThemeToggle({\n variant = \"icon\",\n className = \"\",\n size = \"md\",\n showLabel = false,\n ariaLabel,\n}: ThemeToggleProps) {\n const { theme, mode, toggleTheme, setMode } = useTheme();\n\n if (variant === \"segmented\") {\n return (\n <div\n className={`inline-flex items-center rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))] p-1 gap-1 ${className}`}\n role=\"group\"\n aria-label=\"Theme selector\"\n >\n {(\n [\n { value: \"light\", icon: <SunIcon />, label: \"Light\" },\n { value: \"dark\", icon: <MoonIcon />, label: \"Dark\" },\n { value: \"system\", icon: <SystemIcon />, label: \"System\" },\n ] as const\n ).map(({ value, icon, label }) => {\n const isActive = mode === value;\n return (\n <button\n key={value}\n onClick={() => setMode(value)}\n aria-pressed={isActive}\n className={[\n \"inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-all\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))]\",\n isActive\n ? \"bg-[hsl(var(--background))] text-[hsl(var(--foreground))] shadow-sm\"\n : \"text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]\",\n ].join(\" \")}\n >\n {icon}\n <span>{label}</span>\n </button>\n );\n })}\n </div>\n );\n }\n\n // Icon variant\n const label = ariaLabel ?? `Switch to ${theme === \"dark\" ? \"light\" : \"dark\"} mode`;\n\n return (\n <button\n onClick={toggleTheme}\n aria-label={label}\n className={[\n \"inline-flex items-center justify-center rounded-md\",\n \"text-[hsl(var(--foreground))] bg-transparent\",\n \"hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--accent-foreground))]\",\n \"border border-[hsl(var(--border))]\",\n \"transition-colors duration-200\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))]\",\n sizeMap[size],\n className,\n ].join(\" \")}\n >\n {theme === \"dark\" ? <SunIcon /> : <MoonIcon />}\n {showLabel && (\n <span className=\"ml-2 text-sm font-medium\">\n {theme === \"dark\" ? \"Light\" : \"Dark\"}\n </span>\n )}\n </button>\n );\n}\n\n// ─────────────────────────────────────────────\n// ThemePicker — choose from all available themes\n// ─────────────────────────────────────────────\n\nexport interface ThemePickerProps {\n className?: string;\n showPreview?: boolean;\n}\n\nexport function ThemePicker({ className = \"\", showPreview = true }: ThemePickerProps) {\n const { themes, activeTheme, applyTheme, resetTheme } = useTheme();\n\n const themeList = [\n { name: \"default\", label: \"Default\", primary: \"221 83% 53%\" },\n ...Object.values(themes).map((t) => ({\n name: t.name,\n label: t.name.charAt(0).toUpperCase() + t.name.slice(1),\n primary: t.colors?.light?.primary ?? \"221 83% 53%\",\n })),\n ];\n\n return (\n <div\n className={`flex flex-wrap gap-2 ${className}`}\n role=\"group\"\n aria-label=\"Theme picker\"\n >\n {themeList.map(({ name, label, primary }) => {\n const isActive = (activeTheme ?? \"default\") === name;\n return (\n <button\n key={name}\n onClick={() => (name === \"default\" ? resetTheme() : applyTheme(name))}\n aria-pressed={isActive}\n title={label}\n className={[\n \"inline-flex items-center gap-2 px-3 py-1.5 rounded-full text-sm font-medium\",\n \"border transition-all duration-200\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))]\",\n isActive\n ? \"border-[hsl(var(--primary))] text-[hsl(var(--primary))] bg-[hsl(var(--primary)/0.08)]\"\n : \"border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))] hover:border-[hsl(var(--primary)/0.5)]\",\n ].join(\" \")}\n >\n {showPreview && (\n <span\n className=\"inline-block w-3 h-3 rounded-full\"\n style={{ background: `hsl(${primary})` }}\n aria-hidden=\"true\"\n />\n )}\n {label}\n </button>\n );\n })}\n </div>\n );\n}\n","import { useCallback } from \"react\";\nimport { useTheme } from \"../components/ThemeProvider\";\n\n// ─────────────────────────────────────────────\n// useThemeColor\n// Returns a CSS variable value for any token\n// ─────────────────────────────────────────────\n\n/**\n * Get the resolved CSS variable value for a given token.\n *\n * @example\n * const primary = useThemeColor(\"primary\");\n * // Returns: \"hsl(var(--primary))\"\n *\n * const raw = useThemeColor(\"primary\", true);\n * // Returns: \"221 83% 53%\" (raw HSL parts, no wrapper)\n */\nexport function useThemeColor(token: string, raw = false): string {\n if (raw) {\n if (typeof document === \"undefined\") return \"\";\n const value = getComputedStyle(document.documentElement)\n .getPropertyValue(`--${token.replace(/([A-Z])/g, \"-$1\").toLowerCase()}`)\n .trim();\n return value;\n }\n return `hsl(var(--${token.replace(/([A-Z])/g, \"-$1\").toLowerCase()}))`;\n}\n\n// ─────────────────────────────────────────────\n// useIsDark\n// Simple boolean shortcut\n// ─────────────────────────────────────────────\n\n/**\n * @returns true when the resolved theme is \"dark\"\n */\nexport function useIsDark(): boolean {\n const { theme } = useTheme();\n return theme === \"dark\";\n}\n\n// ─────────────────────────────────────────────\n// useThemeValue\n// Returns a value based on current theme\n// ─────────────────────────────────────────────\n\n/**\n * Returns a value depending on the active theme.\n *\n * @example\n * const bg = useThemeValue(\"white\", \"gray-900\");\n */\nexport function useThemeValue<T>(lightValue: T, darkValue: T): T {\n const { theme } = useTheme();\n return theme === \"dark\" ? darkValue : lightValue;\n}\n\n// ─────────────────────────────────────────────\n// useThemeTransition\n// Smooth CSS transition helper\n// ─────────────────────────────────────────────\n\n/**\n * Temporarily adds a CSS transition to the document root\n * so theme changes animate smoothly.\n *\n * @example\n * const withTransition = useThemeTransition();\n * withTransition(() => applyTheme(\"ocean\"));\n */\nexport function useThemeTransition(duration = 300) {\n const withTransition = useCallback(\n (fn: () => void) => {\n if (typeof document === \"undefined\") {\n fn();\n return;\n }\n const style = document.createElement(\"style\");\n style.textContent = `*, *::before, *::after { transition: background-color ${duration}ms ease, color ${duration}ms ease, border-color ${duration}ms ease !important; }`;\n document.head.appendChild(style);\n fn();\n setTimeout(() => style.remove(), duration + 50);\n },\n [duration]\n );\n\n return withTransition;\n}\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|