Popup widget: - Floating overlay with optional backdrop dimming - Configurable size and position (or centered) - Block wrapper support Modal widget: - Title, message, and action buttons - Keyboard navigation (Tab/arrows to switch buttons) - Helper functions: confirmDialog, alertDialog, yesNoCancelDialog Menu widgets: - MenuItem: action, separator, submenu, toggle types - Menu: Dropdown menu with selection navigation - MenuBar: Horizontal menu bar with dropdown support - Shortcut display support - Enabled/disabled state Example: menu_demo.zig with interactive menu bar and dialogs Tests: 11 tests for popup/menu, all pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
206 lines
6.7 KiB
Zig
206 lines
6.7 KiB
Zig
//! zcatui - Terminal User Interface library for Zig
|
|
//!
|
|
//! Inspired by ratatui (Rust), zcatui provides a simple and flexible way
|
|
//! to create text-based user interfaces in the terminal.
|
|
//!
|
|
//! ## Quick Start
|
|
//!
|
|
//! ```zig
|
|
//! const std = @import("std");
|
|
//! const zcatui = @import("zcatui");
|
|
//!
|
|
//! pub fn main() !void {
|
|
//! var term = try zcatui.Terminal.init();
|
|
//! defer term.deinit();
|
|
//!
|
|
//! try term.draw(ui);
|
|
//! }
|
|
//! ```
|
|
//!
|
|
//! ## Architecture
|
|
//!
|
|
//! zcatui uses immediate mode rendering with intermediate buffers:
|
|
//! - Each frame, all widgets are rendered to a Buffer
|
|
//! - Buffer is diffed against previous state
|
|
//! - Only changes are sent to the terminal
|
|
//!
|
|
|
|
const std = @import("std");
|
|
|
|
// Core types
|
|
pub const style = @import("style.zig");
|
|
pub const Color = style.Color;
|
|
pub const Style = style.Style;
|
|
pub const Modifier = style.Modifier;
|
|
|
|
pub const buffer = @import("buffer.zig");
|
|
pub const Cell = buffer.Cell;
|
|
pub const Buffer = buffer.Buffer;
|
|
pub const Rect = buffer.Rect;
|
|
pub const Symbol = buffer.Symbol;
|
|
pub const Margin = buffer.Margin;
|
|
pub const CellUpdate = buffer.CellUpdate;
|
|
pub const DiffIterator = buffer.DiffIterator;
|
|
|
|
pub const text = @import("text.zig");
|
|
pub const Span = text.Span;
|
|
pub const Line = text.Line;
|
|
pub const Text = text.Text;
|
|
pub const StyledGrapheme = text.StyledGrapheme;
|
|
pub const Alignment = text.Alignment;
|
|
|
|
// Re-exports for convenience
|
|
pub const terminal = @import("terminal.zig");
|
|
pub const Terminal = terminal.Terminal;
|
|
|
|
// Layout
|
|
pub const layout = @import("layout.zig");
|
|
pub const Layout = layout.Layout;
|
|
pub const Constraint = layout.Constraint;
|
|
pub const Direction = layout.Direction;
|
|
|
|
// Symbols (line drawing, borders, blocks, braille, etc.)
|
|
pub const symbols = @import("symbols/symbols.zig");
|
|
|
|
// Widgets
|
|
pub const widgets = struct {
|
|
pub const block_mod = @import("widgets/block.zig");
|
|
pub const Block = block_mod.Block;
|
|
pub const Borders = block_mod.Borders;
|
|
pub const BorderSet = block_mod.BorderSet;
|
|
|
|
pub const paragraph_mod = @import("widgets/paragraph.zig");
|
|
pub const Paragraph = paragraph_mod.Paragraph;
|
|
|
|
pub const list_mod = @import("widgets/list.zig");
|
|
pub const List = list_mod.List;
|
|
pub const ListItem = list_mod.ListItem;
|
|
pub const ListState = list_mod.ListState;
|
|
pub const ListDirection = list_mod.ListDirection;
|
|
pub const HighlightSpacing = list_mod.HighlightSpacing;
|
|
|
|
pub const gauge_mod = @import("widgets/gauge.zig");
|
|
pub const Gauge = gauge_mod.Gauge;
|
|
pub const LineGauge = gauge_mod.LineGauge;
|
|
|
|
pub const tabs_mod = @import("widgets/tabs.zig");
|
|
pub const Tabs = tabs_mod.Tabs;
|
|
|
|
pub const sparkline_mod = @import("widgets/sparkline.zig");
|
|
pub const Sparkline = sparkline_mod.Sparkline;
|
|
pub const RenderDirection = sparkline_mod.RenderDirection;
|
|
|
|
pub const scrollbar_mod = @import("widgets/scrollbar.zig");
|
|
pub const Scrollbar = scrollbar_mod.Scrollbar;
|
|
pub const ScrollbarState = scrollbar_mod.ScrollbarState;
|
|
pub const ScrollbarOrientation = scrollbar_mod.ScrollbarOrientation;
|
|
|
|
pub const barchart_mod = @import("widgets/barchart.zig");
|
|
pub const BarChart = barchart_mod.BarChart;
|
|
pub const Bar = barchart_mod.Bar;
|
|
pub const BarGroup = barchart_mod.BarGroup;
|
|
|
|
pub const table_mod = @import("widgets/table.zig");
|
|
pub const Table = table_mod.Table;
|
|
pub const TableState = table_mod.TableState;
|
|
pub const TableRow = table_mod.Row;
|
|
pub const TableCell = table_mod.Cell;
|
|
|
|
pub const canvas_mod = @import("widgets/canvas.zig");
|
|
pub const Canvas = canvas_mod.Canvas;
|
|
pub const CanvasPainter = canvas_mod.Painter;
|
|
pub const CanvasMarker = canvas_mod.Marker;
|
|
pub const CanvasLine = canvas_mod.Line;
|
|
pub const CanvasPoints = canvas_mod.Points;
|
|
pub const CanvasRectangle = canvas_mod.Rectangle;
|
|
pub const CanvasCircle = canvas_mod.Circle;
|
|
|
|
pub const chart_mod = @import("widgets/chart.zig");
|
|
pub const Chart = chart_mod.Chart;
|
|
pub const Axis = chart_mod.Axis;
|
|
pub const Dataset = chart_mod.Dataset;
|
|
pub const GraphType = chart_mod.GraphType;
|
|
pub const LegendPosition = chart_mod.LegendPosition;
|
|
|
|
pub const clear_mod = @import("widgets/clear.zig");
|
|
pub const Clear = clear_mod.Clear;
|
|
|
|
pub const calendar_mod = @import("widgets/calendar.zig");
|
|
pub const Monthly = calendar_mod.Monthly;
|
|
pub const Date = calendar_mod.Date;
|
|
pub const CalendarEventStore = calendar_mod.CalendarEventStore;
|
|
|
|
pub const input_mod = @import("widgets/input.zig");
|
|
pub const Input = input_mod.Input;
|
|
pub const InputState = input_mod.InputState;
|
|
|
|
pub const popup_mod = @import("widgets/popup.zig");
|
|
pub const Popup = popup_mod.Popup;
|
|
pub const Modal = popup_mod.Modal;
|
|
pub const ModalButton = popup_mod.ModalButton;
|
|
pub const confirmDialog = popup_mod.confirmDialog;
|
|
pub const alertDialog = popup_mod.alertDialog;
|
|
pub const yesNoCancelDialog = popup_mod.yesNoCancelDialog;
|
|
|
|
pub const menu_mod = @import("widgets/menu.zig");
|
|
pub const Menu = menu_mod.Menu;
|
|
pub const MenuItem = menu_mod.MenuItem;
|
|
pub const MenuItemType = menu_mod.MenuItemType;
|
|
pub const MenuBar = menu_mod.MenuBar;
|
|
pub const MenuBarItem = menu_mod.MenuBarItem;
|
|
};
|
|
|
|
// Backend
|
|
pub const backend = @import("backend/backend.zig");
|
|
|
|
// Events (crossterm-style)
|
|
pub const event = @import("event.zig");
|
|
pub const Event = event.Event;
|
|
pub const KeyEvent = event.KeyEvent;
|
|
pub const KeyCode = event.KeyCode;
|
|
pub const KeyModifiers = event.KeyModifiers;
|
|
pub const KeyEventKind = event.KeyEventKind;
|
|
pub const MouseEvent = event.MouseEvent;
|
|
pub const MouseEventKind = event.MouseEventKind;
|
|
pub const MouseButton = event.MouseButton;
|
|
pub const ResizeEvent = event.ResizeEvent;
|
|
|
|
pub const event_reader = @import("event/reader.zig");
|
|
pub const EventReader = event_reader.EventReader;
|
|
|
|
pub const event_parse = @import("event/parse.zig");
|
|
|
|
// Cursor control
|
|
pub const cursor = @import("cursor.zig");
|
|
pub const Cursor = cursor.Cursor;
|
|
pub const CursorStyle = cursor.CursorStyle;
|
|
|
|
// Animation system
|
|
pub const animation = @import("animation.zig");
|
|
pub const Animation = animation.Animation;
|
|
pub const AnimationGroup = animation.AnimationGroup;
|
|
pub const Easing = animation.Easing;
|
|
pub const Timer = animation.Timer;
|
|
|
|
// Clipboard (OSC 52)
|
|
pub const clipboard = @import("clipboard.zig");
|
|
pub const Clipboard = clipboard;
|
|
pub const ClipboardSelection = clipboard.Selection;
|
|
|
|
// ============================================================================
|
|
// Tests
|
|
// ============================================================================
|
|
|
|
test "zcatui module compiles" {
|
|
// Basic compilation test
|
|
_ = style;
|
|
_ = buffer;
|
|
}
|
|
|
|
test {
|
|
// Include all module tests
|
|
_ = @import("event.zig");
|
|
_ = @import("event/reader.zig");
|
|
_ = @import("event/parse.zig");
|
|
_ = @import("cursor.zig");
|
|
}
|