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