styles.go

 1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
 2//
 3// SPDX-License-Identifier: AGPL-3.0-or-later
 4
 5// Package ui provides lipgloss styles for terminal output.
 6package ui
 7
 8import (
 9	"time"
10
11	"github.com/charmbracelet/lipgloss"
12	"github.com/klauspost/lctime"
13)
14
15// Style wraps lipgloss.Style to conditionally render based on output mode.
16type Style struct {
17	style lipgloss.Style
18}
19
20// Render applies the style to the given text, or returns plain text in plain mode.
21func (s Style) Render(strs ...string) string {
22	if IsPlain() {
23		result := ""
24		for _, str := range strs {
25			result += str
26		}
27
28		return result
29	}
30
31	return s.style.Render(strs...)
32}
33
34// Style returns the underlying lipgloss.Style for advanced use.
35func (s Style) Style() lipgloss.Style {
36	return s.style
37}
38
39// Terminal output styles using ANSI colors for broad compatibility.
40var (
41	Success = Style{lipgloss.NewStyle().Foreground(lipgloss.Color("2"))} // green
42	Warning = Style{lipgloss.NewStyle().Foreground(lipgloss.Color("3"))} // yellow
43	Error   = Style{lipgloss.NewStyle().Foreground(lipgloss.Color("1"))} // red
44	Bold    = Style{lipgloss.NewStyle().Bold(true)}
45)
46
47// Heading styles with backgrounds for contrast on any theme.
48var (
49	// H1 is the primary heading style (top-level items).
50	H1 = Style{lipgloss.NewStyle().
51		Bold(true).
52		Foreground(lipgloss.Color("0")).
53		Background(lipgloss.Color("4")).
54		Padding(0, 1)}
55	// H2 is the secondary heading style (nested items).
56	H2 = Style{lipgloss.NewStyle().
57		Bold(true).
58		Foreground(lipgloss.Color("0")).
59		Background(lipgloss.Color("6")).
60		Padding(0, 1)}
61)
62
63// FormatDate formats a time.Time as a date string using the user's locale.
64// Locale is auto-detected from LC_TIME, LC_ALL, or LANG environment variables.
65func FormatDate(t time.Time) string {
66	return lctime.Strftime("%x", t)
67}
68
69// TableHeaderStyle returns the style for table header rows.
70// Returns bold style in interactive mode, plain in non-interactive.
71func TableHeaderStyle() lipgloss.Style {
72	if IsPlain() {
73		return lipgloss.NewStyle()
74	}
75
76	return lipgloss.NewStyle().Bold(true)
77}
78
79// TableBorder returns the border style for tables.
80// Returns a normal border in interactive mode, hidden in non-interactive.
81func TableBorder() lipgloss.Border {
82	if IsPlain() {
83		return lipgloss.HiddenBorder()
84	}
85
86	return lipgloss.NormalBorder()
87}