ratatui_toolkit/widgets/markdown_widget/widget/
mod.rs

1//! A scrollable, interactive markdown widget.
2
3mod constructors;
4pub mod enums;
5mod helpers;
6mod methods;
7mod traits;
8
9pub use enums::MarkdownWidgetMode;
10pub use methods::WidgetStateSync;
11
12use crate::primitives::pane::Pane;
13use crate::widgets::markdown_widget::extensions::scrollbar::ScrollbarConfig;
14use crate::widgets::markdown_widget::extensions::toc::TocConfig;
15use crate::widgets::markdown_widget::foundation::types::GitStats;
16use crate::widgets::markdown_widget::state::{
17    CacheState, CollapseState, DisplaySettings, DoubleClickState, ExpandableState, GitStatsState,
18    ScrollState, SelectionState, SourceState, TocState, VimState,
19};
20
21/// A scrollable, interactive markdown widget.
22///
23/// This widget renders markdown content with:
24/// - Scroll support (keyboard and mouse)
25/// - Click-to-highlight line selection
26/// - Clickable headings to collapse/expand sections
27/// - Clickable frontmatter to collapse/expand
28/// - Expandable content blocks ("Show more"/"Show less")
29/// - Text selection and copy support (drag to select)
30/// - Double-click detection
31/// - Statusline showing mode and scroll position
32///
33/// The widget handles ALL event processing internally and returns `MarkdownEvent`
34/// variants so the parent application can react appropriately.
35///
36/// # Mouse Capture Requirement
37///
38/// For click events to work (line highlighting, TOC navigation, text selection),
39/// you must enable mouse capture in your terminal setup:
40///
41/// ```rust,ignore
42/// use crossterm::{
43///     event::{EnableMouseCapture, DisableMouseCapture},
44///     execute,
45///     terminal::{EnterAlternateScreen, LeaveAlternateScreen},
46/// };
47///
48/// // On startup:
49/// execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
50///
51/// // On cleanup:
52/// execute!(stdout, LeaveAlternateScreen, DisableMouseCapture)?;
53/// ```
54///
55/// Without `EnableMouseCapture`, scroll wheel events may still work (terminal-dependent),
56/// but click events will not be received by the application.
57pub struct MarkdownWidget<'a> {
58    /// The markdown content to render.
59    pub(crate) content: &'a str,
60    /// Scroll state (position, viewport, current line).
61    pub(crate) scroll: &'a mut ScrollState,
62    /// Content source state.
63    pub(crate) source: &'a mut SourceState,
64    /// Render cache state.
65    pub(crate) cache: &'a mut CacheState,
66    /// Display settings (line numbers, themes).
67    pub(crate) display: &'a DisplaySettings,
68    /// Section collapse state.
69    pub(crate) collapse: &'a mut CollapseState,
70    /// Expandable content state.
71    pub(crate) expandable: &'a mut ExpandableState,
72    /// Git stats state.
73    pub(crate) git_stats_state: &'a mut GitStatsState,
74    /// Vim keybinding state.
75    pub(crate) vim: &'a mut VimState,
76    /// Selection state for text selection/copy.
77    pub(crate) selection: &'a mut SelectionState,
78    /// Double-click state for double-click detection.
79    pub(crate) double_click: &'a mut DoubleClickState,
80    /// Optional TOC state for table of contents.
81    pub(crate) toc_state: Option<&'a TocState>,
82    /// When true, use stale cache for smoother resize during drag operations.
83    pub(crate) is_resizing: bool,
84    /// Current mode for the statusline.
85    pub(crate) mode: MarkdownWidgetMode,
86    /// Whether to show the statusline.
87    pub(crate) show_statusline: bool,
88    /// Whether to show the scrollbar.
89    pub(crate) show_scrollbar: bool,
90    /// Configuration for the scrollbar.
91    pub(crate) scrollbar_config: ScrollbarConfig,
92    /// Whether selection mode is active (affects statusline mode display).
93    pub(crate) selection_active: bool,
94    /// Git statistics for the file (optional, from git_stats_state).
95    pub(crate) git_stats: Option<GitStats>,
96    /// Whether to show the TOC.
97    pub(crate) show_toc: bool,
98    /// Configuration for the TOC.
99    pub(crate) toc_config: TocConfig,
100    /// Whether the TOC is currently hovered (expands to show text).
101    pub(crate) toc_hovered: bool,
102    /// Index of the hovered TOC entry.
103    pub(crate) toc_hovered_entry: Option<usize>,
104    /// Scroll offset for the TOC list.
105    pub(crate) toc_scroll_offset: usize,
106    /// Cached rendered lines for selection text extraction.
107    pub(crate) rendered_lines: Vec<ratatui::text::Line<'static>>,
108    /// Optional application theme for styling.
109    pub(crate) app_theme: Option<&'a crate::services::theme::AppTheme>,
110    /// Last double-click info (line number, kind, content) for app to retrieve.
111    pub(crate) last_double_click: Option<(usize, String, String)>,
112    /// Current filter text (when in filter mode).
113    pub(crate) filter: Option<String>,
114    /// Whether filter mode is currently active.
115    pub(crate) filter_mode: bool,
116    /// Whether to render a border around the widget.
117    pub(crate) bordered: bool,
118    /// Whether to wrap the widget in a Pane.
119    pub(crate) has_pane: bool,
120    /// Optional Pane configuration for wrapping the widget.
121    pub(crate) pane: Option<Pane<'a>>,
122    /// Title to use for the default Pane (e.g., filename).
123    pub(crate) pane_title: Option<String>,
124    /// Color for the Pane border.
125    pub(crate) pane_color: Option<ratatui::style::Color>,
126}