Files
wg-admin/internal/tui/theme/theme.go
Calmcacil 26120b8bc2 Add WireGuard TUI implementation
- Add Go TUI with bubbletea for WireGuard management
- Implement client CRUD operations with QR code generation
- Add configuration and validation modules
- Install/update scripts for client setup
- Update Makefile to build binaries to bin/ directory
- Add .gitignore for Go projects
2026-01-12 19:03:35 +01:00

186 lines
4.5 KiB
Go

package theme
import (
"fmt"
"os"
"sync"
"github.com/charmbracelet/lipgloss"
)
// ColorScheme defines the color palette for the theme
type ColorScheme struct {
Primary lipgloss.Color
Success lipgloss.Color
Warning lipgloss.Color
Error lipgloss.Color
Muted lipgloss.Color
Background lipgloss.Color
}
// Theme represents a color theme with its name and color scheme
type Theme struct {
Name string
Scheme ColorScheme
}
// Global variables for current theme and styles
var (
currentTheme *Theme
once sync.Once
// Global styles that can be used throughout the application
StylePrimary lipgloss.Style
StyleSuccess lipgloss.Style
StyleWarning lipgloss.Style
StyleError lipgloss.Style
StyleMuted lipgloss.Style
StyleTitle lipgloss.Style
StyleSubtitle lipgloss.Style
StyleHelpKey lipgloss.Style
)
// DefaultTheme is the standard blue-based theme
var DefaultTheme = &Theme{
Name: "default",
Scheme: ColorScheme{
Primary: lipgloss.Color("62"), // Blue
Success: lipgloss.Color("46"), // Green
Warning: lipgloss.Color("208"), // Orange
Error: lipgloss.Color("196"), // Red
Muted: lipgloss.Color("241"), // Gray
Background: lipgloss.Color(""), // Default terminal background
},
}
// DarkTheme is a purple-based dark theme
var DarkTheme = &Theme{
Name: "dark",
Scheme: ColorScheme{
Primary: lipgloss.Color("141"), // Purple
Success: lipgloss.Color("51"), // Cyan
Warning: lipgloss.Color("226"), // Yellow
Error: lipgloss.Color("196"), // Red
Muted: lipgloss.Color("245"), // Light gray
Background: lipgloss.Color(""), // Default terminal background
},
}
// LightTheme is a green-based light theme
var LightTheme = &Theme{
Name: "light",
Scheme: ColorScheme{
Primary: lipgloss.Color("34"), // Green
Success: lipgloss.Color("36"), // Teal
Warning: lipgloss.Color("214"), // Amber
Error: lipgloss.Color("196"), // Red
Muted: lipgloss.Color("244"), // Gray
Background: lipgloss.Color(""), // Default terminal background
},
}
// ThemeRegistry holds all available themes
var ThemeRegistry = map[string]*Theme{
"default": DefaultTheme,
"dark": DarkTheme,
"light": LightTheme,
}
// GetTheme loads the theme from config or environment variable
// Returns the default theme if no theme is specified
func GetTheme() (*Theme, error) {
once.Do(func() {
// Try to get theme from environment variable first
themeName := os.Getenv("THEME")
if themeName == "" {
themeName = "default"
}
// Look up the theme in the registry
if theme, ok := ThemeRegistry[themeName]; ok {
currentTheme = theme
} else {
// If theme not found, use default
currentTheme = DefaultTheme
}
// Apply the theme to initialize styles
ApplyTheme(currentTheme)
})
return currentTheme, nil
}
// ApplyTheme applies the given theme to all global styles
func ApplyTheme(theme *Theme) {
currentTheme = theme
// Primary style
StylePrimary = lipgloss.NewStyle().
Foreground(theme.Scheme.Primary)
// Success style
StyleSuccess = lipgloss.NewStyle().
Foreground(theme.Scheme.Success)
// Warning style
StyleWarning = lipgloss.NewStyle().
Foreground(theme.Scheme.Warning)
// Error style
StyleError = lipgloss.NewStyle().
Foreground(theme.Scheme.Error)
// Muted style
StyleMuted = lipgloss.NewStyle().
Foreground(theme.Scheme.Muted)
// Title style (bold primary)
StyleTitle = lipgloss.NewStyle().
Foreground(theme.Scheme.Primary).
Bold(true)
// Subtitle style (muted)
StyleSubtitle = lipgloss.NewStyle().
Foreground(theme.Scheme.Muted)
// Help key style (bold primary, slightly different shade)
StyleHelpKey = lipgloss.NewStyle().
Foreground(theme.Scheme.Primary).
Bold(true)
}
// GetThemeNames returns a list of available theme names
func GetThemeNames() []string {
names := make([]string, 0, len(ThemeRegistry))
for name := range ThemeRegistry {
names = append(names, name)
}
return names
}
// SetTheme changes the current theme by name
func SetTheme(name string) error {
theme, ok := ThemeRegistry[name]
if !ok {
return fmt.Errorf("theme '%s' not found. Available themes: %v", name, GetThemeNames())
}
ApplyTheme(theme)
return nil
}
// GetCurrentTheme returns the currently active theme
func GetCurrentTheme() *Theme {
if currentTheme == nil {
currentTheme = DefaultTheme
ApplyTheme(currentTheme)
}
return currentTheme
}
// GetColorScheme returns the color scheme of the current theme
func GetColorScheme() ColorScheme {
return GetCurrentTheme().Scheme
}