Skip to content

Commit

Permalink
feat: allow to hide groups based on previous answers
Browse files Browse the repository at this point in the history
  • Loading branch information
caarlos0 authored and maaslalani committed Dec 1, 2023
1 parent aae2585 commit 17f85d1
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 1 deletion.
31 changes: 31 additions & 0 deletions examples/hide/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package main

import (
"fmt"

"github.com/charmbracelet/huh"
)

func main() {
var isAllergic bool
var allergies string

huh.NewForm(
huh.NewGroup(huh.NewNote().Title("Just for fun!")).WithHideFunc(func() bool { return true }),
huh.NewGroup(huh.NewNote().Title("Just for fun!")).WithHide(true),

huh.NewGroup(huh.NewConfirm().Title("Are you allergic to anything?").Value(&isAllergic)),
huh.NewGroup(
huh.NewText().
Title("Allergies").
Description("Please list all your allergies...").
Value(&allergies),
).WithHideFunc(func() bool {
return !isAllergic
}),
).Run()

if isAllergic {
fmt.Println(allergies)
}
}
21 changes: 21 additions & 0 deletions form.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ func (f *Form) Init() tea.Cmd {
for i, group := range f.groups {
cmds[i] = group.Init()
}

if f.isGroupHidden() {
cmds = append(cmds, nextGroup)
}

return tea.Batch(cmds...)
}

Expand Down Expand Up @@ -266,11 +271,19 @@ func (f *Form) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
f.paginator.NextPage()

if f.isGroupHidden() {
return f, nextGroup
}

case prevGroupMsg:
if len(group.Errors()) > 0 {
return f, nil
}
f.paginator.PrevPage()

if f.isGroupHidden() {
return f, prevGroup
}
}

m, cmd := group.Update(msg)
Expand All @@ -279,6 +292,14 @@ func (f *Form) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return f, cmd
}

func (f *Form) isGroupHidden() bool {
skip := f.groups[f.paginator.Page].hide
if skip == nil {
return false
}
return skip()
}

// View renders the form.
func (f *Form) View() string {
if f.quitting {
Expand Down
15 changes: 15 additions & 0 deletions group.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type Group struct {
width int
theme *Theme
keymap *KeyMap
hide func() bool
}

// NewGroup returns a new group with the given fields.
Expand Down Expand Up @@ -94,6 +95,20 @@ func (g *Group) WithWidth(width int) *Group {
return g
}

// WithHide sets whether this group should be skipped or not.
func (g *Group) WithHide(hide bool) *Group {
g.hide = func() bool {
return hide
}
return g
}

// WithHideFunc sets the function that checks if this group should be skipped.
func (g *Group) WithHideFunc(hideFunc func() bool) *Group {
g.hide = hideFunc
return g
}

// Errors returns the groups' fields' errors.
func (g *Group) Errors() []error {
var errs []error
Expand Down
41 changes: 40 additions & 1 deletion huh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestForm(t *testing.T) {
}

var taco Taco
var order = Order{Taco: taco}
order := Order{Taco: taco}

f := NewForm(
NewGroup(
Expand Down Expand Up @@ -443,6 +443,45 @@ func TestMultiSelect(t *testing.T) {
}
}

func TestSkipGroup(t *testing.T) {
f := NewForm(
NewGroup(
NewNote().
Description("Foo"),
).WithHide(true),

NewGroup(
NewNote().
Description("Bar"),
),

NewGroup(
NewNote().
Description("Baz"),
),

NewGroup(
NewNote().
Description("Qux"),
).WithHideFunc(func() bool {
return false
}).WithHide(true),
)
f.Update(f.Init())

if v := f.View(); !strings.Contains(v, "Bar") {
t.Log(pretty.Render(v))
t.Error("expected Bar to not be hidden")
}

f.Update(nextGroup())

if v := f.View(); !strings.Contains(v, "Baz") {
t.Log(pretty.Render(v))
t.Error("expected Baz to not be hidden")
}
}

func TestNote(t *testing.T) {
field := NewNote().Title("Taco").Description("How may we take your order?").Next(true)
f := NewForm(NewGroup(field))
Expand Down

0 comments on commit 17f85d1

Please sign in to comment.