Files
tasksquire/common/styles.go

178 lines
4.7 KiB
Go

package common
import (
"log/slog"
"strconv"
"strings"
// "github.com/charmbracelet/bubbles/table"
"github.com/charmbracelet/huh"
"github.com/charmbracelet/lipgloss"
"tasksquire/taskwarrior"
)
type TableStyle struct {
Header lipgloss.Style
Cell lipgloss.Style
Selected lipgloss.Style
}
type Styles struct {
Colors map[string]*lipgloss.Style
Base lipgloss.Style
Form *huh.Theme
TableStyle TableStyle
ColumnFocused lipgloss.Style
ColumnBlurred lipgloss.Style
ColumnInsert lipgloss.Style
}
func NewStyles(config *taskwarrior.TWConfig) *Styles {
styles := Styles{}
colors := make(map[string]*lipgloss.Style)
for key, value := range config.GetConfig() {
if strings.HasPrefix(key, "color.") {
_, color, _ := strings.Cut(key, ".")
colors[color] = parseColorString(value)
}
}
styles.Colors = colors
styles.Base = lipgloss.NewStyle()
styles.TableStyle = TableStyle{
// Header: lipgloss.NewStyle().Bold(true).Padding(0, 1).BorderBottom(true),
Cell: lipgloss.NewStyle().Padding(0, 1, 0, 0),
Header: lipgloss.NewStyle().Bold(true).Padding(0, 1, 0, 0).Underline(true),
Selected: lipgloss.NewStyle().Bold(true).Reverse(true),
}
formTheme := huh.ThemeBase()
formTheme.Focused.Title = formTheme.Focused.Title.Bold(true)
formTheme.Focused.SelectSelector = formTheme.Focused.SelectSelector.SetString("→ ")
formTheme.Focused.SelectedOption = formTheme.Focused.SelectedOption.Bold(true)
formTheme.Focused.MultiSelectSelector = formTheme.Focused.MultiSelectSelector.SetString("→ ")
formTheme.Focused.SelectedPrefix = formTheme.Focused.SelectedPrefix.SetString("✓ ")
formTheme.Focused.UnselectedPrefix = formTheme.Focused.SelectedPrefix.SetString("• ")
formTheme.Blurred.Title = formTheme.Blurred.Title.Bold(true)
formTheme.Blurred.SelectSelector = formTheme.Blurred.SelectSelector.SetString(" ")
formTheme.Blurred.SelectedOption = formTheme.Blurred.SelectedOption.Bold(true)
formTheme.Blurred.MultiSelectSelector = formTheme.Blurred.MultiSelectSelector.SetString(" ")
formTheme.Blurred.SelectedPrefix = formTheme.Blurred.SelectedPrefix.SetString("✓ ")
formTheme.Blurred.UnselectedPrefix = formTheme.Blurred.SelectedPrefix.SetString("• ")
styles.Form = formTheme
styles.ColumnFocused = lipgloss.NewStyle().Border(lipgloss.RoundedBorder(), true).Padding(1)
styles.ColumnBlurred = lipgloss.NewStyle().Border(lipgloss.HiddenBorder(), true).Padding(1)
styles.ColumnInsert = lipgloss.NewStyle().Border(lipgloss.RoundedBorder(), true).Padding(1)
if styles.Colors["active"] != nil {
styles.ColumnInsert = styles.ColumnInsert.BorderForeground(styles.Colors["active"].GetForeground())
}
return &styles
}
func parseColorString(color string) *lipgloss.Style {
if color == "" {
return nil
}
style := lipgloss.NewStyle()
if strings.Contains(color, "on") {
fgbg := strings.Split(color, "on")
fg := strings.TrimSpace(fgbg[0])
bg := strings.TrimSpace(fgbg[1])
if fg != "" {
style = style.Foreground(parseColor(fg))
}
if bg != "" {
style = style.Background(parseColor(bg))
}
} else {
style = style.Foreground(parseColor(strings.TrimSpace(color)))
}
return &style
}
func parseColor(color string) lipgloss.Color {
if strings.HasPrefix(color, "rgb") {
return lipgloss.Color(convertRgbToAnsi(strings.TrimPrefix(color, "rgb")))
}
if strings.HasPrefix(color, "color") {
return lipgloss.Color(strings.TrimPrefix(color, "color"))
}
if strings.HasPrefix(color, "gray") {
gray, err := strconv.Atoi(strings.TrimPrefix(color, "gray"))
if err != nil {
slog.Error("Invalid gray color format")
return lipgloss.Color("0")
}
return lipgloss.Color(strconv.Itoa(gray + 232))
}
if ansi, okcolor := colorStrings[color]; okcolor {
return lipgloss.Color(strconv.Itoa(ansi))
}
slog.Error("Invalid color format")
return lipgloss.Color("0")
}
func convertRgbToAnsi(rgbString string) string {
var err error
if len(rgbString) != 3 {
slog.Error("Invalid RGB color format")
return ""
}
r, err := strconv.Atoi(string(rgbString[0]))
if err != nil {
slog.Error("Invalid value for R")
return ""
}
g, err := strconv.Atoi(string(rgbString[1]))
if err != nil {
slog.Error("Invalid value for G")
return ""
}
b, err := strconv.Atoi(string(rgbString[2]))
if err != nil {
slog.Error("Invalid value for B")
return ""
}
return strconv.Itoa(16 + (36 * r) + (6 * g) + b)
}
var colorStrings = map[string]int{
"black": 0,
"red": 1,
"green": 2,
"yellow": 3,
"blue": 4,
"magenta": 5,
"cyan": 6,
"white": 7,
"bright black": 8,
"bright red": 9,
"bright green": 10,
"bright yellow": 11,
"bright blue": 12,
"bright magenta": 13,
"bright cyan": 14,
"bright white": 15,
}