zcatui/docs/TECHNICAL_REFERENCE.md
reugenio c8316f2134 feat: zcatui v2.1 - 7 new widgets, innovations, and technical docs
New widgets (Phase 1-3):
- Spinner: 10 animation styles (dots, line, arc, pulse, etc.)
- Help: Keybinding display with categories
- Viewport: Content scrolling (static/scrollable)
- Progress: Multi-step progress with styles
- Markdown: Basic markdown rendering (headers, lists, code)
- DirectoryTree: File browser with icons and filters
- SyntaxHighlighter: Code highlighting (Zig, Rust, Python, etc.)

Innovation modules:
- testing.zig: Widget testing framework (harness, simulated input, benchmarks)
- theme_loader.zig: Theme hot-reload from JSON/KV files
- serialize.zig: State serialization, undo/redo stack
- accessibility.zig: A11y support (ARIA roles, screen reader, high contrast)

Layout improvements:
- Flex layout with JustifyContent and AlignItems

Documentation:
- TECHNICAL_REFERENCE.md: Comprehensive 1200+ line technical manual

Stats: 67 files, 34 widgets, 250+ tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 20:29:18 +01:00

28 KiB

zcatui v2.1 - Manual Técnico de Referencia

Referencia completa de todos los módulos, widgets y funcionalidades implementadas.


Índice

  1. Arquitectura General
  2. Módulos Core
  3. Widgets
  4. Sistema de Eventos
  5. Layout y Posicionamiento
  6. Themes y Estilos
  7. Innovaciones v2.1
  8. Utilidades

Arquitectura General

┌─────────────────────────────────────────────────────────────┐
│                      Application                             │
├─────────────────────────────────────────────────────────────┤
│  Widgets (34 tipos)  │  Layout  │  Events  │  Animation     │
├─────────────────────────────────────────────────────────────┤
│      Buffer (diff)   │  Style   │  Text    │  Symbols       │
├─────────────────────────────────────────────────────────────┤
│                    Terminal Backend                          │
└─────────────────────────────────────────────────────────────┘

Flujo de Renderizado

  1. Frame Start: El usuario llama a terminal.draw()
  2. Widget Render: Cada widget escribe al Buffer
  3. Diff: Se calcula qué celdas cambiaron
  4. Output: Solo los cambios van al terminal

Módulos Core

Buffer (src/buffer.zig)

El buffer es la representación en memoria de la pantalla.

const Buffer = @import("zcatui").Buffer;
const Rect = @import("zcatui").Rect;

// Crear buffer
var buf = try Buffer.init(allocator, Rect.init(0, 0, 80, 24));
defer buf.deinit();

// Obtener celda
if (buf.get(x, y)) |cell| {
    // cell.symbol, cell.style
}

// Limpiar
buf.clear();

// Redimensionar
try buf.resize(new_rect);

Tipos importantes:

  • Cell: Una celda con símbolo y estilo
  • Rect: Rectángulo (x, y, width, height)
  • Symbol: Carácter Unicode (hasta 7 bytes inline)

Style (src/style.zig)

Sistema de estilos con colores y modificadores.

const Style = @import("zcatui").Style;
const Color = @import("zcatui").Color;

// Crear estilo
const style = Style.init()
    .fg(Color.red)
    .bg(Color.black)
    .bold()
    .italic()
    .underline();

// Colores disponibles
Color.reset       // Terminal default
Color.black       // ANSI 0
Color.red         // ANSI 1
Color.green       // ANSI 2
Color.yellow      // ANSI 3
Color.blue        // ANSI 4
Color.magenta     // ANSI 5
Color.cyan        // ANSI 6
Color.white       // ANSI 7
Color.indexed(n)  // 256-color palette
Color.rgb(r,g,b)  // True color

Text (src/text.zig)

Texto con estilos inline.

const Text = @import("zcatui").Text;
const Line = @import("zcatui").Line;
const Span = @import("zcatui").Span;

// Texto simple
const text = Text.raw("Hello, World!");

// Con estilos
const styled = Text.fromSpans(&.{
    Span.styled("Error: ", Style.init().fg(Color.red).bold()),
    Span.raw("file not found"),
});

// Alineación
text.alignment(.center);

Widgets

Widgets Básicos

Block (src/widgets/block.zig)

Contenedor con bordes y títulos.

const Block = @import("zcatui").widgets.Block;

const block = Block.init()
    .title("Mi Panel")
    .borders(.all)
    .borderType(.rounded)
    .style(Style.init().fg(Color.blue));

block.render(area, buf);

Paragraph (src/widgets/paragraph.zig)

Texto con word-wrap.

const Paragraph = @import("zcatui").widgets.Paragraph;

const para = Paragraph.init(text)
    .block(block)
    .alignment(.center)
    .wrap(.word);

para.render(area, buf);

List (src/widgets/list.zig)

Lista seleccionable.

const List = @import("zcatui").widgets.List;
const ListState = @import("zcatui").widgets.ListState;

var state = ListState{};
state.select(0);

const list = List.init(&items)
    .block(block)
    .highlightStyle(Style.init().bg(Color.blue))
    .highlightSymbol("> ");

list.render(area, buf, &state);

// Navegación
state.selectNext(items.len);
state.selectPrevious(items.len);

Table (src/widgets/table.zig)

Tabla multi-columna.

const Table = @import("zcatui").widgets.Table;
const TableState = @import("zcatui").widgets.TableState;

var state = TableState{};

const table = Table.init(&rows)
    .header(header_row)
    .widths(&.{
        .{ .percentage = 30 },
        .{ .percentage = 70 },
    })
    .highlightStyle(highlight);

table.render(area, buf, &state);

Widgets de Progreso

Gauge (src/widgets/gauge.zig)

Barra de progreso simple.

const Gauge = @import("zcatui").widgets.Gauge;

const gauge = Gauge.init()
    .percent(75)
    .label("75%")
    .gaugeStyle(Style.init().fg(Color.green));

gauge.render(area, buf);

Progress (src/widgets/progress.zig) - NUEVO v2.1

Barra de progreso con ETA y velocidad.

const Progress = @import("zcatui").widgets.Progress;

var progress = Progress.init(100);  // 100 items total
progress.start();

// En cada iteración
progress.tick();  // o progress.set(n);

// Obtener métricas
const eta = progress.etaSeconds();
const speed = progress.itemsPerSecond();
const elapsed = progress.elapsedSeconds();

progress.render(area, buf);

Formatos:

  • .bar: Barra simple
  • .bar_with_percent: Barra + porcentaje
  • .bar_with_eta: Barra + ETA
  • .full: Barra + porcentaje + ETA + velocidad

Spinner (src/widgets/spinner.zig) - NUEVO v2.1

Indicador de carga animado.

const Spinner = @import("zcatui").widgets.Spinner;
const SpinnerStyle = @import("zcatui").widgets.SpinnerStyle;

var spinner = Spinner.init(.dots);  // 17 estilos disponibles

// En el loop de eventos
spinner.tick();
spinner.render(area, buf);

// Estilos disponibles:
// .dots, .dots2, .dots3, .line, .line2
// .pipe, .simple_dots, .simple_dots_scrolling
// .star, .star2, .flip, .hamburger
// .grow_vertical, .grow_horizontal, .balloon
// .noise, .bounce, .box_bounce

Widgets de Navegación

Tabs (src/widgets/tabs.zig)

Pestañas de navegación.

const Tabs = @import("zcatui").widgets.Tabs;

const tabs = Tabs.init(&.{"Home", "Settings", "Help"})
    .select(0)
    .highlightStyle(Style.init().bold());

tabs.render(area, buf);

Menu (src/widgets/menu.zig)

Menús desplegables.

const Menu = @import("zcatui").widgets.Menu;
const MenuItem = @import("zcatui").widgets.MenuItem;
const MenuBar = @import("zcatui").widgets.MenuBar;

// Menú simple
const menu = Menu.init(&items)
    .title("File")
    .width(20);

// Barra de menú
const menubar = MenuBar.init(&.{
    MenuBarItem.init("File", &file_items),
    MenuBarItem.init("Edit", &edit_items),
});

Tree (src/widgets/tree.zig)

Vista de árbol.

const Tree = @import("zcatui").widgets.Tree;
const TreeItem = @import("zcatui").widgets.TreeItem;
const TreeState = @import("zcatui").widgets.TreeState;

var state = TreeState{};

const tree = Tree.init(&items)
    .block(block)
    .highlightStyle(highlight);

tree.render(area, buf, &state);

// Navegación
state.toggle();  // Expandir/colapsar
state.selectNext();
state.selectPrevious();

DirectoryTree (src/widgets/dirtree.zig) - NUEVO v2.1

Navegador de sistema de archivos.

const DirectoryTree = @import("zcatui").widgets.DirectoryTree;

var dirtree = try DirectoryTree.init(allocator, "/home/user");
defer dirtree.deinit();

// Cargar contenido
try dirtree.loadRoot();

// Navegación
dirtree.moveDown();
dirtree.moveUp();
dirtree.toggleExpand();
dirtree.goToParent();
dirtree.toggleHidden();  // Mostrar/ocultar archivos ocultos

// Obtener selección actual
if (dirtree.getSelected()) |node| {
    // node.path, node.name, node.kind
}

dirtree.render(area, buf);

Widgets de Entrada

Input (src/widgets/input.zig)

Campo de texto de una línea.

const Input = @import("zcatui").widgets.Input;
const InputState = @import("zcatui").widgets.InputState;

var state = InputState.init(allocator);
defer state.deinit();

const input = Input.init()
    .placeholder("Enter name...")
    .block(block);

input.render(area, buf, &state);

// Manejar eventos
state.handleKey(key_event);
const text = state.getText();

TextArea (src/widgets/textarea.zig)

Editor multi-línea.

const TextArea = @import("zcatui").widgets.TextArea;

var textarea = TextArea.init(allocator);
defer textarea.deinit();

textarea.render(area, buf);
textarea.handleKey(key_event);

Checkbox (src/widgets/checkbox.zig)

Casillas de verificación.

const Checkbox = @import("zcatui").widgets.Checkbox;
const RadioGroup = @import("zcatui").widgets.RadioGroup;

// Checkbox
const checkbox = Checkbox.init("Accept terms")
    .checked(true);

// Radio group
var selected: usize = 0;
const radio = RadioGroup.init(&.{"Option A", "Option B", "Option C"}, &selected);

Slider (src/widgets/slider.zig)

Control deslizante.

const Slider = @import("zcatui").widgets.Slider;

var value: f32 = 0.5;
const slider = Slider.init(&value)
    .min(0)
    .max(100)
    .step(1);

slider.render(area, buf);

Widgets de Visualización

Chart (src/widgets/chart.zig)

Gráficos con ejes.

const Chart = @import("zcatui").widgets.Chart;
const Dataset = @import("zcatui").widgets.Dataset;
const Axis = @import("zcatui").widgets.Axis;

const chart = Chart.init(&.{
    Dataset.init(&data_points)
        .name("Series 1")
        .graphType(.line)
        .style(Style.init().fg(Color.cyan)),
})
    .xAxis(Axis.init().title("Time"))
    .yAxis(Axis.init().title("Value").bounds(0, 100));

chart.render(area, buf);

BarChart (src/widgets/barchart.zig)

Gráfico de barras.

const BarChart = @import("zcatui").widgets.BarChart;
const Bar = @import("zcatui").widgets.Bar;

const barchart = BarChart.init(&.{
    Bar.init(75).label("Mon"),
    Bar.init(90).label("Tue"),
    Bar.init(60).label("Wed"),
})
    .barWidth(5)
    .barGap(1);

barchart.render(area, buf);

Sparkline (src/widgets/sparkline.zig)

Mini-gráficos.

const Sparkline = @import("zcatui").widgets.Sparkline;

const spark = Sparkline.init(&data)
    .block(block)
    .style(Style.init().fg(Color.yellow));

spark.render(area, buf);

Calendar (src/widgets/calendar.zig)

Calendario mensual.

const Monthly = @import("zcatui").widgets.Monthly;
const Date = @import("zcatui").widgets.Date;

const calendar = Monthly.init(2024, 12)  // Año, mes
    .showWeekNumbers(true)
    .highlightToday(true);

calendar.render(area, buf);

Markdown (src/widgets/markdown.zig) - NUEVO v2.1

Renderizado de Markdown.

const Markdown = @import("zcatui").widgets.Markdown;

const md = Markdown.init(
    \\# Título
    \\
    \\Texto con **negrita** y *cursiva*.
    \\
    \\- Item 1
    \\- Item 2
    \\
    \\```zig
    \\const x = 42;
    \\```
);

md.render(area, buf);

Soporta:

  • Headers (# ## ###)
  • Bold y Italic
  • Listas (- y números)
  • Bloques de código
  • Citas (>)
  • Links text
  • Líneas horizontales (---)

SyntaxHighlighter (src/widgets/syntax.zig) - NUEVO v2.1

Resaltado de sintaxis.

const SyntaxHighlighter = @import("zcatui").widgets.SyntaxHighlighter;
const SyntaxLanguage = @import("zcatui").widgets.SyntaxLanguage;

const highlighter = SyntaxHighlighter.init(.zig)
    .showLineNumbers(true)
    .highlightLine(5);  // Resaltar línea 5

highlighter.render(code, area, buf);

Lenguajes soportados:

  • Zig, Rust, Go, C, C++
  • Python, JavaScript, TypeScript
  • JSON, Bash

Widgets de Overlay

Popup (src/widgets/popup.zig)

Ventanas emergentes y modales.

const Popup = @import("zcatui").widgets.Popup;
const Modal = @import("zcatui").widgets.Modal;

// Popup simple
const popup = Popup.init()
    .title("Info")
    .content("Message here")
    .percentSize(50, 30);

popup.render(area, buf);

// Modal con botones
const modal = Modal.confirm("Delete file?", &on_confirm);
modal.render(area, buf);

// Helpers
const confirm = confirmDialog("Sure?", &callback);
const alert = alertDialog("Error!", &callback);

Tooltip (src/widgets/tooltip.zig)

Tooltips posicionales.

const Tooltip = @import("zcatui").widgets.Tooltip;
const TooltipPosition = @import("zcatui").widgets.TooltipPosition;

const tooltip = Tooltip.init("Help text")
    .position(.below)
    .style(Style.init().bg(Color.yellow));

tooltip.render(anchor_x, anchor_y, buf);

Widgets de Contenedor

Viewport (src/widgets/viewport.zig) - NUEVO v2.1

Contenido scrollable.

const Viewport = @import("zcatui").widgets.Viewport;
const ViewportState = @import("zcatui").widgets.ViewportState;

var state = ViewportState{};

var viewport = try Viewport.init(allocator, 100, 500);  // content width x height
defer viewport.deinit();

// Renderizar contenido al buffer interno
const content_buf = viewport.buffer();
// ... render widgets to content_buf ...

// Scroll
viewport.scrollDown(1);
viewport.scrollUp(1);
viewport.pageDown(area.height);
viewport.pageUp(area.height);

viewport.render(area, buf);

ScrollView (src/widgets/scroll.zig)

Vista con scroll y virtualización.

const ScrollView = @import("zcatui").widgets.ScrollView;
const VirtualList = @import("zcatui").widgets.VirtualList;

// Lista virtual (solo renderiza items visibles)
const virtual = VirtualList.init(total_items, item_height, render_fn);
virtual.render(area, buf, &scroll_state);

Panel (src/widgets/panel.zig)

Paneles divididos.

const Panel = @import("zcatui").widgets.Panel;
const PanelSplit = @import("zcatui").widgets.PanelSplit;
const TabbedPanel = @import("zcatui").widgets.TabbedPanel;

// Panel split
const split = PanelSplit.horizontal()
    .ratio(0.3)  // 30% izquierda
    .gap(1);

const areas = split.split(area);
// areas[0] = izquierda, areas[1] = derecha

// Tabbed panel
const tabbed = TabbedPanel.init(&.{"Tab1", "Tab2"});
tabbed.render(area, buf, &state);

Widgets de Estado

StatusBar (src/widgets/statusbar.zig)

Barra de estado.

const StatusBar = @import("zcatui").widgets.StatusBar;
const StatusBarBuilder = @import("zcatui").widgets.StatusBarBuilder;

const status = StatusBarBuilder.init()
    .left("NORMAL")
    .center("file.zig")
    .right("Ln 42, Col 8")
    .build();

status.render(area, buf);

Toast (src/widgets/statusbar.zig)

Notificaciones temporales.

const Toast = @import("zcatui").widgets.Toast;
const ToastManager = @import("zcatui").widgets.ToastManager;

var toasts = ToastManager.init(allocator);
defer toasts.deinit();

try toasts.show("File saved!", .success, 3000);  // 3 segundos
try toasts.show("Error!", .err, 5000);

toasts.render(area, buf);

Help (src/widgets/help.zig) - NUEVO v2.1

Auto-genera ayuda de keybindings.

const Help = @import("zcatui").widgets.Help;
const KeyBinding = @import("zcatui").widgets.KeyBinding;
const CommonBindings = @import("zcatui").widgets.CommonBindings;

const help = Help.init(&.{
    KeyBinding.init("q", "Quit"),
    KeyBinding.init("?", "Help"),
    KeyBinding.init("j/k", "Up/Down"),
})
    .mode(.compact)  // .single_line, .multi_line, .full
    .separator(" | ");

help.render(area, buf);

// Bindings comunes predefinidos
const common = CommonBindings.vim();  // o .emacs(), .arrows()

Sistema de Eventos

EventReader (src/event/reader.zig)

const EventReader = @import("zcatui").EventReader;
const Event = @import("zcatui").Event;
const KeyCode = @import("zcatui").KeyCode;

var reader = try EventReader.init();
defer reader.deinit();

// Polling
if (try reader.poll(100)) {  // timeout ms
    const event = try reader.read();

    switch (event) {
        .key => |k| {
            if (k.code == .char and k.getChar() == 'q') {
                // Quit
            }
            if (k.code == .enter) {
                // Enter pressed
            }
            if (k.isCtrl() and k.getChar() == 'c') {
                // Ctrl+C
            }
        },
        .mouse => |m| {
            // m.column, m.row, m.kind, m.button
        },
        .resize => |r| {
            // r.width, r.height
        },
        .focus_gained, .focus_lost => {},
    }
}

KeyCode Values

KeyCode.enter
KeyCode.tab
KeyCode.backspace
KeyCode.escape
KeyCode.left, .right, .up, .down
KeyCode.home, .end
KeyCode.page_up, .page_down
KeyCode.insert, .delete
KeyCode.f1 ... KeyCode.f12
KeyCode.char  // con .getChar()

Layout y Posicionamiento

Layout (src/layout.zig)

const Layout = @import("zcatui").Layout;
const Constraint = @import("zcatui").Constraint;
const Direction = @import("zcatui").Direction;

// Dividir área
const chunks = Layout.init(.vertical)
    .constraints(&.{
        Constraint.length(3),      // 3 filas fijas
        Constraint.percentage(50), // 50% del resto
        Constraint.min(10),        // Mínimo 10
        Constraint.max(20),        // Máximo 20
        Constraint.ratio(1, 3),    // 1/3
    })
    .split(area);

Flex Layout - NUEVO v2.1

Layout CSS-like con justify y align.

const Flex = @import("zcatui").Flex;
const JustifyContent = @import("zcatui").JustifyContent;
const AlignItems = @import("zcatui").AlignItems;

const flex = Flex.horizontal()
    .setJustify(.space_between)  // .start, .end, .center, .space_around, .space_evenly
    .setAlign(.center)           // .start, .end, .center, .stretch
    .setGap(2)
    .setSizes(&.{20, 30, 20});   // Tamaños de items

const rects = flex.layout(area);
// rects[0], rects[1], rects[2]...

Helpers de Posicionamiento

const centerRect = @import("zcatui").centerRect;
const alignBottom = @import("zcatui").alignBottom;
const alignRight = @import("zcatui").alignRight;
const alignBottomRight = @import("zcatui").alignBottomRight;

// Centrar un área de 40x10 dentro de parent
const centered = centerRect(parent, 40, 10);

// Alinear al fondo
const bottom = alignBottom(parent, 3);  // 3 filas de alto

// Alinear a la derecha
const right_area = alignRight(parent, 20);  // 20 columnas de ancho

Themes y Estilos

Theme (src/theme.zig)

const Theme = @import("zcatui").Theme;

const theme = Theme{
    .background = Color.black,
    .foreground = Color.white,
    .primary = Color.blue,
    .secondary = Color.magenta,
    .success = Color.green,
    .warning = Color.yellow,
    .error_color = Color.red,
    .info = Color.cyan,
    .border = Color.indexed(240),
    // ... más colores
};

// Usar theme para estilos
const button_style = theme.buttonStyle();
const input_style = theme.inputStyle();

ThemeLoader - NUEVO v2.1

Hot-reload de themes desde archivos.

const ThemeLoader = @import("zcatui").ThemeLoader;
const ThemeWatcher = @import("zcatui").ThemeWatcher;

// Cargar theme
var loader = try ThemeLoader.init(allocator, "theme.json");
defer loader.deinit();

const theme = loader.getTheme();

// Watcher con auto-reload
var watcher = try ThemeWatcher.init(allocator, "theme.json", 1000);  // check cada 1s
defer watcher.deinit();

// En el event loop
if (watcher.poll()) {
    // Theme changed, re-render
}

Formato JSON:

{
  "primary": "#3498db",
  "secondary": "#9b59b6",
  "success": "green",
  "warning": "#f1c40f",
  "error": "red"
}

Formato KV:

# theme.conf
primary = #3498db
secondary = magenta
success = green

Innovaciones v2.1

Testing Framework (src/testing.zig)

Framework para tests de widgets.

const testing = @import("zcatui").testing_framework;
const WidgetHarness = @import("zcatui").WidgetHarness;
const SimulatedInput = @import("zcatui").SimulatedInput;
const Benchmark = @import("zcatui").Benchmark;

test "widget renders correctly" {
    var harness = WidgetHarness.init(std.testing.allocator, 40, 10);
    defer harness.deinit();

    // Renderizar widget
    const widget = MyWidget.init();
    harness.render(widget);

    // Assertions
    try harness.expectText(0, 0, "Hello");
    try harness.expectFg(0, 0, Color.red);
    try harness.expectNotEmpty(area);

    // Debug
    harness.debugPrint();
}

test "keyboard input" {
    // Simular eventos
    const key = SimulatedInput.key(.enter);
    const char = SimulatedInput.char('a');
    const click = SimulatedInput.click(10, 5, .left);
    const ctrl_c = SimulatedInput.keyWithMod(.{ .char = 'c' }, true, false, false);
}

test "benchmark" {
    var bench = Benchmark.start();

    var i: u32 = 0;
    while (i < 1000) : (i += 1) {
        widget.render(area, buf);
        bench.lap();
    }

    bench.report("Widget render");  // Imprime stats
}

Serialization (src/serialize.zig)

Guardar y restaurar estados de widgets.

const serialize = @import("zcatui").serialize;
const StateSnapshot = @import("zcatui").StateSnapshot;
const UndoStack = @import("zcatui").UndoStack;
const toJson = @import("zcatui").toJson;

// Serializar a JSON
const json = try toJson(allocator, my_state);
defer allocator.free(json);

// Snapshot de múltiples estados
var snapshot = StateSnapshot.init(allocator);
defer snapshot.deinit();

try snapshot.save("list", list_state);
try snapshot.save("table", table_state);

// Exportar todo
const all_json = try snapshot.exportAll();

// Undo/Redo
var undo = UndoStack(MyState).init(allocator, 50);  // max 50 items
defer undo.deinit();

try undo.push(current_state);

if (undo.canUndo()) {
    const prev = undo.undo();
}
if (undo.canRedo()) {
    const next = undo.redo();
}

Accessibility (src/accessibility.zig)

Soporte para lectores de pantalla y preferencias.

const a11y = @import("zcatui").accessibility;
const AccessibleInfo = @import("zcatui").AccessibleInfo;
const A11yRole = @import("zcatui").A11yRole;
const Announcer = @import("zcatui").Announcer;

// Verificar preferencias
if (a11y.prefersReducedMotion()) {
    // Desactivar animaciones
}
if (a11y.prefersHighContrast()) {
    theme = a11y.high_contrast_theme;
}

// Información accesible para widget
const info = AccessibleInfo{
    .role = .button,
    .label = "Submit",
    .disabled = false,
    .shortcut = "Enter",
};

// Anuncios para screen readers
var announcer = Announcer.init(allocator);
defer announcer.deinit();

try announcer.announce("Selection changed");
const output = try announcer.flush();
// Escribir output al terminal

// Skip links para navegación
var links = a11y.SkipLinks.init(allocator);
try links.register("main", "Main content", 10);
try links.register("footer", "Footer", 50);

Utilidades

Unicode (src/unicode.zig)

Cálculo de ancho de caracteres.

const unicode = @import("zcatui").unicode;

const width = unicode.charWidth('漢');  // 2 (full-width)
const str_width = unicode.stringWidth("Hello 世界");  // 11

const truncated = unicode.truncateToWidth("Long text here", 10);  // "Long text "

Terminal Capabilities (src/termcap.zig)

Detección de capacidades del terminal.

const termcap = @import("zcatui").termcap;

const caps = termcap.detect();

if (caps.color_support == .true_color) {
    // Usar colores RGB
}
if (caps.unicode) {
    // Usar caracteres Unicode
}
if (caps.mouse) {
    // Habilitar mouse
}

Animation (src/animation.zig)

Sistema de animaciones.

const Animation = @import("zcatui").Animation;
const Easing = @import("zcatui").Easing;
const Timer = @import("zcatui").Timer;

var anim = Animation.init(0, 100, 1000, .ease_out);  // from, to, duration_ms, easing

// En cada frame
anim.update(delta_ms);
const current_value = anim.value();

if (anim.isFinished()) {
    // Done
}

// Timer
var timer = Timer.init(5000);  // 5 segundos
timer.start();

if (timer.isExpired()) {
    // Timeout
}

Clipboard (src/clipboard.zig)

Acceso al portapapeles (OSC 52).

const Clipboard = @import("zcatui").Clipboard;

// Copiar
const seq = Clipboard.copy("Hello");
// Escribir seq al terminal

// Pegar (solicitar)
const req = Clipboard.requestPaste();
// Escribir req, leer respuesta

Links clickeables (OSC 8).

const Hyperlink = @import("zcatui").Hyperlink;

const link = Hyperlink.init("https://example.com", "Click here");
// link.start() ... text ... link.end()

Notifications (src/notification.zig)

Notificaciones de escritorio (OSC 9/777).

const Notification = @import("zcatui").Notification;

const notif = Notification.init("Title", "Body text");
// Escribir notif.sequence() al terminal

Images (src/image.zig)

Imágenes en terminal (Kitty/iTerm2).

const Kitty = @import("zcatui").Kitty;
const Iterm2 = @import("zcatui").Iterm2;

// Kitty protocol
const kitty = Kitty.init(image_data, width, height);
kitty.render(buf);

// iTerm2 protocol
const iterm = Iterm2.init(image_data);
iterm.render(buf);

Archivos del Proyecto

src/
├── root.zig              # Entry point, re-exports
├── buffer.zig            # Buffer, Cell, Rect, Symbol
├── style.zig             # Color, Style, Modifier
├── text.zig              # Text, Line, Span
├── layout.zig            # Layout, Constraint, Flex
├── terminal.zig          # Terminal abstraction
├── event.zig             # Event, KeyEvent, MouseEvent
├── event/
│   ├── reader.zig        # EventReader
│   └── parse.zig         # Escape parser
├── focus.zig             # FocusRing, FocusManager
├── theme.zig             # Theme definitions
├── animation.zig         # Animation, Easing, Timer
├── cursor.zig            # Cursor control
├── clipboard.zig         # OSC 52
├── hyperlink.zig         # OSC 8
├── notification.zig      # OSC 9/777
├── image.zig             # Kitty/iTerm2 images
├── lazy.zig              # RenderCache, Throttle
├── unicode.zig           # charWidth, stringWidth
├── termcap.zig           # Terminal capabilities
├── testing.zig           # Widget testing framework    [NEW v2.1]
├── theme_loader.zig      # Theme hot-reload           [NEW v2.1]
├── serialize.zig         # State serialization        [NEW v2.1]
├── accessibility.zig     # A11y support               [NEW v2.1]
├── backend/
│   └── backend.zig       # ANSI sequences
├── symbols/              # Line, border, block chars
└── widgets/
    ├── block.zig
    ├── paragraph.zig
    ├── list.zig
    ├── table.zig
    ├── gauge.zig
    ├── tabs.zig
    ├── sparkline.zig
    ├── scrollbar.zig
    ├── barchart.zig
    ├── canvas.zig
    ├── chart.zig
    ├── calendar.zig
    ├── clear.zig
    ├── input.zig
    ├── textarea.zig
    ├── popup.zig
    ├── menu.zig
    ├── tooltip.zig
    ├── tree.zig
    ├── filepicker.zig
    ├── scroll.zig
    ├── panel.zig
    ├── checkbox.zig
    ├── select.zig
    ├── slider.zig
    ├── statusbar.zig
    ├── spinner.zig        [NEW v2.1]
    ├── help.zig           [NEW v2.1]
    ├── viewport.zig       [NEW v2.1]
    ├── progress.zig       [NEW v2.1]
    ├── markdown.zig       [NEW v2.1]
    ├── dirtree.zig        [NEW v2.1]
    └── syntax.zig         [NEW v2.1]

Estadísticas v2.1

Métrica Valor
Archivos fuente 67 archivos .zig
Widgets 34 widgets
Módulos core 20 módulos
Tests 250+ tests
Examples 11 demos
Nuevos en v2.1 11 módulos/widgets

Changelog v2.1

Nuevos Widgets

  • Spinner: Indicadores de carga animados (17 estilos)
  • Help: Auto-genera ayuda de keybindings
  • Viewport: Scroll genérico con buffer interno
  • Progress: Barras de progreso con ETA y velocidad
  • Markdown: Renderizado de Markdown styled
  • DirectoryTree: Navegador de archivos
  • SyntaxHighlighter: Resaltado de sintaxis (10 lenguajes)

Nuevas Funcionalidades

  • Flex Layout: CSS-like justify/align
  • Widget Testing Framework: Harness, assertions, benchmarks
  • Theme Hot-Reload: Cargar themes desde archivos
  • Widget Serialization: JSON, undo/redo, snapshots
  • Accessibility: Roles ARIA, announcements, high contrast

Generado para zcatui v2.1 - Diciembre 2024