1package selection
2
3import (
4 "smoothie/tui/style"
5
6 tea "github.com/charmbracelet/bubbletea"
7)
8
9type SelectedMsg struct {
10 Name string
11 Index int
12}
13
14type ActiveMsg struct {
15 Name string
16 Index int
17}
18
19type Bubble struct {
20 Items []string
21 SelectedItem int
22 styles *style.Styles
23}
24
25func NewBubble(items []string, styles *style.Styles) *Bubble {
26 return &Bubble{
27 Items: items,
28 styles: styles,
29 }
30}
31
32func (b *Bubble) Init() tea.Cmd {
33 return nil
34}
35
36func (b Bubble) View() string {
37 s := ""
38 for i, item := range b.Items {
39 if i == b.SelectedItem {
40 s += b.styles.MenuCursor.String()
41 s += b.styles.SelectedMenuItem.Render(item)
42 } else {
43 s += b.styles.MenuItem.Render(item)
44 }
45 if i < len(b.Items)-1 {
46 s += "\n"
47 }
48 }
49 return s
50}
51
52func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
53 cmds := make([]tea.Cmd, 0)
54 switch msg := msg.(type) {
55 case tea.KeyMsg:
56 switch msg.String() {
57 case "k", "up":
58 if b.SelectedItem > 0 {
59 b.SelectedItem--
60 cmds = append(cmds, b.sendActiveMessage)
61 }
62 case "j", "down":
63 if b.SelectedItem < len(b.Items)-1 {
64 b.SelectedItem++
65 cmds = append(cmds, b.sendActiveMessage)
66 }
67 case "enter":
68 cmds = append(cmds, b.sendSelectedMessage)
69 }
70 }
71 return b, tea.Batch(cmds...)
72}
73
74func (b *Bubble) sendActiveMessage() tea.Msg {
75 if b.SelectedItem >= 0 && b.SelectedItem < len(b.Items) {
76 return ActiveMsg{
77 Name: b.Items[b.SelectedItem],
78 Index: b.SelectedItem,
79 }
80 }
81 return nil
82}
83
84func (b *Bubble) sendSelectedMessage() tea.Msg {
85 if b.SelectedItem >= 0 && b.SelectedItem < len(b.Items) {
86 return SelectedMsg{
87 Name: b.Items[b.SelectedItem],
88 Index: b.SelectedItem,
89 }
90 }
91 return nil
92}