Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-core/src/ui_components/list.rs
1use pathfinder_color::ColorU;
2 
3use crate::{
4 elements::{Container, Element, Flex, ParentElement, Text},
5 ui_components::components::{Coords, UiComponent, UiComponentStyles},
6};
7 
8const BULLET: &str = "•";
9 
10pub enum ListStyle {
11 Numbered,
12 Bulleted,
13}
14 
15impl ListStyle {
16 fn render(&self, idx: usize, text: &str) -> String {
17 match self {
18 ListStyle::Numbered => format!("{} {}", idx + 1, text),
19 ListStyle::Bulleted => format!("{BULLET} {text}"),
20 }
21 }
22}
23 
24pub struct List {
25 list_style: ListStyle,
26 styles: UiComponentStyles,
27 items: Vec<String>,
28}
29 
30impl UiComponent for List {
31 type ElementType = Flex;
32 fn build(self) -> Flex {
33 Flex::column().with_children(
34 self.items
35 .iter()
36 .enumerate()
37 .map(|(item_idx, item)| self.render_item(item_idx, item)),
38 )
39 }
40 
41 /// Overwrites _some_ styles passed in `style` parameter
42 fn with_style(self, styles: UiComponentStyles) -> Self {
43 Self {
44 items: self.items,
45 list_style: self.list_style,
46 styles: self.styles.merge(styles),
47 }
48 }
49}
50 
51impl List {
52 pub fn new(
53 list_style: ListStyle,
54 default_styles: UiComponentStyles,
55 items: Vec<String>,
56 ) -> Self {
57 Self {
58 list_style,
59 styles: default_styles,
60 items,
61 }
62 }
63 
64 fn render_item(&self, item_idx: usize, item: &str) -> Box<dyn Element> {
65 let padding = self.styles.padding.unwrap_or_else(|| Coords::uniform(2.));
66 Container::new(
67 Text::new(
68 self.list_style.render(item_idx, item),
69 self.styles.font_family_id.unwrap(),
70 self.styles.font_size.unwrap_or(14.),
71 )
72 .with_color(self.styles.font_color.unwrap_or_else(ColorU::white))
73 .finish(),
74 )
75 .with_padding_top(padding.top)
76 .with_padding_bottom(padding.bottom)
77 .with_padding_left(padding.left)
78 .with_padding_right(padding.right)
79 .finish()
80 }
81}
82