styles.go

  1package styles
  2
  3import (
  4	"github.com/charmbracelet/bubbles/v2/filepicker"
  5	"github.com/charmbracelet/bubbles/v2/help"
  6	"github.com/charmbracelet/bubbles/v2/textarea"
  7	"github.com/charmbracelet/bubbles/v2/textinput"
  8	"github.com/charmbracelet/crush/internal/tui/exp/diffview"
  9	"github.com/charmbracelet/glamour/v2/ansi"
 10	"github.com/charmbracelet/lipgloss/v2"
 11	"github.com/charmbracelet/x/exp/charmtone"
 12)
 13
 14const (
 15	CheckIcon    string = "✓"
 16	ErrorIcon    string = "×"
 17	WarningIcon  string = "⚠"
 18	InfoIcon     string = "ⓘ"
 19	HintIcon     string = "∵"
 20	SpinnerIcon  string = "..."
 21	LoadingIcon  string = "⟳"
 22	DocumentIcon string = "🖼"
 23	ModelIcon    string = "◇"
 24
 25	ToolPending string = "●"
 26	ToolSuccess string = "✓"
 27	ToolError   string = "×"
 28
 29	BorderThin  string = "│"
 30	BorderThick string = "▌"
 31)
 32
 33type Styles struct {
 34	WindowTooSmall lipgloss.Style
 35
 36	// Reusable text styles
 37	Base   lipgloss.Style
 38	Muted  lipgloss.Style
 39	Subtle lipgloss.Style
 40
 41	// Tags
 42	TagBase  lipgloss.Style
 43	TagError lipgloss.Style
 44	TagInfo  lipgloss.Style
 45
 46	// Headers
 47	HeaderTool       lipgloss.Style
 48	HeaderToolNested lipgloss.Style
 49
 50	// Panels
 51	PanelMuted lipgloss.Style
 52	PanelBase  lipgloss.Style
 53
 54	// Line numbers for code blocks
 55	LineNumber lipgloss.Style
 56
 57	// Message borders
 58	FocusedMessageBorder lipgloss.Border
 59
 60	// Tool calls
 61	ToolCallPending   lipgloss.Style
 62	ToolCallError     lipgloss.Style
 63	ToolCallSuccess   lipgloss.Style
 64	ToolCallCancelled lipgloss.Style
 65	EarlyStateMessage lipgloss.Style
 66
 67	// Text selection
 68	TextSelection lipgloss.Style
 69
 70	// LSP and MCP status indicators
 71	ItemOfflineIcon lipgloss.Style
 72	ItemBusyIcon    lipgloss.Style
 73	ItemErrorIcon   lipgloss.Style
 74	ItemOnlineIcon  lipgloss.Style
 75
 76	// Markdown & Chroma
 77	Markdown ansi.StyleConfig
 78
 79	// Inputs
 80	TextInput textinput.Styles
 81	TextArea  textarea.Styles
 82
 83	// Help
 84	Help help.Styles
 85
 86	// Diff
 87	Diff diffview.Style
 88
 89	// FilePicker
 90	FilePicker filepicker.Styles
 91
 92	// Buttons
 93	ButtonSelected   lipgloss.Style
 94	ButtonUnselected lipgloss.Style
 95
 96	// Borders
 97	BorderFocus lipgloss.Style
 98	BorderBlur  lipgloss.Style
 99}
100
101func DefaultStyles() Styles {
102	var (
103		// primary   = charmtone.Charple
104		secondary = charmtone.Dolly
105		// tertiary  = charmtone.Bok
106		// accent    = charmtone.Zest
107
108		// Backgrounds
109		bgBase        = charmtone.Pepper
110		bgBaseLighter = charmtone.BBQ
111		bgSubtle      = charmtone.Charcoal
112		// bgOverlay     = charmtone.Iron
113
114		// Foregrounds
115		fgBase      = charmtone.Ash
116		fgMuted     = charmtone.Squid
117		fgHalfMuted = charmtone.Smoke
118		fgSubtle    = charmtone.Oyster
119		// fgSelected  = charmtone.Salt
120
121		// Borders
122		// border      = charmtone.Charcoal
123		borderFocus = charmtone.Charple
124
125		// Status
126		// success = charmtone.Guac
127		// error   = charmtone.Sriracha
128		// warning = charmtone.Zest
129		// info    = charmtone.Malibu
130
131		// Colors
132		white = charmtone.Butter
133
134		blueLight = charmtone.Sardine
135		blue      = charmtone.Malibu
136
137		// yellow = charmtone.Mustard
138		// citron = charmtone.Citron
139
140		green     = charmtone.Julep
141		greenDark = charmtone.Guac
142		// greenLight = charmtone.Bok
143
144		// red      = charmtone.Coral
145		redDark = charmtone.Sriracha
146		// redLight = charmtone.Salmon
147		// cherry   = charmtone.Cherry
148	)
149
150	s := Styles{}
151
152	// borders
153	s.FocusedMessageBorder = lipgloss.Border{Left: BorderThick}
154
155	// text presets
156	s.Base = lipgloss.NewStyle().Foreground(fgBase)
157	s.Muted = lipgloss.NewStyle().Foreground(fgMuted)
158	s.Subtle = lipgloss.NewStyle().Foreground(fgSubtle)
159
160	s.WindowTooSmall = s.Muted
161
162	// tag presets
163	s.TagBase = lipgloss.NewStyle().Padding(0, 1).Foreground(white)
164	s.TagError = s.TagBase.Background(redDark)
165	s.TagInfo = s.TagBase.Background(blueLight)
166
167	// headers
168	s.HeaderTool = lipgloss.NewStyle().Foreground(blue)
169	s.HeaderToolNested = lipgloss.NewStyle().Foreground(fgHalfMuted)
170
171	// panels
172	s.PanelMuted = s.Muted.Background(bgBaseLighter)
173	s.PanelBase = lipgloss.NewStyle().Background(bgBase)
174
175	// code line number
176	s.LineNumber = lipgloss.NewStyle().Foreground(fgMuted).Background(bgBase).PaddingRight(1).PaddingLeft(1)
177
178	// Tool calls
179	s.ToolCallPending = lipgloss.NewStyle().Foreground(greenDark).SetString(ToolPending)
180	s.ToolCallError = lipgloss.NewStyle().Foreground(redDark).SetString(ToolError)
181	s.ToolCallSuccess = lipgloss.NewStyle().Foreground(green).SetString(ToolSuccess)
182	// Cancelled uses muted tone but same glyph as pending
183	s.ToolCallCancelled = s.Muted.SetString(ToolPending)
184	s.EarlyStateMessage = s.Subtle.PaddingLeft(2)
185
186	// Buttons
187	s.ButtonSelected = lipgloss.NewStyle().Foreground(white).Background(secondary)
188	s.ButtonUnselected = s.Base.Background(bgSubtle)
189
190	// Borders
191	s.BorderFocus = lipgloss.NewStyle().BorderForeground(borderFocus).Border(lipgloss.RoundedBorder()).Padding(1, 2)
192
193	return s
194}