Documentation
¶
Overview ¶
Package styles defines the visual design system including color palettes, lipgloss styles, gradient tabs, and theme application for consistent UI rendering.
Index ¶
- Constants
- Variables
- func ApplyTheme(name string)
- func ApplyThemeColors(theme Theme)
- func ApplyThemeWithGenericOverrides(name string, overrides map[string]interface{})
- func ApplyThemeWithOverrides(name string, overrides map[string]string)
- func BgANSISeqFor(bgColor lipgloss.Color) string
- func CreateTDModalRenderer() monitor.ModalRenderer
- func CreateTDPanelRenderer() monitor.PanelRenderer
- func FillBackground(content string, width int, bgColor lipgloss.Color) string
- func GetCurrentThemeName() string
- func GetMarkdownTheme() string
- func GetSyntaxTheme() string
- func IsValidHexColor(hex string) bool
- func IsValidTheme(name string) bool
- func ListTabPresets() []string
- func ListThemes() []string
- func RGBToHex(c RGB) string
- func RegisterTheme(theme Theme)
- func RenderGradientBorder(content string, width, height int, gradient Gradient, padding int) string
- func RenderGradientTab(label string, tabIndex, totalTabs int, isActive bool) string
- func RenderPanel(content string, width, height int, active bool) string
- func RenderPanelWithGradient(content string, width, height int, gradient Gradient) string
- func RenderPill(text string, fg, bg, outerBg lipgloss.Color) string
- func RenderPillWithStyle(text string, style lipgloss.Style, outerBg lipgloss.Color) string
- func RenderTab(label string, tabIndex, totalTabs int, isActive bool, isPreview bool) string
- type ColorPalette
- type Gradient
- type GradientStop
- type RGB
- type TabThemePreset
- type Theme
Constants ¶
const ANSIReset = "\x1b[0m"
ANSIReset is the ANSI escape code to reset formatting.
const DefaultGradientAngle = 30.0
DefaultGradientAngle is the default angle for gradient borders (30 degrees).
Variables ¶
var ( // Primary colors Primary = lipgloss.Color("#7C3AED") // Purple Secondary = lipgloss.Color("#3B82F6") // Blue Accent = lipgloss.Color("#F59E0B") // Amber // Status colors Success = lipgloss.Color("#10B981") // Green Warning = lipgloss.Color("#F59E0B") // Amber Error = lipgloss.Color("#EF4444") // Red Info = lipgloss.Color("#3B82F6") // Blue // Text colors TextPrimary = lipgloss.Color("#F9FAFB") TextSecondary = lipgloss.Color("#9CA3AF") TextMuted = lipgloss.Color("#6B7280") TextSubtle = lipgloss.Color("#4B5563") TextSelectionColor = lipgloss.Color("#F9FAFB") // Text on selection backgrounds (BgTertiary) // Background colors BgPrimary = lipgloss.Color("#111827") BgSecondary = lipgloss.Color("#1F2937") BgTertiary = lipgloss.Color("#374151") BgOverlay = lipgloss.Color("#00000080") // Border colors BorderNormal = lipgloss.Color("#374151") BorderActive = lipgloss.Color("#7C3AED") BorderMuted = lipgloss.Color("#1F2937") // Diff foreground colors (also updated by ApplyTheme) DiffAddFg = lipgloss.Color("#10B981") DiffRemoveFg = lipgloss.Color("#EF4444") // Additional themeable colors TextHighlight = lipgloss.Color("#E5E7EB") // For subtitle, special text ButtonHoverColor = lipgloss.Color("#9D174D") // Button hover background TabTextInactiveColor = lipgloss.Color("#1a1a1a") // Inactive tab text LinkColor = lipgloss.Color("#60A5FA") // Hyperlink color ToastSuccessTextColor = lipgloss.Color("#000000") // Toast success foreground ToastErrorTextColor = lipgloss.Color("#FFFFFF") // Toast error foreground // Danger button colors DangerLight = lipgloss.Color("#FCA5A5") // Light red text DangerDark = lipgloss.Color("#7F1D1D") // Dark red background DangerBright = lipgloss.Color("#DC2626") // Bright red focused bg DangerHover = lipgloss.Color("#B91C1C") // Darker red hover bg TextInverse = lipgloss.Color("#FFFFFF") // Inverse/contrast text // Scrollbar colors (default to TextSubtle/TextMuted) ScrollbarTrackColor = lipgloss.Color("#4B5563") // Same as TextSubtle ScrollbarThumbColor = lipgloss.Color("#6B7280") // Same as TextMuted // Blame age gradient colors BlameAge1 = lipgloss.Color("#34D399") // < 1 week BlameAge2 = lipgloss.Color("#84CC16") // < 1 month BlameAge3 = lipgloss.Color("#FBBF24") // < 3 months BlameAge4 = lipgloss.Color("#F97316") // < 6 months BlameAge5 = lipgloss.Color("#9CA3AF") // < 1 year // Third-party theme names (updated by ApplyTheme) CurrentSyntaxTheme = "monokai" CurrentMarkdownTheme = "dark" )
Color palette - default dark theme
var ( CurrentTabStyle = "rainbow" CurrentTabColors = []RGB{{220, 60, 60}, {60, 220, 60}, {60, 60, 220}, {156, 60, 220}} // Default rainbow )
Tab theme state (updated by ApplyTheme)
var ( // Active panel with highlighted border PanelActive = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(BorderActive). Padding(0, 1) // Inactive panel with subtle border PanelInactive = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(BorderNormal). Padding(0, 1) // Panel header PanelHeader = lipgloss.NewStyle(). Bold(true). Foreground(TextPrimary). MarginBottom(1) // Panel with no border PanelNoBorder = lipgloss.NewStyle(). Padding(0, 1) )
Panel styles
var ( Title = lipgloss.NewStyle(). Bold(true). Foreground(TextPrimary) Subtitle = lipgloss.NewStyle(). Foreground(TextHighlight) // WorktreeIndicator shows the current worktree branch in the header WorktreeIndicator = lipgloss.NewStyle(). Foreground(Warning). Bold(true) Body = lipgloss.NewStyle(). Foreground(TextPrimary) Muted = lipgloss.NewStyle(). Foreground(TextMuted) Subtle = lipgloss.NewStyle(). Foreground(TextSubtle) Code = lipgloss.NewStyle(). Foreground(Accent) Link = lipgloss.NewStyle(). Foreground(LinkColor). Underline(true) KeyHint = lipgloss.NewStyle(). Foreground(TextMuted). Background(BgTertiary). Padding(0, 1) Logo = lipgloss.NewStyle(). Foreground(Primary). Bold(true) )
Text styles
var ( StatusStaged = lipgloss.NewStyle(). Foreground(Success). Bold(true) StatusModified = lipgloss.NewStyle(). Foreground(Warning). Bold(true) // Toast styles for status messages ToastSuccess = lipgloss.NewStyle(). Background(Success). Foreground(ToastSuccessTextColor). Bold(true). Padding(0, 1) ToastError = lipgloss.NewStyle(). Background(Error). Foreground(ToastErrorTextColor). Bold(true). Padding(0, 1) StatusUntracked = lipgloss.NewStyle(). Foreground(TextMuted) StatusDeleted = lipgloss.NewStyle(). Foreground(Error). Bold(true) StatusInProgress = lipgloss.NewStyle(). Foreground(Info). Bold(true) StatusCompleted = lipgloss.NewStyle(). Foreground(Success) StatusBlocked = lipgloss.NewStyle(). Foreground(Error) StatusPending = lipgloss.NewStyle(). Foreground(TextMuted) // Note status indicator styles StatusArchived = lipgloss.NewStyle(). Foreground(Info) StatusDeletedNote = lipgloss.NewStyle(). Foreground(Error) )
Status indicator styles
var ( ListItemNormal = lipgloss.NewStyle(). Foreground(TextPrimary) ListItemSelected = lipgloss.NewStyle(). Foreground(TextSelectionColor). Background(BgTertiary) ListItemFocused = lipgloss.NewStyle(). Foreground(TextPrimary). Background(Primary) ListCursor = lipgloss.NewStyle(). Foreground(Primary). Bold(true) )
List item styles
var ( BarTitle = lipgloss.NewStyle(). Foreground(TextPrimary). Bold(true) BarText = lipgloss.NewStyle(). Foreground(TextMuted) BarChip = lipgloss.NewStyle(). Foreground(TextMuted). Background(BgTertiary). Padding(0, 1) BarChipActive = lipgloss.NewStyle(). Foreground(TextPrimary). Background(Primary). Padding(0, 1). Bold(true) )
Bar element styles (shared by header/footer)
var ( DiffAdd = lipgloss.NewStyle(). Foreground(Success) DiffRemove = lipgloss.NewStyle(). Foreground(Error) DiffContext = lipgloss.NewStyle(). Foreground(TextMuted) DiffHeader = lipgloss.NewStyle(). Foreground(Info). Bold(true) // Subtle diff backgrounds for syntax-highlighted lines DiffAddBg = lipgloss.Color("#0D2818") // Very subtle dark green DiffRemoveBg = lipgloss.Color("#2D1A1A") // Very subtle dark red )
Diff line styles
var ( // Directory names - bold blue FileBrowserDir = lipgloss.NewStyle(). Foreground(Secondary). Bold(true) // Regular file names FileBrowserFile = lipgloss.NewStyle(). Foreground(TextPrimary) // Gitignored files - muted/dimmed FileBrowserIgnored = lipgloss.NewStyle(). Foreground(TextSubtle) // Line numbers in preview FileBrowserLineNumber = lipgloss.NewStyle(). Foreground(TextMuted). Width(5). AlignHorizontal(lipgloss.Right) // Tree icons (>, +) FileBrowserIcon = lipgloss.NewStyle(). Foreground(TextMuted) // Content search match highlighting SearchMatch = lipgloss.NewStyle(). Background(Warning) // Yellow background for all matches SearchMatchCurrent = lipgloss.NewStyle(). Background(Primary). Foreground(TextPrimary) // Fuzzy match character highlighting (bold in result list) FuzzyMatchChar = lipgloss.NewStyle(). Foreground(Primary). Bold(true) // Quick open result row (normal) QuickOpenItem = lipgloss.NewStyle(). Foreground(TextPrimary) // Quick open result row (selected) QuickOpenItemSelected = lipgloss.NewStyle(). Foreground(TextSelectionColor). Background(BgTertiary) // Palette entry styles (reusable for modals) PaletteEntry = lipgloss.NewStyle(). Foreground(TextPrimary) PaletteEntrySelected = lipgloss.NewStyle(). Foreground(TextSelectionColor). Background(BgTertiary) PaletteKey = lipgloss.NewStyle(). Foreground(TextMuted). Background(BgTertiary). Padding(0, 1) // Text selection for preview pane drag selection TextSelection = lipgloss.NewStyle(). Background(BgTertiary). Foreground(TextSelectionColor) )
File browser styles
var ( Foreground(TextMuted). Background(BgSecondary) Header = lipgloss.NewStyle(). Background(BgSecondary) )
Footer and header
var ( ModalOverlay = lipgloss.NewStyle(). Background(BgOverlay) ModalBox = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(Primary). Background(BgSecondary). Padding(1, 2) ModalTitle = lipgloss.NewStyle(). Foreground(TextPrimary). Bold(true). MarginBottom(1) )
Modal styles
var ( Button = lipgloss.NewStyle(). Foreground(TextSecondary). Background(BgTertiary). Padding(0, 2) ButtonFocused = lipgloss.NewStyle(). Foreground(TextPrimary). Background(Primary). Padding(0, 2). Bold(true) ButtonHover = lipgloss.NewStyle(). Foreground(TextPrimary). Background(ButtonHoverColor). Padding(0, 2) // Danger button styles (for destructive actions like delete) ButtonDanger = lipgloss.NewStyle(). Foreground(DangerLight). Background(DangerDark). Padding(0, 2) ButtonDangerFocused = lipgloss.NewStyle(). Foreground(TextInverse). Background(DangerBright). Padding(0, 2). Bold(true) ButtonDangerHover = lipgloss.NewStyle(). Foreground(TextInverse). Background(DangerHover). Padding(0, 2) )
Button styles
var ( // DefaultTheme is the current dark theme (backwards compatible) DefaultTheme = Theme{ Name: "default", DisplayName: "Default Dark", Colors: ColorPalette{ Primary: "#7C3AED", Secondary: "#3B82F6", Accent: "#F59E0B", Success: "#10B981", Warning: "#F59E0B", Error: "#EF4444", Info: "#3B82F6", TextPrimary: "#F9FAFB", TextSecondary: "#9CA3AF", TextMuted: "#6B7280", TextSubtle: "#4B5563", TextSelection: "#F9FAFB", BgPrimary: "#111827", BgSecondary: "#1F2937", BgTertiary: "#374151", BgOverlay: "#00000080", BorderNormal: "#374151", BorderActive: "#7C3AED", BorderMuted: "#1F2937", GradientBorderActive: []string{"#7C3AED", "#3B82F6"}, GradientBorderNormal: []string{"#374151", "#2D3748"}, GradientBorderAngle: 30.0, TabStyle: "rainbow", TabColors: []string{"#DC3C3C", "#3CDC3C", "#3C3CDC", "#9C3CDC"}, DiffAddFg: "#10B981", DiffAddBg: "#0D2818", DiffRemoveFg: "#EF4444", DiffRemoveBg: "#2D1A1A", TextHighlight: "#E5E7EB", ButtonHover: "#9D174D", TabTextInactive: "#1a1a1a", Link: "#60A5FA", ToastSuccessText: "#000000", ToastErrorText: "#FFFFFF", DangerLight: "#FCA5A5", DangerDark: "#7F1D1D", DangerBright: "#DC2626", DangerHover: "#B91C1C", TextInverse: "#FFFFFF", BlameAge1: "#34D399", BlameAge2: "#84CC16", BlameAge3: "#FBBF24", BlameAge4: "#F97316", BlameAge5: "#9CA3AF", SyntaxTheme: "monokai", MarkdownTheme: "dark", }, } // DraculaTheme is a Dracula-inspired dark theme with vibrant colors DraculaTheme = Theme{ Name: "dracula", DisplayName: "Dracula", Colors: ColorPalette{ Primary: "#BD93F9", Secondary: "#8BE9FD", Accent: "#FFB86C", Success: "#50FA7B", Warning: "#FFB86C", Error: "#FF5555", Info: "#8BE9FD", TextPrimary: "#F8F8F2", TextSecondary: "#BFBFBF", TextMuted: "#6272A4", TextSubtle: "#44475A", TextSelection: "#F8F8F2", BgPrimary: "#282A36", BgSecondary: "#343746", BgTertiary: "#44475A", BgOverlay: "#00000080", BorderNormal: "#44475A", BorderActive: "#BD93F9", BorderMuted: "#343746", GradientBorderActive: []string{"#BD93F9", "#8BE9FD"}, GradientBorderNormal: []string{"#44475A", "#383A4A"}, GradientBorderAngle: 30.0, TabStyle: "gradient", TabColors: []string{"#BD93F9", "#FF79C6", "#8BE9FD"}, DiffAddFg: "#50FA7B", DiffAddBg: "#1E3A29", DiffRemoveFg: "#FF5555", DiffRemoveBg: "#3D2A2A", TextHighlight: "#F8F8F2", ButtonHover: "#FF79C6", TabTextInactive: "#282A36", Link: "#8BE9FD", ToastSuccessText: "#282A36", ToastErrorText: "#F8F8F2", DangerLight: "#FFADAD", DangerDark: "#3D1F1F", DangerBright: "#FF5555", DangerHover: "#E63E3E", TextInverse: "#F8F8F2", BlameAge1: "#69FF94", BlameAge2: "#A4E22E", BlameAge3: "#FFB86C", BlameAge4: "#FF7979", BlameAge5: "#6272A4", SyntaxTheme: "dracula", MarkdownTheme: "dark", }, } // MolokaiTheme is a vibrant, high-contrast theme MolokaiTheme = Theme{ Name: "molokai", DisplayName: "Molokai", Colors: ColorPalette{ Primary: "#F92672", Secondary: "#66D9EF", Accent: "#A6E22E", Success: "#A6E22E", Warning: "#FD971F", Error: "#F92672", Info: "#66D9EF", TextPrimary: "#F8F8F2", TextSecondary: "#CFD0C2", TextMuted: "#75715E", TextSubtle: "#465457", TextSelection: "#F8F8F2", BgPrimary: "#1B1D1E", BgSecondary: "#272822", BgTertiary: "#3E3D32", BgOverlay: "#00000080", BorderNormal: "#465457", BorderActive: "#F92672", BorderMuted: "#3E3D32", GradientBorderActive: []string{"#F92672", "#A6E22E"}, GradientBorderNormal: []string{"#465457", "#3E3D32"}, GradientBorderAngle: 45.0, TabStyle: "solid", TabColors: []string{"#F92672"}, DiffAddFg: "#A6E22E", DiffAddBg: "#13210C", DiffRemoveFg: "#F92672", DiffRemoveBg: "#210C11", TextHighlight: "#E6DB74", ButtonHover: "#F92672", TabTextInactive: "#75715E", Link: "#66D9EF", ToastSuccessText: "#1B1D1E", ToastErrorText: "#F8F8F2", DangerLight: "#F8A0B8", DangerDark: "#3D0F1E", DangerBright: "#F92672", DangerHover: "#D91E63", TextInverse: "#F8F8F2", BlameAge1: "#A6E22E", BlameAge2: "#E6DB74", BlameAge3: "#FD971F", BlameAge4: "#F92672", BlameAge5: "#75715E", SyntaxTheme: "monokai", MarkdownTheme: "dark", }, } // NordTheme is an arctic, north-bluish color palette NordTheme = Theme{ Name: "nord", DisplayName: "Nord", Colors: ColorPalette{ Primary: "#88C0D0", Secondary: "#81A1C1", Accent: "#EBCB8B", Success: "#A3BE8C", Warning: "#EBCB8B", Error: "#BF616A", Info: "#88C0D0", TextPrimary: "#D8DEE9", TextSecondary: "#E5E9F0", TextMuted: "#4C566A", TextSubtle: "#434C5E", TextSelection: "#D8DEE9", BgPrimary: "#2E3440", BgSecondary: "#3B4252", BgTertiary: "#434C5E", BgOverlay: "#2E3440CC", BorderNormal: "#4C566A", BorderActive: "#88C0D0", BorderMuted: "#3B4252", GradientBorderActive: []string{"#88C0D0", "#81A1C1"}, GradientBorderNormal: []string{"#434C5E", "#3B4252"}, GradientBorderAngle: 120.0, TabStyle: "minimal", TabColors: []string{"#88C0D0"}, DiffAddFg: "#A3BE8C", DiffAddBg: "#233129", DiffRemoveFg: "#BF616A", DiffRemoveBg: "#312325", TextHighlight: "#ECEFF4", ButtonHover: "#5E81AC", TabTextInactive: "#4C566A", Link: "#88C0D0", ToastSuccessText: "#2E3440", ToastErrorText: "#E5E9F0", DangerLight: "#D08770", DangerDark: "#3B2A25", DangerBright: "#BF616A", DangerHover: "#A5545C", TextInverse: "#ECEFF4", BlameAge1: "#A3BE8C", BlameAge2: "#EBCB8B", BlameAge3: "#D08770", BlameAge4: "#BF616A", BlameAge5: "#4C566A", SyntaxTheme: "nord", MarkdownTheme: "dark", }, } // SolarizedDarkTheme is a precision color scheme SolarizedDarkTheme = Theme{ Name: "solarized-dark", DisplayName: "Solarized Dark", Colors: ColorPalette{ Primary: "#268BD2", Secondary: "#2AA198", Accent: "#B58900", Success: "#859900", Warning: "#B58900", Error: "#DC322F", Info: "#268BD2", TextPrimary: "#93A1A1", TextSecondary: "#839496", TextMuted: "#586E75", TextSubtle: "#073642", TextSelection: "#93A1A1", BgPrimary: "#002B36", BgSecondary: "#073642", BgTertiary: "#002B36", BgOverlay: "#00181ECC", BorderNormal: "#586E75", BorderActive: "#268BD2", BorderMuted: "#073642", GradientBorderActive: []string{"#268BD2", "#2AA198"}, GradientBorderNormal: []string{"#586E75", "#073642"}, GradientBorderAngle: 90.0, TabStyle: "solid", TabColors: []string{"#2AA198"}, DiffAddFg: "#859900", DiffAddBg: "#002B36", DiffRemoveFg: "#DC322F", DiffRemoveBg: "#002B36", TextHighlight: "#FDF6E3", ButtonHover: "#CB4B16", TabTextInactive: "#586E75", Link: "#268BD2", ToastSuccessText: "#FDF6E3", ToastErrorText: "#FDF6E3", DangerLight: "#E8A0A0", DangerDark: "#2A1515", DangerBright: "#DC322F", DangerHover: "#C12926", TextInverse: "#FDF6E3", BlameAge1: "#859900", BlameAge2: "#B58900", BlameAge3: "#CB4B16", BlameAge4: "#DC322F", BlameAge5: "#586E75", SyntaxTheme: "solarized-dark", MarkdownTheme: "dark", }, } // TokyoNightTheme is a clean, dark theme that celebrates the lights of Downtown Tokyo TokyoNightTheme = Theme{ Name: "tokyo-night", DisplayName: "Tokyo Night", Colors: ColorPalette{ Primary: "#7AA2F7", Secondary: "#BB9AF7", Accent: "#FF9E64", Success: "#9ECE6A", Warning: "#E0AF68", Error: "#F7768E", Info: "#7DCFFF", TextPrimary: "#C0CAF5", TextSecondary: "#A9B1D6", TextMuted: "#565F89", TextSubtle: "#414868", TextSelection: "#C0CAF5", BgPrimary: "#1A1B26", BgSecondary: "#24283B", BgTertiary: "#414868", BgOverlay: "#15161ECC", BorderNormal: "#565F89", BorderActive: "#7AA2F7", BorderMuted: "#24283B", GradientBorderActive: []string{"#7AA2F7", "#BB9AF7"}, GradientBorderNormal: []string{"#565F89", "#414868"}, GradientBorderAngle: 60.0, TabStyle: "gradient", TabColors: []string{"#7AA2F7", "#BB9AF7", "#F7768E"}, DiffAddFg: "#9ECE6A", DiffAddBg: "#283B4D", DiffRemoveFg: "#F7768E", DiffRemoveBg: "#3F2D3D", TextHighlight: "#C0CAF5", ButtonHover: "#BB9AF7", TabTextInactive: "#565F89", Link: "#73DACA", ToastSuccessText: "#15161E", ToastErrorText: "#C0CAF5", DangerLight: "#F7A8B8", DangerDark: "#2D1520", DangerBright: "#F7768E", DangerHover: "#E05F77", TextInverse: "#C0CAF5", BlameAge1: "#9ECE6A", BlameAge2: "#E0AF68", BlameAge3: "#FF9E64", BlameAge4: "#F7768E", BlameAge5: "#565F89", SyntaxTheme: "tokyo-night", MarkdownTheme: "dark", }, } )
Built-in themes
var PillTabsEnabled = false
PillTabsEnabled enables rounded pill-style tabs (requires Nerd Font)
var TabTextActive = lipgloss.NewStyle(). Foreground(TextPrimary). Bold(true)
TabTextActive is the text color for active tabs
var TabTextInactive = lipgloss.NewStyle(). Foreground(TabTextInactiveColor)
TabTextInactive is the text color for inactive tabs
var TabThemePresets = map[string]TabThemePreset{ "rainbow": { Name: "rainbow", DisplayName: "Rainbow", Style: "gradient", Colors: []string{"#DC3C3C", "#3CDC3C", "#3C3CDC", "#9C3CDC"}, }, "sunset": { Name: "sunset", DisplayName: "Sunset", Style: "gradient", Colors: []string{"#FF6B35", "#F7C59F", "#FF006E"}, }, "ocean": { Name: "ocean", DisplayName: "Ocean", Style: "gradient", Colors: []string{"#0077B6", "#00B4D8", "#90E0EF"}, }, "aurora": { Name: "aurora", DisplayName: "Aurora", Style: "gradient", Colors: []string{"#9D4EDD", "#5A189A", "#48BFE3"}, }, "neon": { Name: "neon", DisplayName: "Neon", Style: "gradient", Colors: []string{"#FF00FF", "#00FFFF", "#00FF00"}, }, "fire": { Name: "fire", DisplayName: "Fire", Style: "gradient", Colors: []string{"#FF4500", "#FF8C00", "#FFD700"}, }, "forest": { Name: "forest", DisplayName: "Forest", Style: "gradient", Colors: []string{"#2D5016", "#4C8B2F", "#A8E063"}, }, "candy": { Name: "candy", DisplayName: "Candy", Style: "gradient", Colors: []string{"#FF69B4", "#9370DB", "#40E0D0"}, }, "pastel": { Name: "pastel", DisplayName: "Pastel", Style: "per-tab", Colors: []string{"#FFB3BA", "#BAFFC9", "#BAE1FF", "#FFFFBA"}, }, "jewel": { Name: "jewel", DisplayName: "Jewel Tones", Style: "per-tab", Colors: []string{"#9B2335", "#0F4C81", "#5B5EA6", "#9C6644"}, }, "terminal": { Name: "terminal", DisplayName: "Terminal", Style: "per-tab", Colors: []string{"#FF5555", "#50FA7B", "#8BE9FD", "#F1FA8C"}, }, "mono": { Name: "mono", DisplayName: "Monochrome", Style: "solid", Colors: []string{}, }, "accent": { Name: "accent", DisplayName: "Accent", Style: "solid", Colors: []string{}, }, "underline": { Name: "underline", DisplayName: "Underline", Style: "minimal", Colors: []string{}, }, "dim": { Name: "dim", DisplayName: "Dim", Style: "minimal", Colors: []string{}, }, }
TabThemePresets contains all built-in tab theme presets
Functions ¶
func ApplyTheme ¶
func ApplyTheme(name string)
ApplyTheme applies a theme by name, updating all style variables
func ApplyThemeColors ¶
func ApplyThemeColors(theme Theme)
ApplyThemeColors updates all style package variables from a theme.
IMPORTANT: This function is NOT thread-safe for concurrent reads. It must only be called during initialization, before the TUI starts. The TUI's single-threaded Bubble Tea model ensures safe access after init.
func ApplyThemeWithGenericOverrides ¶
ApplyThemeWithGenericOverrides applies a theme with overrides that may include arrays. This supports gradient array overrides from YAML config.
func ApplyThemeWithOverrides ¶
ApplyThemeWithOverrides applies a theme with color overrides from config
func BgANSISeqFor ¶
BgANSISeqFor extracts the raw ANSI escape sequence for the given background color by rendering a marker character and taking everything before it.
func CreateTDModalRenderer ¶
func CreateTDModalRenderer() monitor.ModalRenderer
CreateTDModalRenderer creates a ModalRenderer that uses sidecar's gradient borders. Maps td monitor ModalType and depth values to appropriate gradients from the current theme.
func CreateTDPanelRenderer ¶
func CreateTDPanelRenderer() monitor.PanelRenderer
CreateTDPanelRenderer creates a PanelRenderer that uses sidecar's gradient borders. Maps td monitor PanelState values to appropriate gradients from the current theme.
func FillBackground ¶
FillBackground ensures each line has a uniform background color. Inner styled elements emit ANSI resets (\x1b[0m) that clear all attributes including the parent container's background, leaving terminal-default black for the remainder of the line. We fix this by re-applying the background ANSI sequence after every reset, then padding short lines with background-colored spaces.
func GetCurrentThemeName ¶
func GetCurrentThemeName() string
GetCurrentThemeName returns the name of the currently active theme
func GetMarkdownTheme ¶
func GetMarkdownTheme() string
GetMarkdownTheme returns the current markdown rendering theme name
func GetSyntaxTheme ¶
func GetSyntaxTheme() string
GetSyntaxTheme returns the current syntax highlighting theme name
func IsValidHexColor ¶
IsValidHexColor checks if a string is a valid hex color code (#RRGGBB or #RRGGBBAA)
func IsValidTheme ¶
IsValidTheme checks if a theme name exists in the registry
func ListTabPresets ¶
func ListTabPresets() []string
ListTabPresets returns the names of all available tab presets
func ListThemes ¶
func ListThemes() []string
ListThemes returns the names of all available themes in sorted order
func RegisterTheme ¶
func RegisterTheme(theme Theme)
RegisterTheme adds a custom theme to the registry
func RenderGradientBorder ¶
RenderGradientBorder renders content inside a box with gradient-colored borders. The gradient flows at the specified angle (typically 30 degrees). width and height are the outer dimensions including borders.
func RenderGradientTab ¶
RenderGradientTab renders a tab label with a gradient background. Kept for backwards compatibility - delegates to RenderTab.
func RenderPanel ¶
RenderPanel renders content in a panel with gradient borders. This is the main function plugins should use for bordered panels. active determines whether to use active (focused) or normal gradient. width and height are the outer dimensions including borders.
func RenderPanelWithGradient ¶
RenderPanelWithGradient renders content in a panel with a custom gradient. Useful for modals or special cases that need different gradient colors.
func RenderPill ¶
RenderPill renders text with pill-shaped caps when NerdFontsEnabled (PillTabsEnabled) is true. fg is the text color, bg is the pill background, outerBg is the surrounding background. If outerBg is empty, defaults to BgSecondary.
func RenderPillWithStyle ¶
RenderPillWithStyle renders text with pill-shaped caps using the provided lipgloss.Style. The style's background color is used for the pill caps. outerBg is the surrounding background; if empty, defaults to BgSecondary.
Types ¶
type ColorPalette ¶
type ColorPalette struct {
// Brand colors
Primary string `json:"primary"`
Secondary string `json:"secondary"`
Accent string `json:"accent"`
// Status colors
Success string `json:"success"`
Warning string `json:"warning"`
Error string `json:"error"`
Info string `json:"info"`
// Text colors
TextPrimary string `json:"textPrimary"`
TextSecondary string `json:"textSecondary"`
TextMuted string `json:"textMuted"`
TextSubtle string `json:"textSubtle"`
TextSelection string `json:"textSelection"` // Text on selection backgrounds (BgTertiary)
// Background colors
BgPrimary string `json:"bgPrimary"`
BgSecondary string `json:"bgSecondary"`
BgTertiary string `json:"bgTertiary"`
BgOverlay string `json:"bgOverlay"`
// Border colors
BorderNormal string `json:"borderNormal"`
BorderActive string `json:"borderActive"`
BorderMuted string `json:"borderMuted"`
// Gradient border colors (for angled gradient borders on panels)
GradientBorderActive []string `json:"gradientBorderActive"` // Colors for active panel gradient
GradientBorderNormal []string `json:"gradientBorderNormal"` // Colors for inactive panel gradient
GradientBorderAngle float64 `json:"gradientBorderAngle"` // Angle in degrees (default: 30)
// Tab theme configuration
TabStyle string `json:"tabStyle"` // "gradient", "per-tab", "solid", "minimal", or preset name
TabColors []string `json:"tabColors"` // Color stops for gradient OR per-tab colors
// Diff colors
DiffAddFg string `json:"diffAddFg"`
DiffAddBg string `json:"diffAddBg"`
DiffRemoveFg string `json:"diffRemoveFg"`
DiffRemoveBg string `json:"diffRemoveBg"`
// Additional UI colors
TextHighlight string `json:"textHighlight"` // For subtitle, special text
ButtonHover string `json:"buttonHover"` // Button hover state
TabTextInactive string `json:"tabTextInactive"` // Inactive tab text
Link string `json:"link"` // Hyperlink color
ToastSuccessText string `json:"toastSuccessText"` // Toast success foreground
ToastErrorText string `json:"toastErrorText"` // Toast error foreground
// Danger button colors (for destructive action buttons)
DangerLight string `json:"dangerLight"` // Light red for danger button text
DangerDark string `json:"dangerDark"` // Dark red for danger button background
DangerBright string `json:"dangerBright"` // Bright red for focused danger button bg
DangerHover string `json:"dangerHover"` // Darker red for hover danger button bg
TextInverse string `json:"textInverse"` // Inverse text (white on dark themes)
// Scrollbar colors
ScrollbarTrack string `json:"scrollbarTrack"` // Track color (default: TextSubtle)
ScrollbarThumb string `json:"scrollbarThumb"` // Thumb color (default: TextMuted)
// Blame age gradient colors (newest → oldest)
BlameAge1 string `json:"blameAge1"` // < 1 week (light green)
BlameAge2 string `json:"blameAge2"` // < 1 month (lime)
BlameAge3 string `json:"blameAge3"` // < 3 months (amber)
BlameAge4 string `json:"blameAge4"` // < 6 months (orange)
BlameAge5 string `json:"blameAge5"` // < 1 year (gray)
// Third-party theme names
SyntaxTheme string `json:"syntaxTheme"` // Chroma theme name
MarkdownTheme string `json:"markdownTheme"` // Glamour theme name
}
ColorPalette holds all theme colors
type Gradient ¶
type Gradient struct {
Stops []GradientStop
Angle float64 // degrees (0 = horizontal left-to-right, 90 = vertical top-to-bottom)
}
Gradient defines a multi-stop color gradient with angle support.
func GetActiveGradient ¶
func GetActiveGradient() Gradient
GetActiveGradient returns the gradient for active (focused) panels from current theme.
func GetFlashGradient ¶
func GetFlashGradient() Gradient
GetFlashGradient returns a warning-colored gradient for flash effects.
func GetInteractiveGradient ¶
func GetInteractiveGradient() Gradient
GetInteractiveGradient returns a gradient for interactive mode borders (td-70aed9). Uses warning/success colors to indicate the pane is receiving keyboard input.
func GetNormalGradient ¶
func GetNormalGradient() Gradient
GetNormalGradient returns the gradient for inactive panels from current theme.
func NewGradient ¶
NewGradient creates a gradient from a slice of hex color strings. Colors are evenly distributed from position 0.0 to 1.0.
func (*Gradient) PositionAt ¶
PositionAt calculates the gradient position for a coordinate given the angle. For a 30-degree angle, the gradient flows diagonally from top-left to bottom-right. Returns a value in range [0, 1].
type GradientStop ¶
GradientStop defines a color at a position (0.0 to 1.0)
type RGB ¶
type RGB struct {
R, G, B float64
}
RGB represents a color in RGB space for interpolation.
type TabThemePreset ¶
type TabThemePreset struct {
Name string // Internal name (e.g., "sunset")
DisplayName string // Display name (e.g., "Sunset")
Style string // "gradient", "per-tab", "solid", "minimal"
Colors []string // Hex colors for gradient stops or per-tab colors
}
TabThemePreset defines a named tab color scheme
func GetTabPreset ¶
func GetTabPreset(name string) *TabThemePreset
GetTabPreset returns a tab theme preset by name, or nil if not found
type Theme ¶
type Theme struct {
Name string `json:"name"`
DisplayName string `json:"displayName"`
Colors ColorPalette `json:"colors"`
}
Theme represents a complete theme configuration
func GetCurrentTheme ¶
func GetCurrentTheme() Theme
GetCurrentTheme returns the currently active theme