### Quick Start: Interactive Component Setup Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Demonstrates setting up focus management, creating component states, handling keyboard events for navigation, and rendering components with focus awareness. Mouse click handling is also shown. ```rust use ratatui_interact::prelude::*; // Define focusable elements #[derive(Clone, Eq, PartialEq, Hash)] enum Element { NameInput, EnableCheckbox, SubmitButton, } // Set up focus manager let mut focus = FocusManager::new(); focus.register(Element::NameInput); focus.register(Element::EnableCheckbox); focus.register(Element::SubmitButton); // Create component states let mut input_state = InputState::new("Hello"); let mut checkbox_state = CheckBoxState::new(false); let button_state = ButtonState::enabled(); // Handle keyboard events match event { Event::Key(key) if is_tab(key) => focus.next(), Event::Key(key) if is_shift_tab(key) => focus.prev(), _ => {} } // Render with focus awareness let input = Input::new(&input_state) .label("Name") .focused(focus.is_focused(&Element::NameInput)); let click_region = input.render_stateful(frame, area); // Handle mouse clicks if let Some(element) = click_region.contains(mouse_x, mouse_y) { focus.focus(&element); } ``` -------------------------------- ### Run Navigation Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the navigation demo example, featuring ListPicker and TreeView components. ```bash cargo run --example navigation_demo ``` -------------------------------- ### Run Theme Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the theme demo example, demonstrating the theme system with dark/light switching. ```bash cargo run --example theme_demo ``` -------------------------------- ### Run Display Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the display demo example, showcasing progress indicators, StepDisplay, and ParagraphExt. ```bash cargo run --example display_demo ``` -------------------------------- ### Run Select Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the select demo example, demonstrating dropdown select boxes. ```bash cargo run --example select_demo ``` -------------------------------- ### Run Spinner Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the spinner demo example, demonstrating animated loading indicators. ```bash cargo run --example spinner_demo ``` -------------------------------- ### Run Input Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the input demo example, demonstrating text input with a cursor. ```bash cargo run --example input_demo ``` -------------------------------- ### Run Dialog Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the dialog demo example, showcasing modal dialogs. ```bash cargo run --example dialog_demo ``` -------------------------------- ### Run Textarea Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the textarea demo example, showcasing multi-line text input. ```bash cargo run --example textarea_demo ``` -------------------------------- ### Run Context Menu Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the context menu demo example, showcasing right-click context menus. ```bash cargo run --example context_menu_demo ``` -------------------------------- ### Run Accordion Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the accordion demo example, showcasing collapsible sections. ```bash cargo run --example accordion_demo ``` -------------------------------- ### Run Hotkey Dialog Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the hotkey dialog demo example, demonstrating a hotkey configuration dialog. ```bash cargo run --example hotkey_dialog_demo ``` -------------------------------- ### Run Split Pane Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the split pane demo example, showcasing resizable split panes. ```bash cargo run --example split_pane_demo ``` -------------------------------- ### Run Button Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the button demo example, illustrating various button variants and styles. ```bash cargo run --example button_demo ``` -------------------------------- ### Run Menu Bar Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the menu bar demo example, demonstrating a file/edit/view/help style menu bar. ```bash cargo run --example menu_bar_demo ``` -------------------------------- ### Run Marquee Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the marquee demo example, demonstrating scrolling text animation. ```bash cargo run --example marquee_demo ``` -------------------------------- ### Run Breadcrumb Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the breadcrumb demo example, demonstrating hierarchical path navigation. ```bash cargo run --example breadcrumb_demo ``` -------------------------------- ### Run Tab View Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the tab view demo example, demonstrating a tab bar with different positioning options. ```bash cargo run --example tab_view_demo ``` -------------------------------- ### Run Copyable Pane Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the copyable pane demo example, featuring ScrollableContent with View/Copy mode. ```bash cargo run --example copyable_pane_demo ``` -------------------------------- ### Run Checkbox Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the checkbox demo example, showcasing different styles of checkboxes. ```bash cargo run --example checkbox_demo ``` -------------------------------- ### Run Diff Viewer Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the diff viewer demo example, demonstrating unified and side-by-side diff modes. ```bash cargo run --example diff_viewer_demo ``` -------------------------------- ### Run Toast Stack Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the toast stack demo example, showing multiple simultaneous toasts with dismiss policies. ```bash cargo run --example toast_stack_demo ``` -------------------------------- ### Run Mouse Pointer Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the mouse pointer demo example, showing a mouse cursor indicator. ```bash cargo run --example mouse_pointer_demo ``` -------------------------------- ### Run Animated Text Demo Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the animated text demo example, featuring animated text with color effects. ```bash cargo run --example animated_text_demo ``` -------------------------------- ### StepDisplay: Define and Drive Workflow Source: https://context7.com/brainwires/ratatui-interact/llms.txt Shows how to define a multi-step workflow with sub-steps and statuses, initialize the state, and drive the workflow by starting, completing, or failing steps and sub-steps. Includes adding output lines per step. ```rust use ratatui_interact::components::{ Step, SubStep, StepDisplay, StepDisplayState, StepStatus, step_display_height, }; let steps = vec![ Step::new("Initialize") .with_sub_steps(vec!["Load configuration", "Connect to database"]), Step::new("Process data") .with_sub_steps(vec!["Validate schema", "Transform records"]), Step::new("Finalize"), ]; let mut state = StepDisplayState::new(steps); // Drive the workflow state.start_step(0); state.start_sub_step(0, 0); state.complete_sub_step(0, 0); state.add_output(0, "Config loaded: 42 settings"); state.start_sub_step(0, 1); state.fail_sub_step(0, 1); state.fail_step(0); // Or complete normally state.complete_step(1); // Layout helper: how many rows does the widget need? let rows_needed = step_display_height(&state); // Widget let display = StepDisplay::new(&state); // display.render(area, frame.buffer_mut()); ``` -------------------------------- ### FileExplorer: Initialize and Navigate State Source: https://context7.com/brainwires/ratatui-interact/llms.txt Shows how to initialize a FileExplorerState with a starting path and perform basic navigation actions like moving the cursor up, down, to top, and to bottom. ```rust use ratatui_interact::components::{FileExplorer, FileExplorerState, FileExplorerStyle}; use std::path::PathBuf; let mut state = FileExplorerState::new(PathBuf::from("/home/user/projects")); // Navigation state.cursor_down(); state.cursor_up(); state.cursor_to_top(); state.cursor_to_bottom(); ``` -------------------------------- ### Install ratatui-interact Source: https://context7.com/brainwires/ratatui-interact/llms.txt Add `ratatui-interact` to your Cargo.toml. Optional features like clipboard, filesystem, and theme serialization can be enabled. ```toml [dependencies] ratatui-interact = "0.5" # Optional features ratatui-interact = { version = "0.5", features = ["clipboard", "filesystem", "theme-serde"] } ``` -------------------------------- ### FileExplorer: Widget Configuration and Rendering Source: https://context7.com/brainwires/ratatui-interact/llms.txt Provides an example of creating and configuring a FileExplorer widget with a title, visibility for hidden files, and a specific style, along with notes on rendering and accessing selected entries. ```rust // Widget let explorer = FileExplorer::new(&state) .title("Select Files") .show_hidden(false) .style(FileExplorerStyle::default()); // Render: explorer.render(area, frame.buffer_mut()); // Selected entries: state.selected_entries() -> &[FileEntry] ``` -------------------------------- ### Toast Notifications: Displaying Transient User Feedback Source: https://github.com/brainwires/ratatui-interact/blob/main/examples/README.md Provides an example of how to implement toast notifications for transient user feedback. Demonstrates showing messages, setting durations, rendering toasts, and clearing expired ones. ```rust use ratatui_interact::components::{Toast, ToastState, ToastStyle}; struct App { toast_state: ToastState, } // Show a toast for 3 seconds app.toast_state.show("File saved successfully!", 3000); // In your render function: fn render(app: &mut App, frame: &mut Frame, area: Rect) { // Draw your main content first... // Then draw toast on top if visible if let Some(message) = app.toast_state.get_message() { Toast::new(message) .style(ToastStyle::Success) .render_with_clear(area, frame.buffer_mut()); } } // In your event loop, periodically clear expired toasts app.toast_state.clear_if_expired(); ``` -------------------------------- ### Handling Mouse Clicks with ClickRegionRegistry Source: https://github.com/brainwires/ratatui-interact/blob/main/examples/README.md Illustrates how to use `render_with_registry` to easily handle mouse clicks on widgets like Buttons. Ensure `app.click_regions.clear()` is called at the start of each frame and `handle_click` is used in the event loop. ```rust use ratatui_interact::components::{Button, ButtonState}; use ratatui_interact::traits::ClickRegionRegistry; struct App { click_regions: ClickRegionRegistry, // ... other fields } // In your render function: fn render(app: &mut App, frame: &mut Frame) { // Clear at start of each frame app.click_regions.clear(); let state = ButtonState::enabled(); let button = Button::new("OK", &state); // Render and register in one call button.render_with_registry(area, frame.buffer_mut(), &mut app.click_regions, 0); } // In your event handler: fn handle_mouse(app: &App, mouse: MouseEvent) { if is_left_click(&mouse) { if let Some(&idx) = app.click_regions.handle_click(mouse.column, mouse.row) { // Button at index `idx` was clicked } } } ``` ```rust let region = button.render_stateful(area, buf); registry.register(region.area, my_custom_action); ``` -------------------------------- ### StepDisplay: Managing and Rendering Step-by-Step Processes Source: https://github.com/brainwires/ratatui-interact/blob/main/examples/README.md Illustrates how to define a series of steps with sub-steps and manage their states using StepDisplayState. Shows how to update progress and add output messages for each step. ```rust use ratatui_interact::components::{Step, StepDisplayState, StepDisplay, StepStatus}; let steps = vec![ Step::new("Initialize").with_sub_steps(vec!["Load config", "Connect DB"]), Step::new("Process data"), Step::new("Finalize"), ]; let mut state = StepDisplayState::new(steps); // Update progress state.start_step(0); state.start_sub_step(0, 0); state.complete_sub_step(0, 0); state.add_output(0, "Config loaded successfully"); state.complete_step(0); let display = StepDisplay::new(&state); ``` -------------------------------- ### Create and Manage a Context Menu Source: https://github.com/brainwires/ratatui-interact/blob/main/examples/README.md Demonstrates how to create context menu items, manage their state, open the menu based on mouse events, render it, and handle keyboard and mouse interactions. Use this for dynamic menus triggered by user actions. ```rust use ratatui_interact::components::{ ContextMenu, ContextMenuItem, ContextMenuState, ContextMenuStyle, handle_context_menu_key, handle_context_menu_mouse, is_context_menu_trigger, }; // Create menu items with actions, separators, and submenus let items = vec![ ContextMenuItem::action("open", "Open").icon("📂").shortcut("Enter"), ContextMenuItem::action("edit", "Edit").icon("✏️").shortcut("E"), ContextMenuItem::separator(), ContextMenuItem::action("copy", "Copy").icon("📋").shortcut("Ctrl+C"), ContextMenuItem::action("paste", "Paste").icon("📄").enabled(false), // Disabled ContextMenuItem::separator(), ContextMenuItem::submenu("More", vec![ ContextMenuItem::action("new_file", "New File").icon("📄"), ContextMenuItem::action("new_folder", "New Folder").icon("📁"), ]).icon("➕"), ContextMenuItem::separator(), ContextMenuItem::action("delete", "Delete").icon("🗑️").shortcut("Del"), ]; // Create state let mut state = ContextMenuState::new(); // Open menu on right-click if is_context_menu_trigger(&mouse_event) { state.open_at(mouse_event.column, mouse_event.row); } // Render the menu (must be rendered last to appear on top) if state.is_open { let menu = ContextMenu::new(&items, &state) .style(ContextMenuStyle::default()); let (menu_area, click_regions) = menu.render_stateful(frame, screen_area); } // Handle keyboard (Up/Down to navigate, Enter to select, Esc to close, Right for submenu) if let Some(action) = handle_context_menu_key(&key_event, &mut state, &items) { match action { ContextMenuAction::Select(id) => println!("Selected: {}", id), ContextMenuAction::Close => println!("Menu closed"), _ => {} } } // Handle mouse clicks handle_context_menu_mouse(&mouse_event, &mut state, menu_area, &click_regions); ``` -------------------------------- ### Applying Themes with Theme System Source: https://github.com/brainwires/ratatui-interact/blob/main/examples/README.md Shows how to initialize a Theme (dark or light preset) and derive component styles from its ColorPalette. Use this to maintain a consistent look and feel across your application's widgets. ```rust use ratatui_interact::theme::Theme; use ratatui_interact::components::{ Button, ButtonState, ButtonStyle }; // Choose a preset let theme = Theme::dark(); // or Theme::light() // Derive any component style from the theme let button_style: ButtonStyle = theme.style(); // Or use the .theme() builder shortcut on any widget let button = Button::new("OK", &ButtonState::enabled()).theme(&theme); // Access the palette directly for custom rendering let fg = theme.palette.text; let bg = theme.palette.surface; let focused_border = theme.palette.border_focused; ``` -------------------------------- ### Run Explorer Log Demo with Filesystem Feature Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Executes the combined explorer and log demo, which requires the 'filesystem' feature to be enabled. ```bash cargo run --example explorer_log_demo --features filesystem ``` -------------------------------- ### Get Text from System Clipboard Source: https://context7.com/brainwires/ratatui-interact/llms.txt Retrieves text content from the system clipboard. Requires the `clipboard` feature. Returns a `ClipboardResult` which can be `Content`, `Empty`, `Error`, or `Unavailable`. ```rust use ratatui_interact::utils::{ get_from_clipboard, ClipboardResult, }; // Paste match get_from_clipboard() { ClipboardResult::Content(text) => println!("Clipboard: {text}"), ClipboardResult::Empty => println!("Clipboard is empty"), ClipboardResult::Error(e) => eprintln!("Error: {e}"), ClipboardResult::Unavailable => {} } ``` -------------------------------- ### Create and Configure TabView Source: https://context7.com/brainwires/ratatui-interact/llms.txt Sets up tabs with optional icons and badges, and initializes the TabViewState. The `TabViewStyle` determines tab position and width. ```rust use ratatui_interact::components::{ Tab, TabView, TabViewState, TabViewStyle, TabPosition, }; use ratatui_interact::traits::ClickRegionRegistry; use ratatui::widgets::{Paragraph, Widget}; let tabs = vec![ Tab::new("General").icon("⚙"), Tab::new("Network").icon("🌐").badge("3"), Tab::new("Security").icon("🔒"), Tab::new("Advanced"), ]; let mut state = TabViewState::new(tabs.len()); state.select(1); // switch to "Network" // Style determines tab position; tab_width for vertical tabs let style_top = TabViewStyle::top(); let style_left = TabViewStyle::left().tab_width(18); let style_right = TabViewStyle::right().tab_width(18); let style_bot = TabViewStyle::bottom(); let tab_view = TabView::new(&tabs, &state) .style(style_left) .content(|idx, area, buf| { let text = ["General settings", "Network config", "Security options", "Advanced"][idx]; Paragraph::new(text).render(area, buf); }); // Render with a click registry let mut registry = ClickRegionRegistry::new(); // tab_view.render_with_registry(area, buf, &mut registry); ``` -------------------------------- ### ListPicker: Navigation and Custom Rendering Source: https://context7.com/brainwires/ratatui-interact/llms.txt Illustrates how to create and navigate a ListPicker, including selecting items, and how to use a custom item renderer for displaying selection prefixes and formatted lines. Also shows how to generate key hint footers. ```rust use ratatui_interact::components::{ListPicker, ListPickerState, ListPickerStyle, key_hints_footer}; use ratatui::text::Line; let items = vec!["Option A", "Option B", "Option C", "Option D"]; let mut state = ListPickerState::new(items.len()); // Navigation state.select_next(); state.select_prev(); state.select_first(); state.select_last(); state.select(2); // jump to index // Current selection if let Some(idx) = state.selected() { println!("Selected: {}", items[idx]); } // Widget with custom item renderer let picker = ListPicker::new(&items, &state) .title("Select Language") .style(ListPickerStyle::default()) .render_item(|item, _idx, selected| { let prefix = if selected { "▶ " } else { " " }; vec![Line::from(format!("{prefix}{item}"))] }); // Render: picker.render(area, frame.buffer_mut()); // Key hint footer (shows "↑↓ navigate Enter select") let footer = key_hints_footer(); ``` -------------------------------- ### Create and Configure MenuBar Source: https://context7.com/brainwires/ratatui-interact/llms.txt Defines menus and initializes the MenuBar state. Keyboard and mouse event handlers are available for interaction. ```rust use ratatui_interact::components::{ Menu, MenuBar, MenuBarItem, MenuBarState, }; let menus = vec![ Menu::new("File").items(vec![ MenuBarItem::action("new", "New") .shortcut("Ctrl+N"), MenuBarItem::action("open", "Open...").shortcut("Ctrl+O"), MenuBarItem::separator(), MenuBarItem::action("save", "Save").shortcut("Ctrl+S"), MenuBarItem::submenu("Export", vec![ MenuBarItem::action("export_pdf", "Export as PDF"), MenuBarItem::action("export_html", "Export as HTML"), ]), MenuBarItem::separator(), MenuBarItem::action("quit", "Quit").shortcut("Ctrl+Q"), ]), Menu::new("Edit").items(vec![ MenuBarItem::action("undo", "Undo") .shortcut("Ctrl+Z"), MenuBarItem::action("redo", "Redo") .shortcut("Ctrl+Y"), MenuBarItem::separator(), MenuBarItem::action("cut", "Cut") .shortcut("Ctrl+X"), MenuBarItem::action("copy", "Copy") .shortcut("Ctrl+C"), MenuBarItem::action("paste", "Paste").shortcut("Ctrl+V").enabled(false), ]), ]; let mut state = MenuBarState::new(); state.focused = true; ``` -------------------------------- ### Create and Configure LogViewer in Rust Source: https://github.com/brainwires/ratatui-interact/blob/main/examples/README.md Illustrates the creation of a LogViewer component for displaying logs. Shows how to initialize it with log data and configure basic features like titles and line numbers. ```rust use ratatui_interact::components::{LogViewer, LogViewerState}; let logs = vec![ "[INFO] Application started".to_string(), "[ERROR] Connection failed".to_string(), ]; let mut state = LogViewerState::new(logs); // Search state.search("ERROR"); state.next_match(); // Scroll state.scroll_down(5); state.scroll_right(10); let viewer = LogViewer::new(&state) .title("Application Log") .show_line_numbers(true); ``` -------------------------------- ### Theme System Usage in Ratatui Interact Source: https://context7.com/brainwires/ratatui-interact/llms.txt Demonstrates how to use built-in and custom themes, derive component styles, and apply themes to widgets. Access palette colors directly for custom rendering. Requires the 'theme-serde' feature for serialization/deserialization. ```rust use ratatui_interact::theme::{Theme, ColorPalette}; use ratatui_interact::components::{ Button, ButtonState, ButtonStyle, Input, InputState, InputStyle, CheckBox, CheckBoxState, CheckBoxStyle, }; use ratatui::style::Color; // Built-in presets let dark = Theme::dark(); // default — yellow primary, dark surfaces let light = Theme::light(); // blue primary, light surfaces let theme = Theme::default(); // same as dark() // Derive any component style let btn_style: ButtonStyle = theme.style(); let inp_style: InputStyle = theme.style(); let cb_style: CheckBoxStyle = theme.style(); // Apply via widget builder shortcuts let button = Button::new("OK", &ButtonState::enabled()).theme(&theme); let input = Input::new(&InputState::new("")).theme(&theme); let checkbox = CheckBox::new("Enable", &CheckBoxState::new(false)).theme(&theme); // Access palette colors directly for custom rendering let fg = theme.palette.text; let bg = theme.palette.surface; let focused_border = theme.palette.border_focused; let primary = theme.palette.primary; let success = theme.palette.success; let error = theme.palette.error; // Custom theme let custom = Theme { name: "Solarized".to_string(), palette: ColorPalette { primary: Color::Rgb(38, 139, 210), secondary: Color::Rgb(42, 161, 152), text: Color::Rgb(131, 148, 150), bg: Color::Rgb(0, 43, 54), surface: Color::Rgb(7, 54, 66), border_focused: Color::Rgb(38, 139, 210), border: Color::Rgb(88, 110, 117), success: Color::Rgb(133, 153, 0), warning: Color::Rgb(181, 137, 0), error: Color::Rgb(220, 50, 47), // ... fill remaining fields ..Theme::dark().palette }, }; // Serialize/deserialize with the theme-serde feature: // [dependencies] // ratatui-interact = { version = "0.5", features = ["theme-serde"] } // -> Theme implements serde::Serialize + serde::Deserialize ``` -------------------------------- ### Create and Manage a Menu Bar Source: https://github.com/brainwires/ratatui-interact/blob/main/examples/README.md Shows how to define menus and menu bar items, manage the menu bar state, render the bar and its dropdowns, and handle keyboard and mouse events for navigation and selection. Suitable for top-level application menus. ```rust use ratatui_interact::components::{ Menu, MenuBar, MenuBarItem, MenuBarState, MenuBarStyle, handle_menu_bar_key, handle_menu_bar_mouse, }; // Create menus with items, separators, shortcuts, and submenus let menus = vec![ Menu::new("File").items(vec![ MenuBarItem::action("new", "New").shortcut("Ctrl+N"), MenuBarItem::action("open", "Open...").shortcut("Ctrl+O"), MenuBarItem::separator(), MenuBarItem::action("save", "Save").shortcut("Ctrl+S"), MenuBarItem::submenu("Export", vec![ MenuBarItem::action("export_pdf", "Export as PDF"), MenuBarItem::action("export_html", "Export as HTML"), ]), MenuBarItem::separator(), MenuBarItem::action("quit", "Quit").shortcut("Ctrl+Q"), ]), Menu::new("Edit").items(vec![ MenuBarItem::action("undo", "Undo").shortcut("Ctrl+Z"), MenuBarItem::action("redo", "Redo").shortcut("Ctrl+Y"), MenuBarItem::separator(), MenuBarItem::action("cut", "Cut").shortcut("Ctrl+X"), MenuBarItem::action("copy", "Copy").shortcut("Ctrl+C"), MenuBarItem::action("paste", "Paste").shortcut("Ctrl+V").enabled(false), // Disabled ]), ]; // Create state let mut state = MenuBarState::new(); state.focused = true; // Render the menu bar let menu_bar = MenuBar::new(&menus, &state) .style(MenuBarStyle::default()); let (bar_area, dropdown_area, click_regions) = menu_bar.render_stateful(frame, area); // Handle keyboard (arrows navigate, Enter selects, Esc closes) if let Some(action) = handle_menu_bar_key(&key_event, &mut state, &menus) { match action { MenuBarAction::ItemSelect(id) => println!("Selected: {}", id), MenuBarAction::MenuOpen(idx) => println!("Menu {} opened", idx), MenuBarAction::MenuClose => println!("Menu closed"), _ => {} } } // Handle mouse (click to open, hover to switch menus) handle_menu_bar_mouse(&mouse_event, &mut state, bar_area, dropdown_area, &click_regions, &menus); ``` -------------------------------- ### Create and Render Select Dropdown Source: https://github.com/brainwires/ratatui-interact/blob/main/examples/README.md Initialize a Select component with options and state. Configure its label and placeholder. Render the main select box and conditionally render the dropdown when open. ```rust use ratatui_interact::components::{Select, SelectState, SelectStyle, handle_select_key, handle_select_mouse}; let options = vec!["Red", "Green", "Blue", "Yellow"]; let mut state = SelectState::new(options.len()); // Pre-select an option let mut state = SelectState::with_selected(options.len(), 1); // "Green" // Render the select box let select = Select::new(&options, &state) .label("Color") .placeholder("Choose a color..."); let click_region = select.render_stateful(frame, area); // Render dropdown when open (must be rendered last to appear on top) let mut dropdown_regions = Vec::new(); if state.is_open { dropdown_regions = select.render_dropdown(frame, area, screen_area); } ``` -------------------------------- ### Create and Render TabView in Rust Source: https://github.com/brainwires/ratatui-interact/blob/main/examples/README.md Demonstrates creating a TabView with custom tabs, state management, styling, and content rendering. Handles keyboard and mouse events for navigation and interaction. ```rust use ratatui_interact::components::{ Tab, TabView, TabViewState, TabViewStyle, TabPosition, handle_tab_view_key, handle_tab_view_mouse, }; use ratatui_interact::traits::ClickRegionRegistry; // Create tabs with optional icons and badges let tabs = vec![ Tab::new("General").icon("⚙"), Tab::new("Network").icon("🌐").badge("3"), Tab::new("Security").icon("🔒"), ]; // Create state let mut state = TabViewState::new(tabs.len()); // Create style (tabs on left side) let style = TabViewStyle::left().tab_width(18); // Create tab view with content renderer let tab_view = TabView::new(&tabs, &state) .style(style) .content(|idx, area, buf| { let text = match idx { 0 => "General settings content", 1 => "Network configuration content", _ => "Security options content", }; Paragraph::new(text).render(area, buf); }); // Render and register click regions let mut registry: ClickRegionRegistry = ClickRegionRegistry::new(); tab_view.render_with_registry(area, buf, &mut registry); // Handle keyboard (arrows navigate, Enter focuses content, Esc focuses tabs, 1-9 direct select) handle_tab_view_key(&mut state, &key_event, style.position); // Handle mouse clicks handle_tab_view_mouse(&mut state, ®istry, &mouse_event); ``` -------------------------------- ### TreeView: Node Management and Custom Rendering Source: https://context7.com/brainwires/ratatui-interact/llms.txt Demonstrates creating a hierarchical TreeView with nodes and children, managing the tree state by toggling collapse/expand and selecting nodes, and rendering items with custom icons and selection markers. Includes retrieving the selected node ID. ```rust use ratatui_interact::components::{TreeView, TreeViewState, TreeNode, TreeStyle, get_selected_id}; #[derive(Clone, Debug)] struct FileInfo { name: String, is_dir: bool } let nodes = vec![ TreeNode::new("src", FileInfo { name: "src".into(), is_dir: true }) .with_children(vec![ TreeNode::new("main", FileInfo { name: "main.rs".into(), is_dir: false }), TreeNode::new("lib", FileInfo { name: "lib.rs".into(), is_dir: false }), ]), TreeNode::new("tests", FileInfo { name: "tests".into(), is_dir: true }) .with_children(vec![ TreeNode::new("test1", FileInfo { name: "test1.rs".into(), is_dir: false }), ]), ]; let mut state = TreeViewState::new(); state.toggle_collapsed("src"); // collapse/expand node state.select("main"); // select a node // Retrieve selection if let Some(id) = get_selected_id(&state) { println!("Selected node id: {id}"); } // Widget let tree = TreeView::new(&nodes, &state) .style(TreeStyle::default()) .render_item(|node, selected| { let icon = if node.data.is_dir { "📁 " } else { "📄 " }; let mark = if selected { "▶" } else { " " }; format!("{mark} {icon}{}", node.data.name) }); // Render: tree.render(area, frame.buffer_mut()); ``` -------------------------------- ### TextArea State and Widget Builder Source: https://context7.com/brainwires/ratatui-interact/llms.txt Demonstrates initializing and manipulating TextArea state, and configuring the TextArea widget with various options like labels, placeholders, and wrapping modes. ```rust use ratatui_interact::components::{ TextArea, TextAreaState, TextAreaStyle, CursorMode, ScrollMode, WrapMode, TabConfig, }; // State let mut state = TextAreaState::new("Hello\nWorld"); assert_eq!(state.cursor_line, 0); assert_eq!(state.cursor_col, 0); state.move_to_end(); assert_eq!(state.cursor_line, 1); assert_eq!(state.cursor_col, 5); // Widget builder let textarea = TextArea::new() .label("Notes") .placeholder("Enter text...") .show_line_numbers(true) .cursor_mode(CursorMode::Block) // inverted-span cursor (default) .cursor_mode(CursorMode::Terminal) // native blinking terminal cursor .scroll_mode(ScrollMode::Minimal) // scroll only when out of view .scroll_mode(ScrollMode::CenterTracking) // keep cursor near midpoint .wrap_mode(WrapMode::None) // horizontal scroll (default) .wrap_mode(WrapMode::Soft) // word-wrap at content width .tab_config(TabConfig::Spaces(4)) // Tab inserts 4 spaces (default) .tab_config(TabConfig::Literal); // Tab inserts \t // render_stateful returns TextAreaRender with click_region + optional cursor_position // let render_result = textarea.render_stateful(frame, area, &mut state); // if let Some(pos) = render_result.cursor_position { // frame.set_cursor_position(pos); // enable native blinking cursor // } // registry.register(render_result.click_region.area, MyAction::FocusEditor); // visual_line_count for layout calculations let wrapped_lines = state.visual_line_count(80); // how many rows at 80-col width ``` -------------------------------- ### ScrollableContent: Initialize and Use Source: https://context7.com/brainwires/ratatui-interact/llms.txt Demonstrates initializing a ScrollableContent state with lines, appending new lines, clearing content, and creating the widget. Handles keyboard and mouse events for navigation and actions like toggling fullscreen. ```rust use ratatui_interact::components::{ ScrollableContent, ScrollableContentState, ScrollableContentStyle, ScrollableContentAction, handle_scrollable_content_key, handle_scrollable_content_mouse, }; let lines: Vec = (1..=100) .map(|i| format!("Line {i}: some content here")) .collect(); let mut state = ScrollableContentState::new(lines); state.focused = true; // Append lines at runtime state.push_line("New line appended".to_string()); // Clear and reset state.clear(); // Widget let pane = ScrollableContent::new(&state) .title("Output") .style(ScrollableContentStyle::default()); // or ::borderless() // Render: pane.render_stateful(frame, area, &mut state); // Keyboard: Up/Down/j/k scroll, PgUp/PgDn page, Home/End, F10/Enter fullscreen // if let Some(action) = handle_scrollable_content_key(&key_event, &mut state) { // match action { // ScrollableContentAction::ToggleFullscreen => {} // _ => {} // } // } // handle_scrollable_content_mouse(&mouse_event, &mut state, area); ``` -------------------------------- ### Create and Style Progress Bars Source: https://github.com/brainwires/ratatui-interact/blob/main/examples/README.md Demonstrates creating progress bars from ratios or step counts, and applying different styles like success or warning. Use these for visual feedback on ongoing tasks. ```rust use ratatui_interact::components::{Progress, ProgressStyle}; // From ratio (0.0 to 1.0) let progress = Progress::new(0.75) .label("Downloading") .show_percentage(true); // From step counts let progress = Progress::from_steps(3, 10) .label("Processing") .show_steps(true); // Different styles let success = Progress::new(1.0).style(ProgressStyle::success()); let warning = Progress::new(0.9).style(ProgressStyle::warning()); ``` -------------------------------- ### FileExplorer: State Management for File Browsing Source: https://github.com/brainwires/ratatui-interact/blob/main/examples/README.md Shows how to initialize and manipulate the state for a file explorer component. Includes navigation, toggling selection and hidden files, and initiating search functionality. ```rust use ratatui_interact::components::{FileExplorerState, FileExplorer}; use std::path::PathBuf; let mut state = FileExplorerState::new(PathBuf::from("/home/user")); // Navigate state.cursor_down(); state.cursor_up(); state.toggle_selection(); // Multi-select state.toggle_hidden(); // Show/hide hidden files // Enter search mode state.start_search(); state.search_push('r'); // Filter by 'r' let explorer = FileExplorer::new(&state) .title("Select Files") .show_hidden(true); ``` -------------------------------- ### Managing Multiple Toasts with ToastStack Source: https://github.com/brainwires/ratatui-interact/blob/main/examples/README.md Demonstrates how to push toasts with different dismiss policies (auto, manual, manual with timeout) and how to tick and render the ToastStack. Use this for displaying temporary notifications to the user. ```rust use ratatui_interact::components::{ ToastDismissPolicy, ToastPlacement, ToastStack, ToastStackLayout, ToastStackState, ToastStyle, }; struct App { toasts: ToastStackState, } // Push toasts with different dismiss policies app.toasts.push("Saved!", ToastStyle::Success, ToastDismissPolicy::Auto { duration_ms: 3000 }); app.toasts.push("Background task running...", ToastStyle::Info, ToastDismissPolicy::Manual); app.toasts.push("Warning: disk almost full", ToastStyle::Warning, ToastDismissPolicy::ManualOrTimeout { duration_ms: 10000 }); // Dismiss by id (returned from push) let id = app.toasts.push("Error occurred", ToastStyle::Error, ToastDismissPolicy::Manual); app.toasts.dismiss(id); // In your event loop — expire auto-dismiss toasts let now_ms = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH).unwrap().as_millis() as i64; app.toasts.tick(now_ms); // In your render function (render last so toasts appear on top) let layout = ToastStackLayout { placement: ToastPlacement::TopRight, ..ToastStackLayout::default() }; ToastStack::new(&app.toasts, layout).render(area, frame.buffer_mut()); ``` -------------------------------- ### Enter and Exit View/Copy Mode in Ratatui Source: https://github.com/brainwires/ratatui-interact/blob/main/README.md Demonstrates how to enter and exit a special View/Copy mode that allows for native terminal text selection. Includes options for different exit strategies. ```rust use ratatui_interact::utils::{ViewCopyMode, ViewCopyConfig, ExitStrategy}; // Enter view/copy mode for native terminal text selection let mode = ViewCopyMode::enter(&mut stdout)?; mode.print_lines(&content)?; // ... wait for user input ... mode.exit(&mut terminal)?; // Choose exit strategy let strategy = ExitStrategy::PrintContent(content); // or ExitStrategy::RestoreConsole strategy.execute()?; ``` -------------------------------- ### Accordion: Initialize and Configure State Source: https://context7.com/brainwires/ratatui-interact/llms.txt Demonstrates initializing AccordionState in both single and multiple expansion modes, and programmatically controlling expanded sections. ```rust use ratatui_interact::components::{ Accordion, AccordionState, AccordionMode, accordion_height, handle_accordion_key, handle_accordion_mouse, }; use ratatui::{text::Line, widgets::{Paragraph, Widget}}; struct Section { id: String, title: String, body: String } let items = vec![ Section { id: "faq1".into(), title: "What is ratatui?".into(), body: "A TUI library.".into() }, Section { id: "faq2".into(), title: "How to install?".into(), body: "cargo add ratatui-interact".into() }, ]; // Single mode: only one section open at a time let mut state = AccordionState::new(items.len()) .with_mode(AccordionMode::Single); // Multiple mode: many can be open simultaneously let mut state = AccordionState::new(items.len()) .with_mode(AccordionMode::Multiple) .with_expanded(vec!["faq1".into()]); state.toggle("faq1"); state.expand("faq2"); state.collapse("faq1"); assert!(state.is_expanded("faq2")); ``` -------------------------------- ### Create and Render SplitPane in Rust Source: https://github.com/brainwires/ratatui-interact/blob/main/examples/README.md Shows how to create a SplitPane for dividing UI areas, managing its state, and handling resizing via keyboard or mouse. Supports horizontal and vertical orientations. ```rust use ratatui_interact::components::{ SplitPane, SplitPaneState, SplitPaneStyle, SplitPaneAction, Orientation, handle_split_pane_key, handle_split_pane_mouse, }; use ratatui_interact::traits::ClickRegionRegistry; // Create state with initial split percentage (50% = equal split) let mut state = SplitPaneState::new(50); state.divider_focused = true; // Enable keyboard resize // Create split pane with horizontal orientation (left | right) let split_pane = SplitPane::new(&state) .orientation(Orientation::Horizontal) .style(SplitPaneStyle::default()) .min_percent(10) // Minimum 10% for first pane .max_percent(90); // Maximum 90% for first pane // Calculate areas for manual rendering let (first_area, divider_area, second_area) = split_pane.calculate_areas(area); // Register click regions for mouse support let mut registry: ClickRegionRegistry = ClickRegionRegistry::new(); registry.register(first_area, SplitPaneAction::FirstPaneClick); registry.register(divider_area, SplitPaneAction::DividerDrag); registry.register(second_area, SplitPaneAction::SecondPaneClick); // Or use the all-in-one render method with closures split_pane.render_with_content( area, buf, &mut state, |first_area, buf| { /* render first pane content */ }, |second_area, buf| { /* render second pane content */ }, &mut registry, ); // Handle keyboard (arrows resize when divider focused, Home/End for min/max) handle_split_pane_key(&mut state, &key_event, Orientation::Horizontal, 5, 10, 90); // Handle mouse (drag divider to resize) handle_split_pane_mouse(&mut state, &mouse_event, Orientation::Horizontal, ®istry, 10, 90); ``` -------------------------------- ### Accordion: Calculate Height and Render Widget Source: https://context7.com/brainwires/ratatui-interact/llms.txt Shows how to calculate the required height for an Accordion widget based on its state and content heights, and how to render the widget. ```rust // Calculate required height for layout let content_heights: Vec = items.iter().map(|_| 3).collect(); let total_rows = accordion_height(&state, &content_heights); // Widget let accordion = Accordion::new(&items, &state) .id_fn(|item, _| item.id.clone()) .render_header(|item, _idx, _focused| Line::raw(item.title.clone())) .render_content(|item, _idx, area, buf| { Paragraph::new(item.body.as_str()).render(area, buf); }); // Render: accordion.render(area, frame.buffer_mut()); // Keyboard: Up/Down navigate, Enter/Space toggle // handle_accordion_key(&key_event, &mut state, items.len()); ``` -------------------------------- ### Progress Bar Creation and Styling Source: https://context7.com/brainwires/ratatui-interact/llms.txt Create progress bars from ratios or step counts. Customize labels, percentage, and step display. Apply predefined styles for success, warning, or error states. ```rust use ratatui_interact::components::{Progress, ProgressStyle}; // From ratio 0.0..=1.0 let bar = Progress::new(0.75) .label("Downloading") .show_percentage(true); // From step counts let bar = Progress::from_steps(7, 10) .label("Processing files") .show_steps(true); // shows "7/10" // .show_percentage(true) // shows "70%" // Style presets let default_bar = Progress::new(0.5).style(ProgressStyle::default()); let success_bar = Progress::new(1.0).style(ProgressStyle::success()); // green let warning_bar = Progress::new(0.9).style(ProgressStyle::warning()); // yellow let error_bar = Progress::new(0.1).style(ProgressStyle::error()); // red // Render: bar.render(area, frame.buffer_mut()); ``` -------------------------------- ### DiffViewer: Parse and Navigate Unified Diffs Source: https://github.com/brainwires/ratatui-interact/blob/main/examples/README.md Demonstrates parsing a unified diff string, initializing the DiffViewerState, and performing navigation and search operations. Handles keyboard and mouse input for interactive diff viewing. ```rust use ratatui_interact::components::{ DiffViewer, DiffViewerState, DiffViewMode, DiffData, handle_diff_viewer_key, handle_diff_viewer_mouse, }; // Parse a unified diff (e.g., from `git diff`) let diff_text = r###"--- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ fn main() { - println!("Hello, world!"); + println!("Hello, Rust!"); + println!("Welcome!"); } "###; let mut state = DiffViewerState::from_unified_diff(diff_text); // Toggle view mode state.toggle_view_mode(); // Switches between Unified and SideBySide // Hunk navigation state.next_hunk(); state.prev_hunk(); // Change navigation (jump to next/prev addition or deletion) state.next_change(); state.prev_change(); // Search within diff state.start_search(); state.search.query = "println".to_string(); state.update_search(); state.next_match(); // Create viewer let viewer = DiffViewer::new(&state) .title("Code Changes") .show_stats(true); // Shows +/- counts in title // Handle keyboard input (in your event loop) // handle_diff_viewer_key(&mut state, &key_event); // Handle mouse scroll // handle_diff_viewer_mouse(&mut state, &mouse_event); ```