Text Input Handling
Relevant source files
The following files were used as context for generating this wiki page:
The Text Input Handling system in the Wizard Tutorial project provides a structured mechanism for capturing user data within a terminal-based wizard interface. Built using the Bubble Tea and Lip Gloss frameworks, the system abstracts different types of user input—specifically short-form text and multi-line text—into a unified interface. This allows the main application loop to manage a sequence of questions without needing to handle the specific implementation details of the underlying input components.
The core of this system is an Input interface that wraps Charm Bracelet's textinput and textarea components. By providing a consistent API for blinking, focusing, blurring, and updating, the system enables a seamless transition between different input fields as the user progresses through the wizard milestones.
Sources: README.md:1-15, input.go:9-17, main.go:37-41
Input Architecture and Interface
The system utilizes a polymorphic approach to handle different input types. The Input interface defines the contract that any input component must fulfill to be used within the Question structure.
The Input Interface
The Input interface ensures that both short-answer and long-answer fields can be managed identically by the Main model's Update and View functions.
type Input interface {
Blink() tea.Msg
Blur() tea.Msg
Focus() tea.Cmd
SetValue(string)
Value() string
Update(tea.Msg) (Input, tea.Cmd)
View() string
}
Sources: input.go:9-17
Component Relationship
The following class diagram illustrates the relationship between the Input interface and its concrete implementations.
The diagram shows how shortAnswerField and longAnswerField wrap their respective Charm Cloud components to satisfy the Input interface.
Sources: input.go:21-110
Input Implementations
The project provides two primary implementations of the Input interface to accommodate various data entry needs.
Short Answer Field
The shortAnswerField is a wrapper around the textinput component. It is intended for single-line inputs like names or small preferences. It initializes with a default placeholder "Your answer here" and sets focus immediately upon creation.
Sources: input.go:21-34
Long Answer Field
The longAnswerField wraps the textarea component. This implementation is used for multi-line text, such as quotes or descriptions. Like the short-answer variant, it includes a placeholder and manages its own focus state.
Sources: input.go:73-86
| Feature | Component | Purpose | Source |
|---|---|---|---|
| Short Answer | textinput | Single-line data entry | input.go:21-23 |
| Long Answer | textarea | Multi-line data entry | input.go:73-75 |
| Placeholder | Internal String | Provides user guidance | input.go:29, 81 |
Data Flow and Interaction
The interaction between the user and the input fields is managed by the Main model in main.go. The model maintains a slice of Question objects, each containing its own Input instance.
Input Life Cycle
The following sequence diagram demonstrates how input is updated and how the system transitions between questions when the "enter" key is pressed.
This diagram shows the delegation of message handling from the main loop to the active input component and the eventual retrieval of the answer.
Sources: main.go:68-91
Input Rendering
The Main.View() method handles the visual placement of the input field. It uses lipgloss.JoinVertical to stack the question text above the rendered input field. The input field itself is styled using a border and padding defined in the Styles struct.
func (m Main) View() string {
// ... logic for done state ...
return lipgloss.Place(
m.width, m.height,
lipgloss.Center, lipgloss.Center,
lipgloss.JoinVertical(
lipgloss.Left,
current.question,
m.styles.InputField.Render(current.input.View()),
),
)
}
Sources: main.go:93-117, main.go:21-25
Configuration and Styling
The appearance of the input fields is centralized in the Styles structure. This ensures a consistent look and feel across different input types.
| Style Attribute | Value / Method | Description | Source |
|---|---|---|---|
| Border Color | lipgloss.Color("36") | Cyan-like color for input borders | main.go:23 |
| Border Style | lipgloss.NormalBorder() | Standard line border | main.go:24 |
| Padding | 1 | Internal space within the input border | main.go:24 |
| Width | 80 | Fixed width for input fields | main.go:24 |
The DefaultStyles function initializes these values, which are then applied to the output of current.input.View() during the rendering phase.
Sources: main.go:21-26, main.go:114
Summary
Text Input Handling is achieved through an interface-driven design that abstracts the complexities of the Bubble Tea framework's internal components. By wrapping textinput and textarea into a common Input interface, the system supports extensible question types while maintaining a clean, centralized logic for state management and rendering. This architecture allows the wizard to scale effectively as more complex input requirements arise.