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,
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,
76 pub style: ratatui::style::Style,
77 pub top_title: Option<Line<'static>>,
78 pub bottom_title: Option<Line<'static>>,
79}
80
81impl Component for Border {
82 type Props<'a> = BorderProps<'a>;
83
84 fn new(props: &Self::Props<'_>) -> Self {
86 Self {
87 padding: props.padding,
88 border_style: props.border_style,
89 borders: props.borders,
90 border_set: props.border_set,
91 style: props.style,
92 top_title: props.top_title.clone(),
93 bottom_title: props.bottom_title.clone(),
94 }
95 }
96
97 fn update(
99 &mut self,
100 props: &mut Self::Props<'_>,
101 _hooks: crate::Hooks,
102 updater: &mut crate::ComponentUpdater,
103 ) {
104 let layout_style = props.layout_style();
106 *self = Self {
108 padding: props.padding,
109 border_style: props.border_style,
110 borders: props.borders,
111 border_set: props.border_set,
112 style: props.style,
113 top_title: props.top_title.clone(),
114 bottom_title: props.bottom_title.clone(),
115 };
116 updater.set_layout_style(layout_style);
118 updater.update_children(&mut props.children, None);
120 }
121
122 fn draw(&mut self, drawer: &mut crate::ComponentDrawer<'_, '_>) {
124 let mut block = Block::new()
126 .style(self.style)
127 .borders(self.borders)
128 .border_set(self.border_set)
129 .border_style(self.border_style)
130 .padding(self.padding);
131
132 if let Some(top_title) = &self.top_title {
134 block = block.title_top(top_title.clone());
135 }
136
137 if let Some(bottom_title) = &self.bottom_title {
139 block = block.title_bottom(bottom_title.clone());
140 }
141
142 let inner_area = block.inner(drawer.area);
144 block.render(drawer.area, drawer.buffer_mut());
146 drawer.area = inner_area;
148 }
149}