byewlma/helpers/
typography.rs

1use crate::{innerlude::*, Color};
2
3pure_props! {
4    /// Bulma Typography Helper
5    ///
6    /// Renders as a <span/>, by default, but can be overidden by the `tag` property
7    pub struct Text {
8        #[prop_or_default]
9        pub tag: Option<&'static str>,
10
11        #[prop_or_default]
12        pub color: Option<Color>,
13
14        #[prop_or_default]
15        pub size: Option<TextSize>,
16        /// Set size when viewport is less than the [`$tablet`](https://bulma.io/documentation/customize/variables/) breakpoint (default: `769px`)
17        #[prop_or_default]
18        pub size_mobile: Option<TextSize>,
19        /// Set size when viewport is less than the [`$desktop`](https://bulma.io/documentation/customize/variables/) breakpoint (default: `1023px`)
20        #[prop_or_default]
21        pub size_touch: Option<TextSize>,
22        /// Set size when viewport is at least the [`$tablet`](https://bulma.io/documentation/customize/variables/) breakpoint (default: `769px`)
23        #[prop_or_default]
24        pub size_tablet_and_greater: Option<TextSize>,
25        /// Set size when viewport is at least the [`$desktop`](https://bulma.io/documentation/customize/variables/) breakpoint (default: `1024px`)
26        #[prop_or_default]
27        pub size_desktop_and_greater: Option<TextSize>,
28        /// Set size when viewport is at least the [`$widescreen`](https://bulma.io/documentation/customize/variables/) breakpoint (default: `1216px`)
29        #[prop_or_default]
30        pub size_widescreen_and_greater: Option<TextSize>,
31        /// Set size when viewport is at least the [`$fullhd`](https://bulma.io/documentation/customize/variables/) breakpoint (default: `1408px`)
32        #[prop_or_default]
33        pub size_fullhd_and_greater: Option<TextSize>,
34
35        #[prop_or_default]
36        pub alignment: Option<TextAlignment>,
37        /// Set alignment when viewport is less than the [`$tablet`](https://bulma.io/documentation/customize/variables/) breakpoint (default: `769px`)
38        #[prop_or_default]
39        pub alignment_mobile: Option<TextAlignment>,
40        /// Set alignment when viewport is less than the [`$desktop`](https://bulma.io/documentation/customize/variables/) breakpoint (default: `1023px`)
41        #[prop_or_default]
42        pub alignment_touch: Option<TextAlignment>,
43        /// Set alignment when viewport is at least the [`$tablet`](https://bulma.io/documentation/customize/variables/) breakpoint (default: `769px`)
44        #[prop_or_default]
45        pub alignment_tablet_and_greater: Option<TextAlignment>,
46        /// Set alignment when viewport is at least the [`$desktop`](https://bulma.io/documentation/customize/variables/) breakpoint (default: `1024px`)
47        #[prop_or_default]
48        pub alignment_desktop_and_greater: Option<TextAlignment>,
49        /// Set alignment when viewport is at least the [`$widescreen`](https://bulma.io/documentation/customize/variables/) breakpoint (default: `1216px`)
50        #[prop_or_default]
51        pub alignment_widescreen_and_greater: Option<TextAlignment>,
52        /// Set alignment when viewport is at least the [`$fullhd`](https://bulma.io/documentation/customize/variables/) breakpoint (default: `1408px`)
53        #[prop_or_default]
54        pub alignment_fullhd_and_greater: Option<TextAlignment>,
55
56        /// Set alignment when viewport is in the tablet range, between the
57        /// [`$tablet`](https://bulma.io/documentation/customize/variables/) (default: `769px`)
58        /// and
59        /// [`$desktop`](https://bulma.io/documentation/customize/variables/) (default: `1023px`)
60        /// breakpoints
61        #[prop_or_default]
62        pub alignment_only_tablet: Option<TextAlignment>,
63
64        /// Set alignment when viewport is in the tablet range, between the
65        /// [`$desktop`](https://bulma.io/documentation/customize/variables/) (default: `1023px`)
66        /// and
67        /// [`$widescreen`](https://bulma.io/documentation/customize/variables/) (default: `1216px`)
68        /// breakpoints
69        #[prop_or_default]
70        pub alignment_only_desktop: Option<TextAlignment>,
71
72        /// Set alignment when viewport is in the tablet range, between the
73        /// [`$widescreen`](https://bulma.io/documentation/customize/variables/) (default: `1216px`)
74        /// and
75        /// [`$fullhd`](https://bulma.io/documentation/customize/variables/) (default: `1408px`)
76        /// breakpoints
77        #[prop_or_default]
78        pub alignment_only_widescreen: Option<TextAlignment>,
79
80        #[prop_or_default]
81        pub transform: Option<TextTransform>,
82
83        #[prop_or_default]
84        pub weight: Option<TextWeight>,
85
86        #[prop_or_default]
87        pub font_family: Option<FontFamily>,
88    }
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, BulmaClass)]
92pub enum TextSize {
93    /// `font-size:`[`$size-1`](https://bulma.io/documentation/customize/variables/) (default: `3rem`)
94    #[bulma_class = "is-size-1"]
95    Sz1,
96    /// `font-size:`[`$size-2`](https://bulma.io/documentation/customize/variables/) (default: `2.5rem`)
97    #[bulma_class = "is-size-2"]
98    Sz2,
99    /// `font-size:`[`$size-3`](https://bulma.io/documentation/customize/variables/) (default: `2rem`)
100    #[bulma_class = "is-size-3"]
101    Sz3,
102    /// `font-size:`[`$size-4`](https://bulma.io/documentation/customize/variables/) (default: `1.5rem`)
103    #[bulma_class = "is-size-4"]
104    Sz4,
105    /// `font-size:`[`$size-5`](https://bulma.io/documentation/customize/variables/) (default: `1.25rem`)
106    #[bulma_class = "is-size-5"]
107    Sz5,
108    /// `font-size:`[`$size-6`](https://bulma.io/documentation/customize/variables/) (default: `1rem`)
109    #[bulma_class = "is-size-6"]
110    Sz6,
111    /// `font-size:`[`$size-7`](https://bulma.io/documentation/customize/variables/) (default: `0.75rem`)
112    #[bulma_class = "is-size-7"]
113    Sz7,
114}
115
116impl TextSize {
117    pub fn mobile(&self) -> &'static str {
118        match self {
119            TextSize::Sz1 => "is-size-1-mobile",
120            TextSize::Sz2 => "is-size-2-mobile",
121            TextSize::Sz3 => "is-size-3-mobile",
122            TextSize::Sz4 => "is-size-4-mobile",
123            TextSize::Sz5 => "is-size-5-mobile",
124            TextSize::Sz6 => "is-size-6-mobile",
125            TextSize::Sz7 => "is-size-7-mobile",
126        }
127    }
128    pub fn touch(&self) -> &'static str {
129        match self {
130            TextSize::Sz1 => "is-size-1-touch",
131            TextSize::Sz2 => "is-size-2-touch",
132            TextSize::Sz3 => "is-size-3-touch",
133            TextSize::Sz4 => "is-size-4-touch",
134            TextSize::Sz5 => "is-size-5-touch",
135            TextSize::Sz6 => "is-size-6-touch",
136            TextSize::Sz7 => "is-size-7-touch",
137        }
138    }
139    pub fn tablet(&self) -> &'static str {
140        match self {
141            TextSize::Sz1 => "is-size-1-tablet",
142            TextSize::Sz2 => "is-size-2-tablet",
143            TextSize::Sz3 => "is-size-3-tablet",
144            TextSize::Sz4 => "is-size-4-tablet",
145            TextSize::Sz5 => "is-size-5-tablet",
146            TextSize::Sz6 => "is-size-6-tablet",
147            TextSize::Sz7 => "is-size-7-tablet",
148        }
149    }
150    pub fn desktop(&self) -> &'static str {
151        match self {
152            TextSize::Sz1 => "is-size-1-desktop",
153            TextSize::Sz2 => "is-size-2-desktop",
154            TextSize::Sz3 => "is-size-3-desktop",
155            TextSize::Sz4 => "is-size-4-desktop",
156            TextSize::Sz5 => "is-size-5-desktop",
157            TextSize::Sz6 => "is-size-6-desktop",
158            TextSize::Sz7 => "is-size-7-desktop",
159        }
160    }
161    pub fn widescreen(&self) -> &'static str {
162        match self {
163            TextSize::Sz1 => "is-size-1-widescreen",
164            TextSize::Sz2 => "is-size-2-widescreen",
165            TextSize::Sz3 => "is-size-3-widescreen",
166            TextSize::Sz4 => "is-size-4-widescreen",
167            TextSize::Sz5 => "is-size-5-widescreen",
168            TextSize::Sz6 => "is-size-6-widescreen",
169            TextSize::Sz7 => "is-size-7-widescreen",
170        }
171    }
172    pub fn fullhd(&self) -> &'static str {
173        match self {
174            TextSize::Sz1 => "is-size-1-fullhd",
175            TextSize::Sz2 => "is-size-2-fullhd",
176            TextSize::Sz3 => "is-size-3-fullhd",
177            TextSize::Sz4 => "is-size-4-fullhd",
178            TextSize::Sz5 => "is-size-5-fullhd",
179            TextSize::Sz6 => "is-size-6-fullhd",
180            TextSize::Sz7 => "is-size-7-fullhd",
181        }
182    }
183}
184
185#[derive(Debug, Clone, Copy, PartialEq, BulmaClass)]
186pub enum TextAlignment {
187    #[bulma_class = "has-text-centered"]
188    Centered,
189    #[bulma_class = "has-text-justified"]
190    Justified,
191    #[bulma_class = "has-text-left"]
192    Left,
193    #[bulma_class = "has-text-right"]
194    Right,
195}
196
197impl TextAlignment {
198    pub fn mobile(&self) -> &'static str {
199        match self {
200            TextAlignment::Centered => "has-text-centered-mobile",
201            TextAlignment::Justified => "has-text-justified-mobile",
202            TextAlignment::Left => "has-text-left-mobile",
203            TextAlignment::Right => "has-text-right-mobile",
204        }
205    }
206    pub fn touch(&self) -> &'static str {
207        match self {
208            TextAlignment::Centered => "has-text-centered-touch",
209            TextAlignment::Justified => "has-text-justified-touch",
210            TextAlignment::Left => "has-text-left-touch",
211            TextAlignment::Right => "has-text-right-touch",
212        }
213    }
214    pub fn tablet_only(&self) -> &'static str {
215        match self {
216            TextAlignment::Centered => "has-text-centered-tablet-only",
217            TextAlignment::Justified => "has-text-justified-tablet-only",
218            TextAlignment::Left => "has-text-left-tablet-only",
219            TextAlignment::Right => "has-text-right-tablet-only",
220        }
221    }
222    pub fn tablet(&self) -> &'static str {
223        match self {
224            TextAlignment::Centered => "has-text-centered-tablet",
225            TextAlignment::Justified => "has-text-justified-tablet",
226            TextAlignment::Left => "has-text-left-tablet",
227            TextAlignment::Right => "has-text-right-tablet",
228        }
229    }
230    pub fn desktop_only(&self) -> &'static str {
231        match self {
232            TextAlignment::Centered => "has-text-centered-desktop-only",
233            TextAlignment::Justified => "has-text-justified-desktop-only",
234            TextAlignment::Left => "has-text-left-desktop-only",
235            TextAlignment::Right => "has-text-right-desktop-only",
236        }
237    }
238    pub fn desktop(&self) -> &'static str {
239        match self {
240            TextAlignment::Centered => "has-text-centered-desktop",
241            TextAlignment::Justified => "has-text-justified-desktop",
242            TextAlignment::Left => "has-text-left-desktop",
243            TextAlignment::Right => "has-text-right-desktop",
244        }
245    }
246    pub fn widescreen_only(&self) -> &'static str {
247        match self {
248            TextAlignment::Centered => "has-text-centered-widescreen-only",
249            TextAlignment::Justified => "has-text-justified-widescreen-only",
250            TextAlignment::Left => "has-text-left-widescreen-only",
251            TextAlignment::Right => "has-text-right-widescreen-only",
252        }
253    }
254    pub fn widescreen(&self) -> &'static str {
255        match self {
256            TextAlignment::Centered => "has-text-centered-widescreen",
257            TextAlignment::Justified => "has-text-justified-widescreen",
258            TextAlignment::Left => "has-text-left-widescreen",
259            TextAlignment::Right => "has-text-right-widescreen",
260        }
261    }
262    pub fn fullhd(&self) -> &'static str {
263        match self {
264            TextAlignment::Centered => "has-text-centered-fullhd",
265            TextAlignment::Justified => "has-text-justified-fullhd",
266            TextAlignment::Left => "has-text-left-fullhd",
267            TextAlignment::Right => "has-text-right-fullhd",
268        }
269    }
270}
271
272#[derive(Debug, Clone, Copy, PartialEq, BulmaClass)]
273pub enum TextTransform {
274    #[bulma_class = "is-capitalized"]
275    Capitalize,
276    #[bulma_class = "is-lowercase"]
277    Lowercase,
278    #[bulma_class = "is-uppercase"]
279    Uppercase,
280    #[bulma_class = "is-italic"]
281    Italic,
282}
283
284#[derive(Debug, Clone, Copy, PartialEq, BulmaClass)]
285pub enum TextWeight {
286    #[bulma_class = "has-text-weight-light"]
287    Light,
288    #[bulma_class = "has-text-weight-normal"]
289    Normal,
290    #[bulma_class = "has-text-weight-medium"]
291    Medium,
292    #[bulma_class = "has-text-weight-semibold"]
293    SemiBold,
294    #[bulma_class = "has-text-weight-bold"]
295    Bold,
296}
297
298#[derive(Debug, Clone, Copy, PartialEq, BulmaClass)]
299pub enum FontFamily {
300    /// Set family to [`$family-sans-serif`](https://bulma.io/documentation/customize/variables/)
301    #[bulma_class = "is-family-sans-serif"]
302    SansSerif,
303    /// Set family to [`$family-monospace`](https://bulma.io/documentation/customize/variables/)
304    #[bulma_class = "is-family-monospace"]
305    Monospace,
306    /// Set family to [`$family-primary`](https://bulma.io/documentation/customize/variables/),
307    /// which is, by default, equal to [`$family-sans-serif`](https://bulma.io/documentation/customize/variables/)
308    #[bulma_class = "is-family-primary"]
309    Primary,
310    /// Set family to [`$family-secondary`](https://bulma.io/documentation/customize/variables/),
311    /// which is, by default, equal to [`$family-sans-serif`](https://bulma.io/documentation/customize/variables/)
312    #[bulma_class = "is-family-secondary"]
313    Secondary,
314    /// Set family to [`$family-code`](https://bulma.io/documentation/customize/variables/)
315    /// which is, by default, equal to [`$family-monospace`](https://bulma.io/documentation/customize/variables/)
316    #[bulma_class = "is-family-code"]
317    Code,
318}
319
320impl PureComponent for PureText {
321    fn render(&self) -> Html {
322        let mut class = self.class.clone();
323
324        if let Some(color) = &self.color {
325            class.push(color.text_class());
326        }
327
328        if let Some(size) = &self.size {
329            class.add(size);
330        }
331
332        unsafe {
333            if let Some(size) = &self.size_mobile {
334                class.unchecked_push(size.mobile());
335            }
336            if let Some(size) = &self.size_touch {
337                class.unchecked_push(size.touch());
338            }
339            if let Some(size) = &self.size_tablet_and_greater {
340                class.unchecked_push(size.tablet());
341            }
342            if let Some(size) = &self.size_desktop_and_greater {
343                class.unchecked_push(size.desktop());
344            }
345            if let Some(size) = &self.size_widescreen_and_greater {
346                class.unchecked_push(size.widescreen());
347            }
348            if let Some(size) = &self.size_fullhd_and_greater {
349                class.unchecked_push(size.fullhd());
350            }
351        }
352
353        if let Some(alignment) = &self.alignment {
354            class.add(alignment);
355        }
356
357        unsafe {
358            if let Some(alignment) = &self.alignment_mobile {
359                class.unchecked_push(alignment.mobile());
360            }
361            if let Some(alignment) = &self.alignment_touch {
362                class.unchecked_push(alignment.touch());
363            }
364            if let Some(alignment) = &self.alignment_only_tablet {
365                class.unchecked_push(alignment.tablet_only());
366            }
367            if let Some(alignment) = &self.alignment_tablet_and_greater {
368                class.unchecked_push(alignment.tablet());
369            }
370            if let Some(alignment) = &self.alignment_only_desktop {
371                class.unchecked_push(alignment.desktop_only());
372            }
373            if let Some(alignment) = &self.alignment_desktop_and_greater {
374                class.unchecked_push(alignment.desktop());
375            }
376            if let Some(alignment) = &self.alignment_only_widescreen {
377                class.unchecked_push(alignment.widescreen_only());
378            }
379            if let Some(alignment) = &self.alignment_widescreen_and_greater {
380                class.unchecked_push(alignment.widescreen());
381            }
382            if let Some(alignment) = &self.alignment_fullhd_and_greater {
383                class.unchecked_push(alignment.fullhd());
384            }
385        }
386
387        if let Some(transform) = &self.transform {
388            class.add(transform);
389        }
390
391        if let Some(weight) = &self.weight {
392            class.add(weight);
393        }
394
395        if let Some(family) = &self.font_family {
396            class.add(family);
397        }
398
399        html! {
400            <@{self.tag.unwrap_or("span")} id={self.id.clone()} class={class} style={self.style.clone()}>
401                {for self.children.iter()}
402            </@>
403        }
404    }
405}