Package

serez-ui

Retained-mode terminal UI library. Build interactive TUIs with composable widgets — Unicode box-drawing, zero ANSI dependencies.

Install

sz install serez-ui

Quick start

import "serez-ui"

let app = new App()

let layout = new Box(
    new VStack([
        new Text("My App", "bold"),
        new Separator(),
        new Text("Item 1"),
        new Text("Item 2"),
        new Spacer(),
        new Text("v1.0"),
    ]),
    { border: true, padding: 1 }
)

app.render(layout)

Widgets

Text

Renders a line of text with optional style:

new Text("Hello world")
new Text("Bold title", "bold")
new Text("Dimmed note", "dim")
new Text("Italic", "italic")

Box

A container with optional border and padding:

new Box(child, options)

// Options:
// border: true/false  — draw a border around the box
// padding: int        — inner padding in characters
// width: int          — fixed width

new Box(new Text("Hello"), { border: true, padding: 1 })
new Box(content, { border: true, width: 40 })

VStack / HStack

Stack widgets vertically or horizontally:

new VStack([
    new Text("Top"),
    new Text("Middle"),
    new Text("Bottom"),
])

new HStack([
    new Box(new Text("Left"),  { border: true }),
    new Box(new Text("Right"), { border: true }),
])

Separator

A horizontal divider line:

new VStack([
    new Text("Section A"),
    new Separator(),
    new Text("Section B"),
])

Spacer

Fills available space — useful for pushing content to the bottom or right:

new VStack([
    new Text("Top content"),
    new Spacer(),
    new Text("Bottom content"),   // pushed to the bottom
])

App

App is the root. Call .render(widget) to draw the layout to the terminal:

let app = new App()
app.render(layout)    // draws once

// Redraw after a state change
app.render(updatedLayout)

Full example — dashboard

import "serez-ui"

let app = new App()

fn make_ui(string title, [string] items) {
    let rows = items.map(item => new Text("  • {item}"))

    return new Box(
        new VStack([
            new Text(title, "bold"),
            new Separator(),
            new VStack(rows),
            new Spacer(),
            new Text("Press Ctrl+C to exit", "dim"),
        ]),
        { border: true, padding: 1, width: 50 }
    )
}

let tasks = ["Write tests", "Fix bug #42", "Deploy v3.5.2"]
app.render(make_ui("Task Manager", tasks))

Output in the terminal:

┌──────────────────────────────────────────────────┐
│ Task Manager                                     │
│ ──────────────────────────────────────────────── │
│   • Write tests                                  │
│   • Fix bug #42                                  │
│   • Deploy v3.5.2                                │
│                                                  │
│ Press Ctrl+C to exit                             │
└──────────────────────────────────────────────────┘