diff options
Diffstat (limited to 'internal/client/ui/choicepopup')
| -rw-r--r-- | internal/client/ui/choicepopup/choicepopup.go | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/internal/client/ui/choicepopup/choicepopup.go b/internal/client/ui/choicepopup/choicepopup.go new file mode 100644 index 0000000..a41abc9 --- /dev/null +++ b/internal/client/ui/choicepopup/choicepopup.go @@ -0,0 +1,92 @@ +package choicepopup + +import ( + "github.com/charmbracelet/bubbles/viewport" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" + + "github.com/kyren223/eko/pkg/assert" +) + +type Model struct { + Width int + Height int + + Dialogue viewport.Model + Cycle bool + + choices []string + index int + + SelectedStyle lipgloss.Style + UnselectedStyle lipgloss.Style + ChoicesStyle lipgloss.Style + Style lipgloss.Style +} + +func New(width, height int) Model { + return Model{ + Width: width, + Height: height, + Dialogue: viewport.New(0, 0), + } +} + +func (m Model) Init() tea.Cmd { + return nil +} + +func (m Model) View() string { + var choices []string + for i, choice := range m.choices { + if i == m.index { + choices = append(choices, m.SelectedStyle.Render(choice)) + } else { + choices = append(choices, m.UnselectedStyle.Render(choice)) + } + } + styledChoices := m.ChoicesStyle.MaxWidth(m.Width).MaxHeight(m.Height). + Render(lipgloss.JoinHorizontal(lipgloss.Center, choices...)) + + m.Dialogue.Width = m.Width + m.Dialogue.Height = m.Height - lipgloss.Height(styledChoices) + + popup := lipgloss.JoinVertical(lipgloss.Left, m.Dialogue.View(), styledChoices) + return m.Style.Render(popup) +} + +func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { + var cmd tea.Cmd + m.Dialogue, cmd = m.Dialogue.Update(msg) + return m, cmd +} + +func (m *Model) SetChoices(choices ...string) { + assert.Assert(len(choices) != 0, "choices must have at least 1 element") + m.choices = choices + m.index = 0 +} + +func (m *Model) ScrollLeft() { + if m.index == 0 { + if m.Cycle { + m.index = len(m.choices) - 1 + } + return + } + m.index-- +} + +func (m *Model) ScrollRight() { + if m.index == len(m.choices)-1 { + if m.Cycle { + m.index = 0 + } + return + } + m.index++ +} + +func (m Model) Select() (index int, choice string) { + return m.index, m.choices[m.index] +} |
