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 #[prop(optional, into)]
32 content_class: MaybeProp<String>,
33 #[prop(optional, into)]
35 content_style: MaybeProp<String>,
36 #[prop(optional)]
43 position: LayoutPosition,
44 #[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}