leumas-private-shared
Version:
Private React JSX Package For Leumas Shared Components, Headers, Footers, Asides, Login Pages, API Key Manager and much more. Styles and everything reusable to avoid DRY code across all of our subdomains
87 lines (76 loc) • 2.56 kB
JSX
import React, { createContext, useContext, useState, useEffect } from 'react';
// Create a ThemeContext with a default value
const ThemeContext = createContext({
theme: 'light',
toggleTheme: () => {},
setColorPalette: () => {}
});
// Custom hook to use the ThemeContext
export const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) {
console.error('useTheme must be used within a ThemeProvider');
return {
theme: 'light',
toggleTheme: () => {},
setColorPalette: () => {}
};
}
return context;
};
// Higher-Order Component to check if ThemeContext exists
const withExistingThemeContext = (Component) => (props) => {
const existingContext = useContext(ThemeContext);
return (
<ThemeContext.Provider value={existingContext || {
theme: 'light',
toggleTheme: () => {},
setColorPalette: () => {}
}}>
<Component {...props} />
</ThemeContext.Provider>
);
};
// ThemeProvider component
const ThemeProvider = ({ children }) => {
const applyColorPalette = (palette) => {
palette.colors.forEach(color => {
if (color.hex) {
document.documentElement.style.setProperty(`--${color.type}-${color.hex.replace('#', '')}`, color.hex);
if (color.type === 'primary') {
document.documentElement.style.setProperty('--primary-color', color.hex);
}
if (color.type === 'secondary') {
document.documentElement.style.setProperty('--secondary-color', color.hex);
}
}
});
};
const [theme, setTheme] = useState(() => {
const savedTheme = localStorage.getItem('theme') || 'light';
const savedPalette = localStorage.getItem('selectedPalette');
if (savedPalette) {
const palette = JSON.parse(savedPalette);
applyColorPalette(palette);
}
return savedTheme;
});
useEffect(() => {
localStorage.setItem('theme', theme);
}, [theme]);
const toggleTheme = () => {
setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
};
const setColorPalette = (palette) => {
applyColorPalette(palette);
localStorage.setItem('selectedPalette', JSON.stringify(palette));
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme, setColorPalette }}>
<div className={`theme-transition theme-${theme}`}>
{children}
</div>
</ThemeContext.Provider>
);
};
export default withExistingThemeContext(ThemeProvider);