# zcatui - Documentacion de Widgets > Referencia completa de todos los widgets disponibles en zcatui ## Indice 1. [Block](#block) - Contenedor con bordes 2. [Paragraph](#paragraph) - Texto con wrapping 3. [List](#list) - Lista seleccionable 4. [Table](#table) - Tabla multi-columna 5. [Gauge](#gauge) - Barra de progreso 6. [LineGauge](#linegauge) - Progreso en linea 7. [Tabs](#tabs) - Navegacion por pestanas 8. [Sparkline](#sparkline) - Mini graficos 9. [Scrollbar](#scrollbar) - Indicador de scroll 10. [BarChart](#barchart) - Graficos de barras 11. [Canvas](#canvas) - Dibujo libre 12. [Chart](#chart) - Graficos con ejes 13. [Calendar](#calendar) - Calendario mensual 14. [Clear](#clear) - Limpiar area --- ## Block Widget base que proporciona bordes, titulos y padding. Usado como contenedor para otros widgets. ### Archivo `src/widgets/block.zig` ### Ejemplo Basico ```zig const block = Block.init() .title("Mi Titulo") .borders(Borders.all) .borderStyle(Style.default.fg(Color.blue)); block.render(area, buf); ``` ### API ```zig pub const Block = struct { // Constructores pub fn init() Block; pub fn bordered() Block; // Con bordes en todos los lados // Configuracion pub fn title(self: Block, t: []const u8) Block; pub fn titleStyle(self: Block, style: Style) Block; pub fn titleAlignment(self: Block, alignment: Alignment) Block; pub fn borders(self: Block, b: Borders) Block; pub fn borderStyle(self: Block, style: Style) Block; pub fn borderSet(self: Block, set: BorderSet) Block; pub fn style(self: Block, s: Style) Block; pub fn padding(self: Block, p: Padding) Block; // Utilidades pub fn inner(self: Block, area: Rect) Rect; pub fn horizontalSpace(self: Block) u16; pub fn verticalSpace(self: Block) u16; // Renderizado pub fn render(self: Block, area: Rect, buf: *Buffer) void; }; pub const Borders = packed struct { top: bool = false, right: bool = false, bottom: bool = false, left: bool = false, pub const none: Borders = .{}; pub const all: Borders = .{ .top = true, .right = true, .bottom = true, .left = true }; pub const top: Borders = .{ .top = true }; // etc. }; ``` ### Border Sets Disponibles | Set | Descripcion | Caracteres | |-----|-------------|------------| | `plain` | Lineas simples | `─ │ ┌ ┐ └ ┘` | | `rounded` | Esquinas redondeadas | `─ │ ╭ ╮ ╰ ╯` | | `double` | Lineas dobles | `═ ║ ╔ ╗ ╚ ╝` | | `thick` | Lineas gruesas | `━ ┃ ┏ ┓ ┗ ┛` | --- ## Paragraph Widget para mostrar texto con word-wrapping, alineacion y scroll. ### Archivo `src/widgets/paragraph.zig` ### Ejemplo Basico ```zig const text = Text.raw("Este es un texto largo que sera\nenvuelto automaticamente si es necesario."); const para = Paragraph.init(text) .setBlock(Block.bordered().title("Info")) .setWrap(.{ .trim = true }) .setAlignment(.center); para.render(area, buf); ``` ### API ```zig pub const Paragraph = struct { pub fn init(text: Text) Paragraph; pub fn initWithSpans(spans: []const Span) Paragraph; pub fn setBlock(self: Paragraph, block: Block) Paragraph; pub fn setStyle(self: Paragraph, style: Style) Paragraph; pub fn setWrap(self: Paragraph, wrap: Wrap) Paragraph; pub fn setAlignment(self: Paragraph, alignment: Alignment) Paragraph; pub fn setScroll(self: Paragraph, offset: struct { x: u16, y: u16 }) Paragraph; pub fn render(self: Paragraph, area: Rect, buf: *Buffer) void; }; pub const Wrap = struct { trim: bool = false, // Eliminar espacios extra }; ``` --- ## List Lista seleccionable con soporte para scroll automatico y highlighting. ### Archivo `src/widgets/list.zig` ### Ejemplo Basico ```zig const items = [_]ListItem{ ListItem.init(Line.raw("Item 1")), ListItem.init(Line.raw("Item 2")).setStyle(Style.default.fg(Color.red)), ListItem.init(Line.raw("Item 3")), }; var state = ListState.init(); state.select(1); // Seleccionar segundo item const list = List.init(&items) .setBlock(Block.bordered().title("Lista")) .setHighlightStyle(Style.default.bg(Color.blue)) .setHighlightSymbol("> "); list.renderStateful(area, buf, &state); ``` ### API ```zig pub const List = struct { pub fn init(items: []const ListItem) List; pub fn setBlock(self: List, block: Block) List; pub fn setStyle(self: List, style: Style) List; pub fn setHighlightStyle(self: List, style: Style) List; pub fn setHighlightSymbol(self: List, symbol: []const u8) List; pub fn setHighlightSpacing(self: List, spacing: HighlightSpacing) List; pub fn setDirection(self: List, direction: ListDirection) List; pub fn setRepeatHighlightSymbol(self: List, repeat: bool) List; pub fn render(self: List, area: Rect, buf: *Buffer) void; pub fn renderStateful(self: List, area: Rect, buf: *Buffer, state: *ListState) void; }; pub const ListState = struct { selected: ?usize = null, offset: usize = 0, pub fn init() ListState; pub fn select(self: *ListState, index: usize) void; pub fn selectNext(self: *ListState, len: usize) void; pub fn selectPrevious(self: *ListState) void; }; pub const ListDirection = enum { top_to_bottom, bottom_to_top }; ``` --- ## Table Tabla multi-columna con headers, footers y seleccion de filas. ### Archivo `src/widgets/table.zig` ### Ejemplo Basico ```zig const header = Row.init(&[_]Cell{ Cell.init(Line.raw("Nombre")), Cell.init(Line.raw("Edad")), Cell.init(Line.raw("Ciudad")), }).setStyle(Style.default.bold()); const rows = [_]Row{ Row.init(&[_]Cell{ Cell.init(Line.raw("Ana")), Cell.init(Line.raw("25")), Cell.init(Line.raw("Madrid")), }), Row.init(&[_]Cell{ Cell.init(Line.raw("Juan")), Cell.init(Line.raw("30")), Cell.init(Line.raw("Barcelona")), }), }; const widths = [_]Constraint{ Constraint.percentage(40), Constraint.length(10), Constraint.fill(1), }; var state = TableState.init(); state.select(0); const table = Table.init(&rows, &widths) .setHeader(header) .setBlock(Block.bordered().title("Usuarios")) .setHighlightStyle(Style.default.bg(Color.yellow)); table.renderStateful(area, buf, &state); ``` ### API ```zig pub const Table = struct { pub fn init(rows: []const Row, widths: []const Constraint) Table; pub fn setHeader(self: Table, header: Row) Table; pub fn setFooter(self: Table, footer: Row) Table; pub fn setBlock(self: Table, block: Block) Table; pub fn setStyle(self: Table, style: Style) Table; pub fn setHighlightStyle(self: Table, style: Style) Table; pub fn setHighlightSymbol(self: Table, symbol: []const u8) Table; pub fn setColumnSpacing(self: Table, spacing: u16) Table; pub fn render(self: Table, area: Rect, buf: *Buffer) void; pub fn renderStateful(self: Table, area: Rect, buf: *Buffer, state: *TableState) void; }; pub const TableState = struct { selected: ?usize = null, offset: usize = 0; pub fn init() TableState; pub fn select(self: *TableState, index: usize) void; }; ``` --- ## Gauge Barra de progreso usando caracteres de bloque. ### Archivo `src/widgets/gauge.zig` ### Ejemplo Basico ```zig const gauge = Gauge.init() .setRatio(0.75) .setLabel("75%") .setBlock(Block.bordered().title("Progreso")) .setGaugeStyle(Style.default.fg(Color.green).bg(Color.black)); gauge.render(area, buf); ``` ### API ```zig pub const Gauge = struct { pub fn init() Gauge; pub fn setRatio(self: Gauge, ratio: f64) Gauge; // 0.0 - 1.0 pub fn setPercent(self: Gauge, percent: u16) Gauge; // 0 - 100 pub fn setLabel(self: Gauge, label: []const u8) Gauge; pub fn setBlock(self: Gauge, block: Block) Gauge; pub fn setStyle(self: Gauge, style: Style) Gauge; pub fn setGaugeStyle(self: Gauge, style: Style) Gauge; pub fn setUseUnicode(self: Gauge, use: bool) Gauge; pub fn render(self: Gauge, area: Rect, buf: *Buffer) void; }; ``` --- ## LineGauge Barra de progreso en una sola linea. ### Archivo `src/widgets/gauge.zig` ### Ejemplo Basico ```zig const gauge = LineGauge.init() .setRatio(0.5) .setLabel("Loading...") .setLineSet(symbols.line.NORMAL) .setFilledStyle(Style.default.fg(Color.cyan)) .setUnfilledStyle(Style.default.fg(Color.white)); gauge.render(area, buf); ``` ### API ```zig pub const LineGauge = struct { pub fn init() LineGauge; pub fn setRatio(self: LineGauge, ratio: f64) LineGauge; pub fn setLabel(self: LineGauge, label: []const u8) LineGauge; pub fn setBlock(self: LineGauge, block: Block) LineGauge; pub fn setStyle(self: LineGauge, style: Style) LineGauge; pub fn setFilledStyle(self: LineGauge, style: Style) LineGauge; pub fn setUnfilledStyle(self: LineGauge, style: Style) LineGauge; pub fn setLineSet(self: LineGauge, set: symbols.line.Set) LineGauge; pub fn render(self: LineGauge, area: Rect, buf: *Buffer) void; }; ``` --- ## Tabs Widget de navegacion por pestanas. ### Archivo `src/widgets/tabs.zig` ### Ejemplo Basico ```zig const titles = [_]Line{ Line.raw("Tab 1"), Line.raw("Tab 2"), Line.raw("Tab 3"), }; const tabs = Tabs.init(&titles) .select(1) .setBlock(Block.bordered()) .setHighlightStyle(Style.default.fg(Color.yellow).bold()) .setDivider(" | "); tabs.render(area, buf); ``` ### API ```zig pub const Tabs = struct { pub fn init(titles: []const Line) Tabs; pub fn select(self: Tabs, index: usize) Tabs; pub fn setBlock(self: Tabs, block: Block) Tabs; pub fn setStyle(self: Tabs, style: Style) Tabs; pub fn setHighlightStyle(self: Tabs, style: Style) Tabs; pub fn setDivider(self: Tabs, divider: []const u8) Tabs; pub fn setPadding(self: Tabs, left: []const u8, right: []const u8) Tabs; pub fn render(self: Tabs, area: Rect, buf: *Buffer) void; }; ``` --- ## Sparkline Mini grafico de linea usando caracteres de bloque. ### Archivo `src/widgets/sparkline.zig` ### Ejemplo Basico ```zig const data = [_]u64{ 0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4 }; const spark = Sparkline.init() .setData(&data) .setMax(5) .setBlock(Block.bordered().title("CPU")) .setStyle(Style.default.fg(Color.cyan)) .setDirection(.left_to_right); spark.render(area, buf); ``` ### API ```zig pub const Sparkline = struct { pub fn init() Sparkline; pub fn setData(self: Sparkline, data: []const u64) Sparkline; pub fn setMax(self: Sparkline, max: u64) Sparkline; pub fn setBlock(self: Sparkline, block: Block) Sparkline; pub fn setStyle(self: Sparkline, style: Style) Sparkline; pub fn setBarSet(self: Sparkline, set: symbols.bar.Set) Sparkline; pub fn setDirection(self: Sparkline, direction: RenderDirection) Sparkline; pub fn render(self: Sparkline, area: Rect, buf: *Buffer) void; }; pub const RenderDirection = enum { left_to_right, right_to_left }; ``` --- ## Scrollbar Indicador visual de posicion de scroll. ### Archivo `src/widgets/scrollbar.zig` ### Ejemplo Basico ```zig var state = ScrollbarState.init(100) // 100 items totales .setPosition(25) // Posicion actual .setViewportContentLength(20); // Items visibles const scrollbar = Scrollbar.init(.vertical_right) .setSymbols(.{ .track = "│", .thumb = "█" }) .setStyle(Style.default.fg(Color.white)); scrollbar.render(area, buf, &state); ``` ### API ```zig pub const Scrollbar = struct { pub fn init(orientation: ScrollbarOrientation) Scrollbar; pub fn setOrientation(self: Scrollbar, o: ScrollbarOrientation) Scrollbar; pub fn setThumbSymbol(self: Scrollbar, symbol: []const u8) Scrollbar; pub fn setTrackSymbol(self: Scrollbar, symbol: ?[]const u8) Scrollbar; pub fn setBeginSymbol(self: Scrollbar, symbol: ?[]const u8) Scrollbar; pub fn setEndSymbol(self: Scrollbar, symbol: ?[]const u8) Scrollbar; pub fn setSymbols(self: Scrollbar, symbols: ScrollbarSymbols) Scrollbar; pub fn setStyle(self: Scrollbar, style: Style) Scrollbar; pub fn setThumbStyle(self: Scrollbar, style: Style) Scrollbar; pub fn setTrackStyle(self: Scrollbar, style: Style) Scrollbar; pub fn render(self: Scrollbar, area: Rect, buf: *Buffer, state: *ScrollbarState) void; }; pub const ScrollbarState = struct { pub fn init(content_length: usize) ScrollbarState; pub fn setPosition(self: ScrollbarState, position: usize) ScrollbarState; pub fn setViewportContentLength(self: ScrollbarState, length: usize) ScrollbarState; }; pub const ScrollbarOrientation = enum { vertical_right, vertical_left, horizontal_bottom, horizontal_top, }; ``` --- ## BarChart Graficos de barras con soporte para grupos. ### Archivo `src/widgets/barchart.zig` ### Ejemplo Basico ```zig const bars = [_]Bar{ Bar.init(50).setLabel("Ene").setStyle(Style.default.fg(Color.red)), Bar.init(80).setLabel("Feb").setStyle(Style.default.fg(Color.green)), Bar.init(65).setLabel("Mar").setStyle(Style.default.fg(Color.blue)), }; const group = BarGroup.init(&bars).setLabel("Q1 2024"); const groups = [_]BarGroup{group}; const chart = BarChart.init() .setData(&groups) .setBarWidth(5) .setBarGap(1) .setGroupGap(2) .setBlock(Block.bordered().title("Ventas")) .setMax(100); chart.render(area, buf); ``` ### API ```zig pub const BarChart = struct { pub fn init() BarChart; pub fn setData(self: BarChart, data: []const BarGroup) BarChart; pub fn setBlock(self: BarChart, block: Block) BarChart; pub fn setBarWidth(self: BarChart, width: u16) BarChart; pub fn setBarGap(self: BarChart, gap: u16) BarChart; pub fn setGroupGap(self: BarChart, gap: u16) BarChart; pub fn setBarStyle(self: BarChart, style: Style) BarChart; pub fn setLabelStyle(self: BarChart, style: Style) BarChart; pub fn setValueStyle(self: BarChart, style: Style) BarChart; pub fn setStyle(self: BarChart, style: Style) BarChart; pub fn setMax(self: BarChart, max: u64) BarChart; pub fn setDirection(self: BarChart, dir: Direction) BarChart; pub fn render(self: BarChart, area: Rect, buf: *Buffer) void; }; pub const Bar = struct { pub fn init(value: u64) Bar; pub fn setLabel(self: Bar, label: []const u8) Bar; pub fn setStyle(self: Bar, style: Style) Bar; pub fn setValueStyle(self: Bar, style: Style) Bar; pub fn setTextValue(self: Bar, text: []const u8) Bar; }; pub const BarGroup = struct { pub fn init(bars: []const Bar) BarGroup; pub fn setLabel(self: BarGroup, label: []const u8) BarGroup; }; ``` --- ## Canvas Widget para dibujo libre con diferentes tipos de marcadores. ### Archivo `src/widgets/canvas.zig` ### Ejemplo Basico ```zig const canvas = Canvas.init() .setXBounds(-10.0, 10.0) .setYBounds(-10.0, 10.0) .setMarker(.braille) .setBlock(Block.bordered().title("Canvas")) .paint(struct { pub fn draw(painter: *Painter) void { // Dibujar una linea painter.line(0, 0, 10, 10, Color.red); // Dibujar un rectangulo painter.rectangle(2, 2, 8, 8, Color.blue); // Dibujar un circulo painter.circle(5, 5, 3, Color.green); // Dibujar puntos individuales painter.point(0, 0, Color.yellow); } }.draw); canvas.render(area, buf); ``` ### API ```zig pub const Canvas = struct { pub fn init() Canvas; pub fn setXBounds(self: Canvas, min: f64, max: f64) Canvas; pub fn setYBounds(self: Canvas, min: f64, max: f64) Canvas; pub fn setMarker(self: Canvas, marker: Marker) Canvas; pub fn setBlock(self: Canvas, block: Block) Canvas; pub fn setBackgroundColor(self: Canvas, color: Color) Canvas; pub fn paint(self: Canvas, painter_fn: *const fn(*Painter) void) Canvas; pub fn render(self: Canvas, area: Rect, buf: *Buffer) void; }; pub const Marker = enum { dot, // Punto simple block, // Caracter bloque completo bar, // Barras verticales braille, // Patrones braille (2x4 por celda) half_block, // Half-blocks (1x2 por celda) }; pub const Painter = struct { pub fn point(self: *Painter, x: f64, y: f64, color: Color) void; pub fn line(self: *Painter, x1: f64, y1: f64, x2: f64, y2: f64, color: Color) void; pub fn rectangle(self: *Painter, x: f64, y: f64, width: f64, height: f64, color: Color) void; pub fn circle(self: *Painter, x: f64, y: f64, radius: f64, color: Color) void; }; ``` ### Resoluciones por Marker | Marker | Resolucion por celda | Uso recomendado | |--------|---------------------|-----------------| | `dot` | 1x1 | Simple, compatible | | `block` | 1x1 | Relleno solido | | `bar` | 8x1 | Barras horizontales | | `braille` | 2x4 | Alta resolucion | | `half_block` | 1x2 | Resolucion media | --- ## Chart Graficos de linea, scatter y barras con ejes X/Y. ### Archivo `src/widgets/chart.zig` ### Ejemplo Basico ```zig const data1 = [_][2]f64{ .{ 0, 0 }, .{ 1, 1 }, .{ 2, 4 }, .{ 3, 9 }, .{ 4, 16 }, }; const data2 = [_][2]f64{ .{ 0, 16 }, .{ 1, 9 }, .{ 2, 4 }, .{ 3, 1 }, .{ 4, 0 }, }; const datasets = [_]Dataset{ Dataset.init(&data1) .setName("x^2") .setMarker(.braille) .setGraphType(.line) .setStyle(Style.default.fg(Color.cyan)), Dataset.init(&data2) .setName("(4-x)^2") .setMarker(.braille) .setGraphType(.scatter) .setStyle(Style.default.fg(Color.yellow)), }; const x_axis = Axis.init() .setTitle("X") .setBounds(0, 4) .setLabels(&[_][]const u8{ "0", "1", "2", "3", "4" }); const y_axis = Axis.init() .setTitle("Y") .setBounds(0, 16); const chart = Chart.init(&datasets) .setXAxis(x_axis) .setYAxis(y_axis) .setBlock(Block.bordered().title("Grafico")) .setLegendPosition(.top_right); chart.render(area, buf); ``` ### API ```zig pub const Chart = struct { pub fn init(datasets: []const Dataset) Chart; pub fn setXAxis(self: Chart, axis: Axis) Chart; pub fn setYAxis(self: Chart, axis: Axis) Chart; pub fn setBlock(self: Chart, block: Block) Chart; pub fn setStyle(self: Chart, style: Style) Chart; pub fn setLegendPosition(self: Chart, pos: ?LegendPosition) Chart; pub fn setHideLegendConstraint(self: Chart, constraint: Constraint) Chart; pub fn render(self: Chart, area: Rect, buf: *Buffer) void; }; pub const Dataset = struct { pub fn init(data: []const [2]f64) Dataset; pub fn setName(self: Dataset, name: []const u8) Dataset; pub fn setData(self: Dataset, data: []const [2]f64) Dataset; pub fn setMarker(self: Dataset, marker: Marker) Dataset; pub fn setGraphType(self: Dataset, graph_type: GraphType) Dataset; pub fn setStyle(self: Dataset, style: Style) Dataset; }; pub const Axis = struct { pub fn init() Axis; pub fn setTitle(self: Axis, title: []const u8) Axis; pub fn setTitleStyle(self: Axis, style: Style) Axis; pub fn setBounds(self: Axis, min: f64, max: f64) Axis; pub fn setLabels(self: Axis, labels: []const []const u8) Axis; pub fn setLabelsAlignment(self: Axis, alignment: Alignment) Axis; pub fn setStyle(self: Axis, style: Style) Axis; }; pub const GraphType = enum { scatter, line, bar }; pub const LegendPosition = enum { top_left, top_right, bottom_left, bottom_right }; ``` --- ## Calendar Calendario mensual con soporte para eventos y estilos personalizados. ### Archivo `src/widgets/calendar.zig` ### Ejemplo Basico ```zig // Crear eventos con estilos var events = CalendarEventStore.init(); events.add(Date.init(2024, 12, 25), Style.default.fg(Color.red).bold()); events.add(Date.init(2024, 12, 31), Style.default.fg(Color.yellow)); const calendar = Monthly.init(Date.init(2024, 12, 1)) .withEvents(events) .showMonthHeader(Style.default.fg(Color.blue).bold()) .showWeekdaysHeader(Style.default.fg(Color.cyan)) .showSurrounding(Style.default.fg(Color.white)) .setDefaultStyle(Style.default) .setBlock(Block.bordered()); calendar.render(area, buf); ``` ### Salida Visual ``` ┌──────────────────────┐ │ December 2024 │ │ Su Mo Tu We Th Fr Sa │ │ 1 2 3 4 5 6 7 │ │ 8 9 10 11 12 13 14 │ │ 15 16 17 18 19 20 21 │ │ 22 23 24 25 26 27 28 │ │ 29 30 31 │ └──────────────────────┘ ``` ### API ```zig pub const Monthly = struct { pub fn init(display_date: Date) Monthly; pub fn withEvents(display_date: Date, events: CalendarEventStore) Monthly; pub fn showSurrounding(self: Monthly, style: Style) Monthly; pub fn showWeekdaysHeader(self: Monthly, style: Style) Monthly; pub fn showMonthHeader(self: Monthly, style: Style) Monthly; pub fn setDefaultStyle(self: Monthly, style: Style) Monthly; pub fn setBlock(self: Monthly, block: Block) Monthly; pub fn width(self: Monthly) u16; // Siempre 21 + bordes pub fn height(self: Monthly) u16; // Variable segun mes pub fn render(self: Monthly, area: Rect, buf: *Buffer) void; }; pub const Date = struct { year: i16, month: u4, // 1-12 day: u5, // 1-31 pub fn init(year: i16, month: u4, day: u5) Date; pub fn isLeapYear(self: Date) bool; pub fn daysInMonth(self: Date) u5; pub fn dayOfWeek(self: Date) u3; // 0=Sunday pub fn monthName(self: Date) []const u8; }; pub const CalendarEventStore = struct { pub fn init() CalendarEventStore; pub fn add(self: *CalendarEventStore, date: Date, style: Style) void; pub fn getStyle(self: CalendarEventStore, date: Date) Style; }; ``` --- ## Clear Widget simple que limpia/resetea un area de la pantalla. ### Archivo `src/widgets/clear.zig` ### Ejemplo Basico ```zig // Limpiar todo el area antes de renderizar otros widgets Clear.init().render(area, buf); // Ahora renderizar contenido fresco my_widget.render(area, buf); ``` ### API ```zig pub const Clear = struct { pub fn init() Clear; pub fn render(self: Clear, area: Rect, buf: *Buffer) void; }; ``` ### Uso Tipico Clear es util cuando: 1. Necesitas borrar contenido previo antes de re-renderizar 2. Quieres resetear estilos de un area especifica 3. Implementas transiciones entre pantallas --- ## Patrones Comunes ### Composicion de Widgets ```zig // Crear un layout dividido const chunks = Layout.vertical(&[_]Constraint{ Constraint.length(3), // Header Constraint.min(0), // Contenido Constraint.length(1), // Footer }).split(area); // Renderizar widgets en cada area Block.bordered().title("Header").render(chunks[0], buf); list.renderStateful(chunks[1], buf, &list_state); Paragraph.init("Status: OK").render(chunks[2], buf); ``` ### Widgets Anidados ```zig // List con block personalizado const list = List.init(items) .setBlock( Block.bordered() .title("Items") .titleStyle(Style.default.bold()) .borderStyle(Style.default.fg(Color.cyan)) ); ``` ### Estilos Condicionales ```zig const item_style = if (is_selected) Style.default.bg(Color.blue).fg(Color.white) else if (is_important) Style.default.fg(Color.red).bold() else Style.default; ```