ratatui_kit/components/
border.rs1use ratatui::{
18 symbols::border,
19 text::Line,
20 widgets::{Block, Padding, Widget},
21};
22use ratatui_kit_macros::{Props, with_layout_style};
23
24use crate::{AnyElement, Component};
25
26#[with_layout_style]
27#[derive(Props)]
28pub struct BorderProps<'a> {
30 pub padding: Padding,
32 pub border_style: ratatui::style::Style,
34 pub borders: ratatui::widgets::Borders,
36 pub border_set: border::Set<'static>,
38 pub style: ratatui::style::Style,
40 pub children: Vec<AnyElement<'a>>,
42 pub top_title: Option<Line<'static>>,
44 pub bottom_title: Option<Line<'static>>,
46}
47
48impl Default for BorderProps<'_> {
49 fn default() -> Self {
50 Self {
51 padding: Padding::default(),
52 border_style: ratatui::style::Style::default(),
53 borders: ratatui::widgets::Borders::ALL,
54 children: Vec::new(),
55 border_set: border::Set::default(),
56 style: ratatui::style::Style::default(),
57 top_title: None,
58 bottom_title: None,
59 margin: Default::default(),
60 offset: Default::default(),
61 width: Default::default(),
62 height: Default::default(),
63 gap: Default::default(),
64 flex_direction: Default::default(),
65 justify_content: Default::default(),
66 }
67 }
68}
69
70pub struct Border {
72 pub padding: Padding,
73 pub border_style: ratatui::style::Style,
74 pub borders: ratatui::widgets::Borders,
75 pub border_set: border::Set<'static>,
76 pub style: ratatui::style::Style,
77 pub top_title: Option<Line<'static>>,
78 pub bottom_title: Option<Line<'static>>,
79}
80
81impl Border {
82 fn from_props(props: &BorderProps<'_>) -> Self {
84 Self {
85 padding: props.padding,
86 border_style: props.border_style,
87 borders: props.borders,
88 border_set: props.border_set,
89 style: props.style,
90 top_title: props.top_title.clone(),
91 bottom_title: props.bottom_title.clone(),
92 }
93 }
94}
95
96impl Component for Border {
97 type Props<'a> = BorderProps<'a>;
98
99 fn new(props: &Self::Props<'_>) -> Self {
101 Self::from_props(props)
102 }
103
104 fn update(
106 &mut self,
107 props: &mut Self::Props<'_>,
108 _hooks: crate::Hooks,
109 updater: &mut crate::ComponentUpdater,
110 ) {
111 *self = Self::from_props(props);
112 updater.set_layout_style(props.layout_style());
114 updater.update_children(&mut props.children, None);
115 }
116
117 fn draw(&mut self, drawer: &mut crate::ComponentDrawer<'_, '_>) {
119 let mut block = Block::new()
121 .style(self.style)
122 .borders(self.borders)
123 .border_set(self.border_set)
124 .border_style(self.border_style)
125 .padding(self.padding);
126
127 if let Some(top_title) = &self.top_title {
129 block = block.title_top(top_title.clone());
130 }
131
132 if let Some(bottom_title) = &self.bottom_title {
134 block = block.title_bottom(bottom_title.clone());
135 }
136
137 let inner_area = block.inner(drawer.area);
139 block.render(drawer.area, drawer.buffer_mut());
141 drawer.area = inner_area;
143 }
144}