tui_realm_stdlib/components/
span.rsuse tuirealm::command::{Cmd, CmdResult};
use tuirealm::props::{
Alignment, AttrValue, Attribute, Color, PropPayload, PropValue, Props, Style, TextModifiers,
TextSpan,
};
use tuirealm::ratatui::text::Line as Spans;
use tuirealm::ratatui::{
layout::Rect,
text::{Span as TuiSpan, Text},
widgets::Paragraph,
};
use tuirealm::{Frame, MockComponent, State};
#[derive(Default)]
pub struct Span {
props: Props,
}
impl Span {
pub fn foreground(mut self, fg: Color) -> Self {
self.attr(Attribute::Foreground, AttrValue::Color(fg));
self
}
pub fn background(mut self, bg: Color) -> Self {
self.attr(Attribute::Background, AttrValue::Color(bg));
self
}
pub fn modifiers(mut self, m: TextModifiers) -> Self {
self.attr(Attribute::TextProps, AttrValue::TextModifiers(m));
self
}
pub fn alignment(mut self, a: Alignment) -> Self {
self.attr(Attribute::Alignment, AttrValue::Alignment(a));
self
}
pub fn spans(mut self, s: &[TextSpan]) -> Self {
self.attr(
Attribute::Text,
AttrValue::Payload(PropPayload::Vec(
s.iter().cloned().map(PropValue::TextSpan).collect(),
)),
);
self
}
}
impl MockComponent for Span {
fn view(&mut self, render: &mut Frame, area: Rect) {
if self.props.get_or(Attribute::Display, AttrValue::Flag(true)) == AttrValue::Flag(true) {
let foreground = self
.props
.get_or(Attribute::Foreground, AttrValue::Color(Color::Reset))
.unwrap_color();
let background = self
.props
.get_or(Attribute::Background, AttrValue::Color(Color::Reset))
.unwrap_color();
let spans: Vec<TuiSpan> =
match self.props.get(Attribute::Text).map(|x| x.unwrap_payload()) {
Some(PropPayload::Vec(spans)) => spans
.iter()
.cloned()
.map(|x| x.unwrap_text_span())
.map(|x| {
let (fg, bg, modifiers) =
crate::utils::use_or_default_styles(&self.props, &x);
TuiSpan::styled(
x.content,
Style::default().add_modifier(modifiers).fg(fg).bg(bg),
)
})
.collect(),
_ => Vec::new(),
};
let text: Text = Text::from(Spans::from(spans));
let alignment: Alignment = self
.props
.get_or(Attribute::Alignment, AttrValue::Alignment(Alignment::Left))
.unwrap_alignment();
render.render_widget(
Paragraph::new(text)
.alignment(alignment)
.style(Style::default().bg(background).fg(foreground)),
area,
);
}
}
fn query(&self, attr: Attribute) -> Option<AttrValue> {
self.props.get(attr)
}
fn attr(&mut self, attr: Attribute, value: AttrValue) {
self.props.set(attr, value)
}
fn state(&self) -> State {
State::None
}
fn perform(&mut self, _cmd: Cmd) -> CmdResult {
CmdResult::None
}
}
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn test_components_span() {
let component = Span::default()
.background(Color::Blue)
.foreground(Color::Red)
.modifiers(TextModifiers::BOLD)
.alignment(Alignment::Center)
.spans(&[
TextSpan::from("Press "),
TextSpan::from("<ESC>").fg(Color::Cyan).bold(),
TextSpan::from(" to quit"),
]);
assert_eq!(component.state(), State::None);
}
}