internal/style/style.go (view raw)
1// Package style provides consistent text styling using lipgloss.
2// It respects the NO_COLOR environment variable (https://no-color.org/).
3package style
4
5import (
6 "fmt"
7 "os"
8
9 "github.com/charmbracelet/lipgloss"
10)
11
12// Italic returns an italic style.
13func Italic(text string) string {
14 return lipgloss.NewStyle().Italic(true).Render(text)
15}
16
17// Colour represents a lipgloss colour that can be applied.
18type Colour lipgloss.Color
19
20// ANSI colour codes (standard 8-colour palette).
21// Using ANSI escape codes for portability across terminals.
22var (
23 // Red for errors and warnings
24 Red = Colour("1")
25
26 // Green for success messages
27 Green = Colour("2")
28
29 // Blue for URLs
30 Blue = Colour("12")
31
32 // Magenta for labels and info
33 Magenta = Colour("5")
34
35 // Cyan for filepaths and values
36 Cyan = Colour("6")
37
38 // White for headings
39 White = Colour("15")
40
41 // BrightBlack is bright black for muted/debug text.
42 BrightBlack = Colour("8")
43)
44
45// NoColor returns true if the NO_COLOR environment variable is set.
46// This respects https://no-color.org/ standard.
47func NoColor() bool {
48 return os.Getenv("NO_COLOR") != ""
49}
50
51// Warning returns an orange and bold warning message.
52// Note: ANSI doesn't have orange, so we use red with bold styling.
53func Warning(text string) string {
54 if NoColor() {
55 return "WARNING: " + text
56 }
57 return lipgloss.NewStyle().
58 Foreground(lipgloss.Color(Red)).
59 Bold(true).
60 Render("WARNING: " + text)
61}
62
63// Warningf returns a formatted warning message.
64func Warningf(format string, args ...any) string {
65 return Warning(fmt.Sprintf(format, args...))
66}
67
68// Error returns a red and bold error message.
69func Error(text string) string {
70 if NoColor() {
71 return "ERROR: " + text
72 }
73 return lipgloss.NewStyle().
74 Foreground(lipgloss.Color(Red)).
75 Bold(true).
76 Render("ERROR: " + text)
77}
78
79// Errorf returns a formatted error message.
80func Errorf(format string, args ...any) string {
81 return Error(fmt.Sprintf(format, args...))
82}
83
84// Success returns a green success message.
85func Success(text string) string {
86 if NoColor() {
87 return "✓ " + text
88 }
89 return lipgloss.NewStyle().
90 Foreground(lipgloss.Color(Green)).
91 Bold(true).
92 Render("✓ " + text)
93}
94
95// Filepath returns a styled filepath in cyan.
96func Filepath(filepath string) string {
97 if NoColor() {
98 return filepath
99 }
100 return lipgloss.NewStyle().Foreground(lipgloss.Color(Cyan)).Render(filepath)
101}
102
103// FilepathStyled returns a lipgloss style for filepaths that can be applied to custom text.
104var FilepathStyled = lipgloss.NewStyle().Foreground(lipgloss.Color(Cyan))
105
106// URLStyled returns a lipgloss style for URLs that can be applied to custom text.
107var URLStyled = lipgloss.NewStyle().Foreground(lipgloss.Color(Blue)).Underline(true)
108
109// Label returns a styled label/key in magenta and bold.
110func Label(text string) string {
111 if NoColor() {
112 return lipgloss.NewStyle().Bold(true).Render(text)
113 }
114 return lipgloss.NewStyle().
115 Foreground(lipgloss.Color(Magenta)).
116 Bold(true).
117 Render(text)
118}
119
120// LabelStyled returns a lipgloss style for labels.
121var LabelStyled = lipgloss.NewStyle().Foreground(lipgloss.Color(Magenta)).Bold(true)
122
123// Heading returns a styled heading.
124func Heading(text string) string {
125 return lipgloss.NewStyle().Bold(true).Render(text)
126}
127
128// Value returns styled value text.
129func Value(text string) string {
130 if NoColor() {
131 return text
132 }
133 return lipgloss.NewStyle().Foreground(lipgloss.Color(Cyan)).Render(text)
134}
135
136// ValueStyled returns a lipgloss style for values.
137var ValueStyled = lipgloss.NewStyle().Foreground(lipgloss.Color(Cyan))
138
139// Info returns a styled info message in cyan.
140func Info(text string) string {
141 if NoColor() {
142 return "ℹ " + text
143 }
144 return lipgloss.NewStyle().Foreground(lipgloss.Color(Cyan)).Render("ℹ " + text)
145}
146
147// Debug returns a styled debug message in grey.
148func Debug(text string) string {
149 if NoColor() {
150 return lipgloss.NewStyle().Italic(true).Render("Debug: " + text)
151 }
152 return lipgloss.NewStyle().
153 Foreground(lipgloss.Color(BrightBlack)).
154 Italic(true).
155 Render("Debug: " + text)
156}
157
158// Debugf returns a formatted debug message.
159func Debugf(format string, args ...any) string {
160 return Debug(fmt.Sprintf(format, args...))
161}