1package ui
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}