dioxus_docs_kit/components/blog/
blog_layout.rs1use dioxus::prelude::*;
2use dioxus_free_icons::Icon;
3use dioxus_free_icons::icons::ld_icons::LdMenu;
4
5use crate::blog::registry::BlogRegistry;
6use crate::components::docs_layout::{DrawerOpen, SearchOpen};
7
8use super::mobile_drawer::BlogMobileDrawer;
9use super::search_modal::BlogSearchModal;
10use super::theme_toggle::BlogThemeToggle;
11
12#[component]
19pub fn BlogLayout(
20 header: Option<Element>,
21 #[props(default = true)] show_header: bool,
22 children: Element,
23) -> Element {
24 let registry = use_context::<&'static BlogRegistry>();
25
26 let parent_search: Option<SearchOpen> = try_use_context();
27 let parent_drawer: Option<DrawerOpen> = try_use_context();
28
29 let local_search = use_signal(|| false);
30 let local_drawer = use_signal(|| false);
31
32 let search_open = parent_search.map(|s| s.0).unwrap_or(local_search);
33 let mut drawer_open = parent_drawer.map(|d| d.0).unwrap_or(local_drawer);
34
35 use_context_provider(|| SearchOpen(search_open));
36 use_context_provider(|| DrawerOpen(drawer_open));
37
38 crate::components::shared::use_theme_provider(registry.theme.clone());
40
41 crate::components::shared::use_search_hotkey(search_open);
43
44 rsx! {
45 div { class: "min-h-screen bg-base-100",
46 if show_header {
47 div { class: "sticky top-0 z-50",
48 if let Some(hdr) = header {
49 {hdr}
50 } else {
51 div { class: "navbar bg-base-200 border-b border-base-300 px-4 lg:px-8",
52 div { class: "flex-1 gap-2",
53 button {
54 class: "btn btn-ghost btn-sm btn-square lg:hidden",
55 onclick: move |_| drawer_open.toggle(),
56 Icon { class: "size-5", icon: LdMenu }
57 }
58 }
59 div { class: "flex-none gap-1",
60 BlogSearchButton { search_open }
61 BlogThemeToggle {}
62 }
63 }
64 }
65 }
66 }
67
68 div { class: "flex-1 min-w-0",
69 {children}
70 }
71 }
72
73 BlogMobileDrawer { open: drawer_open }
74 BlogSearchModal {}
75 }
76}
77
78pub use crate::components::docs_layout::SearchButton as BlogSearchButton;