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	}
26}
27
28func (b *Bubble) Init() tea.Cmd {
29	return nil
30}
31
32func (b *Bubble) View() string {
33	s := ""
34	for i, item := range b.Items {
35		if i == b.selectedItem {
36			s += b.SelectedStyle.Render(item) + "\n"
37		} else {
38			s += b.NormalStyle.Render(item) + "\n"
39		}
40	}
41	return s
42}
43
44func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
45	cmds := make([]tea.Cmd, 0)
46	switch msg := msg.(type) {
47	case tea.KeyMsg:
48		switch msg.String() {
49		case "k", "up":
50			if b.selectedItem > 0 {
51				b.selectedItem--
52			}
53		case "j", "down":
54			if b.selectedItem < len(b.Items)-1 {
55				b.selectedItem++
56			}
57		case "enter":
58			cmds = append(cmds, b.sendMessage)
59		}
60	}
61	return b, tea.Batch(cmds...)
62}
63
64func (b *Bubble) sendMessage() tea.Msg {
65	if b.selectedItem >= 0 && b.selectedItem < len(b.Items) {
66		return SelectedMsg{
67			Name:  b.Items[b.selectedItem],
68			Index: b.selectedItem,
69		}
70	}
71	return nil
72}