tui_realm_stdlib/components/
label.rs1use tuirealm::command::{Cmd, CmdResult};
6use tuirealm::props::{Alignment, AttrValue, Attribute, Color, Props, Style, TextModifiers};
7use tuirealm::ratatui::{layout::Rect, widgets::Paragraph};
8use tuirealm::{Frame, MockComponent, State};
9
10#[derive(Default)]
16#[must_use]
17pub struct Label {
18 props: Props,
19}
20
21impl Label {
22 pub fn foreground(mut self, fg: Color) -> Self {
23 self.attr(Attribute::Foreground, AttrValue::Color(fg));
24 self
25 }
26
27 pub fn background(mut self, bg: Color) -> Self {
28 self.attr(Attribute::Background, AttrValue::Color(bg));
29 self
30 }
31
32 pub fn modifiers(mut self, m: TextModifiers) -> Self {
33 self.attr(Attribute::TextProps, AttrValue::TextModifiers(m));
34 self
35 }
36
37 pub fn text<S: Into<String>>(mut self, t: S) -> Self {
38 self.attr(Attribute::Text, AttrValue::String(t.into()));
39 self
40 }
41
42 pub fn alignment(mut self, alignment: Alignment) -> Self {
43 self.attr(Attribute::Alignment, AttrValue::Alignment(alignment));
44 self
45 }
46}
47
48impl MockComponent for Label {
49 fn view(&mut self, render: &mut Frame, area: Rect) {
50 if self.props.get_or(Attribute::Display, AttrValue::Flag(true)) == AttrValue::Flag(true) {
52 let text = self
54 .props
55 .get_ref(Attribute::Text)
56 .and_then(|v| v.as_string())
57 .map_or("", |v| v.as_str());
58 let foreground = self
59 .props
60 .get_or(Attribute::Foreground, AttrValue::Color(Color::Reset))
61 .unwrap_color();
62 let background = self
63 .props
64 .get_or(Attribute::Background, AttrValue::Color(Color::Reset))
65 .unwrap_color();
66 let alignment: Alignment = self
67 .props
68 .get_or(Attribute::Alignment, AttrValue::Alignment(Alignment::Left))
69 .unwrap_alignment();
70 let modifiers = self
71 .props
72 .get_or(
73 Attribute::TextProps,
74 AttrValue::TextModifiers(TextModifiers::empty()),
75 )
76 .unwrap_text_modifiers();
77 render.render_widget(
78 Paragraph::new(text)
79 .style(
80 Style::default()
81 .fg(foreground)
82 .bg(background)
83 .add_modifier(modifiers),
84 )
85 .alignment(alignment),
86 area,
87 );
88 }
89 }
90
91 fn query(&self, attr: Attribute) -> Option<AttrValue> {
92 self.props.get(attr)
93 }
94
95 fn attr(&mut self, attr: Attribute, value: AttrValue) {
96 self.props.set(attr, value);
97 }
98
99 fn state(&self) -> State {
100 State::None
101 }
102
103 fn perform(&mut self, _cmd: Cmd) -> CmdResult {
104 CmdResult::None
105 }
106}
107
108#[cfg(test)]
109mod tests {
110
111 use super::*;
112
113 use pretty_assertions::assert_eq;
114
115 #[test]
116 fn test_components_label() {
117 let component: Label = Label::default()
118 .alignment(Alignment::Center)
119 .background(Color::Red)
120 .foreground(Color::Yellow)
121 .modifiers(TextModifiers::BOLD)
122 .text("foobar");
123
124 assert_eq!(component.state(), State::None);
125 }
126
127 #[test]
128 fn test_various_text_inputs() {
129 let _ = Label::default().text("str");
130 let _ = Label::default().text(String::from("String"));
131 #[allow(clippy::needless_borrows_for_generic_args)]
133 let _ = Label::default().text(&String::from("&String"));
134 }
135}