The Elm Architecture in Go
Relevant source files
The following files were used as context for generating this wiki page:
The Elm Architecture (TEA) in this project is implemented using the Bubble Tea framework to create a terminal-based wizard. This architecture pattern structures the application into three distinct parts: a Model that represents the state, an Update function to handle state transitions via messages, and a View function to render the UI based on the current state.
In this specific implementation, the architecture manages a sequence of user questions, capturing input through different types of terminal fields (short and long text) and transitioning between them until a final state is reached.
Sources: README.md:1-15, main.go:1-20
Core Architectural Components
The system follows a strict separation of concerns as defined by the tea.Model interface requirements. The Main struct acts as the primary orchestrator, holding the application state.
The Model
The Main struct serves as the root model. It tracks the progress of the wizard through an index, maintains the list of questions, and stores the window dimensions for responsive rendering.
| Field | Type | Description |
|---|---|---|
styles | *Styles | Lip Gloss styles for the UI components |
index | int | Current question index in the sequence |
questions | []Question | Array of Question objects containing inputs and answers |
width | int | Terminal window width |
height | int | Terminal window height |
done | bool | Flag indicating the wizard has completed |
Sources: main.go:23-30, main.go:41-45
The Update Loop
The Update function is the central processing unit for all I/O and state changes. It responds to tea.Msg types, such as keyboard input or window resizing.
The diagram shows how messages are routed through the main model to either trigger global state changes or update sub-components.
Sources: main.go:61-83
Input Component Abstraction
To handle different types of user input (short text vs. multi-line text), the project utilizes an Input interface. This allows the Main model to interact with various UI components polymorphically.
Input Interface
The Input interface ensures that any input component can be integrated into the wizard's lifecycle.
Sources: input.go:9-17
Component Implementation
Two specific implementations of the interface are provided:
- shortAnswerField: Wraps
textinput.Modelfor single-line data. - longAnswerField: Wraps
textarea.Modelfor multi-line data.
The class diagram illustrates the relationship between the generic Input interface and its concrete terminal-component implementations.
Sources: input.go:22-110
View Rendering and Styling
The View function is responsible for the declarative UI. It uses the lipgloss library to position elements and apply visual styling.
UI Layout Logic
The view logic branches based on the application state:
- Initial/Loading State: Displays "loading..." if the window width is not yet determined.
- Active State: Uses
lipgloss.Placeandlipgloss.JoinVerticalto center the current question and its corresponding input field. - Completed State: Iterates through all questions and answers to display a summary.
Sources: main.go:85-108
Styling Configuration
Styles are centralized in a Styles struct and initialized with DefaultStyles().
| Style Property | Lip Gloss Configuration | Purpose |
|---|---|---|
BorderColor | Color("36") | Sets the primary accent color |
InputField | BorderStyle(NormalBorder), Padding(1), Width(80) | Defines the container for user inputs |
Sources: main.go:13-21
Execution Flow
The application entry point in main.go initializes the model with a predefined sequence of questions and starts the Bubble Tea program loop.
The sequence diagram details the lifecycle of the program from initialization through the continuous loop of updates and renders.
Sources: main.go:117-135
Summary
The project demonstrates a robust implementation of The Elm Architecture in Go. By leveraging the Input interface, the system maintains a clean separation between the main application logic and the specific mechanics of terminal input components. This structure allows for easy expansion, such as adding new question types or complex validation, while keeping the core update and view logic predictable and testable.