guise/layout/
container.rs1use gpui::prelude::*;
18use gpui::{div, px, AnyElement, App, IntoElement, Window};
19
20use crate::theme::{theme, Size};
21
22fn max_width(size: Size) -> f32 {
24 match size {
25 Size::Xs => 540.0,
26 Size::Sm => 720.0,
27 Size::Md => 960.0,
28 Size::Lg => 1140.0,
29 Size::Xl => 1320.0,
30 }
31}
32
33#[derive(IntoElement)]
35pub struct Container {
36 size: Size,
37 padding: Size,
38 children: Vec<AnyElement>,
39}
40
41impl Container {
42 pub fn new() -> Self {
43 Container {
44 size: Size::Md,
45 padding: Size::Md,
46 children: Vec::new(),
47 }
48 }
49
50 pub fn size(mut self, size: Size) -> Self {
52 self.size = size;
53 self
54 }
55
56 pub fn padding(mut self, padding: Size) -> Self {
58 self.padding = padding;
59 self
60 }
61}
62
63impl Default for Container {
64 fn default() -> Self {
65 Container::new()
66 }
67}
68
69impl ParentElement for Container {
70 fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
71 self.children.extend(elements);
72 }
73}
74
75impl RenderOnce for Container {
76 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
77 let pad = theme(cx).spacing(self.padding);
78 div().w_full().flex().flex_col().items_center().child(
79 div()
80 .w_full()
81 .max_w(px(max_width(self.size)))
82 .px(px(pad))
83 .flex()
84 .flex_col()
85 .children(self.children),
86 )
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn widths_match_mantine_scale() {
96 assert_eq!(max_width(Size::Xs), 540.0);
97 assert_eq!(max_width(Size::Sm), 720.0);
98 assert_eq!(max_width(Size::Md), 960.0);
99 assert_eq!(max_width(Size::Lg), 1140.0);
100 assert_eq!(max_width(Size::Xl), 1320.0);
101 }
102}