Have your user answer some questions in terminal.
This project intends to provide functionality similar to github.com/AlecAivazis/survey, but built on top of bubbletea.
This library provides the following bubbles:
input: single-line textual input with validationsselection: multi-selection with optional single-selectconfirm: a yes/no/undecided with multiple visual representations (input, horizontal/vertical selection)
The input bubble provides a minimal wrapper around github.com/charmbracelet/bubbles/textinput. You get all the implementation
of the upstream textinput bubble, with a little extra "flair" (a prompt prefix character, validations, suggestions). This allows for styling and functionality
more closely to what you might have had with github.com/AlecAivazis/survey.
Simple validation functions are supported:
m := input.New()
m.Prompt = "Please enter your name:"
m.Placeholder = "(first name only)"
m.Validate = func(v string) error {
if v != "" && !unicode.IsUpper(rune(v[0])) {
return errors.New("name must be uppercase")
}
return nil
}
p := tea.NewProgram(&m)Complex validations defined in the validate package are also supported. These functions chain together via validate.Func, and provide
a common variadic argument for custom error messages (similar to testify's assert functions).
Validation functions available include:
- MinLength: defines the minimum rune count
- MaxLength: defines the maximum rune count
- Matches: defines a regex pattern to match
- Contains: a wrapper around strings.Contains
- And: pass a custom function to the validation chain, in which the chain and function are all evaluated (like
&&) - Or: pass a custom function to the validation chain, in which the custom function is only evaluated if the preceding validation passes (like
||)
For example:
m := input.New()
m.Prompt = "Please enter your name:"
m.Placeholder = "(first name only)"
m.Validate = validate.NewValidation().
MinLength(2, "min: 2 characters").
MaxLength(5, "max: 8 characters").
And(func(input string) error {
for _, r := range input {
if !unicode.IsLetter(r) {
return errors.New("letters only")
}
}
return nil
}).
And(requireUppercase).
Build()
p := tea.NewProgram(&m)Suggestions can be applied via a set of static data using one of the provided text suggestion functions, or via a custom function allowing retrieval from any location such as an external datasource.
Provided suggestions include suggest.LevenshteinDistance and suggest.StartsWith, each with customizable options to optimize their behaviors.
To use suggest.LevenshteinDistance you can apply in the follow manner:
m := input.New()
m.Prompt = "Please enter your name:"
m.Placeholder = "(first name only)"
m.Suggest = suggest.LevenshteinDistance([]string{"Jim", "James", "Jameson"},
suggest.LevenshteinDistanceMin(0),
suggest.LevenshteinDistanceMax(4))To use a custom function, match the signature func(value string) []string. For example:
m := input.New()
m.Prompt = "Please enter your name:"
m.Placeholder = "(first name only)"
m.Suggest = func(value string) []string {
return []string{"A","B","C","D"}
}The selection bubble provides a paginated list of items from which the user can select 0 or more items. This bubble defaults
to multi-select, but can be made single-select by setting MaxSelections to 1. Styles, as well as indicators for prompt,
chooser, and selection are customizable.
See internal/examples/selection:
The confirm bubble provides a yes/no/undecided type of input. This is configurable to show the common terminal usability such as:
? Do you want to continue? y/N
Where the default value is indicated by an uppercase character. In this default rendering display, the user is able to
type either y or n (case insensitive) or hit enter to proceed with the default.
The confirm bubble also supports horizontal and vertical list-style selections.
Horizontal selection could be presented like:
? Prompt? ➤Yes No
Vertical selection could be presented like:
? Prompt?
➤ Yes
No
See internal/examples/confirm:
go get -u github.com/jimschubert/answer
go test -v -race -cover ./...This project is licensed under Apache 2.0.



