tui_realm_stdlib/components/
label.rs

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