markdown: Allow code blocks and tables to be horizontally scrollable (#25956)

This PR adds the ability for Markdown code blocks and tables to be made
horizontally scrollable.

This is a feature that the caller can opt in to.

Right now we're using it for the rendered Markdown in the Assistant 2
panel.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2025-03-03 17:52:59 -05:00 committed by GitHub
parent 7321c814ce
commit 0776fa8f31
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 22 additions and 5 deletions

View file

@ -134,6 +134,8 @@ impl ActiveThread {
base_text_style: text_style, base_text_style: text_style,
syntax: cx.theme().syntax().clone(), syntax: cx.theme().syntax().clone(),
selection_background_color: cx.theme().players().local().selection, selection_background_color: cx.theme().players().local().selection,
code_block_overflow_x_scroll: true,
table_overflow_x_scroll: true,
code_block: StyleRefinement { code_block: StyleRefinement {
margin: EdgesRefinement { margin: EdgesRefinement {
top: Some(Length::Definite(rems(0.).into())), top: Some(Length::Definite(rems(0.).into())),

View file

@ -618,12 +618,12 @@ pub fn hover_markdown_style(window: &Window, cx: &App) -> MarkdownStyle {
}, },
syntax: cx.theme().syntax().clone(), syntax: cx.theme().syntax().clone(),
selection_background_color: { cx.theme().players().local().selection }, selection_background_color: { cx.theme().players().local().selection },
heading: StyleRefinement::default() heading: StyleRefinement::default()
.font_weight(FontWeight::BOLD) .font_weight(FontWeight::BOLD)
.text_base() .text_base()
.mt(rems(1.)) .mt(rems(1.))
.mb_0(), .mb_0(),
..Default::default()
} }
} }

View file

@ -84,6 +84,7 @@ pub fn main() {
selection selection
}, },
heading: Default::default(), heading: Default::default(),
..Default::default()
}; };
let markdown = cx.new(|cx| { let markdown = cx.new(|cx| {
Markdown::new(MARKDOWN_EXAMPLE.into(), markdown_style, None, None, cx) Markdown::new(MARKDOWN_EXAMPLE.into(), markdown_style, None, None, cx)

View file

@ -27,6 +27,7 @@ use crate::parser::CodeBlockKind;
pub struct MarkdownStyle { pub struct MarkdownStyle {
pub base_text_style: TextStyle, pub base_text_style: TextStyle,
pub code_block: StyleRefinement, pub code_block: StyleRefinement,
pub code_block_overflow_x_scroll: bool,
pub inline_code: TextStyleRefinement, pub inline_code: TextStyleRefinement,
pub block_quote: TextStyleRefinement, pub block_quote: TextStyleRefinement,
pub link: TextStyleRefinement, pub link: TextStyleRefinement,
@ -35,6 +36,7 @@ pub struct MarkdownStyle {
pub syntax: Arc<SyntaxTheme>, pub syntax: Arc<SyntaxTheme>,
pub selection_background_color: Hsla, pub selection_background_color: Hsla,
pub heading: StyleRefinement, pub heading: StyleRefinement,
pub table_overflow_x_scroll: bool,
} }
impl Default for MarkdownStyle { impl Default for MarkdownStyle {
@ -42,6 +44,7 @@ impl Default for MarkdownStyle {
Self { Self {
base_text_style: Default::default(), base_text_style: Default::default(),
code_block: Default::default(), code_block: Default::default(),
code_block_overflow_x_scroll: false,
inline_code: Default::default(), inline_code: Default::default(),
block_quote: Default::default(), block_quote: Default::default(),
link: Default::default(), link: Default::default(),
@ -50,6 +53,7 @@ impl Default for MarkdownStyle {
syntax: Arc::new(SyntaxTheme::default()), syntax: Arc::new(SyntaxTheme::default()),
selection_background_color: Default::default(), selection_background_color: Default::default(),
heading: Default::default(), heading: Default::default(),
table_overflow_x_scroll: false,
} }
} }
} }
@ -604,13 +608,20 @@ impl Element for MarkdownElement {
None None
}; };
let mut d = div().w_full().rounded_lg(); let mut code_block = div()
d.style().refine(&self.style.code_block); .id(("code-block", range.start))
.flex()
.rounded_lg()
.when(self.style.code_block_overflow_x_scroll, |mut code_block| {
code_block.style().restrict_scroll_to_axis = Some(true);
code_block.overflow_x_scroll()
});
code_block.style().refine(&self.style.code_block);
if let Some(code_block_text_style) = &self.style.code_block.text { if let Some(code_block_text_style) = &self.style.code_block.text {
builder.push_text_style(code_block_text_style.to_owned()); builder.push_text_style(code_block_text_style.to_owned());
} }
builder.push_code_block(language); builder.push_code_block(language);
builder.push_div(d, range, markdown_end); builder.push_div(code_block, range, markdown_end);
} }
MarkdownTag::HtmlBlock => builder.push_div(div(), range, markdown_end), MarkdownTag::HtmlBlock => builder.push_div(div(), range, markdown_end),
MarkdownTag::List(bullet_index) => { MarkdownTag::List(bullet_index) => {
@ -670,7 +681,10 @@ impl Element for MarkdownElement {
.border_1() .border_1()
.border_color(cx.theme().colors().border) .border_color(cx.theme().colors().border)
.rounded_md() .rounded_md()
.overflow_x_scroll(), .when(self.style.table_overflow_x_scroll, |mut table| {
table.style().restrict_scroll_to_axis = Some(true);
table.overflow_x_scroll()
}),
range, range,
markdown_end, markdown_end,
); );