TUI library para Zig, inspirada en ratatui
Find a file
R.Eugenio cc772cdd5a Estandarizar: CLAUDE.md → claude.md + refs CREDENCIALES
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 15:14:00 +01:00
.claude/commands Actualizar /init para leer credenciales e infraestructura 2026-01-07 00:40:20 +01:00
docs docs: Add comprehensive API reference manual 2025-12-08 22:52:59 +01:00
examples feat: zcatui v2.2 - Complete feature set with 13 new modules 2025-12-08 22:46:06 +01:00
src refactor: Migrar ArrayList a ArrayListUnmanaged (Zig 0.15) 2025-12-23 01:39:41 +01:00
.gitignore Añadir /init optimizado (lee NORMAS_ESENCIALES + teamdocs) 2025-12-23 13:28:54 +01:00
build.zig feat: zcatui v2.2 - Complete feature set with 13 new modules 2025-12-08 22:46:06 +01:00
build.zig.zon 🔧 FIX: Compatibilidad Zig 0.15.2 2025-12-09 23:01:17 +01:00
claude.md Estandarizar: CLAUDE.md → claude.md + refs CREDENCIALES 2026-01-11 15:14:00 +01:00
README.md feat: Add form widgets, status bar, toast system, and documentation 2025-12-08 18:02:06 +01:00
VERIFIED_FEATURES.md docs: Add VERIFIED_FEATURES.md - tracking production-tested features 2025-12-10 12:01:03 +01:00
ZIG_VERSION_NOTES.md docs: Renombrar TEAM_STANDARDS a teamdocs 2025-12-11 19:33:46 +01:00

zcatui

A Terminal User Interface (TUI) library for Zig, inspired by ratatui.

zcatui = "zcat" + "ui" (a nod to ratatui and Zig's mascot)

Features

Core

  • Immediate mode rendering with double buffering and diff-based updates
  • Flexible layout system with constraints (Length, Min, Max, Percentage, Ratio)
  • Rich styling with 16/256/RGB colors and modifiers (bold, italic, underline, etc.)
  • Full event handling for keyboard and mouse input
  • Cross-terminal compatibility via ANSI escape sequences

Widgets (30+)

Category Widgets
Basic Block, Paragraph, List, Table, Tabs
Data Gauge, LineGauge, Sparkline, BarChart, Chart, Canvas
Input Input (text field), TextArea, Checkbox, RadioGroup, Select, Slider
Navigation Menu, MenuBar, ContextMenu, Tree, FilePicker
Overlays Popup, Modal, Tooltip, Toast
Layout Panel, PanelSplit, TabbedPanel, DockingPanel, ScrollView, VirtualList
Utilities Scrollbar, Calendar, StatusBar, Clear

Terminal Extensions

  • Clipboard (OSC 52) - Read/write system clipboard
  • Hyperlinks (OSC 8) - Clickable links in terminal
  • Notifications (OSC 9/777) - Desktop notifications
  • Images (Kitty/iTerm2) - Display images in terminal
  • Cursor control - Style, visibility, position

Advanced Features

  • Animation system with easing functions
  • Lazy rendering with caching and throttling
  • Virtual scrolling for large datasets
  • LEGO panel system for complex layouts

Quick Start

const std = @import("std");
const zcatui = @import("zcatui");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Initialize terminal
    var term = try zcatui.Terminal.init(allocator);
    defer term.deinit();

    // Main loop
    while (true) {
        try term.draw(render);

        if (try term.pollEvent(100)) |event| {
            if (event == .key) {
                if (event.key.code == .char and event.key.code.char == 'q') {
                    break;
                }
            }
        }
    }
}

fn render(area: zcatui.Rect, buf: *zcatui.Buffer) void {
    const block = zcatui.widgets.Block.init()
        .title(" Hello zcatui! ")
        .setBorders(zcatui.widgets.Borders.all)
        .style(zcatui.Style.default.fg(zcatui.Color.cyan));
    block.render(area, buf);
}

Installation

Add zcatui to your build.zig.zon:

.dependencies = .{
    .zcatui = .{
        .url = "https://git.reugenio.com/reugenio/zcatui/archive/main.tar.gz",
        // Add hash after first build attempt
    },
},

Then in build.zig:

const zcatui = b.dependency("zcatui", .{
    .target = target,
    .optimize = optimize,
});
exe.root_module.addImport("zcatui", zcatui.module("zcatui"));

Examples

Run examples with:

zig build hello        # Basic hello world
zig build events-demo  # Keyboard/mouse events
zig build list-demo    # List widget
zig build table-demo   # Table widget
zig build dashboard    # Dashboard with multiple widgets
zig build input-demo   # Text input
zig build animation-demo  # Animations
zig build menu-demo    # Menus and modals
zig build form-demo    # Form widgets
zig build panel-demo   # Panel system

Widget Examples

Layout

const Layout = zcatui.Layout;
const Constraint = zcatui.Constraint;

// Split area vertically
const chunks = Layout.vertical(&.{
    Constraint.length(3),      // Fixed 3 rows
    Constraint.percentage(50), // 50% of remaining
    Constraint.min(5),         // At least 5 rows
}).split(area);

// Split horizontally
const cols = Layout.horizontal(&.{
    Constraint.ratio(1, 3),    // 1/3 of width
    Constraint.ratio(2, 3),    // 2/3 of width
}).split(area);

Block with Borders

const Block = zcatui.widgets.Block;
const Borders = zcatui.widgets.Borders;

const block = Block.init()
    .title(" My Panel ")
    .setBorders(Borders.all)
    .style(Style.default.fg(Color.cyan));
block.render(area, buf);

const inner = block.inner(area); // Get content area

List

const List = zcatui.widgets.List;
const ListItem = zcatui.widgets.ListItem;

const items = &[_]ListItem{
    ListItem.init("Item 1"),
    ListItem.init("Item 2").style(Style.default.fg(Color.green)),
    ListItem.init("Item 3"),
};

var list = List.init(items)
    .block(Block.init().title("List").setBorders(Borders.all))
    .highlightStyle(Style.default.bg(Color.blue));
list.renderStateful(area, buf, &list_state);

Form Widgets

// Checkbox
const checkbox = Checkbox.init("Enable feature")
    .setChecked(true)
    .setFocused(is_focused);
checkbox.render(area, buf);

// Radio buttons
var radio = RadioGroup.init(&.{"Option A", "Option B", "Option C"})
    .setSelected(1);
radio.render(area, buf);

// Dropdown select
var select = Select.init(&.{"Small", "Medium", "Large"})
    .setPlaceholder("Choose size...");
select.render(area, buf);

// Slider
const slider = Slider.init(0, 100)
    .setValue(50)
    .setLabel("Volume");
slider.render(area, buf);

Charts

// Bar chart
const BarChart = zcatui.widgets.BarChart;
const chart = BarChart.init()
    .data(&.{
        .{ .label = "A", .value = 10 },
        .{ .label = "B", .value = 20 },
        .{ .label = "C", .value = 15 },
    })
    .barWidth(5);
chart.render(area, buf);

// Sparkline
const Sparkline = zcatui.widgets.Sparkline;
const sparkline = Sparkline.init(&.{1, 4, 2, 8, 5, 3, 9, 2});
sparkline.render(area, buf);

Popups and Modals

const Modal = zcatui.widgets.Modal;
const confirmDialog = zcatui.widgets.confirmDialog;

// Quick confirm dialog
const modal = confirmDialog("Confirm", &.{"Are you sure?"});
modal.render(area, buf);

// Handle button press
if (modal.getFocusedButton() == 0) {
    // OK pressed
}

Toast Notifications

const ToastManager = zcatui.widgets.ToastManager;

var toasts = ToastManager.init();

// Show notifications
toasts.info("Information message");
toasts.success("Operation completed!");
toasts.warning("Warning!");
toasts.showError("Error occurred");

// In render loop
toasts.update();
toasts.render(area, buf);

Terminal Extensions

Clipboard

const Clipboard = zcatui.Clipboard;

// Write to clipboard
try Clipboard.write(writer, "Hello clipboard!");

// Read (async - response comes via terminal)
try Clipboard.requestRead(writer);
const Hyperlink = zcatui.Hyperlink;

const link = Hyperlink.init("https://example.com", "Click here");
try link.write(writer);

Notifications

const notification = zcatui.notification;

try notification.notify(writer, "Build complete!");
try notification.notifyWithTitle(writer, "zcatui", "Task finished");

Images

const image = zcatui.image;

// Display image (Kitty protocol)
try image.Kitty.displayFile(writer, "/path/to/image.png", .{
    .width = 40,
    .height = 20,
});

Architecture

┌─────────────┐    ┌────────┐    ┌──────────┐
│ Application │───▶│ Buffer │───▶│ Terminal │
│  (widgets)  │    │ (diff) │    │ (output) │
└─────────────┘    └────────┘    └──────────┘
  1. Application renders widgets to a Buffer
  2. Buffer is compared (diff) with previous frame
  3. Only changes are sent to terminal (efficient)

Requirements

  • Zig 0.15.x
  • POSIX terminal (Linux, macOS) or Windows Terminal
  • Terminal with ANSI escape sequence support

License

MIT

Credits

  • Inspired by ratatui (Rust)
  • Built with Zig