charmbracelet / charmbracelet/bubbles
textinput: Distinguish between intermediate valid inputs and final valid inputs
- Dominant language
- Go
- Stars
- 8.9k
- Forks
- 457
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 5
Description
bubbletea and bubbles n00b here, so apologies if I'm holding something wrong.
I'm building on top of `textinput.Model` to provide a variety of more specific input models, e.g. reading an `int` or reading a choice from a list. My current code is in https://github.com/twpayne/chezmoi/pull/2359.
`textinput.Model` has a `Validate` function that checks whether or not the text within the input is valid. As far as I can tell, if, after pressing a key, the new value of the model is not valid then the key is discarded. This means that the value of the model is always valid, as defined by the `Validate` function returning `nil`.
This causes a problem if valid intermediate values are not also final valid values. For example, consider a `Validate` function that attempts to make a `textinput.Model` only accept integers:
```go
textInput := textinput.New()
textInput.Validate = func(s string) error {
_, err := strconv.Atoi(s)
return err
}
```
This fails for common intermediate states:
* The empty string (the initial value of the model) is not valid.
* The value consisting of just a minus sign `-` is not valid.
Both of these are necessary, valid intermediate states, but not valid final states.
For another example of valid intermediate states that are not final valid states, consider a country picker where the user has only to enter a unique country name prefix to chose the final country. `Un` is an intermediate step, but is not a valid final state as it does not differentiate between `United Kingdom` and `United States of America`.
Currently, the only option seems to be to write the `Validate` function so that it accepts intermediate values as well as final values, but this risks that the input is left in an invalid final value state.
A rough fix for this could be approximately:
* Add a `FinalValidateFunc` to `textinput.Model` that is used to validate the final state.
* Add a `Valid() bool` method to `textinput.Model` that returns whether the final state is valid. If `FinalValidateFunc` is nil then this always returns true.
This would maintain backwards compatibility for existing users, while also adding the ability to distinguish between intermediate valid inputs and final valid inputs. Let me know if you'd like a draft PR that implements this.
Contributor guide
Assessment
This issue has not been assessed yet.