1package selector
2
3import (
4 "github.com/charmbracelet/bubbles/key"
5 "github.com/charmbracelet/bubbles/list"
6 tea "github.com/charmbracelet/bubbletea"
7 "github.com/charmbracelet/soft-serve/ui/common"
8)
9
10type Selector struct {
11 list list.Model
12 common common.Common
13 active int
14}
15
16type SelectMsg string
17
18type ActiveMsg string
19
20func New(common common.Common, items []list.Item) *Selector {
21 l := list.New(items, ItemDelegate{common.Styles}, common.Width, common.Height)
22 l.SetShowTitle(false)
23 l.SetShowHelp(false)
24 l.SetShowStatusBar(false)
25 l.DisableQuitKeybindings()
26 s := &Selector{
27 list: l,
28 common: common,
29 }
30 s.SetSize(common.Width, common.Height)
31 return s
32}
33
34func (s *Selector) KeyMap() list.KeyMap {
35 return s.list.KeyMap
36}
37
38func (s *Selector) SetSize(width, height int) {
39 s.common.SetSize(width, height)
40 s.list.SetSize(width, height)
41}
42
43func (s *Selector) SetItems(items []list.Item) tea.Cmd {
44 return s.list.SetItems(items)
45}
46
47func (s *Selector) Index() int {
48 return s.list.Index()
49}
50
51func (s *Selector) Init() tea.Cmd {
52 return s.activeCmd
53}
54
55func (s *Selector) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
56 cmds := make([]tea.Cmd, 0)
57 switch msg := msg.(type) {
58 case tea.KeyMsg:
59 switch {
60 case key.Matches(msg, s.common.Keymap.Select):
61 cmds = append(cmds, s.selectCmd)
62 }
63 }
64 m, cmd := s.list.Update(msg)
65 s.list = m
66 if cmd != nil {
67 cmds = append(cmds, cmd)
68 }
69 // Send ActiveMsg when index change.
70 if s.active != s.list.Index() {
71 cmds = append(cmds, s.activeCmd)
72 }
73 s.active = s.list.Index()
74 return s, tea.Batch(cmds...)
75}
76
77func (s *Selector) View() string {
78 return s.list.View()
79}
80
81func (s *Selector) selectCmd() tea.Msg {
82 item := s.list.SelectedItem()
83 i := item.(Item)
84 return SelectMsg(i.Name)
85}
86
87func (s *Selector) activeCmd() tea.Msg {
88 item := s.list.SelectedItem()
89 i := item.(Item)
90 return ActiveMsg(i.Name)
91}