1package tabs
2
3import (
4 "strings"
5
6 tea "github.com/charmbracelet/bubbletea"
7 "github.com/charmbracelet/soft-serve/ui/common"
8)
9
10// SelectTabMsg is a message that contains the index of the tab to select.
11type SelectTabMsg int
12
13// ActiveTabMsg is a message that contains the index of the current active tab.
14type ActiveTabMsg int
15
16// Tabs is bubbletea component that displays a list of tabs.
17type Tabs struct {
18 common common.Common
19 tabs []string
20 activeTab int
21}
22
23// New creates a new Tabs component.
24func New(c common.Common, tabs []string) *Tabs {
25 r := &Tabs{
26 common: c,
27 tabs: tabs,
28 activeTab: 0,
29 }
30 return r
31}
32
33// SetSize implements common.Component.
34func (t *Tabs) SetSize(width, height int) {
35 t.common.SetSize(width, height)
36}
37
38// Init implements tea.Model.
39func (t *Tabs) Init() tea.Cmd {
40 t.activeTab = 0
41 return nil
42}
43
44// Update implements tea.Model.
45func (t *Tabs) 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 "tab":
51 t.activeTab = (t.activeTab + 1) % len(t.tabs)
52 cmds = append(cmds, t.activeTabCmd)
53 case "shift+tab":
54 t.activeTab = (t.activeTab - 1 + len(t.tabs)) % len(t.tabs)
55 cmds = append(cmds, t.activeTabCmd)
56 }
57 case SelectTabMsg:
58 tab := int(msg)
59 if tab >= 0 && tab < len(t.tabs) {
60 t.activeTab = int(msg)
61 }
62 }
63 return t, tea.Batch(cmds...)
64}
65
66// View implements tea.Model.
67func (t *Tabs) View() string {
68 s := strings.Builder{}
69 sep := t.common.Styles.TabSeparator
70 for i, tab := range t.tabs {
71 style := t.common.Styles.TabInactive.Copy()
72 if i == t.activeTab {
73 style = t.common.Styles.TabActive.Copy()
74 }
75 s.WriteString(style.Render(tab))
76 if i != len(t.tabs)-1 {
77 s.WriteString(sep.String())
78 }
79 }
80 return s.String()
81}
82
83func (t *Tabs) activeTabCmd() tea.Msg {
84 return ActiveTabMsg(t.activeTab)
85}
86
87// SelectTabCmd is a bubbletea command that selects the tab at the given index.
88func SelectTabCmd(tab int) tea.Cmd {
89 return func() tea.Msg {
90 return SelectTabMsg(tab)
91 }
92}