From faee91eda42b835d0016138e7af9ec7d3d5aa2bb Mon Sep 17 00:00:00 2001 From: Moulberry Date: Thu, 6 Nov 2025 21:15:13 +0800 Subject: [PATCH] table: fix row border missing on first frame (#1505) Currently, the bounds are zero on the first frame. Therefore, the extra_rows_count will always be zero on the first frame. This causes rendering issues for row border & row stripes. Unfortunately, I don't know how to get the correct height on the first frame to fix the row stripes. However, an easy fix for the row border rendering issue is to disable the table_is_filled check. The check is problematic anyways since the border affects the height of the element. I attached a video showing the issue, the border doesn't render on the first frame and the height of the element also shifts due to the border: https://github.com/user-attachments/assets/b154c686-cd9c-4b6b-8ba6-c79640297abc --------- Co-authored-by: Jason Lee --- crates/ui/src/table/mod.rs | 43 +++++++++++++++----------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/crates/ui/src/table/mod.rs b/crates/ui/src/table/mod.rs index 5a1f7078..5546983a 100644 --- a/crates/ui/src/table/mod.rs +++ b/crates/ui/src/table/mod.rs @@ -994,7 +994,7 @@ where left_columns_count: usize, col_sizes: Rc>>, columns_count: usize, - extra_rows_count: usize, + is_filled: bool, window: &mut Window, cx: &mut Context, ) -> impl IntoElement { @@ -1006,18 +1006,7 @@ where if row_ix < rows_count { let is_last_row = row_ix + 1 == rows_count; - let table_is_filled = extra_rows_count == 0; - let need_render_border = if is_last_row { - if is_selected { - true - } else if table_is_filled { - false - } else { - !self.options.stripe - } - } else { - true - }; + let need_render_border = is_selected || !is_last_row || !is_filled; let mut tr = self.delegate.render_tr(row_ix, window, cx); let style = tr.style().clone(); @@ -1181,19 +1170,9 @@ where } /// Calculate the extra rows needed to fill the table empty space when `stripe` is true. - fn calculate_extra_rows_needed(&self, rows_count: usize) -> usize { + fn calculate_extra_rows_needed(&self, total_height: Pixels, actual_height: Pixels, row_height: Pixels) -> usize { let mut extra_rows_needed = 0; - let row_height = self.options.size.table_row_height(); - let total_height = self - .vertical_scroll_handle - .0 - .borrow() - .base_handle - .bounds() - .size - .height; - let actual_height = row_height * rows_count as f32; let remaining_height = total_height - actual_height; if remaining_height > px(0.) { extra_rows_needed = (remaining_height / row_height).floor() as usize; @@ -1313,13 +1292,25 @@ where .count(); let rows_count = self.delegate.rows_count(cx); let loading = self.delegate.loading(cx); - let extra_rows_count = self.calculate_extra_rows_needed(rows_count); + + let row_height = self.options.size.table_row_height(); + let total_height = self + .vertical_scroll_handle + .0 + .borrow() + .base_handle + .bounds() + .size + .height; + let actual_height = row_height * rows_count as f32; + let extra_rows_count = self.calculate_extra_rows_needed(total_height, actual_height, row_height); let render_rows_count = if self.options.stripe { rows_count + extra_rows_count } else { rows_count }; let right_clicked_row = self.right_clicked_row; + let is_filled = total_height <= actual_height; let loading_view = if loading { Some( @@ -1417,7 +1408,7 @@ where left_columns_count, col_sizes.clone(), columns_count, - extra_rows_count, + is_filled, window, cx, ));