ratatui_toolkit/
lib.rs

1//! # ratatui-toolkit
2//!
3//! A comprehensive collection of reusable TUI components for [ratatui](https://ratatui.rs/),
4//! the Rust terminal UI library.
5//!
6//! ## Overview
7//!
8//! This crate provides production-ready, reusable widgets for building terminal user interfaces:
9//!
10//! - **Layout Components**: [`ResizableSplit`] for flexible UI layouts
11//! - **UI Components**: [`Button`], [`Dialog`], [`Toast`], [`Pane`] for common UI elements
12//! - **Widgets**: [`TreeView`], [`FuzzyFinder`] for data display
13//! - **Navigation**: [`MenuBar`], [`HotkeyFooter`] for navigation aids
14//! - **Rendering**: [`render_markdown`] for markdown to ratatui text conversion
15//! - **Terminal**: [`TermTui`] for embedded terminal emulation
16//! - **Theming**: [`theme`] module with 33 builtin themes and JSON loader
17//!
18//! ## Feature Flags
19//!
20//! The crate uses feature flags to minimize dependencies:
21//!
22//! | Feature | Default | Description |
23//! |---------|---------|-------------|
24//! | `markdown` | Yes | Markdown rendering support |
25//! | `tree` | Yes | Tree view widget |
26//! | `dialog` | Yes | Modal dialog components |
27//! | `toast` | Yes | Toast notification system |
28//! | `split` | Yes | Resizable split panels |
29//! | `menu` | Yes | Menu bar component |
30//! | `statusline` | Yes | Powerline-style statusline |
31//! | `hotkey` | Yes | Hotkey footer and modal |
32//! | `terminal` | No | Terminal emulator (TermTui) |
33//! | `fuzzy` | No | Fuzzy finder component |
34//! | `file-tree` | No | File system tree with devicons |
35//! | `theme` | No | Theme system with 33 builtin themes |
36//! | `full` | No | Enable all features |
37//!
38//! ## Quick Start
39//!
40//! ```rust,no_run
41//! use ratatui::prelude::*;
42//! use ratatui_toolkit::prelude::*;
43//!
44//! // Create a resizable split
45//! let split = ResizableSplit::new(30); // 30% left, 70% right
46//!
47//! // Create a toast notification
48//! let mut manager = ToastManager::new();
49//! manager.success("File saved!");
50//!
51//! // Render markdown
52//! let text = render_markdown("# Hello\n\n**Bold** and *italic* text.", None);
53//! ```
54//!
55//! ## Examples
56//!
57//! See the `examples/` directory for runnable demos of each component:
58//!
59//! ```bash
60//! cargo run --example resizable_split_demo
61//! cargo run --example tree_view_demo --features tree
62//! cargo run --example toast_manager_demo --features toast
63//! ```
64
65#![cfg_attr(docsrs, feature(doc_cfg))]
66
67// Core components - always available
68pub mod primitives;
69
70pub mod diff_file_tree;
71pub mod widgets;
72
73// Feature-gated components
74#[cfg(feature = "hotkey")]
75#[cfg_attr(docsrs, doc(cfg(feature = "hotkey")))]
76pub mod hotkey_footer;
77
78#[cfg(feature = "fuzzy")]
79#[cfg_attr(docsrs, doc(cfg(feature = "fuzzy")))]
80pub mod fuzzy_finder;
81
82#[cfg(feature = "file-tree")]
83#[cfg_attr(docsrs, doc(cfg(feature = "file-tree")))]
84pub mod file_system_tree;
85
86// Services module - shared infrastructure
87pub mod services;
88
89// Re-export commonly used types - always available
90pub use diff_file_tree::{DiffFileTree, FileStatus};
91pub use primitives::button::render_title_with_buttons::render_title_with_buttons;
92pub use primitives::button::Button;
93pub use primitives::pane::Pane;
94pub use widgets::ai_chat::{AIChat, AIChatEvent, InputState, Message, MessageRole, MessageStore};
95pub use widgets::code_diff::{CodeDiff, DiffConfig, DiffHunk, DiffLine, DiffLineKind, DiffStyle};
96pub use widgets::split_layout::SplitLayoutWidget;
97pub use widgets::split_layout::SplitLayoutWidgetState;
98
99// Feature-gated re-exports
100#[cfg(feature = "dialog")]
101pub use primitives::dialog::widget::DialogWidget;
102#[cfg(feature = "dialog")]
103pub use primitives::dialog::{Dialog, DialogType};
104
105#[cfg(feature = "toast")]
106pub use primitives::toast::methods::render_toasts::render_toasts;
107#[cfg(feature = "toast")]
108pub use primitives::toast::{Toast, ToastLevel, ToastManager};
109
110#[cfg(feature = "split")]
111pub use primitives::resizable_split::{ResizableSplit, SplitDirection};
112#[cfg(feature = "split")]
113pub use primitives::split_layout::{PaneId, PaneLayout, SplitAxis, SplitLayout};
114
115#[cfg(feature = "tree")]
116pub use primitives::tree_view::{
117    get_visible_paths, matches_filter, NodeState, TreeKeyBindings, TreeNavigator, TreeNode,
118    TreeView, TreeViewRef, TreeViewState,
119};
120
121#[cfg(feature = "menu")]
122pub use primitives::menu_bar::{MenuBar, MenuItem};
123
124#[cfg(feature = "statusline")]
125pub use primitives::statusline::{
126    OperationalMode, StatusLineStacked, StyledStatusLine, SLANT_BL_TR, SLANT_TL_BR,
127};
128
129#[cfg(feature = "hotkey")]
130pub use hotkey_footer::{HotkeyFooter, HotkeyFooterBuilder, HotkeyItem};
131
132#[cfg(feature = "hotkey")]
133#[cfg(feature = "markdown")]
134pub use widgets::markdown_widget::{
135    render_markdown, render_markdown_with_style, CacheState, CodeBlockTheme, CollapseState,
136    DisplaySettings, DoubleClickState, ExpandableState, GitStats, GitStatsState,
137    MarkdownDoubleClickEvent, MarkdownEvent, MarkdownState, MarkdownStyle, MarkdownWidget,
138    MarkdownWidgetMode, ScrollState, SelectionPos, SelectionState, SourceState, VimState,
139};
140
141#[cfg(feature = "terminal")]
142pub use primitives::termtui::{TermTui, TermTuiKeyBindings};
143
144#[cfg(feature = "fuzzy")]
145pub use fuzzy_finder::FuzzyFinder;
146
147#[cfg(feature = "file-tree")]
148pub use file_system_tree::{FileSystemEntry, FileSystemTree, FileSystemTreeConfig};
149
150#[cfg(feature = "theme")]
151pub use services::theme::{AppTheme, DiffColors, MarkdownColors, SyntaxColors, ThemeVariant};
152
153// File watcher service - always available
154pub use services::file_watcher::{FileWatcher, WatchConfig, WatchMode};
155
156/// Prelude module for convenient imports
157///
158/// # Example
159///
160/// ```rust
161/// use ratatui_toolkit::prelude::*;
162/// ```
163pub mod prelude {
164    // Core components
165    pub use crate::diff_file_tree::{DiffFileTree, FileStatus};
166    pub use crate::primitives::button::render_title_with_buttons::render_title_with_buttons;
167    pub use crate::primitives::button::Button;
168    pub use crate::primitives::pane::Pane;
169    pub use crate::widgets::ai_chat::{
170        AIChat, AIChatEvent, InputState, Message, MessageRole, MessageStore,
171    };
172    pub use crate::widgets::code_diff::{
173        CodeDiff, DiffConfig, DiffHunk, DiffLine, DiffLineKind, DiffStyle,
174    };
175
176    // Feature-gated components
177    #[cfg(feature = "dialog")]
178    pub use crate::primitives::dialog::widget::DialogWidget;
179    #[cfg(feature = "dialog")]
180    pub use crate::primitives::dialog::{Dialog, DialogType};
181
182    #[cfg(feature = "toast")]
183    pub use crate::primitives::toast::methods::render_toasts::render_toasts;
184    #[cfg(feature = "toast")]
185    pub use crate::primitives::toast::{Toast, ToastLevel, ToastManager};
186
187    #[cfg(feature = "split")]
188    pub use crate::primitives::resizable_split::{ResizableSplit, SplitDirection};
189    #[cfg(feature = "split")]
190    pub use crate::primitives::split_layout::{PaneId, PaneLayout, SplitAxis, SplitLayout};
191    #[cfg(feature = "split")]
192    pub use crate::widgets::split_layout::{SplitLayoutWidget, SplitLayoutWidgetState};
193
194    #[cfg(feature = "tree")]
195    pub use crate::primitives::tree_view::{
196        get_visible_paths, matches_filter, NodeState, TreeKeyBindings, TreeNavigator, TreeNode,
197        TreeView, TreeViewRef, TreeViewState,
198    };
199
200    #[cfg(feature = "menu")]
201    pub use crate::primitives::menu_bar::{MenuBar, MenuItem};
202
203    #[cfg(feature = "statusline")]
204    pub use crate::primitives::statusline::{
205        OperationalMode, StatusLineStacked, StyledStatusLine, SLANT_BL_TR, SLANT_TL_BR,
206    };
207
208    #[cfg(feature = "hotkey")]
209    pub use crate::hotkey_footer::{HotkeyFooter, HotkeyFooterBuilder, HotkeyItem};
210
211    #[cfg(feature = "markdown")]
212    pub use crate::widgets::markdown_widget::{
213        render_markdown, render_markdown_with_style, CacheState, CollapseState, DisplaySettings,
214        DoubleClickState, ExpandableState, GitStatsState, MarkdownState, MarkdownStyle,
215        MarkdownWidget, ScrollState, SelectionState, SourceState, VimState,
216    };
217
218    #[cfg(feature = "terminal")]
219    pub use crate::primitives::termtui::{TermTui, TermTuiKeyBindings};
220
221    #[cfg(feature = "fuzzy")]
222    pub use crate::fuzzy_finder::FuzzyFinder;
223
224    #[cfg(feature = "file-tree")]
225    pub use crate::file_system_tree::{FileSystemEntry, FileSystemTree, FileSystemTreeConfig};
226
227    #[cfg(feature = "theme")]
228    pub use crate::services::theme::{
229        AppTheme, DiffColors, MarkdownColors, SyntaxColors, ThemeVariant,
230    };
231
232    // Services
233    pub use crate::services::file_watcher::{FileWatcher, WatchConfig, WatchMode};
234}
235
236/// Error types for the crate
237#[derive(Debug, thiserror::Error)]
238pub enum Error {
239    /// IO error
240    #[error("IO error: {0}")]
241    Io(#[from] std::io::Error),
242
243    /// Terminal error
244    #[error("Terminal error: {0}")]
245    Terminal(String),
246
247    /// Parse error
248    #[error("Parse error: {0}")]
249    Parse(String),
250}
251
252/// Result type for the crate
253pub type Result<T> = std::result::Result<T, Error>;