feat: apply declarative render rule across components

This commit is contained in:
2026-11-10 08:04:24 +07:00
parent fbc4f24d16
commit 44abaf47a9
12 changed files with 545 additions and 561 deletions
+18 -17
View File
@@ -546,24 +546,25 @@ fn render_row(
},
)
.when(options.line_numbers, |row_element| {
let mut number = gutter_cell(
cx,
colors.muted_foreground,
row.new_number
.or(row.old_number)
.map(|number| number.to_string())
.unwrap_or_default(),
row_element.child(
gutter_cell(
cx,
colors.muted_foreground,
row.new_number
.or(row.old_number)
.map(|number| number.to_string())
.unwrap_or_default(),
)
.w_10()
.whitespace_nowrap()
.bg(match row.kind {
DiffRowKind::Context => wash_gutter(&colors),
_ => wash_strong(change_color),
})
.when(options.indicators == DiffIndicators::Bars, |number| {
number.border_l_4().border_color(change_color)
}),
)
.w_10()
.whitespace_nowrap()
.bg(match row.kind {
DiffRowKind::Context => wash_gutter(&colors),
_ => wash_strong(change_color),
});
if options.indicators == DiffIndicators::Bars {
number = number.border_l_4().border_color(change_color);
}
row_element.child(number)
})
.when(
options.indicators == DiffIndicators::Bars && !options.line_numbers,
+75 -79
View File
@@ -817,43 +817,43 @@ fn text_row(
cx: &App,
) -> AnyElement {
let theme = cx.theme();
let mut frame = block_frame(indent, quote, px(0.), bottom, id, cx);
if let Some(marker) = marker {
let line_height = theme.sizes.small.text_size * BODY_LINE_HEIGHT;
let marker_cell = div()
.flex_none()
.w(theme.root_font_size * MARKER_WIDTH)
.h(line_height)
.flex()
.items_center()
.justify_end()
.pr_1()
.child(match marker {
ListMarker::Bullet => div()
.text_color(theme.colors.muted_foreground)
.child("•")
.into_any_element(),
ListMarker::Ordered(number) => div()
.text_color(theme.colors.muted_foreground)
.whitespace_nowrap()
.child(format!("{number}."))
.into_any_element(),
ListMarker::Task(checked) => task_box(checked, cx),
});
block_frame(indent, quote, px(0.), bottom, id, cx)
.map(|frame| match marker {
Some(marker) => {
let line_height = theme.sizes.small.text_size * BODY_LINE_HEIGHT;
let marker_cell = div()
.flex_none()
.w(theme.root_font_size * MARKER_WIDTH)
.h(line_height)
.flex()
.items_center()
.justify_end()
.pr_1()
.child(match marker {
ListMarker::Bullet => div()
.text_color(theme.colors.muted_foreground)
.child("•")
.into_any_element(),
ListMarker::Ordered(number) => div()
.text_color(theme.colors.muted_foreground)
.whitespace_nowrap()
.child(format!("{number}."))
.into_any_element(),
ListMarker::Task(checked) => task_box(checked, cx),
});
frame = frame.child(
div()
.flex()
.items_start()
.child(marker_cell)
.child(div().flex_1().min_w_0().child(text_child(spans, id, cx))),
);
} else {
frame = frame.child(text_child(spans, id, cx));
}
frame.into_any_element()
frame.child(
div()
.flex()
.items_start()
.child(marker_cell)
.child(div().flex_1().min_w_0().child(text_child(spans, id, cx))),
)
}
None => frame.child(text_child(spans, id, cx)),
})
.into_any_element()
}
/// A read-only task item indicator, matching the checkbox component.
@@ -896,7 +896,7 @@ fn code_row(
let text_size = theme.sizes.small.text_size;
let line_height = text_size * CODE_LINE_HEIGHT;
let mut plate = div()
let plate = div()
.w_full()
.flex()
.flex_col()
@@ -906,17 +906,14 @@ fn code_row(
.font_family(theme.mono_font)
.text_size(text_size)
.line_height(relative(CODE_LINE_HEIGHT))
.overflow_hidden();
for line in &lines.lines {
plate = plate.child(
.overflow_hidden()
.children(lines.lines.iter().map(|line| {
div()
.h(line_height)
.whitespace_nowrap()
.overflow_hidden()
.child(code_line(line, theme.colors, theme.ramps)),
);
}
.child(code_line(line, theme.colors, theme.ramps))
}));
block_frame(
indent,
@@ -961,48 +958,47 @@ fn table_row(
.unwrap_or(0);
let row_count = table.rows.len();
let mut grid = div()
let grid = div()
.w_full()
.flex()
.flex_col()
.border_1()
.border_color(colors.border)
.rounded(theme.radius.control)
.overflow_hidden();
for (row_ix, row) in table.rows.iter().enumerate() {
let mut row_element = div().w_full().flex();
if row_ix + 1 < row_count {
row_element = row_element.border_b_1().border_color(colors.border);
}
if row.header {
row_element = row_element.bg(colors.muted);
}
for (column_ix, cell) in row.cells.iter().enumerate() {
let cell_id = ElementId::from(SharedString::from(format!(
"{id}-cell-{row_ix}-{column_ix}"
)));
row_element = row_element.child(
div()
.flex_1()
.min_w_0()
.px_2()
.py_1()
.when(row.header, |cell_element| {
cell_element.font_weight(FontWeight::SEMIBOLD)
})
.child(text_child(&cell.spans, &cell_id, cx)),
);
}
// Ragged tables pad missing cells so rows align.
for _ in row.cells.len()..width {
row_element = row_element.child(div().flex_1().min_w_0().px_2().py_1());
}
grid = grid.child(row_element);
}
.overflow_hidden()
.children(table.rows.iter().enumerate().map(|(row_ix, row)| {
div()
.w_full()
.flex()
.when(row_ix + 1 < row_count, |row_element| {
row_element.border_b_1().border_color(colors.border)
})
.when(row.header, |row_element| row_element.bg(colors.muted))
.children(
row.cells
.iter()
.enumerate()
.map(|(column_ix, cell)| {
let cell_id = ElementId::from(SharedString::from(format!(
"{id}-cell-{row_ix}-{column_ix}"
)));
div()
.flex_1()
.min_w_0()
.px_2()
.py_1()
.when(row.header, |cell_element| {
cell_element.font_weight(FontWeight::SEMIBOLD)
})
.child(text_child(&cell.spans, &cell_id, cx))
})
// Ragged tables pad missing cells so rows align.
.chain(
(row.cells.len()..width)
.map(|_| div().flex_1().min_w_0().px_2().py_1()),
),
)
}));
block_frame(
indent,