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 ActiveMsg struct {
14 Name string
15 Index int
16}
17
18type Bubble struct {
19 NormalStyle lipgloss.Style
20 SelectedStyle lipgloss.Style
21 Items []string
22 selectedItem int
23}
24
25func NewBubble(items []string) *Bubble {
26 return &Bubble{
27 NormalStyle: normalStyle,
28 SelectedStyle: selectedStyle,
29 Items: items,
30 }
31}
32
33func (b *Bubble) Init() tea.Cmd {
34 return nil
35}
36
37func (b *Bubble) View() string {
38 s := ""
39 for i, item := range b.Items {
40 if i == b.selectedItem {
41 s += b.SelectedStyle.Render(item) + "\n"
42 } else {
43 s += b.NormalStyle.Render(item) + "\n"
44 }
45 }
46 return s
47}
48
49func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
50 cmds := make([]tea.Cmd, 0)
51 switch msg := msg.(type) {
52 case tea.KeyMsg:
53 switch msg.String() {
54 case "k", "up":
55 if b.selectedItem > 0 {
56 b.selectedItem--
57 cmds = append(cmds, b.sendActiveMessage)
58 }
59 case "j", "down":
60 if b.selectedItem < len(b.Items)-1 {
61 b.selectedItem++
62 cmds = append(cmds, b.sendActiveMessage)
63 }
64 case "enter":
65 cmds = append(cmds, b.sendSelectedMessage)
66 }
67 }
68 return b, tea.Batch(cmds...)
69}
70
71func (b *Bubble) sendActiveMessage() tea.Msg {
72 if b.selectedItem >= 0 && b.selectedItem < len(b.Items) {
73 return ActiveMsg{
74 Name: b.Items[b.selectedItem],
75 Index: b.selectedItem,
76 }
77 }
78 return nil
79}
80
81func (b *Bubble) sendSelectedMessage() tea.Msg {
82 if b.selectedItem >= 0 && b.selectedItem < len(b.Items) {
83 return SelectedMsg{
84 Name: b.Items[b.selectedItem],
85 Index: b.selectedItem,
86 }
87 }
88 return nil
89}