use ratatui::prelude::*;
use ratatui::widgets::{Block, Borders, Cell, Row};
use super::*;
pub(super) fn render_table<T: TableRow>(
state: &TableState<T>,
frame: &mut Frame,
area: Rect,
theme: &Theme,
focused: bool,
disabled: bool,
) {
crate::annotation::with_registry(|reg| {
let mut ann = crate::annotation::Annotation::table("table")
.with_focus(focused)
.with_disabled(disabled);
if let Some(idx) = state.selected {
ann = ann.with_selected(true).with_value(idx.to_string());
}
reg.register(area, ann);
});
let header_cells: Vec<Cell> = state
.columns
.iter()
.enumerate()
.map(|(i, col)| {
let mut text = col.header().to_string();
if let Some(pos) = state.sort_columns.iter().position(|&(c, _)| c == i) {
let (_, dir) = state.sort_columns[pos];
let arrow = match dir {
SortDirection::Ascending => "\u{2191}",
SortDirection::Descending => "\u{2193}",
};
if state.sort_columns.len() == 1 {
text.push(' ');
text.push_str(arrow);
} else {
text.push(' ');
text.push_str(arrow);
text.push_str(&(pos + 1).to_string());
}
}
Cell::from(text)
})
.collect();
let header_style = if disabled {
theme.disabled_style()
} else {
Style::default().add_modifier(Modifier::BOLD)
};
let header = Row::new(header_cells).style(header_style).bottom_margin(1);
let rows: Vec<Row> = state
.display_order
.iter()
.map(|&idx| {
let cells: Vec<Cell> = state.rows[idx]
.cells()
.into_iter()
.map(Cell::from)
.collect();
Row::new(cells)
})
.collect();
let widths: Vec<Constraint> = state.columns.iter().map(|c| c.width()).collect();
let border_style = if focused && !disabled {
theme.focused_border_style()
} else {
theme.border_style()
};
let row_highlight_style = if disabled {
theme.disabled_style()
} else {
theme.selected_highlight_style(focused)
};
let table = ratatui::widgets::Table::new(rows, widths)
.header(header)
.block(
Block::default()
.borders(Borders::ALL)
.border_style(border_style),
)
.row_highlight_style(row_highlight_style)
.highlight_symbol("> ");
let mut table_state = ratatui::widgets::TableState::default();
table_state.select(state.selected);
frame.render_stateful_widget(table, area, &mut table_state);
let inner = area.inner(Margin::new(1, 1));
let data_viewport = (inner.height as usize).saturating_sub(2);
if data_viewport > 0 && state.display_order.len() > data_viewport {
let mut bar_scroll = ScrollState::new(state.display_order.len());
bar_scroll.set_viewport_height(data_viewport);
bar_scroll.set_offset(table_state.offset());
crate::scroll::render_scrollbar_inside_border(&bar_scroll, frame, area, theme);
}
}