tabs.go

 1package tabs
 2
 3import (
 4	"strings"
 5
 6	tea "github.com/charmbracelet/bubbletea"
 7	"github.com/charmbracelet/soft-serve/ui/common"
 8)
 9
10type ActiveTabMsg int
11
12type Tabs struct {
13	common    common.Common
14	tabs      []string
15	activeTab int
16}
17
18func New(c common.Common, tabs []string) *Tabs {
19	r := &Tabs{
20		common:    c,
21		tabs:      tabs,
22		activeTab: 0,
23	}
24	return r
25}
26
27func (t *Tabs) SetSize(width, height int) {
28	t.common.SetSize(width, height)
29}
30
31func (t *Tabs) Init() tea.Cmd {
32	t.activeTab = 0
33	return nil
34}
35
36func (t *Tabs) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
37	cmds := make([]tea.Cmd, 0)
38	switch msg := msg.(type) {
39	case tea.KeyMsg:
40		switch msg.String() {
41		case "tab":
42			t.activeTab = (t.activeTab + 1) % len(t.tabs)
43			cmds = append(cmds, t.activeTabCmd)
44		case "shift+tab":
45			t.activeTab = (t.activeTab - 1 + len(t.tabs)) % len(t.tabs)
46			cmds = append(cmds, t.activeTabCmd)
47		}
48	}
49	return t, tea.Batch(cmds...)
50}
51
52func (t *Tabs) View() string {
53	s := strings.Builder{}
54	sep := t.common.Styles.TabSeparator
55	for i, tab := range t.tabs {
56		style := t.common.Styles.TabInactive.Copy()
57		if i == t.activeTab {
58			style = t.common.Styles.TabActive.Copy()
59		}
60		s.WriteString(style.Render(tab))
61		if i != len(t.tabs)-1 {
62			s.WriteString(sep.String())
63		}
64	}
65	return s.String()
66}
67
68func (t *Tabs) activeTabCmd() tea.Msg {
69	return ActiveTabMsg(t.activeTab)
70}