/*
* Copyright (C) 2025 Jonni Liljamo <jonni@liljamo.com>
*
* This file is licensed under GPL-3.0-only, see NOTICE and LICENSE for
* more information.
*/
// Package confirm contains a confirm dialog component for Bubble Tea.
package confirm
import (
"strings"
"github.com/charmbracelet/bubbles/help"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
// Result is is a message containing the result of the confirm dialog.
type Result struct {
Choice bool
}
// Model is the Bubble Tea model for this confirm dialog component.
type Model struct {
keymap *KeyMap
help help.Model
dialogStyle lipgloss.Style
selectedYesStyle lipgloss.Style
selectedNoStyle lipgloss.Style
choice bool
}
// New returns a new Model.
func New() Model {
return Model{
keymap: NewKeyMap(),
help: help.New(),
dialogStyle: lipgloss.NewStyle().
AlignHorizontal(lipgloss.Center).
PaddingLeft(4),
selectedYesStyle: lipgloss.NewStyle().
Foreground(lipgloss.Color("113")),
selectedNoStyle: lipgloss.NewStyle().
Foreground(lipgloss.Color("167")),
choice: false,
}
}
// Init is part of the tea.Model interface.
func (m Model) Init() tea.Cmd {
return nil
}
// Update is part of the tea.Model interface.
func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case m.keymap.Submit.Keys()[0]:
return m, func() tea.Msg {
return Result{Choice: m.choice}
}
case m.keymap.Back.Keys()[0]:
return m, func() tea.Msg {
return Result{Choice: false}
}
case "left", "h", "right", "l":
m.choice = !m.choice
}
}
return m, nil
}
// View is part of the tea.Model interface.
func (m Model) View() string {
s := strings.Builder{}
dialog := strings.Builder{}
dialog.WriteString("Confirm: ")
if m.choice {
dialog.WriteString(" no")
dialog.WriteString(m.selectedYesStyle.Render(" >yes"))
} else {
dialog.WriteString(m.selectedNoStyle.Render(">no"))
dialog.WriteString(" yes")
}
dialog.WriteString("\n")
s.WriteString(m.dialogStyle.Render(dialog.String()))
s.WriteString(m.help.View(m.keymap))
return s.String()
}