Documentation
¶
Overview ¶
Package tui hosts the shared Bubble Tea primitives used by every Multiversa wizard. It defines the Step contract that screens satisfy and the messages used to navigate between them. Concrete step types still live in each wizard's own package (e.g. internal/wizard/steps for the `init` wizard) — this package only owns the abstractions.
The Step interface was originally introduced under internal/wizard/steps; v0.4.0 lifts it here so detect/stack/ workspace/usb/lab wizards can share the same shape.
Index ¶
- func Back() tea.Msg
- func Cancel() tea.Msg
- func Choose[T any](v Verbosity, verbose, standard, condensed T) T
- func ConfirmDecision(input string) bool
- func Header(title, subtitle string, step, total int) string
- func Next() tea.Msg
- type BackMsg
- type CancelMsg
- type LayerStatus
- type NextMsg
- type ProgressItem
- type ProgressList
- type ProgressState
- type Selector
- type SelectorItem
- type Sidebar
- type Step
- type Verbosity
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Choose ¶
Choose returns one of the three strings based on the current verbosity. Useful for inline conditionals in View() methods:
hint := tui.Choose(v, "Press y/n to confirm", "y/n", "")
func ConfirmDecision ¶
ConfirmDecision interprets a user response to a yes/no prompt. The contract is intentionally strict for destructive operations: only an explicit "y", "Y", "yes", or "YES" returns true. Everything else — including blank, spaces, "no", ambiguous strings — returns false. This is the no-default-yes rule baked into v0.4.0 specs.
func Header ¶
Header renders the canonical Multiversa wizard header: an accented title, a dim subtitle, and an optional step-progress crumb of the form "step 2 of 5". The output never contains ANSI hyperlinks so it stays paste-safe in the user's terminal scrollback.
Pass step=0,total=0 to omit the progress crumb (e.g. for one-shot commands like `detect`).
Types ¶
type BackMsg ¶
type BackMsg struct{}
BackMsg signals that the user wants to revisit the previous step.
type CancelMsg ¶
type CancelMsg struct{}
CancelMsg signals that the user wants to abort the wizard. The host program is expected to translate this into exit code 2.
type LayerStatus ¶
type LayerStatus struct {
Name string // e.g. "Técnica"
Tagline string // optional one-line description rendered dim
Steps []ProgressItem
IsCurrent bool // true when the cursor is inside this layer
}
LayerStatus is one layer entry in the Sidebar of the meta-wizard. It represents a vertical group of related Steps (Técnica / Identitaria / Operacional), each with its own per-step progress.
type NextMsg ¶
type NextMsg struct{}
NextMsg signals that the current step is done; the wizard should advance to the next one.
type ProgressItem ¶
type ProgressItem struct {
Label string
Note string
State ProgressState
}
ProgressItem is one row in a ProgressList.
type ProgressList ¶
type ProgressList struct {
Items []ProgressItem
}
ProgressList renders a vertical stack of items with state glyphs. Like Selector, it is stateless rendering — the host owns state transitions and feeds in the slice each frame.
func (ProgressList) Counts ¶
func (p ProgressList) Counts() (done, skipped, failed, pending int)
Counts returns done/skipped/failed/pending counts.
func (ProgressList) Render ¶
func (p ProgressList) Render() string
Render returns the multi-line view for the progress list.
type ProgressState ¶
type ProgressState int
ProgressState is the lifecycle of a single ProgressItem.
const ( // Pending — not started yet. Rendered dim. Pending ProgressState = iota // Running — in flight. Rendered with the accent color. Running // Done — completed successfully. Rendered with ✓. Done // Skipped — intentionally bypassed (e.g. already installed). Skipped // Failed — completed with error. Rendered as ✗ in warn style. Failed )
type Selector ¶
type Selector struct {
Items []SelectorItem
Cursor int
}
Selector is a stateless renderer for a vertical list with a cursor. It is intentionally pure: no Bubble Tea wiring lives here. Wizards own their tea.Model and call Render() from their View().
func (*Selector) MoveDown ¶
func (s *Selector) MoveDown()
MoveDown advances the cursor, skipping disabled items.
func (*Selector) MoveUp ¶
func (s *Selector) MoveUp()
MoveUp retreats the cursor, skipping disabled items.
func (Selector) Selected ¶
func (s Selector) Selected() *SelectorItem
Selected returns the currently focused item or nil if the cursor is out of bounds (empty list).
type SelectorItem ¶
type SelectorItem struct {
Label string
Hint string
Marker string // e.g. "✓" for installed
Disabled bool
}
SelectorItem is one row in a Selector list. Disabled rows are rendered dim and can't be chosen; Marker is an optional glyph the caller can use to flag installed/completed items.
type Sidebar ¶
type Sidebar struct {
Layers []LayerStatus
}
Sidebar renders the layered overview shown on the left of `multiversa lab`. It is intentionally text-only — no fixed-width padding — so the wizard host can wrap it in any layout primitive (lipgloss.JoinHorizontal, etc.) without fighting alignment.
type Step ¶
type Step interface {
Init() tea.Cmd
Update(msg tea.Msg) (Step, tea.Cmd)
View() string
Title() string
}
Step is the contract every wizard screen satisfies. Returning a NextMsg from Update advances the wizard; BackMsg goes back; CancelMsg exits the program with status 2 (user cancel) so scripts can distinguish cancellation from a real failure.
type Verbosity ¶
type Verbosity int
Verbosity is the explanation density a wizard renders. It maps one-to-one to profile.Level (newcomer → Verbose, enthusiast → Standard, expert → Condensed) but stays here as a UI concern so the tui package does not depend on internal/profile.
func VerbosityForLevel ¶
VerbosityForLevel maps a profile level name to the matching Verbosity. Unknown levels default to Standard so missing config never breaks the UI.