Core Concepts
Termina is built on a few key concepts that work together to create reactive terminal UIs.
The MVVM Pattern
Termina follows the Model-View-ViewModel (MVVM) pattern:
| Component | Role | Termina Class |
|---|---|---|
| ViewModel | State + Logic | ReactiveViewModel |
| View | UI Layout | ReactivePage<TViewModel> |
| Model | Data | Your domain objects |
Key Components
ViewModels
ViewModels hold your application state using [Reactive] properties:
csharp
public partial class MyViewModel : ReactiveViewModel
{
[Reactive] private int _count; // Generates Count and CountChanged
}Pages
Pages build the UI layout and bind to ViewModel observables:
csharp
public class MyPage : ReactivePage<MyViewModel>
{
protected override ILayoutNode BuildLayout()
{
return ViewModel.CountChanged
.Select(c => new TextNode($"Count: {c}"))
.AsLayout();
}
}Routing
Pages are registered with routes and parameters:
csharp
builder.Services.AddTermina("/", termina =>
{
termina.RegisterRoute<HomePage, HomeViewModel>("/");
termina.RegisterRoute<DetailPage, DetailViewModel>("/items/{id:int}");
});Data Flow
Keyboard Input
│
▼
Page (capture) → Focused Component (bubble) → ViewModel
│ │ │
└────────────────────┴───────────────────────┘
↓
[Reactive] Property Change
↓
Observable emits new value
↓
Page re-renders region
↓
ANSI Terminal Output- User presses a key
- Page's
KeyBindingschecked first (capture phase) - If not handled, focused component receives input (bubble phase)
- If not handled, ViewModel's
Inputobservable receives event - State change updates a
[Reactive]property - The property's
*Changedobservable emits - Page's reactive binding receives the value
- Only the affected region re-renders
Sections
- Architecture - MVVM and reactive patterns
- Reactive Properties - The
[Reactive]attribute - Observables & Rx - Understanding
IObservable<T> - Source Generators - How code generation works
- Routing - ASP.NET-style route templates
- Navigation - Moving between pages
- Input Handling - Keyboard, mouse, and resize
- Hosting & DI - Integration with Microsoft.Extensions