
Some checks failed
GBCI / build (push) Failing after 10m45s
- Introduced a new CSS theme for Orange, featuring a modern color palette with distinct foreground and background colors. - Added an XTree Gold theme that emulates the classic 1980s DOS interface, complete with authentic colors and styles for file management elements. - Both themes include variables for customization and specific styles for various UI components such as cards, popovers, and menus.
95 lines
No EOL
3.4 KiB
TypeScript
95 lines
No EOL
3.4 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: 'orange', label: 'Orange', cssFile: '/themes/orange.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' },
|
|
{ name: 'xtreegold', label: 'XTreeGold', cssFile: '/themes/xtreegold.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
|
|
} |