51 lines
1.5 KiB
TypeScript
Executable File
51 lines
1.5 KiB
TypeScript
Executable File
import React, { createContext, useContext, useMemo, useState } from 'react';
|
|
import type { ThemeSeed, ThemeToken } from './types';
|
|
import { USAFSeed } from './constants';
|
|
import { createTailwindTheme, injectThemeVariables } from './styles';
|
|
import { generateTheme } from './generator';
|
|
interface ThemeContextValue {
|
|
token: ThemeToken
|
|
setTheme: (options: ThemeSeed) => void;
|
|
toggleDarkMode: () => void;
|
|
}
|
|
const ThemeContext = createContext<ThemeContextValue | null>(null);
|
|
export function ThemeProvider({
|
|
children,
|
|
seed = USAFSeed,
|
|
}: {
|
|
children: React.ReactNode;
|
|
seed?: ThemeSeed;
|
|
}) {
|
|
const [themeSeed, setThemeSeed] = useState<ThemeSeed>(seed);
|
|
const token = useMemo<ThemeToken>(() => {
|
|
|
|
const result = generateTheme(themeSeed)
|
|
console.log(createTailwindTheme(result))
|
|
|
|
injectThemeVariables(result)
|
|
return result.token;
|
|
}, [themeSeed]);
|
|
|
|
const contextValue = useMemo<ThemeContextValue>(
|
|
() => ({
|
|
token,
|
|
setTheme: setThemeSeed,
|
|
toggleDarkMode: () =>
|
|
setThemeSeed((prev) => ({ ...prev, isDark: !prev.isDark })),
|
|
}),
|
|
[token]
|
|
);
|
|
|
|
return (
|
|
<ThemeContext.Provider value={contextValue}>{children}</ThemeContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useTheme() {
|
|
const context = useContext(ThemeContext);
|
|
if (!context) {
|
|
throw new Error('useTheme must be used within a ThemeProvider');
|
|
}
|
|
return context;
|
|
}
|