Skip to content

Commit

Permalink
chore(examples): use lipgloss everywhere possible (#963)
Browse files Browse the repository at this point in the history
Lip Gloss abstracts away the color profiles logic and results in less
lines
  • Loading branch information
aymanbagabas committed Mar 22, 2024
1 parent 0ebbb19 commit a6f77ff
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 42 deletions.
11 changes: 5 additions & 6 deletions examples/altscreen-toggle/main.go
Expand Up @@ -5,13 +5,12 @@ import (
"os"

tea "github.com/charmbracelet/bubbletea"
"github.com/muesli/termenv"
"github.com/charmbracelet/lipgloss"
)

var (
color = termenv.EnvColorProfile().Color
keyword = termenv.Style{}.Foreground(color("204")).Background(color("235")).Styled
help = termenv.Style{}.Foreground(color("241")).Styled
keywordStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("204")).Background(lipgloss.Color("235"))
helpStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("241"))
)

type model struct {
Expand Down Expand Up @@ -61,8 +60,8 @@ func (m model) View() string {
mode = inlineMode
}

return fmt.Sprintf("\n\n You're in %s\n\n\n", keyword(mode)) +
help(" space: switch modes • q: exit\n")
return fmt.Sprintf("\n\n You're in %s\n\n\n", keywordStyle.Render(mode)) +
helpStyle.Render(" space: switch modes • q: exit\n")
}

func main() {
Expand Down
2 changes: 1 addition & 1 deletion examples/go.mod
Expand Up @@ -13,7 +13,6 @@ require (
github.com/lucasb-eyer/go-colorful v1.2.0
github.com/mattn/go-isatty v0.0.20
github.com/muesli/reflow v0.3.0
github.com/muesli/termenv v0.15.2
)

require (
Expand All @@ -32,6 +31,7 @@ require (
github.com/microcosm-cc/bluemonday v1.0.21 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/rivo/uniseg v0.4.6 // indirect
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect
Expand Down
6 changes: 0 additions & 6 deletions examples/simple/main_test.go
Expand Up @@ -8,15 +8,9 @@ import (
"time"

tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/x/exp/teatest"
"github.com/muesli/termenv"
)

func init() {
lipgloss.SetColorProfile(termenv.Ascii)
}

func TestApp(t *testing.T) {
m := model(10)
tm := teatest.NewTestModel(
Expand Down
52 changes: 23 additions & 29 deletions examples/views/main.go
Expand Up @@ -14,28 +14,30 @@ import (
"time"

tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/fogleman/ease"
"github.com/lucasb-eyer/go-colorful"
"github.com/muesli/reflow/indent"
"github.com/muesli/termenv"
)

const (
progressBarWidth = 71
progressFullChar = "█"
progressEmptyChar = "░"
dotChar = " • "
)

// General stuff for styling the view
var (
term = termenv.EnvColorProfile()
keyword = makeFgStyle("211")
subtle = makeFgStyle("241")
progressEmpty = subtle(progressEmptyChar)
dot = colorFg(" • ", "236")
keywordStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("211"))
subtleStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("241"))
ticksStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("79"))
checkboxStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("212"))
progressEmpty = subtleStyle.Render(progressEmptyChar)
dot = lipgloss.NewStyle().Foreground(lipgloss.Color("236")).Render(dotChar)

// Gradient colors we'll use for the progress bar
ramp = makeRamp("#B14FFF", "#00FFA3", progressBarWidth)
ramp = makeRampStyles("#B14FFF", "#00FFA3", progressBarWidth)
)

func main() {
Expand Down Expand Up @@ -183,7 +185,9 @@ func choicesView(m model) string {
tpl := "What to do today?\n\n"
tpl += "%s\n\n"
tpl += "Program quits in %s seconds\n\n"
tpl += subtle("j/k, up/down: select") + dot + subtle("enter: choose") + dot + subtle("q, esc: quit")
tpl += subtleStyle.Render("j/k, up/down: select") + dot +
subtleStyle.Render("enter: choose") + dot +
subtleStyle.Render("q, esc: quit")

choices := fmt.Sprintf(
"%s\n%s\n%s\n%s",
Expand All @@ -193,7 +197,7 @@ func choicesView(m model) string {
checkbox("See friends", c == 3),
)

return fmt.Sprintf(tpl, choices, colorFg(strconv.Itoa(m.Ticks), "79"))
return fmt.Sprintf(tpl, choices, ticksStyle.Render(strconv.Itoa(m.Ticks)))
}

// The second view, after a task has been chosen
Expand All @@ -202,26 +206,26 @@ func chosenView(m model) string {

switch m.Choice {
case 0:
msg = fmt.Sprintf("Carrot planting?\n\nCool, we'll need %s and %s...", keyword("libgarden"), keyword("vegeutils"))
msg = fmt.Sprintf("Carrot planting?\n\nCool, we'll need %s and %s...", keywordStyle.Render("libgarden"), keywordStyle.Render("vegeutils"))
case 1:
msg = fmt.Sprintf("A trip to the market?\n\nOkay, then we should install %s and %s...", keyword("marketkit"), keyword("libshopping"))
msg = fmt.Sprintf("A trip to the market?\n\nOkay, then we should install %s and %s...", keywordStyle.Render("marketkit"), keywordStyle.Render("libshopping"))
case 2:
msg = fmt.Sprintf("Reading time?\n\nOkay, cool, then we’ll need a library. Yes, an %s.", keyword("actual library"))
msg = fmt.Sprintf("Reading time?\n\nOkay, cool, then we’ll need a library. Yes, an %s.", keywordStyle.Render("actual library"))
default:
msg = fmt.Sprintf("It’s always good to see friends.\n\nFetching %s and %s...", keyword("social-skills"), keyword("conversationutils"))
msg = fmt.Sprintf("It’s always good to see friends.\n\nFetching %s and %s...", keywordStyle.Render("social-skills"), keywordStyle.Render("conversationutils"))
}

label := "Downloading..."
if m.Loaded {
label = fmt.Sprintf("Downloaded. Exiting in %s seconds...", colorFg(strconv.Itoa(m.Ticks), "79"))
label = fmt.Sprintf("Downloaded. Exiting in %s seconds...", ticksStyle.Render(strconv.Itoa(m.Ticks)))
}

return msg + "\n\n" + label + "\n" + progressbar(m.Progress) + "%"
}

func checkbox(label string, checked bool) string {
if checked {
return colorFg("[x] "+label, "212")
return checkboxStyle.Render("[x] " + label)
}
return fmt.Sprintf("[ ] %s", label)
}
Expand All @@ -232,7 +236,7 @@ func progressbar(percent float64) string {
fullSize := int(math.Round(w * percent))
var fullCells string
for i := 0; i < fullSize; i++ {
fullCells += termenv.String(progressFullChar).Foreground(term.Color(ramp[i])).String()
fullCells += ramp[i].Render(progressFullChar)
}

emptySize := int(w) - fullSize
Expand All @@ -243,29 +247,19 @@ func progressbar(percent float64) string {

// Utils

// Color a string's foreground with the given value.
func colorFg(val, color string) string {
return termenv.String(val).Foreground(term.Color(color)).String()
}

// Return a function that will colorize the foreground of a given string.
func makeFgStyle(color string) func(string) string {
return termenv.Style{}.Foreground(term.Color(color)).Styled
}

// Generate a blend of colors.
func makeRamp(colorA, colorB string, steps float64) (s []string) {
func makeRampStyles(colorA, colorB string, steps float64) (s []lipgloss.Style) {
cA, _ := colorful.Hex(colorA)
cB, _ := colorful.Hex(colorB)

for i := 0.0; i < steps; i++ {
c := cA.BlendLuv(cB, i/steps)
s = append(s, colorToHex(c))
s = append(s, lipgloss.NewStyle().Foreground(lipgloss.Color(colorToHex(c))))
}
return
}

// Convert a colorful.Color to a hexadecimal format compatible with termenv.
// Convert a colorful.Color to a hexadecimal format.
func colorToHex(c colorful.Color) string {
return fmt.Sprintf("#%s%s%s", colorFloatToHex(c.R), colorFloatToHex(c.G), colorFloatToHex(c.B))
}
Expand Down

0 comments on commit a6f77ff

Please sign in to comment.