Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can't use confirmation prompt as a bubbletea model #25

Closed
kalensk opened this issue Sep 19, 2023 · 6 comments
Closed

can't use confirmation prompt as a bubbletea model #25

kalensk opened this issue Sep 19, 2023 · 6 comments

Comments

@kalensk
Copy link

kalensk commented Sep 19, 2023

How can I use the confirmation prompt as a bubbletea model?

Specifically, can confirmation.New() return a tea.model?
Alternatively, I tried to do something like the following in my code but, validateKeyMap is not exported.

type Model struct {
	model  *confirmation.Confirmation
	result bool

	err error
}

func NewConfirmationPrompt(prompt string) Model {
	err := validateKeyMap(c.KeyMap)
	if err != nil {
		return false, fmt.Errorf("insufficient key map: %w", err)
	}

	m := NewModel(c)

	return Model{
		model: model,
		err:   nil,
	}
}
@erikgeiser
Copy link
Owner

Here is an example of the confirmation prompt as a bubbletea model/widget: https://github.com/erikgeiser/promptkit/blob/main/examples/bubbletea_widget/main.go

@kalensk
Copy link
Author

kalensk commented Sep 23, 2023

Thanks! After playing around some more, looking at your example, and getting more familiar with BubbleTea and promptkit I think I figured it all out.

I'll close this for now and if needed I can always re-open with a specific question or issue.

Thank you for a wonderful model! Super useful and looks good. : )

@kalensk kalensk closed this as completed Sep 23, 2023
@ryuheechul
Copy link

@erikgeiser https://github.com/erikgeiser/promptkit/blob/main/examples/bubbletea_widget/main.go uses Selection not Confirmation, no?

@kalensk do you mind sharing what you learned on how to fit Confirmation into bubbltea?

@kalensk
Copy link
Author

kalensk commented Sep 26, 2023

@ryuheechul Sure thing! Added #26 with an example for confirmation prompt. Feel free to not use the PR and close it since the example is so similar to the existing selection bubbletea example. I'll leave it to you.

@ryuheechul
Copy link

Thanks @kalensk! Now it's clear what I was doing wrong. I should have been looking for confirmation.Model.View but I was looking for confirmation.View instead. But that's crystal clear now thanks to your example code 👍🏼.

@kalensk
Copy link
Author

kalensk commented Sep 26, 2023

Glad you got it working!

I'll paste the example code for confirmation prompt here for others:

// Package main demonstrates how promptkit can be used as a bubbletea widget.
package main

import (
	"fmt"
	"os"
	"strings"

	tea "github.com/charmbracelet/bubbletea"

	"github.com/erikgeiser/promptkit"
	"github.com/erikgeiser/promptkit/confirmation"
)

type confirmationPrompt struct {
	prompt       string
	selection    bool
	confirmation *confirmation.Model
	err          error
}

func newConfirmationPrompt(prompt string) *confirmationPrompt {
	return &confirmationPrompt{prompt: prompt}
}

var _ tea.Model = &confirmationPrompt{}

func (c *confirmationPrompt) Init() tea.Cmd {
	// Here we show how to specify your own keyMap since the default uses left
	// and right arrow keys which you may already be using.
	keyMap := &confirmation.KeyMap{
		Yes:    []string{"y", "Y"},
		No:     []string{"n", "N"},
		Toggle: []string{"tab"},
		Submit: []string{"enter"},
		Abort:  []string{"ctrl+c"},
	}

	conf := &confirmation.Confirmation{
		Prompt:         c.prompt,
		DefaultValue:   confirmation.Undecided,
		Template:       confirmation.DefaultTemplate,
		ResultTemplate: confirmation.DefaultResultTemplate,
		KeyMap:         keyMap,
		WrapMode:       promptkit.Truncate,
	}
	c.confirmation = confirmation.NewModel(conf)

	return c.confirmation.Init()
}

func (c *confirmationPrompt) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	keyMsg, ok := msg.(tea.KeyMsg)
	if !ok {
		return c, nil
	}

	switch {
	case keyMsg.String() == "enter":
		selection, err := c.confirmation.Value()
		if err != nil {
			c.err = err
			return c, tea.Quit
		}

		c.selection = selection
	case keyMsg.String() == "esc":
		return c, tea.Quit
	default:
		_, cmd := c.confirmation.Update(msg)
		return c, cmd
	}

	return c, nil
}

func (c *confirmationPrompt) View() string {
	if c.err != nil {
		return fmt.Sprintf("Error: %v", c.err)
	}

	var b strings.Builder
	b.WriteString(c.confirmation.View())
	b.WriteString("\n=== You Chose: ===\n")
	b.WriteString(fmt.Sprintf("%t", c.selection))

	return b.String()
}

func main() {
	model := newConfirmationPrompt("Would you like to go shopping?")

	p := tea.NewProgram(model)

	_, err := p.Run()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v", err)

		os.Exit(1)
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants