zcatui/docs/API.md
reugenio 560ed1b355 zcatui v1.0 - Implementacion completa de todos los widgets ratatui
Widgets implementados (13):
- Block, Paragraph, List, Table
- Gauge, LineGauge, Tabs, Sparkline
- Scrollbar, BarChart, Canvas, Chart
- Calendar (Monthly), Clear

Modulos:
- src/text.zig: Span, Line, Text, Alignment
- src/symbols/: line, border, block, bar, braille, half_block, scrollbar, marker
- src/widgets/: todos los widgets con tests

Documentacion:
- docs/ARCHITECTURE.md: arquitectura tecnica
- docs/WIDGETS.md: guia completa de widgets
- docs/API.md: referencia rapida
- CLAUDE.md: actualizado con estado v1.0

Tests: 103+ tests en widgets, todos pasan

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

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

644 lines
15 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# zcatui - API Reference
> Referencia rapida de la API publica de zcatui
## Importar la Libreria
```zig
const zcatui = @import("zcatui");
// Core types
const Color = zcatui.Color;
const Style = zcatui.Style;
const Modifier = zcatui.Modifier;
const Cell = zcatui.Cell;
const Buffer = zcatui.Buffer;
const Rect = zcatui.Rect;
const Span = zcatui.Span;
const Line = zcatui.Line;
const Text = zcatui.Text;
const Alignment = zcatui.Alignment;
// Layout
const Layout = zcatui.Layout;
const Constraint = zcatui.Constraint;
const Direction = zcatui.Direction;
// Terminal
const Terminal = zcatui.Terminal;
// Widgets
const widgets = zcatui.widgets;
const Block = widgets.Block;
const Paragraph = widgets.Paragraph;
const List = widgets.List;
const ListState = widgets.ListState;
// ... etc
```
---
## Core Types
### Color
```zig
pub const Color = union(enum) {
// Reset
reset,
// Basic 16 colors
black, red, green, yellow, blue, magenta, cyan, white,
light_black, light_red, light_green, light_yellow,
light_blue, light_magenta, light_cyan, light_white,
// 256 color palette
indexed: u8,
// True color (24-bit)
rgb: struct { r: u8, g: u8, b: u8 },
// Constructor helpers
pub fn indexed(n: u8) Color;
pub fn rgb(r: u8, g: u8, b: u8) Color;
};
```
**Ejemplos:**
```zig
const red = Color.red;
const gray = Color.indexed(240);
const custom = Color.rgb(255, 128, 0);
```
### Style
```zig
pub const Style = struct {
foreground: ?Color = null,
background: ?Color = null,
add_modifiers: Modifier = .{},
sub_modifiers: Modifier = .{},
pub const default: Style = .{};
// Fluent setters
pub fn fg(self: Style, color: Color) Style;
pub fn bg(self: Style, color: Color) Style;
pub fn bold(self: Style) Style;
pub fn dim(self: Style) Style;
pub fn italic(self: Style) Style;
pub fn underlined(self: Style) Style;
pub fn slow_blink(self: Style) Style;
pub fn rapid_blink(self: Style) Style;
pub fn reversed(self: Style) Style;
pub fn hidden(self: Style) Style;
pub fn crossed_out(self: Style) Style;
// Remove modifiers
pub fn notBold(self: Style) Style;
pub fn notDim(self: Style) Style;
// ... etc
// Combine styles
pub fn patch(self: Style, other: Style) Style;
};
```
**Ejemplos:**
```zig
const style1 = Style.default.fg(Color.red).bold();
const style2 = Style.default.bg(Color.blue).italic();
const combined = style1.patch(style2); // red fg, blue bg, bold+italic
```
### Modifier
```zig
pub const Modifier = packed struct {
bold: bool = false,
dim: bool = false,
italic: bool = false,
underlined: bool = false,
slow_blink: bool = false,
rapid_blink: bool = false,
reversed: bool = false,
hidden: bool = false,
crossed_out: bool = false,
pub const empty: Modifier = .{};
pub const all: Modifier = .{ .bold = true, ... };
pub fn contains(self: Modifier, other: Modifier) bool;
pub fn insert(self: Modifier, other: Modifier) Modifier;
pub fn remove(self: Modifier, other: Modifier) Modifier;
};
```
### Rect
```zig
pub const Rect = struct {
x: u16,
y: u16,
width: u16,
height: u16,
pub fn init(x: u16, y: u16, width: u16, height: u16) Rect;
// Getters
pub fn left(self: Rect) u16; // x
pub fn right(self: Rect) u16; // x + width
pub fn top(self: Rect) u16; // y
pub fn bottom(self: Rect) u16; // y + height
pub fn area(self: Rect) u32; // width * height
// Queries
pub fn isEmpty(self: Rect) bool;
pub fn contains(self: Rect, x: u16, y: u16) bool;
// Transformations
pub fn inner(self: Rect, margin: u16) Rect;
pub fn innerMargins(self: Rect, top: u16, right: u16, bottom: u16, left_: u16) Rect;
pub fn intersection(self: Rect, other: Rect) Rect;
pub fn union_(self: Rect, other: Rect) Rect;
};
```
**Ejemplos:**
```zig
const area = Rect.init(0, 0, 80, 24);
const inner = area.inner(1); // Rect.init(1, 1, 78, 22)
```
### Cell
```zig
pub const Cell = struct {
symbol: Symbol,
style: Style,
pub const default_val: Cell = .{ .symbol = Symbol.default_val, .style = Style.default };
pub fn reset(self: *Cell) void;
pub fn setChar(self: *Cell, ch: u21) void;
pub fn setSymbol(self: *Cell, symbol: []const u8) void;
pub fn setStyle(self: *Cell, style: Style) void;
};
pub const Symbol = struct {
data: [4]u8,
len: u3,
pub const default_val: Symbol; // " "
pub fn slice(self: Symbol) []const u8;
};
```
### Buffer
```zig
pub const Buffer = struct {
area: Rect,
cells: []Cell,
allocator: Allocator,
pub fn init(allocator: Allocator, area: Rect) !Buffer;
pub fn deinit(self: *Buffer) void;
pub fn empty(area: Rect) Buffer; // No allocation
// Cell access
pub fn getCell(self: *Buffer, x: u16, y: u16) ?*Cell;
pub fn index(self: Buffer, x: u16, y: u16) ?usize;
// Setting content
pub fn setString(self: *Buffer, x: u16, y: u16, text: []const u8, style: Style) u16;
pub fn setSpan(self: *Buffer, x: u16, y: u16, span: Span, width: u16) u16;
pub fn setLine(self: *Buffer, x: u16, y: u16, line: Line, width: u16) u16;
pub fn setStyle(self: *Buffer, area: Rect, style: Style) void;
// Filling
pub fn fill(self: *Buffer, cell: Cell) void;
pub fn fillArea(self: *Buffer, area: Rect, cell: Cell) void;
// Merging
pub fn merge(self: *Buffer, other: *const Buffer) void;
};
```
**Ejemplos:**
```zig
var buf = try Buffer.init(allocator, Rect.init(0, 0, 80, 24));
defer buf.deinit();
_ = buf.setString(10, 5, "Hello, World!", Style.default.fg(Color.green));
if (buf.getCell(10, 5)) |cell| {
cell.setStyle(Style.default.bold());
}
```
---
## Text Types
### Span
```zig
pub const Span = struct {
content: []const u8,
style: Style,
pub fn init(content: []const u8) Span;
pub fn raw(content: []const u8) Span;
pub fn styled(content: []const u8, style: Style) Span;
pub fn setStyle(self: Span, style: Style) Span;
pub fn width(self: Span) usize;
};
```
### Line
```zig
pub const Line = struct {
spans: []const Span,
alignment: Alignment,
pub fn init(spans: []const Span) Line;
pub fn raw(content: []const u8) Line;
pub fn styled(content: []const u8, style: Style) Line;
pub fn setStyle(self: Line, style: Style) Line;
pub fn setAlignment(self: Line, alignment: Alignment) Line;
pub fn width(self: Line) usize;
};
```
### Text
```zig
pub const Text = struct {
lines: []const Line,
alignment: Alignment,
pub fn init(lines: []const Line) Text;
pub fn raw(content: []const u8) Text;
pub fn styled(content: []const u8, style: Style) Text;
pub fn setStyle(self: Text, style: Style) Text;
pub fn setAlignment(self: Text, alignment: Alignment) Text;
pub fn width(self: Text) usize;
pub fn height(self: Text) usize;
};
```
### Alignment
```zig
pub const Alignment = enum {
left,
center,
right,
};
```
**Ejemplos:**
```zig
// Simple text
const span = Span.styled("Hello", Style.default.fg(Color.red));
const line = Line.raw("Simple line");
// Multi-span line
const multi_line = Line.init(&[_]Span{
Span.styled("Error: ", Style.default.fg(Color.red).bold()),
Span.raw("Something went wrong"),
});
// Multi-line text
const text = Text.raw("Line 1\nLine 2\nLine 3");
```
---
## Layout
### Layout
```zig
pub const Layout = struct {
direction: Direction,
constraints: []const Constraint,
pub fn horizontal(constraints: []const Constraint) Layout;
pub fn vertical(constraints: []const Constraint) Layout;
pub fn init(direction: Direction, constraints: []const Constraint) Layout;
pub fn split(self: Layout, area: Rect, result: []Rect) void;
};
```
### Constraint
```zig
pub const Constraint = union(enum) {
length: u16, // Exactly N cells
min: u16, // At least N cells
max: u16, // At most N cells
percentage: u16, // N% of available space (0-100)
ratio: struct { num: u32, den: u32 },
fill: u16, // Fill remaining space (weight)
pub fn length(n: u16) Constraint;
pub fn min(n: u16) Constraint;
pub fn max(n: u16) Constraint;
pub fn percentage(n: u16) Constraint;
pub fn ratio(num: u32, den: u32) Constraint;
pub fn fill(weight: u16) Constraint;
};
```
### Direction
```zig
pub const Direction = enum {
horizontal,
vertical,
};
```
**Ejemplos:**
```zig
// Vertical layout: header (3 rows), content (rest), footer (1 row)
const layout = Layout.vertical(&[_]Constraint{
Constraint.length(3),
Constraint.min(0),
Constraint.length(1),
});
var chunks: [3]Rect = undefined;
layout.split(area, &chunks);
// Horizontal split: 30% | 70%
const h_layout = Layout.horizontal(&[_]Constraint{
Constraint.percentage(30),
Constraint.percentage(70),
});
```
---
## Symbols
### Line Set
```zig
pub const line = struct {
pub const Set = struct {
vertical: []const u8,
horizontal: []const u8,
top_right: []const u8,
top_left: []const u8,
bottom_right: []const u8,
bottom_left: []const u8,
vertical_left: []const u8,
vertical_right: []const u8,
horizontal_down: []const u8,
horizontal_up: []const u8,
cross: []const u8,
};
pub const NORMAL: Set; // ─│┌┐└┘
pub const ROUNDED: Set; // ─│╭╮╰╯
pub const DOUBLE: Set; // ═║╔╗╚╝
pub const THICK: Set; // ━┃┏┓┗┛
};
```
### Border Set
```zig
pub const border = struct {
pub const Set = struct {
top_left: []const u8,
top_right: []const u8,
bottom_left: []const u8,
bottom_right: []const u8,
horizontal: []const u8,
vertical: []const u8,
};
pub const PLAIN: Set;
pub const ROUNDED: Set;
pub const DOUBLE: Set;
pub const THICK: Set;
};
```
### Block Characters
```zig
pub const block = struct {
pub const FULL: []const u8 = "█";
pub const UPPER_HALF: []const u8 = "▀";
pub const LOWER_HALF: []const u8 = "▄";
pub const LEFT_HALF: []const u8 = "▌";
pub const RIGHT_HALF: []const u8 = "▐";
// ...
};
```
### Bar Characters
```zig
pub const bar = struct {
pub const Set = struct {
full: []const u8,
seven_eighths: []const u8,
three_quarters: []const u8,
five_eighths: []const u8,
half: []const u8,
three_eighths: []const u8,
one_quarter: []const u8,
one_eighth: []const u8,
empty: []const u8,
};
pub const NINE_LEVELS: Set;
pub const THREE_LEVELS: Set;
};
```
### Braille
```zig
pub const braille = struct {
pub const BLANK: []const u8 = ""; // U+2800
// Bit positions for 2x4 grid:
// 0 3
// 1 4
// 2 5
// 6 7
pub const PATTERNS: [256][3]u8; // Pre-computed UTF-8 patterns
pub fn fromPattern(pattern: u8) []const u8;
};
```
### Marker
```zig
pub const Marker = enum {
dot,
block,
bar,
braille,
half_block,
};
```
---
## Terminal
```zig
pub const Terminal = struct {
pub fn init(allocator: Allocator) !Terminal;
pub fn deinit(self: *Terminal) void;
pub fn size(self: Terminal) struct { width: u16, height: u16 };
pub fn area(self: Terminal) Rect;
pub fn draw(self: *Terminal, render_fn: fn(area: Rect, buf: *Buffer) void) !void;
pub fn clear(self: *Terminal) !void;
pub fn flush(self: *Terminal) !void;
pub fn hideCursor(self: *Terminal) !void;
pub fn showCursor(self: *Terminal) !void;
pub fn setCursorPosition(self: *Terminal, x: u16, y: u16) !void;
pub fn enterAlternateScreen(self: *Terminal) !void;
pub fn leaveAlternateScreen(self: *Terminal) !void;
pub fn enableRawMode(self: *Terminal) !void;
pub fn disableRawMode(self: *Terminal) !void;
};
```
**Ejemplo de uso:**
```zig
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var term = try Terminal.init(allocator);
defer term.deinit();
try term.enterAlternateScreen();
defer term.leaveAlternateScreen() catch {};
try term.hideCursor();
defer term.showCursor() catch {};
try term.draw(struct {
pub fn render(area: Rect, buf: *Buffer) void {
const block = Block.bordered().title("Hello zcatui!");
block.render(area, buf);
}
}.render);
// Wait for input...
}
```
---
## Widgets Quick Reference
| Widget | Constructor | Stateful | Key Methods |
|--------|------------|----------|-------------|
| Block | `Block.init()` | No | `title()`, `borders()`, `borderStyle()` |
| Paragraph | `Paragraph.init(text)` | No | `setWrap()`, `setAlignment()`, `setScroll()` |
| List | `List.init(items)` | Yes | `setHighlightStyle()`, `setHighlightSymbol()` |
| Table | `Table.init(rows, widths)` | Yes | `setHeader()`, `setHighlightStyle()` |
| Gauge | `Gauge.init()` | No | `setRatio()`, `setPercent()`, `setLabel()` |
| LineGauge | `LineGauge.init()` | No | `setRatio()`, `setFilledStyle()` |
| Tabs | `Tabs.init(titles)` | No | `select()`, `setDivider()` |
| Sparkline | `Sparkline.init()` | No | `setData()`, `setMax()` |
| Scrollbar | `Scrollbar.init(orientation)` | Yes | `setSymbols()`, `setStyle()` |
| BarChart | `BarChart.init()` | No | `setData()`, `setBarWidth()` |
| Canvas | `Canvas.init()` | No | `setXBounds()`, `setYBounds()`, `paint()` |
| Chart | `Chart.init(datasets)` | No | `setXAxis()`, `setYAxis()` |
| Monthly | `Monthly.init(date)` | No | `showMonthHeader()`, `showWeekdaysHeader()` |
| Clear | `Clear.init()` | No | (none) |
---
## Error Handling
zcatui usa el sistema de errores de Zig. Las funciones que pueden fallar retornan `!T`.
```zig
// Errores comunes
const TerminalError = error{
InitFailed,
WriteFailed,
FlushFailed,
};
const BufferError = error{
OutOfMemory,
};
// Manejo tipico
var term = Terminal.init(allocator) catch |err| {
std.debug.print("Failed to init terminal: {}\n", .{err});
return err;
};
defer term.deinit();
```
---
## Patterns
### Builder Pattern
```zig
const widget = SomeWidget.init()
.setOption1(value1)
.setOption2(value2)
.setBlock(Block.bordered());
```
### Stateful Rendering
```zig
var state = WidgetState.init();
// En el loop de renderizado:
widget.renderStateful(area, buf, &state);
// Actualizar estado basado en input:
state.selectNext(items.len);
```
### Layout Composition
```zig
const outer = Layout.vertical(&[_]Constraint{
Constraint.length(3),
Constraint.min(0),
});
var outer_chunks: [2]Rect = undefined;
outer.split(area, &outer_chunks);
const inner = Layout.horizontal(&[_]Constraint{
Constraint.percentage(50),
Constraint.percentage(50),
});
var inner_chunks: [2]Rect = undefined;
inner.split(outer_chunks[1], &inner_chunks);
```