1package core
2
3import (
4 "image/color"
5 "strings"
6
7 "github.com/charmbracelet/lipgloss/v2"
8 "github.com/charmbracelet/x/ansi"
9 "github.com/opencode-ai/opencode/internal/tui/styles"
10)
11
12func Section(title string, width int) string {
13 t := styles.CurrentTheme()
14 char := "─"
15 length := len(title) + 1
16 remainingWidth := width - length
17 if remainingWidth > 0 {
18 title = title + " " + t.S().Base.Foreground(t.Border).Render(strings.Repeat(char, remainingWidth))
19 }
20 return title
21}
22
23type StatusOpts struct {
24 Icon string
25 IconColor color.Color
26 Title string
27 TitleColor color.Color
28 Description string
29 DescriptionColor color.Color
30}
31
32func Status(ops StatusOpts, width int) string {
33 t := styles.CurrentTheme()
34 icon := "●"
35 iconColor := t.Success
36 if ops.Icon != "" {
37 icon = ops.Icon
38 }
39 if ops.IconColor != nil {
40 iconColor = ops.IconColor
41 }
42 title := ops.Title
43 titleColor := t.FgMuted
44 if ops.TitleColor != nil {
45 titleColor = ops.TitleColor
46 }
47 description := ops.Description
48 descriptionColor := t.FgSubtle
49 if ops.DescriptionColor != nil {
50 descriptionColor = ops.DescriptionColor
51 }
52 icon = t.S().Base.Foreground(iconColor).Render(icon)
53 title = t.S().Base.Foreground(titleColor).Render(title)
54 if description != "" {
55 description = ansi.Truncate(description, width-lipgloss.Width(icon)-lipgloss.Width(title)-2, "…")
56 }
57 description = t.S().Base.Foreground(descriptionColor).Render(description)
58 return strings.Join([]string{
59 icon,
60 title,
61 description,
62 }, " ")
63}