markdown: Fix Markdown table not rendering in hover popover (#44712)

Smit Barmase created

Closes #44306

This PR makes two changes:
- Uses the new `grid_cols_min_content` API. See more here:
https://github.com/zed-industries/zed/pull/44973.
- Changes Markdown table rendering to use a single grid instead of
creating a new grid per row, so column widths stay consistent across
rows.

Release Notes:

- Fixed an issue where Markdown tables wouldn't render in the hover
popover.

Change summary

crates/editor/src/hover_popover.rs |  2 +
crates/markdown/src/markdown.rs    | 56 ++++++++++++++++++-------------
2 files changed, 35 insertions(+), 23 deletions(-)

Detailed changes

crates/editor/src/hover_popover.rs 🔗

@@ -656,6 +656,7 @@ pub fn hover_markdown_style(window: &Window, cx: &App) -> MarkdownStyle {
             .text_base()
             .mt(rems(1.))
             .mb_0(),
+        table_columns_min_size: true,
         ..Default::default()
     }
 }
@@ -709,6 +710,7 @@ pub fn diagnostics_markdown_style(window: &Window, cx: &App) -> MarkdownStyle {
             .font_weight(FontWeight::BOLD)
             .text_base()
             .mb_0(),
+        table_columns_min_size: true,
         ..Default::default()
     }
 }

crates/markdown/src/markdown.rs 🔗

@@ -70,6 +70,7 @@ pub struct MarkdownStyle {
     pub heading_level_styles: Option<HeadingLevelStyles>,
     pub height_is_multiple_of_line_height: bool,
     pub prevent_mouse_interaction: bool,
+    pub table_columns_min_size: bool,
 }
 
 impl Default for MarkdownStyle {
@@ -91,6 +92,7 @@ impl Default for MarkdownStyle {
             heading_level_styles: None,
             height_is_multiple_of_line_height: false,
             prevent_mouse_interaction: false,
+            table_columns_min_size: false,
         }
     }
 }
@@ -1062,11 +1064,21 @@ impl Element for MarkdownElement {
                         MarkdownTag::MetadataBlock(_) => {}
                         MarkdownTag::Table(alignments) => {
                             builder.table_alignments = alignments.clone();
+                            builder.table_row_index = 0;
+                            builder.in_table_head = false;
 
+                            let column_count = alignments.len();
                             builder.push_div(
                                 div()
                                     .id(("table", range.start))
-                                    .min_w_0()
+                                    .grid()
+                                    .grid_cols(column_count as u16)
+                                    .when(self.style.table_columns_min_size, |this| {
+                                        this.grid_cols_min_content(column_count as u16)
+                                    })
+                                    .when(!self.style.table_columns_min_size, |this| {
+                                        this.grid_cols(column_count as u16)
+                                    })
                                     .size_full()
                                     .mb_2()
                                     .border_1()
@@ -1078,38 +1090,30 @@ impl Element for MarkdownElement {
                             );
                         }
                         MarkdownTag::TableHead => {
-                            let column_count = builder.table_alignments.len();
-
-                            builder.push_div(
-                                div()
-                                    .grid()
-                                    .grid_cols(column_count as u16)
-                                    .bg(cx.theme().colors().title_bar_background),
-                                range,
-                                markdown_end,
-                            );
+                            builder.in_table_head = true;
                             builder.push_text_style(TextStyleRefinement {
                                 font_weight: Some(FontWeight::SEMIBOLD),
                                 ..Default::default()
                             });
                         }
-                        MarkdownTag::TableRow => {
-                            let column_count = builder.table_alignments.len();
-
-                            builder.push_div(
-                                div().grid().grid_cols(column_count as u16),
-                                range,
-                                markdown_end,
-                            );
-                        }
+                        MarkdownTag::TableRow => {}
                         MarkdownTag::TableCell => {
+                            let is_header = builder.in_table_head;
+                            let row_index = builder.table_row_index;
+
                             builder.push_div(
                                 div()
                                     .min_w_0()
                                     .border(px(0.5))
                                     .border_color(cx.theme().colors().border)
                                     .px_1()
-                                    .py_0p5(),
+                                    .py_0p5()
+                                    .when(is_header, |this| {
+                                        this.bg(cx.theme().colors().title_bar_background)
+                                    })
+                                    .when(!is_header && row_index % 2 == 1, |this| {
+                                        this.bg(cx.theme().colors().panel_background)
+                                    }),
                                 range,
                                 markdown_end,
                             );
@@ -1224,13 +1228,15 @@ impl Element for MarkdownElement {
                     MarkdownTagEnd::Table => {
                         builder.pop_div();
                         builder.table_alignments.clear();
+                        builder.in_table_head = false;
+                        builder.table_row_index = 0;
                     }
                     MarkdownTagEnd::TableHead => {
-                        builder.pop_div();
                         builder.pop_text_style();
+                        builder.in_table_head = false;
                     }
                     MarkdownTagEnd::TableRow => {
-                        builder.pop_div();
+                        builder.table_row_index += 1;
                     }
                     MarkdownTagEnd::TableCell => {
                         builder.pop_div();
@@ -1500,6 +1506,8 @@ struct MarkdownElementBuilder {
     code_block_stack: Vec<Option<Arc<Language>>>,
     list_stack: Vec<ListStackEntry>,
     table_alignments: Vec<Alignment>,
+    in_table_head: bool,
+    table_row_index: usize,
     syntax_theme: Arc<SyntaxTheme>,
 }
 
@@ -1536,6 +1544,8 @@ impl MarkdownElementBuilder {
             code_block_stack: Vec::new(),
             list_stack: Vec::new(),
             table_alignments: Vec::new(),
+            in_table_head: false,
+            table_row_index: 0,
             syntax_theme,
         }
     }