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}