ratatui_kit/components/
border.rs1use ratatui::{
2 layout::{Constraint, Offset},
3 symbols::border,
4 text::Line,
5 widgets::{Block, Padding},
6};
7use ratatui_kit_macros::Props;
8
9use crate::{AnyElement, Component, layout_style::LayoutStyle};
10
11#[derive(Props)]
12pub struct BorderProps<'a> {
13 pub offset: Offset,
14 pub width: Constraint,
15 pub height: Constraint,
16 pub padding: Padding,
17 pub border_style: ratatui::style::Style,
18 pub borders: ratatui::widgets::Borders,
19 pub border_set: border::Set,
20 pub style: ratatui::style::Style,
21 pub children: Vec<AnyElement<'a>>,
22 pub top_title: Option<Line<'static>>,
23 pub bottom_title: Option<Line<'static>>,
24}
25
26impl Default for BorderProps<'_> {
27 fn default() -> Self {
28 Self {
29 offset: Offset::default(),
30 width: Constraint::default(),
31 height: Constraint::default(),
32 padding: Padding::default(),
33 border_style: ratatui::style::Style::default(),
34 borders: ratatui::widgets::Borders::ALL,
35 children: Vec::new(),
36 border_set: border::Set::default(),
37 style: ratatui::style::Style::default(),
38 top_title: None,
39 bottom_title: None,
40 }
41 }
42}
43
44impl From<&BorderProps<'_>> for LayoutStyle {
45 fn from(props: &BorderProps) -> Self {
46 LayoutStyle {
47 offset: props.offset,
48 width: props.width,
49 height: props.height,
50 ..Default::default()
51 }
52 }
53}
54
55pub struct Border {
56 pub padding: Padding,
57 pub border_style: ratatui::style::Style,
58 pub borders: ratatui::widgets::Borders,
59 pub border_set: border::Set,
60 pub style: ratatui::style::Style,
61 pub top_title: Option<Line<'static>>,
62 pub bottom_title: Option<Line<'static>>,
63}
64
65impl Component for Border {
66 type Props<'a> = BorderProps<'a>;
67
68 fn new(props: &Self::Props<'_>) -> Self {
69 Self {
70 padding: props.padding,
71 border_style: props.border_style,
72 borders: props.borders,
73 border_set: props.border_set,
74 style: props.style,
75 top_title: props.top_title.clone(),
76 bottom_title: props.bottom_title.clone(),
77 }
78 }
79
80 fn update(
81 &mut self,
82 props: &mut Self::Props<'_>,
83 _hooks: crate::Hooks,
84 updater: &mut crate::ComponentUpdater,
85 ) {
86 let layout_style = LayoutStyle::from(&*props);
87 self.padding = props.padding;
88 self.border_style = props.border_style;
89 updater.set_layout_style(layout_style);
90 updater.update_children(&mut props.children, None);
91 }
92
93 fn draw(&mut self, drawer: &mut crate::ComponentDrawer<'_, '_>) {
94 let mut block = Block::new()
95 .style(self.style)
96 .borders(self.borders)
97 .border_set(self.border_set)
98 .border_style(self.border_style)
99 .padding(self.padding);
100
101 if let Some(top_title) = &self.top_title {
102 block = block.title_top(top_title.clone());
103 }
104
105 if let Some(bottom_title) = &self.bottom_title {
106 block = block.title_bottom(bottom_title.clone());
107 }
108
109 let inner_area = block.inner(drawer.area);
110 drawer.frame.render_widget(block, drawer.area);
111
112 drawer.area = inner_area;
113 }
114}