Build user interfaces for terminal apps using an approachable code-first API.
$ dotnet add package Hex1bHex1b is a .NET library for building TUI apps using an approachable code-first API.
dotnet add package Hex1b
A minimal application that displays text and a quit button:
using Hex1b;
using var app = new Hex1bApp(ctx =>
ctx.VStack(b => [
b.Text("Hello, Terminal!"),
b.Button("Quit").OnClick(e => e.Context.RequestStop())
])
);
await app.RunAsync();
An interactive counter demonstrating mutable state across renders:
using Hex1b;
// State persists outside the builder function
var count = 0;
using var app = new Hex1bApp(ctx =>
ctx.VStack(b => [
b.Text($"Count: {count}"),
b.Button("Increment").OnClick(_ => count++),
b.Button("Decrement").OnClick(_ => count--),
b.Text(""),
b.Button("Quit").OnClick(e => e.Context.RequestStop())
])
);
await app.RunAsync();
A counter controlled with custom keyboard shortcuts (Ctrl+A to increment, Ctrl+D to decrement):
using Hex1b;
using Hex1b.Input;
var count = 0;
using var app = new Hex1bApp(ctx =>
ctx.VStack(b => [
b.Text($"Count: {count}"),
b.Text(""),
b.Text("Ctrl+A: Increment"),
b.Text("Ctrl+D: Decrement"),
b.Text("Ctrl+Q: Quit")
]).WithInputBindings(bindings =>
{
bindings.Ctrl().Key(Hex1bKey.A).Action(() => count++, "Increment counter");
bindings.Ctrl().Key(Hex1bKey.D).Action(() => count--, "Decrement counter");
bindings.Ctrl().Key(Hex1bKey.Q).Action(ctx => ctx.RequestStop(), "Quit");
})
);
await app.RunAsync();
Hex1b uses a constraint-based layout system with size hints:
// Vertical stack with flexible sizing
new VStackWidget(
children: [contentWidget, statusBarWidget],
sizeHints: [SizeHint.Fill, SizeHint.Content]
);
Size Hints:
SizeHint.Fill – Expand to fill available spaceSizeHint.Content – Size to fit contentSizeHint.Fixed(n) – Fixed size of n unitsSizeHint.Weighted(n) – Proportional sizing with weight n| Widget | Description |
|---|---|
TextBlockWidget | Display static or dynamic text |
TextBoxWidget | Editable text input with cursor and selection |
ButtonWidget | Clickable button with label and action |
ListWidget | Scrollable list with selection support |
VStackWidget | Vertical layout container |
HStackWidget | Horizontal layout container |
SplitterWidget | Resizable split pane layout |
BorderWidget | Container with border and optional title |
ScrollPanelWidget | Scrollable content area |
Define keyboard shortcuts using the fluent builder API:
widget.WithInputBindings(bindings =>
{
// Simple key
bindings.Key(Hex1bKey.Delete).Action(() => DeleteItem());
// Modifier keys (Ctrl or Shift, but not both)
bindings.Ctrl().Key(Hex1bKey.S).Action(() => Save(), "Save");
bindings.Shift().Key(Hex1bKey.Tab).Action(() => FocusPrevious(), "Previous");
// Multi-step chords
bindings.Ctrl().Key(Hex1bKey.K)
.Then().Key(Hex1bKey.C)
.Action(() => CommentLine(), "Comment line");
});
Apply built-in themes or create your own:
using Hex1b.Theming;
using var app = new Hex1bApp(
builder,
new Hex1bAppOptions { Theme = Hex1bThemes.Sunset }
);
Hex1b is licensed under the MIT License.