Skip to main content

radix_leptos_primitives/theming/layout_system/
container.rs

1use serde::{Deserialize, Serialize};
2
3/// Container system configuration
4#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5pub struct ContainerSystem {
6    pub max_widths: Vec<ContainerMaxWidth>,
7    pub paddings: Vec<f64>,
8    pub margins: Vec<f64>,
9    pub centers: Vec<bool>,
10}
11
12impl Default for ContainerSystem {
13    fn default() -> Self {
14        Self {
15            max_widths: [
16                ContainerMaxWidth::Small,
17                ContainerMaxWidth::Medium,
18                ContainerMaxWidth::Large,
19                ContainerMaxWidth::ExtraLarge,
20                ContainerMaxWidth::Fluid,
21            ]
22            .to_vec(),
23            paddings: [16.0, 24.0, 32.0, 48.0].to_vec(),
24            margins: [0.0, 16.0, 24.0, 32.0, 48.0].to_vec(),
25            centers: [true, false].to_vec(),
26        }
27    }
28}
29
30/// Container max width enum
31#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
32pub enum ContainerMaxWidth {
33    Small,
34    Medium,
35    Large,
36    ExtraLarge,
37    Fluid,
38}
39
40impl ContainerMaxWidth {
41    pub fn as_str(&self) -> &'static str {
42        match self {
43            ContainerMaxWidth::Small => "sm",
44            ContainerMaxWidth::Medium => "md",
45            ContainerMaxWidth::Large => "lg",
46            ContainerMaxWidth::ExtraLarge => "xl",
47            ContainerMaxWidth::Fluid => "fluid",
48        }
49    }
50
51    pub fn max_width(&self) -> Option<f64> {
52        match self {
53            ContainerMaxWidth::Small => Some(640.0),
54            ContainerMaxWidth::Medium => Some(768.0),
55            ContainerMaxWidth::Large => Some(1024.0),
56            ContainerMaxWidth::ExtraLarge => Some(1280.0),
57            ContainerMaxWidth::Fluid => None,
58        }
59    }
60}
61
62/// Grid system configuration
63#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
64pub struct GridSystem {
65    pub columns: u32,
66    pub gutters: Vec<f64>,
67    pub gaps: Vec<f64>,
68    pub alignments: Vec<GridAlignment>,
69}
70
71impl Default for GridSystem {
72    fn default() -> Self {
73        Self {
74            columns: 12,
75            gutters: [16.0, 24.0, 32.0, 48.0].to_vec(),
76            gaps: [8.0, 16.0, 24.0, 32.0, 48.0].to_vec(),
77            alignments: [
78                GridAlignment::Start,
79                GridAlignment::Center,
80                GridAlignment::End,
81                GridAlignment::Stretch,
82                GridAlignment::SpaceBetween,
83                GridAlignment::SpaceAround,
84                GridAlignment::SpaceEvenly,
85            ]
86            .to_vec(),
87        }
88    }
89}
90
91/// Grid alignment enum
92#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
93pub enum GridAlignment {
94    Start,
95    Center,
96    End,
97    Stretch,
98    SpaceBetween,
99    SpaceAround,
100    SpaceEvenly,
101}
102
103impl GridAlignment {
104    pub fn as_str(&self) -> &'static str {
105        match self {
106            GridAlignment::Start => "start",
107            GridAlignment::Center => "center",
108            GridAlignment::End => "end",
109            GridAlignment::Stretch => "stretch",
110            GridAlignment::SpaceBetween => "space-between",
111            GridAlignment::SpaceAround => "space-around",
112            GridAlignment::SpaceEvenly => "space-evenly",
113        }
114    }
115}
116
117/// Flexbox system configuration
118#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
119pub struct FlexboxSystem {
120    pub directions: Vec<FlexDirection>,
121    pub wraps: Vec<FlexWrap>,
122    pub justifications: Vec<JustifyContent>,
123    pub alignments: Vec<AlignItems>,
124    pub grows: Vec<f64>,
125    pub shrinks: Vec<f64>,
126}
127
128impl Default for FlexboxSystem {
129    fn default() -> Self {
130        Self {
131            directions: [
132                FlexDirection::Row,
133                FlexDirection::RowReverse,
134                FlexDirection::Column,
135                FlexDirection::ColumnReverse,
136            ]
137            .to_vec(),
138            wraps: [FlexWrap::Nowrap, FlexWrap::Wrap, FlexWrap::WrapReverse].to_vec(),
139            justifications: [
140                JustifyContent::Start,
141                JustifyContent::End,
142                JustifyContent::Center,
143                JustifyContent::SpaceBetween,
144                JustifyContent::SpaceAround,
145                JustifyContent::SpaceEvenly,
146            ]
147            .to_vec(),
148            alignments: [
149                AlignItems::Start,
150                AlignItems::End,
151                AlignItems::Center,
152                AlignItems::Baseline,
153                AlignItems::Stretch,
154            ]
155            .to_vec(),
156            grows: [0.0, 1.0, 2.0, 3.0].to_vec(),
157            shrinks: [0.0, 1.0, 2.0, 3.0].to_vec(),
158        }
159    }
160}
161
162/// Flex direction enum
163#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
164pub enum FlexDirection {
165    Row,
166    RowReverse,
167    Column,
168    ColumnReverse,
169}
170
171impl FlexDirection {
172    pub fn as_str(&self) -> &'static str {
173        match self {
174            FlexDirection::Row => "row",
175            FlexDirection::RowReverse => "row-reverse",
176            FlexDirection::Column => "column",
177            FlexDirection::ColumnReverse => "column-reverse",
178        }
179    }
180}
181
182/// Flex wrap enum
183#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
184pub enum FlexWrap {
185    Nowrap,
186    Wrap,
187    WrapReverse,
188}
189
190impl FlexWrap {
191    pub fn as_str(&self) -> &'static str {
192        match self {
193            FlexWrap::Nowrap => "nowrap",
194            FlexWrap::Wrap => "wrap",
195            FlexWrap::WrapReverse => "wrap-reverse",
196        }
197    }
198}
199
200/// Justify content enum
201#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
202pub enum JustifyContent {
203    Start,
204    End,
205    Center,
206    SpaceBetween,
207    SpaceAround,
208    SpaceEvenly,
209}
210
211impl JustifyContent {
212    pub fn as_str(&self) -> &'static str {
213        match self {
214            JustifyContent::Start => "start",
215            JustifyContent::End => "end",
216            JustifyContent::Center => "center",
217            JustifyContent::SpaceBetween => "space-between",
218            JustifyContent::SpaceAround => "space-around",
219            JustifyContent::SpaceEvenly => "space-evenly",
220        }
221    }
222}
223
224/// Align items enum
225#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
226pub enum AlignItems {
227    Start,
228    End,
229    Center,
230    Baseline,
231    Stretch,
232}
233
234impl AlignItems {
235    pub fn as_str(&self) -> &'static str {
236        match self {
237            AlignItems::Start => "start",
238            AlignItems::End => "end",
239            AlignItems::Center => "center",
240            AlignItems::Baseline => "baseline",
241            AlignItems::Stretch => "stretch",
242        }
243    }
244}
245
246#[cfg(test)]
247mod container_tests {
248    use super::*;
249
250    #[test]
251    fn test_container_system_default() {
252        let containers = ContainerSystem::default();
253        assert!(containers.max_widths.contains(&ContainerMaxWidth::Small));
254        assert!(containers.max_widths.contains(&ContainerMaxWidth::Medium));
255        assert!(containers.max_widths.contains(&ContainerMaxWidth::Large));
256        assert!(containers
257            .max_widths
258            .contains(&ContainerMaxWidth::ExtraLarge));
259        assert!(containers.max_widths.contains(&ContainerMaxWidth::Fluid));
260        assert!(containers.paddings.contains(&16.0));
261        assert!(containers.paddings.contains(&24.0));
262        assert!(containers.paddings.contains(&32.0));
263        assert!(containers.paddings.contains(&48.0));
264        assert!(containers.margins.contains(&0.0));
265        assert!(containers.margins.contains(&16.0));
266        assert!(containers.margins.contains(&24.0));
267        assert!(containers.margins.contains(&32.0));
268        assert!(containers.margins.contains(&48.0));
269        assert!(containers.centers.contains(&true));
270        assert!(containers.centers.contains(&false));
271    }
272
273    #[test]
274    fn test_container_max_width_enum() {
275        assert_eq!(ContainerMaxWidth::Small.as_str(), "sm");
276        assert_eq!(ContainerMaxWidth::Medium.as_str(), "md");
277        assert_eq!(ContainerMaxWidth::Large.as_str(), "lg");
278        assert_eq!(ContainerMaxWidth::ExtraLarge.as_str(), "xl");
279        assert_eq!(ContainerMaxWidth::Fluid.as_str(), "fluid");
280    }
281
282    #[test]
283    fn test_container_max_width_values() {
284        assert_eq!(ContainerMaxWidth::Small.max_width(), Some(640.0));
285        assert_eq!(ContainerMaxWidth::Medium.max_width(), Some(768.0));
286        assert_eq!(ContainerMaxWidth::Large.max_width(), Some(1024.0));
287        assert_eq!(ContainerMaxWidth::ExtraLarge.max_width(), Some(1280.0));
288        assert_eq!(ContainerMaxWidth::Fluid.max_width(), None);
289    }
290
291    #[test]
292    fn test_grid_system_default() {
293        let grid = GridSystem::default();
294        assert_eq!(grid.columns, 12);
295        assert!(grid.gutters.contains(&16.0));
296        assert!(grid.gutters.contains(&24.0));
297        assert!(grid.gutters.contains(&32.0));
298        assert!(grid.gutters.contains(&48.0));
299        assert!(grid.gaps.contains(&8.0));
300        assert!(grid.gaps.contains(&16.0));
301        assert!(grid.gaps.contains(&24.0));
302        assert!(grid.gaps.contains(&32.0));
303        assert!(grid.gaps.contains(&48.0));
304        assert!(grid.alignments.contains(&GridAlignment::Start));
305        assert!(grid.alignments.contains(&GridAlignment::Center));
306        assert!(grid.alignments.contains(&GridAlignment::End));
307        assert!(grid.alignments.contains(&GridAlignment::Stretch));
308    }
309
310    #[test]
311    fn test_grid_alignment_enum() {
312        assert_eq!(GridAlignment::Start.as_str(), "start");
313        assert_eq!(GridAlignment::Center.as_str(), "center");
314        assert_eq!(GridAlignment::End.as_str(), "end");
315        assert_eq!(GridAlignment::Stretch.as_str(), "stretch");
316        assert_eq!(GridAlignment::SpaceBetween.as_str(), "space-between");
317        assert_eq!(GridAlignment::SpaceAround.as_str(), "space-around");
318        assert_eq!(GridAlignment::SpaceEvenly.as_str(), "space-evenly");
319    }
320
321    #[test]
322    fn test_flexbox_system_default() {
323        let flexbox = FlexboxSystem::default();
324        assert!(flexbox.directions.contains(&FlexDirection::Row));
325        assert!(flexbox.directions.contains(&FlexDirection::RowReverse));
326        assert!(flexbox.directions.contains(&FlexDirection::Column));
327        assert!(flexbox.directions.contains(&FlexDirection::ColumnReverse));
328        assert!(flexbox.wraps.contains(&FlexWrap::Nowrap));
329        assert!(flexbox.wraps.contains(&FlexWrap::Wrap));
330        assert!(flexbox.wraps.contains(&FlexWrap::WrapReverse));
331        assert!(flexbox.justifications.contains(&JustifyContent::Start));
332        assert!(flexbox.justifications.contains(&JustifyContent::End));
333        assert!(flexbox.justifications.contains(&JustifyContent::Center));
334        assert!(flexbox.alignments.contains(&AlignItems::Start));
335        assert!(flexbox.alignments.contains(&AlignItems::End));
336        assert!(flexbox.alignments.contains(&AlignItems::Center));
337        assert!(flexbox.grows.contains(&0.0));
338        assert!(flexbox.grows.contains(&1.0));
339        assert!(flexbox.shrinks.contains(&0.0));
340        assert!(flexbox.shrinks.contains(&1.0));
341    }
342
343    #[test]
344    fn test_flex_direction_enum() {
345        assert_eq!(FlexDirection::Row.as_str(), "row");
346        assert_eq!(FlexDirection::RowReverse.as_str(), "row-reverse");
347        assert_eq!(FlexDirection::Column.as_str(), "column");
348        assert_eq!(FlexDirection::ColumnReverse.as_str(), "column-reverse");
349    }
350
351    #[test]
352    fn test_flex_wrap_enum() {
353        assert_eq!(FlexWrap::Nowrap.as_str(), "nowrap");
354        assert_eq!(FlexWrap::Wrap.as_str(), "wrap");
355        assert_eq!(FlexWrap::WrapReverse.as_str(), "wrap-reverse");
356    }
357
358    #[test]
359    fn test_justify_content_enum() {
360        assert_eq!(JustifyContent::Start.as_str(), "start");
361        assert_eq!(JustifyContent::End.as_str(), "end");
362        assert_eq!(JustifyContent::Center.as_str(), "center");
363        assert_eq!(JustifyContent::SpaceBetween.as_str(), "space-between");
364        assert_eq!(JustifyContent::SpaceAround.as_str(), "space-around");
365        assert_eq!(JustifyContent::SpaceEvenly.as_str(), "space-evenly");
366    }
367
368    #[test]
369    fn test_align_items_enum() {
370        assert_eq!(AlignItems::Start.as_str(), "start");
371        assert_eq!(AlignItems::End.as_str(), "end");
372        assert_eq!(AlignItems::Center.as_str(), "center");
373        assert_eq!(AlignItems::Baseline.as_str(), "baseline");
374        assert_eq!(AlignItems::Stretch.as_str(), "stretch");
375    }
376}