ratatui_widgets/table/
cell.rs

1use ratatui_core::buffer::Buffer;
2use ratatui_core::layout::Rect;
3use ratatui_core::style::{Style, Styled};
4use ratatui_core::text::Text;
5use ratatui_core::widgets::Widget;
6
7/// A [`Cell`] contains the [`Text`] to be displayed in a [`Row`] of a [`Table`].
8///
9/// You can apply a [`Style`] to the [`Cell`] using [`Cell::style`]. This will set the style for the
10/// entire area of the cell. Any [`Style`] set on the [`Text`] content will be combined with the
11/// [`Style`] of the [`Cell`] by adding the [`Style`] of the [`Text`] content to the [`Style`] of
12/// the [`Cell`]. Styles set on the text content will only affect the content.
13///
14/// You can use [`Text::alignment`] when creating a cell to align its content.
15///
16/// # Examples
17///
18/// You can create a `Cell` from anything that can be converted to a [`Text`].
19///
20/// ```rust
21/// use std::borrow::Cow;
22///
23/// use ratatui::style::Stylize;
24/// use ratatui::text::{Line, Span, Text};
25/// use ratatui::widgets::Cell;
26///
27/// Cell::from("simple string");
28/// Cell::from(Span::from("span"));
29/// Cell::from(Line::from(vec![
30///     Span::from("a vec of "),
31///     Span::from("spans").bold(),
32/// ]));
33/// Cell::from(Text::from("a text"));
34/// Cell::from(Text::from(Cow::Borrowed("hello")));
35/// ```
36///
37/// `Cell` implements [`Styled`] which means you can use style shorthands from the [`Stylize`] trait
38/// to set the style of the cell concisely.
39///
40/// ```rust
41/// use ratatui::style::Stylize;
42/// use ratatui::widgets::Cell;
43///
44/// Cell::new("Cell 1").red().italic();
45/// ```
46///
47/// [`Row`]: super::Row
48/// [`Table`]: super::Table
49/// [`Stylize`]: ratatui_core::style::Stylize
50#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
51pub struct Cell<'a> {
52    content: Text<'a>,
53    style: Style,
54}
55
56impl<'a> Cell<'a> {
57    /// Creates a new [`Cell`]
58    ///
59    /// The `content` parameter accepts any value that can be converted into a [`Text`].
60    ///
61    /// # Examples
62    ///
63    /// ```rust
64    /// use ratatui::style::Stylize;
65    /// use ratatui::text::{Line, Span, Text};
66    /// use ratatui::widgets::Cell;
67    ///
68    /// Cell::new("simple string");
69    /// Cell::new(Span::from("span"));
70    /// Cell::new(Line::from(vec![
71    ///     Span::raw("a vec of "),
72    ///     Span::from("spans").bold(),
73    /// ]));
74    /// Cell::new(Text::from("a text"));
75    /// ```
76    pub fn new<T>(content: T) -> Self
77    where
78        T: Into<Text<'a>>,
79    {
80        Self {
81            content: content.into(),
82            style: Style::default(),
83        }
84    }
85
86    /// Set the content of the [`Cell`]
87    ///
88    /// The `content` parameter accepts any value that can be converted into a [`Text`].
89    ///
90    /// This is a fluent setter method which must be chained or used as it consumes self
91    ///
92    /// # Examples
93    ///
94    /// ```rust
95    /// use ratatui::style::Stylize;
96    /// use ratatui::text::{Line, Span, Text};
97    /// use ratatui::widgets::Cell;
98    ///
99    /// Cell::default().content("simple string");
100    /// Cell::default().content(Span::from("span"));
101    /// Cell::default().content(Line::from(vec![
102    ///     Span::raw("a vec of "),
103    ///     Span::from("spans").bold(),
104    /// ]));
105    /// Cell::default().content(Text::from("a text"));
106    /// ```
107    #[must_use = "method moves the value of self and returns the modified value"]
108    pub fn content<T>(mut self, content: T) -> Self
109    where
110        T: Into<Text<'a>>,
111    {
112        self.content = content.into();
113        self
114    }
115
116    /// Set the `Style` of this cell
117    ///
118    /// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
119    /// your own type that implements [`Into<Style>`]).
120    ///
121    /// This `Style` will override the `Style` of the [`Row`] and can be overridden by the `Style`
122    /// of the [`Text`] content.
123    ///
124    /// This is a fluent setter method which must be chained or used as it consumes self
125    ///
126    /// # Examples
127    ///
128    /// ```rust
129    /// use ratatui::style::{Style, Stylize};
130    /// use ratatui::widgets::Cell;
131    ///
132    /// Cell::new("Cell 1").style(Style::new().red().italic());
133    /// ```
134    ///
135    /// `Cell` also implements the [`Styled`] trait, which means you can use style shorthands from
136    /// the [`Stylize`] trait to set the style of the widget more concisely.
137    ///
138    /// ```rust
139    /// use ratatui::style::Stylize;
140    /// use ratatui::widgets::Cell;
141    ///
142    /// Cell::new("Cell 1").red().italic();
143    /// ```
144    ///
145    /// [`Row`]: super::Row
146    /// [`Color`]: ratatui_core::style::Color
147    /// [`Stylize`]: ratatui_core::style::Stylize
148    #[must_use = "method moves the value of self and returns the modified value"]
149    pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
150        self.style = style.into();
151        self
152    }
153}
154
155impl Cell<'_> {
156    pub(crate) fn render(&self, area: Rect, buf: &mut Buffer) {
157        buf.set_style(area, self.style);
158        Widget::render(&self.content, area, buf);
159    }
160}
161
162impl<'a, T> From<T> for Cell<'a>
163where
164    T: Into<Text<'a>>,
165{
166    fn from(content: T) -> Self {
167        Self {
168            content: content.into(),
169            style: Style::default(),
170        }
171    }
172}
173
174impl Styled for Cell<'_> {
175    type Item = Self;
176
177    fn style(&self) -> Style {
178        self.style
179    }
180
181    fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
182        self.style(style)
183    }
184}
185
186#[cfg(test)]
187mod tests {
188    use ratatui_core::style::{Color, Modifier, Stylize};
189
190    use super::*;
191
192    #[test]
193    fn new() {
194        let cell = Cell::new("");
195        assert_eq!(cell.content, Text::from(""));
196    }
197
198    #[test]
199    fn content() {
200        let cell = Cell::default().content("");
201        assert_eq!(cell.content, Text::from(""));
202    }
203
204    #[test]
205    fn style() {
206        let style = Style::default().red().italic();
207        let cell = Cell::default().style(style);
208        assert_eq!(cell.style, style);
209    }
210
211    #[test]
212    fn stylize() {
213        assert_eq!(
214            Cell::from("").black().on_white().bold().not_dim().style,
215            Style::default()
216                .fg(Color::Black)
217                .bg(Color::White)
218                .add_modifier(Modifier::BOLD)
219                .remove_modifier(Modifier::DIM)
220        );
221    }
222}