a2ui_tui/components/
card.rs1use ratatui::{
4 Frame,
5 layout::Rect,
6 style::{Color, Style},
7 widgets::{Block, BorderType, Borders},
8};
9
10use a2ui_base::model::component_context::ComponentContext;
11use crate::component_impl::TuiComponent;
12
13pub struct CardComponent;
19
20impl TuiComponent for CardComponent {
21 fn name(&self) -> &'static str {
22 "Card"
23 }
24
25 fn render(
26 &self,
27 ctx: &ComponentContext,
28 area: Rect,
29 frame: &mut Frame,
30 render_child: &mut dyn FnMut(&str, Rect, &mut Frame, &str),
31 _measure_child: &mut dyn FnMut(&str, &str, u16) -> Option<u16>,
32 ) {
33 let comp_model = match ctx.components.get(&ctx.component_id) {
34 Some(m) => m,
35 None => return,
36 };
37
38 let inner = crate::layout_engine::padded_content(area);
40
41 if inner.width == 0 || inner.height == 0 {
42 return;
43 }
44
45 let block = Block::default()
47 .borders(Borders::ALL)
48 .border_type(BorderType::Rounded)
49 .border_style(Style::default().fg(Color::DarkGray))
50 .style(Style::default());
51
52 let child_area = block.inner(inner);
54
55 frame.render_widget(block, inner);
57
58 if let Some(child_id) = comp_model.child() {
60 if child_area.width > 0 && child_area.height > 0 {
61 render_child(&child_id, child_area, frame, "");
62 }
63 }
64 }
65
66 fn natural_height(
68 &self,
69 ctx: &ComponentContext,
70 available_width: u16,
71 measure_child: &mut dyn FnMut(&str, &str, u16) -> Option<u16>,
72 ) -> Option<u16> {
73 let comp_model = ctx.components.get(&ctx.component_id)?;
74 let child_id = comp_model.child()?;
75 let inner_width = available_width.saturating_sub(4);
77 let child_h = measure_child(&child_id, "", inner_width)?;
78 Some(child_h.saturating_add(4))
79 }
80}