choice.go

 1package tui
 2
 3import (
 4	"fmt"
 5	"strings"
 6
 7	tea "github.com/charmbracelet/bubbletea"
 8	"github.com/charmbracelet/lipgloss"
 9)
10
11var (
12	// A more beautiful style for the main menu
13	docStyle = lipgloss.NewStyle().Margin(1, 2)
14
15	titleStyle = lipgloss.NewStyle().
16			Foreground(lipgloss.Color("#FFFDF5")).
17			Background(lipgloss.Color("#25A065")).
18			Padding(0, 1)
19
20	helpStyle = lipgloss.NewStyle().
21			Foreground(lipgloss.Color("241"))
22
23	// Styling for the choice list
24	listHeader = lipgloss.NewStyle().
25			Foreground(lipgloss.Color("241")).
26			PaddingBottom(1)
27
28	// Custom item styles
29	itemStyle         = lipgloss.NewStyle().PaddingLeft(2)
30	selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("205"))
31)
32
33type Choice struct {
34	cursor int
35}
36
37func NewChoice() Choice {
38	return Choice{cursor: 0}
39}
40
41func (m Choice) Init() tea.Cmd {
42	return nil
43}
44
45func (m Choice) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
46	switch msg := msg.(type) {
47	case tea.KeyMsg:
48		switch msg.String() {
49		case "up", "k":
50			if m.cursor > 0 {
51				m.cursor--
52			}
53		case "down", "j":
54			if m.cursor < 2 { // We have three choices now
55				m.cursor++
56			}
57		case "enter":
58			switch m.cursor {
59			case 0:
60				return m, func() tea.Msg { return GoToInboxMsg{} }
61			case 1:
62				return m, func() tea.Msg { return GoToSendMsg{} }
63			case 2:
64				return m, func() tea.Msg { return GoToSettingsMsg{} }
65			}
66		}
67	}
68	return m, nil
69}
70
71func (m Choice) View() string {
72	var b strings.Builder
73
74	// Title
75	b.WriteString(titleStyle.Render("Email CLI") + "\n\n")
76
77	// Header
78	b.WriteString(listHeader.Render("What would you like to do?"))
79	b.WriteString("\n\n")
80
81	// Choices
82	choices := []string{"View Inbox", "Compose Email", "Settings"}
83	for i, choice := range choices {
84		if m.cursor == i {
85			b.WriteString(selectedItemStyle.Render(fmt.Sprintf("> %s", choice)))
86		} else {
87			b.WriteString(itemStyle.Render(fmt.Sprintf("  %s", choice)))
88		}
89		b.WriteString("\n")
90	}
91
92	// Help
93	b.WriteString("\n\n")
94	b.WriteString(helpStyle.Render("Use ↑/↓ to navigate, enter to select, and q to quit."))
95
96	return docStyle.Render(b.String())
97}