ratatui_kit/components/
text.rs1use crate::{
2 AnyElement, ComponentTheme, Hooks, Palette, UseTheme, components::theme::resolve_style,
3 element, prelude::Fragment,
4};
5use ratatui::{
6 buffer::Buffer,
7 layout::{Position, Rect},
8 style::Style,
9 text::{Line, Text as RataText},
10 widgets::{Paragraph, Widget},
11};
12use ratatui_kit_macros::{Props, component};
13use std::ops::{Deref, DerefMut};
14
15#[non_exhaustive]
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub struct TextTheme {
19 pub style: Style,
21}
22
23impl ComponentTheme for TextTheme {
24 fn from_palette(palette: &Palette) -> Self {
25 Self {
26 style: Style::new().fg(palette.fg),
27 }
28 }
29}
30
31impl Default for TextTheme {
32 fn default() -> Self {
33 Self::from_palette(&Palette::default())
34 }
35}
36
37#[derive(Clone, Default)]
38pub struct TextParagraph<'a> {
39 inner: Paragraph<'a>,
40}
41
42impl<'a> Deref for TextParagraph<'a> {
43 type Target = Paragraph<'a>;
44
45 fn deref(&self) -> &Self::Target {
46 &self.inner
47 }
48}
49
50impl DerefMut for TextParagraph<'_> {
51 fn deref_mut(&mut self) -> &mut Self::Target {
52 &mut self.inner
53 }
54}
55
56impl Widget for TextParagraph<'_> {
59 fn render(self, area: Rect, buf: &mut Buffer) {
60 self.inner.render(area, buf);
61 }
62}
63
64impl From<String> for TextParagraph<'_> {
65 fn from(value: String) -> Self {
66 Self {
67 inner: Paragraph::new(value),
68 }
69 }
70}
71
72impl<'a> From<Paragraph<'a>> for TextParagraph<'a> {
73 fn from(value: Paragraph<'a>) -> Self {
74 Self { inner: value }
75 }
76}
77
78impl<'a> From<&'a str> for TextParagraph<'a> {
81 fn from(value: &'a str) -> Self {
82 Self {
83 inner: Paragraph::new(value),
84 }
85 }
86}
87
88impl<'a> From<Line<'a>> for TextParagraph<'a> {
89 fn from(value: Line<'a>) -> Self {
90 Self {
91 inner: Paragraph::new(value),
92 }
93 }
94}
95
96impl<'a> From<RataText<'a>> for TextParagraph<'a> {
97 fn from(value: RataText<'a>) -> Self {
98 Self {
99 inner: Paragraph::new(value),
100 }
101 }
102}
103
104#[derive(Default, Props)]
105pub struct TextProps {
106 pub text: TextParagraph<'static>,
107 pub style: Option<Style>,
109 pub alignment: ratatui::layout::Alignment,
110 pub scroll: Position,
111 pub wrap: Option<bool>,
113}
114
115#[component]
116pub fn Text(props: &TextProps, hooks: Hooks) -> impl Into<AnyElement<'static>> {
117 let theme = hooks.use_component_theme::<TextTheme>();
119 let style = resolve_style(theme.style, props.style);
120
121 let paragraph = props
122 .text
123 .inner
124 .clone()
125 .style(style)
126 .scroll((props.scroll.x, props.scroll.y))
127 .alignment(props.alignment);
128
129 let paragraph = if let Some(wrap) = props.wrap {
130 paragraph.wrap(ratatui::widgets::Wrap { trim: wrap })
131 } else {
132 paragraph
133 };
134
135 let paragraph = TextParagraph::from(paragraph);
136
137 element! {
138 Fragment{
139 widget(paragraph)
140 }
141 }
142}