daisy_rsx/
app_layout.rs

1#![allow(non_snake_case)]
2use dioxus::prelude::*;
3
4#[derive(Props, Clone, PartialEq)]
5pub struct AppLayoutProps {
6    title: String,
7    fav_icon_src: Option<String>,
8    stylesheets: Vec<String>,
9    js_href: Option<String>,
10    header: Element,
11    children: Element,
12    sidebar: Element,
13    sidebar_footer: Element,
14    sidebar_header: Element,
15}
16
17pub fn AppLayout(props: AppLayoutProps) -> Element {
18    rsx!(
19        head {
20            title {
21                "{props.title}"
22            }
23            meta {
24                charset: "utf-8"
25            }
26            meta {
27                "http-equiv": "X-UA-Compatible",
28                content: "IE=edge"
29            }
30            meta {
31                name: "viewport",
32                content: "width=device-width, initial-scale=1"
33            }
34            for href in &props.stylesheets {
35                link {
36                    rel: "stylesheet",
37                    href: "{href}",
38                    "type": "text/css"
39                }
40            }
41            if let Some(js_href) = props.js_href {
42                script {
43                    "type": "module",
44                    src: "{js_href}"
45                }
46            }
47            if let Some(fav_icon_src) = props.fav_icon_src {
48                link {
49                    rel: "icon",
50                    "type": "image/svg+xml",
51                    href: "{fav_icon_src}"
52                }
53            }
54        }
55        body {
56            div {
57                class: "flex h-screen overflow-hidden",
58                nav {
59                    id: "sidebar",
60                    class: "
61                        border-r border-base-300
62                        fixed
63                        bg-base-200
64                        inset-y-0
65                        left-0
66                        w-64
67                        transform
68                        -translate-x-full
69                        transition-transform
70                        duration-200
71                        ease-in-out
72                        flex
73                        flex-col
74                        lg:translate-x-0
75                        lg:static
76                        lg:inset-auto
77                        lg:transform-none
78                        z-20",
79                    div {
80                        class: "flex items-center p-4",
81                        {props.sidebar_header}
82                    }
83                    div {
84                        class: "flex-1 overflow-y-auto",
85                        {props.sidebar}
86                    }
87                    div {
88                        class: "p-4",
89                        {props.sidebar_footer}
90                    }
91                }
92                main {
93                    id: "main-content",
94                    class: "flex-1 flex flex-col",
95                    header {
96                        class: "flex items-center p-4 border-b border-base-300",
97                        button {
98                            id: "toggleButton",
99                            svg {
100                                xmlns: "http://www.w3.org/2000/svg",
101                                width: "24",
102                                height: "24",
103                                view_box: "0 0 24 24",
104                                fill: "none",
105                                stroke: "currentColor",
106                                stroke_width: "2",
107                                stroke_linecap: "round",
108                                stroke_linejoin: "round",
109                                class: "lucide lucide-panel-left",
110                                rect {
111                                    width: "18",
112                                    height: "18",
113                                    x: "3",
114                                    y: "3",
115                                    rx: "2",
116                                }
117                                path {
118                                    d: "M9 3v18",
119                                }
120                            }
121                        }
122                        {props.header}
123                    }
124                    section {
125                        class: "flex-1 overflow-y-auto",
126                        {props.children}
127                    }
128                }
129            }
130        }
131    )
132}