dioxus_docs_kit/components/
page_nav.rs1use dioxus::prelude::*;
2
3use crate::DocsContext;
4use crate::registry::DocsRegistry;
5
6#[component]
8pub fn DocsPageNav(current_path: String) -> Element {
9 let registry = use_context::<&'static DocsRegistry>();
10 let ctx = use_context::<DocsContext>();
11 let nav = ®istry.nav;
12
13 let current_tab = registry.tab_for_path(¤t_path);
15
16 let tab_groups: Vec<_> = if let Some(ref tab) = current_tab {
18 nav.groups_for_tab(tab)
19 } else {
20 nav.groups.iter().collect()
21 };
22
23 let api_prefix = registry.get_first_api_prefix();
24 let overview_path = api_prefix.map(|p| format!("{p}/overview"));
25
26 let mut all_pages: Vec<String> = Vec::new();
27 for group in &tab_groups {
28 for page in &group.pages {
29 all_pages.push(page.clone());
30 if let Some(ref ov) = overview_path
32 && page == ov
33 {
34 all_pages.extend(registry.get_api_endpoint_paths());
35 }
36 }
37 }
38
39 let current_index = all_pages.iter().position(|p| *p == current_path);
40
41 let prev_page = current_index.and_then(|i| {
42 if i > 0 {
43 Some(all_pages[i - 1].clone())
44 } else {
45 None
46 }
47 });
48
49 let next_page = current_index.and_then(|i| {
50 if i + 1 < all_pages.len() {
51 Some(all_pages[i + 1].clone())
52 } else {
53 None
54 }
55 });
56
57 rsx! {
58 nav { class: "mt-16 pt-8 border-t border-base-300 flex justify-between gap-4",
59 div { class: "flex-1",
61 if let Some(prev) = prev_page {
62 {
63 let title = registry.get_sidebar_title(&prev).unwrap_or_else(|| prev.clone());
64 let href = format!("{}/{}", ctx.base_path, prev);
65 rsx! {
66 Link {
67 to: NavigationTarget::Internal(href),
68 class: "group flex flex-col p-4 rounded-lg border border-base-300 hover:border-primary/50 hover:bg-base-200/50 transition-all",
69 span { class: "text-xs text-base-content/50 mb-1", "Previous" }
70 span { class: "font-medium group-hover:text-primary transition-colors",
71 "{title}"
72 }
73 }
74 }
75 }
76 }
77 }
78
79 div { class: "flex-1 text-right",
81 if let Some(next) = next_page {
82 {
83 let title = registry.get_sidebar_title(&next).unwrap_or_else(|| next.clone());
84 let href = format!("{}/{}", ctx.base_path, next);
85 rsx! {
86 Link {
87 to: NavigationTarget::Internal(href),
88 class: "group flex flex-col p-4 rounded-lg border border-base-300 hover:border-primary/50 hover:bg-base-200/50 transition-all items-end",
89 span { class: "text-xs text-base-content/50 mb-1", "Next" }
90 span { class: "font-medium group-hover:text-primary transition-colors",
91 "{title}"
92 }
93 }
94 }
95 }
96 }
97 }
98 }
99 }
100}