Repository Structure
Relevant source files
The following files were used as context for generating this wiki page:
The wizard-tutorial repository is a structured Go project designed as a companion for a terminal wizard tutorial. It utilizes the Charm ecosystem, specifically the Bubble Tea framework for TUI (Terminal User Interface) state management and Lip Gloss for layout and styling.
The project is organized to demonstrate a modular approach to building multi-step terminal forms. It separates core application logic, styling, and custom input components into distinct structures, allowing for a sequential "wizard" flow where users answer a series of questions that are eventually summarized.
Sources: README.md:1-12, main.go:1-12
Core Architecture and Component Model
The application follows the Elm Architecture (Model-Update-View) pattern as implemented by Bubble Tea. The Main struct acts as the primary model, managing the overall state of the wizard, including the current question index, the list of questions, and terminal dimensions.
Data Structures
The repository defines several key structures to manage the state and lifecycle of the terminal wizard:
| Structure | Description | Location |
|---|---|---|
Main | The primary Bubble Tea model; manages terminal size, question indexing, and completion state. | main.go:21-28 |
Styles | Defines the visual presentation of the TUI, including border colors and input field padding. | main.go:13-16 |
Question | Represents a single step in the wizard, containing the prompt string, the recorded answer, and the input model. | main.go:30-34 |
Input | An interface that abstracts different types of input components (short vs. long text). | input.go:9-17 |
Sources: main.go:13-34, input.go:9-17
Component Relationship
The Main model contains a slice of Question objects. Each Question wraps an Input interface, which is satisfied by either shortAnswerField or longAnswerField.
The relationship between the main controller and the abstract input components.
Sources: main.go:21-34, input.go:9-17
Input Component System
To handle different types of user data, the repository implements a wrapper system in input.go. This abstraction is necessary because standard Bubble Tea components like textinput and textarea do not inherently satisfy the project's custom Input interface.
Input Types
- Short Answer Field: Utilizes
github.com/charmbracelet/bubbles/textinputfor single-line entries (e.g., Name). - Long Answer Field: Utilizes
github.com/charmbracelet/bubbles/textareafor multi-line entries (e.g., Quotes).
Initialization Logic
The project uses factory functions to instantiate specific question types, automatically assigning the correct input model to the Question struct.
newShortQuestion(q string): Assigns ashortAnswerField.newLongQuestion(q string): Assigns alongAnswerField.
Sources: main.go:42-55, input.go:23-45, input.go:76-98
Application Flow and State Transitions
The application transitions through states based on user interaction (primarily the "Enter" key). When a user submits an answer, the Main model updates the current question's answer field and increments the index.
Wizard Sequence Flow
The following diagram illustrates the lifecycle of a single question within the wizard:
The flow of events when a user types and submits an answer.
Sources: main.go:68-84
Program Termination
Once the final question in the questions slice is answered, the m.done flag is set to true. The View() function then switches from rendering input fields to rendering a summary of all collected questions and answers.
Sources: main.go:78-80, main.go:88-95
Visual Layout and Styling
The project uses lipgloss to handle the positioning of UI elements. The DefaultStyles function defines the aesthetics of the wizard.
func DefaultStyles() *Styles {
s := new(Styles)
s.BorderColor = lipgloss.Color("36")
s.InputField = lipgloss.NewStyle().BorderForeground(s.BorderColor).BorderStyle(lipgloss.NormalBorder()).Padding(1).Width(80)
return s
}
Sources: main.go:18-23
The View method calculates the center of the terminal using lipgloss.Place and stacks the question text and the input field vertically using lipgloss.JoinVertical.
Sources: main.go:102-113
Conclusion
The repository is structured to facilitate a clear separation between terminal-specific I/O components and the high-level wizard logic. By abstracting inputs through an interface, the system can easily be extended with new question types (e.g., multiple choice) without modifying the core Main model's logic.
Sources: main.go, input.go