
Some checks failed
GBCI / build (push) Failing after 1m48s
- Updated the layout to integrate a new ThemeProvider component. - Removed the old ModeToggle component and integrated theme selection directly into the ThemeProvider. - Deleted unused SVG files (tauri.svg, vite.svg) and the old mode-toggle and theme-provider components. - Added a comprehensive ThemeProvider that supports multiple themes with corresponding CSS files. - Created new theme CSS files for various themes including RetroWave, CyberPunk, and more. - Updated tsconfig.json to include new component paths for better type checking. - Ensured the application loads the saved theme from localStorage on startup.
94 lines
No EOL
3.3 KiB
TypeScript
94 lines
No EOL
3.3 KiB
TypeScript
// themes/theme-provider.tsx
|
|
'use client'
|
|
|
|
import React, { createContext, useContext, useEffect, useState } from 'react'
|
|
|
|
type Theme = {
|
|
name: string
|
|
label: string
|
|
cssFile: string
|
|
}
|
|
|
|
const themes: Theme[] = [
|
|
{ name: 'retrowave', label: 'RetroWave', cssFile: '/themes/retrowave.css' },
|
|
{ name: '3dbevel', label: '3dbevel', cssFile: '/themes/3dbevel.css' },
|
|
{ name: 'arcadeflash', label: 'Arcadeflash', cssFile: '/themes/arcadeflash.css' },
|
|
{ name: 'cyberpunk', label: 'Cyberpunk', cssFile: '/themes/cyberpunk.css' },
|
|
{ name: 'discofever', label: 'Discofever', cssFile: '/themes/discofever.css' },
|
|
{ name: 'grungeera', label: 'Grungeera', cssFile: '/themes/grungeera.css' },
|
|
{ name: 'jazzage', label: 'Jazzage', cssFile: '/themes/jazzage.css' },
|
|
{ name: 'mellowgold', label: 'Mellowgold', cssFile: '/themes/mellowgold.css' },
|
|
{ name: 'midcenturymod', label: 'Midcenturymod', cssFile: '/themes/midcenturymod.css' },
|
|
{ name: 'oldhollywood', label: 'Oldhollywood', cssFile: '/themes/oldhollywood.css' },
|
|
{ name: 'polaroidmemories', label: 'Polaroidmemories', cssFile: '/themes/polaroidmemories.css' },
|
|
{ name: 'retrowave', label: 'Retrowave', cssFile: '/themes/retrowave.css' },
|
|
{ name: 'saturdaycartoons', label: 'Saturdaycartoons', cssFile: '/themes/saturdaycartoons.css' },
|
|
{ name: 'seasidepostcard', label: 'Seasidepostcard', cssFile: '/themes/seasidepostcard.css' },
|
|
{ name: 'typewriter', label: 'Typewriter', cssFile: '/themes/typewriter.css' },
|
|
{ name: 'vapordream', label: 'Vapordream', cssFile: '/themes/vapordream.css' },
|
|
{ name: 'xeroxui', label: 'Xeroxui', cssFile: '/themes/xeroxui.css' },
|
|
{ name: 'y2kglow', label: 'Y2kglow', cssFile: '/themes/y2kglow.css' }
|
|
|
|
]
|
|
|
|
type ThemeContextType = {
|
|
theme: Theme
|
|
setTheme: (themeName: string) => void
|
|
themes: Theme[]
|
|
}
|
|
|
|
const ThemeContext = createContext<ThemeContextType | undefined>(undefined)
|
|
|
|
export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
|
const [currentTheme, setCurrentTheme] = useState<Theme>(themes[0])
|
|
const [isLoaded, setIsLoaded] = useState(false)
|
|
|
|
useEffect(() => {
|
|
// Load saved theme from localStorage
|
|
const savedThemeName = localStorage.getItem('theme') || themes[0].name
|
|
const savedTheme = themes.find(t => t.name === savedThemeName) || themes[0]
|
|
setTheme(savedTheme.name)
|
|
setIsLoaded(true)
|
|
}, [])
|
|
|
|
const setTheme = (themeName: string) => {
|
|
const theme = themes.find(t => t.name === themeName)
|
|
if (!theme) return
|
|
|
|
// Remove any existing theme link
|
|
const existingLink = document.getElementById('theme-stylesheet')
|
|
if (existingLink) {
|
|
document.head.removeChild(existingLink)
|
|
}
|
|
|
|
// Create new link element
|
|
const link = document.createElement('link')
|
|
link.id = 'theme-stylesheet'
|
|
link.rel = 'stylesheet'
|
|
link.href = theme.cssFile
|
|
link.onload = () => {
|
|
setCurrentTheme(theme)
|
|
localStorage.setItem('theme', theme.name)
|
|
}
|
|
|
|
document.head.appendChild(link)
|
|
}
|
|
|
|
if (!isLoaded) {
|
|
return null // or loading spinner
|
|
}
|
|
|
|
return (
|
|
<ThemeContext.Provider value={{ theme: currentTheme, setTheme, themes }}>
|
|
{children}
|
|
</ThemeContext.Provider>
|
|
)
|
|
}
|
|
|
|
export function useTheme() {
|
|
const context = useContext(ThemeContext)
|
|
if (!context) {
|
|
throw new Error('useTheme must be used within a ThemeProvider')
|
|
}
|
|
return context
|
|
} |