choice.go

 1package tui
 2
 3import (
 4	"fmt"
 5	"os"
 6
 7	"github.com/charmbracelet/bubbles/list"
 8	tea "github.com/charmbracelet/bubbletea"
 9	"github.com/charmbracelet/lipgloss"
10)
11
12type choiceModel struct {
13	list   list.Model
14	choice string
15}
16
17func (m choiceModel) Init() tea.Cmd {
18	return nil
19}
20
21func (m choiceModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
22	switch msg := msg.(type) {
23	case tea.KeyMsg:
24		switch keypress := msg.String(); keypress {
25		case "ctrl+c", "q":
26			return m, tea.Quit
27
28		case "enter":
29			i, ok := m.list.SelectedItem().(item)
30			if ok {
31				m.choice = string(i.title)
32			}
33			return m, tea.Quit
34		}
35	case tea.WindowSizeMsg:
36		h, v := DialogBoxStyle.GetFrameSize()
37		m.list.SetSize(msg.Width-h, msg.Height-v)
38	}
39
40	var cmd tea.Cmd
41	m.list, cmd = m.list.Update(msg)
42	return m, cmd
43}
44
45func (m choiceModel) View() string {
46	return DialogBoxStyle.Render(m.list.View())
47}
48
49type item struct {
50	title, desc string
51}
52
53func (i item) Title() string       { return i.title }
54func (i item) Description() string { return i.desc }
55func (i item) FilterValue() string { return i.title }
56
57func RunChoice() (string, error) {
58	items := []list.Item{
59		item{title: "send", desc: "Send a new email"},
60		item{title: "inbox", desc: "View your inbox"},
61	}
62
63	l := list.New(items, list.NewDefaultDelegate(), 0, 0)
64	l.Title = "What would you like to do?"
65	l.Styles.Title = lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Bold(true)
66
67	m := choiceModel{list: l}
68
69	p := tea.NewProgram(m, tea.WithAltScreen())
70
71	mod, err := p.Run()
72	if err != nil {
73		fmt.Println("Error running program:", err)
74		os.Exit(1)
75	}
76	if m, ok := mod.(choiceModel); ok && m.choice != "" {
77		return m.choice, nil
78	}
79	return "", fmt.Errorf("no choice made")
80}