Skip to main content

whisker_css/prop/
text.rs

1//! Text-content properties: alignment, decoration, transform,
2//! overflow, vertical alignment, whitespace handling.
3
4use crate::css::Css;
5use crate::data_type::{Color, Length, LengthPercentage};
6use crate::keyword::{
7    TextAlign, TextDecorationLine, TextDecorationStyle, TextOverflow, TextTransform, VerticalAlign,
8    WhiteSpace, WordBreak, WordWrap,
9};
10
11impl Css {
12    /// Sets `text-align`. **`justify` is not supported by Lynx**.
13    /// <https://lynxjs.org/api/css/properties/text-align>
14    pub fn text_align(self, v: TextAlign) -> Self {
15        self.push("text-align", v)
16    }
17
18    /// Sets `text-decoration-line` (single value).
19    /// <https://lynxjs.org/api/css/properties/text-decoration-line>
20    pub fn text_decoration_line(self, v: TextDecorationLine) -> Self {
21        self.push("text-decoration-line", v)
22    }
23
24    /// Sets `text-decoration-style`.
25    /// <https://lynxjs.org/api/css/properties/text-decoration-style>
26    pub fn text_decoration_style(self, v: TextDecorationStyle) -> Self {
27        self.push("text-decoration-style", v)
28    }
29
30    /// Sets `text-decoration-color`.
31    /// <https://lynxjs.org/api/css/properties/text-decoration-color>
32    pub fn text_decoration_color(self, v: Color) -> Self {
33        self.push("text-decoration-color", v)
34    }
35
36    /// Sets `text-decoration-thickness`.
37    /// <https://lynxjs.org/api/css/properties/text-decoration-thickness>
38    pub fn text_decoration_thickness(self, v: Length) -> Self {
39        self.push("text-decoration-thickness", v)
40    }
41
42    /// Sets `text-overflow`.
43    /// <https://lynxjs.org/api/css/properties/text-overflow>
44    pub fn text_overflow(self, v: TextOverflow) -> Self {
45        self.push("text-overflow", v)
46    }
47
48    /// Sets `text-transform`.
49    /// <https://lynxjs.org/api/css/properties/text-transform>
50    pub fn text_transform(self, v: TextTransform) -> Self {
51        self.push("text-transform", v)
52    }
53
54    /// Sets `text-indent` — first-line indentation.
55    /// <https://lynxjs.org/api/css/properties/text-indent>
56    pub fn text_indent(self, v: impl Into<LengthPercentage>) -> Self {
57        self.push("text-indent", v.into())
58    }
59
60    /// Sets `vertical-align`.
61    /// <https://lynxjs.org/api/css/properties/vertical-align>
62    pub fn vertical_align(self, v: VerticalAlign) -> Self {
63        self.push("vertical-align", v)
64    }
65
66    /// Sets `white-space`.
67    /// <https://lynxjs.org/api/css/properties/white-space>
68    pub fn white_space(self, v: WhiteSpace) -> Self {
69        self.push("white-space", v)
70    }
71
72    /// Sets `word-break`.
73    /// <https://lynxjs.org/api/css/properties/word-break>
74    pub fn word_break(self, v: WordBreak) -> Self {
75        self.push("word-break", v)
76    }
77
78    /// Sets `word-wrap` (also known as `overflow-wrap`).
79    /// <https://lynxjs.org/api/css/properties/word-wrap>
80    pub fn word_wrap(self, v: WordWrap) -> Self {
81        self.push("word-wrap", v)
82    }
83
84    /// Sets `overflow-wrap` — synonym of `word-wrap`.
85    /// <https://lynxjs.org/api/css/properties/overflow-wrap>
86    pub fn overflow_wrap(self, v: WordWrap) -> Self {
87        self.push("overflow-wrap", v)
88    }
89
90    /// Sets `-webkit-line-clamp` — limit the visible line count.
91    /// <https://lynxjs.org/api/css/properties/-webkit-line-clamp>
92    pub fn webkit_line_clamp(self, v: u32) -> Self {
93        self.push_raw("-webkit-line-clamp", v.to_string())
94    }
95
96    /// Sets `text-stroke-width`.
97    /// <https://lynxjs.org/api/css/properties/text-stroke-width>
98    pub fn text_stroke_width(self, v: Length) -> Self {
99        self.push("text-stroke-width", v)
100    }
101
102    /// Sets `text-stroke-color`.
103    /// <https://lynxjs.org/api/css/properties/text-stroke-color>
104    pub fn text_stroke_color(self, v: Color) -> Self {
105        self.push("text-stroke-color", v)
106    }
107}
108
109#[cfg(test)]
110mod tests {
111    use crate::data_type::{Color, NamedColor};
112    use crate::ext::*;
113    use crate::keyword::*;
114    use crate::Css;
115
116    #[test]
117    fn text_align_keywords() {
118        let s = Css::new().text_align(TextAlign::Center);
119        assert_eq!(s.to_string(), "text-align: center;");
120    }
121
122    #[test]
123    fn text_decoration_set() {
124        let s = Css::new()
125            .text_decoration_line(TextDecorationLine::Underline)
126            .text_decoration_style(TextDecorationStyle::Wavy)
127            .text_decoration_color(Color::Named(NamedColor::Red))
128            .text_decoration_thickness(2.px());
129        assert_eq!(
130            s.to_string(),
131            "text-decoration-line: underline; text-decoration-style: wavy; text-decoration-color: red; text-decoration-thickness: 2px;"
132        );
133    }
134
135    #[test]
136    fn text_overflow_and_transform() {
137        let s = Css::new()
138            .text_overflow(TextOverflow::Ellipsis)
139            .text_transform(TextTransform::Uppercase);
140        assert_eq!(
141            s.to_string(),
142            "text-overflow: ellipsis; text-transform: uppercase;"
143        );
144    }
145
146    #[test]
147    fn text_indent_value() {
148        let s = Css::new().text_indent(px(20));
149        assert_eq!(s.to_string(), "text-indent: 20px;");
150    }
151
152    #[test]
153    fn vertical_align_keywords() {
154        let s = Css::new().vertical_align(VerticalAlign::Middle);
155        assert_eq!(s.to_string(), "vertical-align: middle;");
156    }
157
158    #[test]
159    fn whitespace_word_handling() {
160        let s = Css::new()
161            .white_space(WhiteSpace::Nowrap)
162            .word_break(WordBreak::BreakAll)
163            .word_wrap(WordWrap::BreakWord)
164            .overflow_wrap(WordWrap::Normal);
165        assert_eq!(
166            s.to_string(),
167            "white-space: nowrap; word-break: break-all; word-wrap: break-word; overflow-wrap: normal;"
168        );
169    }
170
171    #[test]
172    fn webkit_line_clamp_count() {
173        let s = Css::new().webkit_line_clamp(2);
174        assert_eq!(s.to_string(), "-webkit-line-clamp: 2;");
175    }
176
177    #[test]
178    fn text_stroke_set() {
179        let s = Css::new()
180            .text_stroke_width(1.px())
181            .text_stroke_color(Color::hex(0x000000));
182        assert_eq!(
183            s.to_string(),
184            "text-stroke-width: 1px; text-stroke-color: rgb(0, 0, 0);"
185        );
186    }
187}