Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7cbb1db

Browse files
committed
chore(ui): use Lip Gloss for color blends
1 parent 15f20e6 commit 7cbb1db

4 files changed

Lines changed: 37 additions & 63 deletions

File tree

‎internal/ui/common/elements.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ func DialogTitle(t *styles.Styles, title string, width int, fromColor, toColor c
193193
remainingWidth := width - length
194194
if remainingWidth > 0 {
195195
lines := strings.Repeat(char, remainingWidth)
196-
lines = styles.ApplyForegroundGrad(t, lines, fromColor, toColor)
196+
lines = styles.ApplyForegroundGrad(t.Base, lines, fromColor, toColor)
197197
title = title + " " + lines
198198
}
199199
return title

‎internal/ui/logo/example/main.go‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ package main
33
import (
44
"fmt"
55
"math/rand/v2"
6+
"os"
67

78
"charm.land/lipgloss/v2"
89
"github.com/charmbracelet/crush/internal/ui/logo"
10+
"github.com/charmbracelet/crush/internal/ui/styles"
911
"github.com/charmbracelet/x/exp/slice"
12+
"github.com/charmbracelet/x/term"
1013
)
1114

1215
func renderLetterforms(stretch bool) string {
@@ -42,8 +45,26 @@ func renderLetterforms(stretch bool) string {
4245
}
4346

4447
func main() {
48+
w, _, err := term.GetSize(os.Stdout.Fd())
49+
if err != nil {
50+
fmt.Fprintf(os.Stderr, "Could not get terminal size: %s", err)
51+
}
52+
53+
s := styles.DefaultStyles()
54+
opts := logo.Opts{
55+
FieldColor: s.LogoFieldColor,
56+
TitleColorA: s.LogoTitleColorA,
57+
TitleColorB: s.LogoTitleColorB,
58+
CharmColor: s.LogoCharmColor,
59+
VersionColor: s.LogoVersionColor,
60+
Width: w,
61+
}
62+
63+
lipgloss.Println(logo.Render(s.Base, "v1.0.0", false, opts))
64+
lipgloss.Println(logo.Render(s.Base, "v1.0.0", true, opts))
65+
4566
fmt.Println(renderLetterforms(false))
46-
for range 10 {
67+
for range 5 {
4768
fmt.Println(renderLetterforms(true))
4869
}
4970
}

‎internal/ui/logo/logo.go‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,17 @@ type Opts struct {
2323
TitleColorA color.Color // left gradient ramp point
2424
TitleColorB color.Color // right gradient ramp point
2525
CharmColor color.Color // Charmâ„¢ text color
26-
VersionColor color.Color // Version text color
26+
VersionColor color.Color // version text color
2727
Width int // width of the rendered logo, used for truncation
28+
Hyper bool // whether it is Crush or Hypercrush
2829
}
2930

3031
// Render renders the Crush logo. Set the argument to true to render the narrow
3132
// version, intended for use in a sidebar.
3233
//
3334
// The compact argument determines whether it renders compact for the sidebar
3435
// or wider for the main pane.
35-
func Render(s *styles.Styles, version string, compact bool, o Opts) string {
36+
func Render(base lipgloss.Style, version string, compact bool, o Opts) string {
3637
const charm = " Charmâ„¢"
3738

3839
fg := func(c color.Color, s string) string {
@@ -52,12 +53,11 @@ func Render(s *styles.Styles, version string, compact bool, o Opts) string {
5253
if !compact {
5354
stretchIndex = cachedRandN(len(letterforms))
5455
}
55-
5656
crush := renderWord(spacing, stretchIndex, letterforms...)
5757
crushWidth := lipgloss.Width(crush)
5858
b := new(strings.Builder)
5959
for r := range strings.SplitSeq(crush, "\n") {
60-
fmt.Fprintln(b, styles.ApplyForegroundGrad(s, r, o.TitleColorA, o.TitleColorB))
60+
fmt.Fprintln(b, styles.ApplyForegroundGrad(base, r, o.TitleColorA, o.TitleColorB))
6161
}
6262
crush = b.String()
6363

@@ -117,7 +117,7 @@ func Render(s *styles.Styles, version string, compact bool, o Opts) string {
117117
// smaller windows or sidebar usage.
118118
func SmallRender(t *styles.Styles, width int) string {
119119
title := t.Base.Foreground(t.Secondary).Render("Charmâ„¢")
120-
title = fmt.Sprintf("%s %s", title, styles.ApplyBoldForegroundGrad(t, "Crush", t.Secondary, t.Primary))
120+
title = fmt.Sprintf("%s %s", title, styles.ApplyBoldForegroundGrad(t.Base, "Crush", t.Secondary, t.Primary))
121121
remainingWidth := width - lipgloss.Width(title) - 1 // 1 for the space after "Crush"
122122
if remainingWidth > 0 {
123123
lines := strings.Repeat("╱", remainingWidth)

‎internal/ui/styles/grad.go‎

Lines changed: 9 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ import (
55
"image/color"
66
"strings"
77

8-
"github.com/lucasb-eyer/go-colorful"
8+
"charm.land/lipgloss/v2"
99
"github.com/rivo/uniseg"
1010
)
1111

1212
// ForegroundGrad returns a slice of strings representing the input string
1313
// rendered with a horizontal gradient foreground from color1 to color2. Each
1414
// string in the returned slice corresponds to a grapheme cluster in the input
1515
// string. If bold is true, the rendered strings will be bolded.
16-
func ForegroundGrad(t *Styles, input string, bold bool, color1, color2 color.Color) []string {
16+
func ForegroundGrad(base lipgloss.Style, input string, bold bool, color1, color2 color.Color) []string {
1717
if input == "" {
1818
return []string{""}
1919
}
2020
if len(input) == 1 {
21-
style := t.Base.Foreground(color1)
21+
style := base.Foreground(color1)
2222
if bold {
2323
style.Bold(true)
2424
}
@@ -30,9 +30,9 @@ func ForegroundGrad(t *Styles, input string, bold bool, color1, color2 color.Col
3030
clusters = append(clusters, string(gr.Runes()))
3131
}
3232

33-
ramp := blendColors(len(clusters), color1, color2)
33+
ramp := lipgloss.Blend1D(len(clusters), color1, color2)
3434
for i, c := range ramp {
35-
style := t.Base.Foreground(c)
35+
style := base.Foreground(c)
3636
if bold {
3737
style.Bold(true)
3838
}
@@ -43,12 +43,12 @@ func ForegroundGrad(t *Styles, input string, bold bool, color1, color2 color.Col
4343

4444
// ApplyForegroundGrad renders a given string with a horizontal gradient
4545
// foreground.
46-
func ApplyForegroundGrad(t *Styles, input string, color1, color2 color.Color) string {
46+
func ApplyForegroundGrad(base lipgloss.Style, input string, color1, color2 color.Color) string {
4747
if input == "" {
4848
return ""
4949
}
5050
var o strings.Builder
51-
clusters := ForegroundGrad(t, input, false, color1, color2)
51+
clusters := ForegroundGrad(base, input, false, color1, color2)
5252
for _, c := range clusters {
5353
fmt.Fprint(&o, c)
5454
}
@@ -57,61 +57,14 @@ func ApplyForegroundGrad(t *Styles, input string, color1, color2 color.Color) st
5757

5858
// ApplyBoldForegroundGrad renders a given string with a horizontal gradient
5959
// foreground.
60-
func ApplyBoldForegroundGrad(t *Styles, input string, color1, color2 color.Color) string {
60+
func ApplyBoldForegroundGrad(base lipgloss.Style, input string, color1, color2 color.Color) string {
6161
if input == "" {
6262
return ""
6363
}
6464
var o strings.Builder
65-
clusters := ForegroundGrad(t, input, true, color1, color2)
65+
clusters := ForegroundGrad(base, input, true, color1, color2)
6666
for _, c := range clusters {
6767
fmt.Fprint(&o, c)
6868
}
6969
return o.String()
7070
}
71-
72-
// blendColors returns a slice of colors blended between the given keys.
73-
// Blending is done in Hcl to stay in gamut.
74-
func blendColors(size int, stops ...color.Color) []color.Color {
75-
if len(stops) < 2 {
76-
return nil
77-
}
78-
79-
stopsPrime := make([]colorful.Color, len(stops))
80-
for i, k := range stops {
81-
stopsPrime[i], _ = colorful.MakeColor(k)
82-
}
83-
84-
numSegments := len(stopsPrime) - 1
85-
blended := make([]color.Color, 0, size)
86-
87-
// Calculate how many colors each segment should have.
88-
segmentSizes := make([]int, numSegments)
89-
baseSize := size / numSegments
90-
remainder := size % numSegments
91-
92-
// Distribute the remainder across segments.
93-
for i := range numSegments {
94-
segmentSizes[i] = baseSize
95-
if i < remainder {
96-
segmentSizes[i]++
97-
}
98-
}
99-
100-
// Generate colors for each segment.
101-
for i := range numSegments {
102-
c1 := stopsPrime[i]
103-
c2 := stopsPrime[i+1]
104-
segmentSize := segmentSizes[i]
105-
106-
for j := range segmentSize {
107-
var t float64
108-
if segmentSize > 1 {
109-
t = float64(j) / float64(segmentSize-1)
110-
}
111-
c := c1.BlendHcl(c2, t)
112-
blended = append(blended, c)
113-
}
114-
}
115-
116-
return blended
117-
}

0 commit comments

Comments
 (0)