ratatui_toolkit/widgets/markdown_widget/widget/methods/
calculate_toc_area.rs

1//! Calculate the TOC area.
2
3use ratatui::layout::Rect;
4
5use crate::widgets::markdown_widget::extensions::toc::Toc;
6use crate::widgets::markdown_widget::widget::MarkdownWidget;
7
8impl<'a> MarkdownWidget<'a> {
9    /// Calculate the TOC area based on current widget configuration.
10    ///
11    /// Uses dynamic dimensions based on content:
12    /// - Expanded mode: width fits all headers, height fits all entries
13    /// - Compact mode: fixed width, height based on entry count and line spacing
14    ///
15    /// # Arguments
16    ///
17    /// * `total_area` - The total area available for the widget
18    ///
19    /// # Returns
20    ///
21    /// `Some(Rect)` with the TOC area if TOC is enabled, `None` otherwise.
22    pub fn calculate_toc_area(&self, total_area: Rect) -> Option<Rect> {
23        if !self.show_toc {
24            return None;
25        }
26
27        // Account for statusline
28        let main_area = if self.show_statusline && total_area.height > 1 {
29            Rect {
30                height: total_area.height.saturating_sub(1),
31                ..total_area
32            }
33        } else {
34            total_area
35        };
36
37        let padding_right: u16 = 2;
38        let padding_top: u16 = 1;
39
40        // Use dynamic dimensions matching the rendering code
41        let toc_width = if self.toc_hovered {
42            // Dynamic width based on content for expanded mode
43            Toc::required_expanded_width(self.content, self.toc_config.show_border)
44                .min(main_area.width.saturating_sub(padding_right + 4))
45        } else {
46            self.toc_config.compact_width
47        };
48
49        let toc_height = if self.toc_hovered {
50            // Expanded: one row per entry
51            Toc::required_height(self.content, self.toc_config.show_border)
52                .min(main_area.height.saturating_sub(1))
53        } else {
54            // Compact: based on entries and line_spacing
55            Toc::required_compact_height(
56                self.content,
57                self.toc_config.line_spacing,
58                self.toc_config.show_border,
59            )
60            .min(main_area.height.saturating_sub(1))
61        };
62
63        if main_area.width <= toc_width + padding_right + 2 {
64            return None;
65        }
66
67        Some(Rect {
68            x: main_area.x + main_area.width.saturating_sub(toc_width + padding_right),
69            y: main_area.y + padding_top,
70            width: toc_width,
71            height: toc_height,
72        })
73    }
74}