huhx

package module
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 23, 2026 License: MIT Imports: 10 Imported by: 0

README

huhx

ci Go Reference

CLIs built on huh break in CI, scripts, and agent-driven workflows. huh has no way to skip the TUI and accept answers programmatically, so every team that hits this hand-rolls the same workaround: parallel flag handling, TTY detection, duplicated validation logic, drifting code paths.

huhx fixes this. Build your form once. It runs as a beautiful TUI on a terminal and accepts CLI flags, environment variables, or YAML/JSON answer files everywhere else — CI pipelines, shell scripts, automated tooling.

Driving CLIs from agents. When an AI agent or orchestrator invokes your CLI as a subprocess, huhx accepts answers via --answer key=val flags, env vars, or an answer file — no TTY required and no separate code path to maintain. When the agent is itself a Go program embedding your form in-process, the same form can be driven via WithAnswers(map[string]any{...}). Both surfaces reuse every validator and every option the form already enforces. There is no separate "headless mode" — huhx is the same form.

The wrapper mirrors huh's full chainable API; existing huh code ports by changing import paths.

Install

go get github.com/cabljac/huhx

Quick start

package main

import (
    "fmt"
    "os"

    "charm.land/huh/v2"
    "github.com/cabljac/huhx"
    "github.com/spf13/cobra"
)

func main() {
    var (
        name        string
        environment string
        allRegions  bool
    )

    cmd := &cobra.Command{
        Use: "deploy",
        RunE: func(cmd *cobra.Command, args []string) error {
            form := huhx.NewForm(
                huhx.NewGroup(
                    huhx.NewInput().Key("name").Title("App name").Value(&name),
                    huhx.NewSelect[string]().Key("environment").Title("Environment").
                        Options(
                            huh.NewOption("staging", "staging"),
                            huh.NewOption("prod", "prod"),
                        ).Value(&environment),
                ),
                huhx.NewGroup(
                    huhx.NewConfirm().Key("all-regions").Title("Deploy to all regions?").Value(&allRegions),
                ).WithHideFunc(func() bool { return environment != "prod" }),
            )

            runner := huhx.New(form,
                huhx.WithEnvPrefix("DEPLOY"),
                huhx.WithCobraFlags(cmd),
            )
            return runner.Run()
        },
    }
    flags := cmd.Flags()
    flags.String("name", "", "")
    flags.String("environment", "", "")
    flags.Bool("all-regions", false, "")
    flags.StringArray("answer", nil, "additional key=val answers")
    flags.Bool("non-interactive", false, "force non-interactive mode")

    if err := cmd.Execute(); err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
}

Running the deploy example

# interactive
go run ./examples/deploy

# non-interactive
CI=1 go run ./examples/deploy \
  --answer name=myapp \
  --answer environment=prod \
  --answer all-regions=true

Mode selection

huhx.AutoDetect (default) picks non-interactive when any of:

  1. NON_INTERACTIVE=1 or CI=1 is set.
  2. stdin is not a TTY.
  3. --non-interactive flag is present on the wired cobra command.

Otherwise the runner delegates to huh.Form.Run().

Force the mode with huhx.WithNonInteractive(huhx.Always | huhx.Never).

Answer source precedence

When non-interactive, each field's answer is resolved in order:

  1. WithAnswers(map[string]any{...}) — programmatic injection.
  2. Cobra named flag matching the field key (e.g. --name).
  3. --answer key=val entries from a StringArray flag named answer.
  4. Answer file from WithAnswerFile(path) (YAML or JSON).
  5. Environment variable <PREFIX>_<KEY> (with WithEnvPrefix).
  6. Otherwise the field is reported as missing.

Field types

huhx wraps
Input *huh.Input
Text *huh.Text
Confirm *huh.Confirm
Select[T] *huh.Select[T]
MultiSelect[T] *huh.MultiSelect[T]

Each wrapper mirrors huh's chainable API. Validate(fn) stores the validator on the wrapper so it runs against headless-injected values without going through huh internals.

MultiSelect accepts comma-separated answers (a,b,c).

Confirm parses with strconv.ParseBool.

Static vs dynamic options

Select and MultiSelect support both:

  • Options(opts...) — static list captured at construction time.
  • OptionsFunc(f, bindings) — dynamic provider re-evaluated lazily at injection time. Useful when the available choices depend on an earlier field's value (e.g. State depending on Country).

When using OptionsFunc, the dependent field must live in a later group than its source field. The non-interactive runner walks groups in order and writes each field's value before later groups resolve, so closures capturing earlier-field pointers see the right values. This is the same constraint huh's interactive bindings machinery already enforces.

Calling Options(...) clears any prior OptionsFunc(...) and vice versa — last setter wins.

Conditional groups

Group.WithHide(bool) and Group.WithHideFunc(func() bool) skip the group in non-interactive mode and hide it in interactive mode. Both mirror huh's API exactly — WithHide takes a static bool, WithHideFunc takes a predicate re-evaluated at run time.

Missing-answer error

missing required answers for:
  --name        (env: DEPLOY_NAME)
  --environment (env: DEPLOY_ENVIRONMENT)

Migrating from huh

Migration is mostly mechanical — one decision per field.

1. Import + constructors
// before
import "charm.land/huh/v2"

form := huh.NewForm(
    huh.NewGroup(
        huh.NewInput().Title("Name").Value(&name),
    ),
)
if err := form.Run(); err != nil { ... }
// after
import (
    "charm.land/huh/v2"
    "github.com/cabljac/huhx"
)

form := huhx.NewForm(
    huhx.NewGroup(
        huhx.NewInput().Key("name").Title("Name").Value(&name),
    ),
)
runner := huhx.New(form,
    huhx.WithEnvPrefix("MYAPP"),
    huhx.WithCobraFlags(cmd), // if cobra is wired
)
if err := runner.Run(); err != nil { ... }

Keep huh.NewOption, huh.Option[T], huh.Accessor[T], theme types, etc. — huhx reuses huh's types unchanged.

2. The Key decision

Every field that should be drivable non-interactively needs a .Key(k). The key becomes the CLI flag name (--my-key), the environment variable suffix (PREFIX_MY_KEY), and the answer file key. Pick keys that read well as flags — lowercase, hyphen-separated.

huhx.NewInput().Key("repo-name").Title("Repository name").Value(&repoName)
// non-interactive: --answer repo-name=...   MYAPP_REPO_NAME=...

Fields without .Key() still work in interactive mode — huhx forwards them to huh as normal. Non-interactive behavior:

  • Required keyless field → runner errors with required field M in group N has no Key() set; call .Key("...") on it to enable non-interactive mode (1-based group + field index). Run the binary once in non-interactive mode, see which field needs a key, add it, repeat.
  • Optional keyless field (.Optional()) → silently skipped in non-interactive mode.

That's the whole migration loop. The rest is search-and-replace.

3. WithCobraFlags wiring (cobra users)

Register matching flags on your cobra command so huhx can read named flag values:

cmd.Flags().String("repo-name", "", "")
cmd.Flags().StringArray("answer", nil, "additional answers in key=val form")
cmd.Flags().String("answer-file", "", "path to YAML/JSON answer file")
cmd.Flags().Bool("non-interactive", false, "force non-interactive mode")

Then pass huhx.WithCobraFlags(cmd) to the runner.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Confirm

type Confirm struct {
	// contains filtered or unexported fields
}

Confirm wraps *huh.Confirm for headless drive.

func NewConfirm

func NewConfirm() *Confirm

NewConfirm returns a new Confirm wrapping huh.NewConfirm().

func (*Confirm) Accessor

func (c *Confirm) Accessor(a huh.Accessor[bool]) *Confirm

Accessor sets a custom accessor for the field value.

func (*Confirm) Affirmative

func (c *Confirm) Affirmative(s string) *Confirm

Affirmative sets the affirmative label.

func (*Confirm) Description

func (c *Confirm) Description(s string) *Confirm

Description sets the field description.

func (*Confirm) DescriptionFunc

func (c *Confirm) DescriptionFunc(f func() string, bindings any) *Confirm

DescriptionFunc sets a dynamic description function with bindings.

func (*Confirm) Inline

func (c *Confirm) Inline(inline bool) *Confirm

Inline sets whether the confirm renders inline.

func (*Confirm) Key

func (c *Confirm) Key(k string) *Confirm

Key sets the field key used for answer lookup.

func (*Confirm) Negative

func (c *Confirm) Negative(s string) *Confirm

Negative sets the negative label.

func (*Confirm) Optional

func (c *Confirm) Optional() *Confirm

Optional marks the field as not required in non-interactive mode.

func (*Confirm) Title

func (c *Confirm) Title(s string) *Confirm

Title sets the field title.

func (*Confirm) TitleFunc

func (c *Confirm) TitleFunc(f func() string, bindings any) *Confirm

TitleFunc sets a dynamic title function with bindings.

func (*Confirm) Validate

func (c *Confirm) Validate(fn func(bool) error) *Confirm

Validate sets the validator on both the wrapper and the inner huh field.

func (*Confirm) Value

func (c *Confirm) Value(v *bool) *Confirm

Value binds a destination bool pointer.

func (*Confirm) WithButtonAlignment

func (c *Confirm) WithButtonAlignment(p lipgloss.Position) *Confirm

WithButtonAlignment sets the button alignment position.

type Form

type Form struct {
	// contains filtered or unexported fields
}

Form wraps *huh.Form and retains the huhx groups so the runner can walk them in non-interactive mode.

func NewForm

func NewForm(groups ...*Group) *Form

NewForm builds a Form from huhx groups.

func (*Form) Huh

func (f *Form) Huh() *huh.Form

Huh returns the underlying *huh.Form for callers that need huh-native access (e.g. tests, advanced theming).

Calling Run() directly on the returned form bypasses runner mode detection and the non-interactive answer pipeline.

type Group

type Group struct {
	// contains filtered or unexported fields
}

Group wraps *huh.Group and tracks the hide predicate alongside the huhx field list so the non-interactive runner can walk groups in order, skip hidden ones, and dispatch answers to the correct field.

func NewGroup

func NewGroup(fields ...field) *Group

NewGroup builds a Group from huhx field wrappers.

func (*Group) Description

func (g *Group) Description(s string) *Group

Description sets the group description.

func (*Group) Title

func (g *Group) Title(s string) *Group

Title sets the group title.

func (*Group) WithHeight

func (g *Group) WithHeight(h int) *Group

WithHeight sets the group height.

func (*Group) WithHide

func (g *Group) WithHide(hide bool) *Group

WithHide marks the group as skipped (in non-interactive mode) and hidden (in interactive mode) when hide is true. The predicate stored on the wrapper is a constant returning hide.

func (*Group) WithHideFunc

func (g *Group) WithHideFunc(fn func() bool) *Group

WithHideFunc marks the group as skipped (in non-interactive mode) and hidden (in interactive mode) when fn returns true. Mirrors huh's WithHideFunc.

func (*Group) WithKeyMap

func (g *Group) WithKeyMap(k *huh.KeyMap) *Group

WithKeyMap applies a key map to the group.

func (*Group) WithShowErrors

func (g *Group) WithShowErrors(show bool) *Group

WithShowErrors toggles error display for the group.

func (*Group) WithShowHelp

func (g *Group) WithShowHelp(show bool) *Group

WithShowHelp toggles the help text for the group.

func (*Group) WithTheme

func (g *Group) WithTheme(t huh.Theme) *Group

WithTheme applies a theme to the group.

func (*Group) WithWidth

func (g *Group) WithWidth(w int) *Group

WithWidth sets the group width.

type Input

type Input struct {
	// contains filtered or unexported fields
}

Input is a thin builder over *huh.Input that captures the validator and destination pointer so the non-interactive runner can drive the field without going through huh's bubble tea loop.

func NewInput

func NewInput() *Input

NewInput returns a new Input wrapping huh.NewInput().

func (*Input) Accessor

func (i *Input) Accessor(a huh.Accessor[string]) *Input

Accessor sets a custom accessor for reading and writing the field value.

func (*Input) CharLimit

func (i *Input) CharLimit(n int) *Input

CharLimit sets the maximum character length.

func (*Input) Description

func (i *Input) Description(s string) *Input

Description sets the field description.

func (*Input) DescriptionFunc

func (i *Input) DescriptionFunc(f func() string, bindings any) *Input

DescriptionFunc sets a dynamic description function.

func (*Input) EchoMode

func (i *Input) EchoMode(mode huh.EchoMode) *Input

EchoMode sets the echo mode for the input.

func (*Input) Inline

func (i *Input) Inline(inline bool) *Input

Inline toggles inline rendering for the input.

func (*Input) Key

func (i *Input) Key(k string) *Input

Key sets the field key used for answer lookup.

func (*Input) Optional

func (i *Input) Optional() *Input

Optional marks the field as not required in non-interactive mode.

func (*Input) Password

func (i *Input) Password(password bool) *Input

Password toggles password masking for the input.

func (*Input) Placeholder

func (i *Input) Placeholder(s string) *Input

Placeholder sets the field placeholder.

func (*Input) PlaceholderFunc

func (i *Input) PlaceholderFunc(f func() string, bindings any) *Input

PlaceholderFunc sets a dynamic placeholder function.

func (*Input) Prompt

func (i *Input) Prompt(s string) *Input

Prompt sets the input prompt.

func (*Input) Suggestions

func (i *Input) Suggestions(suggestions []string) *Input

Suggestions sets the autocomplete suggestions.

func (*Input) SuggestionsFunc

func (i *Input) SuggestionsFunc(f func() []string, bindings any) *Input

SuggestionsFunc sets a dynamic suggestions function.

func (*Input) Title

func (i *Input) Title(s string) *Input

Title sets the field title.

func (*Input) TitleFunc

func (i *Input) TitleFunc(f func() string, bindings any) *Input

TitleFunc sets a dynamic title function.

func (*Input) Validate

func (i *Input) Validate(fn func(string) error) *Input

Validate sets the validator on both the wrapper and the inner huh field.

func (*Input) Value

func (i *Input) Value(v *string) *Input

Value binds a destination string pointer.

type Mode

type Mode int

Mode controls how the runner chooses between interactive and non-interactive execution.

const (
	// AutoDetect chooses non-interactive when env (NON_INTERACTIVE/CI),
	// stdin (not a TTY), or the --non-interactive flag say so; otherwise
	// interactive.
	AutoDetect Mode = iota
	// Always forces non-interactive mode.
	Always
	// Never forces interactive mode.
	Never
)

type MultiSelect

type MultiSelect[T comparable] struct {
	// contains filtered or unexported fields
}

MultiSelect wraps *huh.MultiSelect[T] for headless drive. The non-interactive answer is a comma-separated string of option keys or values. Options provided via Options(...) are captured at construction time; options provided via OptionsFunc(...) are re-evaluated lazily inside set() so closures that depend on earlier fields' values resolve correctly.

func NewMultiSelect

func NewMultiSelect[T comparable]() *MultiSelect[T]

NewMultiSelect returns a new MultiSelect wrapping huh.NewMultiSelect[T]().

func (*MultiSelect[T]) Accessor

func (m *MultiSelect[T]) Accessor(a huh.Accessor[[]T]) *MultiSelect[T]

Accessor binds a custom accessor for reading and writing the value.

func (*MultiSelect[T]) Description

func (m *MultiSelect[T]) Description(d string) *MultiSelect[T]

Description sets the field description.

func (*MultiSelect[T]) DescriptionFunc

func (m *MultiSelect[T]) DescriptionFunc(f func() string, bindings any) *MultiSelect[T]

DescriptionFunc sets a dynamic description provider re-evaluated on bindings change.

func (*MultiSelect[T]) Filterable

func (m *MultiSelect[T]) Filterable(filterable bool) *MultiSelect[T]

Filterable toggles filtering UI.

func (*MultiSelect[T]) Filtering

func (m *MultiSelect[T]) Filtering(filtering bool) *MultiSelect[T]

Filtering sets the current filtering state.

func (*MultiSelect[T]) Height

func (m *MultiSelect[T]) Height(h int) *MultiSelect[T]

Height sets the field height.

func (*MultiSelect[T]) Key

func (m *MultiSelect[T]) Key(k string) *MultiSelect[T]

Key sets the field key used for answer lookup.

func (*MultiSelect[T]) Limit

func (m *MultiSelect[T]) Limit(n int) *MultiSelect[T]

Limit sets the maximum number of selections.

func (*MultiSelect[T]) Optional

func (m *MultiSelect[T]) Optional() *MultiSelect[T]

Optional marks the field as not required in non-interactive mode.

func (*MultiSelect[T]) Options

func (m *MultiSelect[T]) Options(opts ...huh.Option[T]) *MultiSelect[T]

Options sets the available options statically. The wrapper retains a copy so the non-interactive runner can match answers without going through huh internals. Calling Options clears any previously set OptionsFunc.

func (*MultiSelect[T]) OptionsFunc

func (m *MultiSelect[T]) OptionsFunc(f func() []huh.Option[T], bindings any) *MultiSelect[T]

OptionsFunc sets a dynamic options provider. The provider is forwarded to huh for interactive mode and is re-evaluated by the non-interactive runner at injection time so closures that depend on earlier fields' values resolve correctly. The dependent field must live in a later group than its source field (same rule as huh's interactive bindings). Calling OptionsFunc clears any previously set static Options.

func (*MultiSelect[T]) Title

func (m *MultiSelect[T]) Title(t string) *MultiSelect[T]

Title sets the field title.

func (*MultiSelect[T]) TitleFunc

func (m *MultiSelect[T]) TitleFunc(f func() string, bindings any) *MultiSelect[T]

TitleFunc sets a dynamic title provider re-evaluated on bindings change.

func (*MultiSelect[T]) Validate

func (m *MultiSelect[T]) Validate(fn func([]T) error) *MultiSelect[T]

Validate sets the validator on both the wrapper and the inner huh field.

func (*MultiSelect[T]) Value

func (m *MultiSelect[T]) Value(v *[]T) *MultiSelect[T]

Value binds a destination slice pointer.

func (*MultiSelect[T]) Width

func (m *MultiSelect[T]) Width(w int) *MultiSelect[T]

Width sets the field width.

type Option

type Option func(*Runner)

Option configures a Runner.

func WithAnswerFile

func WithAnswerFile(path string) Option

WithAnswerFile loads answers from a YAML or JSON file. YAML is a superset of JSON so a single decoder handles both.

func WithAnswers

func WithAnswers(m map[string]any) Option

WithAnswers supplies answers programmatically. Values are stringified via fmt.Sprintf("%v", v) before being handed to the field's setter. This has the highest precedence among answer sources.

func WithCobraFlags

func WithCobraFlags(cmd *cobra.Command) Option

WithCobraFlags wires the runner to a cobra command. The runner uses the command for three things:

  1. Looking up each field's key as a named flag (e.g. --name) and using its value when the flag has been explicitly set.
  2. Reading --answer key=val pairs from a StringSlice flag named "answer" if present.
  3. Honouring a --non-interactive bool flag if present and set, as one of the AutoDetect inputs.

func WithEnvPrefix

func WithEnvPrefix(prefix string) Option

WithEnvPrefix sets the prefix used when looking up answers in environment variables. A field with key "name" and prefix "MYCLI" is looked up as MYCLI_NAME.

func WithNonInteractive

func WithNonInteractive(mode Mode) Option

WithNonInteractive overrides the mode selection. Default is AutoDetect.

type Runner

type Runner struct {
	// contains filtered or unexported fields
}

Runner drives a Form either interactively (delegating to huh) or non-interactively (walking groups and injecting answers from configured sources).

func New

func New(form *Form, opts ...Option) *Runner

New returns a Runner. Default mode is AutoDetect.

func (*Runner) Run

func (r *Runner) Run() error

Run executes the form. In interactive mode it delegates to huh.Form.Run(). In non-interactive mode it walks groups and resolves each field's answer from the configured sources, returning a descriptive error if any required answer is missing or any validator fails.

type Select

type Select[T comparable] struct {
	// contains filtered or unexported fields
}

Select wraps *huh.Select[T] for headless drive. Options provided via Options(...) are captured at construction time; options provided via OptionsFunc(...) are re-evaluated lazily inside set() so closures that depend on earlier fields' values resolve correctly.

func NewSelect

func NewSelect[T comparable]() *Select[T]

NewSelect returns a new Select wrapping huh.NewSelect[T]().

func (*Select[T]) Accessor

func (s *Select[T]) Accessor(a huh.Accessor[T]) *Select[T]

Accessor binds a custom accessor for reading/writing the field value.

func (*Select[T]) Description

func (s *Select[T]) Description(d string) *Select[T]

Description sets the field description.

func (*Select[T]) DescriptionFunc

func (s *Select[T]) DescriptionFunc(f func() string, bindings any) *Select[T]

DescriptionFunc sets a dynamic description with bindings.

func (*Select[T]) Filtering

func (s *Select[T]) Filtering(filtering bool) *Select[T]

Filtering toggles filter input for options.

func (*Select[T]) Height

func (s *Select[T]) Height(height int) *Select[T]

Height sets the visible option list height.

func (*Select[T]) Inline

func (s *Select[T]) Inline(inline bool) *Select[T]

Inline sets inline rendering.

func (*Select[T]) Key

func (s *Select[T]) Key(k string) *Select[T]

Key sets the field key used for answer lookup.

func (*Select[T]) Optional

func (s *Select[T]) Optional() *Select[T]

Optional marks the field as not required in non-interactive mode.

func (*Select[T]) Options

func (s *Select[T]) Options(opts ...huh.Option[T]) *Select[T]

Options sets the available options statically. The wrapper retains a copy so the non-interactive runner can match answers without going through huh internals. Calling Options clears any previously set OptionsFunc.

func (*Select[T]) OptionsFunc

func (s *Select[T]) OptionsFunc(f func() []huh.Option[T], bindings any) *Select[T]

OptionsFunc sets a dynamic options provider. The provider is forwarded to huh for interactive mode and is re-evaluated by the non-interactive runner at injection time so closures that depend on earlier fields' values resolve correctly. The dependent field must live in a later group than its source field (same rule as huh's interactive bindings). Calling OptionsFunc clears any previously set static Options.

func (*Select[T]) Title

func (s *Select[T]) Title(t string) *Select[T]

Title sets the field title.

func (*Select[T]) TitleFunc

func (s *Select[T]) TitleFunc(f func() string, bindings any) *Select[T]

TitleFunc sets a dynamic title with bindings.

func (*Select[T]) Validate

func (s *Select[T]) Validate(fn func(T) error) *Select[T]

Validate sets the validator on both the wrapper and the inner huh field.

func (*Select[T]) Value

func (s *Select[T]) Value(v *T) *Select[T]

Value binds a destination pointer.

type Text

type Text struct {
	// contains filtered or unexported fields
}

Text wraps *huh.Text for headless drive.

func NewText

func NewText() *Text

NewText returns a new Text wrapping huh.NewText().

func (*Text) Accessor

func (t *Text) Accessor(a huh.Accessor[string]) *Text

Accessor sets a custom accessor used for reading and writing the value.

func (*Text) CharLimit

func (t *Text) CharLimit(n int) *Text

CharLimit sets the maximum character length.

func (*Text) Description

func (t *Text) Description(s string) *Text

Description sets the field description.

func (*Text) DescriptionFunc

func (t *Text) DescriptionFunc(f func() string, bindings any) *Text

DescriptionFunc sets the description via a dynamic function with bindings.

func (*Text) Editor

func (t *Text) Editor(editor ...string) *Text

Editor sets the external editor command.

func (*Text) EditorExtension

func (t *Text) EditorExtension(ext string) *Text

EditorExtension sets the file extension used by the external editor.

func (*Text) ExternalEditor

func (t *Text) ExternalEditor(enabled bool) *Text

ExternalEditor toggles the external editor.

func (*Text) Key

func (t *Text) Key(k string) *Text

Key sets the field key used for answer lookup.

func (*Text) Lines

func (t *Text) Lines(n int) *Text

Lines sets the number of visible lines.

func (*Text) Optional

func (t *Text) Optional() *Text

Optional marks the field as not required in non-interactive mode.

func (*Text) Placeholder

func (t *Text) Placeholder(s string) *Text

Placeholder sets the field placeholder.

func (*Text) PlaceholderFunc

func (t *Text) PlaceholderFunc(f func() string, bindings any) *Text

PlaceholderFunc sets the placeholder via a dynamic function with bindings.

func (*Text) ShowLineNumbers

func (t *Text) ShowLineNumbers(show bool) *Text

ShowLineNumbers toggles display of line numbers.

func (*Text) Title

func (t *Text) Title(s string) *Text

Title sets the field title.

func (*Text) TitleFunc

func (t *Text) TitleFunc(f func() string, bindings any) *Text

TitleFunc sets the title via a dynamic function with bindings.

func (*Text) Validate

func (t *Text) Validate(fn func(string) error) *Text

Validate sets the validator on both the wrapper and the inner huh field.

func (*Text) Value

func (t *Text) Value(v *string) *Text

Value binds a destination string pointer.

Directories

Path Synopsis
examples
deploy command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL