-
Notifications
You must be signed in to change notification settings - Fork 139
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
feature suggestion: make callbacks configurable #280
feature suggestion: make callbacks configurable #280
Conversation
I plan on making a larger example for this during the weekend once I'm free from work, but curious to know what people think now. I'm on the fence about |
I like exposing the |
I think you're right. As of now I'm no longer using |
….mod (#60) [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [github.com/charmbracelet/huh](https://togithub.com/charmbracelet/huh) | `v0.4.2` -> `v0.5.1` | [![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2fcharmbracelet%2fhuh/v0.5.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/go/github.com%2fcharmbracelet%2fhuh/v0.5.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/go/github.com%2fcharmbracelet%2fhuh/v0.4.2/v0.5.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2fcharmbracelet%2fhuh/v0.4.2/v0.5.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>charmbracelet/huh (github.com/charmbracelet/huh)</summary> ### [`v0.5.1`](https://togithub.com/charmbracelet/huh/compare/v0.5.0...v0.5.1) [Compare Source](https://togithub.com/charmbracelet/huh/compare/v0.5.0...v0.5.1) ### [`v0.5.0`](https://togithub.com/charmbracelet/huh/releases/tag/v0.5.0) [Compare Source](https://togithub.com/charmbracelet/huh/compare/v0.4.2...v0.5.0) ### Dynamic Forms 🪄 <img width="600" src="https://vhs.charm.sh/vhs-6FRmBjNi2aiRb4INPXwIjo.gif" alt="Country / State form with dynamic inputs running."> `huh?` forms can now react to changes in other parts of the form. Replace properties such as `Options`, `Title`, `Description` with their dynamic counterparts: `OptionsFunc`, `TitleFunc`, and `DescriptionFunc` to recompute properties values on changes when watched variables change. Let’s build a simple state / province picker. ```go var country string var state string ``` The `country` select will be static, we’ll use this value to recompute the options and title for the next input. ```go huh.NewSelect[string](). Options(huh.NewOptions("United States", "Canada", "Mexico")...). Value(&country). Title("Country"). ``` Define your `Select` with `TitleFunc` and `OptionsFunc` and bind them to the `&country` value from the previous field. Whenever the user chooses a different country, the `TitleFunc` and `OptionsFunc` will be recomputed. > \[!IMPORTANT] > We have to pass `&country` as the binding to recompute the function only when > `country` changes, otherwise we will hit the API too often. ```go huh.NewSelect[string](). Value(&state). Height(8). TitleFunc(func() string { switch country { case "United States": return "State" case "Canada": return "Province" default: return "Territory" } }, &country). OptionsFunc(func() []huh.Option[string] { opts := fetchStatesForCountry(country) return huh.NewOptions(opts...) }, &country), ``` Lastly, run the `form` with these inputs. ```go err := form.Run() if err != nil { log.Fatal(err) } ``` ##### Other Changes #### What's Changed - Form Layouts by [@​adamdottv](https://togithub.com/adamdottv) in [https://github.com/charmbracelet/huh/pull/274](https://togithub.com/charmbracelet/huh/pull/274) - Resolve conflict between select and filter by [@​MikaelFangel](https://togithub.com/MikaelFangel) in [https://github.com/charmbracelet/huh/pull/252](https://togithub.com/charmbracelet/huh/pull/252) - Add `CursorText` style by [@​nervo](https://togithub.com/nervo) in [https://github.com/charmbracelet/huh/pull/259](https://togithub.com/charmbracelet/huh/pull/259) - Adjust input width to char limit by [@​nervo](https://togithub.com/nervo) in [https://github.com/charmbracelet/huh/pull/260](https://togithub.com/charmbracelet/huh/pull/260) - Implement `WithInput` by [@​Delta456](https://togithub.com/Delta456) in [https://github.com/charmbracelet/huh/pull/271](https://togithub.com/charmbracelet/huh/pull/271) - Implement WithTimeout by [@​Delta456](https://togithub.com/Delta456) in [https://github.com/charmbracelet/huh/pull/276](https://togithub.com/charmbracelet/huh/pull/276) - Set filtering state of select by [@​PJGaetan](https://togithub.com/PJGaetan) in [https://github.com/charmbracelet/huh/pull/179](https://togithub.com/charmbracelet/huh/pull/179) - `Filtering` on `Select` and `MultiSelect` fields by [@​maaslalani](https://togithub.com/maaslalani) in [https://github.com/charmbracelet/huh/pull/283](https://togithub.com/charmbracelet/huh/pull/283) - Introduce `accessor` by [@​nervo](https://togithub.com/nervo) in [https://github.com/charmbracelet/huh/pull/263](https://togithub.com/charmbracelet/huh/pull/263) - fix: aborting a form returning a timeout error by [@​Sculas](https://togithub.com/Sculas) in [https://github.com/charmbracelet/huh/pull/287](https://togithub.com/charmbracelet/huh/pull/287) #### New Contributors - [@​MikaelFangel](https://togithub.com/MikaelFangel) made their first contribution in [https://github.com/charmbracelet/huh/pull/252](https://togithub.com/charmbracelet/huh/pull/252) - [@​nervo](https://togithub.com/nervo) made their first contribution in [https://github.com/charmbracelet/huh/pull/253](https://togithub.com/charmbracelet/huh/pull/253) - [@​shedyfreak](https://togithub.com/shedyfreak) made their first contribution in [https://github.com/charmbracelet/huh/pull/230](https://togithub.com/charmbracelet/huh/pull/230) - [@​Delta456](https://togithub.com/Delta456) made their first contribution in [https://github.com/charmbracelet/huh/pull/271](https://togithub.com/charmbracelet/huh/pull/271) - [@​abradley2](https://togithub.com/abradley2) made their first contribution in [https://github.com/charmbracelet/huh/pull/280](https://togithub.com/charmbracelet/huh/pull/280) - [@​PJGaetan](https://togithub.com/PJGaetan) made their first contribution in [https://github.com/charmbracelet/huh/pull/179](https://togithub.com/charmbracelet/huh/pull/179) - [@​Sculas](https://togithub.com/Sculas) made their first contribution in [https://github.com/charmbracelet/huh/pull/287](https://togithub.com/charmbracelet/huh/pull/287) **Full Changelog**: charmbracelet/huh@v0.4.2...v0.5.0 *** <a href="https://charm.sh/"><img alt="The Charm logo" src="https://stuff.charm.sh/charm-badge.jpg" width="400"></a> Thoughts? Questions? We love hearing from you. Feel free to reach out on [Twitter](https://twitter.com/charmcli), [The Fediverse](https://mastodon.technology/@​charm), or [Slack](https://charm.sh/slack). </details> --- ### Configuration 📅 **Schedule**: Branch creation - "* */8 * * *" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/jippi/dottie). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MjUuMSIsInVwZGF0ZWRJblZlciI6IjM3LjQyNS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
I'm using
huh
to make some internal tooling with neat little TUI's.In this case, we have suite of tools that are their own individual
huh
forms. These can be used as top level forms, but I've also set things up in a way where forms can compose other forms that are otherwise top level. This uses a pattern commonly referred to as Nested Tea. Some of our tools are sometimes the top level form, other times they're forms within a form and this pattern makes them super composable.It's a bit tricky, to compose them in this way, however. It often involves a line that looks sort of like this:
The tricky part is
if-statements
in the control flow of update. Missing simple statements likem.subFormFoo = nil
can cause a bad loop. When callbacks are configurable things become much easier and everything can stay in the msg/update pattern:Initializing a new form in this way is pretty straight forward
Notice that in these cases we aren't using
form.Run()
to run a form because it's undesirable to have it calltea.Quit
when that form is submitted.For this reason it isn't necessary to use the
RunWithCallbacks
function I added here. That would be used for top level forms where we want to stay in the "TEA mode" when the form is exited.