markdown_preview: Fix markdown tables taking up the full width of the parent element (#43555)

Remco Smits created

Closes #39152

This PR fixes an issue where we would render Markdown tables full width
based on their container size. We now render tables based on their
content min size, meaning you are still allowed to make the table render
as it was before by making the columns `w_full`.

I had to change the `div()` to `v_flex().items_start()` because this
introduced a weird displaying behavior of the outside table border,
because the grid container was not shrinking due to It was always taking
up the full width of their container.

**Before**
<img width="1273" height="800" alt="Screenshot 2025-11-26 at 14 37 19"
src="https://github.com/user-attachments/assets/2e152021-8679-48c2-b7bd-1c02768c0253"
/>

**After**
<img width="1273" height="797" alt="Screenshot 2025-11-26 at 14 56 12"
src="https://github.com/user-attachments/assets/4459d20e-8c3b-487b-a215-c95ee5c1fc8e"
/>

**Code example**

```markdown
|   Name   |   Age   |   Occupation   |
|:--------:|:-------:|:--------------:|
| Alice    |  28     | Engineer       |
| Bob      |  34     | Designer       |
| Carol    |  25     | Developer      |


| Syntax      | Description |
| ----------- | ----------- |
| Header      | Title       |
| Paragraph   | Text        |


| City           | Population (approx.) | Known For                          |
|----------------|----------------------|------------------------------------|
| New York       | 8,500,000            | Statue of Liberty, Wall Street     |
| Los Angeles    | 4,000,000            | Hollywood, film industry           |
| Chicago        | 2,700,000            | Architecture, deep-dish pizza      |
| Houston        | 2,300,000            | NASA, energy industry              |
| Miami          | 470,000              | Beaches, Latin culture             |
| San Francisco  | 800,000              | Golden Gate Bridge, Silicon Valley |
| Las Vegas      | 650,000              | Casinos, nightlife                 |


<table>
    <caption>Table Caption</caption>
  <thead>
    <tr>
    <th>ID asjkfjaslkf jalksjflksajflka jlksdla k</th>
    <th>Name</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Chris</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Dennis</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Sarah</td>
    </tr>
    <tr>
      <td>4</td>
      <td>Karen</td>
    </tr>
  </tbody>
</table>
```

cc @bennetbo

Release Notes:

- Markdown Preview: Markdown tables scale now based on their content
size

Change summary

crates/gpui/src/taffy.rs                         | 7 ++++---
crates/markdown_preview/src/markdown_renderer.rs | 4 +---
2 files changed, 5 insertions(+), 6 deletions(-)

Detailed changes

crates/gpui/src/taffy.rs 🔗

@@ -8,6 +8,7 @@ use std::{fmt::Debug, ops::Range};
 use taffy::{
     TaffyTree, TraversePartialTree as _,
     geometry::{Point as TaffyPoint, Rect as TaffyRect, Size as TaffySize},
+    prelude::min_content,
     style::AvailableSpace as TaffyAvailableSpace,
     tree::NodeId,
 };
@@ -295,7 +296,7 @@ trait ToTaffy<Output> {
 
 impl ToTaffy<taffy::style::Style> for Style {
     fn to_taffy(&self, rem_size: Pixels, scale_factor: f32) -> taffy::style::Style {
-        use taffy::style_helpers::{fr, length, minmax, repeat};
+        use taffy::style_helpers::{length, minmax, repeat};
 
         fn to_grid_line(
             placement: &Range<crate::GridPlacement>,
@@ -309,8 +310,8 @@ impl ToTaffy<taffy::style::Style> for Style {
         fn to_grid_repeat<T: taffy::style::CheapCloneStr>(
             unit: &Option<u16>,
         ) -> Vec<taffy::GridTemplateComponent<T>> {
-            // grid-template-columns: repeat(<number>, minmax(0, 1fr));
-            unit.map(|count| vec![repeat(count, vec![minmax(length(0.0), fr(1.0))])])
+            // grid-template-columns: repeat(<number>, minmax(0, min-content));
+            unit.map(|count| vec![repeat(count, vec![minmax(length(0.0), min_content())])])
                 .unwrap_or_default()
         }
 

crates/markdown_preview/src/markdown_renderer.rs 🔗

@@ -520,7 +520,6 @@ fn render_markdown_table(parsed: &ParsedMarkdownTable, cx: &mut RenderContext) -
                 .px_2()
                 .py_1()
                 .border_1()
-                .size_full()
                 .border_color(cx.border_color)
                 .when(cell.is_header, |this| {
                     this.bg(cx.title_bar_background_color)
@@ -551,7 +550,6 @@ fn render_markdown_table(parsed: &ParsedMarkdownTable, cx: &mut RenderContext) -
 
             let empty_cell = div()
                 .border_1()
-                .size_full()
                 .border_color(cx.border_color)
                 .when(row_idx % 2 == 1, |this| this.bg(cx.panel_background_color));
 
@@ -560,7 +558,7 @@ fn render_markdown_table(parsed: &ParsedMarkdownTable, cx: &mut RenderContext) -
         }
     }
 
-    cx.with_common_p(div())
+    cx.with_common_p(v_flex().items_start())
         .when_some(parsed.caption.as_ref(), |this, caption| {
             this.children(render_markdown_text(caption, cx))
         })