thaw/layout/
mod.rs

1mod layout_header;
2mod layout_sider;
3
4pub use layout_header::*;
5pub use layout_sider::*;
6
7use crate::Scrollbar;
8use leptos::prelude::*;
9use thaw_utils::{class_list, mount_style};
10
11#[derive(Default, PartialEq)]
12pub enum LayoutPosition {
13    #[default]
14    Static,
15    Absolute,
16}
17
18impl LayoutPosition {
19    pub fn as_str(&self) -> &str {
20        match self {
21            LayoutPosition::Static => "static",
22            LayoutPosition::Absolute => "absolute",
23        }
24    }
25}
26
27#[component]
28pub fn Layout(
29    #[prop(optional, into)] class: MaybeProp<String>,
30    /// Addtional classes for the layout element.
31    #[prop(optional, into)]
32    content_class: MaybeProp<String>,
33    /// Style of scrollable content node.
34    #[prop(optional, into)]
35    content_style: MaybeProp<String>,
36    /// static position will make it css position set to static.
37    /// absolute position will make it css position set to absolute and left,
38    /// right, top, bottom to 0. absolute position is very useful
39    /// when you want to make content scroll in a fixed container or make
40    /// the whole page's layout in a fixed position. You may need to change
41    /// the style of the component to make it display as you expect.
42    #[prop(optional)]
43    position: LayoutPosition,
44    /// Whether the component has sider inside. If so it must be true.
45    #[prop(optional, into)]
46    has_sider: Signal<bool>,
47    children: Children,
48) -> impl IntoView {
49    mount_style("layout", include_str!("./layout.css"));
50
51    let sider_style = Memo::new(move |_| {
52        if has_sider.get() {
53            Some("display: flex; flex-wrap: nowrap; flex-direction: row; width: 100%;")
54        } else {
55            None
56        }
57    });
58    view! {
59        <div class=class_list![gen_class(position), class]>
60            <Scrollbar
61                content_class
62                content_style=Signal::derive(move || {
63                    format!(
64                        "{} {}",
65                        sider_style.get().unwrap_or_default(),
66                        content_style.get().unwrap_or_default(),
67                    )
68                })
69            >
70
71                {children()}
72            </Scrollbar>
73        </div>
74    }
75}
76
77fn gen_class(position: LayoutPosition) -> String {
78    let mut class = String::from("thaw-layout");
79    if position == LayoutPosition::Absolute {
80        class.push_str(" thaw-layout--absolute-positioned");
81    }
82    class
83}