bubble.go

 1package selection
 2
 3import (
 4	tea "github.com/charmbracelet/bubbletea"
 5	"github.com/charmbracelet/lipgloss"
 6)
 7
 8type SelectedMsg struct {
 9	Name  string
10	Index int
11}
12
13type Bubble struct {
14	NormalStyle   lipgloss.Style
15	SelectedStyle lipgloss.Style
16	Items         []string
17	selectedItem  int
18}
19
20func NewBubble(items []string) *Bubble {
21	return &Bubble{
22		NormalStyle:   normalStyle,
23		SelectedStyle: selectedStyle,
24		Items:         items,
25		selectedItem:  -1,
26	}
27}
28
29func (b *Bubble) Init() tea.Cmd {
30	return nil
31}
32
33func (b *Bubble) View() string {
34	s := ""
35	for i, item := range b.Items {
36		if i == b.selectedItem {
37			s += b.SelectedStyle.Render(item) + "\n"
38		} else {
39			s += b.NormalStyle.Render(item) + "\n"
40		}
41	}
42	return s
43}
44
45func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
46	cmds := make([]tea.Cmd, 0)
47	switch msg := msg.(type) {
48	case tea.KeyMsg:
49		switch msg.String() {
50		case "k", "up":
51			if b.selectedItem > 0 {
52				b.selectedItem--
53			}
54		case "j", "down":
55			if b.selectedItem < len(b.Items)-1 {
56				b.selectedItem++
57			}
58		case "enter":
59			cmds = append(cmds, b.sendMessage)
60		}
61	}
62	return b, tea.Batch(cmds...)
63}
64
65func (b *Bubble) sendMessage() tea.Msg {
66	if b.selectedItem >= 0 && b.selectedItem < len(b.Items) {
67		return SelectedMsg{
68			Name:  b.Items[b.selectedItem],
69			Index: b.selectedItem,
70		}
71	}
72	return nil
73}