1package styles
2
3import (
4 "fmt"
5 "image/color"
6 "strings"
7
8 "charm.land/lipgloss/v2"
9 "github.com/rivo/uniseg"
10)
11
12// ForegroundGrad returns a slice of strings representing the input string
13// rendered with a horizontal gradient foreground from color1 to color2. Each
14// string in the returned slice corresponds to a grapheme cluster in the input
15// string. If bold is true, the rendered strings will be bolded.
16func ForegroundGrad(base lipgloss.Style, input string, bold bool, color1, color2 color.Color) []string {
17 if input == "" {
18 return []string{""}
19 }
20 if len(input) == 1 {
21 style := base.Foreground(color1)
22 if bold {
23 style.Bold(true)
24 }
25 return []string{style.Render(input)}
26 }
27 var clusters []string
28 gr := uniseg.NewGraphemes(input)
29 for gr.Next() {
30 clusters = append(clusters, string(gr.Runes()))
31 }
32
33 ramp := lipgloss.Blend1D(len(clusters), color1, color2)
34 for i, c := range ramp {
35 style := base.Foreground(c)
36 if bold {
37 style.Bold(true)
38 }
39 clusters[i] = style.Render(clusters[i])
40 }
41 return clusters
42}
43
44// ApplyForegroundGrad renders a given string with a horizontal gradient
45// foreground.
46func ApplyForegroundGrad(base lipgloss.Style, input string, color1, color2 color.Color) string {
47 if input == "" {
48 return ""
49 }
50 var o strings.Builder
51 clusters := ForegroundGrad(base, input, false, color1, color2)
52 for _, c := range clusters {
53 fmt.Fprint(&o, c)
54 }
55 return o.String()
56}
57
58// ApplyBoldForegroundGrad renders a given string with a horizontal gradient
59// foreground.
60func ApplyBoldForegroundGrad(base lipgloss.Style, input string, color1, color2 color.Color) string {
61 if input == "" {
62 return ""
63 }
64 var o strings.Builder
65 clusters := ForegroundGrad(base, input, true, color1, color2)
66 for _, c := range clusters {
67 fmt.Fprint(&o, c)
68 }
69 return o.String()
70}